mirror of
https://github.com/tsukumijima/px4_drv.git
synced 2025-07-23 20:20:36 +02:00
Compare commits
487 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
b4a6f9a9f5 | ||
|
fe259b52b7 | ||
|
5ac1fca737 | ||
|
26e8327823 | ||
|
62cfb11290 | ||
|
12a1213912 | ||
|
17496bed2c | ||
|
d2053ae4de | ||
|
419f1dea5a | ||
|
5892e3bfde | ||
|
0a63d0c9fa | ||
|
51134d6d74 | ||
|
d6baacdcbc | ||
|
f0d3a52f1f | ||
|
b13ef1c959 | ||
|
3829363fae | ||
|
8f6a0dbaa7 | ||
|
4c647926c7 | ||
|
63ed9e67d7 | ||
|
ee968631a3 | ||
|
c2a33ddd2a | ||
|
d9c3f9e24c | ||
|
f282d1c100 | ||
|
70d12956d2 | ||
|
2e62d1fe76 | ||
|
cf161dd1ed | ||
|
cc6c5b83ee | ||
|
72363fcca1 | ||
|
e2c5f170c3 | ||
|
764e0e9c29 | ||
|
dd518c7155 | ||
|
b97c90e398 | ||
|
adf8f45b5b | ||
|
796bff8fb9 | ||
|
234ff894b1 | ||
|
0924a824ee | ||
|
5ba9c49184 | ||
|
30de72a3fa | ||
|
1ce2c8e0dd | ||
|
547c57a428 | ||
|
2388dc018b | ||
|
713ed80bad | ||
|
58548711ed | ||
|
864fe6c7a9 | ||
|
099105860d | ||
|
5215dbe706 | ||
|
257c2548ce | ||
|
b701cf7dda | ||
|
b3ec9051ac | ||
|
8af1ed950a | ||
|
d0a95f33a9 | ||
|
d0617f0371 | ||
|
1b1610987d | ||
|
b17286c828 | ||
|
963e578ad1 | ||
|
8e90591121 | ||
|
363657dc88 | ||
|
be06a00250 | ||
|
cca59d4ceb | ||
|
f96562f267 | ||
|
87f413e313 | ||
|
4a0ec1c9e7 | ||
|
266fea2c80 | ||
|
3612f51c06 | ||
|
f5f19254e5 | ||
|
186547561e | ||
|
d40d5d4f67 | ||
|
99985a05d6 | ||
|
e01add895c | ||
|
a0015bf651 | ||
|
32e26806e4 | ||
|
c0430f7ecb | ||
|
a6a98b8bd6 | ||
|
f9e69c6e45 | ||
|
260940c8e8 | ||
|
2624f23bcf | ||
|
7fb081442c | ||
|
bf5ff099be | ||
|
d10120f86d | ||
|
1a2b9b3579 | ||
|
8ae929ffb7 | ||
|
fe4d37c0c9 | ||
|
79bb2fe388 | ||
|
a0b7670ae1 | ||
|
ea3adf3d58 | ||
|
b8b093c6c6 | ||
|
166e3d5b62 | ||
|
e73785c7d1 | ||
|
76408cade2 | ||
|
b8de94ff01 | ||
|
78e999923e | ||
|
af7dac18a3 | ||
|
9bd4f0ead5 | ||
|
722a1b1b18 | ||
|
a4ff7540b1 | ||
|
6b7ad302a6 | ||
|
1c1e6fa146 | ||
|
e0562da5d4 | ||
|
8806a7ebcb | ||
|
01caed9195 | ||
|
c1ffdee45d | ||
|
0664bfc974 | ||
|
623f4e5ec9 | ||
|
2d417a1f2c | ||
|
c6afab65ef | ||
|
07334069ef | ||
|
24dfcf8c66 | ||
|
881b233cda | ||
|
b14e0caeb0 | ||
|
c22f0aec99 | ||
|
65832329f9 | ||
|
b900737046 | ||
|
c5b83509e1 | ||
|
56eb94f016 | ||
|
e51cbc5754 | ||
|
8cdee1e1f6 | ||
|
a2519877b3 | ||
|
70cb17d4f8 | ||
|
3e2e60d3c8 | ||
|
40974f659c | ||
|
803c4f055f | ||
|
ef9b018ddb | ||
|
d1e72f6506 | ||
|
aead424c6d | ||
|
2183bc7c06 | ||
|
0fbcd39232 | ||
|
91a41505e6 | ||
|
0e09904170 | ||
|
4677a13af6 | ||
|
1c861b8a17 | ||
|
76969000f1 | ||
|
02c9c1492a | ||
|
692b1e4c1d | ||
|
6f218be5e5 | ||
|
a20b95df06 | ||
|
501e61eac5 | ||
|
4918a06be1 | ||
|
8d451b86e4 | ||
|
6d5cfeaee4 | ||
|
349271251b | ||
|
23dcfe6ed4 | ||
|
e470e44175 | ||
|
1a5457777b | ||
|
9a7fd2b601 | ||
|
2b78e77b5f | ||
|
ab253e8324 | ||
|
949cc2ab86 | ||
|
73fd838992 | ||
|
8f12572065 | ||
|
58bb058bd7 | ||
|
7fa9f05d2c | ||
|
cfe0712251 | ||
|
9e3483d1eb | ||
|
c504580dfd | ||
|
815a1c62ee | ||
|
8d3e4818c1 | ||
|
2c825d4e82 | ||
|
71f6c55dd8 | ||
|
0dfc9581fe | ||
|
c6d32decd8 | ||
|
0629312066 | ||
|
472f0ed53b | ||
|
61e6bd690c | ||
|
a355b9cb2c | ||
|
ee5aa24121 | ||
|
920fa75b0b | ||
|
67fca6c53a | ||
|
d1b0e6a962 | ||
|
662052e770 | ||
|
5f2a59894f | ||
|
2b8c6fb21c | ||
|
df8bbdc683 | ||
|
a7769a8c8a | ||
|
3eaf291bce | ||
|
fc3efc9cb8 | ||
|
2a575214b7 | ||
|
af44658439 | ||
|
f6de2ef50a | ||
|
2e48790719 | ||
|
5564aa7a64 | ||
|
c64eb24917 | ||
|
f8db5e59b1 | ||
|
c5e56d7eab | ||
|
b0fd87db53 | ||
|
702610785f | ||
|
baafcda4c1 | ||
|
b8a4ac0244 | ||
|
47d8944b5e | ||
|
bc66962660 | ||
|
837286e0fa | ||
|
d043147896 | ||
|
bc46d8af26 | ||
|
fb458e592a | ||
|
a3771a0646 | ||
|
e311c543d9 | ||
|
9f3448759c | ||
|
989e3b5aa1 | ||
|
b1f8aaf26c | ||
|
6fe5a3adba | ||
|
481601bbfd | ||
|
0cd842cc8b | ||
|
897e7c8cfe | ||
|
347ed353fa | ||
|
21c472e00f | ||
|
a2213e9426 | ||
|
3e02c781b5 | ||
|
6f4bae23ac | ||
|
1d9ae906bc | ||
|
3632502459 | ||
|
242772cb02 | ||
|
a5ea5b5e62 | ||
|
c9d048ca7c | ||
|
2c9dc342a0 | ||
|
1e90d3d312 | ||
|
9ed1242a49 | ||
|
d528b9b6af | ||
|
d24051bb3e | ||
|
1d7c7c268c | ||
|
a387d88820 | ||
|
e043c79207 | ||
|
1d60034c56 | ||
|
30a2539016 | ||
|
48a60f3867 | ||
|
767961a28a | ||
|
38f0698cd8 | ||
|
58d2a0384a | ||
|
4a967cbf9a | ||
|
73f96ea876 | ||
|
7ae4b34f2f | ||
|
b9f697bc08 | ||
|
a26b4664a6 | ||
|
282e7de36c | ||
|
96c0e2bcbd | ||
|
a8b15aec26 | ||
|
dcd06b69c5 | ||
|
e3d8a7804f | ||
|
187e921465 | ||
|
43dd75d9df | ||
|
0d0d3697ca | ||
|
77ad6c4813 | ||
|
baa8694612 | ||
|
f7e1c07560 | ||
|
d2e8755056 | ||
|
fb2a88bfc3 | ||
|
ca9ab67d07 | ||
|
fb8cfb7c61 | ||
|
dce918961b | ||
|
0002f7a010 | ||
|
bea994ee4d | ||
|
e65d046c41 | ||
|
b0179d7e20 | ||
|
f6d300f615 | ||
|
1e28d77b48 | ||
|
a9ea31075e | ||
|
c7953e1312 | ||
|
dee91bb37a | ||
|
38b5f28ab7 | ||
|
e91bfe56cc | ||
|
bb46d57f46 | ||
|
cbffeea396 | ||
|
4f5e67ba2e | ||
|
f05e1559d8 | ||
|
db569a0939 | ||
|
39eb6555f7 | ||
|
2f21b29665 | ||
|
4cec8dde7e | ||
|
2e674878d9 | ||
|
255dcb9fe1 | ||
|
1f79dd4157 | ||
|
3b849a8281 | ||
|
97ed1866da | ||
|
2f4da3d340 | ||
|
945d8ef72b | ||
|
818356a89a | ||
|
21cf2899df | ||
|
3dcd6770a8 | ||
|
568f0d16a6 | ||
|
546677c407 | ||
|
bf432fb10b | ||
|
ffe744d898 | ||
|
5c00001200 | ||
|
52d05908f7 | ||
|
fd3132f61c | ||
|
0fc58ab140 | ||
|
cb2d33751c | ||
|
acc485f633 | ||
|
f131a51289 | ||
|
e2053eada5 | ||
|
2a3426b293 | ||
|
48a88d2066 | ||
|
d91fc30862 | ||
|
68c282e29e | ||
|
ac8ba33a72 | ||
|
07cd96149d | ||
|
90570c10a7 | ||
|
a196d9382e | ||
|
63d9c009cc | ||
|
013b95aba2 | ||
|
efae8d7ed4 | ||
|
32890029d9 | ||
|
a92e4c2f65 | ||
|
728cee532e | ||
|
67237abbc9 | ||
|
c1144b3c7a | ||
|
7e50c5da70 | ||
|
0d1a7cfe15 | ||
|
7b26d4bdfd | ||
|
2e41d8bf78 | ||
|
9329250d5f | ||
|
bb9bca65a8 | ||
|
fab851c0b9 | ||
|
f19e89bd27 | ||
|
73a76f15c1 | ||
|
160b89e656 | ||
|
9897e722a2 | ||
|
92646a5761 | ||
|
d77e24512a | ||
|
570211f3a3 | ||
|
9f34fa3e8c | ||
|
84dc886dad | ||
|
903513718a | ||
|
485347b24e | ||
|
fe7feac336 | ||
|
699c1cc867 | ||
|
3d669abbd5 | ||
|
9110bf8689 | ||
|
12f66979e8 | ||
|
1c0c4fcda5 | ||
|
16d588f43b | ||
|
68d8ca49f7 | ||
|
3efb88af2e | ||
|
634c37a14a | ||
|
90e0a4b30b | ||
|
1882d35606 | ||
|
5bac958132 | ||
|
5ba6ace34d | ||
|
a1b81c3f76 | ||
|
9015edf1ab | ||
|
b87a6fd410 | ||
|
505d15996f | ||
|
6354834432 | ||
|
e90b149791 | ||
|
4f5ad790d0 | ||
|
798e155f5f | ||
|
440c88c78a | ||
|
daa167b646 | ||
|
7c28ceebeb | ||
|
d52a2dc3aa | ||
|
def314352e | ||
|
515d0bb7fc | ||
|
e96784f745 | ||
|
68cb22ed95 | ||
|
b83b4981b9 | ||
|
0d085be5c3 | ||
|
7f434e1034 | ||
|
ae39001aff | ||
|
0588093ba6 | ||
|
912bb2aa51 | ||
|
a17833c928 | ||
|
bd7e05a076 | ||
|
2d4bc9eb04 | ||
|
03a32aa6a9 | ||
|
217e56b9b3 | ||
|
88c28e999f | ||
|
2098fa906d | ||
|
2174d21fa5 | ||
|
5b2976c9ff | ||
|
e88699bdda | ||
|
f3609c9da7 | ||
|
dfb583a24c | ||
|
4576e1fdc7 | ||
|
42e40dd506 | ||
|
bc02e19bac | ||
|
5c004d9531 | ||
|
738b8bc985 | ||
|
1741ce2870 | ||
|
cee7062c01 | ||
|
5ea39fd30a | ||
|
b23c1a250e | ||
|
409df99df3 | ||
|
30b09221eb | ||
|
6ed2256b2c | ||
|
cce2deada0 | ||
|
c80f488d5d | ||
|
36d711eacd | ||
|
6603d92832 | ||
|
0c93bfe263 | ||
|
4c8b1f745b | ||
|
f1df9b6a70 | ||
|
42685943c9 | ||
|
19cd7252cf | ||
|
35646e689c | ||
|
4d1d3c5364 | ||
|
2b3f79b5bc | ||
|
779f6c5bbf | ||
|
ff43a28889 | ||
|
6d64f7def4 | ||
|
beb56d2419 | ||
|
6f76cf70f8 | ||
|
964af620e5 | ||
|
59d380ddb7 | ||
|
79d1039061 | ||
|
2bab256b39 | ||
|
51a9810228 | ||
|
2a0616e5ac | ||
|
a94bbc2690 | ||
|
86ffec5d08 | ||
|
8388c0fdca | ||
|
4eb321ec7d | ||
|
b8a78942bd | ||
|
361ba3e4aa | ||
|
0f6f6969a3 | ||
|
4f085244d4 | ||
|
2a02922765 | ||
|
443ab19f90 | ||
|
bc8937a111 | ||
|
863b273b69 | ||
|
67ddf4583d | ||
|
2f3cdbc3b0 | ||
|
fe6fec9515 | ||
|
95fdd11a1d | ||
|
1cc01ce611 | ||
|
817a9fac9b | ||
|
40fb13434d | ||
|
6092382dde | ||
|
bab9b5c973 | ||
|
db2b714389 | ||
|
5c6fadf040 | ||
|
137aabff89 | ||
|
18423b831e | ||
|
8416614d54 | ||
|
2bb907a8cf | ||
|
8e481f4ec5 | ||
|
a6996ee913 | ||
|
d6d51358a1 | ||
|
0286f22f21 | ||
|
d2df7af2a6 | ||
|
d2add56300 | ||
|
43edd23873 | ||
|
9079ba28ce | ||
|
3e1d1b82f7 | ||
|
3fac63c036 | ||
|
f1d1ba732e | ||
|
b35bd6dc64 | ||
|
1fed65b648 | ||
|
4cfe4bf743 | ||
|
1a4ae1d624 | ||
|
09e40fdbdf | ||
|
6a88a6af40 | ||
|
357181d8d5 | ||
|
4991c67481 | ||
|
8e67a3deed | ||
|
fcadb178f2 | ||
|
4253344cad | ||
|
de058dbdec | ||
|
61ba208ba7 | ||
|
27881cd704 | ||
|
3c6348eb59 | ||
|
846261492f | ||
|
ee81361a51 | ||
|
4f954fe55d | ||
|
530d63f802 | ||
|
a531ce875b | ||
|
69a4ff5e8e | ||
|
44e114fde2 | ||
|
08e1376e7c | ||
|
f9c5b3016c | ||
|
bec3a2e5e9 | ||
|
fa46761dbb | ||
|
d2e153814c | ||
|
88b92619bf | ||
|
ad1560f6db | ||
|
459c0a7fac | ||
|
33bd855dfe | ||
|
dcdbe5c4fe | ||
|
ec421cd1a4 | ||
|
a030b09087 | ||
|
2b4752e57b | ||
|
36649b6320 | ||
|
cb55a18759 | ||
|
a529faa53d | ||
|
e4fd2d671c | ||
|
1b14c22d4a | ||
|
a9dd0dd4e4 | ||
|
d88a0ba9bd | ||
|
452e51d75e | ||
|
c0094c23a0 |
44
.github/workflows/build.yml
vendored
Normal file
44
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
name: Build and Check Debian Package
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- develop
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build and Check Debian Package
|
||||
runs-on: ubuntu-24.04
|
||||
container:
|
||||
image: ubuntu:20.04
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install DKMS
|
||||
run: apt-get update && apt-get install -y -q --no-install-recommends debhelper devscripts dh-exec dkms dpkg
|
||||
shell: bash
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
|
||||
- name: Build Debian package
|
||||
run: dkms mkdeb --source-only
|
||||
shell: bash
|
||||
|
||||
- name: Check artifacts
|
||||
run: ls -l ../*.deb
|
||||
shell: bash
|
||||
|
||||
- name: Check install
|
||||
run: dpkg -i $(ls -1 ../*.deb | head -n 1)
|
||||
shell: bash
|
||||
|
||||
- name: Check dkms install
|
||||
run: apt-get install -y linux-headers-virtual
|
||||
shell: bash
|
||||
|
||||
- name: Check dkms result
|
||||
run: ls -l /lib/modules/*/updates/dkms/px4_drv.ko*
|
||||
shell: bash
|
51
.github/workflows/build_and_release.yml
vendored
Normal file
51
.github/workflows/build_and_release.yml
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
name: Build and Release Debian Package
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "*"
|
||||
|
||||
jobs:
|
||||
build_and_release:
|
||||
name: Build and Release Debian Package
|
||||
runs-on: ubuntu-24.04
|
||||
container:
|
||||
image: ubuntu:20.04
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install DKMS
|
||||
run: apt-get update && apt-get install -y -q --no-install-recommends debhelper devscripts dh-exec dkms dpkg
|
||||
shell: bash
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
|
||||
- name: Build Debian package
|
||||
run: dkms mkdeb --source-only
|
||||
shell: bash
|
||||
|
||||
- name: Check artifacts
|
||||
run: ls -l ../*.deb
|
||||
shell: bash
|
||||
|
||||
- name: Check install
|
||||
run: dpkg -i $(ls -1 ../*.deb | head -n 1)
|
||||
shell: bash
|
||||
|
||||
- name: Check dkms install
|
||||
run: apt-get install -y linux-headers-virtual
|
||||
shell: bash
|
||||
|
||||
- name: Check dkms result
|
||||
run: ls -l /lib/modules/*/updates/dkms/px4_drv.ko*
|
||||
shell: bash
|
||||
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
generate_release_notes: true
|
||||
files: |
|
||||
../*.deb
|
15
.gitignore
vendored
15
.gitignore
vendored
@@ -6,9 +6,22 @@ modules.order
|
||||
*.ko
|
||||
*.o.cmd
|
||||
*.ko.cmd
|
||||
*.symvers.cmd
|
||||
*.mod.cmd
|
||||
*.mod
|
||||
*.mod.c
|
||||
*.mod.o
|
||||
|
||||
*.bin
|
||||
/driver/revision.h
|
||||
/fwtool/fwtool
|
||||
|
||||
fwtool/*.bin
|
||||
*.sys
|
||||
*.zip
|
||||
|
||||
*.obj
|
||||
*.exe
|
||||
*.deb
|
||||
|
||||
.vscode/
|
||||
!.vscode/c_cpp_properties.json
|
||||
|
23
.vscode/c_cpp_properties.json
vendored
Normal file
23
.vscode/c_cpp_properties.json
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**",
|
||||
"/usr/src/linux-headers-*-generic/ubuntu/include",
|
||||
"/usr/src/linux-headers-*-generic/include/generated/uapi",
|
||||
"/usr/src/linux-headers-*-generic/arch/x86/include/generated/uapi",
|
||||
"/usr/src/linux-headers-*-generic/arch/x86/include/uapi",
|
||||
"/usr/src/linux-headers-*-generic/include",
|
||||
"/usr/src/linux-headers-*-generic/arch/x86/include/generated",
|
||||
"/usr/src/linux-headers-*-generic/include/uapi",
|
||||
"/usr/src/linux-headers-*-generic/arch/x86/include"
|
||||
],
|
||||
"intelliSenseMode": "linux-gcc-x64",
|
||||
"compilerPath": "/usr/bin/gcc",
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++17"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
58
README
58
README
@@ -1,58 +0,0 @@
|
||||
PLEX PX-W3U4/W3PE4/Q3PE4 Unofficial Linux driver
|
||||
|
||||
(現在開発中です。)
|
||||
|
||||
PLEX PX-W3U4/W3PE4/Q3PE4の非公式版Linux用ドライバです。
|
||||
PLEX社のWebサイト( http://plex-net.co.jp )にて配布されているドライバのソースコードではありませんのでご注意ください。
|
||||
|
||||
このドライバを使用するには、別途ファームウェアファイルを用意する必要があります。
|
||||
fwtoolを使用すると、簡単にファームウェアファイルを用意することができます。
|
||||
|
||||
このドライバの動作確認にはPX-W3U4とPX-Q3PE4を使用しています。
|
||||
|
||||
|
||||
[fwtoolを用いたファームウェアファイルの用意]
|
||||
|
||||
unzip, gcc, makeがインストールされている必要があります
|
||||
|
||||
$ cd fwtool
|
||||
$ make
|
||||
$ wget http://plex-net.co.jp/plex/pxw3u4/pxw3u4_BDA_ver1x64.zip -O pxw3u4_BDA_ver1x64.zip
|
||||
$ unzip -oj pxw3u4_BDA_ver1x64.zip pxw3u4_BDA_ver1x64/PXW3U4.sys
|
||||
$ ./fwtool PXW3U4.sys it930x-firmware.bin
|
||||
$ sudo mkdir -p /lib/firmware
|
||||
$ sudo cp it930x-firmware.bin /lib/firmware/
|
||||
$ cd ../
|
||||
|
||||
[ドライバのインストール]
|
||||
|
||||
gcc, make, カーネルソース/ヘッダがインストールされている必要があります
|
||||
|
||||
$ cd driver
|
||||
$ make
|
||||
$ sudo make install
|
||||
$ cd ../
|
||||
|
||||
ドライバがカーネルにロードされている状態で再度インストールを行った場合には以下を実行してください
|
||||
|
||||
$ sudo modprobe -r px4_drv
|
||||
$ sudo modprobe px4_drv
|
||||
|
||||
[ドライバのアンインストール]
|
||||
|
||||
$ cd driver
|
||||
$ sudo make uninstall
|
||||
$ cd ../
|
||||
|
||||
[ドライバのインストール (DKMS)]
|
||||
|
||||
gcc, make, カーネルソース/ヘッダ, dkmsがインストールされている必要があります
|
||||
|
||||
$ sudo cp -a ./ /usr/src/px4_drv-0.1.0
|
||||
$ sudo dkms add px4_drv/0.1.0
|
||||
$ sudo dkms install px4_drv/0.1.0
|
||||
|
||||
[ドライバのアンインストール (DKMS)]
|
||||
|
||||
$ sudo dkms remove px4_drv/0.1.0 --all
|
||||
$ sudo rm -rf /usr/src/px4_drv-0.1.0
|
470
README.md
Normal file
470
README.md
Normal file
@@ -0,0 +1,470 @@
|
||||
# px4_drv - Unofficial Linux / Windows (WinUSB) driver for PLEX PX4/PX5/PX-MLT series ISDB-T/S receivers
|
||||
|
||||
PLEX や e-Better から発売された各種 ISDB-T/S チューナー向けの chardev 版非公式 Linux ドライバ / Windows (WinUSB) ドライバです。
|
||||
PLEX 社の [Webサイト](http://plex-net.co.jp) にて配布されている公式ドライバとは**別物**です。
|
||||
|
||||
## このフォークについて
|
||||
|
||||
本家 [nns779/px4_drv](https://github.com/nns779/px4_drv) は 2021 年以降メンテナンスされておらず、残念ながら [nns779](https://github.com/nns779) 氏自身もネット上から失踪されています。
|
||||
このフォークは、各々のフォークに散逸していた有用な変更を一つにまとめ、継続的にメンテナンスしていくことを目的としています。
|
||||
|
||||
### 変更点 (WinUSB 版)
|
||||
|
||||
- エラー発生時の MessageBox を表示しない設定を追加
|
||||
- BonDriver の ini 内の `DisplayErrorMessage` を 1 に設定すると今まで通り MessageBox が表示される
|
||||
- BS/CS の ChSet に2024年10月~2025年1月に行われた BS トランスポンダ再編後の物理チャンネル情報を反映
|
||||
- [hendecarows 氏のフォーク](https://github.com/hendecarows/px4_drv) での更新を取り込み、DTV02A-1T1S-U / DTV03A-1TU / PX-M1UR / PX-S1UR に対応
|
||||
- PX-Q3PE5 の inf ファイルを追加
|
||||
- inf ファイルをより分かりやすい名前に変更
|
||||
- inf ファイルを ARM 版 Windows でもインストールできるようにする
|
||||
- 実機がないので試せていないけど、おそらくインストールできるはず
|
||||
- ref: https://mevius.5ch.net/test/read.cgi/avi/1625673548/762
|
||||
- inf ファイルを改善し、チューナーをタスクトレイの「ハードウェアの安全な取り外し」に表示しないようにする
|
||||
- ref: https://mevius.5ch.net/test/read.cgi/avi/1666581918/207
|
||||
- inf ファイルに自己署名を行い、自己署名証明書のインストールだけで正式なドライバーと認識されるように
|
||||
- 以前は署名がないためインストール時にドライバー署名の強制の無効化が必要だったが、事前に自己署名証明書を適切な証明書ストアにインストールしておけばこの作業が不要になる
|
||||
- ref: https://mevius.5ch.net/test/read.cgi/avi/1577466040/104-108
|
||||
- 自己署名証明書のインストール・アンインストールスクリプトを追加
|
||||
- 拡張子が .jse となっているが、これは PowerShell スクリプトにダブルクリックで実行させるための JScript コードを先頭の行に加えたもの
|
||||
- 実際に表示されないかは今のところ未確認
|
||||
- 地上波の ChSet に物理 53ch ~ 62ch の定義を追加
|
||||
- 物理 53ch ~ 62ch は地上波の割り当て周波数から削除されているが、現在も ”イッツコムch10” など、一部ケーブルテレビの自主放送の割り当て周波数として使われている
|
||||
- BS/CS の ChSet に2022年3月開局の BS 新チャンネル(BS松竹東急・BSJapanext・BSよしもと)の定義を追加
|
||||
- バージョン情報が DLL のプロパティに表示されないのを修正
|
||||
- ビルドとパッケージングを全自動で行うスクリプトを追加
|
||||
- Visual Studio 2019 が入っていれば、build.ps1 を実行するだけで全自動でビルドからパッケージングまで行える
|
||||
- README(このページ)に WinUSB 版のインストール方法などを追記
|
||||
|
||||
### 変更点 (Linux 版)
|
||||
|
||||
動作確認は Ubuntu 20.04 LTS (x64) で行っています。
|
||||
|
||||
- チップ構成が一部変更された、ロット番号 2309 (2023年9月) 以降の DTV02A-1T1S-U に対応
|
||||
- [otya 氏のフォーク](https://github.com/otya128/px4_drv) での更新を取り込み、安定性と互換性を改善
|
||||
- [techmadot 氏のフォーク](https://github.com/techmadot/px4_drv) の更新を取り込み、PX-M1UR / PX-S1UR に対応
|
||||
- [kznrluk 氏のフォーク](https://github.com/kznrluk/px4_drv) の更新を取り込み、Linux カーネル 6.4 系以降の API 変更に対応
|
||||
- [hendecarows 氏のフォーク](https://github.com/hendecarows/px4_drv) での更新を取り込み、DTV03A-1TU に対応
|
||||
- https://github.com/tsukumijima/px4_drv/pull/6 をマージし、Linux カーネル 6.8 系以降の API 変更に対応
|
||||
- https://github.com/tsukumijima/px4_drv/pull/3 をマージし、`ctrl_timeout` をモジュールパラメーターに追加
|
||||
- Debian パッケージ (.deb) の作成とインストールに対応
|
||||
- DKMS でのインストール時にファームウェアを自動でインストールするように変更
|
||||
- README (このページ) に Debian パッケージからのインストール方法などを追記
|
||||
|
||||
## 対応デバイス
|
||||
|
||||
- PLEX
|
||||
|
||||
- PX-W3U4
|
||||
- PX-Q3U4
|
||||
- PX-W3PE4
|
||||
- PX-Q3PE4
|
||||
- PX-W3PE5
|
||||
- PX-Q3PE5
|
||||
- PX-MLT5PE
|
||||
- PX-MLT8PE
|
||||
- PX-M1UR
|
||||
- PX-S1UR
|
||||
|
||||
- e-Better
|
||||
|
||||
- DTV02-1T1S-U (実験的)
|
||||
- DTV02A-1T1S-U
|
||||
- チップ構成が一部変更された、ロット番号 2309 (2023年9月) 以降の DTV02A-1T1S-U にも対応しています。
|
||||
手元の実機では問題なく動作していますが、長期間の動作テストは行えていないため、未知の不具合があるかもしれません。
|
||||
- DTV02A-4TS-P
|
||||
- DTV03A-1TU (実験的)
|
||||
- チップ構成が大幅に変更された、ロット番号 2021-11 以降の個体のみ対応しています。
|
||||
|
||||
> [!NOTE]
|
||||
> 2021 年以降メンテナンスされていない [nns779/px4_drv](https://github.com/nns779/px4_drv) と異なり、新規に下記チューナーのサポートを追加しています。
|
||||
>
|
||||
> - PLEX PX-M1UR
|
||||
> - PLEX PX-S1UR
|
||||
> - e-Better DTV02A-1T1S-U / Digibest ISDB2056 (Windows 版ドライバを新規追加)
|
||||
> - e-Better DTV02A-1T1S-U (ロット番号 2309 以降) / Digibest ISDB2056N
|
||||
> - e-Better DTV03A-1TU / Digibest ISDBT2071 (ロット番号 2021-11 以降)
|
||||
|
||||
> [!WARNING]
|
||||
> PX-M1UR または DTV02(A)-1T1S-U で CATV(周波数変換パススルー)の ISDB-T C13ch ~ C24ch を受信するには、[専用の recpt1 フォーク (hendecarows/recpt1)](https://github.com/hendecarows/recpt1) が必要となります。
|
||||
> [stz2012/recpt1](https://github.com/stz2012/recpt1) や [recisdb](https://github.com/kazuki0824/recisdb-rs) では、当該機種にて C13ch ~ C62ch を正常に選局できないことが報告されています([詳細はこちら](https://github.com/tsukumijima/px4_drv/issues/16))。
|
||||
> ただし、C13ch ~ C24ch 以外のチャンネルであれば、stz2012/recpt1 や recisdb でも問題なく選局・受信が可能です。
|
||||
|
||||
## インストール (Windows)
|
||||
|
||||
Windows (WinUSB) 版のドライバは、OS にチューナーを認識させるための inf ファイルと、px4_drv 専用の BonDriver、ドライバの実体でチューナー操作を司る DriverHost_PX4 から構成されています。
|
||||
|
||||
ビルド済みのアーカイブは [こちら](https://github.com/tsukumijima/DTV-Builds) からダウンロードできます。
|
||||
または、winusb フォルダにある build.ps1 を実行して、ご自分でビルドしたものを使うこともできます (Visual Studio 2019 が必要です) 。
|
||||
|
||||
### 1. 自己署名証明書のインストール
|
||||
|
||||
Driver フォルダには、各機種ごとのドライバのインストールファイル (.inf) が配置されています。
|
||||
ドライバをインストールする前に cert-install.jse を実行し、自己署名証明書をインストールしてください。
|
||||
|
||||
自己署名証明書をインストールして信頼することで、自己署名証明書を使用して署名されたドライバも、(自己署名証明書をアンインストールするまでは)通常の署名付きドライバと同様に信頼されるようになります。
|
||||
|
||||
### 2. ドライバのインストール
|
||||
|
||||
自己署名証明書をインストールしたあとは、公式ドライバと同様の手順でインストールできると思います(公式ドライバは事前にアンインストールしてください)。
|
||||
|
||||
具体的には、デバイスマネージャーからチューナーデバイスを選択し、右クリックメニューの [ドライバーの更新] → [コンピューターを参照してドライバーを検索] から、inf ファイルが入っている Driver フォルダを指定してください。[ドライバーが正常に更新されました] と表示されていれば OK です。
|
||||
|
||||
### 3. BonDriver の配置
|
||||
|
||||
チューナーの機種に応じた BonDriver を配置します。
|
||||
|
||||
- PX4/PX5 シリーズの機種: `BonDriver_PX4`
|
||||
- PX-MLT シリーズの機種・DTV02A-4TS-P: `BonDriver_PX-MLT`
|
||||
- DTV02A-1T1S-U: `BonDriver_ISDB2056`
|
||||
- DTV02A-1T1S-U (ロット番号 2309 以降): `BonDriver_ISDB2056N`
|
||||
- DTV03A-1TU: `BonDriver_ISDBT2071`
|
||||
- PX-M1UR: `BonDriver_PX-M1UR`
|
||||
- PX-S1UR: `BonDriver_PX-S1UR`
|
||||
|
||||
お使いの PC に合うビット数のフォルダの中のファイルを**すべて**選択し、TVTest や EDCB などのソフトウェアが指定する BonDriver の配置フォルダにコピーします。
|
||||
BonDriver と同じフォルダに DriverHost_PX4.exe / DriverHost_PX4.ini / it930x-firmware.bin があることを確認してください。
|
||||
|
||||
使用にあたり、特段 ini ファイルの設定変更などは必要ありません。ソフトウェアごとにチャンネルスキャンを行えばそのまま視聴できます。
|
||||
なお、BonDriver の ini ファイル内の `DisplayErrorMessage` を 1 に設定すると、オリジナル同様にエラー発生時にメッセージボックスを表示します。
|
||||
|
||||
## インストール (Linux)
|
||||
|
||||
### 1. ファームウェアの抽出とインストール (手動インストール時のみ)
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **px4_drv を Debian パッケージや DKMS を使用してインストールする際、ファームウェアは自動的にインストールされます。**
|
||||
> **Debian パッケージや DKMS を使用してインストールを行う場合は、この手順をスキップしてください。**
|
||||
|
||||
事前に unzip, gcc, make がインストールされている必要があります。
|
||||
|
||||
$ cd fwtool
|
||||
$ make
|
||||
$ wget http://plex-net.co.jp/plex/pxw3u4/pxw3u4_BDA_ver1x64.zip -O pxw3u4_BDA_ver1x64.zip
|
||||
$ unzip -oj pxw3u4_BDA_ver1x64.zip pxw3u4_BDA_ver1x64/PXW3U4.sys && rm pxw3u4_BDA_ver1x64.zip
|
||||
$ ./fwtool PXW3U4.sys it930x-firmware.bin && rm PXW3U4.sys
|
||||
$ sudo mkdir -p /lib/firmware && sudo cp it930x-firmware.bin /lib/firmware/
|
||||
$ cd ../
|
||||
|
||||
または、抽出済みのファームウェアを利用することもできます。
|
||||
|
||||
$ sudo mkdir -p /lib/firmware && sudo cp ./etc/it930x-firmware.bin /lib/firmware/
|
||||
|
||||
### 2. ドライバのインストール
|
||||
|
||||
一部の Linux ディストリビューションでは、別途 udev のインストールが必要になる場合があります。
|
||||
|
||||
#### Debian パッケージを使用してインストール (強く推奨)
|
||||
|
||||
Debian パッケージを使用してインストールすると依存パッケージも自動インストールされるほか、DKMS のソースコード管理も透過的に行われます。
|
||||
Ubuntu / Debian 環境では Debian パッケージを使用してインストールすることを強く推奨します。
|
||||
|
||||
$ wget https://github.com/tsukumijima/px4_drv/releases/download/v0.5.4/px4-drv-dkms_0.5.4_all.deb
|
||||
$ sudo apt install -y ./px4-drv-dkms_0.5.4_all.deb
|
||||
|
||||
上記コマンドで、px4_drv の Debian パッケージをインストールできます。
|
||||
|
||||
> [!TIP]
|
||||
手動で Debian パッケージを生成することもできます。
|
||||
> `./build_deb.sh` を実行すると、`./build_deb.sh` の一つ上層のディレクトリに `px4-drv-dkms_0.5.4_all.deb` という名前の Debian パッケージが生成されます。
|
||||
> ```
|
||||
> $ ./build_deb.sh
|
||||
> $ sudo apt install -y ../px4-drv-dkms_0.5.4_all.deb
|
||||
> ```
|
||||
> 上記コマンドで、生成した px4_drv の Debian パッケージをインストールできます。
|
||||
|
||||
#### DKMS を使用してインストールする
|
||||
|
||||
gcc, make, カーネルソース/ヘッダ, dkms がインストールされている必要があります。
|
||||
|
||||
$ sudo cp -a ./ /usr/src/px4_drv-0.5.4
|
||||
$ sudo dkms add px4_drv/0.5.4
|
||||
$ sudo dkms install px4_drv/0.5.4
|
||||
|
||||
#### DKMS を使用せずにインストールする
|
||||
|
||||
事前に gcc, make, カーネルソース/ヘッダがインストールされている必要があります。
|
||||
|
||||
> [!WARNING]
|
||||
> DKMS を使用せずにインストールした場合、**カーネルのアップデート時にドライバが自動で再ビルドされないため、アップデート後に再度インストールを行う必要があります。**
|
||||
> **可能な限り DKMS を使用してインストールすることをおすすめします。**
|
||||
|
||||
$ cd driver
|
||||
$ make
|
||||
$ sudo make install
|
||||
$ cd ../
|
||||
|
||||
### 3. 確認
|
||||
|
||||
#### 3.1 カーネルモジュールのロードの確認
|
||||
|
||||
**下記のコマンドを実行し、`px4_drv` から始まる行が表示されれば、カーネルモジュールが正常にロードされています。**
|
||||
|
||||
$ lsmod | grep -e ^px4_drv
|
||||
px4_drv 81920 0
|
||||
|
||||
**何も表示されない場合は、下記のコマンドでカーネルモジュールを明示的にロードしてから、再度上記のコマンドを実行して確認を行ってください。**
|
||||
|
||||
$ sudo modprobe px4_drv
|
||||
|
||||
それでもカーネルモジュールが正常にロードされない場合は、インストールから再度やり直してください。
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **px4_drv や Linux カーネルの更新後、px4_drv は自動再ロードされない場合があります。**
|
||||
> **px4_drv や Linux カーネルを更新した際は、可能な限りすぐに PC を再起動することを強く推奨します。**
|
||||
> すぐに再起動ができない状況では、必ず `sudo modprobe px4_drv` を実行してください。
|
||||
> (当然ですが、録画予約のある時間帯に px4_drv や Linux カーネルを更新するべきではありません。)
|
||||
|
||||
#### 3.2 デバイスファイルの確認
|
||||
|
||||
インストールに成功し、カーネルモジュールがロードされた状態でデバイスが接続されると、`/dev/` 以下にデバイスファイルが作成されます。
|
||||
下記のようなコマンドで確認できます。
|
||||
|
||||
##### PLEX PX-W3U4/W3PE4/W3PE5 を接続した場合
|
||||
|
||||
$ ls /dev/px4video*
|
||||
/dev/px4video0 /dev/px4video1 /dev/px4video2 /dev/px4video3
|
||||
|
||||
チューナーは、`px4video0` から ISDB-S, ISDB-S, ISDB-T, ISDB-T というように、SとTが2つずつ交互に割り当てられます。
|
||||
|
||||
##### PLEX PX-Q3U4/Q3PE4/Q3PE5 を接続した場合
|
||||
|
||||
$ ls /dev/px4video*
|
||||
/dev/px4video0 /dev/px4video2 /dev/px4video4 /dev/px4video6
|
||||
/dev/px4video1 /dev/px4video3 /dev/px4video5 /dev/px4video7
|
||||
|
||||
チューナーは、`px4video0` から ISDB-S, ISDB-S, ISDB-T, ISDB-T, ISDB-S, ISDB-S, ISDB-T, ISDB-T というように、S と T が2つずつ交互に割り当てられます。
|
||||
|
||||
##### PLEX PX-MLT5PE を接続した場合
|
||||
|
||||
$ ls /dev/pxmlt5video*
|
||||
/dev/pxmlt5video0 /dev/pxmlt5video2 /dev/pxmlt5video4
|
||||
/dev/pxmlt5video1 /dev/pxmlt5video3
|
||||
|
||||
すべてのチューナーにおいて、ISDB-T と ISDB-S のどちらも受信可能です。
|
||||
|
||||
##### PLEX PX-MLT8PE を接続した場合
|
||||
|
||||
$ ls /dev/pxmlt8video*
|
||||
/dev/pxmlt8video0 /dev/pxmlt8video3 /dev/pxmlt8video6
|
||||
/dev/pxmlt8video1 /dev/pxmlt8video4 /dev/pxmlt8video7
|
||||
/dev/pxmlt8video2 /dev/pxmlt8video5
|
||||
|
||||
すべてのチューナーにおいて、ISDB-T と ISDB-S のどちらも受信可能です。
|
||||
|
||||
##### PLEX PX-M1UR を接続した場合
|
||||
|
||||
$ ls /dev/pxm1urvideo*
|
||||
/dev/pxm1urvideo0
|
||||
|
||||
すべてのチューナーにおいて、ISDB-T と ISDB-S のどちらも受信可能です。
|
||||
|
||||
##### PLEX PX-S1UR を接続した場合
|
||||
|
||||
$ ls /dev/pxs1urvideo*
|
||||
/dev/pxs1urvideo0
|
||||
|
||||
すべてのチューナーにおいて、ISDB-T のみ受信可能です。
|
||||
|
||||
##### e-Better DTV03A-1TU を接続した場合
|
||||
|
||||
$ ls /dev/isdbt2071video*
|
||||
/dev/isdbt2071video0
|
||||
|
||||
すべてのチューナーにおいて、ISDB-T のみ受信可能です。
|
||||
|
||||
##### e-Better DTV02-1T1S-U/DTV02A-1T1S-U を接続した場合
|
||||
|
||||
$ ls /dev/isdb2056video*
|
||||
/dev/isdb2056video0
|
||||
|
||||
すべてのチューナーにおいて、ISDB-T と ISDB-S のどちらも受信可能です。
|
||||
|
||||
> [!NOTE]
|
||||
> ロット番号 2309 以降の DTV02A-1T1S-U を接続した場合でも、デバイスファイル名は `/dev/isdb2056video*` となります。
|
||||
> `/dev/isdb2056nvideo*` ではないので注意してください。
|
||||
|
||||
##### e-Better DTV02A-4TS-P を接続した場合
|
||||
|
||||
$ ls /dev/isdb6014video*
|
||||
/dev/isdb6014video0 /dev/isdb6014video2
|
||||
/dev/isdb6014video1 /dev/isdb6014video3
|
||||
|
||||
すべてのチューナーにおいて、ISDB-T と ISDB-S のどちらも受信可能です。
|
||||
|
||||
## アンインストール (Windows)
|
||||
|
||||
### 1. ドライバのアンインストール
|
||||
|
||||
デバイスマネージャーからチューナーデバイス( PLEX PX-W3PE5 ISDB-T/S Receiver Device (WinUSB) のような名前)を選択します。
|
||||
その後、右クリックメニュー → [デバイスのアンインストール] から、[このデバイスのドライバー ソフトウェアを削除します] にチェックを入れて、ドライバをアンインストールしてください。
|
||||
|
||||
### 2. 自己署名証明書のアンインストール
|
||||
|
||||
ドライバのインストール時にインストールした自己署名証明書をアンインストールするには、cert-uninstall.jse を実行します。アンインストールするとドライバが信頼されなくなってしまうので、十分注意してください。
|
||||
|
||||
## アンインストール (Linux)
|
||||
|
||||
### 1. ドライバのアンインストール
|
||||
|
||||
#### Debian パッケージを使用してインストールした場合
|
||||
|
||||
$ sudo apt purge px4-drv-dkms
|
||||
|
||||
#### DKMS を使用してインストールした場合
|
||||
|
||||
$ sudo dkms remove px4_drv/0.5.4 --all
|
||||
$ sudo rm -rf /usr/src/px4_drv-0.5.4
|
||||
|
||||
#### DKMS を使用せずにインストールした場合
|
||||
|
||||
$ sudo modprobe -r px4_drv
|
||||
$ cd driver
|
||||
$ sudo make uninstall
|
||||
$ cd ../
|
||||
|
||||
### 2. ファームウェアのアンインストール
|
||||
|
||||
> [!NOTE]
|
||||
> **px4_drv を Debian パッケージや DKMS を使用してインストールした場合、ファームウェアは自動的にアンインストールされます。**
|
||||
> Debian パッケージや DKMS を使用してインストールを行った場合は、この手順はスキップしてください。
|
||||
|
||||
$ sudo rm /lib/firmware/it930x-firmware.bin
|
||||
|
||||
## 受信方法
|
||||
|
||||
### Windows
|
||||
|
||||
チューナーの機種に応じた BonDriver とその設定ファイルを配置し、TVTest や EDCB などの BonDriver に対応したソフトウェアで使用することで、TS データを受信することが可能です。
|
||||
|
||||
BonDriver は専用のものが必要になるため、公式 (Jacky版) BonDriver や radi-sh 氏版 BonDriver_BDA と併用することはできません。
|
||||
|
||||
### Linux
|
||||
|
||||
recpt1 や [BonDriverProxy_Linux](https://github.com/u-n-k-n-o-w-n/BonDriverProxy_Linux) 等の PT シリーズ用 chardev ドライバに対応したソフトウェアを使用することで、TS データを受信することが可能です。
|
||||
recpt1 は、PLEX 社より配布されているものを使用する必要はありません。
|
||||
|
||||
BonDriverProxy_Linux と、PLEX PX-MLT5PE や e-Better DTV02A-1T1S-U などのデバイスファイル1つで ISDB-T と ISDB-S のどちらも受信可能なチューナーを組み合わせて使用する場合は、BonDriver として BonDriverProxy_Linux に同梱されている BonDriver_LinuxPT の代わりに、[BonDriver_LinuxPTX](https://github.com/nns779/BonDriver_LinuxPTX) を使用してください。
|
||||
|
||||
## LNB電源の出力
|
||||
|
||||
### PLEX PX-W3U4/Q3U4/W3PE4/Q3PE4
|
||||
|
||||
出力なしと 15V の出力のみに対応しています。デフォルトでは LNB 電源の出力を行いません。
|
||||
LNB 電源の出力を行うには、recpt1 を実行する際のパラメータに `--lnb 15` を追加してください。
|
||||
|
||||
Windows では、BonDriver_PX4-S.ini に記載の `LNBPower=0` を `LNBPower=1` に変更してください。
|
||||
|
||||
### PLEX PX-W3PE5/Q3PE5
|
||||
|
||||
出力なしと 15V の出力のみに対応しているものと思われます。
|
||||
|
||||
### PLEX PX-MLT5PE/MLT8PE
|
||||
|
||||
対応していないものとされていましたが、5ch の有志により、正しく LNB 電源を出力できることが確認されています ([参考](https://mevius.5ch.net/test/read.cgi/avi/1648542476/267-288))。
|
||||
|
||||
### PLEX PX-M1UR / e-Better DTV02-1T1S-U/DTV02A-1T1S-U
|
||||
|
||||
対応しておりません。
|
||||
|
||||
### e-Better DTV02A-4TS-P
|
||||
|
||||
対応していると思われます。
|
||||
|
||||
## 備考
|
||||
|
||||
### 内蔵カードリーダーやリモコンについて
|
||||
|
||||
このドライバは、各種対応デバイスに内蔵されているカードリーダーやリモコンの操作には対応していません。
|
||||
また、今後対応を行う予定もありません。ご了承ください。
|
||||
|
||||
### e-Better DTV02-1T1S-U について
|
||||
|
||||
e-Better DTV02-1T1S-U は、個体によりデバイスからの応答が無くなることのある不具合が各所にて多数報告されています。そのため、このドライバでは「実験的な対応」とさせていただいております。
|
||||
上記の不具合はこの非公式ドライバでも完全には解消できないと思われますので、その点は予めご了承ください。
|
||||
|
||||
### e-Better DTV02A-1T1S-U について
|
||||
|
||||
e-better DTV02A-1T1S-U は、DTV02-1T1S-U に存在した上記の不具合がハードウェアレベルで修正されています。そのため、このドライバでは「正式な対応」とさせていただいております。
|
||||
|
||||
## 技術情報
|
||||
|
||||
### デバイスの構成
|
||||
|
||||
PX-W3PE4/Q3PE4/MLT5PE/MLT8PE, e-Better DTV02A-4TS-P は、電源の供給を PCIe スロットから受け、データのやり取りを USB を介して行います。
|
||||
PX-W3PE5/Q3PE5 は、PX-W3PE4/Q3PE4 相当の基板に PCIe→USB ブリッジチップを追加し、USB ケーブルを不要とした構造となっています。
|
||||
PX-Q3U4/Q3PE4 は、PX-W3U4/W3PE4 相当のデバイスが USB ハブを介して2つぶら下がる構造となっています。
|
||||
|
||||
- PX-W3U4/W3PE4
|
||||
|
||||
- USB Bridge: ITE IT9305E
|
||||
- ISDB-T/S Demodulator: Toshiba TC90522XBG
|
||||
- Terrestrial Tuner: RafaelMicro R850 (x2)
|
||||
- Satellite Tuner: RafaelMicro RT710 (x2)
|
||||
|
||||
- PX-Q3U4/Q3PE4
|
||||
|
||||
- USB Bridge: ITE IT9305E (x2)
|
||||
- ISDB-T/S Demodulator: Toshiba TC90522XBG (x2)
|
||||
- Terrestrial Tuner: RafaelMicro R850 (x4)
|
||||
- Satellite Tuner: RafaelMicro RT710 (x4)
|
||||
|
||||
- PX-W3PE5
|
||||
|
||||
- PCIe to USB Bridge: ASIX MCS9990CV-AA
|
||||
- USB Bridge: ITE IT9305E
|
||||
- ISDB-T/S Demodulator: Toshiba TC90522XBG
|
||||
- Terrestrial Tuner: RafaelMicro R850 (x2)
|
||||
- Satellite Tuner: RafaelMicro RT710 (x2)
|
||||
|
||||
- PX-Q3PE5
|
||||
|
||||
- PCIe to USB Bridge: ASIX MCS9990CV-AA
|
||||
- USB Bridge: ITE IT9305E (x2)
|
||||
- ISDB-T/S Demodulator: Toshiba TC90522XBG (x2)
|
||||
- Terrestrial Tuner: RafaelMicro R850 (x4)
|
||||
- Satellite Tuner: RafaelMicro RT710 (x4)
|
||||
|
||||
PX-MLT8PE は、同一基板上に PX-MLT5PE 相当のデバイスと、3チャンネル分のチューナーを持つデバイスが実装されている構造となっています。
|
||||
|
||||
- PX-MLT5PE/MLT8PE5
|
||||
|
||||
- USB Bridge: ITE IT9305E
|
||||
- ISDB-T/S Demodulator: Sony CXD2856ER (x5)
|
||||
- Terrestrial/Satellite Tuner: Sony CXD2858ER (x5)
|
||||
|
||||
- PX-MLT8PE3
|
||||
|
||||
- USB Bridge: ITE IT9305E
|
||||
- ISDB-T/S Demodulator: Sony CXD2856ER (x3)
|
||||
- Terrestrial/Satellite Tuner: Sony CXD2858ER (x3)
|
||||
|
||||
DTV02-1T1S-U/DTV02A-1T1S-U は、ISDB-T 側の TS シリアル出力を ISDB-S 側と共有しています。そのため、同時に受信できるチャンネル数は1チャンネルのみです。
|
||||
|
||||
- DTV02-1T1S-U/DTV02A-1T1S-U (ロット番号 2309 以前: Digibest ISDB2056)
|
||||
|
||||
- USB Bridge: ITE IT9303FN
|
||||
- ISDB-T/S Demodulator: Toshiba TC90532XBG
|
||||
- Terrestrial Tuner: RafaelMicro R850
|
||||
- Satellite Tuner: RafaelMicro RT710
|
||||
|
||||
ロット番号 2309 (2023年9月) 以降の DTV02A-1T1S-U では、ISDB-T/S Demodulator IC が TC90532XBG (ISDB-T×1TS + ISDB-S×1TS) から TC90522XBG (ISDB-T×2TS + ISDB-S×2TS) に変更されています。([詳細](https://web.archive.org/web/20130513083035/http://www.semicon.toshiba.co.jp/product/new_products/assp/1275558_37644.html))
|
||||
この変更に伴い、内部名称が ISDB2056 から ISDB2056N に変更されています。
|
||||
|
||||
- DTV02A-1T1S-U (ロット番号 2309 以降: Digibest ISDB2056N)
|
||||
|
||||
- USB Bridge: ITE IT9303FN
|
||||
- ISDB-T/S Demodulator: Toshiba TC90522XBG (TC90532XBG -> TC90522XBG)
|
||||
- Terrestrial Tuner: RafaelMicro R850
|
||||
- Satellite Tuner: RafaelMicro RT710
|
||||
|
||||
DTV02A-4TS-P は、PX-MLT5PE から1チャンネル分のチューナーを削減した構造となっています。
|
||||
|
||||
- DTV02A-4TS-P (Digibest ISDB6014)
|
||||
|
||||
- USB Bridge: ITE IT9305E
|
||||
- ISDB-T/S Demodulator: Sony CXD2856ER (x4)
|
||||
- Terrestrial/Satellite Tuner: Sony CXD2858ER (x4)
|
||||
|
||||
### TS Aggregation の設定
|
||||
|
||||
sync_byte をデバイス側で書き換え、ホスト側でその値を元にそれぞれのチューナーの TS データを振り分けるモードを使用しています。
|
9
build_deb.sh
Executable file
9
build_deb.sh
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -CEuo pipefail
|
||||
|
||||
# Prep
|
||||
sudo apt-get install -y debhelper devscripts dh-exec dkms dpkg
|
||||
|
||||
# Build dkms deb
|
||||
dkms mkdeb --source-only
|
@@ -1,10 +1,10 @@
|
||||
PACKAGE_NAME="px4_drv"
|
||||
PACKAGE_VERSION="0.1.0"
|
||||
PACKAGE_VERSION="0.5.4"
|
||||
CLEAN="cd ./driver; make clean"
|
||||
MAKE="cd ./driver; make KVER=${kernelver} px4_drv.ko"
|
||||
BUILT_MODULE_LOCATION="driver"
|
||||
BUILT_MODULE_NAME="px4_drv"
|
||||
DEST_MODULE_LOCATION="/updates/dkms"
|
||||
POST_INSTALL="dkms/post_install"
|
||||
POST_REMOVE="dkms/post_remove"
|
||||
POST_INSTALL="dkms/post_install.sh"
|
||||
POST_REMOVE="dkms/post_remove.sh"
|
||||
AUTOINSTALL="yes"
|
||||
|
@@ -1,3 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
rm -fv /etc/udev/rules.d/90-px4.rules
|
||||
install -D -v -m 644 ./etc/99-px4video.rules /etc/udev/rules.d/99-px4video.rules
|
||||
install -D -v -m 644 ./etc/it930x-firmware.bin /lib/firmware/it930x-firmware.bin
|
@@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
if [ `find /lib/modules/ -name px4_drv.ko | wc -l` -eq 0 ]; then
|
||||
rm -fv /etc/udev/rules.d/90-px4.rules /etc/udev/rules.d/99-px4video.rules
|
||||
fi
|
6
dkms/post_remove.sh
Executable file
6
dkms/post_remove.sh
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ `find /lib/modules/ -name 'px4_drv.ko*' | wc -l` -eq 0 ]; then
|
||||
rm -fv /etc/udev/rules.d/90-px4.rules /etc/udev/rules.d/99-px4video.rules
|
||||
rm -fv /lib/firmware/it930x-firmware.bin
|
||||
fi
|
54
driver/Kbuild
Normal file
54
driver/Kbuild
Normal file
@@ -0,0 +1,54 @@
|
||||
# Kbuild for px4_drv
|
||||
|
||||
DEBUG := 0
|
||||
|
||||
PX4_USB_MAX_DEVICE := 0
|
||||
PXMLT5_USB_MAX_DEVICE := 0
|
||||
PXMLT8_USB_MAX_DEVICE := 0
|
||||
ISDB2056_USB_MAX_DEVICE := 0
|
||||
ISDB6014_4TS_USB_MAX_DEVICE := 0
|
||||
PXM1UR_USB_MAX_DEVICE := 0
|
||||
PXS1UR_USB_MAX_DEVICE := 0
|
||||
ISDBT2071_USB_MAX_DEVICE := 0
|
||||
PSB_DEBUG := 0
|
||||
ITEDTV_BUS_USE_WORKQUEUE := 0
|
||||
|
||||
ccflags-y := -I$(M)/../include
|
||||
|
||||
ifneq ($(DEBUG),0)
|
||||
ccflags-y += -DDEBUG -g
|
||||
endif
|
||||
|
||||
ifneq ($(PX4_USB_MAX_DEVICE),0)
|
||||
ccflags-y += -DPX4_USB_MAX_DEVICE=$(PX4_USB_MAX_DEVICE)
|
||||
endif
|
||||
ifneq ($(PXMLT5_USB_MAX_DEVICE),0)
|
||||
ccflags-y += -DPXMLT5_USB_MAX_DEVICE=$(PXMLT5_USB_MAX_DEVICE)
|
||||
endif
|
||||
ifneq ($(PXMLT8_USB_MAX_DEVICE),0)
|
||||
ccflags-y += -DPXMLT8_USB_MAX_DEVICE=$(PXMLT8_USB_MAX_DEVICE)
|
||||
endif
|
||||
ifneq ($(ISDB2056_USB_MAX_DEVICE),0)
|
||||
ccflags-y += -DISDB2056_USB_MAX_DEVICE=$(ISDB2056_USB_MAX_DEVICE)
|
||||
endif
|
||||
ifneq ($(ISDB6014_4TS_USB_MAX_DEVICE),0)
|
||||
ccflags-y += -DISDB6014_4TS_USB_MAX_DEVICE=$(ISDB6014_4TS_USB_MAX_DEVICE)
|
||||
endif
|
||||
ifneq ($(PXM1UR_USB_MAX_DEVICE),0)
|
||||
ccflags-y += -DPXM1UR_USB_MAX_DEVICE=$(PXM1UR_USB_MAX_DEVICE)
|
||||
endif
|
||||
ifneq ($(PXS1UR_USB_MAX_DEVICE),0)
|
||||
ccflags-y += -DPXS1UR_USB_MAX_DEVICE=$(PXS1UR_USB_MAX_DEVICE)
|
||||
endif
|
||||
ifneq ($(ISDBT2071_USB_MAX_DEVICE),0)
|
||||
ccflags-y += -DISDBT2071_USB_MAX_DEVICE=$(ISDBT2071_USB_MAX_DEVICE)
|
||||
endif
|
||||
ifneq ($(PSB_DEBUG),0)
|
||||
ccflags-y += -DPSB_DEBUG
|
||||
endif
|
||||
ifneq ($(ITEDTV_BUS_USE_WORKQUEUE),0)
|
||||
ccflags-y += -DITEDTV_BUS_USE_WORKQUEUE
|
||||
endif
|
||||
|
||||
obj-m := px4_drv.o
|
||||
px4_drv-y := driver_module.o ptx_chrdev.o px4_usb.o px4_usb_params.o px4_device.o px4_device_params.o px4_mldev.o pxmlt_device.o isdb2056_device.o it930x.o itedtv_bus.o tc90522.o r850.o rt710.o cxd2856er.o cxd2858er.o ringbuffer.o s1ur_device.o m1ur_device.o
|
@@ -1,39 +1,28 @@
|
||||
KVER := $(shell uname -r)
|
||||
KBUILD_DIR := /lib/modules/$(KVER)/build
|
||||
INSTALL_DIR := /lib/modules/$(KVER)/misc
|
||||
CURRENT_DIR := $(shell pwd)
|
||||
VERBOSE := 0
|
||||
DEBUG := 0
|
||||
TARGET := px4_drv.ko
|
||||
# Makefile for px4_drv
|
||||
|
||||
drv-MAX_DEVICE := 0
|
||||
KVER := $(shell uname -r)
|
||||
KDIR := /lib/modules/$(KVER)/build
|
||||
PWD := $(shell pwd)
|
||||
INSTALL_DIR := /lib/modules/$(KVER)/misc
|
||||
VERBOSE := 0
|
||||
|
||||
cmd_prefix := @
|
||||
|
||||
ccflags-y := -I$(M)/../include
|
||||
ifneq ($(DEBUG),0)
|
||||
ccflags-y += -DDEBUG -g
|
||||
endif
|
||||
ifneq ($(VERBOSE),0)
|
||||
cmd_prefix :=
|
||||
endif
|
||||
ifneq ($(drv-MAX_DEVICE),0)
|
||||
ccflags-y += -DMAX_DEVICE=$(drv-MAX_DEVICE)
|
||||
endif
|
||||
|
||||
obj-m := px4_drv.o
|
||||
px4_drv-objs := px4.o it930x-bus.o it930x.o tc90522.o rt710.o r850_lite.o r850_channel.o ringbuffer.o
|
||||
all: modules
|
||||
|
||||
all: $(TARGET)
|
||||
modules: px4_drv.ko
|
||||
|
||||
$(TARGET): FORCE revision.h
|
||||
$(cmd_prefix)$(MAKE) -C $(KBUILD_DIR) M=$(CURRENT_DIR) KBUILD_VERBOSE=$(VERBOSE) modules
|
||||
px4_drv.ko: FORCE revision.h
|
||||
$(cmd_prefix)$(MAKE) -C $(KDIR) M=$(PWD) KBUILD_VERBOSE=$(VERBOSE) px4_drv.ko
|
||||
|
||||
revision.h: FORCE
|
||||
$(cmd_prefix)rev=`git rev-list --count HEAD` 2>/dev/null; \
|
||||
rev_name=`git name-rev --name-only HEAD` 2>/dev/null; \
|
||||
commit=`git rev-list --max-count=1 HEAD` 2>/dev/null; \
|
||||
if [ ! -s $@ ] || [ \"`grep -soP '(?<=#define REVISION_NUMBER\\s\\")[0-9]+(?=\\")' $@`.`grep -soP '(?<=#define REVISION_NAME\\s\\")[[:print:]]+(?=\\")' $@`.`grep -soP '(?<=#define COMMIT_HASH\\s\\")[0-9A-Fa-f]+(?=\\")' $@`\" != \"$${rev}.$${rev_name}.$${commit}\" ]; then \
|
||||
if [ ! -s $@ ] || [ \"`grep -soE '^#define REVISION_NUMBER[[:blank:]]+"[0-9]+"$$' $@ | sed -E 's/^.+"(.*)"$$/\1/g'`.`grep -soE '^#define REVISION_NAME[[:blank:]]+"[[:print:]]+"$$' $@ | sed -E 's/^.+"(.*)"$$/\1/g'`.`grep -soE '^#define COMMIT_HASH[[:blank:]]+"[0-9A-Fa-f]+"$$' $@ | sed -E 's/^.+"(.*)"$$/\1/g'`\" != \"$${rev}.$${rev_name}.$${commit}\" ]; then \
|
||||
echo "// revision.h" > $@; \
|
||||
echo "" >> $@; \
|
||||
echo "#ifndef __REVISION_H__" >> $@; \
|
||||
@@ -54,18 +43,25 @@ revision.h: FORCE
|
||||
fi
|
||||
|
||||
clean:
|
||||
$(cmd_prefix)$(MAKE) -C $(KBUILD_DIR) M=$(CURRENT_DIR) KBUILD_VERBOSE=$(VERBOSE) clean
|
||||
$(cmd_prefix)$(MAKE) -C $(KDIR) M=$(PWD) KBUILD_VERBOSE=$(VERBOSE) clean
|
||||
$(cmd_prefix)rm -f revision.h
|
||||
|
||||
install:
|
||||
$(cmd_prefix)install -D -v -m 644 $(TARGET) $(INSTALL_DIR)/$(TARGET)
|
||||
$(cmd_prefix)if [ `grep -e '^px4_drv' /proc/modules | wc -l` -ne 0 ]; then \
|
||||
modprobe -r px4_drv; \
|
||||
fi
|
||||
$(cmd_prefix)install -D -v -m 644 px4_drv.ko $(INSTALL_DIR)/px4_drv.ko
|
||||
$(cmd_prefix)rm -fv /etc/udev/rules.d/90-px4.rules
|
||||
$(cmd_prefix)install -D -v -m 644 ../etc/99-px4video.rules /etc/udev/rules.d/99-px4video.rules
|
||||
$(cmd_prefix)depmod -a $(KVER)
|
||||
$(cmd_prefix)modprobe px4_drv
|
||||
|
||||
uninstall:
|
||||
$(cmd_prefix)rm -fv $(INSTALL_DIR)/$(TARGET)
|
||||
$(cmd_prefix)if [ `find /lib/modules/ -name px4_drv.ko | wc -l` -eq 0 ]; then \
|
||||
$(cmd_prefix)if [ `grep -e '^px4_drv' /proc/modules | wc -l` -ne 0 ]; then \
|
||||
modprobe -r px4_drv; \
|
||||
fi
|
||||
$(cmd_prefix)rm -fv $(INSTALL_DIR)/px4_drv.ko
|
||||
$(cmd_prefix)if [ `find /lib/modules/ -name 'px4_drv.ko*' | wc -l` -eq 0 ]; then \
|
||||
rm -fv /etc/udev/rules.d/90-px4.rules /etc/udev/rules.d/99-px4video.rules; \
|
||||
fi
|
||||
$(cmd_prefix)depmod -a $(KVER)
|
||||
|
1141
driver/cxd2856er.c
Normal file
1141
driver/cxd2856er.c
Normal file
File diff suppressed because it is too large
Load Diff
154
driver/cxd2856er.h
Normal file
154
driver/cxd2856er.h
Normal file
@@ -0,0 +1,154 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Sony CXD2856ER driver definitions (cxd2856er.h)
|
||||
*
|
||||
* Copyright (c) 2018-2021 nns779
|
||||
*/
|
||||
|
||||
#ifndef __CXD2856ER_H__
|
||||
#define __CXD2856ER_H__
|
||||
|
||||
#ifdef __linux__
|
||||
#include <linux/types.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/device.h>
|
||||
#elif defined(_WIN32) || defined(_WIN64)
|
||||
#include "misc_win.h"
|
||||
#endif
|
||||
|
||||
#include "i2c_comm.h"
|
||||
|
||||
struct cxd2856er_config {
|
||||
u32 xtal;
|
||||
bool tuner_i2c;
|
||||
};
|
||||
|
||||
enum cxd2856er_state {
|
||||
CXD2856ER_UNKNOWN_STATE = 0,
|
||||
CXD2856ER_SLEEP_STATE,
|
||||
CXD2856ER_ACTIVE_STATE
|
||||
};
|
||||
|
||||
enum cxd2856er_system {
|
||||
CXD2856ER_UNSPECIFIED_SYSTEM = 0,
|
||||
CXD2856ER_ISDB_T_SYSTEM,
|
||||
CXD2856ER_ISDB_S_SYSTEM
|
||||
};
|
||||
|
||||
enum cxd2856er_i2c_target {
|
||||
CXD2856ER_I2C_SLVX = 0,
|
||||
CXD2856ER_I2C_SLVT
|
||||
};
|
||||
|
||||
union cxd2856er_system_params {
|
||||
u32 bandwidth;
|
||||
};
|
||||
|
||||
struct cxd2856er_demod {
|
||||
const struct device *dev;
|
||||
const struct i2c_comm_master *i2c;
|
||||
struct i2c_comm_master i2c_master;
|
||||
struct {
|
||||
u8 slvx; // system
|
||||
u8 slvt; // demod
|
||||
} i2c_addr;
|
||||
struct cxd2856er_config config;
|
||||
enum cxd2856er_state state;
|
||||
enum cxd2856er_system system;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
int cxd2856er_read_regs(struct cxd2856er_demod *demod,
|
||||
enum cxd2856er_i2c_target target,
|
||||
u8 reg, u8 *buf, int len);
|
||||
int cxd2856er_write_regs(struct cxd2856er_demod *demod,
|
||||
enum cxd2856er_i2c_target target,
|
||||
u8 reg, u8 *buf, int len);
|
||||
int cxd2856er_write_reg_mask(struct cxd2856er_demod *demod,
|
||||
enum cxd2856er_i2c_target target,
|
||||
u8 reg, u8 val, u8 mask);
|
||||
|
||||
static inline int cxd2856er_read_slvx_regs(struct cxd2856er_demod *demod,
|
||||
u8 reg, u8 *buf, int len)
|
||||
{
|
||||
return cxd2856er_read_regs(demod, CXD2856ER_I2C_SLVX, reg, buf, len);
|
||||
}
|
||||
|
||||
static inline int cxd2856er_read_slvt_regs(struct cxd2856er_demod *demod,
|
||||
u8 reg, u8 *buf, int len)
|
||||
{
|
||||
return cxd2856er_read_regs(demod, CXD2856ER_I2C_SLVT, reg, buf, len);
|
||||
}
|
||||
|
||||
static inline int cxd2856er_read_slvx_reg(struct cxd2856er_demod *demod,
|
||||
u8 reg, u8 *val)
|
||||
{
|
||||
return cxd2856er_read_regs(demod, CXD2856ER_I2C_SLVX, reg, val, 1);
|
||||
}
|
||||
|
||||
static inline int cxd2856er_read_slvt_reg(struct cxd2856er_demod *demod,
|
||||
u8 reg, u8 *val)
|
||||
{
|
||||
return cxd2856er_read_regs(demod, CXD2856ER_I2C_SLVT, reg, val, 1);
|
||||
}
|
||||
|
||||
static inline int cxd2856er_write_slvx_regs(struct cxd2856er_demod *demod,
|
||||
u8 reg, u8 *buf, int len)
|
||||
{
|
||||
return cxd2856er_write_regs(demod, CXD2856ER_I2C_SLVX, reg, buf, len);
|
||||
}
|
||||
|
||||
static inline int cxd2856er_write_slvt_regs(struct cxd2856er_demod *demod,
|
||||
u8 reg, u8 *buf, int len)
|
||||
{
|
||||
return cxd2856er_write_regs(demod, CXD2856ER_I2C_SLVT, reg, buf, len);
|
||||
}
|
||||
|
||||
static inline int cxd2856er_write_slvx_reg(struct cxd2856er_demod *demod,
|
||||
u8 reg, u8 val)
|
||||
{
|
||||
return cxd2856er_write_regs(demod, CXD2856ER_I2C_SLVX, reg, &val, 1);
|
||||
}
|
||||
|
||||
static inline int cxd2856er_write_slvt_reg(struct cxd2856er_demod *demod,
|
||||
u8 reg, u8 val)
|
||||
{
|
||||
return cxd2856er_write_regs(demod, CXD2856ER_I2C_SLVT, reg, &val, 1);
|
||||
}
|
||||
|
||||
static inline int cxd2856er_write_slvx_reg_mask(struct cxd2856er_demod *demod,
|
||||
u8 reg, u8 val, u8 mask)
|
||||
{
|
||||
return cxd2856er_write_reg_mask(demod, CXD2856ER_I2C_SLVX,
|
||||
reg, val, mask);
|
||||
}
|
||||
|
||||
static inline int cxd2856er_write_slvt_reg_mask(struct cxd2856er_demod *demod,
|
||||
u8 reg, u8 val, u8 mask)
|
||||
{
|
||||
return cxd2856er_write_reg_mask(demod, CXD2856ER_I2C_SLVT,
|
||||
reg, val, mask);
|
||||
}
|
||||
|
||||
int cxd2856er_init(struct cxd2856er_demod *demod);
|
||||
int cxd2856er_term(struct cxd2856er_demod *demod);
|
||||
|
||||
int cxd2856er_sleep(struct cxd2856er_demod *demod);
|
||||
int cxd2856er_wakeup(struct cxd2856er_demod *demod,
|
||||
enum cxd2856er_system system,
|
||||
union cxd2856er_system_params *params);
|
||||
int cxd2856er_post_tune(struct cxd2856er_demod *demod);
|
||||
int cxd2856er_set_slot_isdbs(struct cxd2856er_demod *demod, u16 idx);
|
||||
int cxd2856er_set_tsid_isdbs(struct cxd2856er_demod *demod, u16 tsid);
|
||||
int cxd2856er_is_ts_locked_isdbt(struct cxd2856er_demod *demod,
|
||||
bool *locked, bool *unlocked);
|
||||
int cxd2856er_is_ts_locked_isdbs(struct cxd2856er_demod *demod, bool *locked);
|
||||
int cxd2856er_read_cnr_raw_isdbt(struct cxd2856er_demod *demod, u16 *value);
|
||||
int cxd2856er_read_cnr_raw_isdbs(struct cxd2856er_demod *demod, u16 *value);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
640
driver/cxd2858er.c
Normal file
640
driver/cxd2858er.c
Normal file
@@ -0,0 +1,640 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Sony CXD2858ER driver (cxd2858er.c)
|
||||
*
|
||||
* Copyright (c) 2018-2021 nns779
|
||||
*/
|
||||
|
||||
#include "print_format.h"
|
||||
#include "cxd2858er.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#include <linux/delay.h>
|
||||
#endif
|
||||
|
||||
static int cxd2858er_stop_t(struct cxd2858er_tuner *tuner);
|
||||
static int cxd2858er_stop_s(struct cxd2858er_tuner *tuner);
|
||||
|
||||
static int cxd2858er_read_regs(struct cxd2858er_tuner *tuner,
|
||||
u8 reg, u8 *buf, int len)
|
||||
{
|
||||
u8 b;
|
||||
struct i2c_comm_request req[2];
|
||||
|
||||
if (!buf || !len)
|
||||
return -EINVAL;
|
||||
|
||||
b = reg;
|
||||
|
||||
req[0].req = I2C_WRITE_REQUEST;
|
||||
req[0].addr = tuner->i2c_addr;
|
||||
req[0].data = &b;
|
||||
req[0].len = 1;
|
||||
|
||||
req[1].req = I2C_READ_REQUEST;
|
||||
req[1].addr = tuner->i2c_addr;
|
||||
req[1].data = buf;
|
||||
req[1].len = len;
|
||||
|
||||
return i2c_comm_master_request(tuner->i2c, req, 2);
|
||||
}
|
||||
|
||||
static int cxd2858er_read_reg(struct cxd2858er_tuner *tuner,
|
||||
u8 reg, u8 *val)
|
||||
{
|
||||
return cxd2858er_read_regs(tuner, reg, val, 1);
|
||||
}
|
||||
|
||||
static int cxd2858er_write_regs(struct cxd2858er_tuner *tuner,
|
||||
u8 reg, u8 *buf, int len)
|
||||
{
|
||||
u8 b[255];
|
||||
struct i2c_comm_request req[1];
|
||||
|
||||
if (!buf || !len || len > 254)
|
||||
return -EINVAL;
|
||||
|
||||
b[0] = reg;
|
||||
memcpy(&b[1], buf, len);
|
||||
|
||||
req[0].req = I2C_WRITE_REQUEST;
|
||||
req[0].addr = tuner->i2c_addr;
|
||||
req[0].data = b;
|
||||
req[0].len = 1 + len;
|
||||
|
||||
return i2c_comm_master_request(tuner->i2c, req, 1);
|
||||
}
|
||||
|
||||
static int cxd2858er_write_reg(struct cxd2858er_tuner *tuner,
|
||||
u8 reg, u8 val)
|
||||
{
|
||||
return cxd2858er_write_regs(tuner, reg, &val, 1);
|
||||
}
|
||||
|
||||
static int cxd2858er_write_reg_mask(struct cxd2858er_tuner *tuner,
|
||||
u8 reg, u8 val, u8 mask)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 tmp;
|
||||
|
||||
if (!mask)
|
||||
return -EINVAL;
|
||||
|
||||
if (mask != 0xff) {
|
||||
ret = cxd2858er_read_regs(tuner, reg, &tmp, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
tmp &= ~mask;
|
||||
tmp |= (val & mask);
|
||||
} else {
|
||||
tmp = val;
|
||||
}
|
||||
|
||||
return cxd2858er_write_regs(tuner, reg, &tmp, 1);
|
||||
}
|
||||
|
||||
static int cxd2858er_power_on(struct cxd2858er_tuner *tuner)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 data[20], tmp;
|
||||
|
||||
/* T mode */
|
||||
ret = cxd2858er_write_reg(tuner, 0x01, 0x00);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = cxd2858er_write_reg(tuner, 0x67, 0x00);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = cxd2858er_write_reg(tuner, 0x43,
|
||||
0x05 | ((tuner->config.ter.lna) ? 0x02
|
||||
: 0x00));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
data[0] = 0x15;
|
||||
data[1] = 0x00;
|
||||
data[2] = 0x00;
|
||||
|
||||
ret = cxd2858er_write_regs(tuner, 0x5e, data, 3);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = cxd2858er_write_reg(tuner, 0x0c, 0x14);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
data[0] = 0x7a;
|
||||
data[1] = 0x01;
|
||||
|
||||
ret = cxd2858er_write_regs(tuner, 0x99, data, 2);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (tuner->config.xtal) {
|
||||
case 16000:
|
||||
data[0] = 0x10;
|
||||
break;
|
||||
|
||||
case 24000:
|
||||
data[0] = 0x18;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
data[1] = 0x80 | (0x04 & 0x1f);
|
||||
data[2] = 0x80 | 0x26;
|
||||
data[3] = 0x00;
|
||||
data[4] = 0x00;
|
||||
data[5] = 0x00;
|
||||
data[6] = 0xc4;
|
||||
data[7] = 0x40;
|
||||
data[8] = 0x10;
|
||||
data[9] = 0x00;
|
||||
data[10] = 0x45;
|
||||
data[11] = 0x75;
|
||||
data[12] = 0x07;
|
||||
data[13] = 0x1c;
|
||||
data[14] = 0x3f;
|
||||
data[15] = 0x02;
|
||||
data[16] = 0x10;
|
||||
data[17] = 0x20;
|
||||
data[18] = 0x0a;
|
||||
data[19] = 0x00;
|
||||
|
||||
ret = cxd2858er_write_regs(tuner, 0x81, data, 20);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = cxd2858er_write_reg(tuner, 0x9b, 0x00);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
msleep(10);
|
||||
|
||||
ret = cxd2858er_read_reg(tuner, 0x1a, &tmp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (tmp != 0x00)
|
||||
return -EIO;
|
||||
|
||||
data[0] = 0x90;
|
||||
data[1] = 0x06;
|
||||
|
||||
ret = cxd2858er_write_regs(tuner, 0x17, data, 2);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
msleep(1);
|
||||
|
||||
ret = cxd2858er_read_reg(tuner, 0x19, &tmp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = cxd2858er_write_reg(tuner, 0x95, (tmp & 0xf0) >> 4);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = cxd2858er_write_reg(tuner, 0x74, 0x02);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = cxd2858er_write_reg(tuner, 0x88, 0x00);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = cxd2858er_write_reg(tuner, 0x87, 0xc0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = cxd2858er_write_reg(tuner, 0x80, 0x01);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
data[0] = 0x07;
|
||||
data[1] = 0x00;
|
||||
|
||||
ret = cxd2858er_write_regs(tuner, 0x41, data, 2);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cxd2858er_init(struct cxd2858er_tuner *tuner)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!tuner->dev || !tuner->i2c || !tuner->i2c_addr)
|
||||
return -EINVAL;
|
||||
|
||||
if (tuner->config.xtal != 16000 && tuner->config.xtal != 24000)
|
||||
return -EINVAL;
|
||||
|
||||
tuner->system = CXD2858ER_UNSPECIFIED_SYSTEM;
|
||||
|
||||
ret = i2c_comm_master_gate_ctrl(tuner->i2c, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = cxd2858er_power_on(tuner);
|
||||
|
||||
i2c_comm_master_gate_ctrl(tuner->i2c, false);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cxd2858er_term(struct cxd2858er_tuner *tuner)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (tuner->system == CXD2858ER_UNSPECIFIED_SYSTEM)
|
||||
return 0;
|
||||
|
||||
ret = i2c_comm_master_gate_ctrl(tuner->i2c, true);
|
||||
if (!ret) {
|
||||
switch (tuner->system) {
|
||||
case CXD2858ER_ISDB_T_SYSTEM:
|
||||
cxd2858er_stop_t(tuner);
|
||||
break;
|
||||
|
||||
case CXD2858ER_ISDB_S_SYSTEM:
|
||||
cxd2858er_stop_s(tuner);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
i2c_comm_master_gate_ctrl(tuner->i2c, false);
|
||||
} else {
|
||||
tuner->system = CXD2858ER_UNSPECIFIED_SYSTEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cxd2858er_set_params_t(struct cxd2858er_tuner *tuner,
|
||||
enum cxd2858er_system system,
|
||||
u32 freq, u32 bandwidth)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 data[17];
|
||||
|
||||
if (system != CXD2858ER_ISDB_T_SYSTEM)
|
||||
return -EINVAL;
|
||||
|
||||
ret = i2c_comm_master_gate_ctrl(tuner->i2c, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (tuner->system) {
|
||||
case CXD2858ER_ISDB_S_SYSTEM:
|
||||
ret = cxd2858er_stop_s(tuner);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
/* T mode */
|
||||
ret = cxd2858er_write_reg(tuner, 0x01, 0x00);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
ret = cxd2858er_write_reg(tuner, 0x74, 0x02);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
data[0] = 0xc4;
|
||||
data[1] = 0x40;
|
||||
|
||||
ret = cxd2858er_write_regs(tuner, 0x87, data, 2);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
data[0] = 0x10;
|
||||
data[1] = 0x20;
|
||||
|
||||
ret = cxd2858er_write_regs(tuner, 0x91, data, 2);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
data[0] = 0x00;
|
||||
data[1] = 0x00;
|
||||
|
||||
ret = cxd2858er_write_regs(tuner, 0x9c, data, 2);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
data[0] = 0xee;
|
||||
data[1] = 0x02;
|
||||
data[2] = 0x1e;
|
||||
data[3] = 0x67;
|
||||
|
||||
switch (tuner->config.xtal) {
|
||||
case 16000:
|
||||
data[4] = 0x02;
|
||||
break;
|
||||
|
||||
case 24000:
|
||||
data[4] = 0x03;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
data[5] = 0xb4;
|
||||
data[6] = 0x78;
|
||||
data[7] = 0x08;
|
||||
data[8] = 0x30;
|
||||
|
||||
ret = cxd2858er_write_regs(tuner, 0x5e, data, 9);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
ret = cxd2858er_write_reg_mask(tuner, 0x67, 0x00, 0x02);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
data[0] = 0x00;
|
||||
data[1] = 0x88;
|
||||
data[2] = 0x00;
|
||||
data[3] = 0x0b;
|
||||
data[4] = 0x22;
|
||||
data[5] = 0x00;
|
||||
data[6] = 0x17;
|
||||
data[7] = 0x1b;
|
||||
|
||||
data[8] = freq & 0xff;
|
||||
data[9] = (freq >> 8) & 0xff;
|
||||
data[10] = (freq >> 16) & 0x0f;
|
||||
|
||||
data[11] = 0xff;
|
||||
data[12] = 0x01;
|
||||
data[13] = 0x99;
|
||||
data[14] = 0x00;
|
||||
data[15] = 0x24;
|
||||
data[16] = 0x87;
|
||||
|
||||
ret = cxd2858er_write_regs(tuner, 0x68, data, 17);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
msleep(50);
|
||||
|
||||
ret = cxd2858er_write_reg(tuner, 0x88, 0x00);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
ret = cxd2858er_write_reg(tuner, 0x87, 0xc0);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
tuner->system = system;
|
||||
|
||||
exit:
|
||||
i2c_comm_master_gate_ctrl(tuner->i2c, false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cxd2858er_set_params_s(struct cxd2858er_tuner *tuner,
|
||||
enum cxd2858er_system system,
|
||||
u32 freq, u32 symbol_rate)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 data[18];
|
||||
|
||||
if (system != CXD2858ER_ISDB_S_SYSTEM)
|
||||
return -EINVAL;
|
||||
|
||||
ret = i2c_comm_master_gate_ctrl(tuner->i2c, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (tuner->system) {
|
||||
case CXD2858ER_ISDB_T_SYSTEM:
|
||||
ret = cxd2858er_stop_t(tuner);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
ret = cxd2858er_write_reg(tuner, 0x15, 0x02);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
ret = cxd2858er_write_reg(tuner, 0x43, 0x06);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
data[0] = 0x00;
|
||||
data[1] = 0x00;
|
||||
|
||||
ret = cxd2858er_write_regs(tuner, 0x6a, data, 2);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
ret = cxd2858er_write_reg(tuner, 0x75, 0x99);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
ret = cxd2858er_write_reg(tuner, 0x9d, 0x00);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
ret = cxd2858er_write_reg(tuner, 0x61, 0x07);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
/* S mode */
|
||||
ret = cxd2858er_write_reg(tuner, 0x01, 0x01);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
data[0] = 0xc4;
|
||||
data[1] = 0x40;
|
||||
|
||||
switch (tuner->config.xtal) {
|
||||
case 16000:
|
||||
data[2] = 0x02;
|
||||
break;
|
||||
|
||||
case 24000:
|
||||
data[2] = 0x03;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
data[3] = 0x00;
|
||||
data[4] = 0xb4;
|
||||
data[5] = 0x78;
|
||||
data[6] = 0x08;
|
||||
data[7] = 0x30;
|
||||
data[8] = 0xfe | ((tuner->config.sat.lna) ? 0x01 : 0x00);
|
||||
data[9] = 0x02;
|
||||
data[10] = 0x1e;
|
||||
|
||||
switch (system) {
|
||||
case CXD2858ER_ISDB_S_SYSTEM:
|
||||
data[11] = 0x16;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
freq = (freq + 2) / 4;
|
||||
|
||||
data[12] = freq & 0xff;
|
||||
data[13] = (freq >> 8) & 0xff;
|
||||
data[14] = (freq >> 16) & 0x0f;
|
||||
|
||||
data[15] = 0xff;
|
||||
data[16] = 0x00;
|
||||
data[17] = 0x01;
|
||||
|
||||
ret = cxd2858er_write_regs(tuner, 0x04, data, 18);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
msleep(10);
|
||||
|
||||
ret = cxd2858er_write_reg(tuner, 0x05, 0x00);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
ret = cxd2858er_write_reg(tuner, 0x04, 0xc0);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
tuner->system = system;
|
||||
|
||||
exit:
|
||||
i2c_comm_master_gate_ctrl(tuner->i2c, false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cxd2858er_stop_t(struct cxd2858er_tuner *tuner)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 data[3];
|
||||
|
||||
if (tuner->system != CXD2858ER_ISDB_T_SYSTEM)
|
||||
return -EINVAL;
|
||||
|
||||
ret = cxd2858er_write_reg(tuner, 0x74, 0x02);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = cxd2858er_write_reg_mask(tuner, 0x67, 0x00, 0xfe);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
data[0] = 0x15;
|
||||
data[1] = 0x00;
|
||||
data[2] = 0x00;
|
||||
|
||||
ret = cxd2858er_write_regs(tuner, 0x5e, data, 3);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = cxd2858er_write_reg(tuner, 0x88, 0x00);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = cxd2858er_write_reg(tuner, 0x87, 0xc0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
tuner->system = CXD2858ER_UNSPECIFIED_SYSTEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cxd2858er_stop_s(struct cxd2858er_tuner *tuner)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 data[3];
|
||||
|
||||
if (tuner->system != CXD2858ER_ISDB_S_SYSTEM)
|
||||
return -EINVAL;
|
||||
|
||||
ret = cxd2858er_write_reg(tuner, 0x15, 0x02);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = cxd2858er_write_reg(tuner, 0x43,
|
||||
0x05 | ((tuner->config.ter.lna) ? 0x02
|
||||
: 0x00));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
data[0] = 0x14;
|
||||
data[1] = 0x00;
|
||||
data[2] = 0x00;
|
||||
|
||||
ret = cxd2858er_write_regs(tuner, 0x0c, data, 3);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = cxd2858er_write_reg(tuner, 0x01, 0x00);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = cxd2858er_write_reg(tuner, 0x05, 0x00);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = cxd2858er_write_reg(tuner, 0x04, 0xc0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
tuner->system = CXD2858ER_UNSPECIFIED_SYSTEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cxd2858er_stop(struct cxd2858er_tuner *tuner)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (tuner->system == CXD2858ER_UNSPECIFIED_SYSTEM)
|
||||
return -EALREADY;
|
||||
|
||||
ret = i2c_comm_master_gate_ctrl(tuner->i2c, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (tuner->system) {
|
||||
case CXD2858ER_ISDB_T_SYSTEM:
|
||||
cxd2858er_stop_t(tuner);
|
||||
break;
|
||||
|
||||
case CXD2858ER_ISDB_S_SYSTEM:
|
||||
cxd2858er_stop_s(tuner);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
i2c_comm_master_gate_ctrl(tuner->i2c, false);
|
||||
return 0;
|
||||
}
|
61
driver/cxd2858er.h
Normal file
61
driver/cxd2858er.h
Normal file
@@ -0,0 +1,61 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Sony CXD2858ER driver definitions (cxd2858er.h)
|
||||
*
|
||||
* Copyright (c) 2018-2021 nns779
|
||||
*/
|
||||
|
||||
#ifndef __CXD2858ER_H__
|
||||
#define __CXD2858ER_H__
|
||||
|
||||
#ifdef __linux__
|
||||
#include <linux/types.h>
|
||||
#include <linux/device.h>
|
||||
#elif defined(_WIN32) || defined(_WIN64)
|
||||
#include "misc_win.h"
|
||||
#endif
|
||||
|
||||
#include "i2c_comm.h"
|
||||
|
||||
struct cxd2858er_config {
|
||||
u32 xtal;
|
||||
struct {
|
||||
bool lna;
|
||||
} ter;
|
||||
struct {
|
||||
bool lna;
|
||||
} sat;
|
||||
};
|
||||
|
||||
enum cxd2858er_system {
|
||||
CXD2858ER_UNSPECIFIED_SYSTEM = 0,
|
||||
CXD2858ER_ISDB_T_SYSTEM,
|
||||
CXD2858ER_ISDB_S_SYSTEM
|
||||
};
|
||||
|
||||
struct cxd2858er_tuner {
|
||||
const struct device *dev;
|
||||
const struct i2c_comm_master *i2c;
|
||||
u8 i2c_addr;
|
||||
struct cxd2858er_config config;
|
||||
enum cxd2858er_system system;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
int cxd2858er_init(struct cxd2858er_tuner *tuner);
|
||||
int cxd2858er_term(struct cxd2858er_tuner *tuner);
|
||||
|
||||
int cxd2858er_set_params_t(struct cxd2858er_tuner *tuner,
|
||||
enum cxd2858er_system system,
|
||||
u32 freq, u32 bandwidth);
|
||||
int cxd2858er_set_params_s(struct cxd2858er_tuner *tuner,
|
||||
enum cxd2858er_system system,
|
||||
u32 freq, u32 symbol_rate);
|
||||
int cxd2858er_stop(struct cxd2858er_tuner *tuner);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
74
driver/driver_module.c
Normal file
74
driver/driver_module.c
Normal file
@@ -0,0 +1,74 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Module initiator of the driver (driver_module.c)
|
||||
*
|
||||
* Copyright (c) 2018-2021 nns779
|
||||
*/
|
||||
|
||||
#include "print_format.h"
|
||||
#include "driver_module.h"
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
#include "revision.h"
|
||||
#include "px4_usb.h"
|
||||
#include "firmware.h"
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,15,4)
|
||||
static int __init m_init(void)
|
||||
#else
|
||||
int init_module(void)
|
||||
#endif
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
pr_info(KBUILD_MODNAME
|
||||
#ifdef PX4_DRV_VERSION
|
||||
" version " PX4_DRV_VERSION
|
||||
#endif
|
||||
#ifdef REVISION_NUMBER
|
||||
#if defined(PX4_DRV_VERSION)
|
||||
","
|
||||
#endif
|
||||
" rev: " REVISION_NUMBER
|
||||
#endif
|
||||
#ifdef COMMIT_HASH
|
||||
#if defined(PX4_DRV_VERSION) || defined(REVISION_NUMBER)
|
||||
","
|
||||
#endif
|
||||
" commit: " COMMIT_HASH
|
||||
#endif
|
||||
#ifdef REVISION_NAME
|
||||
" @ " REVISION_NAME
|
||||
#endif
|
||||
"\n");
|
||||
|
||||
ret = px4_usb_register();
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,15,4)
|
||||
static void __exit m_cleanup(void)
|
||||
#else
|
||||
void cleanup_module(void)
|
||||
#endif
|
||||
{
|
||||
px4_usb_unregister();
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,15,4)
|
||||
module_init(m_init);
|
||||
module_exit(m_cleanup);
|
||||
#endif
|
||||
|
||||
MODULE_VERSION(PX4_DRV_VERSION);
|
||||
MODULE_AUTHOR("nns779");
|
||||
MODULE_DESCRIPTION("Unofficial Linux driver for PLEX PX4/PX5/PX-MLT series ISDB-T/S receivers");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
||||
MODULE_FIRMWARE(IT930X_FIRMWARE_FILENAME);
|
8
driver/driver_module.h
Normal file
8
driver/driver_module.h
Normal file
@@ -0,0 +1,8 @@
|
||||
// driver_module.h
|
||||
|
||||
#ifndef __DRIVER_MODULE_H__
|
||||
#define __DRIVER_MODULE_H__
|
||||
|
||||
#define PX4_DRV_VERSION "0.5.4"
|
||||
|
||||
#endif
|
8
driver/firmware.h
Normal file
8
driver/firmware.h
Normal file
@@ -0,0 +1,8 @@
|
||||
// firmware.h
|
||||
|
||||
#ifndef __FIRMWARE_H__
|
||||
#define __FIRMWARE_H__
|
||||
|
||||
#define IT930X_FIRMWARE_FILENAME "it930x-firmware.bin"
|
||||
|
||||
#endif
|
@@ -1,28 +1,77 @@
|
||||
// i2c_comm.h
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Definitions for I2C communicators (i2c_comm.h)
|
||||
*
|
||||
* Copyright (c) 2018-2021 nns779
|
||||
*/
|
||||
|
||||
#ifndef __I2C_COMM_H__
|
||||
#define __I2C_COMM_H__
|
||||
|
||||
#ifdef __linux__
|
||||
#include <linux/types.h>
|
||||
#elif defined(_WIN32) || defined(_WIN64)
|
||||
#include "misc_win.h"
|
||||
#endif
|
||||
|
||||
struct i2c_comm_request {
|
||||
enum i2c_request_type {
|
||||
I2C_UNDEFINED_REQUEST = 0,
|
||||
I2C_READ_REQUEST,
|
||||
I2C_WRITE_REQUEST
|
||||
} req;
|
||||
u16 addr;
|
||||
u8 *data;
|
||||
int len;
|
||||
};
|
||||
|
||||
struct i2c_comm_master {
|
||||
int (*wr) (void *priv, u8 addr, const u8 * data, int len);
|
||||
int (*rd) (void *priv, u8 addr, u8 *data, int len);
|
||||
int (*gate_ctrl)(void *i2c_priv, bool open);
|
||||
int (*request)(void *i2c_priv,
|
||||
const struct i2c_comm_request *req,
|
||||
int num);
|
||||
void *priv;
|
||||
};
|
||||
|
||||
static inline int i2c_comm_master_write(struct i2c_comm_master *m, u8 addr, const u8 *data, int len)
|
||||
static inline int i2c_comm_master_gate_ctrl(const struct i2c_comm_master *m,
|
||||
bool open)
|
||||
{
|
||||
if (m && m->wr)
|
||||
return m->wr(m->priv, addr, data, len);
|
||||
else
|
||||
return -EFAULT;
|
||||
return ((m && m ->gate_ctrl) ? m->gate_ctrl(m->priv, open) : -EFAULT);
|
||||
}
|
||||
|
||||
static inline int i2c_comm_master_read(struct i2c_comm_master *m, u8 addr, u8 *data, int len)
|
||||
static inline int i2c_comm_master_request(const struct i2c_comm_master *m,
|
||||
const struct i2c_comm_request *req,
|
||||
int num)
|
||||
{
|
||||
if (m && m->rd)
|
||||
return m->rd(m->priv, addr, data, len);
|
||||
else
|
||||
return -EFAULT;
|
||||
return ((m && m->request) ? m->request(m->priv, req, num) : -EFAULT);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static inline int i2c_comm_master_read(const struct i2c_comm_master *m,
|
||||
u8 addr, u8 *data, int len)
|
||||
{
|
||||
struct i2c_comm_request req[1];
|
||||
|
||||
req[0].req = I2C_READ_REQUEST;
|
||||
req[0].addr = addr;
|
||||
req[0].data = data;
|
||||
req[0].len = len;
|
||||
|
||||
return i2c_comm_master_request(m, &req, 1);
|
||||
}
|
||||
|
||||
static inline int i2c_comm_master_write(const struct i2c_comm_master *m,
|
||||
u8 addr, const u8 *data, int len)
|
||||
{
|
||||
struct i2c_comm_request req[1];
|
||||
|
||||
req[0].req = I2C_WRITE_REQUEST;
|
||||
req[0].addr = addr;
|
||||
req[0].data = data;
|
||||
req[0].len = len;
|
||||
|
||||
return i2c_comm_master_request(m, &req, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
1146
driver/isdb2056_device.c
Normal file
1146
driver/isdb2056_device.c
Normal file
File diff suppressed because it is too large
Load Diff
57
driver/isdb2056_device.h
Normal file
57
driver/isdb2056_device.h
Normal file
@@ -0,0 +1,57 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* PTX driver definitions for Digibest ISDB2056 device (isdb2056_device.h)
|
||||
*
|
||||
* Copyright (c) 2018-2021 nns779
|
||||
*/
|
||||
|
||||
#ifndef __ISDB2056_DEVICE_H__
|
||||
#define __ISDB2056_DEVICE_H__
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/kref.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
#include "ptx_chrdev.h"
|
||||
#include "it930x.h"
|
||||
#include "tc90522.h"
|
||||
#include "r850.h"
|
||||
#include "rt710.h"
|
||||
|
||||
#define ISDB2056_CHRDEV_NUM 1
|
||||
|
||||
enum isdb2056_model {
|
||||
ISDB2056_MODEL = 0,
|
||||
ISDB2056N_MODEL,
|
||||
};
|
||||
|
||||
struct isdb2056_chrdev {
|
||||
struct ptx_chrdev *chrdev;
|
||||
struct tc90522_demod tc90522_t;
|
||||
struct tc90522_demod tc90522_s;
|
||||
struct tc90522_demod tc90522_s0;
|
||||
struct r850_tuner r850;
|
||||
struct rt710_tuner rt710;
|
||||
};
|
||||
|
||||
struct isdb2056_device {
|
||||
struct kref kref;
|
||||
atomic_t available;
|
||||
struct device *dev;
|
||||
enum isdb2056_model isdb2056_model;
|
||||
struct completion *quit_completion;
|
||||
struct ptx_chrdev_group *chrdev_group;
|
||||
struct isdb2056_chrdev chrdev2056;
|
||||
struct it930x_bridge it930x;
|
||||
void *stream_ctx;
|
||||
};
|
||||
|
||||
int isdb2056_device_init(struct isdb2056_device *isdb2056, struct device *dev,
|
||||
enum isdb2056_model isdb2056_model,
|
||||
struct ptx_chrdev_context *chrdev_ctx,
|
||||
struct completion *quit_completion);
|
||||
void isdb2056_device_term(struct isdb2056_device *isdb2056);
|
||||
|
||||
#endif
|
@@ -1,378 +0,0 @@
|
||||
// it930x-bus.c
|
||||
|
||||
// IT930x bus functions
|
||||
|
||||
#include "print_format.h"
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/usb.h>
|
||||
|
||||
#include "it930x-config.h"
|
||||
#include "it930x-bus.h"
|
||||
|
||||
struct context {
|
||||
struct it930x_bus *bus;
|
||||
it930x_bus_on_stream_t on_stream;
|
||||
void *ctx;
|
||||
};
|
||||
|
||||
struct priv_data_usb {
|
||||
struct urb **urbs;
|
||||
u32 num_urb;
|
||||
bool no_dma;
|
||||
struct context ctx;
|
||||
atomic_t start;
|
||||
};
|
||||
|
||||
static int it930x_usb_ctrl_tx(struct it930x_bus *bus, const void *buf, int len, void *opt)
|
||||
{
|
||||
int ret = 0, rlen = 0;
|
||||
struct usb_device *dev = bus->usb.dev;
|
||||
#if 0
|
||||
const u8 *p = buf;
|
||||
#endif
|
||||
|
||||
if (len > IT930X_USB_MAX_CONTROL_TRANSFER_SIZE || !buf || !len)
|
||||
return -EINVAL;
|
||||
|
||||
#if 0
|
||||
while (len > 0) {
|
||||
int s = (len < IT930X_USB_MAX_CONTROL_PACKET_SIZE) ? len : IT930X_USB_MAX_CONTROL_PACKET_SIZE;
|
||||
|
||||
ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, 0x02), p, s, &rlen, bus->usb.timeout);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
p += rlen;
|
||||
len -= rlen;
|
||||
}
|
||||
#else
|
||||
/* Endpoint 0x02: Control IN */
|
||||
ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, 0x02), (void *)buf, len, &rlen, bus->usb.ctrl_timeout);
|
||||
#endif
|
||||
|
||||
if (ret)
|
||||
dev_dbg(bus->dev, "it930x_usb_ctrl_tx: Failed. (ret: %d)\n", ret);
|
||||
|
||||
mdelay(1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int it930x_usb_ctrl_rx(struct it930x_bus *bus, void *buf, int *len, void *opt)
|
||||
{
|
||||
int ret = 0, rlen = 0;
|
||||
struct usb_device *dev = bus->usb.dev;
|
||||
|
||||
if (!buf || !len || !*len)
|
||||
return -EINVAL;
|
||||
|
||||
/* Endpoint 0x81: Control OUT */
|
||||
ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, 0x81), buf, *len, &rlen, bus->usb.ctrl_timeout);
|
||||
if (ret)
|
||||
dev_dbg(bus->dev, "it930x_usb_ctrl_rx: Failed. (ret: %d)\n", ret);
|
||||
|
||||
*len = rlen;
|
||||
|
||||
mdelay(1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int it930x_usb_stream_rx(struct it930x_bus *bus, void *buf, int *len, int timeout)
|
||||
{
|
||||
int ret = 0, rlen = 0;
|
||||
struct usb_device *dev = bus->usb.dev;
|
||||
|
||||
if (!buf | !len || !*len)
|
||||
return -EINVAL;
|
||||
|
||||
/* Endpoint 0x84: Stream OUT */
|
||||
ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, 0x84), buf, *len, &rlen, timeout);
|
||||
if (ret)
|
||||
dev_dbg(bus->dev, "it930x_usb_stream_rx: Failed. (ret: %d)\n", ret);
|
||||
|
||||
*len = rlen;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void free_urb_buffers(struct usb_device *dev, struct urb **urbs, u32 n, bool free_urb, bool no_dma)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
if (!urbs)
|
||||
return;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
struct urb *urb = urbs[i];
|
||||
if (urb != NULL) {
|
||||
if (urb->transfer_buffer) {
|
||||
if (!no_dma)
|
||||
usb_free_coherent(dev, urb->transfer_buffer_length, urb->transfer_buffer, urb->transfer_dma);
|
||||
else
|
||||
kfree(urb->transfer_buffer);
|
||||
|
||||
urb->transfer_buffer = NULL;
|
||||
urb->transfer_buffer_length = 0;
|
||||
}
|
||||
|
||||
if (free_urb) {
|
||||
usb_free_urb(urb);
|
||||
urbs[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void it930x_usb_complete(struct urb *urb)
|
||||
{
|
||||
int ret = 0;
|
||||
struct context *ctx = urb->context;
|
||||
|
||||
if (urb->status) {
|
||||
dev_dbg(ctx->bus->dev, "it930x_usb_complete: status: %d\n", urb->status);
|
||||
return;
|
||||
}
|
||||
|
||||
if (urb->actual_length)
|
||||
ret = ctx->on_stream(ctx->ctx, urb->transfer_buffer, urb->actual_length);
|
||||
else
|
||||
dev_dbg(ctx->bus->dev, "it930x_usb_complete: !urb->actual_length\n");
|
||||
|
||||
if (!ret) {
|
||||
ret = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (ret)
|
||||
dev_dbg(ctx->bus->dev, "it930x_usb_complete: usb_submit_urb() failed. (ret: %d)\n", ret);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int it930x_usb_start_streaming(struct it930x_bus *bus, it930x_bus_on_stream_t on_stream, void *context)
|
||||
{
|
||||
int ret = 0;
|
||||
u32 i, l, n;
|
||||
bool no_dma;
|
||||
struct usb_device *dev = bus->usb.dev;
|
||||
struct priv_data_usb *priv = bus->usb.priv;
|
||||
struct urb **urbs;
|
||||
struct context *ctx = &priv->ctx;
|
||||
|
||||
if (!on_stream)
|
||||
return -EINVAL;
|
||||
|
||||
dev_dbg(bus->dev, "it930x_usb_start_streaming\n");
|
||||
|
||||
if (atomic_add_return(2, &priv->start) > 2) {
|
||||
atomic_sub(2, &priv->start);
|
||||
return 0;
|
||||
}
|
||||
|
||||
l = bus->usb.streaming_xfer_size;
|
||||
n = bus->usb.streaming_urb_num;
|
||||
no_dma = bus->usb.streaming_no_dma;
|
||||
|
||||
ctx->on_stream = on_stream;
|
||||
ctx->ctx = context;
|
||||
|
||||
urbs = kcalloc(n, sizeof(*urbs), GFP_KERNEL);
|
||||
if (!urbs) {
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
void *p;
|
||||
dma_addr_t dma;
|
||||
|
||||
urbs[i] = usb_alloc_urb(0, GFP_ATOMIC | __GFP_ZERO);
|
||||
if (!urbs[i]) {
|
||||
dev_dbg(bus->dev, "it930x_usb_start_streaming: usb_alloc_urb() failed.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!no_dma)
|
||||
p = usb_alloc_coherent(dev, l, GFP_ATOMIC, &dma);
|
||||
else
|
||||
p = kmalloc(l, GFP_ATOMIC);
|
||||
|
||||
if (!p) {
|
||||
dev_dbg(bus->dev, "it930x_usb_start_streaming: usb_alloc_coherent() failed.\n");
|
||||
|
||||
usb_free_urb(urbs[i]);
|
||||
urbs[i] = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
dev_dbg(bus->dev, "it930x_usb_start_streaming: p: %p, l: %u, dma: %pad\n", p, l, &dma);
|
||||
|
||||
usb_fill_bulk_urb(urbs[i], dev, usb_rcvbulkpipe(dev, 0x84), p, l, it930x_usb_complete, ctx);
|
||||
|
||||
if (!no_dma) {
|
||||
urbs[i]->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
|
||||
urbs[i]->transfer_dma = dma;
|
||||
}
|
||||
}
|
||||
|
||||
n = i;
|
||||
|
||||
if (!n) {
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
usb_reset_endpoint(dev, 0x84);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
ret = usb_submit_urb(urbs[i], GFP_ATOMIC);
|
||||
if (ret) {
|
||||
int j;
|
||||
|
||||
dev_dbg(bus->dev, "it930x_usb_start_streaming: usb_submit_urb() failed. (i: %u, ret: %d)\n", i, ret);
|
||||
|
||||
for (j = 0; j < i; j++)
|
||||
usb_kill_urb(urbs[j]);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
dev_dbg(bus->dev, "it930x_usb_start_streaming: n: %u\n", n);
|
||||
|
||||
priv->urbs = urbs;
|
||||
priv->num_urb = n;
|
||||
priv->no_dma = no_dma;
|
||||
|
||||
atomic_sub(1, &priv->start);
|
||||
|
||||
return ret;
|
||||
|
||||
fail:
|
||||
free_urb_buffers(dev, urbs, n, true, no_dma);
|
||||
kfree(urbs);
|
||||
|
||||
atomic_sub(2, &priv->start);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int it930x_usb_stop_streaming(struct it930x_bus *bus)
|
||||
{
|
||||
u32 i, n;
|
||||
struct usb_device *dev = bus->usb.dev;
|
||||
struct priv_data_usb *priv = bus->usb.priv;
|
||||
struct urb **urbs = priv->urbs;
|
||||
|
||||
dev_dbg(bus->dev, "it930x_usb_stop_streaming\n");
|
||||
|
||||
if (atomic_read(&priv->start) != 1)
|
||||
return 0;
|
||||
|
||||
n = priv->num_urb;
|
||||
|
||||
if (urbs) {
|
||||
for (i = 0; i < n; i++)
|
||||
usb_kill_urb(urbs[i]);
|
||||
|
||||
free_urb_buffers(dev, urbs, n, true, priv->no_dma);
|
||||
kfree(urbs);
|
||||
|
||||
priv->urbs = NULL;
|
||||
}
|
||||
|
||||
priv->num_urb = 0;
|
||||
priv->no_dma = false;
|
||||
|
||||
atomic_set(&priv->start, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int it930x_bus_init(struct it930x_bus *bus)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!bus)
|
||||
return -EINVAL;
|
||||
|
||||
switch(bus->type) {
|
||||
case IT930X_BUS_USB:
|
||||
if (!bus->usb.dev) {
|
||||
ret = -EINVAL;
|
||||
} else {
|
||||
struct priv_data_usb *priv;
|
||||
|
||||
priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
|
||||
if (!priv) {
|
||||
ret = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
|
||||
usb_get_dev(bus->usb.dev);
|
||||
|
||||
priv->urbs = NULL;
|
||||
priv->num_urb = 0;
|
||||
priv->no_dma = false;
|
||||
priv->ctx.bus = bus;
|
||||
atomic_set(&priv->start, 0);
|
||||
|
||||
bus->usb.priv = priv;
|
||||
|
||||
bus->ops.ctrl_tx = it930x_usb_ctrl_tx;
|
||||
bus->ops.ctrl_rx = it930x_usb_ctrl_rx;
|
||||
bus->ops.stream_rx = it930x_usb_stream_rx;
|
||||
bus->ops.start_streaming = it930x_usb_start_streaming;
|
||||
bus->ops.stop_streaming = it930x_usb_stop_streaming;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int it930x_bus_term(struct it930x_bus *bus)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!bus) {
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
switch(bus->type) {
|
||||
case IT930X_BUS_USB:
|
||||
{
|
||||
struct priv_data_usb *priv = bus->usb.priv;
|
||||
|
||||
if (priv) {
|
||||
it930x_usb_stop_streaming(bus);
|
||||
kfree(priv);
|
||||
}
|
||||
if (bus->usb.dev)
|
||||
usb_put_dev(bus->usb.dev);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
memset(bus, 0, sizeof(struct it930x_bus));
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
@@ -1,87 +0,0 @@
|
||||
// it930x-bus.h
|
||||
|
||||
#ifndef __IT930X_BUS_H__
|
||||
#define __IT930X_BUS_H__
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/usb.h>
|
||||
|
||||
#include "it930x-config.h"
|
||||
|
||||
typedef enum {
|
||||
IT930X_BUS_NONE = 0,
|
||||
IT930X_BUS_USB,
|
||||
} it930x_bus_type_t;
|
||||
|
||||
typedef int (*it930x_bus_on_stream_t)(void *context, void *buf, u32 len);
|
||||
|
||||
struct it930x_bus;
|
||||
|
||||
struct it930x_bus_operations {
|
||||
int (*ctrl_tx)(struct it930x_bus *bus, const void *buf, int len, void *opt);
|
||||
int (*ctrl_rx)(struct it930x_bus *bus, void *buf, int *len, void *opt);
|
||||
int (*stream_rx)(struct it930x_bus *bus, void *buf, int *len, int timeout);
|
||||
int (*start_streaming)(struct it930x_bus *bus, it930x_bus_on_stream_t on_stream, void *context);
|
||||
int (*stop_streaming)(struct it930x_bus *bus);
|
||||
};
|
||||
|
||||
struct it930x_bus {
|
||||
struct device *dev;
|
||||
it930x_bus_type_t type;
|
||||
union {
|
||||
struct {
|
||||
struct usb_device *dev;
|
||||
int ctrl_timeout;
|
||||
u32 streaming_xfer_size;
|
||||
u32 streaming_urb_num;
|
||||
bool streaming_no_dma;
|
||||
void *priv;
|
||||
} usb;
|
||||
};
|
||||
struct it930x_bus_operations ops;
|
||||
};
|
||||
|
||||
int it930x_bus_init(struct it930x_bus *bus);
|
||||
int it930x_bus_term(struct it930x_bus *bus);
|
||||
|
||||
static inline int it930x_bus_ctrl_tx(struct it930x_bus *bus, const void *buf, int len, void *opt)
|
||||
{
|
||||
if (!bus || !bus->ops.ctrl_tx)
|
||||
return -EINVAL;
|
||||
|
||||
return bus->ops.ctrl_tx(bus, buf, len, opt);
|
||||
}
|
||||
|
||||
static inline int it930x_bus_ctrl_rx(struct it930x_bus *bus, void *buf, int *len, void *opt)
|
||||
{
|
||||
if (!bus || !bus->ops.ctrl_rx)
|
||||
return -EINVAL;
|
||||
|
||||
return bus->ops.ctrl_rx(bus, buf, len, opt);
|
||||
}
|
||||
|
||||
static inline int it930x_bus_stream_rx(struct it930x_bus *bus, void *buf, int *len, int timeout)
|
||||
{
|
||||
if (!bus || !bus->ops.stream_rx)
|
||||
return -EINVAL;
|
||||
|
||||
return bus->ops.stream_rx(bus, buf, len, timeout);
|
||||
}
|
||||
|
||||
static inline int it930x_bus_start_streaming(struct it930x_bus *bus, it930x_bus_on_stream_t on_stream, void *context)
|
||||
{
|
||||
if (!bus || !bus->ops.start_streaming)
|
||||
return -EINVAL;
|
||||
|
||||
return bus->ops.start_streaming(bus, on_stream, context);
|
||||
}
|
||||
|
||||
static inline int it930x_bus_stop_streaming(struct it930x_bus *bus)
|
||||
{
|
||||
if (!bus || !bus->ops.stop_streaming)
|
||||
return -EINVAL;
|
||||
|
||||
return bus->ops.stop_streaming(bus);
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,12 +0,0 @@
|
||||
// it930x-config.h
|
||||
|
||||
#ifndef __IT930X_CONFIG_H__
|
||||
#define __IT930X_CONFIG_H__
|
||||
|
||||
// USB
|
||||
#define IT930X_USB_MAX_CONTROL_TRANSFER_SIZE 63
|
||||
|
||||
// I2C
|
||||
#define IT930X_I2C_SPEED 0x07
|
||||
|
||||
#endif
|
1392
driver/it930x.c
1392
driver/it930x.c
File diff suppressed because it is too large
Load Diff
103
driver/it930x.h
103
driver/it930x.h
@@ -1,13 +1,21 @@
|
||||
// it930x.h
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* ITE IT930x driver definitions (it930x.h)
|
||||
*
|
||||
* Copyright (c) 2018-2021 nns779
|
||||
*/
|
||||
|
||||
#ifndef __IT930X_H__
|
||||
#define __IT930X_H__
|
||||
|
||||
#ifdef __linux__
|
||||
#include <linux/types.h>
|
||||
#include <linux/device.h>
|
||||
#elif defined(_WIN32) || defined(_WIN64)
|
||||
#include "misc_win.h"
|
||||
#endif
|
||||
|
||||
#include "it930x-config.h"
|
||||
#include "it930x-bus.h"
|
||||
#include "itedtv_bus.h"
|
||||
#include "i2c_comm.h"
|
||||
|
||||
#define IT930X_CMD_REG_READ 0x00
|
||||
@@ -18,9 +26,16 @@
|
||||
#define IT930X_CMD_I2C_READ 0x2a
|
||||
#define IT930X_CMD_I2C_WRITE 0x2b
|
||||
|
||||
struct it930x_i2c_master_info {
|
||||
struct it930x_bridge *it930x;
|
||||
u8 bus;
|
||||
enum it930x_gpio_mode {
|
||||
IT930X_GPIO_UNDEFINED = 0,
|
||||
IT930X_GPIO_IN,
|
||||
IT930X_GPIO_OUT,
|
||||
};
|
||||
|
||||
struct it930x_pid_filter {
|
||||
bool block;
|
||||
int num;
|
||||
u16 pid[64];
|
||||
};
|
||||
|
||||
struct it930x_stream_input {
|
||||
@@ -34,53 +49,53 @@ struct it930x_stream_input {
|
||||
u8 sync_byte;
|
||||
};
|
||||
|
||||
struct it930x_config {
|
||||
u32 xfer_size;
|
||||
u8 i2c_speed;
|
||||
struct it930x_stream_input input[5];
|
||||
};
|
||||
|
||||
struct it930x_bridge {
|
||||
struct device *dev;
|
||||
struct it930x_bus bus;
|
||||
u32 fw_version;
|
||||
struct it930x_stream_input input[5];
|
||||
struct it930x_i2c_master_info i2c[2];
|
||||
struct i2c_comm_master i2c_master[2];
|
||||
u8 buf[255];
|
||||
u8 sequence;
|
||||
struct itedtv_bus bus;
|
||||
struct it930x_config config;
|
||||
struct i2c_comm_master i2c_master[3];
|
||||
void *priv;
|
||||
};
|
||||
|
||||
struct it930x_regbuf {
|
||||
u32 reg;
|
||||
u8 *buf;
|
||||
union {
|
||||
u8 val; // buf == NULL (write only)
|
||||
u8 len; // buf != NULL
|
||||
} u;
|
||||
};
|
||||
|
||||
static inline void it930x_regbuf_set_val(struct it930x_regbuf *regbuf, u32 reg, u8 val)
|
||||
{
|
||||
regbuf->reg = reg;
|
||||
regbuf->buf = NULL;
|
||||
regbuf->u.val = val;
|
||||
}
|
||||
|
||||
static inline void it930x_regbuf_set_buf(struct it930x_regbuf *regbuf, u32 reg, u8 *buf, u8 len)
|
||||
{
|
||||
regbuf->reg = reg;
|
||||
regbuf->buf = buf;
|
||||
regbuf->u.len = len;
|
||||
}
|
||||
|
||||
int it930x_write_regs(struct it930x_bridge *it930x, struct it930x_regbuf *regbuf, int num_regbuf);
|
||||
int it930x_write_reg(struct it930x_bridge *it930x, u32 reg, u8 val);
|
||||
int it930x_write_reg_bits(struct it930x_bridge *it930x, u32 reg, u8 val, u8 pos, u8 len);
|
||||
int it930x_read_regs(struct it930x_bridge *it930x, struct it930x_regbuf *regbuf, int num_regbuf);
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
int it930x_read_regs(struct it930x_bridge *it930x,
|
||||
u32 reg,
|
||||
u8 *rbuf, u8 len);
|
||||
int it930x_read_reg(struct it930x_bridge *it930x, u32 reg, u8 *val);
|
||||
int it930x_write_regs(struct it930x_bridge *it930x,
|
||||
u32 reg,
|
||||
u8 *wbuf, u8 len);
|
||||
int it930x_write_reg(struct it930x_bridge *it930x, u32 reg, u8 val);
|
||||
int it930x_write_reg_mask(struct it930x_bridge *it930x,
|
||||
u32 reg,
|
||||
u8 val, u8 mask);
|
||||
|
||||
int it930x_init(struct it930x_bridge *it930x);
|
||||
int it930x_term(struct it930x_bridge *it930x);
|
||||
|
||||
int it930x_raise(struct it930x_bridge *it930x);
|
||||
int it930x_load_firmware(struct it930x_bridge *it930x, const char *filename);
|
||||
int it930x_init_device(struct it930x_bridge *it930x);
|
||||
int it930x_set_gpio(struct it930x_bridge *it930x, int gpio, bool h);
|
||||
int it930x_enable_stream_input(struct it930x_bridge *it930x, u8 input_idx, bool enable);
|
||||
int it930x_purge_psb(struct it930x_bridge *it930x);
|
||||
int it930x_init_warm(struct it930x_bridge *it930x);
|
||||
int it930x_set_gpio_mode(struct it930x_bridge *it930x,
|
||||
int gpio,
|
||||
enum it930x_gpio_mode mode,
|
||||
bool enable);
|
||||
int it930x_enable_gpio(struct it930x_bridge *it930x, int gpio, bool enable);
|
||||
int it930x_read_gpio(struct it930x_bridge *it930x, int gpio, bool *high);
|
||||
int it930x_write_gpio(struct it930x_bridge *it930x, int gpio, bool high);
|
||||
int it930x_set_pid_filter(struct it930x_bridge *it930x, int input_idx,
|
||||
struct it930x_pid_filter *filter);
|
||||
int it930x_purge_psb(struct it930x_bridge *it930x, int timeout);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
645
driver/itedtv_bus.c
Normal file
645
driver/itedtv_bus.c
Normal file
@@ -0,0 +1,645 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* ITE IT930x bus driver (itedtv_bus.c)
|
||||
*
|
||||
* Copyright (c) 2018-2021 nns779
|
||||
*/
|
||||
|
||||
#include "print_format.h"
|
||||
#include "itedtv_bus.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/slab.h>
|
||||
#endif
|
||||
|
||||
#if defined(ITEDTV_BUS_USE_WORKQUEUE) && !defined(__linux__)
|
||||
#undef ITEDTV_BUS_USE_WORKQUEUE
|
||||
#endif
|
||||
|
||||
struct itedtv_usb_context;
|
||||
|
||||
struct itedtv_usb_work {
|
||||
struct itedtv_usb_context *ctx;
|
||||
struct urb *urb;
|
||||
#ifdef ITEDTV_BUS_USE_WORKQUEUE
|
||||
struct work_struct work;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct itedtv_usb_context {
|
||||
struct mutex lock;
|
||||
struct itedtv_bus *bus;
|
||||
itedtv_bus_stream_handler_t stream_handler;
|
||||
void *ctx;
|
||||
u32 num_urb;
|
||||
bool no_dma;
|
||||
#ifdef ITEDTV_BUS_USE_WORKQUEUE
|
||||
struct workqueue_struct *wq;
|
||||
#endif
|
||||
u32 num_works;
|
||||
struct itedtv_usb_work *works;
|
||||
atomic_t streaming;
|
||||
};
|
||||
|
||||
static int itedtv_usb_ctrl_tx(struct itedtv_bus *bus, void *buf, int len)
|
||||
{
|
||||
int ret = 0, rlen = 0;
|
||||
struct usb_device *dev = bus->usb.dev;
|
||||
|
||||
if (unlikely(!buf || !len))
|
||||
return -EINVAL;
|
||||
|
||||
/* Endpoint 0x02: Host->Device bulk endpoint for controlling the device */
|
||||
ret = usb_bulk_msg(dev,
|
||||
usb_sndbulkpipe(dev, 0x02),
|
||||
buf, len,
|
||||
&rlen, bus->usb.ctrl_timeout);
|
||||
|
||||
if (ret) {
|
||||
dev_err(bus->dev,
|
||||
"itedtv_usb_ctrl_tx: usb_bulk_msg() failed. (ret: %d)\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
mdelay(1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int itedtv_usb_ctrl_rx(struct itedtv_bus *bus, void *buf, int *len)
|
||||
{
|
||||
int ret = 0, rlen = 0;
|
||||
struct usb_device *dev = bus->usb.dev;
|
||||
|
||||
if (unlikely(!buf || !len || !*len))
|
||||
return -EINVAL;
|
||||
|
||||
/* Endpoint 0x81: Device->Host bulk endpoint for controlling the device */
|
||||
ret = usb_bulk_msg(dev,
|
||||
usb_rcvbulkpipe(dev, 0x81),
|
||||
buf, *len,
|
||||
&rlen, bus->usb.ctrl_timeout);
|
||||
|
||||
if (ret) {
|
||||
dev_err(bus->dev,
|
||||
"itedtv_usb_ctrl_rx: usb_bulk_msg() failed. (ret: %d)\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
*len = rlen;
|
||||
|
||||
mdelay(1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int itedtv_usb_stream_rx(struct itedtv_bus *bus,
|
||||
void *buf, int *len,
|
||||
int timeout)
|
||||
{
|
||||
int ret = 0, rlen = 0;
|
||||
struct usb_device *dev = bus->usb.dev;
|
||||
|
||||
if (unlikely(!buf | !len || !*len))
|
||||
return -EINVAL;
|
||||
|
||||
/* Endpoint 0x84: Device->Host bulk endpoint for receiving TS from the device */
|
||||
ret = usb_bulk_msg(dev,
|
||||
usb_rcvbulkpipe(dev, 0x84),
|
||||
buf, *len,
|
||||
&rlen, timeout);
|
||||
|
||||
*len = rlen;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef ITEDTV_BUS_USE_WORKQUEUE
|
||||
static void itedtv_usb_workqueue_handler(struct work_struct *work)
|
||||
{
|
||||
int ret = 0;
|
||||
struct itedtv_usb_work *w = container_of(work,
|
||||
struct itedtv_usb_work, work);
|
||||
struct itedtv_usb_context *ctx = w->ctx;
|
||||
struct urb *urb = w->urb;
|
||||
|
||||
if (likely(urb->actual_length))
|
||||
ret = ctx->stream_handler(ctx->ctx,
|
||||
urb->transfer_buffer,
|
||||
urb->actual_length);
|
||||
else
|
||||
dev_dbg(ctx->bus->dev,
|
||||
"itedtv_usb_workqueue_handler: !urb->actual_length\n");
|
||||
|
||||
if (unlikely(ret || (atomic_read_acquire(&ctx->streaming) < 1)))
|
||||
return;
|
||||
|
||||
ret = usb_submit_urb(urb, GFP_KERNEL);
|
||||
if (unlikely(ret))
|
||||
dev_err(ctx->bus->dev,
|
||||
"itedtv_usb_workqueue_handler: usb_submit_urb() failed. (ret: %d)\n",
|
||||
ret);
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void itedtv_usb_complete(struct urb *urb)
|
||||
{
|
||||
#ifndef ITEDTV_BUS_USE_WORKQUEUE
|
||||
int ret = 0;
|
||||
#endif
|
||||
struct itedtv_usb_work *w = urb->context;
|
||||
struct itedtv_usb_context *ctx = w->ctx;
|
||||
|
||||
if (unlikely(urb->status)) {
|
||||
dev_dbg(ctx->bus->dev,
|
||||
"itedtv_usb_complete: status: %d\n",
|
||||
urb->status);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef ITEDTV_BUS_USE_WORKQUEUE
|
||||
if (unlikely(!queue_work(ctx->wq, &w->work)))
|
||||
dev_err(ctx->bus->dev,
|
||||
"itedtv_usb_complete: queue_work() failed.\n");
|
||||
#else
|
||||
if (likely(urb->actual_length))
|
||||
ret = ctx->stream_handler(ctx->ctx,
|
||||
urb->transfer_buffer,
|
||||
urb->actual_length);
|
||||
else
|
||||
dev_dbg(ctx->bus->dev,
|
||||
"itedtv_usb_complete: !urb->actual_length\n");
|
||||
|
||||
if (unlikely(ret || (atomic_read_acquire(&ctx->streaming) < 1)))
|
||||
return;
|
||||
|
||||
ret = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (unlikely(ret))
|
||||
dev_err(ctx->bus->dev,
|
||||
"itedtv_usb_complete: usb_submit_urb() failed. (ret: %d)\n",
|
||||
ret);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int itedtv_usb_alloc_urb_buffers(struct itedtv_usb_context *ctx,
|
||||
u32 buf_size)
|
||||
{
|
||||
u32 i;
|
||||
struct itedtv_bus *bus = ctx->bus;
|
||||
struct usb_device *dev = bus->usb.dev;
|
||||
u32 num = ctx->num_works;
|
||||
bool no_dma = ctx->no_dma;
|
||||
struct itedtv_usb_work *works = ctx->works;
|
||||
|
||||
if (!works)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
struct urb *urb;
|
||||
void *p;
|
||||
#ifdef __linux__
|
||||
dma_addr_t dma;
|
||||
#endif
|
||||
|
||||
if (works[i].urb) {
|
||||
urb = works[i].urb;
|
||||
|
||||
if (urb->transfer_buffer) {
|
||||
#ifdef __linux__
|
||||
if ((urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) &&
|
||||
(no_dma || urb->transfer_buffer_length != buf_size)) {
|
||||
usb_free_coherent(dev,
|
||||
urb->transfer_buffer_length,
|
||||
urb->transfer_buffer,
|
||||
urb->transfer_dma);
|
||||
urb->transfer_flags &= ~URB_NO_TRANSFER_DMA_MAP;
|
||||
urb->transfer_dma = 0;
|
||||
|
||||
urb->transfer_buffer = NULL;
|
||||
urb->transfer_buffer_length = 0;
|
||||
urb->actual_length = 0;
|
||||
} else if (!(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) &&
|
||||
(!no_dma || urb->transfer_buffer_length != buf_size)) {
|
||||
kfree(urb->transfer_buffer);
|
||||
|
||||
urb->transfer_buffer = NULL;
|
||||
urb->transfer_buffer_length = 0;
|
||||
urb->actual_length = 0;
|
||||
}
|
||||
#else
|
||||
kfree(urb->transfer_buffer);
|
||||
|
||||
urb->transfer_buffer = NULL;
|
||||
urb->transfer_buffer_length = 0;
|
||||
urb->actual_length = 0;
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (!urb) {
|
||||
dev_err(bus->dev,
|
||||
"itedtv_usb_alloc_urb_buffers: usb_alloc_urb() failed. (i: %u)\n",
|
||||
i);
|
||||
break;
|
||||
}
|
||||
|
||||
works[i].urb = urb;
|
||||
}
|
||||
|
||||
works[i].ctx = ctx;
|
||||
|
||||
if (!urb->transfer_buffer) {
|
||||
#ifdef __linux__
|
||||
#ifdef __GFP_RETRY_MAYFAIL
|
||||
if (!no_dma)
|
||||
p = usb_alloc_coherent(dev, buf_size,
|
||||
GFP_KERNEL | __GFP_RETRY_MAYFAIL, &dma);
|
||||
else
|
||||
p = kmalloc(buf_size, GFP_KERNEL | __GFP_RETRY_MAYFAIL);
|
||||
#else
|
||||
if (!no_dma)
|
||||
p = usb_alloc_coherent(dev, buf_size,
|
||||
GFP_KERNEL | __GFP_REPEAT, &dma);
|
||||
else
|
||||
p = kmalloc(buf_size, GFP_KERNEL | __GFP_REPEAT);
|
||||
#endif
|
||||
#else
|
||||
p = kmalloc(buf_size, GFP_KERNEL);
|
||||
#endif
|
||||
|
||||
if (!p) {
|
||||
#ifdef __linux__
|
||||
if (!no_dma)
|
||||
dev_err(bus->dev,
|
||||
"itedtv_usb_alloc_urb_buffers: usb_alloc_coherent() failed. (i: %u)\n",
|
||||
i);
|
||||
else
|
||||
dev_err(bus->dev,
|
||||
"itedtv_usb_alloc_urb_buffers: kmalloc() failed. (i: %u)\n",
|
||||
i);
|
||||
#else
|
||||
dev_err(bus->dev,
|
||||
"itedtv_usb_alloc_urb_buffers: kmalloc() failed. (i: %u)\n",
|
||||
i);
|
||||
#endif
|
||||
|
||||
usb_free_urb(urb);
|
||||
works[i].urb = NULL;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
dev_dbg(bus->dev,
|
||||
"itedtv_usb_alloc_urb_buffers: p: %p, buf_size: %u, dma: %pad\n",
|
||||
p, buf_size, &dma);
|
||||
#else
|
||||
dev_dbg(bus->dev,
|
||||
"itedtv_usb_alloc_urb_buffers: p: %p, buf_size: %u\n",
|
||||
p, buf_size);
|
||||
#endif
|
||||
|
||||
usb_fill_bulk_urb(urb, dev,
|
||||
usb_rcvbulkpipe(dev, 0x84),
|
||||
p, buf_size,
|
||||
itedtv_usb_complete, &works[i]);
|
||||
|
||||
#ifdef __linux__
|
||||
if (!no_dma) {
|
||||
urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
|
||||
urb->transfer_dma = dma;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ITEDTV_BUS_USE_WORKQUEUE
|
||||
INIT_WORK(&works[i].work, itedtv_usb_workqueue_handler);
|
||||
#endif
|
||||
}
|
||||
|
||||
ctx->num_urb = i;
|
||||
|
||||
if (!i)
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void itedtv_usb_free_urb_buffers(struct itedtv_usb_context *ctx,
|
||||
bool free_urb)
|
||||
{
|
||||
u32 i;
|
||||
struct usb_device *dev = ctx->bus->usb.dev;
|
||||
u32 num = ctx->num_works;
|
||||
bool no_dma = ctx->no_dma;
|
||||
struct itedtv_usb_work *works = ctx->works;
|
||||
|
||||
if (!works)
|
||||
return;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
struct urb *urb = works[i].urb;
|
||||
|
||||
if (!urb)
|
||||
continue;
|
||||
|
||||
if (urb->transfer_buffer) {
|
||||
#ifdef __linux__
|
||||
if (!no_dma) {
|
||||
usb_free_coherent(dev,
|
||||
urb->transfer_buffer_length,
|
||||
urb->transfer_buffer,
|
||||
urb->transfer_dma);
|
||||
urb->transfer_flags &= ~URB_NO_TRANSFER_DMA_MAP;
|
||||
urb->transfer_dma = 0;
|
||||
} else {
|
||||
kfree(urb->transfer_buffer);
|
||||
}
|
||||
#else
|
||||
kfree(urb->transfer_buffer);
|
||||
#endif
|
||||
|
||||
urb->transfer_buffer = NULL;
|
||||
urb->transfer_buffer_length = 0;
|
||||
urb->actual_length = 0;
|
||||
}
|
||||
|
||||
if (free_urb) {
|
||||
usb_free_urb(urb);
|
||||
works[i].urb = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (free_urb)
|
||||
ctx->num_urb = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void itedtv_usb_clean_context(struct itedtv_usb_context *ctx, bool free_works)
|
||||
{
|
||||
#ifdef ITEDTV_BUS_USE_WORKQUEUE
|
||||
if (ctx->wq)
|
||||
destroy_workqueue(ctx->wq);
|
||||
#endif
|
||||
|
||||
if (free_works && ctx->works) {
|
||||
itedtv_usb_free_urb_buffers(ctx, true);
|
||||
kfree(ctx->works);
|
||||
ctx->num_urb = 0;
|
||||
ctx->works = NULL;
|
||||
ctx->num_works = 0;
|
||||
}
|
||||
|
||||
ctx->stream_handler = NULL;
|
||||
ctx->ctx = NULL;
|
||||
ctx->no_dma = false;
|
||||
#ifdef ITEDTV_BUS_USE_WORKQUEUE
|
||||
ctx->wq = NULL;
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int itedtv_usb_start_streaming(struct itedtv_bus *bus,
|
||||
itedtv_bus_stream_handler_t stream_handler,
|
||||
void *context)
|
||||
{
|
||||
int ret = 0;
|
||||
u32 i, buf_size, num;
|
||||
struct itedtv_usb_context *ctx = bus->usb.priv;
|
||||
struct itedtv_usb_work *works;
|
||||
|
||||
if (!stream_handler)
|
||||
return -EINVAL;
|
||||
|
||||
dev_dbg(bus->dev, "itedtv_usb_start_streaming\n");
|
||||
|
||||
mutex_lock(&ctx->lock);
|
||||
|
||||
ctx->stream_handler = stream_handler;
|
||||
ctx->ctx = context;
|
||||
|
||||
buf_size = bus->usb.streaming.urb_buffer_size;
|
||||
num = bus->usb.streaming.urb_num;
|
||||
ctx->no_dma = bus->usb.streaming.no_dma;
|
||||
|
||||
if (ctx->works && num != ctx->num_works) {
|
||||
itedtv_usb_free_urb_buffers(ctx, true);
|
||||
kfree(ctx->works);
|
||||
ctx->works = NULL;
|
||||
}
|
||||
|
||||
ctx->num_works = num;
|
||||
|
||||
if (!ctx->works) {
|
||||
ctx->works = kcalloc(ctx->num_works,
|
||||
sizeof(*works), GFP_KERNEL);
|
||||
if (!ctx->works) {
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
ret = itedtv_usb_alloc_urb_buffers(ctx, buf_size);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
#ifdef ITEDTV_BUS_USE_WORKQUEUE
|
||||
if (!ctx->wq) {
|
||||
ctx->wq = create_singlethread_workqueue("itedtv_usb_workqueue");
|
||||
if (!ctx->wq) {
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
usb_reset_endpoint(bus->usb.dev, 0x84);
|
||||
atomic_xchg(&ctx->streaming, 1);
|
||||
|
||||
num = ctx->num_urb;
|
||||
works = ctx->works;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
ret = usb_submit_urb(works[i].urb, GFP_KERNEL);
|
||||
if (ret) {
|
||||
u32 j;
|
||||
|
||||
dev_err(bus->dev,
|
||||
"itedtv_usb_start_streaming: usb_submit_urb() failed. (i: %u, ret: %d)\n",
|
||||
i, ret);
|
||||
|
||||
for (j = 0; j < i; j++)
|
||||
usb_kill_urb(works[i].urb);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
dev_dbg(bus->dev, "itedtv_usb_start_streaming: num: %u\n", num);
|
||||
|
||||
mutex_unlock(&ctx->lock);
|
||||
|
||||
return ret;
|
||||
|
||||
fail:
|
||||
atomic_xchg(&ctx->streaming, 0);
|
||||
|
||||
#ifdef ITEDTV_BUS_USE_WORKQUEUE
|
||||
if (ctx->wq)
|
||||
flush_workqueue(ctx->wq);
|
||||
#endif
|
||||
|
||||
itedtv_usb_clean_context(ctx, true);
|
||||
|
||||
mutex_unlock(&ctx->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int itedtv_usb_stop_streaming(struct itedtv_bus *bus)
|
||||
{
|
||||
u32 i;
|
||||
struct itedtv_usb_context *ctx = bus->usb.priv;
|
||||
|
||||
dev_dbg(bus->dev, "itedtv_usb_stop_streaming\n");
|
||||
|
||||
mutex_lock(&ctx->lock);
|
||||
|
||||
atomic_xchg(&ctx->streaming, 0);
|
||||
|
||||
#ifdef ITEDTV_BUS_USE_WORKQUEUE
|
||||
if (ctx->wq)
|
||||
flush_workqueue(ctx->wq);
|
||||
#endif
|
||||
|
||||
if (ctx->works) {
|
||||
u32 num = ctx->num_urb;
|
||||
struct itedtv_usb_work *works = ctx->works;
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
usb_kill_urb(works[i].urb);
|
||||
}
|
||||
|
||||
itedtv_usb_clean_context(ctx, false);
|
||||
|
||||
mutex_unlock(&ctx->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int itedtv_bus_init(struct itedtv_bus *bus)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!bus)
|
||||
return -EINVAL;
|
||||
|
||||
switch (bus->type) {
|
||||
case ITEDTV_BUS_USB:
|
||||
{
|
||||
struct itedtv_usb_context *ctx;
|
||||
|
||||
if (!bus->usb.dev) {
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (bus->usb.dev->descriptor.bcdUSB < 0x0110) {
|
||||
ret = -EIO;
|
||||
break;
|
||||
}
|
||||
|
||||
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
|
||||
if (!ctx) {
|
||||
ret = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
|
||||
usb_get_dev(bus->usb.dev);
|
||||
|
||||
mutex_init(&ctx->lock);
|
||||
ctx->bus = bus;
|
||||
ctx->stream_handler = NULL;
|
||||
ctx->ctx = NULL;
|
||||
ctx->num_urb = 0;
|
||||
ctx->no_dma = false;
|
||||
#ifdef ITEDTV_BUS_USE_WORKQUEUE
|
||||
ctx->wq = NULL;
|
||||
#endif
|
||||
ctx->num_works = 0;
|
||||
ctx->works = NULL;
|
||||
atomic_set(&ctx->streaming, 0);
|
||||
|
||||
bus->usb.priv = ctx;
|
||||
|
||||
if (!bus->usb.max_bulk_size)
|
||||
bus->usb.max_bulk_size = (bus->usb.dev->descriptor.bcdUSB == 0x0110) ? 64
|
||||
: 512;
|
||||
|
||||
bus->ops.ctrl_tx = itedtv_usb_ctrl_tx;
|
||||
bus->ops.ctrl_rx = itedtv_usb_ctrl_rx;
|
||||
bus->ops.stream_rx = itedtv_usb_stream_rx;
|
||||
bus->ops.start_streaming = itedtv_usb_start_streaming;
|
||||
bus->ops.stop_streaming = itedtv_usb_stop_streaming;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int itedtv_bus_term(struct itedtv_bus *bus)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!bus) {
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
switch (bus->type) {
|
||||
case ITEDTV_BUS_USB:
|
||||
{
|
||||
struct itedtv_usb_context *ctx = bus->usb.priv;
|
||||
|
||||
if (ctx) {
|
||||
if (atomic_read_acquire(&ctx->streaming))
|
||||
itedtv_usb_stop_streaming(bus);
|
||||
|
||||
itedtv_usb_clean_context(ctx, true);
|
||||
mutex_destroy(&ctx->lock);
|
||||
kfree(ctx);
|
||||
}
|
||||
|
||||
if (bus->usb.dev)
|
||||
usb_put_dev(bus->usb.dev);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
memset(bus, 0, sizeof(*bus));
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
115
driver/itedtv_bus.h
Normal file
115
driver/itedtv_bus.h
Normal file
@@ -0,0 +1,115 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* ITE IT930x bus driver definitions (itedtv_bus.h)
|
||||
*
|
||||
* Copyright (c) 2018-2021 nns779
|
||||
*/
|
||||
|
||||
#ifndef __ITEDTV_BUS_H__
|
||||
#define __ITEDTV_BUS_H__
|
||||
|
||||
#ifdef __linux__
|
||||
#include <linux/device.h>
|
||||
#include <linux/usb.h>
|
||||
#elif defined(_WIN32) || defined(_WIN64)
|
||||
#include "misc_win.h"
|
||||
#include "winusb_compat.h"
|
||||
#endif
|
||||
|
||||
enum itedtv_bus_type {
|
||||
ITEDTV_BUS_NONE = 0,
|
||||
ITEDTV_BUS_USB,
|
||||
};
|
||||
|
||||
typedef int (*itedtv_bus_stream_handler_t)(void *context, void *buf, u32 len);
|
||||
|
||||
struct itedtv_bus;
|
||||
|
||||
struct itedtv_bus_operations {
|
||||
int (*ctrl_tx)(struct itedtv_bus *bus, void *buf, int len);
|
||||
int (*ctrl_rx)(struct itedtv_bus *bus, void *buf, int *len);
|
||||
int (*stream_rx)(struct itedtv_bus *bus,
|
||||
void *buf, int *len,
|
||||
int timeout);
|
||||
int (*start_streaming)(struct itedtv_bus *bus,
|
||||
itedtv_bus_stream_handler_t stream_handler,
|
||||
void *context);
|
||||
int (*stop_streaming)(struct itedtv_bus *bus);
|
||||
};
|
||||
|
||||
struct itedtv_bus {
|
||||
struct device *dev;
|
||||
enum itedtv_bus_type type;
|
||||
union {
|
||||
struct {
|
||||
struct usb_device *dev;
|
||||
int ctrl_timeout;
|
||||
int max_bulk_size;
|
||||
struct {
|
||||
u32 urb_buffer_size;
|
||||
u32 urb_num;
|
||||
bool no_dma; // for Linux
|
||||
bool no_raw_io; // for Windows(WinUSB)
|
||||
} streaming;
|
||||
void *priv;
|
||||
} usb;
|
||||
};
|
||||
struct itedtv_bus_operations ops;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
int itedtv_bus_init(struct itedtv_bus *bus);
|
||||
int itedtv_bus_term(struct itedtv_bus *bus);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int itedtv_bus_ctrl_tx(struct itedtv_bus *bus,
|
||||
void *buf, int len)
|
||||
{
|
||||
if (!bus || !bus->ops.ctrl_tx)
|
||||
return -EINVAL;
|
||||
|
||||
return bus->ops.ctrl_tx(bus, buf, len);
|
||||
}
|
||||
|
||||
static inline int itedtv_bus_ctrl_rx(struct itedtv_bus *bus,
|
||||
void *buf, int *len)
|
||||
{
|
||||
if (!bus || !bus->ops.ctrl_rx)
|
||||
return -EINVAL;
|
||||
|
||||
return bus->ops.ctrl_rx(bus, buf, len);
|
||||
}
|
||||
|
||||
static inline int itedtv_bus_stream_rx(struct itedtv_bus *bus,
|
||||
void *buf, int *len,
|
||||
int timeout)
|
||||
{
|
||||
if (!bus || !bus->ops.stream_rx)
|
||||
return -EINVAL;
|
||||
|
||||
return bus->ops.stream_rx(bus, buf, len, timeout);
|
||||
}
|
||||
|
||||
static inline int itedtv_bus_start_streaming(struct itedtv_bus *bus,
|
||||
itedtv_bus_stream_handler_t stream_handler,
|
||||
void *context)
|
||||
{
|
||||
if (!bus || !bus->ops.start_streaming)
|
||||
return -EINVAL;
|
||||
|
||||
return bus->ops.start_streaming(bus, stream_handler, context);
|
||||
}
|
||||
|
||||
static inline int itedtv_bus_stop_streaming(struct itedtv_bus *bus)
|
||||
{
|
||||
if (!bus || !bus->ops.stop_streaming)
|
||||
return -EINVAL;
|
||||
|
||||
return bus->ops.stop_streaming(bus);
|
||||
}
|
||||
|
||||
#endif
|
1091
driver/m1ur_device.c
Normal file
1091
driver/m1ur_device.c
Normal file
File diff suppressed because it is too large
Load Diff
49
driver/m1ur_device.h
Normal file
49
driver/m1ur_device.h
Normal file
@@ -0,0 +1,49 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* PTX driver definitions for PLEX PX-M1UR device (m1ur_device.h)
|
||||
*
|
||||
* Copyright (c) 2023 techma.
|
||||
*/
|
||||
|
||||
#ifndef __M1UR_DEVICE_H__
|
||||
#define __M1UR_DEVICE_H__
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/kref.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
#include "ptx_chrdev.h"
|
||||
#include "it930x.h"
|
||||
#include "tc90522.h"
|
||||
#include "r850.h"
|
||||
#include "rt710.h"
|
||||
|
||||
#define M1UR_CHRDEV_NUM 1
|
||||
|
||||
struct m1ur_chrdev {
|
||||
struct ptx_chrdev *chrdev;
|
||||
struct tc90522_demod tc90522_t;
|
||||
struct tc90522_demod tc90522_s;
|
||||
struct r850_tuner r850;
|
||||
struct rt710_tuner rt710;
|
||||
};
|
||||
|
||||
struct m1ur_device {
|
||||
struct kref kref;
|
||||
atomic_t available;
|
||||
struct device *dev;
|
||||
struct completion *quit_completion;
|
||||
struct ptx_chrdev_group *chrdev_group;
|
||||
struct m1ur_chrdev chrdevm1ur;
|
||||
struct it930x_bridge it930x;
|
||||
void *stream_ctx;
|
||||
};
|
||||
|
||||
int m1ur_device_init(struct m1ur_device *m1ur, struct device *dev,
|
||||
struct ptx_chrdev_context *chrdev_ctx,
|
||||
struct completion *quit_completion);
|
||||
void m1ur_device_term(struct m1ur_device *m1ur);
|
||||
|
||||
#endif
|
1074
driver/ptx_chrdev.c
Normal file
1074
driver/ptx_chrdev.c
Normal file
File diff suppressed because it is too large
Load Diff
138
driver/ptx_chrdev.h
Normal file
138
driver/ptx_chrdev.h
Normal file
@@ -0,0 +1,138 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Character device operator definitions for PTX devices (ptx_chrdev.h)
|
||||
*
|
||||
* Copyright (c) 2018-2021 nns779
|
||||
*/
|
||||
|
||||
#ifndef __PTX_CHRDEV__
|
||||
#define __PTX_CHRDEV__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/kref.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
#include "ptx_ioctl.h"
|
||||
#include "ringbuffer.h"
|
||||
|
||||
struct ptx_tune_params {
|
||||
enum ptx_system_type system;
|
||||
u32 freq;
|
||||
u32 bandwidth;
|
||||
u16 stream_id;
|
||||
};
|
||||
|
||||
struct ptx_chrdev;
|
||||
struct ptx_chrdev_group;
|
||||
struct ptx_chrdev_context;
|
||||
|
||||
struct ptx_chrdev_operations {
|
||||
int (*init)(struct ptx_chrdev *chrdev);
|
||||
int (*term)(struct ptx_chrdev *chrdev);
|
||||
int (*open)(struct ptx_chrdev *chrdev);
|
||||
int (*release)(struct ptx_chrdev *chrdev);
|
||||
int (*tune)(struct ptx_chrdev *chrdev, struct ptx_tune_params *params);
|
||||
int (*check_lock)(struct ptx_chrdev *chrdev, bool *locked);
|
||||
int (*set_stream_id)(struct ptx_chrdev *chrdev, u16 stream_id);
|
||||
int (*set_lnb_voltage)(struct ptx_chrdev *chrdev, int voltage);
|
||||
int (*set_capture)(struct ptx_chrdev *chrdev, bool status);
|
||||
int (*read_signal_strength)(struct ptx_chrdev *chrdev, u32 *value);
|
||||
int (*read_cnr)(struct ptx_chrdev *chrdev, u32 *value);
|
||||
int (*read_cnr_raw)(struct ptx_chrdev *chrdev, u32 *value);
|
||||
};
|
||||
|
||||
#define PTX_CHRDEV_SAT_SET_STREAM_ID_BEFORE_TUNE 0x00000010
|
||||
#define PTX_CHRDEV_SAT_SET_STREAM_ID_AFTER_TUNE 0x00000020
|
||||
#define PTX_CHRDEV_WAIT_AFTER_LOCK 0x00000040
|
||||
#define PTX_CHRDEV_WAIT_AFTER_LOCK_TC_T 0x00000080
|
||||
|
||||
struct ptx_chrdev_config {
|
||||
enum ptx_system_type system_cap;
|
||||
const struct ptx_chrdev_operations *ops;
|
||||
u32 options;
|
||||
size_t ringbuf_size;
|
||||
size_t ringbuf_threshold_size;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
struct ptx_chrdev_group_config {
|
||||
struct kref *owner_kref;
|
||||
void (*owner_kref_release)(struct kref *);
|
||||
bool reserved;
|
||||
unsigned int minor_base;
|
||||
unsigned int chrdev_num;
|
||||
struct ptx_chrdev_config *chrdev_config;
|
||||
};
|
||||
|
||||
struct ptx_chrdev {
|
||||
struct mutex lock;
|
||||
unsigned int id;
|
||||
atomic_t open;
|
||||
char name[64];
|
||||
enum ptx_system_type system_cap;
|
||||
enum ptx_system_type current_system;
|
||||
const struct ptx_chrdev_operations *ops;
|
||||
struct ptx_chrdev_group *parent;
|
||||
struct ptx_tune_params params;
|
||||
u32 options;
|
||||
bool streaming;
|
||||
struct ringbuffer *ringbuf;
|
||||
wait_queue_head_t ringbuf_wait;
|
||||
size_t ringbuf_threshold_size;
|
||||
size_t ringbuf_write_size;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
struct ptx_chrdev_group {
|
||||
struct list_head list;
|
||||
struct mutex lock;
|
||||
struct kref kref;
|
||||
unsigned int id;
|
||||
atomic_t available;
|
||||
struct ptx_chrdev_context *parent;
|
||||
struct device *dev;
|
||||
struct cdev cdev;
|
||||
struct kref *owner_kref;
|
||||
void (*owner_kref_release)(struct kref *);
|
||||
unsigned int minor_base;
|
||||
unsigned int chrdev_num;
|
||||
struct ptx_chrdev chrdev[];
|
||||
};
|
||||
|
||||
#define PTX_CHRDEV_MINOR_FREE 0
|
||||
#define PTX_CHRDEV_MINOR_RESERVED 1
|
||||
#define PTX_CHRDEV_MINOR_IN_USE 2
|
||||
|
||||
struct ptx_chrdev_context {
|
||||
struct list_head list;
|
||||
struct mutex lock;
|
||||
struct kref kref;
|
||||
char devname[64];
|
||||
struct class *class;
|
||||
dev_t dev_base;
|
||||
unsigned int last_id;
|
||||
unsigned int minor_num;
|
||||
u8 *minor_table;
|
||||
struct list_head group_list;
|
||||
};
|
||||
|
||||
int ptx_chrdev_context_create(const char *name, const char *devname,
|
||||
unsigned int total_num,
|
||||
struct ptx_chrdev_context **chrdev_ctx);
|
||||
void ptx_chrdev_context_destroy(struct ptx_chrdev_context *chrdev_ctx);
|
||||
int ptx_chrdev_context_reserve(struct ptx_chrdev_context *chrdev_ctx,
|
||||
unsigned int num, unsigned int *minor_base);
|
||||
int ptx_chrdev_context_add_group(struct ptx_chrdev_context *chrdev_ctx,
|
||||
struct device *dev,
|
||||
const struct ptx_chrdev_group_config *config,
|
||||
struct ptx_chrdev_group **chrdev_group);
|
||||
int ptx_chrdev_context_remove_group(struct ptx_chrdev_context *chrdev_ctx,
|
||||
unsigned int minor_base);
|
||||
void ptx_chrdev_group_destroy(struct ptx_chrdev_group *chrdev_group);
|
||||
int ptx_chrdev_put_stream(struct ptx_chrdev *chrdev, void *buf, size_t len);
|
||||
|
||||
#endif
|
1686
driver/px4.c
1686
driver/px4.c
File diff suppressed because it is too large
Load Diff
@@ -1,8 +0,0 @@
|
||||
// px4.h
|
||||
|
||||
#ifndef __PX4_H__
|
||||
#define __PX4_H__
|
||||
|
||||
#define PX4_DRIVER_VERSION "0.1.0"
|
||||
|
||||
#endif
|
1413
driver/px4_device.c
Normal file
1413
driver/px4_device.c
Normal file
File diff suppressed because it is too large
Load Diff
68
driver/px4_device.h
Normal file
68
driver/px4_device.h
Normal file
@@ -0,0 +1,68 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* PTX driver definitions for PLEX PX4/PX5 series devices (px4_device.h)
|
||||
*
|
||||
* Copyright (c) 2018-2021 nns779
|
||||
*/
|
||||
|
||||
#ifndef __PX4_DEVICE_H__
|
||||
#define __PX4_DEVICE_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/kref.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
#include "px4_mldev.h"
|
||||
#include "ptx_chrdev.h"
|
||||
#include "it930x.h"
|
||||
#include "tc90522.h"
|
||||
#include "r850.h"
|
||||
#include "rt710.h"
|
||||
|
||||
#define PX4_CHRDEV_NUM 4
|
||||
|
||||
struct px4_device;
|
||||
|
||||
struct px4_chrdev {
|
||||
struct ptx_chrdev *chrdev;
|
||||
struct px4_device *parent;
|
||||
bool lnb_power;
|
||||
struct tc90522_demod tc90522;
|
||||
union {
|
||||
struct r850_tuner r850;
|
||||
struct rt710_tuner rt710;
|
||||
} tuner;
|
||||
};
|
||||
|
||||
struct px4_serial_number {
|
||||
unsigned long long serial_number;
|
||||
unsigned int dev_id;
|
||||
};
|
||||
|
||||
struct px4_device {
|
||||
struct mutex lock;
|
||||
struct kref kref;
|
||||
atomic_t available;
|
||||
struct device *dev;
|
||||
struct px4_serial_number serial;
|
||||
struct px4_mldev *mldev;
|
||||
struct completion *quit_completion;
|
||||
unsigned int open_count;
|
||||
unsigned int lnb_power_count;
|
||||
unsigned int streaming_count;
|
||||
struct ptx_chrdev_group *chrdev_group;
|
||||
struct px4_chrdev chrdev4[PX4_CHRDEV_NUM];
|
||||
struct it930x_bridge it930x;
|
||||
void *stream_ctx;
|
||||
};
|
||||
|
||||
int px4_device_init(struct px4_device *px4, struct device *dev,
|
||||
const char *dev_serial, bool use_mldev,
|
||||
struct ptx_chrdev_context *chrdev_ctx,
|
||||
struct completion *quit_completion);
|
||||
void px4_device_term(struct px4_device *px4);
|
||||
|
||||
#endif
|
89
driver/px4_device_params.c
Normal file
89
driver/px4_device_params.c
Normal file
@@ -0,0 +1,89 @@
|
||||
// SPDX-Licence-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Module parameter definitions (px4_device_params.c)
|
||||
*
|
||||
* Copyright (c) 2018-2021 nns779
|
||||
*/
|
||||
|
||||
#include "px4_device_params.h"
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
static const struct {
|
||||
enum px4_mldev_mode mode;
|
||||
char str[8];
|
||||
} mldev_mode_table[] = {
|
||||
{ PX4_MLDEV_ALL_MODE, "all" },
|
||||
{ PX4_MLDEV_S_ONLY_MODE, "s-only" },
|
||||
{ PX4_MLDEV_S0_ONLY_MODE, "s0-only" },
|
||||
{ PX4_MLDEV_S1_ONLY_MODE, "s1-only" },
|
||||
};
|
||||
|
||||
struct px4_device_param_set px4_device_params = {
|
||||
.tsdev_max_packets = 2048,
|
||||
.psb_purge_timeout = 2000,
|
||||
.disable_multi_device_power_control = false,
|
||||
.multi_device_power_control_mode = PX4_MLDEV_ALL_MODE,
|
||||
.s_tuner_no_sleep = false,
|
||||
.discard_null_packets = false
|
||||
};
|
||||
|
||||
static int set_multi_device_power_control_mode(const char *val,
|
||||
const struct kernel_param *kp)
|
||||
{
|
||||
int i;
|
||||
enum px4_mldev_mode mode;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mldev_mode_table); i++) {
|
||||
if (sysfs_streq(val, mldev_mode_table[i].str)) {
|
||||
mode = mldev_mode_table[i].mode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == ARRAY_SIZE(mldev_mode_table))
|
||||
return -EINVAL;
|
||||
|
||||
px4_device_params.multi_device_power_control_mode = mode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_multi_device_power_control_mode(char *buffer,
|
||||
const struct kernel_param *kp)
|
||||
{
|
||||
enum px4_mldev_mode mode = px4_device_params.multi_device_power_control_mode;
|
||||
|
||||
if (mode < PX4_MLDEV_ALL_MODE && mode > PX4_MLDEV_S1_ONLY_MODE)
|
||||
return -EINVAL;
|
||||
|
||||
return scnprintf(buffer, 4096, "%s\n", mldev_mode_table[mode].str);
|
||||
}
|
||||
|
||||
static const struct kernel_param_ops multi_device_power_control_mode_ops = {
|
||||
.set = set_multi_device_power_control_mode,
|
||||
.get = get_multi_device_power_control_mode
|
||||
};
|
||||
|
||||
module_param_named(tsdev_max_packets, px4_device_params.tsdev_max_packets,
|
||||
uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
MODULE_PARM_DESC(tsdev_max_packets,
|
||||
"Maximum number of TS packets buffering in tsdev. (default: 2048)");
|
||||
|
||||
module_param_named(psb_purge_timeout, px4_device_params.psb_purge_timeout,
|
||||
int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
|
||||
module_param_named(disable_multi_device_power_control,
|
||||
px4_device_params.disable_multi_device_power_control,
|
||||
bool, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
|
||||
module_param_cb(multi_device_power_control_mode,
|
||||
&multi_device_power_control_mode_ops,
|
||||
NULL, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
|
||||
module_param_named(s_tuner_no_sleep, px4_device_params.s_tuner_no_sleep,
|
||||
bool, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
|
||||
module_param_named(discard_null_packets, px4_device_params.discard_null_packets,
|
||||
bool, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
21
driver/px4_device_params.h
Normal file
21
driver/px4_device_params.h
Normal file
@@ -0,0 +1,21 @@
|
||||
// px4_device_params.h
|
||||
|
||||
#ifndef __PX4_DEVICE_PARAMS_H__
|
||||
#define __PX4_DEVICE_PARAMS_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "px4_mldev.h"
|
||||
|
||||
struct px4_device_param_set {
|
||||
unsigned int tsdev_max_packets;
|
||||
int psb_purge_timeout;
|
||||
bool disable_multi_device_power_control;
|
||||
enum px4_mldev_mode multi_device_power_control_mode;
|
||||
bool s_tuner_no_sleep;
|
||||
bool discard_null_packets;
|
||||
};
|
||||
|
||||
extern struct px4_device_param_set px4_device_params;
|
||||
|
||||
#endif
|
293
driver/px4_mldev.c
Normal file
293
driver/px4_mldev.c
Normal file
@@ -0,0 +1,293 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* PX4 multi-device power manager (px4_mldev.c)
|
||||
*
|
||||
* Copyright (c) 2018-2021 nns779
|
||||
*/
|
||||
|
||||
#include "print_format.h"
|
||||
#include "px4_mldev.h"
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
static LIST_HEAD(px4_mldev_list);
|
||||
static DEFINE_MUTEX(px4_mldev_glock);
|
||||
|
||||
static bool px4_mldev_get_chrdev_status(struct px4_mldev *mldev,
|
||||
unsigned int dev_id);
|
||||
static bool px4_mldev_is_power_interlocking_required(struct px4_mldev *mldev,
|
||||
unsigned int dev_id);
|
||||
|
||||
bool px4_mldev_search(unsigned long long serial_number,
|
||||
struct px4_mldev **mldev)
|
||||
{
|
||||
struct px4_mldev *m;
|
||||
|
||||
*mldev = NULL;
|
||||
|
||||
mutex_lock(&px4_mldev_glock);
|
||||
list_for_each_entry(m, &px4_mldev_list, list) {
|
||||
if (m->serial_number == serial_number) {
|
||||
*mldev = m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&px4_mldev_glock);
|
||||
|
||||
return (*mldev) ? true : false;
|
||||
}
|
||||
|
||||
int px4_mldev_alloc(struct px4_mldev **mldev, enum px4_mldev_mode mode,
|
||||
struct px4_device *px4,
|
||||
int (*backend_set_power)(struct px4_device *, bool))
|
||||
{
|
||||
int i, j;
|
||||
unsigned int dev_id = px4->serial.dev_id - 1;
|
||||
struct px4_mldev *m;
|
||||
|
||||
dev_dbg(px4->dev,
|
||||
"px4_mldev_alloc: serial_number: %014llu, dev_id: %u\n",
|
||||
px4->serial.serial_number, dev_id + 1);
|
||||
|
||||
if (dev_id > 1)
|
||||
return -EINVAL;
|
||||
|
||||
m = kzalloc(sizeof(*m), GFP_KERNEL);
|
||||
if (!m)
|
||||
return -ENOMEM;
|
||||
|
||||
kref_init(&m->kref);
|
||||
mutex_init(&m->lock);
|
||||
m->mode = mode;
|
||||
m->serial_number = px4->serial.serial_number;
|
||||
for (i = 0; i < 2; i++) {
|
||||
m->dev[i] = (i == dev_id) ? px4 : NULL;
|
||||
m->power_state[i] = false;
|
||||
for (j = 0; j < 4; j++)
|
||||
m->chrdev_state[i][j] = false;
|
||||
}
|
||||
m->backend_set_power = backend_set_power;
|
||||
|
||||
mutex_lock(&px4_mldev_glock);
|
||||
list_add_tail(&m->list, &px4_mldev_list);
|
||||
mutex_unlock(&px4_mldev_glock);
|
||||
|
||||
*mldev = m;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void px4_mldev_release(struct kref *kref)
|
||||
{
|
||||
struct px4_mldev *mldev = container_of(kref, struct px4_mldev, kref);
|
||||
|
||||
pr_debug("px4_mldev_release: serial_number: %014llu\n",
|
||||
mldev->serial_number);
|
||||
|
||||
mutex_lock(&px4_mldev_glock);
|
||||
list_del(&mldev->list);
|
||||
mutex_unlock(&px4_mldev_glock);
|
||||
|
||||
mutex_destroy(&mldev->lock);
|
||||
kfree(mldev);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int px4_mldev_add(struct px4_mldev *mldev, struct px4_device *px4)
|
||||
{
|
||||
int ret = 0, i;
|
||||
unsigned int dev_id = px4->serial.dev_id - 1;
|
||||
|
||||
dev_dbg(px4->dev,
|
||||
"px4_mldev_add: serial_number: %014llu, dev_id: %u\n",
|
||||
mldev->serial_number, dev_id + 1);
|
||||
|
||||
if (dev_id > 1)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&mldev->lock);
|
||||
|
||||
if (kref_read(&mldev->kref) >= 2) {
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (mldev->dev[dev_id]) {
|
||||
ret = -EALREADY;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mldev->power_state[dev_id] = false;
|
||||
for (i = 0; i < 4; i++)
|
||||
mldev->chrdev_state[dev_id][i] = false;
|
||||
|
||||
if (px4_mldev_is_power_interlocking_required(mldev, (dev_id) ? 0 : 1)) {
|
||||
ret = mldev->backend_set_power(px4, true);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
mldev->power_state[dev_id] = true;
|
||||
}
|
||||
|
||||
mldev->dev[dev_id] = px4;
|
||||
kref_get(&mldev->kref);
|
||||
|
||||
exit:
|
||||
mutex_unlock(&mldev->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int px4_mldev_remove(struct px4_mldev *mldev, struct px4_device *px4)
|
||||
{
|
||||
int i;
|
||||
unsigned int dev_id = px4->serial.dev_id - 1;
|
||||
unsigned int other_dev_id = (dev_id) ? 1 : 0;
|
||||
|
||||
dev_dbg(px4->dev,
|
||||
"px4_mldev_remove: serial_number: %014llu, dev_id: %u\n",
|
||||
mldev->serial_number, dev_id + 1);
|
||||
|
||||
if (dev_id > 1)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&mldev->lock);
|
||||
|
||||
if (mldev->dev[dev_id] != px4) {
|
||||
mutex_unlock(&mldev->lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (mldev->power_state[dev_id])
|
||||
mldev->backend_set_power(px4, false);
|
||||
|
||||
mldev->dev[dev_id] = NULL;
|
||||
mldev->power_state[dev_id] = false;
|
||||
for (i = 0; i < 4; i++)
|
||||
mldev->chrdev_state[dev_id][i] = false;
|
||||
|
||||
if (mldev->dev[other_dev_id] &&
|
||||
!px4_mldev_get_chrdev_status(mldev, other_dev_id) &&
|
||||
mldev->power_state[other_dev_id]) {
|
||||
mldev->backend_set_power(mldev->dev[other_dev_id], false);
|
||||
mldev->power_state[other_dev_id] = false;
|
||||
}
|
||||
|
||||
if (kref_put(&mldev->kref, px4_mldev_release))
|
||||
return 0;
|
||||
|
||||
mutex_unlock(&mldev->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool px4_mldev_get_chrdev_status(struct px4_mldev *mldev,
|
||||
unsigned int dev_id)
|
||||
{
|
||||
bool *state = mldev->chrdev_state[dev_id];
|
||||
return (state[0] || state[1] || state[2] || state[3]);
|
||||
}
|
||||
|
||||
static bool px4_mldev_is_power_interlocking_required(struct px4_mldev *mldev,
|
||||
unsigned int dev_id)
|
||||
{
|
||||
bool ret = false;
|
||||
bool *state = mldev->chrdev_state[dev_id];
|
||||
|
||||
switch (mldev->mode) {
|
||||
case PX4_MLDEV_S_ONLY_MODE:
|
||||
ret = state[0] || state[1];
|
||||
break;
|
||||
|
||||
case PX4_MLDEV_S0_ONLY_MODE:
|
||||
ret = state[0];
|
||||
break;
|
||||
|
||||
case PX4_MLDEV_S1_ONLY_MODE:
|
||||
ret = state[1];
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = state[0] || state[1] || state[2] || state[3];
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int px4_mldev_set_power(struct px4_mldev *mldev, struct px4_device *px4,
|
||||
unsigned int chrdev_id, bool state, bool *first)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int dev_id = px4->serial.dev_id - 1;
|
||||
unsigned int other_dev_id = (dev_id) ? 0 : 1;
|
||||
|
||||
dev_dbg(px4->dev,
|
||||
"px4_mldev_set_power: serial_number: %014llu, dev_id: %u, chrdev_id: %u state: %s\n",
|
||||
mldev->serial_number, dev_id, chrdev_id,
|
||||
(state) ? "true" : "false");
|
||||
dev_dbg(px4->dev,
|
||||
"px4_mldev_set_power: power_state: %s, %s\n",
|
||||
(mldev->power_state[0]) ? "true" : "false",
|
||||
(mldev->power_state[1]) ? "true" : "false");
|
||||
dev_dbg(px4->dev,
|
||||
"px4_mldev_set_power: chrdev_state[%u][%u]: %s\n",
|
||||
dev_id, chrdev_id,
|
||||
(mldev->chrdev_state[dev_id][chrdev_id]) ? "true" : "false");
|
||||
|
||||
if (dev_id > 1 || chrdev_id > 3)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&mldev->lock);
|
||||
|
||||
if (mldev->dev[dev_id] != px4) {
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (mldev->chrdev_state[dev_id][chrdev_id] == state)
|
||||
goto exit;
|
||||
|
||||
if (!state)
|
||||
mldev->chrdev_state[dev_id][chrdev_id] = false;
|
||||
|
||||
if (!px4_mldev_get_chrdev_status(mldev, dev_id)) {
|
||||
if (mldev->power_state[dev_id] != state &&
|
||||
(state || !px4_mldev_is_power_interlocking_required(mldev, other_dev_id))) {
|
||||
ret = mldev->backend_set_power(mldev->dev[dev_id],
|
||||
state);
|
||||
if (ret && state)
|
||||
goto exit;
|
||||
|
||||
mldev->power_state[dev_id] = state;
|
||||
}
|
||||
|
||||
if (state && first)
|
||||
*first = true;
|
||||
}
|
||||
|
||||
if (state)
|
||||
mldev->chrdev_state[dev_id][chrdev_id] = true;
|
||||
|
||||
if (mldev->dev[other_dev_id]) {
|
||||
bool interlocking = px4_mldev_is_power_interlocking_required(mldev, dev_id);
|
||||
|
||||
dev_dbg(px4->dev,
|
||||
"px4_mldev_set_power: interlocking: %s\n",
|
||||
(interlocking) ? "true" : "false");
|
||||
|
||||
if (interlocking == state &&
|
||||
mldev->power_state[other_dev_id] != interlocking &&
|
||||
(state || !px4_mldev_get_chrdev_status(mldev, other_dev_id))) {
|
||||
ret = mldev->backend_set_power(mldev->dev[other_dev_id],
|
||||
state);
|
||||
if (!ret || !state)
|
||||
mldev->power_state[other_dev_id] = state;
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
mutex_unlock(&mldev->lock);
|
||||
return ret;
|
||||
}
|
47
driver/px4_mldev.h
Normal file
47
driver/px4_mldev.h
Normal file
@@ -0,0 +1,47 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* PX4 multi-device power manager definitions (px4_mldev.h)
|
||||
*
|
||||
* Copyright (c) 2018-2021 nns779
|
||||
*/
|
||||
|
||||
#ifndef __PX4_MLDEV_H__
|
||||
#define __PX4_MLDEV_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/kref.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#include "px4_device.h"
|
||||
|
||||
enum px4_mldev_mode {
|
||||
PX4_MLDEV_ALL_MODE = 0,
|
||||
PX4_MLDEV_S_ONLY_MODE,
|
||||
PX4_MLDEV_S0_ONLY_MODE,
|
||||
PX4_MLDEV_S1_ONLY_MODE,
|
||||
};
|
||||
|
||||
struct px4_mldev {
|
||||
struct kref kref;
|
||||
struct list_head list;
|
||||
struct mutex lock;
|
||||
enum px4_mldev_mode mode;
|
||||
unsigned long long serial_number;
|
||||
struct px4_device *dev[2];
|
||||
bool power_state[2];
|
||||
bool chrdev_state[2][4];
|
||||
int (*backend_set_power)(struct px4_device *px4, bool state);
|
||||
};
|
||||
|
||||
bool px4_mldev_search(unsigned long long serial_number,
|
||||
struct px4_mldev **mldev);
|
||||
int px4_mldev_alloc(struct px4_mldev **mldev, enum px4_mldev_mode mode,
|
||||
struct px4_device *px4,
|
||||
int (*backend_set_power)(struct px4_device *, bool));
|
||||
int px4_mldev_add(struct px4_mldev *mldev, struct px4_device *px4);
|
||||
int px4_mldev_remove(struct px4_mldev *mldev, struct px4_device *px4);
|
||||
int px4_mldev_set_power(struct px4_mldev *mldev, struct px4_device *px4,
|
||||
unsigned int chrdev_id, bool state, bool *first);
|
||||
|
||||
#endif
|
511
driver/px4_usb.c
Normal file
511
driver/px4_usb.c
Normal file
@@ -0,0 +1,511 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* PTX driver for USB devices (px4_usb.c)
|
||||
*
|
||||
* Copyright (c) 2018-2021 nns779
|
||||
*/
|
||||
|
||||
#include "print_format.h"
|
||||
#include "px4_usb.h"
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/usb.h>
|
||||
|
||||
#include "px4_usb_params.h"
|
||||
#include "px4_device_params.h"
|
||||
#include "ptx_chrdev.h"
|
||||
#include "px4_device.h"
|
||||
#include "pxmlt_device.h"
|
||||
#include "isdb2056_device.h"
|
||||
#include "s1ur_device.h"
|
||||
#include "m1ur_device.h"
|
||||
|
||||
#ifndef PX4_USB_MAX_DEVICE
|
||||
#define PX4_USB_MAX_DEVICE 16
|
||||
#endif
|
||||
#define PX4_USB_MAX_CHRDEV (PX4_USB_MAX_DEVICE * PX4_CHRDEV_NUM)
|
||||
|
||||
#ifndef PXMLT5_USB_MAX_DEVICE
|
||||
#define PXMLT5_USB_MAX_DEVICE 14
|
||||
#endif
|
||||
#define PXMLT5_USB_MAX_CHRDEV (PXMLT5_USB_MAX_DEVICE * PXMLT5_CHRDEV_NUM)
|
||||
|
||||
#ifndef PXMLT8_USB_MAX_DEVICE
|
||||
#define PXMLT8_USB_MAX_DEVICE 8
|
||||
#endif
|
||||
#define PXMLT8_USB_MAX_CHRDEV (PXMLT8_USB_MAX_DEVICE * PXMLT8_CHRDEV_NUM)
|
||||
|
||||
#ifndef ISDB2056_USB_MAX_DEVICE
|
||||
#define ISDB2056_USB_MAX_DEVICE 64
|
||||
#endif
|
||||
#define ISDB2056_USB_MAX_CHRDEV (ISDB2056_USB_MAX_DEVICE * ISDB2056_CHRDEV_NUM)
|
||||
|
||||
#ifndef ISDB6014_4TS_USB_MAX_DEVICE
|
||||
#define ISDB6014_4TS_USB_MAX_DEVICE 16
|
||||
#endif
|
||||
#define ISDB6014_4TS_USB_MAX_CHRDEV (ISDB6014_4TS_USB_MAX_DEVICE * ISDB6014_4TS_CHRDEV_NUM)
|
||||
|
||||
#ifndef PXM1UR_USB_MAX_DEVICE
|
||||
#define PXM1UR_USB_MAX_DEVICE 64
|
||||
#endif
|
||||
#define PXM1UR_USB_MAX_CHRDEV (PXM1UR_USB_MAX_DEVICE * M1UR_CHRDEV_NUM)
|
||||
|
||||
#ifndef PXS1UR_USB_MAX_DEVICE
|
||||
#define PXS1UR_USB_MAX_DEVICE 64
|
||||
#endif
|
||||
#define PXS1UR_USB_MAX_CHRDEV (PXS1UR_USB_MAX_DEVICE * S1UR_CHRDEV_NUM)
|
||||
|
||||
#ifndef ISDBT2071_USB_MAX_DEVICE
|
||||
#define ISDBT2071_USB_MAX_DEVICE 64
|
||||
#endif
|
||||
#define ISDBT2071_USB_MAX_CHRDEV (ISDBT2071_USB_MAX_DEVICE * ISDBT2071_CHRDEV_NUM)
|
||||
|
||||
|
||||
struct px4_usb_context {
|
||||
enum px4_usb_device_type type;
|
||||
struct completion quit_completion;
|
||||
union {
|
||||
struct px4_device px4;
|
||||
struct pxmlt_device pxmlt;
|
||||
struct isdb2056_device isdb2056;
|
||||
struct m1ur_device m1ur;
|
||||
struct s1ur_device s1ur;
|
||||
} ctx;
|
||||
};
|
||||
|
||||
static struct ptx_chrdev_context *px4_usb_chrdev_ctx[MAX_USB_DEVICE_TYPE];
|
||||
|
||||
static int px4_usb_init_bridge(struct device *dev, struct usb_device *usb_dev,
|
||||
struct it930x_bridge *it930x)
|
||||
{
|
||||
struct itedtv_bus *bus = &it930x->bus;
|
||||
|
||||
bus->dev = dev;
|
||||
bus->type = ITEDTV_BUS_USB;
|
||||
bus->usb.dev = usb_dev;
|
||||
bus->usb.ctrl_timeout = px4_usb_params.ctrl_timeout;
|
||||
bus->usb.streaming.urb_buffer_size = 188 * px4_usb_params.urb_max_packets;
|
||||
bus->usb.streaming.urb_num = px4_usb_params.max_urbs;
|
||||
bus->usb.streaming.no_dma = px4_usb_params.no_dma;
|
||||
|
||||
it930x->dev = dev;
|
||||
it930x->config.xfer_size = 188 * px4_usb_params.xfer_packets;
|
||||
it930x->config.i2c_speed = 0x07;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int px4_usb_probe(struct usb_interface *intf,
|
||||
const struct usb_device_id *id)
|
||||
{
|
||||
int ret = 0;
|
||||
struct device *dev;
|
||||
struct usb_device *usb_dev;
|
||||
struct px4_usb_context *ctx;
|
||||
|
||||
dev = &intf->dev;
|
||||
usb_dev = interface_to_usbdev(intf);
|
||||
|
||||
if (usb_dev->speed < USB_SPEED_HIGH)
|
||||
dev_warn(dev, "This device is operating as USB 1.1.\n");
|
||||
|
||||
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
|
||||
if (!ctx) {
|
||||
dev_err(dev, "px4_usb_probe: kzalloc(sizeof(*ctx)) failed.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
init_completion(&ctx->quit_completion);
|
||||
|
||||
switch (id->idVendor) {
|
||||
case 0x0511:
|
||||
{
|
||||
bool px4_use_mldev = false;
|
||||
enum pxmlt_model pxmlt5_model = PXMLT5PE_MODEL;
|
||||
enum pxmlt_model pxmlt8_model = PXMLT8PE5_MODEL;
|
||||
|
||||
switch (id->idProduct) {
|
||||
case USB_PID_PX_Q3U4:
|
||||
case USB_PID_PX_Q3PE4:
|
||||
case USB_PID_PX_Q3PE5:
|
||||
if (!px4_device_params.disable_multi_device_power_control)
|
||||
px4_use_mldev = true;
|
||||
|
||||
dev_info(dev, "Multi-device power control: %s\n",
|
||||
(px4_use_mldev) ? "enabled" : "disabled");
|
||||
fallthrough;
|
||||
case USB_PID_PX_W3U4:
|
||||
case USB_PID_PX_W3PE4:
|
||||
case USB_PID_PX_W3PE5:
|
||||
ret = px4_usb_init_bridge(dev, usb_dev,
|
||||
&ctx->ctx.px4.it930x);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
ctx->type = PX4_USB_DEVICE;
|
||||
ret = px4_device_init(&ctx->ctx.px4, dev,
|
||||
usb_dev->serial, px4_use_mldev,
|
||||
px4_usb_chrdev_ctx[PX4_USB_DEVICE],
|
||||
&ctx->quit_completion);
|
||||
break;
|
||||
|
||||
case USB_PID_PX_MLT5U:
|
||||
pxmlt5_model = PXMLT5U_MODEL;
|
||||
fallthrough;
|
||||
case USB_PID_PX_MLT5PE:
|
||||
ret = px4_usb_init_bridge(dev, usb_dev,
|
||||
&ctx->ctx.pxmlt.it930x);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
ctx->type = PXMLT5_USB_DEVICE;
|
||||
ret = pxmlt_device_init(&ctx->ctx.pxmlt, dev, pxmlt5_model,
|
||||
px4_usb_chrdev_ctx[PXMLT5_USB_DEVICE],
|
||||
&ctx->quit_completion);
|
||||
break;
|
||||
|
||||
case USB_PID_PX_MLT8PE3:
|
||||
pxmlt8_model = PXMLT8PE3_MODEL;
|
||||
fallthrough;
|
||||
case USB_PID_PX_MLT8PE5:
|
||||
ret = px4_usb_init_bridge(dev, usb_dev,
|
||||
&ctx->ctx.pxmlt.it930x);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
ctx->type = PXMLT8_USB_DEVICE;
|
||||
ret = pxmlt_device_init(&ctx->ctx.pxmlt, dev, pxmlt8_model,
|
||||
px4_usb_chrdev_ctx[PXMLT8_USB_DEVICE],
|
||||
&ctx->quit_completion);
|
||||
break;
|
||||
|
||||
case USB_PID_DIGIBEST_ISDB2056:
|
||||
ret = px4_usb_init_bridge(dev, usb_dev,
|
||||
&ctx->ctx.isdb2056.it930x);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
ctx->type = ISDB2056_USB_DEVICE;
|
||||
ret = isdb2056_device_init(&ctx->ctx.isdb2056, dev, ISDB2056_MODEL,
|
||||
px4_usb_chrdev_ctx[ISDB2056_USB_DEVICE],
|
||||
&ctx->quit_completion);
|
||||
break;
|
||||
|
||||
case USB_PID_DIGIBEST_ISDB2056N:
|
||||
ret = px4_usb_init_bridge(dev, usb_dev,
|
||||
&ctx->ctx.isdb2056.it930x);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
ctx->type = ISDB2056_USB_DEVICE;
|
||||
ret = isdb2056_device_init(&ctx->ctx.isdb2056, dev, ISDB2056N_MODEL,
|
||||
px4_usb_chrdev_ctx[ISDB2056_USB_DEVICE],
|
||||
&ctx->quit_completion);
|
||||
break;
|
||||
|
||||
case USB_PID_DIGIBEST_ISDB6014_4TS:
|
||||
ret = px4_usb_init_bridge(dev, usb_dev,
|
||||
&ctx->ctx.pxmlt.it930x);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
ctx->type = ISDB6014_4TS_USB_DEVICE;
|
||||
ret = pxmlt_device_init(&ctx->ctx.pxmlt, dev, ISDB6014_4TS_MODEL,
|
||||
px4_usb_chrdev_ctx[ISDB6014_4TS_USB_DEVICE],
|
||||
&ctx->quit_completion);
|
||||
break;
|
||||
|
||||
case USB_PID_PX_M1UR:
|
||||
ret = px4_usb_init_bridge(dev, usb_dev,
|
||||
&ctx->ctx.m1ur.it930x);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
ctx->type = PXM1UR_USB_DEVICE;
|
||||
ret = m1ur_device_init(&ctx->ctx.m1ur, dev,
|
||||
px4_usb_chrdev_ctx[PXM1UR_USB_DEVICE],
|
||||
&ctx->quit_completion);
|
||||
break;
|
||||
|
||||
case USB_PID_PX_S1UR:
|
||||
ret = px4_usb_init_bridge(dev, usb_dev,
|
||||
&ctx->ctx.s1ur.it930x);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
ctx->type = PXS1UR_USB_DEVICE;
|
||||
ret = s1ur_device_init(&ctx->ctx.s1ur, dev,
|
||||
PXS1UR_MODEL,
|
||||
px4_usb_chrdev_ctx[PXS1UR_USB_DEVICE],
|
||||
&ctx->quit_completion);
|
||||
break;
|
||||
|
||||
case USB_PID_DIGIBEST_ISDBT2071:
|
||||
ret = px4_usb_init_bridge(dev, usb_dev,
|
||||
&ctx->ctx.s1ur.it930x);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
ctx->type = ISDBT2071_USB_DEVICE;
|
||||
ret = s1ur_device_init(&ctx->ctx.s1ur, dev,
|
||||
ISDBT2071_MODEL,
|
||||
px4_usb_chrdev_ctx[ISDBT2071_USB_DEVICE],
|
||||
&ctx->quit_completion);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
get_device(dev);
|
||||
usb_set_intfdata(intf, ctx);
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
if (ctx)
|
||||
kfree(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void px4_usb_disconnect(struct usb_interface *intf)
|
||||
{
|
||||
struct px4_usb_context *ctx;
|
||||
|
||||
ctx = usb_get_intfdata(intf);
|
||||
if (!ctx) {
|
||||
pr_err("px4_usb_disconnect: ctx is NULL.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
usb_set_intfdata(intf, NULL);
|
||||
|
||||
switch (ctx->type) {
|
||||
case PX4_USB_DEVICE:
|
||||
px4_device_term(&ctx->ctx.px4);
|
||||
wait_for_completion(&ctx->quit_completion);
|
||||
break;
|
||||
|
||||
case PXMLT5_USB_DEVICE:
|
||||
case PXMLT8_USB_DEVICE:
|
||||
case ISDB6014_4TS_USB_DEVICE:
|
||||
pxmlt_device_term(&ctx->ctx.pxmlt);
|
||||
wait_for_completion(&ctx->quit_completion);
|
||||
break;
|
||||
|
||||
case ISDB2056_USB_DEVICE:
|
||||
isdb2056_device_term(&ctx->ctx.isdb2056);
|
||||
wait_for_completion(&ctx->quit_completion);
|
||||
break;
|
||||
|
||||
case PXM1UR_USB_DEVICE:
|
||||
m1ur_device_term(&ctx->ctx.m1ur);
|
||||
wait_for_completion(&ctx->quit_completion);
|
||||
break;
|
||||
|
||||
case PXS1UR_USB_DEVICE:
|
||||
case ISDBT2071_USB_DEVICE:
|
||||
s1ur_device_term(&ctx->ctx.s1ur);
|
||||
wait_for_completion(&ctx->quit_completion);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* unknown device */
|
||||
break;
|
||||
}
|
||||
|
||||
dev_dbg(&intf->dev, "px4_usb_disconnect: release\n");
|
||||
|
||||
put_device(&intf->dev);
|
||||
kfree(ctx);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int px4_usb_suspend(struct usb_interface *intf, pm_message_t message)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static int px4_usb_resume(struct usb_interface *intf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct usb_device_id px4_usb_ids[] = {
|
||||
{ USB_DEVICE(0x0511, USB_PID_PX_W3U4) },
|
||||
{ USB_DEVICE(0x0511, USB_PID_PX_Q3U4) },
|
||||
{ USB_DEVICE(0x0511, USB_PID_PX_W3PE4) },
|
||||
{ USB_DEVICE(0x0511, USB_PID_PX_Q3PE4) },
|
||||
{ USB_DEVICE(0x0511, USB_PID_PX_W3PE5) },
|
||||
{ USB_DEVICE(0x0511, USB_PID_PX_Q3PE5) },
|
||||
{ USB_DEVICE(0x0511, USB_PID_PX_MLT5U) },
|
||||
{ USB_DEVICE(0x0511, USB_PID_PX_MLT5PE) },
|
||||
{ USB_DEVICE(0x0511, USB_PID_PX_MLT8PE3) },
|
||||
{ USB_DEVICE(0x0511, USB_PID_PX_MLT8PE5) },
|
||||
{ USB_DEVICE(0x0511, USB_PID_DIGIBEST_ISDB2056) },
|
||||
{ USB_DEVICE(0x0511, USB_PID_DIGIBEST_ISDB2056N) },
|
||||
{ USB_DEVICE(0x0511, USB_PID_DIGIBEST_ISDB6014_4TS) },
|
||||
{ USB_DEVICE(0x0511, USB_PID_PX_M1UR) },
|
||||
{ USB_DEVICE(0x0511, USB_PID_PX_S1UR) },
|
||||
{ USB_DEVICE(0x0511, USB_PID_DIGIBEST_ISDBT2071) },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(usb, px4_usb_ids);
|
||||
|
||||
static struct usb_driver px4_usb_driver = {
|
||||
.name = "px4_usb",
|
||||
.probe = px4_usb_probe,
|
||||
.disconnect = px4_usb_disconnect,
|
||||
.suspend = px4_usb_suspend,
|
||||
.resume = px4_usb_resume,
|
||||
.id_table = px4_usb_ids
|
||||
};
|
||||
|
||||
int px4_usb_register()
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
pr_debug("px4_usb_register: PX4_USB_MAX_DEVICE: %d\n", PX4_USB_MAX_DEVICE);
|
||||
pr_debug("px4_usb_register: PXMLT5_USB_MAX_DEVICE: %d\n", PXMLT5_USB_MAX_DEVICE);
|
||||
pr_debug("px4_usb_register: PXMLT8_USB_MAX_DEVICE: %d\n", PXMLT8_USB_MAX_DEVICE);
|
||||
pr_debug("px4_usb_register: ISDB2056_USB_MAX_DEVICE: %d\n", ISDB2056_USB_MAX_DEVICE);
|
||||
pr_debug("px4_usb_register: ISDB6014_4TS_USB_MAX_DEVICE: %d\n", ISDB6014_4TS_USB_MAX_DEVICE);
|
||||
pr_debug("px4_usb_register: PXM1UR_USB_MAX_DEVICE: %d\n", PXM1UR_USB_MAX_DEVICE);
|
||||
pr_debug("px4_usb_register: PXS1UR_USB_MAX_DEVICE: %d\n", PXS1UR_USB_MAX_DEVICE);
|
||||
pr_debug("px4_usb_register: ISDBT2071_USB_MAX_DEVICE: %d\n", ISDBT2071_USB_MAX_DEVICE);
|
||||
|
||||
memset(&px4_usb_chrdev_ctx, 0, sizeof(px4_usb_chrdev_ctx));
|
||||
|
||||
ret = ptx_chrdev_context_create("px4", "px4video",
|
||||
PX4_USB_MAX_CHRDEV,
|
||||
&px4_usb_chrdev_ctx[PX4_USB_DEVICE]);
|
||||
if (ret) {
|
||||
pr_err("px4_usb_register: ptx_chrdev_context_create(\"px4\") failed.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = ptx_chrdev_context_create("pxmlt5", "pxmlt5video",
|
||||
PXMLT5_USB_MAX_CHRDEV,
|
||||
&px4_usb_chrdev_ctx[PXMLT5_USB_DEVICE]);
|
||||
if (ret) {
|
||||
pr_err("px4_usb_register: ptx_chrdev_context_create(\"pxmlt5\") failed.\n");
|
||||
goto fail_mlt5;
|
||||
}
|
||||
|
||||
ret = ptx_chrdev_context_create("pxmlt8", "pxmlt8video",
|
||||
PXMLT8_USB_MAX_CHRDEV,
|
||||
&px4_usb_chrdev_ctx[PXMLT8_USB_DEVICE]);
|
||||
if (ret) {
|
||||
pr_err("px4_usb_register: ptx_chrdev_context_create(\"pxmlt8\") failed.\n");
|
||||
goto fail_mlt8;
|
||||
}
|
||||
|
||||
ret = ptx_chrdev_context_create("isdb2056", "isdb2056video",
|
||||
ISDB2056_USB_MAX_CHRDEV,
|
||||
&px4_usb_chrdev_ctx[ISDB2056_USB_DEVICE]);
|
||||
if (ret) {
|
||||
pr_err("px4_usb_register: ptx_chrdev_context_create(\"isdb2056\") failed.\n");
|
||||
goto fail_isdb2056;
|
||||
}
|
||||
|
||||
ret = ptx_chrdev_context_create("isdb6014", "isdb6014video",
|
||||
ISDB6014_4TS_USB_MAX_CHRDEV,
|
||||
&px4_usb_chrdev_ctx[ISDB6014_4TS_USB_DEVICE]);
|
||||
if (ret) {
|
||||
pr_err("px4_usb_register: ptx_chrdev_context_create(\"isdb6014\") failed.\n");
|
||||
goto fail_isdb6014;
|
||||
}
|
||||
|
||||
ret = ptx_chrdev_context_create("pxm1ur", "pxm1urvideo",
|
||||
PXM1UR_USB_MAX_CHRDEV,
|
||||
&px4_usb_chrdev_ctx[PXM1UR_USB_DEVICE]);
|
||||
if (ret) {
|
||||
pr_err("px4_usb_register: ptx_chrdev_context_create(\"pxm1ur\") failed.\n");
|
||||
goto fail_pxm1ur;
|
||||
}
|
||||
|
||||
ret = ptx_chrdev_context_create("pxs1ur", "pxs1urvideo",
|
||||
PXS1UR_USB_MAX_CHRDEV,
|
||||
&px4_usb_chrdev_ctx[PXS1UR_USB_DEVICE]);
|
||||
if (ret) {
|
||||
pr_err("px4_usb_register: ptx_chrdev_context_create(\"pxs1ur\") failed.\n");
|
||||
goto fail_pxs1ur;
|
||||
}
|
||||
|
||||
ret = ptx_chrdev_context_create("isdbt2071", "isdbt2071video",
|
||||
ISDBT2071_USB_MAX_CHRDEV,
|
||||
&px4_usb_chrdev_ctx[ISDBT2071_USB_DEVICE]);
|
||||
if (ret) {
|
||||
pr_err("px4_usb_register: ptx_chrdev_context_create(\"isdbt2071\") failed.\n");
|
||||
goto fail_isdbt2071;
|
||||
}
|
||||
|
||||
ret = usb_register(&px4_usb_driver);
|
||||
if (ret) {
|
||||
pr_err("px4_usb_register: usb_register() failed.\n");
|
||||
goto fail_usb;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail_usb:
|
||||
ptx_chrdev_context_destroy(px4_usb_chrdev_ctx[ISDBT2071_USB_DEVICE]);
|
||||
|
||||
fail_isdbt2071:
|
||||
ptx_chrdev_context_destroy(px4_usb_chrdev_ctx[PXS1UR_USB_DEVICE]);
|
||||
|
||||
fail_pxs1ur:
|
||||
ptx_chrdev_context_destroy(px4_usb_chrdev_ctx[PXM1UR_USB_DEVICE]);
|
||||
|
||||
fail_pxm1ur:
|
||||
ptx_chrdev_context_destroy(px4_usb_chrdev_ctx[ISDB6014_4TS_USB_DEVICE]);
|
||||
|
||||
fail_isdb6014:
|
||||
ptx_chrdev_context_destroy(px4_usb_chrdev_ctx[ISDB2056_USB_DEVICE]);
|
||||
|
||||
fail_isdb2056:
|
||||
ptx_chrdev_context_destroy(px4_usb_chrdev_ctx[PXMLT8_USB_DEVICE]);
|
||||
|
||||
fail_mlt8:
|
||||
ptx_chrdev_context_destroy(px4_usb_chrdev_ctx[PXMLT5_USB_DEVICE]);
|
||||
|
||||
fail_mlt5:
|
||||
ptx_chrdev_context_destroy(px4_usb_chrdev_ctx[PX4_USB_DEVICE]);
|
||||
|
||||
fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void px4_usb_unregister()
|
||||
{
|
||||
usb_deregister(&px4_usb_driver);
|
||||
ptx_chrdev_context_destroy(px4_usb_chrdev_ctx[ISDBT2071_USB_DEVICE]);
|
||||
ptx_chrdev_context_destroy(px4_usb_chrdev_ctx[PXS1UR_USB_DEVICE]);
|
||||
ptx_chrdev_context_destroy(px4_usb_chrdev_ctx[PXM1UR_USB_DEVICE]);
|
||||
ptx_chrdev_context_destroy(px4_usb_chrdev_ctx[ISDB6014_4TS_USB_DEVICE]);
|
||||
ptx_chrdev_context_destroy(px4_usb_chrdev_ctx[ISDB2056_USB_DEVICE]);
|
||||
ptx_chrdev_context_destroy(px4_usb_chrdev_ctx[PXMLT8_USB_DEVICE]);
|
||||
ptx_chrdev_context_destroy(px4_usb_chrdev_ctx[PXMLT5_USB_DEVICE]);
|
||||
ptx_chrdev_context_destroy(px4_usb_chrdev_ctx[PX4_USB_DEVICE]);
|
||||
}
|
46
driver/px4_usb.h
Normal file
46
driver/px4_usb.h
Normal file
@@ -0,0 +1,46 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* PTX driver definitions for USB devices (px4_usb.h)
|
||||
*
|
||||
* Copyright (c) 2018-2021 nns779
|
||||
*/
|
||||
|
||||
#ifndef __PX4_USB_H__
|
||||
#define __PX4_USB_H__
|
||||
|
||||
#define USB_PID_PX_W3U4 0x083f
|
||||
#define USB_PID_PX_Q3U4 0x084a
|
||||
#define USB_PID_PX_W3PE4 0x023f
|
||||
#define USB_PID_PX_Q3PE4 0x024a
|
||||
#define USB_PID_PX_W3PE5 0x073f
|
||||
#define USB_PID_PX_Q3PE5 0x074a
|
||||
#define USB_PID_PX_MLT5U 0x084e
|
||||
#define USB_PID_PX_MLT5PE 0x024e
|
||||
#define USB_PID_PX_MLT8PE3 0x0252
|
||||
#define USB_PID_PX_MLT8PE5 0x0253
|
||||
#define USB_PID_DIGIBEST_ISDB2056 0x004b
|
||||
#define USB_PID_DIGIBEST_ISDB2056N 0x084b
|
||||
#define USB_PID_DIGIBEST_ISDB6014_4TS 0x0254
|
||||
#define USB_PID_PX_M1UR 0x0854
|
||||
#define USB_PID_PX_S1UR 0x0855
|
||||
#define USB_PID_DIGIBEST_ISDBT2071 0x0052
|
||||
|
||||
|
||||
enum px4_usb_device_type {
|
||||
UNKNOWN_USB_DEVICE = 0,
|
||||
PX4_USB_DEVICE,
|
||||
PXMLT5_USB_DEVICE,
|
||||
PXMLT8_USB_DEVICE,
|
||||
ISDB2056_USB_DEVICE,
|
||||
ISDB6014_4TS_USB_DEVICE,
|
||||
PXM1UR_USB_DEVICE,
|
||||
PXS1UR_USB_DEVICE,
|
||||
ISDBT2071_USB_DEVICE,
|
||||
//----
|
||||
MAX_USB_DEVICE_TYPE,
|
||||
};
|
||||
|
||||
int px4_usb_register(void);
|
||||
void px4_usb_unregister(void);
|
||||
|
||||
#endif
|
42
driver/px4_usb_params.c
Normal file
42
driver/px4_usb_params.c
Normal file
@@ -0,0 +1,42 @@
|
||||
// SPDX-Licence-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Module parameter definitions (px4_usb_params.c)
|
||||
*
|
||||
* Copyright (c) 2018-2021 nns779
|
||||
*/
|
||||
|
||||
#include "px4_usb_params.h"
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
struct px4_usb_param_set px4_usb_params = {
|
||||
.ctrl_timeout = 3000,
|
||||
.xfer_packets = 816,
|
||||
.urb_max_packets = 816,
|
||||
.max_urbs = 6,
|
||||
.no_dma = false
|
||||
};
|
||||
|
||||
module_param_named(ctrl_timeout, px4_usb_params.ctrl_timeout,
|
||||
int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
MODULE_PARM_DESC(ctrl_timeout,
|
||||
"Time in msecs to wait for the message to complete " \
|
||||
"before timing out (if 0 the wait is forever). (default: 3000)");
|
||||
|
||||
module_param_named(xfer_packets, px4_usb_params.xfer_packets,
|
||||
uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
MODULE_PARM_DESC(xfer_packets,
|
||||
"Number of transfer packets from the device. (default: 816)");
|
||||
|
||||
module_param_named(urb_max_packets, px4_usb_params.urb_max_packets,
|
||||
uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
MODULE_PARM_DESC(urb_max_packets,
|
||||
"Maximum number of TS packets per URB. (default: 816)");
|
||||
|
||||
module_param_named(max_urbs, px4_usb_params.max_urbs,
|
||||
uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
MODULE_PARM_DESC(max_urbs, "Maximum number of URBs. (default: 6)");
|
||||
|
||||
module_param_named(no_dma, px4_usb_params.no_dma,
|
||||
bool, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
18
driver/px4_usb_params.h
Normal file
18
driver/px4_usb_params.h
Normal file
@@ -0,0 +1,18 @@
|
||||
// px4_usb_params.h
|
||||
|
||||
#ifndef __PX4_USB_PARAMS_H__
|
||||
#define __PX4_USB_PARAMS_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct px4_usb_param_set {
|
||||
int ctrl_timeout;
|
||||
unsigned int xfer_packets;
|
||||
unsigned int urb_max_packets;
|
||||
unsigned int max_urbs;
|
||||
bool no_dma;
|
||||
};
|
||||
|
||||
extern struct px4_usb_param_set px4_usb_params;
|
||||
|
||||
#endif
|
1139
driver/pxmlt_device.c
Normal file
1139
driver/pxmlt_device.c
Normal file
File diff suppressed because it is too large
Load Diff
71
driver/pxmlt_device.h
Normal file
71
driver/pxmlt_device.h
Normal file
@@ -0,0 +1,71 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* PTX driver definitions for PLEX PX-MLT series devices (pxmlt_device.c)
|
||||
*
|
||||
* Copyright (c) 2018-2021 nns779
|
||||
*/
|
||||
|
||||
#ifndef __PXMLT_DEVICE_H__
|
||||
#define __PXMLT_DEVICE_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/kref.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
#include "ptx_chrdev.h"
|
||||
#include "it930x.h"
|
||||
#include "cxd2856er.h"
|
||||
#include "cxd2858er.h"
|
||||
|
||||
#define PXMLT_CHRDEV_MAX_NUM 5
|
||||
|
||||
#define PXMLT5_CHRDEV_NUM 5
|
||||
#define PXMLT8_CHRDEV_NUM 8
|
||||
#define ISDB6014_4TS_CHRDEV_NUM 4
|
||||
|
||||
enum pxmlt_model {
|
||||
PXMLT5U_MODEL = 0,
|
||||
PXMLT5PE_MODEL,
|
||||
PXMLT8PE3_MODEL,
|
||||
PXMLT8PE5_MODEL,
|
||||
ISDB6014_4TS_MODEL
|
||||
};
|
||||
|
||||
struct pxmlt_device;
|
||||
|
||||
struct pxmlt_chrdev {
|
||||
struct ptx_chrdev *chrdev;
|
||||
struct pxmlt_device *parent;
|
||||
bool lnb_power;
|
||||
struct mutex *tuner_lock;
|
||||
struct cxd2856er_demod cxd2856er;
|
||||
struct cxd2858er_tuner cxd2858er;
|
||||
};
|
||||
|
||||
struct pxmlt_device {
|
||||
struct mutex lock;
|
||||
struct kref kref;
|
||||
atomic_t available;
|
||||
struct device *dev;
|
||||
struct completion *quit_completion;
|
||||
unsigned int open_count;
|
||||
unsigned int lnb_power_count;
|
||||
unsigned int streaming_count;
|
||||
struct mutex tuner_lock[2];
|
||||
struct ptx_chrdev_group *chrdev_group;
|
||||
int chrdevm_num;
|
||||
struct pxmlt_chrdev chrdevm[PXMLT_CHRDEV_MAX_NUM];
|
||||
struct it930x_bridge it930x;
|
||||
void *stream_ctx;
|
||||
};
|
||||
|
||||
int pxmlt_device_init(struct pxmlt_device *pxmlt, struct device *dev,
|
||||
enum pxmlt_model model,
|
||||
struct ptx_chrdev_context *chrdev_ctx,
|
||||
struct completion *quit_completion);
|
||||
void pxmlt_device_term(struct pxmlt_device *pxmlt);
|
||||
|
||||
#endif
|
2339
driver/r850.c
Normal file
2339
driver/r850.c
Normal file
File diff suppressed because it is too large
Load Diff
106
driver/r850.h
Normal file
106
driver/r850.h
Normal file
@@ -0,0 +1,106 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* RafaelMicro R850 driver definitions (r850.h)
|
||||
*
|
||||
* Copyright (c) 2018-2021 nns779
|
||||
*/
|
||||
|
||||
#ifndef __R850_H__
|
||||
#define __R850_H__
|
||||
|
||||
#ifdef __linux__
|
||||
#include <linux/types.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/device.h>
|
||||
#elif defined(_WIN32) || defined(_WIN64)
|
||||
#include "misc_win.h"
|
||||
#endif
|
||||
|
||||
#include "i2c_comm.h"
|
||||
|
||||
#define R850_NUM_REGS 0x30
|
||||
|
||||
struct r850_config {
|
||||
u32 xtal;
|
||||
bool loop_through;
|
||||
bool clock_out;
|
||||
bool no_imr_calibration;
|
||||
bool no_lpf_calibration;
|
||||
};
|
||||
|
||||
enum r850_system {
|
||||
R850_SYSTEM_UNDEFINED = 0,
|
||||
R850_SYSTEM_DVB_T,
|
||||
R850_SYSTEM_DVB_T2,
|
||||
R850_SYSTEM_DVB_T2_1,
|
||||
R850_SYSTEM_DVB_C,
|
||||
R850_SYSTEM_J83B,
|
||||
R850_SYSTEM_ISDB_T,
|
||||
R850_SYSTEM_DTMB,
|
||||
R850_SYSTEM_ATSC,
|
||||
R850_SYSTEM_FM,
|
||||
};
|
||||
|
||||
enum r850_bandwidth{
|
||||
R850_BANDWIDTH_6M = 0,
|
||||
R850_BANDWIDTH_7M,
|
||||
R850_BANDWIDTH_8M,
|
||||
};
|
||||
|
||||
struct r850_system_config {
|
||||
enum r850_system system;
|
||||
enum r850_bandwidth bandwidth;
|
||||
u32 if_freq;
|
||||
};
|
||||
|
||||
struct r850_imr {
|
||||
u8 gain; // x
|
||||
u8 phase; // y
|
||||
u8 iqcap;
|
||||
u8 value;
|
||||
};
|
||||
|
||||
struct r850_priv {
|
||||
struct mutex lock;
|
||||
bool init;
|
||||
int chip;
|
||||
u8 xtal_pwr;
|
||||
u8 regs[R850_NUM_REGS];
|
||||
bool sleep;
|
||||
struct r850_system_config sys;
|
||||
u8 mixer_mode;
|
||||
u8 mixer_amp_lpf_imr_cal;
|
||||
struct {
|
||||
struct r850_imr imr[5];
|
||||
bool done;
|
||||
bool result[5];
|
||||
u8 mixer_amp_lpf;
|
||||
} imr_cal[2];
|
||||
struct r850_system_config sys_curr;
|
||||
};
|
||||
|
||||
struct r850_tuner {
|
||||
const struct device *dev;
|
||||
const struct i2c_comm_master *i2c;
|
||||
u8 i2c_addr;
|
||||
struct r850_config config;
|
||||
struct r850_priv priv;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
int r850_init(struct r850_tuner *t);
|
||||
int r850_term(struct r850_tuner *t);
|
||||
|
||||
int r850_sleep(struct r850_tuner *t);
|
||||
int r850_wakeup(struct r850_tuner *t);
|
||||
int r850_set_system(struct r850_tuner *t,
|
||||
struct r850_system_config *system);
|
||||
int r850_set_frequency(struct r850_tuner *t, u32 freq);
|
||||
int r850_is_pll_locked(struct r850_tuner *t, bool *locked);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@@ -1,10 +0,0 @@
|
||||
// r850_channel.h
|
||||
|
||||
#ifndef __R850_CHANNEL_H__
|
||||
#define __R850_CHANNEL_H__
|
||||
|
||||
#include "r850_lite.h"
|
||||
|
||||
int r850_channel_get_regs(u32 no, u8 regs[2][R850_NUM_REGS - 0x08]);
|
||||
|
||||
#endif
|
@@ -1,135 +0,0 @@
|
||||
// r850_lite.c
|
||||
|
||||
// Rafael Micro R850 driver (lite version)
|
||||
|
||||
// Some features are not implemented.
|
||||
|
||||
#include "print_format.h"
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
#include "r850_lite.h"
|
||||
|
||||
/* Some versions, the first 8 bytes are zero. */
|
||||
static const u8 init_regs[R850_NUM_REGS] = {
|
||||
0x35, 0xc8, 0x0f, 0x80, 0xfa, 0xff, 0xff, 0xf0,
|
||||
0xc0, 0x49, 0x3a, 0x90, 0x03, 0xc1, 0x61, 0x71,
|
||||
0x17, 0xf1, 0x18, 0x55, 0x30, 0x20, 0xf3, 0xed,
|
||||
0x1f, 0x1c, 0x81, 0x13, 0x00, 0x80, 0x0a, 0x07,
|
||||
0x21, 0x71, 0x54, 0xf1, 0xf2, 0xa9, 0xbb, 0x0b,
|
||||
0xa3, 0xf6, 0x0b, 0x44, 0x92, 0x17, 0xe6, 0x80
|
||||
};
|
||||
|
||||
static u8 reverse_bit(u8 val)
|
||||
{
|
||||
u8 t = val;
|
||||
|
||||
t = (t & 0x55) << 1 | (t & 0xaa) >> 1;
|
||||
t = (t & 0x33) << 2 | (t & 0xcc) >> 2;
|
||||
t = (t & 0x0f) << 4 | (t & 0xf0) >> 4;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
static int r850_write_regs(struct r850_tuner *t, u8 reg, const u8 *buf, int len)
|
||||
{
|
||||
u8 b[1 + R850_NUM_REGS];
|
||||
|
||||
if (!t || !buf || !len)
|
||||
return -EINVAL;
|
||||
|
||||
if (len > (R850_NUM_REGS - reg))
|
||||
return -EINVAL;
|
||||
|
||||
b[0] = reg;
|
||||
memcpy(&b[1], buf, len);
|
||||
|
||||
return i2c_comm_master_write(t->i2c, t->i2c_addr, b, len + 1);
|
||||
}
|
||||
|
||||
static int r850_read_regs(struct r850_tuner *t, u8 reg, u8 *buf, int len)
|
||||
{
|
||||
int ret = 0, i;
|
||||
u8 b[1 + R850_NUM_REGS];
|
||||
|
||||
if (!t || !buf || !len)
|
||||
return -EINVAL;
|
||||
|
||||
if (len > (R850_NUM_REGS - reg))
|
||||
return -EINVAL;
|
||||
|
||||
b[0] = 0x00;
|
||||
|
||||
ret = i2c_comm_master_write(t->i2c, t->i2c_addr, b, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = i2c_comm_master_read(t->i2c, t->i2c_addr, &b[0], len + reg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = reg; i < (reg + len); i++)
|
||||
buf[i - reg] = reverse_bit(b[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int r850_init(struct r850_tuner *t)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (t->init)
|
||||
return 0;
|
||||
|
||||
// should check reg 0x00
|
||||
t->chip = 1;
|
||||
|
||||
memcpy(t->regs, init_regs, sizeof(init_regs));
|
||||
|
||||
#if 0
|
||||
ret = r850_write_regs(t, 0x00, t->regs, R850_NUM_REGS);
|
||||
#endif
|
||||
|
||||
t->init = true;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int r850_term(struct r850_tuner *t)
|
||||
{
|
||||
if (!t->init)
|
||||
return 0;
|
||||
|
||||
memset(t->regs, 0, sizeof(t->regs));
|
||||
|
||||
t->chip = 0;
|
||||
|
||||
t->init = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int r850_write_config_regs(struct r850_tuner *t, u8 *regs)
|
||||
{
|
||||
return r850_write_regs(t, 0x08, regs, R850_NUM_REGS - 0x08);
|
||||
}
|
||||
|
||||
int r850_is_pll_locked(struct r850_tuner *t, bool *locked)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 tmp;
|
||||
|
||||
ret = r850_read_regs(t, 0x02, &tmp, 1);
|
||||
if (ret) {
|
||||
dev_err(t->dev, "r850_is_pll_locked: r850_read_regs() failed. (ret: %d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*locked = (tmp & 0x40) ? true : false;
|
||||
|
||||
return ret;
|
||||
}
|
@@ -1,49 +0,0 @@
|
||||
// r850_lite.h
|
||||
|
||||
#ifndef __R850_LITE_H__
|
||||
#define __R850_LITE_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
#include "i2c_comm.h"
|
||||
|
||||
#define R850_NUM_REGS 0x30
|
||||
|
||||
typedef enum {
|
||||
R850_SYSTEM_STANDARD = 0,
|
||||
R850_SYSTEM_ISDB_T,
|
||||
} r850_system_t;
|
||||
|
||||
typedef enum {
|
||||
R850_BANDWIDTH_6M = 0,
|
||||
R850_BANDWIDTH_7M,
|
||||
R850_BANDWIDTH_8M,
|
||||
} r850_bandwidth_t;
|
||||
|
||||
struct r850_system_config {
|
||||
r850_system_t system;
|
||||
r850_bandwidth_t bandwidth;
|
||||
u32 if_freq;
|
||||
bool is_cable_system; // DVB-C, J38B
|
||||
};
|
||||
|
||||
struct r850_tuner {
|
||||
struct device *dev;
|
||||
struct i2c_comm_master *i2c;
|
||||
u8 i2c_addr;
|
||||
bool init;
|
||||
int chip;
|
||||
u32 xtal;
|
||||
u8 xtal_pwr;
|
||||
struct r850_system_config config;
|
||||
u8 regs[R850_NUM_REGS];
|
||||
};
|
||||
|
||||
int r850_init(struct r850_tuner *t);
|
||||
int r850_term(struct r850_tuner *t);
|
||||
|
||||
int r850_write_config_regs(struct r850_tuner *t, u8 *regs);
|
||||
int r850_is_pll_locked(struct r850_tuner *t, bool *locked);
|
||||
|
||||
#endif
|
@@ -1,294 +1,288 @@
|
||||
// ringbuffer.c
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/uaccess.h>
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Ringbuffer implementation (ringbuffer.c)
|
||||
*
|
||||
* Copyright (c) 2018-2021 nns779
|
||||
*/
|
||||
|
||||
#include "ringbuffer.h"
|
||||
|
||||
static int _ringbuffer_init(struct ringbuffer *ringbuffer)
|
||||
{
|
||||
spin_lock_init(&ringbuffer->lock);
|
||||
atomic_set(&ringbuffer->avail, 0);
|
||||
atomic_set(&ringbuffer->rw_cnt, 0);
|
||||
atomic_set(&ringbuffer->wait_cnt, 0);
|
||||
init_waitqueue_head(&ringbuffer->wait);
|
||||
init_waitqueue_head(&ringbuffer->data_wait);
|
||||
ringbuffer->buf = NULL;
|
||||
ringbuffer->buf_size = 0;
|
||||
ringbuffer->data_size = 0;
|
||||
ringbuffer->tail_pos = 0;
|
||||
ringbuffer->head_pos = 0;
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
return 0;
|
||||
}
|
||||
static void ringbuffer_free_nolock(struct ringbuffer *ringbuf);
|
||||
static void ringbuffer_lock(struct ringbuffer *ringbuf);
|
||||
|
||||
int ringbuffer_create(struct ringbuffer **ringbuffer)
|
||||
int ringbuffer_create(struct ringbuffer **ringbuf)
|
||||
{
|
||||
int ret = 0;
|
||||
struct ringbuffer *p;
|
||||
|
||||
*ringbuffer = NULL;
|
||||
|
||||
p = kzalloc(sizeof(struct ringbuffer), GFP_ATOMIC);
|
||||
p = kzalloc(sizeof(*p), GFP_KERNEL);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = _ringbuffer_init(p);
|
||||
if (!ret)
|
||||
*ringbuffer = p;
|
||||
else
|
||||
kfree(p);
|
||||
atomic_set(&p->state, 0);
|
||||
atomic_set(&p->rw_count, 0);
|
||||
atomic_set(&p->wait_count, 0);
|
||||
init_waitqueue_head(&p->wait);
|
||||
p->buf = NULL;
|
||||
p->size = 0;
|
||||
atomic_set(&p->actual_size, 0);
|
||||
atomic_set(&p->head, 0);
|
||||
atomic_set(&p->tail, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ringbuffer_destroy(struct ringbuffer *ringbuffer)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = ringbuffer_free(ringbuffer);
|
||||
if (!ret)
|
||||
kfree(ringbuffer);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void _ringbuffer_free(struct ringbuffer *ringbuffer)
|
||||
{
|
||||
free_pages((unsigned long)ringbuffer->buf, get_order(ringbuffer->buf_size));
|
||||
|
||||
ringbuffer->buf = NULL;
|
||||
ringbuffer->buf_size = 0;
|
||||
ringbuffer->data_size = 0;
|
||||
ringbuffer->tail_pos = 0;
|
||||
ringbuffer->head_pos = 0;
|
||||
}
|
||||
|
||||
int ringbuffer_alloc(struct ringbuffer *ringbuffer, size_t size)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
// Acquire lock
|
||||
if (atomic_add_return(1, &ringbuffer->wait_cnt) != 1) {
|
||||
// Someone is waiting
|
||||
ret = -EAGAIN;
|
||||
goto exit;
|
||||
}
|
||||
atomic_set(&ringbuffer->avail, 0);
|
||||
wake_up(&ringbuffer->data_wait);
|
||||
wait_event(ringbuffer->wait, !atomic_read(&ringbuffer->rw_cnt));
|
||||
|
||||
if (ringbuffer->buf) {
|
||||
if (ringbuffer->buf_size == size)
|
||||
goto reset;
|
||||
|
||||
_ringbuffer_free(ringbuffer);
|
||||
}
|
||||
|
||||
// Allocate
|
||||
|
||||
ringbuffer->buf = (u8 *)__get_free_pages(GFP_ATOMIC, get_order(size));
|
||||
if (!ringbuffer->buf) {
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ringbuffer->buf_size = size;
|
||||
|
||||
reset:
|
||||
ringbuffer->data_size = 0;
|
||||
ringbuffer->tail_pos = 0;
|
||||
ringbuffer->head_pos = 0;
|
||||
|
||||
exit:
|
||||
// Release lock
|
||||
atomic_sub(1, &ringbuffer->wait_cnt);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ringbuffer_free(struct ringbuffer *ringbuffer)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
// Acquire lock
|
||||
if (atomic_add_return(1, &ringbuffer->wait_cnt) != 1) {
|
||||
// Someone is waiting
|
||||
ret = -EAGAIN;
|
||||
goto exit;
|
||||
}
|
||||
atomic_set(&ringbuffer->avail, 0);
|
||||
wake_up(&ringbuffer->data_wait);
|
||||
wait_event(ringbuffer->wait, !atomic_read(&ringbuffer->rw_cnt));
|
||||
|
||||
if (!ringbuffer->buf)
|
||||
goto exit;
|
||||
|
||||
_ringbuffer_free(ringbuffer);
|
||||
|
||||
exit:
|
||||
// Release lock
|
||||
atomic_sub(1, &ringbuffer->wait_cnt);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ringbuffer_start(struct ringbuffer *ringbuffer)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (atomic_read(&ringbuffer->avail))
|
||||
return 0;
|
||||
|
||||
// Acquire lock for read buffer pointer
|
||||
if (atomic_add_return(1, &ringbuffer->wait_cnt) != 1) {
|
||||
// Someone is waiting
|
||||
ret = -EAGAIN;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (ringbuffer->buf && ringbuffer->buf_size)
|
||||
atomic_set(&ringbuffer->avail, 1);
|
||||
|
||||
exit:
|
||||
// Release lock
|
||||
atomic_sub(1, &ringbuffer->wait_cnt);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ringbuffer_stop(struct ringbuffer *ringbuffer)
|
||||
{
|
||||
atomic_set(&ringbuffer->avail, 0);
|
||||
wake_up(&ringbuffer->data_wait);
|
||||
*ringbuf = p;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ringbuffer_write_atomic(struct ringbuffer *ringbuffer, const void *data, size_t len)
|
||||
int ringbuffer_destroy(struct ringbuffer *ringbuf)
|
||||
{
|
||||
unsigned long flags;
|
||||
const u8 *p = data;
|
||||
size_t buf_size, data_size, tail_pos, write_size;
|
||||
int rr;
|
||||
ringbuffer_stop(ringbuf);
|
||||
|
||||
if (atomic_read(&ringbuffer->avail) != 2)
|
||||
return -EIO;
|
||||
|
||||
atomic_add(1, &ringbuffer->rw_cnt);
|
||||
|
||||
if (atomic_read(&ringbuffer->wait_cnt)) {
|
||||
atomic_sub(1, &ringbuffer->rw_cnt);
|
||||
wake_up(&ringbuffer->wait);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
buf_size = ringbuffer->buf_size;
|
||||
tail_pos = ringbuffer->tail_pos;
|
||||
|
||||
spin_lock_irqsave(&ringbuffer->lock, flags);
|
||||
data_size = ringbuffer->data_size;
|
||||
spin_unlock_irqrestore(&ringbuffer->lock, flags);
|
||||
|
||||
write_size = (data_size + len <= buf_size) ? (len) : (buf_size - data_size);
|
||||
if (write_size) {
|
||||
size_t t = (tail_pos + write_size <= buf_size) ? (write_size) : (buf_size - tail_pos);
|
||||
|
||||
memcpy(ringbuffer->buf + tail_pos, p, t);
|
||||
if (t < write_size) {
|
||||
memcpy(ringbuffer->buf, p + t, write_size - t);
|
||||
tail_pos = write_size - t;
|
||||
} else {
|
||||
tail_pos = (tail_pos + write_size == buf_size) ? 0 : (tail_pos + write_size);
|
||||
}
|
||||
|
||||
ringbuffer->tail_pos = tail_pos;
|
||||
|
||||
spin_lock_irqsave(&ringbuffer->lock, flags);
|
||||
ringbuffer->data_size += write_size;
|
||||
spin_unlock_irqrestore(&ringbuffer->lock, flags);
|
||||
|
||||
wake_up(&ringbuffer->data_wait);
|
||||
}
|
||||
|
||||
rr = atomic_sub_return(1, &ringbuffer->rw_cnt);
|
||||
if (atomic_read(&ringbuffer->wait_cnt) && !rr)
|
||||
wake_up(&ringbuffer->wait);
|
||||
|
||||
return (write_size != len) ? (-ECANCELED) : (0);
|
||||
}
|
||||
|
||||
int ringbuffer_read_to_user(struct ringbuffer *ringbuffer, void __user *buf, size_t *len)
|
||||
{
|
||||
u8 *p = buf;
|
||||
size_t buf_size, l = *len, buf_pos = 0;
|
||||
int rr;
|
||||
|
||||
if (!atomic_cmpxchg(&ringbuffer->avail, 1, 2))
|
||||
return -EIO;
|
||||
|
||||
atomic_add(1, &ringbuffer->rw_cnt);
|
||||
|
||||
if (atomic_read(&ringbuffer->wait_cnt)) {
|
||||
atomic_sub(1, &ringbuffer->rw_cnt);
|
||||
wake_up(&ringbuffer->wait);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
buf_size = ringbuffer->buf_size;
|
||||
|
||||
while (l > buf_pos && atomic_read(&ringbuffer->avail)) {
|
||||
size_t data_size, head_pos, read_size, t;
|
||||
unsigned long r;
|
||||
|
||||
wait_event(ringbuffer->data_wait, (ringbuffer->data_size || !atomic_read(&ringbuffer->avail)));
|
||||
|
||||
spin_lock(&ringbuffer->lock);
|
||||
data_size = ringbuffer->data_size;
|
||||
spin_unlock(&ringbuffer->lock);
|
||||
|
||||
if (!data_size)
|
||||
break;
|
||||
|
||||
head_pos = ringbuffer->head_pos;
|
||||
|
||||
read_size = (l - buf_pos > data_size) ? (data_size) : (l - buf_pos);
|
||||
|
||||
t = (head_pos + read_size <= buf_size) ? (read_size) : (buf_size - head_pos);
|
||||
|
||||
r = copy_to_user(p + buf_pos, ringbuffer->buf + head_pos, t);
|
||||
if (r)
|
||||
pr_debug("ringbuffer_read_to_user: copy_to_user() 1 failed. remain: %lu\n", r);
|
||||
|
||||
if (t < read_size) {
|
||||
r = copy_to_user(p + buf_pos + t, ringbuffer->buf, read_size - t);
|
||||
if (r)
|
||||
pr_debug("ringbuffer_read_to_user: copy_to_user() 2 failed. remain: %lu\n", r);
|
||||
|
||||
head_pos = read_size - t;
|
||||
} else {
|
||||
head_pos = (head_pos + read_size == buf_size) ? 0 : (head_pos + read_size);
|
||||
}
|
||||
|
||||
ringbuffer->head_pos = head_pos;
|
||||
buf_pos += read_size;
|
||||
|
||||
spin_lock(&ringbuffer->lock);
|
||||
ringbuffer->data_size -= read_size;
|
||||
spin_unlock(&ringbuffer->lock);
|
||||
}
|
||||
|
||||
*len = buf_pos;
|
||||
|
||||
rr = atomic_sub_return(1, &ringbuffer->rw_cnt);
|
||||
if (atomic_read(&ringbuffer->wait_cnt) && !rr)
|
||||
wake_up(&ringbuffer->wait);
|
||||
ringbuffer_lock(ringbuf);
|
||||
ringbuffer_free_nolock(ringbuf);
|
||||
kfree(ringbuf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ringbuffer_free_nolock(struct ringbuffer *ringbuf)
|
||||
{
|
||||
if (ringbuf->buf)
|
||||
free_pages((unsigned long)ringbuf->buf,
|
||||
get_order(ringbuf->size));
|
||||
|
||||
ringbuf->buf = NULL;
|
||||
ringbuf->size = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void ringbuffer_reset_nolock(struct ringbuffer *ringbuf)
|
||||
{
|
||||
atomic_set(&ringbuf->actual_size, 0);
|
||||
atomic_set(&ringbuf->head, 0);
|
||||
atomic_set(&ringbuf->tail, 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void ringbuffer_lock(struct ringbuffer *ringbuf)
|
||||
{
|
||||
atomic_add_return(1, &ringbuf->wait_count);
|
||||
wait_event(ringbuf->wait, !atomic_read(&ringbuf->rw_count));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void ringbuffer_unlock(struct ringbuffer *ringbuf)
|
||||
{
|
||||
if (atomic_sub_return(1, &ringbuf->wait_count))
|
||||
wake_up(&ringbuf->wait);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int ringbuffer_alloc(struct ringbuffer *ringbuf, size_t size)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (size > INT_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
if (atomic_read_acquire(&ringbuf->state))
|
||||
return -EBUSY;
|
||||
|
||||
ringbuffer_lock(ringbuf);
|
||||
|
||||
if (ringbuf->buf && ringbuf->size != size)
|
||||
ringbuffer_free_nolock(ringbuf);
|
||||
|
||||
ringbuf->size = 0;
|
||||
ringbuffer_reset_nolock(ringbuf);
|
||||
|
||||
if (!ringbuf->buf) {
|
||||
#ifdef __GFP_RETRY_MAYFAIL
|
||||
ringbuf->buf = (u8 *)__get_free_pages(GFP_KERNEL | __GFP_RETRY_MAYFAIL,
|
||||
get_order(size));
|
||||
#else
|
||||
ringbuf->buf = (u8 *)__get_free_pages(GFP_KERNEL | __GFP_REPEAT,
|
||||
get_order(size));
|
||||
#endif
|
||||
if (!ringbuf->buf)
|
||||
ret = -ENOMEM;
|
||||
else
|
||||
ringbuf->size = size;
|
||||
}
|
||||
|
||||
ringbuffer_unlock(ringbuf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ringbuffer_free(struct ringbuffer *ringbuf)
|
||||
{
|
||||
if (atomic_read_acquire(&ringbuf->state))
|
||||
return -EBUSY;
|
||||
|
||||
ringbuffer_lock(ringbuf);
|
||||
ringbuffer_reset_nolock(ringbuf);
|
||||
ringbuffer_free_nolock(ringbuf);
|
||||
ringbuffer_unlock(ringbuf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ringbuffer_reset(struct ringbuffer *ringbuf)
|
||||
{
|
||||
if (atomic_read_acquire(&ringbuf->state))
|
||||
return -EBUSY;
|
||||
|
||||
ringbuffer_lock(ringbuf);
|
||||
ringbuffer_reset_nolock(ringbuf);
|
||||
ringbuffer_unlock(ringbuf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ringbuffer_start(struct ringbuffer *ringbuf)
|
||||
{
|
||||
if (atomic_cmpxchg(&ringbuf->state, 0, 1))
|
||||
return -EALREADY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ringbuffer_stop(struct ringbuffer *ringbuf)
|
||||
{
|
||||
if (!atomic_xchg(&ringbuf->state, 0))
|
||||
return -EALREADY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ringbuffer_ready_read(struct ringbuffer *ringbuf)
|
||||
{
|
||||
if (!atomic_cmpxchg(&ringbuf->state, 1, 2))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ringbuffer_read_user(struct ringbuffer *ringbuf,
|
||||
void __user *buf, size_t *len)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 *p;
|
||||
size_t buf_size, actual_size, head, read_size;
|
||||
|
||||
atomic_add_return_acquire(1, &ringbuf->rw_count);
|
||||
|
||||
p = ringbuf->buf;
|
||||
buf_size = ringbuf->size;
|
||||
actual_size = atomic_read_acquire(&ringbuf->actual_size);
|
||||
head = atomic_read(&ringbuf->head);
|
||||
|
||||
read_size = (*len <= actual_size) ? *len : actual_size;
|
||||
if (likely(read_size)) {
|
||||
unsigned long res;
|
||||
|
||||
if (likely(head + read_size <= buf_size)) {
|
||||
res = copy_to_user(buf, p + head, read_size);
|
||||
if (unlikely(res)) {
|
||||
read_size -= res;
|
||||
ret = -EFAULT;
|
||||
}
|
||||
|
||||
head = (head + read_size == buf_size) ? 0
|
||||
: (head + read_size);
|
||||
} else {
|
||||
size_t tmp = buf_size - head;
|
||||
|
||||
res = copy_to_user(buf, p + head, tmp);
|
||||
if (likely(!res))
|
||||
res = copy_to_user(((u8 *)buf) + tmp, p,
|
||||
read_size - tmp);
|
||||
|
||||
if (unlikely(res)) {
|
||||
read_size -= res;
|
||||
ret = -EFAULT;
|
||||
}
|
||||
|
||||
head = read_size - tmp;
|
||||
}
|
||||
|
||||
atomic_xchg(&ringbuf->head, head);
|
||||
atomic_sub_return_release(read_size,
|
||||
&ringbuf->actual_size);
|
||||
}
|
||||
|
||||
if (unlikely(!atomic_sub_return(1, &ringbuf->rw_count) &&
|
||||
atomic_read(&ringbuf->wait_count)))
|
||||
wake_up(&ringbuf->wait);
|
||||
|
||||
*len = read_size;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ringbuffer_write_atomic(struct ringbuffer *ringbuf,
|
||||
const void *buf, size_t *len)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 *p;
|
||||
size_t buf_size, actual_size, tail, write_size;
|
||||
|
||||
if (unlikely(atomic_read(&ringbuf->state) != 2))
|
||||
return -EINVAL;
|
||||
|
||||
atomic_add_return_acquire(1, &ringbuf->rw_count);
|
||||
|
||||
p = ringbuf->buf;
|
||||
buf_size = ringbuf->size;
|
||||
actual_size = atomic_read_acquire(&ringbuf->actual_size);
|
||||
tail = atomic_read(&ringbuf->tail);
|
||||
|
||||
write_size = likely(actual_size + *len <= buf_size) ? *len
|
||||
: (buf_size - actual_size);
|
||||
if (likely(write_size)) {
|
||||
if (likely(tail + write_size <= buf_size)) {
|
||||
memcpy(p + tail, buf, write_size);
|
||||
tail = unlikely(tail + write_size == buf_size) ? 0
|
||||
: (tail + write_size);
|
||||
} else {
|
||||
size_t tmp = buf_size - tail;
|
||||
|
||||
memcpy(p + tail, buf, tmp);
|
||||
memcpy(p, ((u8 *)buf) + tmp, write_size - tmp);
|
||||
tail = write_size - tmp;
|
||||
}
|
||||
|
||||
atomic_xchg(&ringbuf->tail, tail);
|
||||
atomic_add_return_release(write_size,
|
||||
&ringbuf->actual_size);
|
||||
}
|
||||
|
||||
if (unlikely(!atomic_sub_return(1, &ringbuf->rw_count) &&
|
||||
atomic_read(&ringbuf->wait_count)))
|
||||
wake_up(&ringbuf->wait);
|
||||
|
||||
if (unlikely(*len != write_size))
|
||||
ret = -EOVERFLOW;
|
||||
|
||||
*len = write_size;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ringbuffer_is_running(struct ringbuffer *ringbuf)
|
||||
{
|
||||
return !!atomic_read_acquire(&ringbuf->state);
|
||||
}
|
||||
|
||||
bool ringbuffer_is_readable(struct ringbuffer *ringbuf)
|
||||
{
|
||||
return !!atomic_read_acquire(&ringbuf->actual_size);
|
||||
}
|
||||
|
@@ -1,34 +1,42 @@
|
||||
// ringbuffer.h
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Ringbuffer definitions (ringbuffer.h)
|
||||
*
|
||||
* Copyright (c) 2018-2021 nns779
|
||||
*/
|
||||
|
||||
#ifndef __RINGBUFFER_H__
|
||||
#define __RINGBUFFER_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/wait.h>
|
||||
|
||||
struct ringbuffer {
|
||||
spinlock_t lock; // for data_size
|
||||
atomic_t avail;
|
||||
atomic_t rw_cnt;
|
||||
atomic_t wait_cnt;
|
||||
atomic_t state;
|
||||
atomic_t rw_count;
|
||||
atomic_t wait_count;
|
||||
wait_queue_head_t wait;
|
||||
wait_queue_head_t data_wait;
|
||||
u8 *buf;
|
||||
size_t buf_size;
|
||||
size_t data_size;
|
||||
size_t tail_pos; // write
|
||||
size_t head_pos; // read
|
||||
size_t size;
|
||||
atomic_t actual_size;
|
||||
atomic_t head; // read
|
||||
atomic_t tail; // write
|
||||
};
|
||||
|
||||
int ringbuffer_create(struct ringbuffer **ringbuffer);
|
||||
int ringbuffer_destroy(struct ringbuffer *ringbuffer);
|
||||
int ringbuffer_alloc(struct ringbuffer *ringbuffer, size_t size);
|
||||
int ringbuffer_free(struct ringbuffer *ringbuffer);
|
||||
int ringbuffer_start(struct ringbuffer *ringbuffer);
|
||||
int ringbuffer_stop(struct ringbuffer *ringbuffer);
|
||||
int ringbuffer_write_atomic(struct ringbuffer *ringbuffer, const void *data, size_t len);
|
||||
int ringbuffer_read_to_user(struct ringbuffer *ringbuffer, void __user *buf, size_t *len);
|
||||
int ringbuffer_create(struct ringbuffer **ringbuf);
|
||||
int ringbuffer_destroy(struct ringbuffer *ringbuf);
|
||||
int ringbuffer_alloc(struct ringbuffer *ringbuf, size_t size);
|
||||
int ringbuffer_free(struct ringbuffer *ringbuf);
|
||||
int ringbuffer_reset(struct ringbuffer *ringbuf);
|
||||
int ringbuffer_start(struct ringbuffer *ringbuf);
|
||||
int ringbuffer_stop(struct ringbuffer *ringbuf);
|
||||
int ringbuffer_ready_read(struct ringbuffer *ringbuf);
|
||||
int ringbuffer_read_user(struct ringbuffer *ringbuf,
|
||||
void __user *buf, size_t *len);
|
||||
int ringbuffer_write_atomic(struct ringbuffer *ringbuf,
|
||||
const void *buf, size_t *len);
|
||||
bool ringbuffer_is_readable(struct ringbuffer *ringbuf);
|
||||
bool ringbuffer_is_running(struct ringbuffer *ringbuf);
|
||||
|
||||
#endif
|
||||
|
793
driver/rt710.c
793
driver/rt710.c
@@ -1,24 +1,35 @@
|
||||
// rt710.c
|
||||
|
||||
// RafaelMicro RT710 driver
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* RafaelMicro RT710 driver (rt710.c)
|
||||
*
|
||||
* Copyright (c) 2018-2021 nns779
|
||||
*/
|
||||
|
||||
#include "print_format.h"
|
||||
#include "rt710.h"
|
||||
|
||||
#include <linux/types.h>
|
||||
#ifdef __linux__
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
#include "i2c_comm.h"
|
||||
#include "rt710.h"
|
||||
#endif
|
||||
|
||||
#define NUM_REGS 0x10
|
||||
|
||||
static const u8 init_regs[NUM_REGS] = {
|
||||
struct rt710_bandwidth_param {
|
||||
u8 coarse;
|
||||
u8 fine;
|
||||
};
|
||||
|
||||
static const u8 rt710_init_regs[NUM_REGS] = {
|
||||
0x40, 0x1d, 0x20, 0x10, 0x41, 0x50, 0xed, 0x25,
|
||||
0x07, 0x58, 0x39, 0x64, 0x38, 0xf7/*0xe7*/, 0x90, 0x35
|
||||
0x07, 0x58, 0x39, 0x64, 0x38, 0xe7, 0x90, 0x35
|
||||
};
|
||||
|
||||
static const u8 rt720_init_regs[NUM_REGS] = {
|
||||
0x00, 0x1c, 0x00, 0x10, 0x41, 0x48, 0xda, 0x4b,
|
||||
0x07, 0x58, 0x38, 0x40, 0x37, 0xe7, 0x4c, 0x59
|
||||
};
|
||||
|
||||
static const u8 sleep_regs[NUM_REGS] = {
|
||||
@@ -26,6 +37,51 @@ static const u8 sleep_regs[NUM_REGS] = {
|
||||
0x47, 0xfc, 0x48, 0xa2, 0x08, 0x0f, 0xf3, 0x59
|
||||
};
|
||||
|
||||
static const struct {
|
||||
u32 bandwidth;
|
||||
struct rt710_bandwidth_param param;
|
||||
} bandwidth_params[] = {
|
||||
{ 50000, { 0, 0 } },
|
||||
{ 73000, { 0, 1 } },
|
||||
{ 96000, { 1, 0 } },
|
||||
{ 104000, { 1, 1 } },
|
||||
{ 116000, { 2, 0 } },
|
||||
{ 126000, { 2, 1 } },
|
||||
{ 134000, { 3, 0 } },
|
||||
{ 146000, { 3, 1 } },
|
||||
{ 158000, { 4, 0 } },
|
||||
{ 170000, { 4, 1 } },
|
||||
{ 178000, { 5, 0 } },
|
||||
{ 190000, { 5, 1 } },
|
||||
{ 202000, { 6, 0 } },
|
||||
{ 212000, { 6, 1 } },
|
||||
{ 218000, { 7, 0 } },
|
||||
{ 234000, { 7, 1 } },
|
||||
{ 244000, { 9, 1 } },
|
||||
{ 246000, { 10, 0 } },
|
||||
{ 262000, { 10, 1 } },
|
||||
{ 266000, { 11, 0 } },
|
||||
{ 282000, { 11, 1 } },
|
||||
{ 298000, { 12, 1 } },
|
||||
{ 318000, { 13, 1 } },
|
||||
{ 340000, { 14, 1 } },
|
||||
{ 358000, { 15, 1 } },
|
||||
{ 379999, { 16, 1 } },
|
||||
};
|
||||
|
||||
static const u16 rt710_lna_acc_gain[] = {
|
||||
0, 26, 42, 74, 103, 129, 158, 181,
|
||||
188, 200, 220, 248, 280, 312, 341, 352,
|
||||
366, 389, 409
|
||||
};
|
||||
|
||||
static const u16 rt720_lna_acc_gain[] = {
|
||||
0, 27, 53, 81, 109, 134, 156, 176,
|
||||
194, 202, 211, 221, 232, 245, 258, 271,
|
||||
285, 307, 326, 341, 357, 374, 393, 410,
|
||||
428, 439, 445, 470, 476, 479, 495, 507
|
||||
};
|
||||
|
||||
static u8 reverse_bit(u8 val)
|
||||
{
|
||||
u8 t = val;
|
||||
@@ -37,9 +93,50 @@ static u8 reverse_bit(u8 val)
|
||||
return t;
|
||||
}
|
||||
|
||||
static int rt710_write_regs(struct rt710_tuner *t, u8 reg, const u8 *buf, int len)
|
||||
static int rt710_read_regs(struct rt710_tuner *t, u8 reg, u8 *buf, int len)
|
||||
{
|
||||
int ret = 0, i;
|
||||
u8 b[1 + NUM_REGS];
|
||||
struct i2c_comm_request req[2];
|
||||
|
||||
if (!t || !buf || !len)
|
||||
return -EINVAL;
|
||||
|
||||
if (len > (NUM_REGS - reg))
|
||||
return -EINVAL;
|
||||
|
||||
b[0] = 0x00;
|
||||
|
||||
req[0].req = I2C_WRITE_REQUEST;
|
||||
req[0].addr = t->i2c_addr;
|
||||
req[0].data = b;
|
||||
req[0].len = 1;
|
||||
|
||||
req[1].req = I2C_READ_REQUEST;
|
||||
req[1].addr = t->i2c_addr;
|
||||
req[1].data = b;
|
||||
req[1].len = reg + len;
|
||||
|
||||
ret = i2c_comm_master_request(t->i2c, req, 2);
|
||||
if (ret) {
|
||||
dev_err(t->dev,
|
||||
"rt710_read_regs: i2c_comm_master_request() failed. (reg: 0x%02x, len: %d, ret: %d)\n",
|
||||
reg, len, ret);
|
||||
} else {
|
||||
for (i = reg; i < (reg + len); i++)
|
||||
buf[i - reg] = reverse_bit(b[i]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rt710_write_regs(struct rt710_tuner *t,
|
||||
u8 reg,
|
||||
const u8 *buf, int len)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 b[1 + NUM_REGS];
|
||||
struct i2c_comm_request req[1];
|
||||
|
||||
if (!t || !buf || !len)
|
||||
return -EINVAL;
|
||||
@@ -50,163 +147,142 @@ static int rt710_write_regs(struct rt710_tuner *t, u8 reg, const u8 *buf, int le
|
||||
b[0] = reg;
|
||||
memcpy(&b[1], buf, len);
|
||||
|
||||
return i2c_comm_master_write(t->i2c, t->i2c_addr, b, len + 1);
|
||||
req[0].req = I2C_WRITE_REQUEST;
|
||||
req[0].addr = t->i2c_addr;
|
||||
req[0].data = b;
|
||||
req[0].len = 1 + len;
|
||||
|
||||
ret = i2c_comm_master_request(t->i2c, req, 1);
|
||||
if (ret)
|
||||
dev_err(t->dev,
|
||||
"rt710_write_regs: i2c_comm_master_request() failed. (reg: 0x%02x, len: %d, ret: %d)\n",
|
||||
reg, len, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rt710_read_regs(struct rt710_tuner *t, u8 reg, u8 *buf, int len)
|
||||
{
|
||||
int ret = 0, i;
|
||||
u8 b[1 + NUM_REGS];
|
||||
|
||||
if (!t || !buf || !len)
|
||||
return -EINVAL;
|
||||
|
||||
if (len > (NUM_REGS - reg))
|
||||
return -EINVAL;
|
||||
|
||||
b[0] = 0x00;
|
||||
|
||||
ret = i2c_comm_master_write(t->i2c, t->i2c_addr, b, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = i2c_comm_master_read(t->i2c, t->i2c_addr, &b[0], len + reg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = reg; i < (reg + len); i++)
|
||||
buf[i - reg] = reverse_bit(b[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rt710_init(struct rt710_tuner *t)
|
||||
static int rt710_set_pll(struct rt710_tuner *t, u8 *regs, u32 freq)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 tmp;
|
||||
u32 xtal, vco_min, vco_max, vco_freq;
|
||||
u16 vco_fra, nsdm = 2, sdm = 0;
|
||||
u8 mix_div = 2, div_num, nint, ni, si;
|
||||
|
||||
ret = rt710_read_regs(t, 0x03, &tmp, 1);
|
||||
if (ret) {
|
||||
dev_err(t->dev, "rt710_init: rt710_read_regs() failed.\n");
|
||||
return ret;
|
||||
}
|
||||
xtal = t->config.xtal;
|
||||
|
||||
if ((tmp & 0xf0) != 0x70) {
|
||||
dev_err(t->dev, "rt710_init: Unknown chip.\n");
|
||||
return -ENOSYS;
|
||||
}
|
||||
vco_min = 2350000;
|
||||
vco_max = vco_min * 2;
|
||||
vco_freq = freq * mix_div;
|
||||
|
||||
return 0;
|
||||
}
|
||||
t->priv.freq = 0;
|
||||
|
||||
int rt710_term(struct rt710_tuner *t)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rt710_sleep(struct rt710_tuner *t, bool sleep)
|
||||
{
|
||||
u8 regs[NUM_REGS];
|
||||
|
||||
memcpy(regs, sleep_regs, sizeof(regs));
|
||||
|
||||
if (sleep)
|
||||
regs[0x03] = 0x20;
|
||||
|
||||
return rt710_write_regs(t, 0x00, regs, NUM_REGS);
|
||||
}
|
||||
|
||||
static int rt710_set_pll_regs(struct rt710_tuner *t, u8 *regs, u32 freq)
|
||||
{
|
||||
int ret = 0;
|
||||
u32 min, max, b, c;
|
||||
u16 e, g, h;
|
||||
u8 div, a, d, f;
|
||||
|
||||
min = 2350000;
|
||||
max = min * 2;
|
||||
div = 2;
|
||||
a = 0;
|
||||
g = 2;
|
||||
h = 0;
|
||||
|
||||
do {
|
||||
u32 q;
|
||||
q = freq * div;
|
||||
if (q >= min && q <= max) {
|
||||
switch(div) {
|
||||
case 2:
|
||||
a = 1;
|
||||
break;
|
||||
case 4:
|
||||
a = 0;
|
||||
break;
|
||||
case 8:
|
||||
a = 2;
|
||||
break;
|
||||
case 16:
|
||||
a = 3;
|
||||
break;
|
||||
default:
|
||||
return -ECANCELED;
|
||||
}
|
||||
while (mix_div <= 16) {
|
||||
if (vco_freq >= vco_min && vco_freq <= vco_max)
|
||||
break;
|
||||
}
|
||||
div *= 2;
|
||||
} while(div <= 16);
|
||||
|
||||
regs[4] &= 0xfe;
|
||||
regs[4] |= (a & 1);
|
||||
mix_div *= 2;
|
||||
vco_freq = freq * mix_div;
|
||||
}
|
||||
|
||||
switch (mix_div) {
|
||||
case 2:
|
||||
div_num = 1;
|
||||
break;
|
||||
case 4:
|
||||
div_num = 0;
|
||||
break;
|
||||
case 8:
|
||||
div_num = 2;
|
||||
break;
|
||||
case 16:
|
||||
div_num = 3;
|
||||
break;
|
||||
default:
|
||||
div_num = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
regs[0x04] &= 0xfe;
|
||||
regs[0x04] |= (div_num & 0x01);
|
||||
|
||||
ret = rt710_write_regs(t, 0x04, ®s[0x04], 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
b = freq * div;
|
||||
c = (b / 2) / 24000;
|
||||
d = (c & 0xff);
|
||||
e = (d * 17536) + (b & 0xffff);
|
||||
if (t->priv.chip == RT710_CHIP_TYPE_RT720) {
|
||||
regs[0x08] &= 0xef;
|
||||
regs[0x08] |= ((div_num << 3) & 0x10);
|
||||
|
||||
if (e < 375) {
|
||||
e = 0;
|
||||
} else if (e > 47625) {
|
||||
e = 0;
|
||||
d++;
|
||||
} else if (e > 23812 && e < 24000) {
|
||||
e = 23812;
|
||||
} else if (e > 24000 && e < 24187) {
|
||||
e = 24187;
|
||||
ret = rt710_write_regs(t, 0x08, ®s[0x08], 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
regs[0x04] &= 0x3f;
|
||||
|
||||
if (div_num <= 1) {
|
||||
regs[0x04] |= 0x40;
|
||||
regs[0x0c] |= 0x10;
|
||||
} else {
|
||||
regs[0x04] |= 0x80;
|
||||
regs[0x0c] &= 0xef;
|
||||
}
|
||||
|
||||
ret = rt710_write_regs(t, 0x04, ®s[0x04], 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = rt710_write_regs(t, 0x0c, ®s[0x0c], 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
f = (d - 13) / 4;
|
||||
regs[0x05] = f + ((d - (f * 4) - 13) << 6);
|
||||
nint = (vco_freq / 2) / xtal;
|
||||
vco_fra = vco_freq - (xtal * 2 * nint);
|
||||
|
||||
if (vco_fra < (xtal / 64)) {
|
||||
vco_fra = 0;
|
||||
} else if (vco_fra > (xtal * 127 / 64)) {
|
||||
vco_fra = 0;
|
||||
nint++;
|
||||
} else if ((vco_fra > (xtal * 127 / 128)) && (vco_fra < xtal)) {
|
||||
vco_fra = xtal * 127 / 128;
|
||||
} else if ((vco_fra > xtal) && vco_fra < (xtal * 129 / 128)) {
|
||||
vco_fra = xtal * 129 / 128;
|
||||
}
|
||||
|
||||
ni = (nint - 13) / 4;
|
||||
si = nint - (ni * 4) - 13;
|
||||
|
||||
regs[0x05] = (ni & 0x3f) | ((si << 6) & 0xc0);
|
||||
|
||||
ret = rt710_write_regs(t, 0x05, ®s[0x05], 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!e)
|
||||
if (!vco_fra)
|
||||
regs[0x04] |= 0x02;
|
||||
|
||||
ret = rt710_write_regs(t, 0x04, ®s[0x04], 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
while (e > 1) {
|
||||
u32 s;
|
||||
s = (24000 * 2) / g;
|
||||
if (e > s) {
|
||||
h += (32768 / (g / 2));
|
||||
e -= s;
|
||||
if (g >= 32768) {
|
||||
while (vco_fra > 1) {
|
||||
u32 t;
|
||||
|
||||
t = (xtal * 2) / nsdm;
|
||||
if (vco_fra > t) {
|
||||
sdm += (0x8000 / (nsdm / 2));
|
||||
vco_fra -= t;
|
||||
|
||||
if (nsdm >= 0x8000)
|
||||
break;
|
||||
}
|
||||
}
|
||||
g *= 2;
|
||||
|
||||
nsdm *= 2;
|
||||
}
|
||||
|
||||
regs[0x07] = ((h >> 8) & 0xff);
|
||||
regs[0x06] = (h & 0xff);
|
||||
regs[0x07] = ((sdm >> 8) & 0xff);
|
||||
regs[0x06] = (sdm & 0xff);
|
||||
|
||||
ret = rt710_write_regs(t, 0x07, ®s[0x07], 1);
|
||||
if (ret)
|
||||
@@ -216,127 +292,310 @@ static int rt710_set_pll_regs(struct rt710_tuner *t, u8 *regs, u32 freq)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
t->priv.freq = freq;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rt710_set_params(struct rt710_tuner *t, u32 freq, u32 symbol_rate, u32 rolloff)
|
||||
int rt710_init(struct rt710_tuner *t)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 tmp;
|
||||
|
||||
mutex_init(&t->priv.lock);
|
||||
|
||||
t->priv.init = false;
|
||||
t->priv.freq = 0;
|
||||
|
||||
ret = rt710_read_regs(t, 0x03, &tmp, 1);
|
||||
if (ret) {
|
||||
dev_err(t->dev,
|
||||
"rt710_init: rt710_read_regs() failed. (ret: %d)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
t->priv.chip = ((tmp & 0xf0) == 0x70) ? RT710_CHIP_TYPE_RT710
|
||||
: RT710_CHIP_TYPE_RT720;
|
||||
|
||||
t->priv.init = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rt710_term(struct rt710_tuner *t)
|
||||
{
|
||||
if (!t->priv.init)
|
||||
return 0;
|
||||
|
||||
mutex_destroy(&t->priv.lock);
|
||||
|
||||
t->priv.init = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rt710_sleep(struct rt710_tuner *t)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 regs[NUM_REGS];
|
||||
u32 a;
|
||||
u8 b = 0, f = 0;
|
||||
struct {
|
||||
u32 a;
|
||||
u8 b;
|
||||
u8 f;
|
||||
} c[] = {
|
||||
{ 50000, 0, 0 },
|
||||
{ 73000, 0, 1 },
|
||||
{ 96000, 1, 0 },
|
||||
{ 104000, 1, 1 },
|
||||
{ 116000, 2, 0 },
|
||||
{ 126000, 2, 1 },
|
||||
{ 134000, 3, 0 },
|
||||
{ 146000, 3, 1 },
|
||||
{ 158000, 4, 0 },
|
||||
{ 170000, 4, 1 },
|
||||
{ 178000, 5, 0 },
|
||||
{ 190000, 5, 1 },
|
||||
{ 202000, 6, 0 },
|
||||
{ 212000, 6, 1 },
|
||||
{ 218000, 7, 0 },
|
||||
{ 234000, 7, 1 },
|
||||
{ 244000, 9, 1 },
|
||||
{ 246000, 10, 0 },
|
||||
{ 262000, 10, 1 },
|
||||
{ 266000, 11, 0 },
|
||||
{ 282000, 11, 1 },
|
||||
{ 298000, 12, 1 },
|
||||
{ 318000, 13, 1 },
|
||||
{ 340000, 14, 1 },
|
||||
{ 358000, 15, 1 },
|
||||
{ 379999, 16, 1 }
|
||||
};
|
||||
|
||||
if (!t->priv.init)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(regs, sleep_regs, sizeof(regs));
|
||||
|
||||
mutex_lock(&t->priv.lock);
|
||||
|
||||
if (t->priv.chip == RT710_CHIP_TYPE_RT720) {
|
||||
regs[0x01] = 0x5e;
|
||||
regs[0x03] |= 0x20;
|
||||
} else if (t->config.clock_out) {
|
||||
regs[0x03] = 0x20;
|
||||
}
|
||||
|
||||
ret = rt710_write_regs(t, 0x00, regs, NUM_REGS);
|
||||
|
||||
mutex_unlock(&t->priv.lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rt710_set_params(struct rt710_tuner *t,
|
||||
u32 freq,
|
||||
u32 symbol_rate, u32 rolloff)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 regs[NUM_REGS];
|
||||
u32 bandwidth;
|
||||
struct rt710_bandwidth_param bw_param = { 0 };
|
||||
|
||||
if (!t->priv.init)
|
||||
return -EINVAL;
|
||||
|
||||
if (rolloff > 5)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(regs, init_regs, sizeof(regs));
|
||||
memcpy(regs,
|
||||
(t->priv.chip == RT710_CHIP_TYPE_RT710) ? rt710_init_regs
|
||||
: rt720_init_regs,
|
||||
sizeof(regs));
|
||||
|
||||
if (t->config.loop_through)
|
||||
regs[0x01] &= 0xfb;
|
||||
else
|
||||
regs[0x01] |= 0x04;
|
||||
|
||||
if (t->config.clock_out)
|
||||
regs[0x03] &= 0xef;
|
||||
else
|
||||
regs[0x03] |= 0x10;
|
||||
|
||||
switch (t->config.signal_output_mode) {
|
||||
case RT710_SIGNAL_OUTPUT_DIFFERENTIAL:
|
||||
regs[0x0b] &= 0xef;
|
||||
break;
|
||||
|
||||
case RT710_SIGNAL_OUTPUT_SINGLE:
|
||||
default:
|
||||
regs[0x0b] |= 0x10;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (t->config.agc_mode) {
|
||||
case RT710_AGC_POSITIVE:
|
||||
regs[0x0d] |= 0x10;
|
||||
break;
|
||||
|
||||
case RT710_AGC_NEGATIVE:
|
||||
default:
|
||||
regs[0x0d] &= 0xef;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (t->config.vga_atten_mode) {
|
||||
case RT710_VGA_ATTEN_ON:
|
||||
regs[0x0b] |= 0x08;
|
||||
break;
|
||||
|
||||
case RT710_VGA_ATTEN_OFF:
|
||||
default:
|
||||
regs[0x0b] &= 0xf7;
|
||||
break;
|
||||
}
|
||||
|
||||
if (t->priv.chip == RT710_CHIP_TYPE_RT710) {
|
||||
if (t->config.fine_gain >= RT710_FINE_GAIN_3DB &&
|
||||
t->config.fine_gain <= RT710_FINE_GAIN_0DB) {
|
||||
regs[0x0e] &= 0xfc;
|
||||
regs[0x0e] |= (t->config.fine_gain & 0x03);
|
||||
}
|
||||
} else {
|
||||
if (t->config.fine_gain == RT710_FINE_GAIN_3DB ||
|
||||
t->config.fine_gain == RT710_FINE_GAIN_2DB)
|
||||
regs[0x0e] &= 0xfe;
|
||||
else
|
||||
regs[0x0e] |= 0x01;
|
||||
|
||||
regs[0x03] &= 0xf0;
|
||||
}
|
||||
|
||||
mutex_lock(&t->priv.lock);
|
||||
|
||||
ret = rt710_write_regs(t, 0x00, regs, NUM_REGS);
|
||||
if (ret) {
|
||||
dev_err(t->dev, "rt710_set_params: rt710_write_regs(0x00, NUM_REGS) failed. (ret: %d)", ret);
|
||||
return ret;
|
||||
dev_err(t->dev,
|
||||
"rt710_set_params: rt710_write_regs(0x00, NUM_REGS) failed. (ret: %d)",
|
||||
ret);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = rt710_set_pll_regs(t, regs, freq);
|
||||
ret = rt710_set_pll(t, regs, freq);
|
||||
if (ret) {
|
||||
dev_err(t->dev, "rt710_set_params: rt710_set_pll_regs() failed. (ret: %d)\n", ret);
|
||||
return ret;
|
||||
dev_err(t->dev,
|
||||
"rt710_set_params: rt710_set_pll() failed. (ret: %d)\n",
|
||||
ret);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
msleep(10);
|
||||
|
||||
if ((freq - 1600000) >= 350000) {
|
||||
regs[0x02] &= 0xbf;
|
||||
regs[0x08] &= 0x7f;
|
||||
if (freq >= 1950000)
|
||||
regs[0x0a] = 0x38;
|
||||
if (t->priv.chip == RT710_CHIP_TYPE_RT710) {
|
||||
if ((freq - 1600000) >= 350000) {
|
||||
regs[0x02] &= 0xbf;
|
||||
regs[0x08] &= 0x7f;
|
||||
if (freq >= 1950000)
|
||||
regs[0x0a] = 0x38;
|
||||
} else {
|
||||
regs[0x02] |= 0x40;
|
||||
regs[0x08] |= 0x80;
|
||||
}
|
||||
|
||||
ret = rt710_write_regs(t, 0x0a, ®s[0x0a], 1);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
ret = rt710_write_regs(t, 0x02, ®s[0x02], 1);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
ret = rt710_write_regs(t, 0x08, ®s[0x08], 1);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
regs[0x0e] &= 0xf3;
|
||||
|
||||
if (freq >= 2000000)
|
||||
regs[0x0e] |= 0x08;
|
||||
|
||||
ret = rt710_write_regs(t, 0x0e, ®s[0x0e], 1);
|
||||
if (ret)
|
||||
goto fail;
|
||||
} else {
|
||||
regs[0x02] |= 0x40;
|
||||
regs[0x08] |= 0x80;
|
||||
switch (t->config.scan_mode) {
|
||||
case RT710_SCAN_AUTO:
|
||||
regs[0x0b] |= 0x02;
|
||||
|
||||
symbol_rate += 10000;
|
||||
|
||||
break;
|
||||
|
||||
case RT710_SCAN_MANUAL:
|
||||
default:
|
||||
regs[0x0b] &= 0xfc;
|
||||
|
||||
if (symbol_rate >= 15000)
|
||||
symbol_rate += 6000;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
ret = rt710_write_regs(t, 0x0b, ®s[0x0b], 1);
|
||||
if (ret)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = rt710_write_regs(t, 0x0a, ®s[0x0a], 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
bandwidth = (symbol_rate * (115 + (rolloff * 5))) / 10;
|
||||
|
||||
ret = rt710_write_regs(t, 0x02, ®s[0x02], 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!bandwidth) {
|
||||
ret = -ECANCELED;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = rt710_write_regs(t, 0x08, ®s[0x08], 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (t->priv.chip == RT710_CHIP_TYPE_RT710) {
|
||||
if (bandwidth >= 380000) {
|
||||
bandwidth -= 380000;
|
||||
if (bandwidth % 17400)
|
||||
bw_param.coarse++;
|
||||
bw_param.coarse += ((bandwidth / 17400) & 0xff) + 0x10;
|
||||
bw_param.fine = 1;
|
||||
} else {
|
||||
int i;
|
||||
|
||||
regs[0x0e] &= 0xf3;
|
||||
|
||||
if (freq >= 2000000)
|
||||
regs[0x0e] |= 0x08;
|
||||
|
||||
ret = rt710_write_regs(t, 0x0e, ®s[0x0e], 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
a = (symbol_rate * (0x73 + (rolloff * 5))) / 10;
|
||||
|
||||
if (!a)
|
||||
return -ECANCELED;
|
||||
|
||||
if (a >= 380000) {
|
||||
a -= 380000;
|
||||
if (a % 17400)
|
||||
b++;
|
||||
a /= 17400;
|
||||
b += (a & 0xff) + 0x10;
|
||||
f = 1;
|
||||
} else {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < (sizeof(c) / sizeof(c[0])); i++) {
|
||||
if (a <= c[i].a) {
|
||||
b = c[i].b;
|
||||
f = c[i].f;
|
||||
break;
|
||||
for (i = 0; i < ARRAY_SIZE(bandwidth_params); i++) {
|
||||
if (bandwidth <= bandwidth_params[i].bandwidth) {
|
||||
bw_param = bandwidth_params[i].param;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
u32 range, s;
|
||||
|
||||
bw_param.fine = (rolloff > 1) ? 1 : 0;
|
||||
range = bw_param.fine * 20000;
|
||||
s = symbol_rate * 12;
|
||||
|
||||
if (symbol_rate <= 15000)
|
||||
symbol_rate += 3000;
|
||||
else if (symbol_rate <= 20000)
|
||||
symbol_rate += 2000;
|
||||
else if (symbol_rate <= 30000)
|
||||
symbol_rate += 1000;
|
||||
|
||||
if (s <= (88000 + range)) {
|
||||
bw_param.coarse = 0;
|
||||
} else if (s <= (368000 + range)) {
|
||||
bw_param.coarse = (s - 88000 - range) / 20000;
|
||||
|
||||
if ((s - 88000 - range) % 20000)
|
||||
bw_param.coarse++;
|
||||
|
||||
if (bw_param.coarse > 6)
|
||||
bw_param.coarse++;
|
||||
} else if (s <= (764000 + range)) {
|
||||
bw_param.coarse = ((s - 368000 - range) / 20000) + 15;
|
||||
|
||||
if ((s + 25216 - range) % 20000)
|
||||
bw_param.coarse++;
|
||||
|
||||
if (bw_param.coarse >= 33)
|
||||
bw_param.coarse += 3;
|
||||
else if (bw_param.coarse >= 29)
|
||||
bw_param.coarse += 2;
|
||||
else if (bw_param.coarse >= 27)
|
||||
bw_param.coarse += 3;
|
||||
else if (bw_param.coarse >= 24)
|
||||
bw_param.coarse += 2;
|
||||
else if (bw_param.coarse >= 19)
|
||||
bw_param.coarse++;
|
||||
} else {
|
||||
bw_param.coarse = 42;
|
||||
}
|
||||
}
|
||||
|
||||
regs[0x0f] = (b << 2) | f;
|
||||
regs[0x0f] = ((bw_param.coarse << 2) & 0xfc) | (bw_param.fine & 0x03);
|
||||
|
||||
ret = rt710_write_regs(t, 0x0f, ®s[0x0f], 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto fail;
|
||||
|
||||
mutex_unlock(&t->priv.lock);
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
mutex_unlock(&t->priv.lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -346,13 +605,97 @@ int rt710_is_pll_locked(struct rt710_tuner *t, bool *locked)
|
||||
int ret = 0;
|
||||
u8 tmp;
|
||||
|
||||
if (!t->priv.init)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&t->priv.lock);
|
||||
|
||||
ret = rt710_read_regs(t, 0x02, &tmp, 1);
|
||||
|
||||
mutex_unlock(&t->priv.lock);
|
||||
|
||||
if (ret) {
|
||||
dev_err(t->dev, "rt710_is_pll_locked: rt710_read_regs() failed. (ret: %d)\n", ret);
|
||||
dev_err(t->dev,
|
||||
"rt710_is_pll_locked: rt710_read_regs() failed. (ret: %d)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*locked = (tmp & 0x80) ? true : false;
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rt710_get_rf_gain(struct rt710_tuner *t, u8 *gain)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 tmp, g;
|
||||
|
||||
if (!t->priv.init)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&t->priv.lock);
|
||||
|
||||
ret = rt710_read_regs(t, 0x01, &tmp, 1);
|
||||
|
||||
mutex_unlock(&t->priv.lock);
|
||||
|
||||
if (ret) {
|
||||
dev_err(t->dev,
|
||||
"rt710_get_rf_gain: rt710_read_regs() failed. (ret: %d)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
g = ((tmp & 0xf0) >> 4) | ((tmp & 0x01) << 4);
|
||||
|
||||
if (t->priv.chip == RT710_CHIP_TYPE_RT710) {
|
||||
if (g <= 2) {
|
||||
*gain = 0;
|
||||
} else if (g <= 9) {
|
||||
/* 1 - 7 */
|
||||
*gain = g - 2;
|
||||
} else if (g <= 12) {
|
||||
*gain = 7;
|
||||
} else if (g <= 22) {
|
||||
/* 8 - 17 */
|
||||
*gain = g - 5;
|
||||
} else {
|
||||
*gain = 18;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rt710_get_rf_signal_strength(struct rt710_tuner *t, s32 *ss)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 gain;
|
||||
s32 tmp;
|
||||
|
||||
ret = rt710_get_rf_gain(t, &gain);
|
||||
if (ret) {
|
||||
dev_err(t->dev,
|
||||
"rt710_get_rf_signal_strength: rt710_get_rf_gain() failed. (ret: %d)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (t->priv.chip == RT710_CHIP_TYPE_RT710) {
|
||||
if (t->priv.freq < 1200000) {
|
||||
tmp = 190;
|
||||
} else if (t->priv.freq < 1800000) {
|
||||
tmp = 170;
|
||||
} else {
|
||||
tmp = 140;
|
||||
}
|
||||
tmp += rt710_lna_acc_gain[gain];
|
||||
} else {
|
||||
tmp = 70 + rt720_lna_acc_gain[gain];
|
||||
}
|
||||
|
||||
*ss = tmp * -100;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1,24 +1,95 @@
|
||||
// rt710.h
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* RafaelMicro RT710 driver definitions (rt710.h)
|
||||
*
|
||||
* Copyright (c) 2018-2021 nns779
|
||||
*/
|
||||
|
||||
#ifndef __RT710_H__
|
||||
#define __RT710_H__
|
||||
|
||||
#ifdef __linux__
|
||||
#include <linux/types.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/device.h>
|
||||
#elif defined(_WIN32) || defined(_WIN64)
|
||||
#include "misc_win.h"
|
||||
#endif
|
||||
|
||||
#include "i2c_comm.h"
|
||||
|
||||
struct rt710_tuner {
|
||||
struct device *dev;
|
||||
struct i2c_comm_master *i2c;
|
||||
u8 i2c_addr;
|
||||
enum rt710_chip_type {
|
||||
RT710_CHIP_TYPE_UNKNOWN = 0,
|
||||
RT710_CHIP_TYPE_RT710,
|
||||
RT710_CHIP_TYPE_RT720,
|
||||
};
|
||||
|
||||
enum rt710_signal_output_mode {
|
||||
RT710_SIGNAL_OUTPUT_SINGLE = 0,
|
||||
RT710_SIGNAL_OUTPUT_DIFFERENTIAL,
|
||||
};
|
||||
|
||||
enum rt710_agc_mode {
|
||||
RT710_AGC_NEGATIVE = 0,
|
||||
RT710_AGC_POSITIVE,
|
||||
};
|
||||
|
||||
enum rt710_vga_attenuate_mode {
|
||||
RT710_VGA_ATTEN_OFF = 0,
|
||||
RT710_VGA_ATTEN_ON,
|
||||
};
|
||||
|
||||
enum rt710_fine_gain {
|
||||
RT710_FINE_GAIN_3DB = 0,
|
||||
RT710_FINE_GAIN_2DB,
|
||||
RT710_FINE_GAIN_1DB,
|
||||
RT710_FINE_GAIN_0DB,
|
||||
};
|
||||
|
||||
enum rt710_scan_mode {
|
||||
RT710_SCAN_MANUAL = 0,
|
||||
RT710_SCAN_AUTO,
|
||||
};
|
||||
|
||||
struct rt710_config {
|
||||
u32 xtal;
|
||||
bool loop_through;
|
||||
bool clock_out;
|
||||
enum rt710_signal_output_mode signal_output_mode;
|
||||
enum rt710_agc_mode agc_mode;
|
||||
enum rt710_vga_attenuate_mode vga_atten_mode;
|
||||
enum rt710_fine_gain fine_gain;
|
||||
enum rt710_scan_mode scan_mode; // only for RT720
|
||||
};
|
||||
|
||||
struct rt710_priv {
|
||||
struct mutex lock;
|
||||
bool init;
|
||||
enum rt710_chip_type chip;
|
||||
u32 freq;
|
||||
};
|
||||
|
||||
struct rt710_tuner {
|
||||
const struct device *dev;
|
||||
const struct i2c_comm_master *i2c;
|
||||
u8 i2c_addr;
|
||||
struct rt710_config config;
|
||||
struct rt710_priv priv;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
int rt710_init(struct rt710_tuner *t);
|
||||
int rt710_term(struct rt710_tuner *t);
|
||||
|
||||
int rt710_sleep(struct rt710_tuner *t, bool sleep);
|
||||
int rt710_sleep(struct rt710_tuner *t);
|
||||
int rt710_set_params(struct rt710_tuner *t, u32 freq, u32 symbol_rate, u32 rolloff);
|
||||
int rt710_is_pll_locked(struct rt710_tuner *t, bool *locked);
|
||||
int rt710_get_rf_gain(struct rt710_tuner *t, u8 *gain);
|
||||
int rt710_get_rf_signal_strength(struct rt710_tuner *t, s32 *ss);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
938
driver/s1ur_device.c
Normal file
938
driver/s1ur_device.c
Normal file
@@ -0,0 +1,938 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* PTX driver for Digibest PLEX PX-S1UR device (s1ur_device.c)
|
||||
* and Digibest ISDBT2071 (DTV03A-1TU) device
|
||||
*
|
||||
* Copyright (c) 2023 techma.
|
||||
* 2025 hendecarows
|
||||
*/
|
||||
|
||||
#include "print_format.h"
|
||||
#include "s1ur_device.h"
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "px4_device_params.h"
|
||||
#include "firmware.h"
|
||||
|
||||
#define S1UR_DEVICE_TS_SYNC_COUNT 4
|
||||
#define S1UR_DEVICE_TS_SYNC_SIZE (188 * S1UR_DEVICE_TS_SYNC_COUNT)
|
||||
|
||||
struct s1ur_stream_context {
|
||||
struct ptx_chrdev *chrdev;
|
||||
u8 remain_buf[S1UR_DEVICE_TS_SYNC_SIZE];
|
||||
size_t remain_len;
|
||||
};
|
||||
|
||||
static void s1ur_device_release(struct kref *kref);
|
||||
|
||||
static int s1ur_backend_set_power(struct s1ur_device *s1ur,
|
||||
bool state)
|
||||
{
|
||||
int ret = 0;
|
||||
struct it930x_bridge *it930x = &s1ur->it930x;
|
||||
|
||||
dev_dbg(s1ur->dev,
|
||||
"s1ur_backend_set_power: %s\n", (state) ? "true" : "false");
|
||||
|
||||
if (!state && !atomic_read(&s1ur->available))
|
||||
return 0;
|
||||
|
||||
if (state) {
|
||||
ret = it930x_write_gpio(it930x, 3, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
msleep(100);
|
||||
|
||||
ret = it930x_write_gpio(it930x, 2, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
msleep(20);
|
||||
} else {
|
||||
it930x_write_gpio(it930x, 2, false);
|
||||
it930x_write_gpio(it930x, 3, true);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s1ur_backend_init(struct s1ur_device *s1ur)
|
||||
{
|
||||
int ret = 0;
|
||||
struct s1ur_chrdev *chrdevs1ur = &s1ur->chrdevs1ur;
|
||||
|
||||
ret = tc90522_init(&chrdevs1ur->tc90522_t);
|
||||
if (ret) {
|
||||
dev_err(s1ur->dev,
|
||||
"s1ur_backend_init: tc90522_init() (t) failed. (ret: %d)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (s1ur->s1ur_model) {
|
||||
case PXS1UR_MODEL:
|
||||
default:
|
||||
ret = tc90522_init(&chrdevs1ur->tc90522_s);
|
||||
if (ret) {
|
||||
dev_err(s1ur->dev,
|
||||
"s1ur_backend_init: tc90522_init() (s) failed. (ret: %d)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
|
||||
case ISDBT2071_MODEL:
|
||||
tc90522_term(&chrdevs1ur->tc90522_s);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = r850_init(&chrdevs1ur->r850);
|
||||
if (ret) {
|
||||
dev_err(s1ur->dev,
|
||||
"s1ur_backend_init: r850_init() failed. (ret: %d)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s1ur_backend_term(struct s1ur_device *s1ur)
|
||||
{
|
||||
struct s1ur_chrdev *chrdevs1ur = &s1ur->chrdevs1ur;
|
||||
|
||||
r850_term(&chrdevs1ur->r850);
|
||||
tc90522_term(&chrdevs1ur->tc90522_t);
|
||||
tc90522_term(&chrdevs1ur->tc90522_s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void s1ur_device_stream_process(struct ptx_chrdev *chrdev,
|
||||
u8 **buf, u32 *len)
|
||||
{
|
||||
u8 *p = *buf;
|
||||
u32 remain = *len;
|
||||
|
||||
while (likely(remain)) {
|
||||
u32 i = 0;
|
||||
bool sync_remain = false;
|
||||
|
||||
while (true) {
|
||||
if (likely(((i + 1) * 188) <= remain)) {
|
||||
if (unlikely(p[i * 188] != 0x47))
|
||||
break;
|
||||
} else {
|
||||
sync_remain = true;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (unlikely(i < S1UR_DEVICE_TS_SYNC_COUNT)) {
|
||||
p++;
|
||||
remain--;
|
||||
continue;
|
||||
}
|
||||
|
||||
ptx_chrdev_put_stream(chrdev, p, 188 * i);
|
||||
|
||||
p += 188 * i;
|
||||
remain -= 188 * i;
|
||||
|
||||
if (unlikely(sync_remain))
|
||||
break;
|
||||
}
|
||||
|
||||
*buf = p;
|
||||
*len = remain;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int s1ur_device_stream_handler(void *context, void *buf, u32 len)
|
||||
{
|
||||
struct s1ur_stream_context *stream_ctx = context;
|
||||
u8 *ctx_remain_buf = stream_ctx->remain_buf;
|
||||
u32 ctx_remain_len = stream_ctx->remain_len;
|
||||
u8 *p = buf;
|
||||
u32 remain = len;
|
||||
|
||||
if (unlikely(ctx_remain_len)) {
|
||||
if (likely((ctx_remain_len + len) >= S1UR_DEVICE_TS_SYNC_SIZE)) {
|
||||
u32 t = S1UR_DEVICE_TS_SYNC_SIZE - ctx_remain_len;
|
||||
|
||||
memcpy(ctx_remain_buf + ctx_remain_len, p, t);
|
||||
ctx_remain_len = S1UR_DEVICE_TS_SYNC_SIZE;
|
||||
|
||||
s1ur_device_stream_process(stream_ctx->chrdev,
|
||||
&ctx_remain_buf,
|
||||
&ctx_remain_len);
|
||||
if (likely(!ctx_remain_len)) {
|
||||
p += t;
|
||||
remain -= t;
|
||||
}
|
||||
|
||||
stream_ctx->remain_len = 0;
|
||||
} else {
|
||||
memcpy(ctx_remain_buf + ctx_remain_len, p, len);
|
||||
stream_ctx->remain_len += len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
s1ur_device_stream_process(stream_ctx->chrdev, &p, &remain);
|
||||
|
||||
if (unlikely(remain)) {
|
||||
memcpy(stream_ctx->remain_buf, p, remain);
|
||||
stream_ctx->remain_len = remain;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s1ur_chrdev_init(struct ptx_chrdev *chrdev)
|
||||
{
|
||||
dev_dbg(chrdev->parent->dev, "s1ur_chrdev_init\n");
|
||||
|
||||
chrdev->params.system = PTX_ISDB_T_SYSTEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s1ur_chrdev_term(struct ptx_chrdev *chrdev)
|
||||
{
|
||||
dev_dbg(chrdev->parent->dev, "s1ur_chrdev_term\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct tc90522_regbuf tc_init_s1ur[] = {
|
||||
{ 0xb0, NULL, { 0xa0 } },
|
||||
{ 0xb2, NULL, { 0x3d } },
|
||||
{ 0xb3, NULL, { 0x25 } },
|
||||
{ 0xb4, NULL, { 0x8b } },
|
||||
{ 0xb5, NULL, { 0x4b } },
|
||||
{ 0xb6, NULL, { 0x3f } },
|
||||
{ 0xb7, NULL, { 0xff } },
|
||||
{ 0xb8, NULL, { 0xc0 } },
|
||||
};
|
||||
|
||||
static struct tc90522_regbuf tc_init_isdbt2071t[] = {
|
||||
{ 0x04, NULL, { 0x00 } },
|
||||
{ 0x10, NULL, { 0x00 } },
|
||||
{ 0x11, NULL, { 0x2d } },
|
||||
{ 0x12, NULL, { 0x02 } },
|
||||
{ 0x13, NULL, { 0x62 } },
|
||||
{ 0x14, NULL, { 0x60 } },
|
||||
{ 0x15, NULL, { 0x00 } },
|
||||
{ 0x16, NULL, { 0x00 } },
|
||||
{ 0x1d, NULL, { 0x05 } },
|
||||
{ 0x1e, NULL, { 0x15 } },
|
||||
{ 0x1f, NULL, { 0x40 } },
|
||||
{ 0x30, NULL, { 0x20 } },
|
||||
{ 0x31, NULL, { 0x0b } },
|
||||
{ 0x32, NULL, { 0x8f } },
|
||||
{ 0x34, NULL, { 0x0f } },
|
||||
{ 0x38, NULL, { 0x01 } },
|
||||
{ 0x39, NULL, { 0x1c } },
|
||||
};
|
||||
|
||||
static int s1ur_chrdev_open(struct ptx_chrdev *chrdev)
|
||||
{
|
||||
int ret = 0;
|
||||
struct ptx_chrdev_group *chrdev_group = chrdev->parent;
|
||||
struct s1ur_chrdev *chrdevs1ur = chrdev->priv;
|
||||
struct s1ur_device *s1ur = container_of(chrdevs1ur,
|
||||
struct s1ur_device,
|
||||
chrdevs1ur);
|
||||
struct r850_system_config sys;
|
||||
|
||||
dev_dbg(s1ur->dev,
|
||||
"s1ur_chrdev_open %u\n", chrdev_group->id);
|
||||
|
||||
ret = s1ur_backend_set_power(s1ur, true);
|
||||
if (ret) {
|
||||
dev_err(s1ur->dev,
|
||||
"s1ur_chrdev_open %u: s1ur_backend_set_power(true) failed. (ret: %d)\n",
|
||||
chrdev_group->id, ret);
|
||||
goto fail_backend_power;
|
||||
}
|
||||
|
||||
ret = s1ur_backend_init(s1ur);
|
||||
if (ret) {
|
||||
dev_err(s1ur->dev,
|
||||
"s1ur_chrdev_open %u: s1ur_backend_init() failed. (ret: %d)\n",
|
||||
chrdev_group->id, ret);
|
||||
goto fail_backend_init;
|
||||
}
|
||||
|
||||
/* Initialization for ISDB-T */
|
||||
switch (s1ur->s1ur_model) {
|
||||
case PXS1UR_MODEL:
|
||||
default:
|
||||
ret = tc90522_write_multiple_regs(&chrdevs1ur->tc90522_t,
|
||||
tc_init_s1ur, ARRAY_SIZE(tc_init_s1ur));
|
||||
break;
|
||||
|
||||
case ISDBT2071_MODEL:
|
||||
ret = tc90522_write_multiple_regs(&chrdevs1ur->tc90522_t,
|
||||
tc_init_isdbt2071t, ARRAY_SIZE(tc_init_isdbt2071t));
|
||||
break;
|
||||
}
|
||||
if (ret) {
|
||||
dev_err(s1ur->dev,
|
||||
"s1ur_chrdev_open %u: tc90522_write_multiple_regs(tc_init_t) failed. (ret: %d)\n",
|
||||
chrdev_group->id, ret);
|
||||
goto fail_backend;
|
||||
}
|
||||
|
||||
/* disable ts pins */
|
||||
ret = tc90522_enable_ts_pins_t(&chrdevs1ur->tc90522_t, false);
|
||||
if (ret) {
|
||||
dev_err(s1ur->dev,
|
||||
"s1ur_chrdev_open %u: tc90522_enable_ts_pins_t(false) failed. (ret: %d)\n",
|
||||
chrdev_group->id, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* wake up */
|
||||
ret = tc90522_sleep_t(&chrdevs1ur->tc90522_t, false);
|
||||
if (ret) {
|
||||
dev_err(s1ur->dev,
|
||||
"s1ur_chrdev_open %u: tc90522_sleep_t(true) failed. (ret: %d)\n",
|
||||
chrdev_group->id, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = r850_wakeup(&chrdevs1ur->r850);
|
||||
if (ret) {
|
||||
dev_err(s1ur->dev,
|
||||
"s1ur_chrdev_tune %u: r850_wakeup() failed. (ret: %d)\n",
|
||||
chrdev_group->id, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
sys.system = R850_SYSTEM_ISDB_T;
|
||||
sys.bandwidth = R850_BANDWIDTH_6M;
|
||||
sys.if_freq = 4063;
|
||||
|
||||
ret = r850_set_system(&chrdevs1ur->r850, &sys);
|
||||
if (ret) {
|
||||
dev_err(s1ur->dev,
|
||||
"s1ur_chrdev_open %u: r850_set_system() failed. (ret: %d)\n",
|
||||
chrdev_group->id, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (s1ur->s1ur_model) {
|
||||
case PXS1UR_MODEL:
|
||||
default:
|
||||
/* disable ts pins */
|
||||
ret = tc90522_enable_ts_pins_s(&chrdevs1ur->tc90522_s, false);
|
||||
if (ret) {
|
||||
dev_err(s1ur->dev,
|
||||
"s1ur_chrdev_open %u: tc90522_enable_ts_pins_s(false) failed. (ret: %d)\n",
|
||||
chrdev_group->id, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* sleep */
|
||||
ret = tc90522_sleep_s(&chrdevs1ur->tc90522_s, true);
|
||||
if (ret) {
|
||||
dev_err(s1ur->dev,
|
||||
"s1ur_chrdev_open %u: tc90522_sleep_s(true) failed. (ret: %d)\n",
|
||||
chrdev_group->id, ret);
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
|
||||
case ISDBT2071_MODEL:
|
||||
break;
|
||||
}
|
||||
|
||||
kref_get(&s1ur->kref);
|
||||
return 0;
|
||||
|
||||
fail_backend:
|
||||
s1ur_backend_term(s1ur);
|
||||
|
||||
fail_backend_init:
|
||||
s1ur_backend_set_power(s1ur, false);
|
||||
|
||||
fail_backend_power:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int s1ur_chrdev_release(struct ptx_chrdev *chrdev)
|
||||
{
|
||||
struct ptx_chrdev_group *chrdev_group = chrdev->parent;
|
||||
struct s1ur_chrdev *chrdevs1ur = chrdev->priv;
|
||||
struct s1ur_device *s1ur = container_of(chrdevs1ur,
|
||||
struct s1ur_device,
|
||||
chrdevs1ur);
|
||||
|
||||
dev_dbg(s1ur->dev,
|
||||
"s1ur_chrdev_release %u: kref count: %u\n",
|
||||
chrdev_group->id, kref_read(&s1ur->kref));
|
||||
|
||||
s1ur_backend_term(s1ur);
|
||||
s1ur_backend_set_power(s1ur, false);
|
||||
|
||||
kref_put(&s1ur->kref, s1ur_device_release);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s1ur_chrdev_tune(struct ptx_chrdev *chrdev,
|
||||
struct ptx_tune_params *params)
|
||||
{
|
||||
int ret = 0, i;
|
||||
struct ptx_chrdev_group *chrdev_group = chrdev->parent;
|
||||
struct s1ur_chrdev *chrdevs1ur = chrdev->priv;
|
||||
struct s1ur_device *s1ur = container_of(chrdevs1ur,
|
||||
struct s1ur_device,
|
||||
chrdevs1ur);
|
||||
bool tuner_locked;
|
||||
|
||||
dev_dbg(s1ur->dev,
|
||||
"s1ur_chrdev_tune %u\n", chrdev_group->id);
|
||||
|
||||
switch (params->system) {
|
||||
case PTX_ISDB_T_SYSTEM:
|
||||
ret = tc90522_write_reg(&chrdevs1ur->tc90522_t, 0x47, 0x30);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
ret = tc90522_set_agc_t(&chrdevs1ur->tc90522_t, false);
|
||||
if (ret) {
|
||||
dev_err(s1ur->dev,
|
||||
"s1ur_chrdev_tune %u: tc90522_set_agc_t(false) failed. (ret: %d)\n",
|
||||
chrdev_group->id, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (s1ur->s1ur_model) {
|
||||
case PXS1UR_MODEL:
|
||||
default:
|
||||
ret = tc90522_write_reg(&chrdevs1ur->tc90522_t, 0x0e, 0x77);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
ret = tc90522_write_reg(&chrdevs1ur->tc90522_t, 0x0f, 0x10);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
ret = tc90522_write_reg(&chrdevs1ur->tc90522_t, 0x71, 0x20);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
ret = tc90522_write_reg(&chrdevs1ur->tc90522_t, 0x76, 0x0c);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
ret = tc90522_write_reg(&chrdevs1ur->tc90522_t, 0x1f, 0x30);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
break;
|
||||
|
||||
case ISDBT2071_MODEL:
|
||||
ret = tc90522_write_reg(&chrdevs1ur->tc90522_t, 0x76, 0x03);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
ret = tc90522_write_reg(&chrdevs1ur->tc90522_t, 0x77, 0x01);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
ret = tc90522_write_reg(&chrdevs1ur->tc90522_t, 0x3b, 0x10);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
ret = tc90522_write_reg(&chrdevs1ur->tc90522_t, 0x3c, 0x10);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
ret = tc90522_write_reg(&chrdevs1ur->tc90522_t, 0x3d, 0x24);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
ret = r850_set_frequency(&chrdevs1ur->r850, params->freq);
|
||||
if (ret) {
|
||||
dev_err(s1ur->dev,
|
||||
"s1ur_chrdev_tune %u: r850_set_frequency(%u) failed. (ret: %d)\n",
|
||||
chrdev_group->id, params->freq, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
i = 50;
|
||||
while (i--) {
|
||||
ret = r850_is_pll_locked(&chrdevs1ur->r850,
|
||||
&tuner_locked);
|
||||
if (!ret && tuner_locked)
|
||||
break;
|
||||
|
||||
msleep(10);
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
dev_err(s1ur->dev,
|
||||
"s1ur_chrdev_tune %u: r850_is_pll_locked() failed. (ret: %d)\n",
|
||||
chrdev_group->id, ret);
|
||||
break;
|
||||
} else if (!tuner_locked) {
|
||||
/* PLL error */
|
||||
dev_dbg(s1ur->dev,
|
||||
"s1ur_chrdev_tune %u: PLL is NOT locked.\n",
|
||||
chrdev_group->id);
|
||||
ret = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
|
||||
dev_dbg(s1ur->dev,
|
||||
"s1ur_chrdev_tune %u: PLL is locked. count: %d\n",
|
||||
chrdev_group->id, i);
|
||||
|
||||
ret = tc90522_set_agc_t(&chrdevs1ur->tc90522_t, true);
|
||||
if (ret) {
|
||||
dev_err(s1ur->dev,
|
||||
"s1ur_chrdev_tune %u: tc90522_set_agc_t(true) failed. (ret: %d)\n",
|
||||
chrdev_group->id, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (s1ur->s1ur_model) {
|
||||
case PXS1UR_MODEL:
|
||||
default:
|
||||
ret = tc90522_write_reg(&chrdevs1ur->tc90522_t, 0x71, 0x01);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
ret = tc90522_write_reg(&chrdevs1ur->tc90522_t, 0x72, 0x25);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
ret = tc90522_write_reg(&chrdevs1ur->tc90522_t, 0x75, 0x00);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
break;
|
||||
|
||||
case ISDBT2071_MODEL:
|
||||
break;
|
||||
}
|
||||
|
||||
msleep(100);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int s1ur_chrdev_check_lock(struct ptx_chrdev *chrdev, bool *locked)
|
||||
{
|
||||
int ret = 0;
|
||||
struct s1ur_chrdev *chrdevs1ur = chrdev->priv;
|
||||
|
||||
switch (chrdev->current_system) {
|
||||
case PTX_ISDB_T_SYSTEM:
|
||||
ret = tc90522_is_signal_locked_t(&chrdevs1ur->tc90522_t,
|
||||
locked);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int s1ur_chrdev_start_capture(struct ptx_chrdev *chrdev)
|
||||
{
|
||||
int ret = 0;
|
||||
struct ptx_chrdev_group *chrdev_group = chrdev->parent;
|
||||
struct s1ur_chrdev *chrdevs1ur = chrdev->priv;
|
||||
struct s1ur_device *s1ur = container_of(chrdevs1ur,
|
||||
struct s1ur_device,
|
||||
chrdevs1ur);
|
||||
struct s1ur_stream_context *stream_ctx = s1ur->stream_ctx;
|
||||
|
||||
|
||||
dev_dbg(s1ur->dev,
|
||||
"s1ur_chrdev_start_capture %u\n", chrdev_group->id);
|
||||
|
||||
ret = it930x_purge_psb(&s1ur->it930x,
|
||||
px4_device_params.psb_purge_timeout);
|
||||
if (ret) {
|
||||
dev_err(s1ur->dev,
|
||||
"s1ur_chrdev_start_capture %u: it930x_purge_psb() failed. (ret: %d)\n",
|
||||
chrdev_group->id, ret);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
switch (chrdev->current_system) {
|
||||
case PTX_ISDB_T_SYSTEM:
|
||||
ret = tc90522_enable_ts_pins_t(&chrdevs1ur->tc90522_t, true);
|
||||
if (ret)
|
||||
dev_err(s1ur->dev,
|
||||
"s1ur_chrdev_start_capture %u: tc90522_enable_ts_pins_t(true) failed. (ret: %d)\n",
|
||||
chrdev_group->id, ret);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
goto fail_tc;
|
||||
|
||||
stream_ctx->remain_len = 0;
|
||||
|
||||
ret = itedtv_bus_start_streaming(&s1ur->it930x.bus,
|
||||
s1ur_device_stream_handler,
|
||||
stream_ctx);
|
||||
if (ret) {
|
||||
dev_err(s1ur->dev,
|
||||
"s1ur_chrdev_start_capture %u: itedtv_bus_start_streaming() failed. (ret: %d)\n",
|
||||
chrdev_group->id, ret);
|
||||
goto fail_bus;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail_bus:
|
||||
|
||||
fail_tc:
|
||||
switch (chrdev->current_system) {
|
||||
case PTX_ISDB_T_SYSTEM:
|
||||
tc90522_enable_ts_pins_t(&chrdevs1ur->tc90522_t, false);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int s1ur_chrdev_stop_capture(struct ptx_chrdev *chrdev)
|
||||
{
|
||||
struct ptx_chrdev_group *chrdev_group = chrdev->parent;
|
||||
struct s1ur_chrdev *chrdevs1ur = chrdev->priv;
|
||||
struct s1ur_device *s1ur = container_of(chrdevs1ur,
|
||||
struct s1ur_device,
|
||||
chrdevs1ur);
|
||||
|
||||
dev_dbg(s1ur->dev,
|
||||
"s1ur_chrdev_stop_capture %u\n", chrdev_group->id);
|
||||
|
||||
itedtv_bus_stop_streaming(&s1ur->it930x.bus);
|
||||
|
||||
if (!atomic_read(&s1ur->available))
|
||||
return 0;
|
||||
|
||||
switch (chrdev->current_system) {
|
||||
case PTX_ISDB_T_SYSTEM:
|
||||
tc90522_enable_ts_pins_t(&chrdevs1ur->tc90522_t, false);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s1ur_chrdev_set_capture(struct ptx_chrdev *chrdev, bool status)
|
||||
{
|
||||
return (status) ? s1ur_chrdev_start_capture(chrdev)
|
||||
: s1ur_chrdev_stop_capture(chrdev);
|
||||
}
|
||||
|
||||
static int s1ur_chrdev_read_cnr_raw(struct ptx_chrdev *chrdev, u32 *value)
|
||||
{
|
||||
int ret = 0;
|
||||
struct s1ur_chrdev *chrdevs1ur = chrdev->priv;
|
||||
|
||||
switch (chrdev->current_system) {
|
||||
case PTX_ISDB_T_SYSTEM:
|
||||
ret = tc90522_get_cndat_t(&chrdevs1ur->tc90522_t, value);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct ptx_chrdev_operations s1ur_chrdev_ops = {
|
||||
.init = s1ur_chrdev_init,
|
||||
.term = s1ur_chrdev_term,
|
||||
.open = s1ur_chrdev_open,
|
||||
.release = s1ur_chrdev_release,
|
||||
.tune = s1ur_chrdev_tune,
|
||||
.check_lock = s1ur_chrdev_check_lock,
|
||||
.set_stream_id = NULL,
|
||||
.set_lnb_voltage = NULL,
|
||||
.set_capture = s1ur_chrdev_set_capture,
|
||||
.read_signal_strength = NULL,
|
||||
.read_cnr = NULL,
|
||||
.read_cnr_raw = s1ur_chrdev_read_cnr_raw
|
||||
};
|
||||
|
||||
static int s1ur_device_load_config(struct s1ur_device *s1ur,
|
||||
struct ptx_chrdev_config *chrdev_config)
|
||||
{
|
||||
int ret = 0, i;
|
||||
struct device *dev = s1ur->dev;
|
||||
struct it930x_bridge *it930x = &s1ur->it930x;
|
||||
struct it930x_stream_input *input = &it930x->config.input[0];
|
||||
struct s1ur_chrdev *chrdevs1ur = &s1ur->chrdevs1ur;
|
||||
u8 tmp;
|
||||
|
||||
ret = it930x_read_reg(it930x, 0x4979, &tmp);
|
||||
if (ret) {
|
||||
dev_err(dev,
|
||||
"s1ur_load_config: it930x_read_reg(0x4979) failed.\n");
|
||||
return ret;
|
||||
} else if (!tmp) {
|
||||
dev_warn(dev, "EEPROM error.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
chrdev_config->system_cap = PTX_ISDB_T_SYSTEM;
|
||||
|
||||
input->enable = true;
|
||||
input->is_parallel = false;
|
||||
input->port_number = 0;
|
||||
input->slave_number = 0;
|
||||
input->i2c_bus = 3;
|
||||
input->i2c_addr = 0x10;
|
||||
input->packet_len = 188;
|
||||
input->sync_byte = 0x47;
|
||||
|
||||
chrdevs1ur->tc90522_t.dev = dev;
|
||||
chrdevs1ur->tc90522_t.i2c = &it930x->i2c_master[2];
|
||||
chrdevs1ur->tc90522_t.i2c_addr = 0x10;
|
||||
chrdevs1ur->tc90522_t.is_secondary = false;
|
||||
|
||||
chrdevs1ur->tc90522_s.dev = dev;
|
||||
chrdevs1ur->tc90522_s.i2c = &it930x->i2c_master[2];
|
||||
chrdevs1ur->tc90522_s.i2c_addr = 0x11;
|
||||
chrdevs1ur->tc90522_s.is_secondary = false;
|
||||
|
||||
chrdevs1ur->r850.dev = dev;
|
||||
chrdevs1ur->r850.i2c = &chrdevs1ur->tc90522_t.i2c_master;
|
||||
chrdevs1ur->r850.i2c_addr = 0x7c;
|
||||
chrdevs1ur->r850.config.xtal = 24000;
|
||||
chrdevs1ur->r850.config.loop_through = false;
|
||||
chrdevs1ur->r850.config.clock_out = false;
|
||||
chrdevs1ur->r850.config.no_imr_calibration = true;
|
||||
chrdevs1ur->r850.config.no_lpf_calibration = true;
|
||||
|
||||
switch(s1ur->s1ur_model) {
|
||||
case PXS1UR_MODEL:
|
||||
default:
|
||||
for (i = 1; i < 5; i++) {
|
||||
it930x->config.input[i].enable = false;
|
||||
it930x->config.input[i].port_number = i;
|
||||
}
|
||||
break;
|
||||
|
||||
case ISDBT2071_MODEL:
|
||||
input->port_number = 4;
|
||||
input->i2c_addr = 0x18;
|
||||
chrdevs1ur->tc90522_t.i2c_addr = 0x18;
|
||||
|
||||
for (i = 1; i < 5; i++) {
|
||||
it930x->config.input[i].enable = false;
|
||||
it930x->config.input[i].port_number = i - 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int s1ur_device_init(struct s1ur_device *s1ur, struct device *dev,
|
||||
enum s1ur_model s1ur_model,
|
||||
struct ptx_chrdev_context *chrdev_ctx,
|
||||
struct completion *quit_completion)
|
||||
{
|
||||
int ret = 0;
|
||||
struct it930x_bridge *it930x;
|
||||
struct itedtv_bus *bus;
|
||||
struct ptx_chrdev_config chrdev_config;
|
||||
struct ptx_chrdev_group_config chrdev_group_config;
|
||||
struct ptx_chrdev_group *chrdev_group;
|
||||
struct s1ur_stream_context *stream_ctx;
|
||||
|
||||
if (!s1ur || !dev || !chrdev_ctx || !quit_completion)
|
||||
return -EINVAL;
|
||||
|
||||
dev_dbg(dev, "s1ur_device_init\n");
|
||||
|
||||
get_device(dev);
|
||||
|
||||
kref_init(&s1ur->kref);
|
||||
s1ur->dev = dev;
|
||||
s1ur->s1ur_model = s1ur_model;
|
||||
s1ur->quit_completion = quit_completion;
|
||||
|
||||
stream_ctx = kzalloc(sizeof(*stream_ctx), GFP_KERNEL);
|
||||
if (!stream_ctx) {
|
||||
dev_err(s1ur->dev,
|
||||
"s1ur_device_init: kzalloc(sizeof(*stream_ctx), GFP_KERNEL) failed.\n");
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
s1ur->stream_ctx = stream_ctx;
|
||||
|
||||
it930x = &s1ur->it930x;
|
||||
bus = &it930x->bus;
|
||||
|
||||
ret = itedtv_bus_init(bus);
|
||||
if (ret)
|
||||
goto fail_bus;
|
||||
|
||||
ret = it930x_init(it930x);
|
||||
if (ret)
|
||||
goto fail_bridge;
|
||||
|
||||
ret = it930x_raise(it930x);
|
||||
if (ret)
|
||||
goto fail_device;
|
||||
|
||||
ret = s1ur_device_load_config(s1ur, &chrdev_config);
|
||||
if (ret)
|
||||
goto fail_device;
|
||||
|
||||
chrdev_config.ops = &s1ur_chrdev_ops;
|
||||
chrdev_config.options = PTX_CHRDEV_WAIT_AFTER_LOCK_TC_T;
|
||||
chrdev_config.ringbuf_size = 188 * px4_device_params.tsdev_max_packets;
|
||||
chrdev_config.ringbuf_threshold_size = chrdev_config.ringbuf_size / 10;
|
||||
chrdev_config.priv = &s1ur->chrdevs1ur;
|
||||
|
||||
ret = it930x_load_firmware(it930x, IT930X_FIRMWARE_FILENAME);
|
||||
if (ret)
|
||||
goto fail_device;
|
||||
|
||||
ret = it930x_init_warm(it930x);
|
||||
if (ret)
|
||||
goto fail_device;
|
||||
|
||||
/* GPIO */
|
||||
ret = it930x_set_gpio_mode(it930x, 3, IT930X_GPIO_OUT, true);
|
||||
if (ret)
|
||||
goto fail_device;
|
||||
|
||||
ret = it930x_write_gpio(it930x, 3, true);
|
||||
if (ret)
|
||||
goto fail_device;
|
||||
|
||||
ret = it930x_set_gpio_mode(it930x, 2, IT930X_GPIO_OUT, true);
|
||||
if (ret)
|
||||
goto fail_device;
|
||||
|
||||
ret = it930x_write_gpio(it930x, 2, false);
|
||||
if (ret)
|
||||
goto fail_device;
|
||||
|
||||
if (px4_device_params.discard_null_packets) {
|
||||
struct it930x_pid_filter filter;
|
||||
|
||||
filter.block = true;
|
||||
filter.num = 1;
|
||||
filter.pid[0] = 0x1fff;
|
||||
|
||||
ret = it930x_set_pid_filter(it930x, 0, &filter);
|
||||
if (ret)
|
||||
goto fail_device;
|
||||
}
|
||||
|
||||
chrdev_group_config.owner_kref = &s1ur->kref;
|
||||
chrdev_group_config.owner_kref_release = s1ur_device_release;
|
||||
chrdev_group_config.reserved = false;
|
||||
chrdev_group_config.minor_base = 0; /* unused */
|
||||
chrdev_group_config.chrdev_num = 1;
|
||||
chrdev_group_config.chrdev_config = &chrdev_config;
|
||||
|
||||
ret = ptx_chrdev_context_add_group(chrdev_ctx, dev,
|
||||
&chrdev_group_config, &chrdev_group);
|
||||
if (ret)
|
||||
goto fail_chrdev;
|
||||
|
||||
s1ur->chrdev_group = chrdev_group;
|
||||
s1ur->chrdevs1ur.chrdev = &chrdev_group->chrdev[0];
|
||||
stream_ctx->chrdev = &chrdev_group->chrdev[0];
|
||||
|
||||
atomic_set(&s1ur->available, 1);
|
||||
return 0;
|
||||
|
||||
fail_chrdev:
|
||||
|
||||
fail_device:
|
||||
it930x_term(it930x);
|
||||
|
||||
fail_bridge:
|
||||
itedtv_bus_term(bus);
|
||||
|
||||
fail_bus:
|
||||
kfree(s1ur->stream_ctx);
|
||||
|
||||
fail:
|
||||
put_device(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void s1ur_device_release(struct kref *kref)
|
||||
{
|
||||
struct s1ur_device *s1ur = container_of(kref,
|
||||
struct s1ur_device,
|
||||
kref);
|
||||
|
||||
dev_dbg(s1ur->dev, "s1ur_device_release\n");
|
||||
|
||||
it930x_term(&s1ur->it930x);
|
||||
itedtv_bus_term(&s1ur->it930x.bus);
|
||||
|
||||
kfree(s1ur->stream_ctx);
|
||||
put_device(s1ur->dev);
|
||||
|
||||
complete(s1ur->quit_completion);
|
||||
return;
|
||||
}
|
||||
|
||||
void s1ur_device_term(struct s1ur_device *s1ur)
|
||||
{
|
||||
dev_dbg(s1ur->dev,
|
||||
"s1ur_device_term: kref count: %u\n",
|
||||
kref_read(&s1ur->kref));
|
||||
|
||||
atomic_xchg(&s1ur->available, 0);
|
||||
ptx_chrdev_group_destroy(s1ur->chrdev_group);
|
||||
|
||||
kref_put(&s1ur->kref, s1ur_device_release);
|
||||
return;
|
||||
}
|
55
driver/s1ur_device.h
Normal file
55
driver/s1ur_device.h
Normal file
@@ -0,0 +1,55 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* PTX driver definitions for PLEX PX-S1UR and DIGIBEST ISDBT2071 (DTV03A-1TU) devices (s1ur_device.h)
|
||||
*
|
||||
* Copyright (c) 2023 techma.
|
||||
*/
|
||||
|
||||
#ifndef __S1UR_DEVICE_H__
|
||||
#define __S1UR_DEVICE_H__
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/kref.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
#include "ptx_chrdev.h"
|
||||
#include "it930x.h"
|
||||
#include "tc90522.h"
|
||||
#include "r850.h"
|
||||
|
||||
#define S1UR_CHRDEV_NUM 1
|
||||
#define ISDBT2071_CHRDEV_NUM 1
|
||||
|
||||
enum s1ur_model {
|
||||
PXS1UR_MODEL = 0,
|
||||
ISDBT2071_MODEL,
|
||||
};
|
||||
|
||||
struct s1ur_chrdev {
|
||||
struct ptx_chrdev *chrdev;
|
||||
struct tc90522_demod tc90522_t;
|
||||
struct tc90522_demod tc90522_s;
|
||||
struct r850_tuner r850;
|
||||
};
|
||||
|
||||
struct s1ur_device {
|
||||
struct kref kref;
|
||||
atomic_t available;
|
||||
struct device *dev;
|
||||
enum s1ur_model s1ur_model;
|
||||
struct completion *quit_completion;
|
||||
struct ptx_chrdev_group *chrdev_group;
|
||||
struct s1ur_chrdev chrdevs1ur;
|
||||
struct it930x_bridge it930x;
|
||||
void *stream_ctx;
|
||||
};
|
||||
|
||||
int s1ur_device_init(struct s1ur_device *s1ur, struct device *dev,
|
||||
enum s1ur_model s1ur_model,
|
||||
struct ptx_chrdev_context *chrdev_ctx,
|
||||
struct completion *quit_completion);
|
||||
void s1ur_device_term(struct s1ur_device *s1ur);
|
||||
|
||||
#endif
|
491
driver/tc90522.c
491
driver/tc90522.c
@@ -1,139 +1,374 @@
|
||||
// tc90522.c
|
||||
|
||||
// Toshiba TC90522 driver
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Toshiba TC90522 driver (tc90522.c)
|
||||
*
|
||||
* Copyright (c) 2018-2021 nns779
|
||||
*/
|
||||
|
||||
#include "print_format.h"
|
||||
#include "tc90522.h"
|
||||
|
||||
#include <linux/types.h>
|
||||
#ifdef __linux__
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/slab.h>
|
||||
#endif
|
||||
|
||||
#include "i2c_comm.h"
|
||||
#include "tc90522.h"
|
||||
|
||||
int tc90522_write_regs(struct tc90522_demod *demod, struct tc90522_regbuf *regbuf, int num)
|
||||
static int tc90522_read_regs_nolock(struct tc90522_demod *demod,
|
||||
u8 reg,
|
||||
u8 *buf, u8 len)
|
||||
{
|
||||
int ret = 0, i;
|
||||
int ret = 0;
|
||||
u8 b;
|
||||
struct i2c_comm_request req[2];
|
||||
|
||||
if (!regbuf || !num)
|
||||
if (!buf || !len)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
u8 b[255], len;
|
||||
b = reg;
|
||||
|
||||
b[0] = regbuf[i].reg;
|
||||
req[0].req = I2C_WRITE_REQUEST;
|
||||
req[0].addr = demod->i2c_addr;
|
||||
req[0].data = &b;
|
||||
req[0].len = 1;
|
||||
|
||||
if (regbuf[i].buf) {
|
||||
len = regbuf[i].u.len;
|
||||
if (!len || len > 254) {
|
||||
dev_dbg(demod->dev, "tc90522_write_regs: Buffer too large. (num: %d, i: %d, addr: %x, reg: %x)\n", num, i, demod->i2c_addr, regbuf[i].reg);
|
||||
continue;
|
||||
}
|
||||
memcpy(&b[1], regbuf[i].buf, len);
|
||||
} else {
|
||||
b[1] = regbuf[i].u.val;
|
||||
len = 1;
|
||||
}
|
||||
req[1].req = I2C_READ_REQUEST;
|
||||
req[1].addr = demod->i2c_addr;
|
||||
req[1].data = buf;
|
||||
req[1].len = len;
|
||||
|
||||
ret = i2c_comm_master_write(demod->i2c, demod->i2c_addr, b, len + 1);
|
||||
if (ret) {
|
||||
dev_err(demod->dev, "tc90522_write_regs: i2c_comm_master_write() failed. (num: %d, i: %d, addr: %x, reg: %x, ret: %d)\n", num, i, demod->i2c_addr, regbuf[i].reg, ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ret = i2c_comm_master_request(demod->i2c, req, 2);
|
||||
if (ret)
|
||||
dev_err(demod->dev,
|
||||
"tc90522_read_regs_nolock: i2c_comm_master_request() failed. (addr: 0x%x, reg: 0x%x, len: %u)\n",
|
||||
demod->i2c_addr, reg, len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tc90522_write_reg(struct tc90522_demod *demod, u8 reg, u8 val)
|
||||
static int tc90522_read_reg_nolock(struct tc90522_demod *demod, u8 reg, u8 *val)
|
||||
{
|
||||
struct tc90522_regbuf regbuf[1];
|
||||
|
||||
tc90522_regbuf_set_val(®buf[0], reg, val);
|
||||
|
||||
return tc90522_write_regs(demod, regbuf, 1);
|
||||
return tc90522_read_regs_nolock(demod, reg, val, 1);
|
||||
}
|
||||
|
||||
int tc90522_read_regs(struct tc90522_demod *demod, struct tc90522_regbuf *regbuf, int num)
|
||||
int tc90522_read_regs(struct tc90522_demod *demod, u8 reg, u8 *buf, u8 len)
|
||||
{
|
||||
int ret = 0, i;
|
||||
int ret = 0;
|
||||
|
||||
if (!regbuf || !num)
|
||||
return -EINVAL;
|
||||
mutex_lock(&demod->priv.lock);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
u8 b[1];
|
||||
ret = tc90522_read_regs_nolock(demod, reg, buf, len);
|
||||
|
||||
if (!regbuf[i].buf || !regbuf[i].u.len) {
|
||||
dev_dbg(demod->dev, "tc90522_read_regs: Invalid buffer. (num: %d, i: %d, addr: %x, reg: %x)\n", num, i, demod->i2c_addr, regbuf[i].reg);
|
||||
continue;
|
||||
}
|
||||
|
||||
b[0] = regbuf[i].reg;
|
||||
|
||||
ret = i2c_comm_master_write(demod->i2c, demod->i2c_addr, b, 1);
|
||||
if (ret) {
|
||||
dev_err(demod->dev, "tc90522_read_regs: i2c_comm_master_write() failed. (num: %d, i: %d, addr: %x, reg: %x, ret: %d)\n", num, i, demod->i2c_addr, regbuf[i].reg, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = i2c_comm_master_read(demod->i2c, demod->i2c_addr, regbuf[i].buf, regbuf[i].u.len);
|
||||
if (ret) {
|
||||
dev_err(demod->dev, "tc90522_read_regs: i2c_comm_master_read() failed. (num: %d, i: %d, addr: %x, reg: %x, ret: %d)\n", num, i, demod->i2c_addr, regbuf[i].reg, ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&demod->priv.lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tc90522_read_reg(struct tc90522_demod *demod, u8 reg, u8 *val)
|
||||
{
|
||||
struct tc90522_regbuf regbuf[1];
|
||||
int ret = 0;
|
||||
|
||||
tc90522_regbuf_set_buf(®buf[0], reg, val, 1);
|
||||
mutex_lock(&demod->priv.lock);
|
||||
|
||||
return tc90522_read_regs(demod, regbuf, 1);
|
||||
ret = tc90522_read_regs_nolock(demod, reg, val, 1);
|
||||
|
||||
mutex_unlock(&demod->priv.lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tc90522_i2c_master_write(struct tc90522_demod *demod, u8 addr, const u8 *data, int len)
|
||||
int tc90522_read_multiple_regs(struct tc90522_demod *demod,
|
||||
struct tc90522_regbuf *regbuf, int num)
|
||||
{
|
||||
u8 b[255];
|
||||
int ret = 0, i;
|
||||
|
||||
if (!data || !len || len > 253)
|
||||
if (!regbuf || !num)
|
||||
return -EINVAL;
|
||||
|
||||
b[0] = 0xfe;
|
||||
b[1] = (addr << 1);
|
||||
memcpy(&b[2], data, len);
|
||||
mutex_lock(&demod->priv.lock);
|
||||
|
||||
return i2c_comm_master_write(demod->i2c, demod->i2c_addr, b, len + 2);
|
||||
for (i = 0; i < num; i++) {
|
||||
ret = tc90522_read_regs_nolock(demod,
|
||||
regbuf[i].reg,
|
||||
regbuf[i].buf, regbuf[i].u.len);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
mutex_unlock(&demod->priv.lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tc90522_i2c_master_read(struct tc90522_demod *demod, u8 addr, u8 *data, int len)
|
||||
static int tc90522_write_regs_nolock(struct tc90522_demod *demod,
|
||||
u8 reg,
|
||||
u8 *buf, u8 len)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 b[2];
|
||||
u8 b[255];
|
||||
struct i2c_comm_request req[1];
|
||||
|
||||
if (!data || !len)
|
||||
if (!buf || !len) {
|
||||
return -EINVAL;
|
||||
} else if (len > 254) {
|
||||
dev_dbg(demod->dev,
|
||||
"tc90522_write_regs_nolock: Buffer too large. (addr: 0x%x, reg: %u, len: 0x%x)\n",
|
||||
demod->i2c_addr, reg, len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
b[0] = reg;
|
||||
memcpy(&b[1], buf, len);
|
||||
|
||||
req[0].req = I2C_WRITE_REQUEST;
|
||||
req[0].addr = demod->i2c_addr;
|
||||
req[0].data = b;
|
||||
req[0].len = 1 + len;
|
||||
|
||||
ret = i2c_comm_master_request(demod->i2c, req, 1);
|
||||
if (ret)
|
||||
dev_err(demod->dev,
|
||||
"tc90522_write_regs_nolock: i2c_comm_master_request() failed. (addr: 0x%x, reg: 0x%x, len: %u, ret: %d)\n",
|
||||
demod->i2c_addr, reg, len, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int tc90522_write_reg_nolock(struct tc90522_demod *demod, u8 reg, u8 val)
|
||||
{
|
||||
return tc90522_write_regs_nolock(demod, reg, &val, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
int tc90522_write_regs(struct tc90522_demod *demod, u8 reg, u8 *buf, u8 len)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&demod->priv.lock);
|
||||
|
||||
ret = tc90522_write_regs_nolock(demod, reg, buf, len);
|
||||
|
||||
mutex_unlock(&demod->priv.lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tc90522_write_reg(struct tc90522_demod *demod, u8 reg, u8 val)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&demod->priv.lock);
|
||||
|
||||
ret = tc90522_write_regs_nolock(demod, reg, &val, 1);
|
||||
|
||||
mutex_unlock(&demod->priv.lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tc90522_write_multiple_regs(struct tc90522_demod *demod,
|
||||
struct tc90522_regbuf *regbuf, int num)
|
||||
{
|
||||
int ret = 0, i;
|
||||
|
||||
if (!regbuf || !num)
|
||||
return -EINVAL;
|
||||
|
||||
b[0] = 0xfe;
|
||||
b[1] = (addr << 1) | 0x01;
|
||||
mutex_lock(&demod->priv.lock);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
if (regbuf[i].buf)
|
||||
ret = tc90522_write_regs_nolock(demod,
|
||||
regbuf[i].reg,
|
||||
regbuf[i].buf,
|
||||
regbuf[i].u.len);
|
||||
else
|
||||
ret = tc90522_write_regs_nolock(demod,
|
||||
regbuf[i].reg,
|
||||
®buf[i].u.val,
|
||||
1);
|
||||
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
mutex_unlock(&demod->priv.lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tc90522_i2c_master_request(void *i2c_priv,
|
||||
const struct i2c_comm_request *req,
|
||||
int num)
|
||||
{
|
||||
int ret = 0, i, master_req_num = 0, n = 0;
|
||||
struct tc90522_demod *demod = i2c_priv;
|
||||
struct i2c_comm_request *master_req = NULL;
|
||||
|
||||
mutex_lock(&demod->priv.lock);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
switch (req[i].req) {
|
||||
case I2C_READ_REQUEST:
|
||||
if (!req[i].data || !req[i].len) {
|
||||
dev_dbg(demod->dev,
|
||||
"tc90522_i2c_master_request: Invalid parameter. (i: %d)\n",
|
||||
i);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
master_req_num += 2;
|
||||
break;
|
||||
|
||||
case I2C_WRITE_REQUEST:
|
||||
if (!req[i].data || !req[i].len || req[i].len > 253) {
|
||||
dev_dbg(demod->dev,
|
||||
"tc90522_i2c_master_request: Invalid parameter. (i: %d)\n",
|
||||
i);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
master_req_num++;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ret = i2c_comm_master_write(demod->i2c, demod->i2c_addr, b, 2);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto exit;
|
||||
|
||||
return i2c_comm_master_read(demod->i2c, demod->i2c_addr, data, len);
|
||||
if (!master_req_num)
|
||||
goto exit;
|
||||
|
||||
if ((num == 1 && req[0].req == I2C_WRITE_REQUEST) ||
|
||||
(num == 2 && req[0].req == I2C_WRITE_REQUEST &&
|
||||
req[1].req == I2C_READ_REQUEST)) {
|
||||
u8 b[255], br[2];
|
||||
struct i2c_comm_request master_req[3];
|
||||
|
||||
b[0] = 0xfe;
|
||||
b[1] = (req[0].addr << 1);
|
||||
memcpy(&b[2], req[0].data, req[0].len);
|
||||
|
||||
master_req[0].req = I2C_WRITE_REQUEST;
|
||||
master_req[0].addr = demod->i2c_addr;
|
||||
master_req[0].data = b;
|
||||
master_req[0].len = 2 + req[0].len;
|
||||
|
||||
if (num == 2) {
|
||||
br[0] = 0xfe;
|
||||
br[1] = (req[1].addr << 1) | 0x01;
|
||||
|
||||
master_req[1].req = I2C_WRITE_REQUEST;
|
||||
master_req[1].addr = demod->i2c_addr;
|
||||
master_req[1].data = br;
|
||||
master_req[1].len = 2;
|
||||
|
||||
master_req[2].req = I2C_READ_REQUEST;
|
||||
master_req[2].addr = demod->i2c_addr;
|
||||
master_req[2].data = req[1].data;
|
||||
master_req[2].len = req[1].len;
|
||||
}
|
||||
|
||||
ret = i2c_comm_master_request(demod->i2c,
|
||||
master_req, (num == 2) ? 3 : 1);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
master_req = (struct i2c_comm_request *)kmalloc(sizeof(*master_req) * master_req_num,
|
||||
GFP_KERNEL);
|
||||
if (!master_req) {
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
u8 *b;
|
||||
|
||||
switch (req[i].req) {
|
||||
case I2C_READ_REQUEST:
|
||||
b = (u8 *)kmalloc(sizeof(*b) * 2, GFP_KERNEL);
|
||||
if (!b) {
|
||||
ret = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
|
||||
b[0] = 0xfe;
|
||||
b[1] = (req[i].addr << 1) | 0x01;
|
||||
|
||||
master_req[n].req = I2C_WRITE_REQUEST;
|
||||
master_req[n].addr = demod->i2c_addr;
|
||||
master_req[n].data = b;
|
||||
master_req[n].len = 2;
|
||||
|
||||
master_req[n + 1].req = I2C_READ_REQUEST;
|
||||
master_req[n + 1].addr = demod->i2c_addr;
|
||||
master_req[n + 1].data = req[i].data;
|
||||
master_req[n + 1].len = req[i].len;
|
||||
|
||||
n += 2;
|
||||
break;
|
||||
|
||||
case I2C_WRITE_REQUEST:
|
||||
b = (u8 *)kmalloc(sizeof(*b) * (2 + req[i].len),
|
||||
GFP_KERNEL);
|
||||
if (!b) {
|
||||
ret = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
|
||||
b[0] = 0xfe;
|
||||
b[1] = (req[i].addr << 1);
|
||||
memcpy(&b[2], req[i].data, req[i].len);
|
||||
|
||||
master_req[n].req = I2C_WRITE_REQUEST;
|
||||
master_req[n].addr = demod->i2c_addr;
|
||||
master_req[n].data = b;
|
||||
master_req[n].len = 2 + req[i].len;
|
||||
|
||||
n++;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
goto exit_with_free;
|
||||
}
|
||||
|
||||
ret = i2c_comm_master_request(demod->i2c, master_req, master_req_num);
|
||||
|
||||
exit_with_free:
|
||||
for (i = 0; i < master_req_num; i++) {
|
||||
if (master_req[i].req == I2C_WRITE_REQUEST &&
|
||||
master_req[i].data)
|
||||
kfree(master_req[i].data);
|
||||
}
|
||||
|
||||
if (master_req)
|
||||
kfree(master_req);
|
||||
|
||||
exit:
|
||||
mutex_unlock(&demod->priv.lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tc90522_init(struct tc90522_demod *demod)
|
||||
{
|
||||
demod->i2c_master.wr = (int (*)(void *, u8, const u8 *, int))tc90522_i2c_master_write;
|
||||
demod->i2c_master.rd = (int (*)(void *, u8, u8 *, int))tc90522_i2c_master_read;
|
||||
mutex_init(&demod->priv.lock);
|
||||
|
||||
demod->i2c_master.gate_ctrl = NULL;
|
||||
demod->i2c_master.request = tc90522_i2c_master_request;
|
||||
demod->i2c_master.priv = demod;
|
||||
|
||||
return 0;
|
||||
@@ -141,10 +376,12 @@ int tc90522_init(struct tc90522_demod *demod)
|
||||
|
||||
int tc90522_term(struct tc90522_demod *demod)
|
||||
{
|
||||
demod->i2c_master.wr = NULL;
|
||||
demod->i2c_master.rd = NULL;
|
||||
demod->i2c_master.gate_ctrl = NULL;
|
||||
demod->i2c_master.request = NULL;
|
||||
demod->i2c_master.priv = NULL;
|
||||
|
||||
mutex_destroy(&demod->priv.lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -157,12 +394,12 @@ int tc90522_sleep_s(struct tc90522_demod *demod, bool sleep)
|
||||
};
|
||||
|
||||
if (sleep) {
|
||||
// sleep
|
||||
/* sleep */
|
||||
regbuf[0].u.val = 0x80;
|
||||
regbuf[1].u.val = 0xff;
|
||||
}
|
||||
|
||||
return tc90522_write_regs(demod, regbuf, 2);
|
||||
return tc90522_write_multiple_regs(demod, regbuf, 2);
|
||||
#else
|
||||
return tc90522_write_reg(demod, 0x17, (sleep) ? 0x01 : 0x00);
|
||||
#endif
|
||||
@@ -177,35 +414,40 @@ int tc90522_set_agc_s(struct tc90522_demod *demod, bool on)
|
||||
{ 0x03, NULL, { 0x01 } }
|
||||
};
|
||||
|
||||
if (demod->is_secondary)
|
||||
regbuf[1].u.val = 0x30;
|
||||
|
||||
if (on) {
|
||||
// on
|
||||
/* on */
|
||||
regbuf[0].u.val = 0xff;
|
||||
regbuf[1].u.val |= 0x02;
|
||||
regbuf[2].u.val = 0x00;
|
||||
}
|
||||
|
||||
return tc90522_write_regs(demod, regbuf, 4);
|
||||
return tc90522_write_multiple_regs(demod, regbuf, 4);
|
||||
}
|
||||
|
||||
int tc90522_tmcc_get_tsid_s(struct tc90522_demod *demod, u8 idx, u16 *tsid)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 b[2];
|
||||
struct tc90522_regbuf regbuf[1];
|
||||
|
||||
if (idx >= 12)
|
||||
return -EINVAL;
|
||||
|
||||
tc90522_regbuf_set_buf(®buf[0], 0xc3, &b[0], 1);
|
||||
ret = tc90522_read_regs(demod, regbuf, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = tc90522_read_regs(demod, 0xce + (idx * 2), &b[0], 2);
|
||||
if (!ret)
|
||||
*tsid = (b[0] << 8 | b[1]);
|
||||
|
||||
if (b[0] & 0x10)
|
||||
return -EAGAIN;
|
||||
return ret;
|
||||
}
|
||||
|
||||
tc90522_regbuf_set_buf(®buf[0], 0xce + (idx * 2), &b[0], 2);
|
||||
ret = tc90522_read_regs(demod, regbuf, 1);
|
||||
int tc90522_get_tsid_s(struct tc90522_demod *demod, u16 *tsid)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 b[2];
|
||||
|
||||
ret = tc90522_read_regs(demod, 0xe6, &b[0], 2);
|
||||
if (!ret)
|
||||
*tsid = (b[0] << 8 | b[1]);
|
||||
|
||||
@@ -215,39 +457,19 @@ int tc90522_tmcc_get_tsid_s(struct tc90522_demod *demod, u8 idx, u16 *tsid)
|
||||
int tc90522_set_tsid_s(struct tc90522_demod *demod, u16 tsid)
|
||||
{
|
||||
u8 b[2];
|
||||
struct tc90522_regbuf regbuf[2];
|
||||
|
||||
b[0] = ((tsid >> 8) & 0xff);
|
||||
b[1] = (tsid & 0xff);
|
||||
|
||||
tc90522_regbuf_set_buf(®buf[0], 0x8f, &b[0], 1);
|
||||
tc90522_regbuf_set_buf(®buf[1], 0x90, &b[1], 1);
|
||||
|
||||
return tc90522_write_regs(demod, regbuf, 2);
|
||||
}
|
||||
|
||||
int tc90522_get_tsid_s(struct tc90522_demod *demod, u16 *tsid)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 b[2];
|
||||
struct tc90522_regbuf regbuf[1];
|
||||
|
||||
tc90522_regbuf_set_buf(®buf[0], 0xe6, &b[0], 2);
|
||||
ret = tc90522_read_regs(demod, regbuf, 1);
|
||||
if (!ret)
|
||||
*tsid = (b[0] << 8 | b[1]);
|
||||
|
||||
return ret;
|
||||
return tc90522_write_regs(demod, 0x8f, b, 2);
|
||||
}
|
||||
|
||||
int tc90522_get_cn_s(struct tc90522_demod *demod, u16 *cn)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 b[2];
|
||||
struct tc90522_regbuf regbuf[1];
|
||||
|
||||
tc90522_regbuf_set_buf(®buf[0], 0xbc, &b[0], 2);
|
||||
ret = tc90522_read_regs(demod, regbuf, 1);
|
||||
ret = tc90522_read_regs(demod, 0xbc, &b[0], 2);
|
||||
if (!ret)
|
||||
*cn = (b[0] << 8) | b[1];
|
||||
|
||||
@@ -266,7 +488,7 @@ int tc90522_enable_ts_pins_s(struct tc90522_demod *demod, bool e)
|
||||
regbuf[1].u.val = 0x22;
|
||||
}
|
||||
|
||||
return tc90522_write_regs(demod, regbuf, 2);
|
||||
return tc90522_write_multiple_regs(demod, regbuf, 2);
|
||||
}
|
||||
|
||||
int tc90522_is_signal_locked_s(struct tc90522_demod *demod, bool *lock)
|
||||
@@ -302,20 +524,18 @@ int tc90522_set_agc_t(struct tc90522_demod *demod, bool on)
|
||||
};
|
||||
|
||||
if (on)
|
||||
// on
|
||||
/* on */
|
||||
regbuf[2].u.val &= ~0x01;
|
||||
|
||||
return tc90522_write_regs(demod, regbuf, 4);
|
||||
return tc90522_write_multiple_regs(demod, regbuf, 4);
|
||||
}
|
||||
|
||||
int tc90522_get_cndat_t(struct tc90522_demod *demod, u32 *cndat)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 b[3];
|
||||
struct tc90522_regbuf regbuf[1];
|
||||
|
||||
tc90522_regbuf_set_buf(®buf[0], 0x8b, &b[0], 3);
|
||||
ret = tc90522_read_regs(demod, regbuf, 1);
|
||||
ret = tc90522_read_regs(demod, 0x8b, &b[0], 3);
|
||||
if (!ret)
|
||||
*cndat = (b[0] << 16) | (b[1] << 8) | b[2];
|
||||
|
||||
@@ -334,19 +554,20 @@ int tc90522_is_signal_locked_t(struct tc90522_demod *demod, bool *lock)
|
||||
|
||||
*lock = false;
|
||||
|
||||
ret = tc90522_read_reg(demod, 0x80, &b);
|
||||
if (ret)
|
||||
return ret;
|
||||
else if (b & 0x28)
|
||||
return 0;
|
||||
mutex_lock(&demod->priv.lock);
|
||||
|
||||
ret = tc90522_read_reg(demod, 0xb0, &b);
|
||||
if (ret)
|
||||
return ret;
|
||||
else if ((b & 0x0f) < 8)
|
||||
return 0;
|
||||
ret = tc90522_read_reg_nolock(demod, 0x80, &b);
|
||||
if (ret || (b & 0x28))
|
||||
goto exit;
|
||||
|
||||
ret = tc90522_read_reg_nolock(demod, 0xb0, &b);
|
||||
if (ret || (b & 0x0f) < 8)
|
||||
goto exit;
|
||||
|
||||
*lock = true;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&demod->priv.lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1,18 +1,34 @@
|
||||
// tc90522.h
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Toshiba TC90522 driver definitions (tc90522.c)
|
||||
*
|
||||
* Copyright (c) 2018-2021 nns779
|
||||
*/
|
||||
|
||||
#ifndef __TC90522_H__
|
||||
#define __TC90522_H__
|
||||
|
||||
#ifdef __linux__
|
||||
#include <linux/types.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/device.h>
|
||||
#elif defined(_WIN32) || defined(_WIN64)
|
||||
#include "misc_win.h"
|
||||
#endif
|
||||
|
||||
#include "i2c_comm.h"
|
||||
|
||||
struct tc90522_priv {
|
||||
struct mutex lock;
|
||||
};
|
||||
|
||||
struct tc90522_demod {
|
||||
struct device *dev;
|
||||
struct i2c_comm_master *i2c;
|
||||
const struct device *dev;
|
||||
const struct i2c_comm_master *i2c;
|
||||
u8 i2c_addr;
|
||||
struct i2c_comm_master i2c_master;
|
||||
bool is_secondary;
|
||||
struct tc90522_priv priv;
|
||||
};
|
||||
|
||||
struct tc90522_regbuf {
|
||||
@@ -24,24 +40,33 @@ struct tc90522_regbuf {
|
||||
} u;
|
||||
};
|
||||
|
||||
static inline void tc90522_regbuf_set_val(struct tc90522_regbuf *regbuf, u8 reg, u8 val)
|
||||
static inline void tc90522_regbuf_set_val(struct tc90522_regbuf *regbuf,
|
||||
u8 reg, u8 val)
|
||||
{
|
||||
regbuf->reg = reg;
|
||||
regbuf->buf = NULL;
|
||||
regbuf->u.val = val;
|
||||
}
|
||||
|
||||
static inline void tc90522_regbuf_set_buf(struct tc90522_regbuf *regbuf, u8 reg, u8 *buf, u8 len)
|
||||
static inline void tc90522_regbuf_set_buf(struct tc90522_regbuf *regbuf,
|
||||
u8 reg, u8 *buf, u8 len)
|
||||
{
|
||||
regbuf->reg = reg;
|
||||
regbuf->buf = buf;
|
||||
regbuf->u.len = len;
|
||||
}
|
||||
|
||||
int tc90522_write_regs(struct tc90522_demod *demod, struct tc90522_regbuf *regbuf, int num);
|
||||
int tc90522_write_reg(struct tc90522_demod *demod, u8 reg, u8 val);
|
||||
int tc90522_read_regs(struct tc90522_demod *demod, struct tc90522_regbuf *regbuf, int num);
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
int tc90522_read_regs(struct tc90522_demod *demod, u8 reg, u8 *buf, u8 len);
|
||||
int tc90522_read_reg(struct tc90522_demod *demod, u8 reg, u8 *val);
|
||||
int tc90522_read_multiple_regs(struct tc90522_demod *demod,
|
||||
struct tc90522_regbuf *regbuf, int num);
|
||||
int tc90522_write_regs(struct tc90522_demod *demod, u8 reg, u8 *buf, u8 len);
|
||||
int tc90522_write_reg(struct tc90522_demod *demod, u8 reg, u8 val);
|
||||
int tc90522_write_multiple_regs(struct tc90522_demod *demod,
|
||||
struct tc90522_regbuf *regbuf, int num);
|
||||
|
||||
int tc90522_init(struct tc90522_demod *demod);
|
||||
int tc90522_term(struct tc90522_demod *demod);
|
||||
@@ -49,8 +74,8 @@ int tc90522_term(struct tc90522_demod *demod);
|
||||
int tc90522_sleep_s(struct tc90522_demod *demod, bool sleep);
|
||||
int tc90522_set_agc_s(struct tc90522_demod *demod, bool on);
|
||||
int tc90522_tmcc_get_tsid_s(struct tc90522_demod *demod, u8 idx, u16 *tsid);
|
||||
int tc90522_set_tsid_s(struct tc90522_demod *demod, u16 tsid);
|
||||
int tc90522_get_tsid_s(struct tc90522_demod *demod, u16 *tsid);
|
||||
int tc90522_set_tsid_s(struct tc90522_demod *demod, u16 tsid);
|
||||
int tc90522_get_cn_s(struct tc90522_demod *demod, u16 *cn);
|
||||
int tc90522_enable_ts_pins_s(struct tc90522_demod *demod, bool e);
|
||||
int tc90522_is_signal_locked_s(struct tc90522_demod *demod, bool *lock);
|
||||
@@ -60,5 +85,8 @@ int tc90522_set_agc_t(struct tc90522_demod *demod, bool on);
|
||||
int tc90522_get_cndat_t(struct tc90522_demod *demod, u32 *cndat);
|
||||
int tc90522_enable_ts_pins_t(struct tc90522_demod *demod, bool e);
|
||||
int tc90522_is_signal_locked_t(struct tc90522_demod *demod, bool *lock);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@@ -1 +1,11 @@
|
||||
KERNEL=="px4video*", GROUP="video", MODE="0664"
|
||||
KERNEL=="pxmlt5video*", GROUP="video", MODE="0664"
|
||||
KERNEL=="pxmlt8video*", GROUP="video", MODE="0664"
|
||||
KERNEL=="isdb2056video*", GROUP="video", MODE="0664"
|
||||
KERNEL=="isdb6014video*", GROUP="video", MODE="0664"
|
||||
KERNEL=="pxm1urvideo*", GROUP="video", MODE="0664"
|
||||
KERNEL=="pxs1urvideo*", GROUP="video", MODE="0664"
|
||||
KERNEL=="isdbt2071video*", GROUP="video", MODE="0664"
|
||||
|
||||
# Digibest 製チューナーに常に USB 電源を供給し、チューナーが不安定にならないようにする
|
||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="0511", ACTION=="add", TEST=="power/control", ATTR{power/control}="on"
|
||||
|
BIN
etc/it930x-firmware.bin
Normal file
BIN
etc/it930x-firmware.bin
Normal file
Binary file not shown.
@@ -1,9 +1,84 @@
|
||||
description size crc32 align firmware_code firmware_segment firmware_partition firmware_crc32
|
||||
PX-W3U4 BDA Ver.1.1 32bit 169088 b92f9c4b 4 00022aa8 00023328 00023321 0b41a994
|
||||
PX-W3U4 BDA Ver.1.1 64bit 191360 af8a5673 4 00028d50 000295d0 00028be6 0b41a994
|
||||
PX-W3PE4 BDA Ver.1.1 32bit 169088 8455512f 4 00022aa8 00023328 00023321 0b41a994
|
||||
PX-W3PE4 BDA Ver.1.1 64bit 191360 8ea7d533 4 00028d50 000295d0 00028be6 0b41a994
|
||||
PX-W3U4 BDA Ver.1.0 32bit 167296 4c2cf43f 4 00022528 00022da8 00022da1 0b41a994
|
||||
PX-W3U4 BDA Ver.1.0 64bit 189440 5743d95f 4 000287d0 00029050 00028666 0b41a994
|
||||
PX-W3PE4 BDA Ver.Beta 32bit 165504 2ec9ef50 4 00021ea8 00022728 00022721 0b41a994
|
||||
PX-W3PE4 BDA Ver.Beta 64bit 187776 709a3353 4 00028150 000289d0 00027fe6 0b41a994
|
||||
description target size crc32 align firmware_code firmware_segment firmware_partition firmware_crc32
|
||||
PX-M1UR Ver 2022.07 64bit it930x 187136 c1fab42a 4 000225B0 00024120 000245b8 df0bf49a
|
||||
PX-W3U4 BDA Ver.1.4 64bit it930x 207232 a1e8223d 4 00029f50 0002bac0 0002bf58 df0bf49a
|
||||
PX-Q3U4 BDA Ver.1.4 64bit it930x 207232 f9953f08 4 00029f50 0002bac0 0002bf58 df0bf49a
|
||||
PX-W3PE4 BDA Ver.1.4 64bit it930x 207232 69900db0 4 00029f50 0002bac0 0002bf58 df0bf49a
|
||||
PX-Q3PE4 BDA Ver.1.4 64bit it930x 207232 76e67055 4 00029f50 0002bac0 0002bf58 df0bf49a
|
||||
PX-W3U4 BDA Ver.1.3 64bit it930x 207360 9bd2358c 4 00029fd0 0002bb40 0002bfd8 df0bf49a
|
||||
PX-Q3U4 BDA Ver.1.3 64bit it930x 207360 14ddd3c3 4 00029fd0 0002bb40 0002bfd8 df0bf49a
|
||||
PX-W3PE4 BDA Ver.1.3 64bit it930x 207360 fd9fd9af 4 00029fd0 0002bb40 0002bfd8 df0bf49a
|
||||
PX-Q3PE4 BDA Ver.1.3 64bit it930x 207360 3037e4b1 4 00029fd0 0002bb40 0002bfd8 df0bf49a
|
||||
PX-W3U4 BDA Ver.1.2 64bit it930x 195968 3feb7702 4 00029fd0 0002a850 0002a9c0 0b41a994
|
||||
PX-Q3U4 BDA Ver.1.2 64bit it930x 195968 51f7e4fb 4 00029fd0 0002a850 0002a9c0 0b41a994
|
||||
PX-W3PE4 BDA Ver.1.2 64bit it930x 195968 19dd3eff 4 00029fd0 0002a850 0002a9c0 0b41a994
|
||||
PX-Q3PE4 BDA Ver.1.2 64bit it930x 195968 c48ad577 4 00029fd0 0002a850 0002a9c0 0b41a994
|
||||
PX-W3U4 BDA Ver.1.1 64bit it930x 191360 af8a5673 4 00028d50 000295d0 00028be6 0b41a994
|
||||
PX-Q3U4 BDA Ver.1.1 64bit it930x 191360 25517c75 4 00028d50 000295d0 00028be6 0b41a994
|
||||
PX-W3PE4 BDA Ver.1.1 64bit it930x 191360 8ea7d533 4 00028d50 000295d0 00028be6 0b41a994
|
||||
PX-Q3PE4 BDA Ver.1.1 64bit it930x 191360 14a5461f 4 00028d50 000295d0 00028be6 0b41a994
|
||||
PX-W3U4 BDA Ver.1.0 64bit it930x 189440 5743d95f 4 000287d0 00029050 00028666 0b41a994
|
||||
PX-Q3U4 BDA Ver.1.0 64bit it930x 189440 96a5469e 4 000287d0 00029050 00028666 0b41a994
|
||||
PX-Q3PE4 BDA Ver.Beta 64bit it930x 189440 e5421c5c 4 000287d0 00029050 00028666 0b41a994
|
||||
PX-W3U4 BDA Ver.Beta 64bit it930x 187776 31d5d9f1 4 00028150 000289d0 00027fe6 0b41a994
|
||||
PX-W3PE4 BDA Ver.Beta 64bit it930x 187776 709a3353 4 00028150 000289d0 00027fe6 0b41a994
|
||||
PX-Q3U4 BDA Ver.Beta(8TS) 64bit it930x 187776 ad45808c 4 00028150 000289d0 00027fe6 0b41a994
|
||||
PX-Q3U4 BDA Ver.Beta(6TS) 64bit it930x 187520 0cd9ce5d 4 00028050 000288d0 00027ee6 0b41a994
|
||||
PX-MLT5PE BDA Ver.1.4 64bit it930x 232704 a0200be6 4 0002a240 0002bdb0 0002c248 df0bf49a
|
||||
PX-MLT5PE BDA Ver.1.3 64bit it930x 223232 78c43202 4 0002a240 0002bdb0 0002c248 df0bf49a
|
||||
PX-MLT5PE BDA Ver.1.2 64bit it930x 223232 dc91472c 4 0002a240 0002bdb0 0002c248 df0bf49a
|
||||
PX-MLT5PE BDA Ver.1.1 64bit it930x 223360 e1f39cc2 4 0002a2c0 0002be30 0002c2c8 df0bf49a
|
||||
PX-MLT5PE BDA Ver.1.0 64bit it930x 210944 4421bbcb 4 00029ec0 0002a740 0002a8b0 0b41a994
|
||||
PX-MLT5PE BDA Ver.Beta 64bit it930x 208768 27456f8a 4 000296c0 00029f40 00029636 0b41a994
|
||||
PX-MLT8PE3 BDA Ver.1.0 64bit it930x 213504 45b39a25 4 00029eb0 0002ba20 0002beb8 df0bf49a
|
||||
PX-MLT8PE5 BDA Ver.1.0 64bit it930x 223232 f381e19b 4 0002a240 0002bdb0 0002c248 df0bf49a
|
||||
PX-W3U4 BDA Ver.1.4 32bit it930x 183808 2e894562 4 00024dc0 00026928 00026dc0 df0bf49a
|
||||
PX-Q3U4 BDA Ver.1.4 32bit it930x 183808 bea379cd 4 00024dc0 00026928 00026dc0 df0bf49a
|
||||
PX-W3PE4 BDA Ver.1.4 32bit it930x 183808 578abd05 4 00024dc0 00026928 00026dc0 df0bf49a
|
||||
PX-Q3PE4 BDA Ver.1.4 32bit it930x 183808 a4e7c6f0 4 00024dc0 00026928 00026dc0 df0bf49a
|
||||
PX-W3U4 BDA Ver.1.3 32bit it930x 183808 482d5150 4 00024dc0 00026928 00026dc0 df0bf49a
|
||||
PX-Q3U4 BDA Ver.1.3 32bit it930x 183808 b7ef7baf 4 00024dc0 00026928 00026dc0 df0bf49a
|
||||
PX-W3PE4 BDA Ver.1.3 32bit it930x 183808 a112e0ae 4 00024dc0 00026928 00026dc0 df0bf49a
|
||||
PX-Q3PE4 BDA Ver.1.3 32bit it930x 183808 4bff6784 4 00024dc0 00026928 00026dc0 df0bf49a
|
||||
PX-W3U4 BDA Ver.1.2 32bit it930x 173568 3ecdc93d 4 00023bb0 00024430 000245a0 0b41a994
|
||||
PX-Q3U4 BDA Ver.1.2 32bit it930x 173568 9e5228a0 4 00023bb0 00024430 000245a0 0b41a994
|
||||
PX-W3PE4 BDA Ver.1.2 32bit it930x 173568 e2345778 4 00023bb0 00024430 000245a0 0b41a994
|
||||
PX-Q3PE4 BDA Ver.1.2 32bit it930x 173568 a66a5e9c 4 00023bb0 00024430 000245a0 0b41a994
|
||||
PX-W3U4 BDA Ver.1.1 32bit it930x 169088 b92f9c4b 4 00022aa8 00023328 00023321 0b41a994
|
||||
PX-Q3U4 BDA Ver.1.1 32bit it930x 169088 ce0ee466 4 00022aa8 00023328 00023321 0b41a994
|
||||
PX-W3PE4 BDA Ver.1.1 32bit it930x 169088 8455512f 4 00022aa8 00023328 00023321 0b41a994
|
||||
PX-Q3PE4 BDA Ver.1.1 32bit it930x 169088 d3ae2670 4 00022aa8 00023328 00023321 0b41a994
|
||||
PX-W3U4 BDA Ver.1.0 32bit it930x 167296 4c2cf43f 4 00022528 00022da8 00022da1 0b41a994
|
||||
PX-Q3U4 BDA Ver.1.0 32bit it930x 167296 a0d1a0c5 4 00022528 00022da8 00022da1 0b41a994
|
||||
PX-Q3PE4 BDA Ver.Beta 32bit it930x 167296 13bc8533 4 00022528 00022da8 00022da1 0b41a994
|
||||
PX-W3U4 BDA Ver.Beta 32bit it930x 165504 9ce477bf 4 00021ea8 00022728 00022721 0b41a994
|
||||
PX-W3PE4 BDA Ver.Beta 32bit it930x 165504 2ec9ef50 4 00021ea8 00022728 00022721 0b41a994
|
||||
PX-Q3U4 BDA Ver.Beta(8TS) 32bit it930x 165504 c980c89d 4 00021ea8 00022728 00022721 0b41a994
|
||||
PX-Q3U4 BDA Ver.Beta(6TS) 32bit it930x 165248 67a3d394 4 00021da8 00022628 00022621 0b41a994
|
||||
PX-MLT5PE BDA Ver.1.3 32bit it930x 198784 690eef71 4 000261c0 00027d28 000281c0 df0bf49a
|
||||
PX-MLT5PE BDA Ver.1.2 32bit it930x 198784 3d622f89 4 000261c0 00027d28 000281c0 df0bf49a
|
||||
PX-MLT5PE BDA Ver.1.1 32bit it930x 198784 c0fa8836 4 000261c0 00027d28 000281c0 df0bf49a
|
||||
PX-MLT5PE BDA Ver.1.0 32bit it930x 185600 58c0a635 4 00024530 00024db0 00024f20 0b41a994
|
||||
PX-MLT5PE BDA Ver.Beta 32bit it930x 183296 4b79b0b9 4 00023d28 000245a8 000245a1 0b41a994
|
||||
PX-MLT8PE3 BDA Ver.1.0 32bit it930x 190208 8bc06fc4 4 00025e40 000279a8 00027e40 df0bf49a
|
||||
PX-MLT8PE5 BDA Ver.1.0 32bit it930x 198784 6fede341 4 000261c0 00027d28 000281c0 df0bf49a
|
||||
ISDB2056 BDA v19.05.07.1 64bit it930x 198400 4e590b4c 4 00028be0 0002a750 0002abe8 df0bf49a
|
||||
ISDB2056 BDA v18.02.21.1 64bit it930x 181760 cc649bcf 4 000277c0 00028040 00027666 0b41a994
|
||||
ISDB2056 BDA v19.05.07.1 32bit it930x 178048 5af0bf7f 4 00024640 000261a8 00026640 df0bf49a
|
||||
ISDB2056 BDA v18.02.21.1 32bit it930x 161024 ce336e4e 4 00021b28 000223a8 000223a1 0b41a994
|
||||
ISDBT6013 BDA v18.02.28.1 64bit it930x 179968 58703933 4 00026c80 00027500 00023b5b 0b41a994
|
||||
ISDBT6013 BDA v18.02.28.1 32bit it930x 159360 d07789f7 4 0001eaa8 0001f328 0001f321 0b41a994
|
||||
ISDB6014 BDA 2021-04-13 64bit it930x 227840 46eda834 4 0002a140 0002bcb0 0002c148 df0bf49a
|
||||
ISDB6014 BDA 2020-10-12 64bit it930x 218624 1598f9cc 4 0002a140 0002bcb0 0002c148 df0bf49a
|
||||
ISDB6014 BDA 2021-04-13 32bit it930x 203776 44b919df 4 00025fc0 00027b28 00027fc0 df0bf49a
|
||||
ISDB6014 BDA 2020-10-12 32bit it930x 194560 1418110c 4 00025fc0 00027b28 00027fc0 df0bf49a
|
||||
usb-px4 (CentOS6_64bit_kernel2.6.32-696) it930x 7387804 3e71febc 8 0004a740 0004a340 0004a320 b3887375
|
||||
usb-px4 (CentOS7-1708_64bit_kernel3.10.0-693) it930x 7838824 05ac7ba2 8 0004bee0 0004bae0 0004bac0 b3887375
|
||||
usb-px4 (CentOS7-1804_64bit_kernel3.10.0-862) it930x 8251312 f35af36a 8 00050560 00050160 00050140 b3887375
|
||||
usb-px4 (Debian8.0.0_64bit_kernel3.16.0-4) it930x 6748320 6f680d31 8 00048e40 00048a40 00048a20 b3887375
|
||||
usb-px4 (Debian9.4_64bit_kernel4.9.0-6) it930x 11660800 1b78136d 8 0004d7a0 0004d3a0 0004d380 b3887375
|
||||
usb-px4 (Ubuntu14.04.1_64bit_kernel3.13.0-137) it930x 604884 6b40ef01 8 0004a540 0004a140 0004a120 b3887375
|
||||
usb-px4 (Ubuntu17.10_64bit_Kernel4.13.0-19) it930x 601312 91e12606 8 00048be0 000487e0 000487c0 b3887375
|
||||
usb-px4 (Ubuntu18.04_64bit_kernel4.15.0-23) it930x 640928 c5c5b0e7 8 0004cdc0 0004c9c0 0004c9a0 b3887375
|
||||
usb-px4 (CentOS7-1708_32bit_kernel3.10.0-693) it930x 5401460 1ecd924b 4 00045ca0 00045aa0 00045a90 b3887375
|
||||
usb-px4 (Debian8.0.0_32bit_kernel3.16.0-4) it930x 4584340 b2dad9f4 4 00044200 00044000 00043ff0 b3887375
|
||||
usb-px4 (Ubuntu14.04.1_32bit_kernel3.13.0-32) it930x 441980 791b65e1 4 000446c0 000444c0 000444b0 b3887375
|
||||
|
|
224
fwtool/fwtool.c
224
fwtool/fwtool.c
@@ -18,9 +18,15 @@
|
||||
|
||||
#define le32_load(p) (*((uint8_t *)(p)) | *(((uint8_t *)(p)) + 1) << 8 | *(((uint8_t *)(p)) + 2) << 16 | *(((uint8_t *)(p)) + 3) << 24)
|
||||
|
||||
enum fw_target {
|
||||
FW_TARGET_UNKNOWN = 0,
|
||||
FW_TARGET_IT930X
|
||||
};
|
||||
|
||||
struct fwinfo {
|
||||
char *desc;
|
||||
long size;
|
||||
enum fw_target target;
|
||||
unsigned long size;
|
||||
uint32_t crc32;
|
||||
uint8_t align;
|
||||
uint32_t code_ofs;
|
||||
@@ -31,6 +37,7 @@ struct fwinfo {
|
||||
|
||||
static const char *name[] = {
|
||||
"description",
|
||||
"target",
|
||||
"size",
|
||||
"crc32",
|
||||
"align",
|
||||
@@ -40,83 +47,127 @@ static const char *name[] = {
|
||||
"firmware_crc32"
|
||||
};
|
||||
|
||||
#define NAME_NUM (sizeof(name) / sizeof(name[0]))
|
||||
static struct {
|
||||
char str[16];
|
||||
enum fw_target target;
|
||||
} target_list[] = {
|
||||
{ "it930x", FW_TARGET_IT930X }
|
||||
};
|
||||
|
||||
static int load_file(const char *path, char **buf, long *size)
|
||||
#define NAME_NUM (sizeof(name) / sizeof(name[0]))
|
||||
#define TARGET_LIST_NUM (sizeof(target_list) / sizeof(target_list[0]))
|
||||
|
||||
static int load_file(const char *path, uint8_t **buf, unsigned long *size)
|
||||
{
|
||||
int ret = -1, fd;
|
||||
FILE *fp;
|
||||
int ret = -1, fd = -1;
|
||||
FILE *fp = NULL;
|
||||
struct stat stbuf;
|
||||
off_t sz;
|
||||
char *b;
|
||||
uint8_t *b;
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
fd = open(path, O_RDONLY | O_BINARY);
|
||||
if (_sopen_s(&fd, path, _O_RDONLY | O_BINARY, _SH_DENYWR, _S_IREAD) || fd == -1) {
|
||||
#else
|
||||
fd = open(path, O_RDONLY);
|
||||
#endif
|
||||
if (fd == -1) {
|
||||
#endif
|
||||
fprintf(stderr, "Couldn't open file '%s' to read.\n", path);
|
||||
goto end;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
fp = _fdopen(fd, "rb");
|
||||
if (!fp) {
|
||||
fprintf(stderr, "_fdopen() failed.\n");
|
||||
#else
|
||||
fp = fdopen(fd, "rb");
|
||||
if (!fp) {
|
||||
fprintf(stderr, "fdopen() failed.\n");
|
||||
close(fd);
|
||||
goto end;
|
||||
#endif
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (fstat(fd, &stbuf) == -1) {
|
||||
fprintf(stderr, "fstat() failed.\n");
|
||||
goto end2;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
sz = stbuf.st_size;
|
||||
if (sz < 0) {
|
||||
fprintf(stderr, "Invalid file size.\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
b = malloc(sz);
|
||||
b = (uint8_t *)malloc(sz);
|
||||
if (b == NULL) {
|
||||
fprintf(stderr, "No enough memory.\n");
|
||||
goto end2;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (fread(b, sz, 1, fp) < 1) {
|
||||
fprintf(stderr, "Incorrect read size.\n");
|
||||
fprintf(stderr, "Failed to read from file '%s'.\n", path);
|
||||
free(b);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
*buf = b;
|
||||
*size = sz;
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
end2:
|
||||
fclose(fp);
|
||||
end:
|
||||
exit:
|
||||
if (fp)
|
||||
fclose(fp);
|
||||
else if (fd != -1)
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
_close(fd);
|
||||
#else
|
||||
close(fd);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int load_tsv_file(struct tsv_data **tsv)
|
||||
{
|
||||
int ret = -1;
|
||||
char *buf;
|
||||
long size;
|
||||
uint8_t *buf;
|
||||
unsigned long size;
|
||||
|
||||
ret = load_file("fwinfo.tsv", &buf, &size);
|
||||
if (ret == -1) {
|
||||
if (ret == -1)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = tsv_load(buf, size, tsv);
|
||||
if (ret == -1) {
|
||||
if (ret == -1)
|
||||
fprintf(stderr, "File 'fwinfo.tsv' is invalid.\n");
|
||||
}
|
||||
|
||||
free(buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int parse_fw_target(const char *str, enum fw_target *target)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < TARGET_LIST_NUM; i++) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
if (!_stricmp(str, target_list[i].str)) {
|
||||
#else
|
||||
if (!strcasecmp(str, target_list[i].str)) {
|
||||
#endif
|
||||
*target = target_list[i].target;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= TARGET_LIST_NUM) {
|
||||
*target = FW_TARGET_UNKNOWN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int load_fwinfo(struct tsv_data *tsv, struct fwinfo *fi, int num)
|
||||
{
|
||||
int i, j;
|
||||
@@ -141,21 +192,25 @@ static int load_fwinfo(struct tsv_data *tsv, struct fwinfo *fi, int num)
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
fi[i].desc = tsv->field[i][name_map[0]];
|
||||
fi[i].size = strtol(tsv->field[i][name_map[1]], NULL, 10);
|
||||
fi[i].crc32 = strtoul(tsv->field[i][name_map[2]], NULL, 16);
|
||||
fi[i].align = strtoul(tsv->field[i][name_map[3]], NULL, 10);
|
||||
fi[i].code_ofs = strtoul(tsv->field[i][name_map[4]], NULL, 16);
|
||||
fi[i].segment_ofs = strtoul(tsv->field[i][name_map[5]], NULL, 16);
|
||||
fi[i].partition_ofs = strtoul(tsv->field[i][name_map[6]], NULL, 16);
|
||||
fi[i].fw_crc32 = strtoul(tsv->field[i][name_map[7]], NULL, 16);
|
||||
if (parse_fw_target(tsv->field[i][name_map[1]], &fi[i].target)) {
|
||||
fprintf(stderr, "Unknown firmware target '%s'.\n", tsv->field[i][name_map[1]]);
|
||||
return -1;
|
||||
}
|
||||
fi[i].size = strtoul(tsv->field[i][name_map[2]], NULL, 10);
|
||||
fi[i].crc32 = strtoul(tsv->field[i][name_map[3]], NULL, 16);
|
||||
fi[i].align = (uint8_t)strtoul(tsv->field[i][name_map[4]], NULL, 10);
|
||||
fi[i].code_ofs = strtoul(tsv->field[i][name_map[5]], NULL, 16);
|
||||
fi[i].segment_ofs = strtoul(tsv->field[i][name_map[6]], NULL, 16);
|
||||
fi[i].partition_ofs = strtoul(tsv->field[i][name_map[7]], NULL, 16);
|
||||
fi[i].fw_crc32 = strtoul(tsv->field[i][name_map[8]], NULL, 16);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int output_firmware(struct fwinfo *fi, const char *buf, long size, const char *path)
|
||||
static int output_firmware(struct fwinfo *fi, const uint8_t *buf, unsigned long size, const char *path)
|
||||
{
|
||||
int i, n;
|
||||
uint8_t i, n;
|
||||
uint8_t align;
|
||||
uint32_t partition_ofs, segment_ofs, code_ofs, crc32;
|
||||
size_t code_len = 0;
|
||||
@@ -171,9 +226,8 @@ static int output_firmware(struct fwinfo *fi, const char *buf, long size, const
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (align < 4) {
|
||||
if (align < 4)
|
||||
align = 4;
|
||||
}
|
||||
|
||||
if (size < partition_ofs + 1) {
|
||||
fprintf(stderr, "Invalid file size.\n");
|
||||
@@ -211,18 +265,22 @@ static int output_firmware(struct fwinfo *fi, const char *buf, long size, const
|
||||
fprintf(stderr, "Firmware CRC32: %08x\n", crc32);
|
||||
|
||||
if (fi->fw_crc32 && crc32 != fi->fw_crc32) {
|
||||
fprintf(stderr, "Incorrect CRC32!\n");
|
||||
fprintf(stderr, "Incorrect CRC32 checksum!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
if (fopen_s(&fp, path, "wb") || !fp) {
|
||||
#else
|
||||
fp = fopen(path, "wb");
|
||||
if (!fp) {
|
||||
#endif
|
||||
fprintf(stderr, "Couldn't open file '%s' to write.\n", path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fwrite(&buf[code_ofs], code_len, 1, fp) < 1) {
|
||||
fprintf(stderr, "Incorrect write size.\n");
|
||||
fprintf(stderr, "Failed to write to file '%s'.\n", path);
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
@@ -240,69 +298,107 @@ static void usage()
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret, num, i;
|
||||
struct tsv_data *tsv;
|
||||
struct fwinfo *fi;
|
||||
char *buf;
|
||||
long size;
|
||||
char *in = NULL, *out = NULL;
|
||||
enum fw_target target = FW_TARGET_UNKNOWN;
|
||||
struct tsv_data *tsv = NULL;
|
||||
struct fwinfo *fi = NULL;
|
||||
uint8_t *buf = NULL;
|
||||
unsigned long size;
|
||||
uint32_t crc32;
|
||||
|
||||
fprintf(stderr, "fwtool for px4 drivers\n\n");
|
||||
|
||||
if (argc < 3) {
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (argv[i][0] == '-') {
|
||||
if (argv[i][1] == 't') {
|
||||
// target parameter
|
||||
char *t = NULL;
|
||||
|
||||
if (argv[i][2] == '\0') {
|
||||
if ((i + 1) < argc)
|
||||
t = argv[++i];
|
||||
} else {
|
||||
t = &argv[i][2];
|
||||
}
|
||||
|
||||
if (!t)
|
||||
continue;
|
||||
|
||||
parse_fw_target(t, &target);
|
||||
}
|
||||
} else if (!in) {
|
||||
in = argv[i];
|
||||
} else if (!out) {
|
||||
out = argv[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (!in) {
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Driver file: %s\n", argv[1]);
|
||||
fprintf(stderr, "Output file: %s\n\n", argv[2]);
|
||||
if (out && target == FW_TARGET_UNKNOWN)
|
||||
target = FW_TARGET_IT930X;
|
||||
else if (!out && target == FW_TARGET_IT930X)
|
||||
out = "it930x-firmware.bin";
|
||||
|
||||
if (!out || target == FW_TARGET_UNKNOWN) {
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Driver file (in) : %s\n", in);
|
||||
fprintf(stderr, "Firmware file (out) : %s\n\n", out);
|
||||
|
||||
ret = load_tsv_file(&tsv);
|
||||
if (ret) {
|
||||
fprintf(stderr, "Failed to load firmware information file.\n");
|
||||
return 1;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
num = tsv->row_num;
|
||||
|
||||
if (!num) {
|
||||
fprintf(stderr, "No rows in 'fwinfo.tsv'.\n");
|
||||
goto end;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fi = malloc(sizeof(struct fwinfo) * num);
|
||||
fi = (struct fwinfo *)malloc(sizeof(struct fwinfo) * num);
|
||||
if (!fi) {
|
||||
fprintf(stderr, "No enough memory.\n");
|
||||
goto end;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = load_fwinfo(tsv, fi, num);
|
||||
if (ret) {
|
||||
fprintf(stderr, "Failed to load firmware information.\n");
|
||||
goto end2;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = load_file(argv[1], &buf, &size);
|
||||
ret = load_file(in, &buf, &size);
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "Failed to load driver file.\n");
|
||||
goto end2;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
crc32 = crc32_calc(buf, size);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
if (size == fi[i].size && crc32 == fi[i].crc32) {
|
||||
if (target == fi[i].target && size == fi[i].size && crc32 == fi[i].crc32) {
|
||||
fprintf(stderr, "Driver description: %s\n", fi[i].desc);
|
||||
ret = output_firmware(&fi[i], buf, size, argv[2]);
|
||||
if (!ret) {
|
||||
|
||||
ret = output_firmware(&fi[i], buf, size, out);
|
||||
if (!ret)
|
||||
fprintf(stderr, "OK.\n");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= num) {
|
||||
fprintf(stderr, "Unknown driver file.\n");
|
||||
goto end3;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
@@ -311,11 +407,13 @@ int main(int argc, char *argv[])
|
||||
|
||||
return 0;
|
||||
|
||||
end3:
|
||||
free(buf);
|
||||
end2:
|
||||
free(fi);
|
||||
end:
|
||||
fail:
|
||||
if (buf)
|
||||
free(buf);
|
||||
|
||||
if (fi)
|
||||
free(fi);
|
||||
|
||||
tsv_free(tsv);
|
||||
|
||||
return 1;
|
||||
|
144
fwtool/tsv.c
144
fwtool/tsv.c
@@ -1,152 +1,106 @@
|
||||
// tsv.c
|
||||
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "tsv.h"
|
||||
|
||||
int load(const char *buf, size_t buf_len, struct tsv_data *tsv, void *str_pool, size_t *str_poolsize)
|
||||
int load(const uint8_t *buf, size_t buf_len, struct tsv_data *tsv, void *str_pool, size_t *str_poolsize)
|
||||
{
|
||||
const char *p = buf;
|
||||
char *sp = str_pool;
|
||||
size_t l = buf_len, npl = 0, pl = 0;
|
||||
const uint8_t *p = buf;
|
||||
uint8_t *pool_p = (uint8_t *)str_pool;
|
||||
size_t l = buf_len, pool_size = 0, pool_remain = 0;
|
||||
int col_num = 0, row_num = 0;
|
||||
|
||||
if (sp && str_poolsize) {
|
||||
pl = *str_poolsize;
|
||||
}
|
||||
if (pool_p && str_poolsize)
|
||||
pool_remain = *str_poolsize;
|
||||
|
||||
while (l && *p != '\0') {
|
||||
int n = 0; // number of columns (current line)
|
||||
int num = 0; // number of columns (current line)
|
||||
int newline = 0;
|
||||
|
||||
if (*p == '#') {
|
||||
// comment
|
||||
p++;
|
||||
l--;
|
||||
while (l && *p != '\0') {
|
||||
p++;
|
||||
l--;
|
||||
if (*(p - 1) == '\r') {
|
||||
if (l && *p == '\n') {
|
||||
p++;
|
||||
l--;
|
||||
}
|
||||
break;
|
||||
} else if (*(p - 1) == '\n') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
do {
|
||||
const char *pb, *pp = NULL;
|
||||
int quote = 0;
|
||||
|
||||
pb = p;
|
||||
const uint8_t *pb = p, *pp = NULL;
|
||||
|
||||
while(l && *p != '\0') {
|
||||
if (*p == '\t' && !quote) {
|
||||
if (*p == '\t') {
|
||||
// TAB
|
||||
pp = p;
|
||||
while(--l && *++p == '\t')
|
||||
;
|
||||
p++;
|
||||
l--;
|
||||
break;
|
||||
} else if (*p == '\r') {
|
||||
if (quote) {
|
||||
errno = EBADMSG;
|
||||
return -1;
|
||||
}
|
||||
// CR
|
||||
pp = p;
|
||||
p++;
|
||||
l--;
|
||||
newline = 1;
|
||||
if (l && *p == '\n') {
|
||||
// CRLF
|
||||
p++;
|
||||
l--;
|
||||
}
|
||||
break;
|
||||
} else if (*p == '\n') {
|
||||
if (quote) {
|
||||
errno = EBADMSG;
|
||||
return -1;
|
||||
}
|
||||
// LF
|
||||
pp = p;
|
||||
p++;
|
||||
l--;
|
||||
newline = 1;
|
||||
break;
|
||||
} else if (*p == '\"') {
|
||||
quote ^= 1;
|
||||
} else if (*p == '\\') {
|
||||
if (l > 1) {
|
||||
p++;
|
||||
l--;
|
||||
}
|
||||
}
|
||||
p++;
|
||||
l--;
|
||||
}
|
||||
|
||||
if (!pp) {
|
||||
pp = p;
|
||||
}
|
||||
if (pp && pp > pb) {
|
||||
size_t sl = pp - pb + 1;
|
||||
|
||||
if (pp > pb) {
|
||||
size_t sl, plb, slb;
|
||||
if (pool_p) {
|
||||
memcpy(pool_p, pb, sl - 1);
|
||||
pool_p[sl - 1] = '\0';
|
||||
|
||||
sl = pp - pb;
|
||||
if (!col_num)
|
||||
tsv->name[num] = (char *)pool_p;
|
||||
else
|
||||
tsv->field[row_num][num] = (char *)pool_p;
|
||||
|
||||
if (pl) {
|
||||
for (plb = 0, slb = 0; plb < sl; plb++) {
|
||||
if (pb[plb] == '\"') {
|
||||
continue;
|
||||
} else if (pb[plb] == '\\') {
|
||||
if ((plb + 1) < sl) {
|
||||
plb++;
|
||||
}
|
||||
}
|
||||
sp[slb++] = pb[plb];
|
||||
}
|
||||
sp[sl] = '\0';
|
||||
|
||||
if (!col_num) {
|
||||
tsv->name[n] = sp;
|
||||
} else {
|
||||
tsv->field[row_num - 1][n] = sp;
|
||||
}
|
||||
sp += sl + 1;
|
||||
pl -= sl + 1;
|
||||
pool_p += sl;
|
||||
pool_remain -= sl;
|
||||
}
|
||||
npl += sl + 1;
|
||||
n++;
|
||||
}
|
||||
} while(!newline && l && *p != '\0');
|
||||
|
||||
if (n) {
|
||||
pool_size += sl;
|
||||
num++;
|
||||
}
|
||||
} while (!newline && l && *p != '\0');
|
||||
|
||||
if (num) {
|
||||
if (!col_num) {
|
||||
col_num = n;
|
||||
} else if (col_num != n) {
|
||||
errno = EBADMSG;
|
||||
return -1;
|
||||
}
|
||||
// first line
|
||||
col_num = num;
|
||||
} else {
|
||||
if (col_num != num) {
|
||||
errno = EBADMSG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
row_num++;
|
||||
row_num++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tsv->col_num = col_num;
|
||||
tsv->row_num = row_num - 1;
|
||||
tsv->row_num = row_num;
|
||||
|
||||
if (!str_pool && str_poolsize) {
|
||||
*str_poolsize = npl;
|
||||
}
|
||||
if (!str_pool && str_poolsize)
|
||||
*str_poolsize = pool_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tsv_load(const char *buf, size_t len, struct tsv_data **tsv)
|
||||
int tsv_load(const uint8_t *buf, size_t len, struct tsv_data **tsv)
|
||||
{
|
||||
int ret = 0, i;
|
||||
struct tsv_data tsv_tmp, *tsv_ret;
|
||||
@@ -159,16 +113,14 @@ int tsv_load(const char *buf, size_t len, struct tsv_data **tsv)
|
||||
}
|
||||
|
||||
ret = load(buf, len, &tsv_tmp, NULL, &str_poolsize);
|
||||
if (ret) {
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
array_poolsize = /* name */(sizeof(char **) * tsv_tmp.col_num) + /* field */((sizeof(char ***) * tsv_tmp.row_num) + (sizeof(char **) * tsv_tmp.col_num * tsv_tmp.row_num));
|
||||
|
||||
tsv_ret = (struct tsv_data *)malloc(sizeof(*tsv_ret) + array_poolsize + str_poolsize);
|
||||
if (!tsv_ret) {
|
||||
if (!tsv_ret)
|
||||
return -1;
|
||||
}
|
||||
|
||||
pool = (char *)(tsv_ret + 1);
|
||||
|
||||
|
@@ -2,6 +2,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct tsv_data {
|
||||
int col_num;
|
||||
int row_num;
|
||||
@@ -9,5 +11,5 @@ struct tsv_data {
|
||||
char ***field;
|
||||
};
|
||||
|
||||
int tsv_load(const char *buf, size_t len, struct tsv_data **tsv);
|
||||
int tsv_load(const uint8_t *buf, size_t len, struct tsv_data **tsv);
|
||||
void tsv_free(struct tsv_data *tsv);
|
||||
|
@@ -3,6 +3,23 @@
|
||||
#ifndef __PTX_IOCTL_H__
|
||||
#define __PTX_IOCTL_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
// common definitions
|
||||
|
||||
enum ptx_system_type {
|
||||
PTX_UNSPECIFIED_SYSTEM = 0x00000000,
|
||||
PTX_ISDB_T_SYSTEM = 0x00000010,
|
||||
PTX_ISDB_S_SYSTEM = 0x00000020
|
||||
};
|
||||
|
||||
enum ptx_stream_type {
|
||||
PTX_UNSPECIFIED_STREAM = 0x00000000,
|
||||
PTX_MPEG_TRANSPORT_STREAM = 0x00000010 // MPEG2-TS
|
||||
};
|
||||
|
||||
// basic ioctls
|
||||
|
||||
struct ptx_freq {
|
||||
int freq_no;
|
||||
int slot;
|
||||
@@ -14,5 +31,61 @@ struct ptx_freq {
|
||||
#define PTX_GET_CNR _IOR(0x8d, 0x04, int *)
|
||||
#define PTX_ENABLE_LNB_POWER _IOW(0x8d, 0x05, int)
|
||||
#define PTX_DISABLE_LNB_POWER _IO(0x8d, 0x06)
|
||||
#define PTX_SET_SYSTEM_MODE _IOW(0x8d, 0x0b, int)
|
||||
|
||||
// extended ioctls
|
||||
|
||||
struct ptxt_cap {
|
||||
enum ptx_system_type systems;
|
||||
enum ptx_stream_type streams;
|
||||
};
|
||||
|
||||
struct ptxt_info {
|
||||
char name[64];
|
||||
struct ptxt_cap cap; // device capability information
|
||||
};
|
||||
|
||||
enum ptxt_param_code {
|
||||
PTXT_UNDEFINED_PARAM = 0,
|
||||
PTXT_BANDWIDTH_PARAM = 1,
|
||||
PTXT_STREAM_ID_PARAM = 16
|
||||
};
|
||||
|
||||
struct ptxt_additional_param {
|
||||
enum ptxt_param_code prop;
|
||||
__u32 data;
|
||||
};
|
||||
|
||||
struct ptxt_params {
|
||||
enum ptx_system_type system;
|
||||
__u32 freq; // ISDB-T: Hz, ISDB-S/S3: kHz
|
||||
__u32 num_prop;
|
||||
struct ptxt_additional_param *prop;
|
||||
};
|
||||
|
||||
enum ptxt_stat_code {
|
||||
PTXT_UNKNOWN_STAT = 0,
|
||||
PTXT_SIGNAL_STRENGTH_STAT,
|
||||
PTXT_CNR_STAT
|
||||
};
|
||||
|
||||
struct ptxt_stat {
|
||||
enum ptxt_stat_code stat;
|
||||
__u32 value;
|
||||
};
|
||||
|
||||
struct ptxt_stats {
|
||||
__u32 num_stat;
|
||||
struct ptxt_stat *stat;
|
||||
};
|
||||
|
||||
#define PTXT_GET_INFO _IOR(0xe7, 0x00, struct ptxt_info *)
|
||||
#define PTXT_GET_PARAMS _IOR(0xe7, 0x01, struct ptxt_params *)
|
||||
#define PTXT_SET_PARAMS _IOW(0xe7, 0x02, struct ptxt_params *)
|
||||
#define PTXT_CLEAR_PARAMS _IO(0xe7, 0x03)
|
||||
#define PTXT_TUNE _IO(0xe7, 0x04)
|
||||
#define PTXT_SET_LNB_VOLTAGE _IOW(0xe7, 0x05, int)
|
||||
#define PTXT_SET_CAPTURE _IOW(0xe7, 0x06, bool)
|
||||
#define PTXT_READ_STATS _IOR(0xe7, 0x07, struct ptxt_stats *)
|
||||
|
||||
#endif
|
||||
|
29
px4_drv-dkms-mkdeb/Makefile
Normal file
29
px4_drv-dkms-mkdeb/Makefile
Normal file
@@ -0,0 +1,29 @@
|
||||
#/usr/bin/make
|
||||
SRC = $(DESTDIR)/usr/src
|
||||
SHARE = $(DESTDIR)/usr/share/$(NAME)-dkms
|
||||
|
||||
all:
|
||||
|
||||
clean:
|
||||
|
||||
install:
|
||||
|
||||
#source tree
|
||||
ifeq ("$(wildcard $(NAME)-$(VERSION))", "$(NAME)-$(VERSION)")
|
||||
install -d "$(SRC)"
|
||||
cp -a $(NAME)-$(VERSION) $(SRC)
|
||||
#ref: https://github.com/dell/dkms/issues/53#issuecomment-1591788158
|
||||
#chmod 644 -R "$(SRC)/$(NAME)-$(VERSION)"
|
||||
endif
|
||||
|
||||
#tarball, possibly with binaries
|
||||
ifeq ("$(wildcard $(NAME)-$(VERSION).dkms.tar.gz)", "$(NAME)-$(VERSION).dkms.tar.gz")
|
||||
install -d "$(SHARE)"
|
||||
install -m 644 $(NAME)-$(VERSION).dkms.tar.gz "$(SHARE)"
|
||||
endif
|
||||
|
||||
#postinst, only if we are supporting legacy mode
|
||||
ifeq ("$(wildcard common.postinst)", "common.postinst")
|
||||
install -d "$(SHARE)"
|
||||
install -m 755 $(PREFIX)/usr/lib/dkms/common.postinst $(SHARE)/postinst
|
||||
endif
|
5
px4_drv-dkms-mkdeb/debian/README.Debian
Normal file
5
px4_drv-dkms-mkdeb/debian/README.Debian
Normal file
@@ -0,0 +1,5 @@
|
||||
MODULE_NAME DKMS module for Debian
|
||||
|
||||
This package was automatically generated by the DKMS system,
|
||||
for distribution on Debian based operating systems.
|
||||
|
6
px4_drv-dkms-mkdeb/debian/changelog
Normal file
6
px4_drv-dkms-mkdeb/debian/changelog
Normal file
@@ -0,0 +1,6 @@
|
||||
DEBIAN_PACKAGE-dkms (MODULE_VERSION) stable; urgency=low
|
||||
|
||||
* Automatically packaged by DKMS.
|
||||
|
||||
-- Dynamic Kernel Modules Support Team <pkg-dkms-maint@lists.alioth.debian.org> DATE_STAMP
|
||||
|
1
px4_drv-dkms-mkdeb/debian/compat
Normal file
1
px4_drv-dkms-mkdeb/debian/compat
Normal file
@@ -0,0 +1 @@
|
||||
7
|
12
px4_drv-dkms-mkdeb/debian/control
Normal file
12
px4_drv-dkms-mkdeb/debian/control
Normal file
@@ -0,0 +1,12 @@
|
||||
Source: DEBIAN_PACKAGE-dkms
|
||||
Section: misc
|
||||
Priority: optional
|
||||
Maintainer: Dynamic Kernel Modules Support Team <pkg-dkms-maint@lists.alioth.debian.org>
|
||||
Build-Depends: debhelper (>= 7), dkms
|
||||
Standards-Version: 3.8.1
|
||||
|
||||
Package: DEBIAN_PACKAGE-dkms
|
||||
Architecture: DEBIAN_BUILD_ARCH
|
||||
Provides: DEBIAN_PACKAGE-modules (= MODULE_VERSION)
|
||||
Depends: dkms (>= 1.95), ${misc:Depends}
|
||||
Description: DEBIAN_PACKAGE driver in DKMS format.
|
2
px4_drv-dkms-mkdeb/debian/copyright
Normal file
2
px4_drv-dkms-mkdeb/debian/copyright
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
This copyright has not been completed by the author of this package.
|
1
px4_drv-dkms-mkdeb/debian/dirs
Normal file
1
px4_drv-dkms-mkdeb/debian/dirs
Normal file
@@ -0,0 +1 @@
|
||||
usr/src
|
49
px4_drv-dkms-mkdeb/debian/postinst
Executable file
49
px4_drv-dkms-mkdeb/debian/postinst
Executable file
@@ -0,0 +1,49 @@
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2002-2005 Flavio Stanchina
|
||||
# Copyright (C) 2005-2006 Aric Cyr
|
||||
# Copyright (C) 2007 Mario Limonciello
|
||||
# Copyright (C) 2009 Alberto Milone
|
||||
|
||||
set -e
|
||||
|
||||
NAME=MODULE_NAME
|
||||
PACKAGE_NAME=$NAME-dkms
|
||||
DEB_NAME=$(echo $PACKAGE_NAME | sed 's,_,-,')
|
||||
CVERSION=`dpkg-query -W -f='${Version}' $DEB_NAME | awk -F "-" '{print $1}' | cut -d\: -f2`
|
||||
ARCH=`dpkg-architecture -qDEB_BUILD_GNU_CPU`
|
||||
|
||||
dkms_configure () {
|
||||
for POSTINST in /usr/lib/dkms/common.postinst "/usr/share/$PACKAGE_NAME/postinst"; do
|
||||
if [ -f "$POSTINST" ]; then
|
||||
"$POSTINST" "$NAME" "$CVERSION" "/usr/share/$PACKAGE_NAME" "$ARCH" "$2"
|
||||
return $?
|
||||
fi
|
||||
echo "WARNING: $POSTINST does not exist." >&2
|
||||
done
|
||||
echo "ERROR: DKMS version is too old and $PACKAGE_NAME was not" >&2
|
||||
echo "built with legacy DKMS support." >&2
|
||||
echo "You must either rebuild $PACKAGE_NAME with legacy postinst" >&2
|
||||
echo "support or upgrade DKMS to a more current version." >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
configure)
|
||||
dkms_configure
|
||||
;;
|
||||
|
||||
abort-upgrade|abort-remove|abort-deconfigure)
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "postinst called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# dh_installdeb will replace this with shell code automatically
|
||||
# generated by other debhelper scripts.
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
exit 0
|
28
px4_drv-dkms-mkdeb/debian/prerm
Executable file
28
px4_drv-dkms-mkdeb/debian/prerm
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/bin/sh
|
||||
|
||||
NAME=MODULE_NAME
|
||||
VERSION=MODULE_VERSION
|
||||
|
||||
set -e
|
||||
|
||||
case "$1" in
|
||||
remove|upgrade|deconfigure)
|
||||
if [ "`dkms status -m $NAME`" ]; then
|
||||
dkms remove -m $NAME -v $VERSION --all
|
||||
fi
|
||||
;;
|
||||
|
||||
failed-upgrade)
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "prerm called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
exit 0
|
||||
|
||||
|
54
px4_drv-dkms-mkdeb/debian/rules
Executable file
54
px4_drv-dkms-mkdeb/debian/rules
Executable file
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/make -f
|
||||
# -*- makefile -*-
|
||||
|
||||
# Uncomment this to turn on verbose mode.
|
||||
#export DH_VERBOSE=1
|
||||
|
||||
DEB_NAME=DEBIAN_PACKAGE
|
||||
NAME=MODULE_NAME
|
||||
VERSION=MODULE_VERSION
|
||||
|
||||
configure: configure-stamp
|
||||
configure-stamp:
|
||||
dh_testdir
|
||||
touch configure-stamp
|
||||
|
||||
|
||||
build: build-stamp
|
||||
|
||||
build-stamp: configure-stamp
|
||||
dh_testdir
|
||||
$(MAKE)
|
||||
touch $@
|
||||
|
||||
clean:
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
rm -f build-stamp configure-stamp
|
||||
-$(MAKE) clean
|
||||
dh_clean
|
||||
|
||||
install: build
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_prep
|
||||
dh_installdirs
|
||||
$(MAKE) DESTDIR=$(CURDIR)/debian/$(DEB_NAME)-dkms NAME=$(NAME) VERSION=$(VERSION) install
|
||||
|
||||
binary-arch: build install
|
||||
|
||||
binary-indep: build install
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_link
|
||||
dh_strip
|
||||
dh_compress
|
||||
dh_fixperms
|
||||
dh_installdeb
|
||||
dh_shlibdeps
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
|
||||
binary: binary-indep binary-arch
|
||||
.PHONY: build clean binary-indep binary-arch binary install configure
|
39
update_version.sh
Executable file
39
update_version.sh
Executable file
@@ -0,0 +1,39 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
# Check if version argument is provided
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "Usage: $0 <version>"
|
||||
echo "Example: $0 0.5.2"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Remove 'v' prefix if present
|
||||
version=${1//v/}
|
||||
|
||||
cd $(dirname $0)
|
||||
|
||||
# Update version in dkms.conf
|
||||
sed -i -e "s/^PACKAGE_VERSION=.*/PACKAGE_VERSION=\"$version\"/" dkms.conf
|
||||
|
||||
# Update version in driver/driver_module.h
|
||||
sed -i -e "s/^#define\s\s*PX4_DRV_VERSION\s\s*.*/#define PX4_DRV_VERSION \"$version\"/" driver/driver_module.h
|
||||
|
||||
# Update version in winusb/src/BonDriver_PX4/resource.h
|
||||
sed -i -e "s/^#define\s\s*VER_FILE\s\s*.*/#define VER_FILE ${version//./,},0/" winusb/src/BonDriver_PX4/resource.h
|
||||
sed -i -e "s/^#define\s\s*VER_FILE_STR\s\s*.*/#define VER_FILE_STR \"$version\"/" winusb/src/BonDriver_PX4/resource.h
|
||||
sed -i -e "s/^#define\s\s*VER_PRODUCT\s\s*.*/#define VER_PRODUCT ${version//./,},0/" winusb/src/BonDriver_PX4/resource.h
|
||||
sed -i -e "s/^#define\s\s*VER_PRODUCT_STR\s\s*.*/#define VER_PRODUCT_STR \"$version\"/" winusb/src/BonDriver_PX4/resource.h
|
||||
|
||||
# Update version in winusb/src/DriverHost_PX4/resource.h
|
||||
sed -i -e "s/^#define\s\s*VER_FILE\s\s*.*/#define VER_FILE ${version//./,},0/" winusb/src/DriverHost_PX4/resource.h
|
||||
sed -i -e "s/^#define\s\s*VER_FILE_STR\s\s*.*/#define VER_FILE_STR \"$version\"/" winusb/src/DriverHost_PX4/resource.h
|
||||
sed -i -e "s/^#define\s\s*VER_PRODUCT\s\s*.*/#define VER_PRODUCT ${version//./,},0/" winusb/src/DriverHost_PX4/resource.h
|
||||
sed -i -e "s/^#define\s\s*VER_PRODUCT_STR\s\s*.*/#define VER_PRODUCT_STR \"$version\"/" winusb/src/DriverHost_PX4/resource.h
|
||||
|
||||
# Update version in README.md
|
||||
sed -i -e "s/px4-drv-dkms_[0-9]\+\.[0-9]\+\.[0-9]\+_all\.deb/px4-drv-dkms_${version}_all.deb/g" README.md
|
||||
sed -i -e "s/v[0-9]\+\.[0-9]\+\.[0-9]\+/v${version}/g" README.md
|
||||
sed -i -e "s/px4_drv-[0-9]\+\.[0-9]\+\.[0-9]\+/px4_drv-${version}/g" README.md
|
||||
sed -i -e "s/px4_drv\/[0-9]\+\.[0-9]\+\.[0-9]\+/px4_drv\/${version}/g" README.md
|
9
winusb/.gitignore
vendored
Normal file
9
winusb/.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
.vs/
|
||||
build/
|
||||
dist/
|
||||
|
||||
*.aps
|
||||
*.user
|
||||
|
||||
!*.rc
|
||||
!it930x-firmware.bin
|
176
winusb/build.ps1
Normal file
176
winusb/build.ps1
Normal file
@@ -0,0 +1,176 @@
|
||||
|
||||
# カレントディレクトリに移動
|
||||
if ($MyInvocation.MyCommand.Path -ne $null) {
|
||||
$CurrentPath = (Split-Path $MyInvocation.MyCommand.Path -Parent)
|
||||
} else {
|
||||
$CurrentPath = $PSScriptRoot
|
||||
}
|
||||
Set-Location $CurrentPath
|
||||
|
||||
# コンソールウインドウのサイズを変更
|
||||
$ErrorActionPreference = 'Stop' # エラーを確実に catch する
|
||||
try { (Get-Host).UI.RawUI.BufferSize = New-Object System.Management.Automation.Host.Size(120,25) } catch {}
|
||||
try { (Get-Host).UI.RawUI.WindowSize = New-Object System.Management.Automation.Host.Size(120,25) } catch {}
|
||||
|
||||
# MSBuild のパスを環境変数 PATH に追加
|
||||
$msbuild_path = 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin'
|
||||
$env:PATH = "$env:PATH;$msbuild_path"
|
||||
|
||||
# MSBuild を使用してソリューションをビルド
|
||||
msbuild px4_winusb.sln /t:"Rebuild" /p:"Configuration=Release-static;Platform=x86;PlatformToolset=v142"
|
||||
msbuild px4_winusb.sln /t:"Rebuild" /p:"Configuration=Release-static;Platform=x64;PlatformToolset=v142"
|
||||
|
||||
# dist/ フォルダにビルドされたファイルをコピー
|
||||
# フォルダの作成
|
||||
Remove-Item -Recurse -Force dist/ -ErrorAction SilentlyContinue
|
||||
New-Item -ItemType Directory dist/
|
||||
New-Item -ItemType Directory dist/BonDriver_PX4_32bit
|
||||
New-Item -ItemType Directory dist/BonDriver_PX4_64bit
|
||||
New-Item -ItemType Directory dist/BonDriver_PX-MLT_32bit
|
||||
New-Item -ItemType Directory dist/BonDriver_PX-MLT_64bit
|
||||
New-Item -ItemType Directory dist/BonDriver_ISDB2056_32bit
|
||||
New-Item -ItemType Directory dist/BonDriver_ISDB2056_64bit
|
||||
New-Item -ItemType Directory dist/BonDriver_ISDB2056N_32bit
|
||||
New-Item -ItemType Directory dist/BonDriver_ISDB2056N_64bit
|
||||
New-Item -ItemType Directory dist/BonDriver_ISDBT2071_32bit
|
||||
New-Item -ItemType Directory dist/BonDriver_ISDBT2071_64bit
|
||||
New-Item -ItemType Directory dist/BonDriver_PX-M1UR_32bit
|
||||
New-Item -ItemType Directory dist/BonDriver_PX-M1UR_64bit
|
||||
New-Item -ItemType Directory dist/BonDriver_PX-S1UR_32bit
|
||||
New-Item -ItemType Directory dist/BonDriver_PX-S1UR_64bit
|
||||
|
||||
# BonDriver_PX4_32bit のファイルをコピー
|
||||
Copy-Item build/x86/Release-static/BonDriver_PX4.dll dist/BonDriver_PX4_32bit/BonDriver_PX4-T.dll
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX4-T.ini dist/BonDriver_PX4_32bit/BonDriver_PX4-T.ini
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX4-T.ChSet.txt dist/BonDriver_PX4_32bit/BonDriver_PX4-T.ChSet.txt
|
||||
Copy-Item build/x86/Release-static/BonDriver_PX4.dll dist/BonDriver_PX4_32bit/BonDriver_PX4-S.dll
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX4-S.ini dist/BonDriver_PX4_32bit/BonDriver_PX4-S.ini
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX4-S.ChSet.txt dist/BonDriver_PX4_32bit/BonDriver_PX4-S.ChSet.txt
|
||||
Copy-Item build/x86/Release-static/DriverHost_PX4.exe dist/BonDriver_PX4_32bit/DriverHost_PX4.exe
|
||||
Copy-Item pkg/DriverHost_PX4/DriverHost_PX4.ini dist/BonDriver_PX4_32bit/DriverHost_PX4.ini
|
||||
Copy-Item pkg/DriverHost_PX4/it930x-firmware.bin dist/BonDriver_PX4_32bit/it930x-firmware.bin
|
||||
|
||||
# BonDriver_PX4_64bit のファイルをコピー
|
||||
Copy-Item build/x64/Release-static/BonDriver_PX4.dll dist/BonDriver_PX4_64bit/BonDriver_PX4-T.dll
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX4-T.ini dist/BonDriver_PX4_64bit/BonDriver_PX4-T.ini
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX4-T.ChSet.txt dist/BonDriver_PX4_64bit/BonDriver_PX4-T.ChSet.txt
|
||||
Copy-Item build/x64/Release-static/BonDriver_PX4.dll dist/BonDriver_PX4_64bit/BonDriver_PX4-S.dll
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX4-S.ini dist/BonDriver_PX4_64bit/BonDriver_PX4-S.ini
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX4-S.ChSet.txt dist/BonDriver_PX4_64bit/BonDriver_PX4-S.ChSet.txt
|
||||
Copy-Item build/x64/Release-static/DriverHost_PX4.exe dist/BonDriver_PX4_64bit/DriverHost_PX4.exe
|
||||
Copy-Item pkg/DriverHost_PX4/DriverHost_PX4.ini dist/BonDriver_PX4_64bit/DriverHost_PX4.ini
|
||||
Copy-Item pkg/DriverHost_PX4/it930x-firmware.bin dist/BonDriver_PX4_64bit/it930x-firmware.bin
|
||||
|
||||
# BonDriver_PX-MLT_32bit のファイルをコピー
|
||||
Copy-Item build/x86/Release-static/BonDriver_PX4.dll dist/BonDriver_PX-MLT_32bit/BonDriver_PX-MLT.dll
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX-MLT.ini dist/BonDriver_PX-MLT_32bit/BonDriver_PX-MLT.ini
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX4-T.ChSet.txt dist/BonDriver_PX-MLT_32bit/BonDriver_PX4-T.ChSet.txt
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX4-S.ChSet.txt dist/BonDriver_PX-MLT_32bit/BonDriver_PX4-S.ChSet.txt
|
||||
Copy-Item build/x86/Release-static/DriverHost_PX4.exe dist/BonDriver_PX-MLT_32bit/DriverHost_PX4.exe
|
||||
Copy-Item pkg/DriverHost_PX4/DriverHost_PX4.ini dist/BonDriver_PX-MLT_32bit/DriverHost_PX4.ini
|
||||
Copy-Item pkg/DriverHost_PX4/it930x-firmware.bin dist/BonDriver_PX-MLT_32bit/it930x-firmware.bin
|
||||
|
||||
# BonDriver_PX-MLT_64bit のファイルをコピー
|
||||
Copy-Item build/x64/Release-static/BonDriver_PX4.dll dist/BonDriver_PX-MLT_64bit/BonDriver_PX-MLT.dll
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX-MLT.ini dist/BonDriver_PX-MLT_64bit/BonDriver_PX-MLT.ini
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX4-T.ChSet.txt dist/BonDriver_PX-MLT_64bit/BonDriver_PX4-T.ChSet.txt
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX4-S.ChSet.txt dist/BonDriver_PX-MLT_64bit/BonDriver_PX4-S.ChSet.txt
|
||||
Copy-Item build/x64/Release-static/DriverHost_PX4.exe dist/BonDriver_PX-MLT_64bit/DriverHost_PX4.exe
|
||||
Copy-Item pkg/DriverHost_PX4/DriverHost_PX4.ini dist/BonDriver_PX-MLT_64bit/DriverHost_PX4.ini
|
||||
Copy-Item pkg/DriverHost_PX4/it930x-firmware.bin dist/BonDriver_PX-MLT_64bit/it930x-firmware.bin
|
||||
|
||||
# BonDriver_ISDB2056_32bit のファイルをコピー
|
||||
Copy-Item build/x86/Release-static/BonDriver_PX4.dll dist/BonDriver_ISDB2056_32bit/BonDriver_ISDB2056.dll
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_ISDB2056.ini dist/BonDriver_ISDB2056_32bit/BonDriver_ISDB2056.ini
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX4-T.ChSet.txt dist/BonDriver_ISDB2056_32bit/BonDriver_PX4-T.ChSet.txt
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX4-S.ChSet.txt dist/BonDriver_ISDB2056_32bit/BonDriver_PX4-S.ChSet.txt
|
||||
Copy-Item build/x86/Release-static/DriverHost_PX4.exe dist/BonDriver_ISDB2056_32bit/DriverHost_PX4.exe
|
||||
Copy-Item pkg/DriverHost_PX4/DriverHost_PX4.ini dist/BonDriver_ISDB2056_32bit/DriverHost_PX4.ini
|
||||
Copy-Item pkg/DriverHost_PX4/it930x-firmware.bin dist/BonDriver_ISDB2056_32bit/it930x-firmware.bin
|
||||
|
||||
# BonDriver_ISDB2056_64bit のファイルをコピー
|
||||
Copy-Item build/x64/Release-static/BonDriver_PX4.dll dist/BonDriver_ISDB2056_64bit/BonDriver_ISDB2056.dll
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_ISDB2056.ini dist/BonDriver_ISDB2056_64bit/BonDriver_ISDB2056.ini
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX4-T.ChSet.txt dist/BonDriver_ISDB2056_64bit/BonDriver_PX4-T.ChSet.txt
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX4-S.ChSet.txt dist/BonDriver_ISDB2056_64bit/BonDriver_PX4-S.ChSet.txt
|
||||
Copy-Item build/x64/Release-static/DriverHost_PX4.exe dist/BonDriver_ISDB2056_64bit/DriverHost_PX4.exe
|
||||
Copy-Item pkg/DriverHost_PX4/DriverHost_PX4.ini dist/BonDriver_ISDB2056_64bit/DriverHost_PX4.ini
|
||||
Copy-Item pkg/DriverHost_PX4/it930x-firmware.bin dist/BonDriver_ISDB2056_64bit/it930x-firmware.bin
|
||||
|
||||
# BonDriver_ISDB2056N_32bit のファイルをコピー
|
||||
Copy-Item build/x86/Release-static/BonDriver_PX4.dll dist/BonDriver_ISDB2056N_32bit/BonDriver_ISDB2056N.dll
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_ISDB2056N.ini dist/BonDriver_ISDB2056N_32bit/BonDriver_ISDB2056N.ini
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX4-T.ChSet.txt dist/BonDriver_ISDB2056N_32bit/BonDriver_PX4-T.ChSet.txt
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX4-S.ChSet.txt dist/BonDriver_ISDB2056N_32bit/BonDriver_PX4-S.ChSet.txt
|
||||
Copy-Item build/x86/Release-static/DriverHost_PX4.exe dist/BonDriver_ISDB2056N_32bit/DriverHost_PX4.exe
|
||||
Copy-Item pkg/DriverHost_PX4/DriverHost_PX4.ini dist/BonDriver_ISDB2056N_32bit/DriverHost_PX4.ini
|
||||
Copy-Item pkg/DriverHost_PX4/it930x-firmware.bin dist/BonDriver_ISDB2056N_32bit/it930x-firmware.bin
|
||||
|
||||
# BonDriver_ISDB2056N_64bit のファイルをコピー
|
||||
Copy-Item build/x64/Release-static/BonDriver_PX4.dll dist/BonDriver_ISDB2056N_64bit/BonDriver_ISDB2056N.dll
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_ISDB2056N.ini dist/BonDriver_ISDB2056N_64bit/BonDriver_ISDB2056N.ini
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX4-T.ChSet.txt dist/BonDriver_ISDB2056N_64bit/BonDriver_PX4-T.ChSet.txt
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX4-S.ChSet.txt dist/BonDriver_ISDB2056N_64bit/BonDriver_PX4-S.ChSet.txt
|
||||
Copy-Item build/x64/Release-static/DriverHost_PX4.exe dist/BonDriver_ISDB2056N_64bit/DriverHost_PX4.exe
|
||||
Copy-Item pkg/DriverHost_PX4/DriverHost_PX4.ini dist/BonDriver_ISDB2056N_64bit/DriverHost_PX4.ini
|
||||
Copy-Item pkg/DriverHost_PX4/it930x-firmware.bin dist/BonDriver_ISDB2056N_64bit/it930x-firmware.bin
|
||||
|
||||
# BonDriver_PX-M1UR_32bit のファイルをコピー
|
||||
Copy-Item build/x86/Release-static/BonDriver_PX4.dll dist/BonDriver_PX-M1UR_32bit/BonDriver_PX-M1UR.dll
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX-M1UR.ini dist/BonDriver_PX-M1UR_32bit/BonDriver_PX-M1UR.ini
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX4-T.ChSet.txt dist/BonDriver_PX-M1UR_32bit/BonDriver_PX4-T.ChSet.txt
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX4-S.ChSet.txt dist/BonDriver_PX-M1UR_32bit/BonDriver_PX4-S.ChSet.txt
|
||||
Copy-Item build/x86/Release-static/DriverHost_PX4.exe dist/BonDriver_PX-M1UR_32bit/DriverHost_PX4.exe
|
||||
Copy-Item pkg/DriverHost_PX4/DriverHost_PX4.ini dist/BonDriver_PX-M1UR_32bit/DriverHost_PX4.ini
|
||||
Copy-Item pkg/DriverHost_PX4/it930x-firmware.bin dist/BonDriver_PX-M1UR_32bit/it930x-firmware.bin
|
||||
|
||||
# BonDriver_PX-M1UR_64bit のファイルをコピー
|
||||
Copy-Item build/x64/Release-static/BonDriver_PX4.dll dist/BonDriver_PX-M1UR_64bit/BonDriver_PX-M1UR.dll
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX-M1UR.ini dist/BonDriver_PX-M1UR_64bit/BonDriver_PX-M1UR.ini
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX4-T.ChSet.txt dist/BonDriver_PX-M1UR_64bit/BonDriver_PX4-T.ChSet.txt
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX4-S.ChSet.txt dist/BonDriver_PX-M1UR_64bit/BonDriver_PX4-S.ChSet.txt
|
||||
Copy-Item build/x64/Release-static/DriverHost_PX4.exe dist/BonDriver_PX-M1UR_64bit/DriverHost_PX4.exe
|
||||
Copy-Item pkg/DriverHost_PX4/DriverHost_PX4.ini dist/BonDriver_PX-M1UR_64bit/DriverHost_PX4.ini
|
||||
Copy-Item pkg/DriverHost_PX4/it930x-firmware.bin dist/BonDriver_PX-M1UR_64bit/it930x-firmware.bin
|
||||
|
||||
# BonDriver_ISDBT2071_32bit のファイルをコピー
|
||||
Copy-Item build/x86/Release-static/BonDriver_PX4.dll dist/BonDriver_ISDBT2071_32bit/BonDriver_ISDBT2071.dll
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_ISDBT2071.ini dist/BonDriver_ISDBT2071_32bit/BonDriver_ISDBT2071.ini
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX4-T.ChSet.txt dist/BonDriver_ISDBT2071_32bit/BonDriver_PX4-T.ChSet.txt
|
||||
Copy-Item build/x86/Release-static/DriverHost_PX4.exe dist/BonDriver_ISDBT2071_32bit/DriverHost_PX4.exe
|
||||
Copy-Item pkg/DriverHost_PX4/DriverHost_PX4.ini dist/BonDriver_ISDBT2071_32bit/DriverHost_PX4.ini
|
||||
Copy-Item pkg/DriverHost_PX4/it930x-firmware.bin dist/BonDriver_ISDBT2071_32bit/it930x-firmware.bin
|
||||
|
||||
# BonDriver_ISDBT2071_64bit のファイルをコピー
|
||||
Copy-Item build/x64/Release-static/BonDriver_PX4.dll dist/BonDriver_ISDBT2071_64bit/BonDriver_ISDBT2071.dll
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_ISDBT2071.ini dist/BonDriver_ISDBT2071_64bit/BonDriver_ISDBT2071.ini
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX4-T.ChSet.txt dist/BonDriver_ISDBT2071_64bit/BonDriver_PX4-T.ChSet.txt
|
||||
Copy-Item build/x64/Release-static/DriverHost_PX4.exe dist/BonDriver_ISDBT2071_64bit/DriverHost_PX4.exe
|
||||
Copy-Item pkg/DriverHost_PX4/DriverHost_PX4.ini dist/BonDriver_ISDBT2071_64bit/DriverHost_PX4.ini
|
||||
Copy-Item pkg/DriverHost_PX4/it930x-firmware.bin dist/BonDriver_ISDBT2071_64bit/it930x-firmware.bin
|
||||
|
||||
# BonDriver_PX-S1UR_32bit のファイルをコピー
|
||||
Copy-Item build/x86/Release-static/BonDriver_PX4.dll dist/BonDriver_PX-S1UR_32bit/BonDriver_PX-S1UR.dll
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX-S1UR.ini dist/BonDriver_PX-S1UR_32bit/BonDriver_PX-S1UR.ini
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX4-T.ChSet.txt dist/BonDriver_PX-S1UR_32bit/BonDriver_PX4-T.ChSet.txt
|
||||
Copy-Item build/x86/Release-static/DriverHost_PX4.exe dist/BonDriver_PX-S1UR_32bit/DriverHost_PX4.exe
|
||||
Copy-Item pkg/DriverHost_PX4/DriverHost_PX4.ini dist/BonDriver_PX-S1UR_32bit/DriverHost_PX4.ini
|
||||
Copy-Item pkg/DriverHost_PX4/it930x-firmware.bin dist/BonDriver_PX-S1UR_32bit/it930x-firmware.bin
|
||||
|
||||
# BonDriver_PX-S1UR_64bit のファイルをコピー
|
||||
Copy-Item build/x64/Release-static/BonDriver_PX4.dll dist/BonDriver_PX-S1UR_64bit/BonDriver_PX-S1UR.dll
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX-S1UR.ini dist/BonDriver_PX-S1UR_64bit/BonDriver_PX-S1UR.ini
|
||||
Copy-Item pkg/BonDriver_PX4/BonDriver_PX4-T.ChSet.txt dist/BonDriver_PX-S1UR_64bit/BonDriver_PX4-T.ChSet.txt
|
||||
Copy-Item build/x64/Release-static/DriverHost_PX4.exe dist/BonDriver_PX-S1UR_64bit/DriverHost_PX4.exe
|
||||
Copy-Item pkg/DriverHost_PX4/DriverHost_PX4.ini dist/BonDriver_PX-S1UR_64bit/DriverHost_PX4.ini
|
||||
Copy-Item pkg/DriverHost_PX4/it930x-firmware.bin dist/BonDriver_PX-S1UR_64bit/it930x-firmware.bin
|
||||
|
||||
# inf ファイルをコピー
|
||||
Copy-Item -Recurse pkg/inf/ dist/Driver
|
||||
|
||||
Write-Host ' '
|
||||
Write-Host ' '
|
||||
Write-Host ' BonDriver のビルドとパッケージングを完了しました。'
|
||||
Write-Host ' ビルドしたファイルは dist/ フォルダに配置されています。'
|
||||
Write-Host ' '
|
||||
Start-Sleep -Seconds 5
|
39
winusb/include/IBonDriver.h
Normal file
39
winusb/include/IBonDriver.h
Normal file
@@ -0,0 +1,39 @@
|
||||
// IBonDriver.h: IBonDriver <20>N<EFBFBD><4E><EFBFBD>X<EFBFBD>̃C<CC83><43><EFBFBD>^<5E>[<5B>t<EFBFBD>F<EFBFBD>C<EFBFBD>X
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(_IBONDRIVER_H_)
|
||||
#define _IBONDRIVER_H_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
|
||||
// <20>}<7D>h<EFBFBD><68><EFBFBD>C<EFBFBD>o<EFBFBD>C<EFBFBD><43><EFBFBD>^<5E>t<EFBFBD>F<EFBFBD>[<5B>X
|
||||
class IBonDriver
|
||||
{
|
||||
public:
|
||||
virtual const BOOL OpenTuner(void) = 0;
|
||||
virtual void CloseTuner(void) = 0;
|
||||
|
||||
virtual const BOOL SetChannel(const BYTE bCh) = 0;
|
||||
virtual const float GetSignalLevel(void) = 0;
|
||||
|
||||
virtual const DWORD WaitTsStream(const DWORD dwTimeOut = 0) = 0;
|
||||
virtual const DWORD GetReadyCount(void) = 0;
|
||||
|
||||
virtual const BOOL GetTsStream(BYTE *pDst, DWORD *pdwSize, DWORD *pdwRemain) = 0;
|
||||
virtual const BOOL GetTsStream(BYTE **ppDst, DWORD *pdwSize, DWORD *pdwRemain) = 0;
|
||||
|
||||
virtual void PurgeTsStream(void) = 0;
|
||||
|
||||
virtual void Release(void) = 0;
|
||||
};
|
||||
|
||||
|
||||
// <20>C<EFBFBD><43><EFBFBD>X<EFBFBD>^<5E><><EFBFBD>X<EFBFBD><58><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\<5C>b<EFBFBD>h
|
||||
extern "C" __declspec(dllimport) IBonDriver * CreateBonDriver();
|
||||
|
||||
|
||||
#endif // !defined(_IBONDRIVER_H_)
|
36
winusb/include/IBonDriver2.h
Normal file
36
winusb/include/IBonDriver2.h
Normal file
@@ -0,0 +1,36 @@
|
||||
// IBonDriver2.h: IBonDriver2 <20>N<EFBFBD><4E><EFBFBD>X<EFBFBD>̃C<CC83><43><EFBFBD>^<5E>[<5B>t<EFBFBD>F<EFBFBD>C<EFBFBD>X
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(_IBONDRIVER2_H_)
|
||||
#define _IBONDRIVER2_H_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
|
||||
#include "IBonDriver.h"
|
||||
|
||||
|
||||
// <20>}<7D>h<EFBFBD><68><EFBFBD>C<EFBFBD>o<EFBFBD>C<EFBFBD><43><EFBFBD>^<5E>t<EFBFBD>F<EFBFBD>[<5B>X2
|
||||
class IBonDriver2 : public IBonDriver
|
||||
{
|
||||
public:
|
||||
virtual LPCTSTR GetTunerName(void) = 0;
|
||||
|
||||
virtual const BOOL IsTunerOpening(void) = 0;
|
||||
|
||||
virtual LPCTSTR EnumTuningSpace(const DWORD dwSpace) = 0;
|
||||
virtual LPCTSTR EnumChannelName(const DWORD dwSpace, const DWORD dwChannel) = 0;
|
||||
|
||||
virtual const BOOL SetChannel(const DWORD dwSpace, const DWORD dwChannel) = 0;
|
||||
|
||||
virtual const DWORD GetCurSpace(void) = 0;
|
||||
virtual const DWORD GetCurChannel(void) = 0;
|
||||
|
||||
// IBonDriver
|
||||
virtual void Release(void) = 0;
|
||||
};
|
||||
|
||||
#endif // !defined(_IBONDRIVER2_H_)
|
23
winusb/pkg/BonDriver_PX4/BonDriver_ISDB2056.ini
Normal file
23
winusb/pkg/BonDriver_PX4/BonDriver_ISDB2056.ini
Normal file
@@ -0,0 +1,23 @@
|
||||
[BonDriver]
|
||||
Name="ISDB2056"
|
||||
System="ISDB-T,ISDB-S"
|
||||
DriverHostPath=".\DriverHost_PX4.exe"
|
||||
PipeConnectTimeout=1000
|
||||
TuneTimeout=5000
|
||||
NumberOfPacketsPerBuffer=1024
|
||||
MaximumNumberOfBuffers=64
|
||||
MinimumNumberOfBuffers=4
|
||||
NumberOfBuffersToIgnoreAfterPurge=1
|
||||
DisplayErrorMessage=0
|
||||
|
||||
[BonDriver.ISDB-T]
|
||||
ChSetPath="BonDriver_PX4-T.ChSet.txt"
|
||||
|
||||
[BonDriver.ISDB-S]
|
||||
ChSetPath="BonDriver_PX4-S.ChSet.txt"
|
||||
LNBPower=0
|
||||
|
||||
[ReceiverDefinition0]
|
||||
DeviceName="Digibest ISDB2056"
|
||||
DeviceGUID="{5d04b1e3-6063-4bdd-87ce-64b916aa4180}"
|
||||
System="ISDB-T,ISDB-S"
|
23
winusb/pkg/BonDriver_PX4/BonDriver_ISDB2056N.ini
Normal file
23
winusb/pkg/BonDriver_PX4/BonDriver_ISDB2056N.ini
Normal file
@@ -0,0 +1,23 @@
|
||||
[BonDriver]
|
||||
Name="ISDB2056N"
|
||||
System="ISDB-T,ISDB-S"
|
||||
DriverHostPath=".\DriverHost_PX4.exe"
|
||||
PipeConnectTimeout=1000
|
||||
TuneTimeout=5000
|
||||
NumberOfPacketsPerBuffer=1024
|
||||
MaximumNumberOfBuffers=64
|
||||
MinimumNumberOfBuffers=4
|
||||
NumberOfBuffersToIgnoreAfterPurge=1
|
||||
DisplayErrorMessage=0
|
||||
|
||||
[BonDriver.ISDB-T]
|
||||
ChSetPath="BonDriver_PX4-T.ChSet.txt"
|
||||
|
||||
[BonDriver.ISDB-S]
|
||||
ChSetPath="BonDriver_PX4-S.ChSet.txt"
|
||||
LNBPower=0
|
||||
|
||||
[ReceiverDefinition0]
|
||||
DeviceName="Digibest ISDB2056N"
|
||||
DeviceGUID="{c29c6ef9-6321-470d-bbc9-ae4358e4c6b1}"
|
||||
System="ISDB-T,ISDB-S"
|
19
winusb/pkg/BonDriver_PX4/BonDriver_ISDBT2071.ini
Normal file
19
winusb/pkg/BonDriver_PX4/BonDriver_ISDBT2071.ini
Normal file
@@ -0,0 +1,19 @@
|
||||
[BonDriver]
|
||||
Name="ISDBT2071"
|
||||
System="ISDB-T"
|
||||
DriverHostPath=".\DriverHost_PX4.exe"
|
||||
PipeConnectTimeout=1000
|
||||
TuneTimeout=5000
|
||||
NumberOfPacketsPerBuffer=1024
|
||||
MaximumNumberOfBuffers=64
|
||||
MinimumNumberOfBuffers=4
|
||||
NumberOfBuffersToIgnoreAfterPurge=1
|
||||
DisplayErrorMessage=0
|
||||
|
||||
[BonDriver.ISDB-T]
|
||||
ChSetPath="BonDriver_PX4-T.ChSet.txt"
|
||||
|
||||
[ReceiverDefinition0]
|
||||
DeviceName="Digibest ISDBT2071"
|
||||
DeviceGUID="{3dff00b8-b3f4-41ee-9d68-5e458143086e}"
|
||||
System="ISDB-T"
|
23
winusb/pkg/BonDriver_PX4/BonDriver_PX-M1UR.ini
Normal file
23
winusb/pkg/BonDriver_PX4/BonDriver_PX-M1UR.ini
Normal file
@@ -0,0 +1,23 @@
|
||||
[BonDriver]
|
||||
Name="PX-M1UR"
|
||||
System="ISDB-T,ISDB-S"
|
||||
DriverHostPath=".\DriverHost_PX4.exe"
|
||||
PipeConnectTimeout=1000
|
||||
TuneTimeout=5000
|
||||
NumberOfPacketsPerBuffer=1024
|
||||
MaximumNumberOfBuffers=64
|
||||
MinimumNumberOfBuffers=4
|
||||
NumberOfBuffersToIgnoreAfterPurge=1
|
||||
DisplayErrorMessage=0
|
||||
|
||||
[BonDriver.ISDB-T]
|
||||
ChSetPath="BonDriver_PX4-T.ChSet.txt"
|
||||
|
||||
[BonDriver.ISDB-S]
|
||||
ChSetPath="BonDriver_PX4-S.ChSet.txt"
|
||||
LNBPower=0
|
||||
|
||||
[ReceiverDefinition0]
|
||||
DeviceName="PLEX PX-M1UR"
|
||||
DeviceGUID="{a3c9bf85-13fe-465c-9a33-22441975c190}"
|
||||
System="ISDB-T,ISDB-S"
|
38
winusb/pkg/BonDriver_PX4/BonDriver_PX-MLT.ini
Normal file
38
winusb/pkg/BonDriver_PX4/BonDriver_PX-MLT.ini
Normal file
@@ -0,0 +1,38 @@
|
||||
[BonDriver]
|
||||
Name="PX-MLT"
|
||||
System="ISDB-T,ISDB-S"
|
||||
DriverHostPath=".\DriverHost_PX4.exe"
|
||||
PipeConnectTimeout=1000
|
||||
TuneTimeout=5000
|
||||
NumberOfPacketsPerBuffer=1024
|
||||
MaximumNumberOfBuffers=64
|
||||
MinimumNumberOfBuffers=4
|
||||
NumberOfBuffersToIgnoreAfterPurge=1
|
||||
DisplayErrorMessage=0
|
||||
|
||||
[BonDriver.ISDB-T]
|
||||
ChSetPath="BonDriver_PX4-T.ChSet.txt"
|
||||
|
||||
[BonDriver.ISDB-S]
|
||||
ChSetPath="BonDriver_PX4-S.ChSet.txt"
|
||||
LNBPower=0
|
||||
|
||||
[ReceiverDefinition0]
|
||||
DeviceName="PLEX PX-MLT5PE"
|
||||
DeviceGUID="{b4eeca78-7c7f-423e-8ab8-305416d1c4f2}"
|
||||
System="ISDB-T,ISDB-S"
|
||||
|
||||
[ReceiverDefinition1]
|
||||
DeviceName="PLEX PX-MLT8PE3"
|
||||
DeviceGUID="{a6a02476-1ba2-4686-84ec-c7aa2b045267}"
|
||||
System="ISDB-T,ISDB-S"
|
||||
|
||||
[ReceiverDefinition2]
|
||||
DeviceName="PLEX PX-MLT8PE5"
|
||||
DeviceGUID="{7de16cba-9609-432a-83bf-bc14ba785152}"
|
||||
System="ISDB-T,ISDB-S"
|
||||
|
||||
[ReceiverDefinition3]
|
||||
DeviceName="Digibest ISDB6014"
|
||||
DeviceGUID="{1fbeec9a-a12c-4262-8d33-134966ba7ff4}"
|
||||
System="ISDB-T,ISDB-S"
|
19
winusb/pkg/BonDriver_PX4/BonDriver_PX-S1UR.ini
Normal file
19
winusb/pkg/BonDriver_PX4/BonDriver_PX-S1UR.ini
Normal file
@@ -0,0 +1,19 @@
|
||||
[BonDriver]
|
||||
Name="PX-S1UR"
|
||||
System="ISDB-T"
|
||||
DriverHostPath=".\DriverHost_PX4.exe"
|
||||
PipeConnectTimeout=1000
|
||||
TuneTimeout=5000
|
||||
NumberOfPacketsPerBuffer=1024
|
||||
MaximumNumberOfBuffers=64
|
||||
MinimumNumberOfBuffers=4
|
||||
NumberOfBuffersToIgnoreAfterPurge=1
|
||||
DisplayErrorMessage=0
|
||||
|
||||
[BonDriver.ISDB-T]
|
||||
ChSetPath="BonDriver_PX4-T.ChSet.txt"
|
||||
|
||||
[ReceiverDefinition0]
|
||||
DeviceName="PLEX PX-S1UR"
|
||||
DeviceGUID="{bf4454d8-63c4-4a97-ae0d-19329c4da997}"
|
||||
System="ISDB-T"
|
49
winusb/pkg/BonDriver_PX4/BonDriver_PX4-S.ChSet.txt
Normal file
49
winusb/pkg/BonDriver_PX4/BonDriver_PX4-S.ChSet.txt
Normal file
@@ -0,0 +1,49 @@
|
||||
;
|
||||
; BonDriver_PX4 チャンネル定義ファイル (ISDB-S) (日本における衛星波デジタル放送用)
|
||||
; (BonDriver_PT3-STのChSet.txtと互換性あり)
|
||||
;
|
||||
; チャンネル空間定義 ($チャンネル空間名<TAB>チャンネル空間ID)
|
||||
$BS 0
|
||||
$CS110 1
|
||||
;
|
||||
; チャンネル定義 (チャンネル名<TAB>チャンネル空間ID<TAB>チャンネルID<TAB>PTX内部チャンネルID<TAB>TSID(ISDB-S用))
|
||||
; [BS]
|
||||
BS01/TS0 0 0 0 16400
|
||||
BS01/TS1 0 1 0 16401
|
||||
BS01/TS2 0 2 0 16402
|
||||
BS03/TS0 0 3 1 16432
|
||||
BS03/TS1 0 4 1 17969
|
||||
BS03/TS2 0 5 1 17970
|
||||
BS05/TS0 0 6 2 17488
|
||||
BS05/TS1 0 7 2 17489
|
||||
BS09/TS0 0 8 4 16528
|
||||
BS09/TS1 0 9 4 16530
|
||||
BS13/TS0 0 10 6 16592
|
||||
BS13/TS1 0 11 6 16593
|
||||
BS13/TS2 0 12 6 18130
|
||||
BS15/TS0 0 13 7 16625
|
||||
BS15/TS1 0 14 7 16626
|
||||
BS15/TS2 0 15 7 18675
|
||||
BS19/TS0 0 16 9 18224
|
||||
BS19/TS1 0 17 9 18225
|
||||
BS19/TS2 0 18 9 18226
|
||||
BS19/TS3 0 19 9 18227
|
||||
BS21/TS0 0 20 10 18256
|
||||
BS21/TS1 0 21 10 18257
|
||||
BS21/TS2 0 22 10 18258
|
||||
BS23/TS0 0 23 11 18288
|
||||
BS23/TS1 0 24 11 18801
|
||||
BS23/TS2 0 25 11 18803
|
||||
; [CS]
|
||||
ND02 1 0 12 24608
|
||||
ND04 1 1 13 28736
|
||||
ND06 1 2 14 28768
|
||||
ND08 1 3 15 24704
|
||||
ND10 1 4 16 24736
|
||||
ND12 1 5 17 28864
|
||||
ND14 1 6 18 28896
|
||||
ND16 1 7 19 28928
|
||||
ND18 1 8 20 28960
|
||||
ND20 1 9 21 28992
|
||||
ND22 1 10 22 29024
|
||||
ND24 1 11 23 29056
|
45
winusb/pkg/BonDriver_PX4/BonDriver_PX4-S.ini
Normal file
45
winusb/pkg/BonDriver_PX4/BonDriver_PX4-S.ini
Normal file
@@ -0,0 +1,45 @@
|
||||
[BonDriver]
|
||||
Name="PX4 (ISDB-S)"
|
||||
System="ISDB-S"
|
||||
DriverHostPath=".\DriverHost_PX4.exe"
|
||||
PipeConnectTimeout=1000
|
||||
TuneTimeout=5000
|
||||
NumberOfPacketsPerBuffer=1024
|
||||
MaximumNumberOfBuffers=64
|
||||
MinimumNumberOfBuffers=4
|
||||
NumberOfBuffersToIgnoreAfterPurge=0
|
||||
DisplayErrorMessage=0
|
||||
|
||||
[BonDriver.ISDB-S]
|
||||
ChSetPath="BonDriver_PX4-S.ChSet.txt"
|
||||
LNBPower=0
|
||||
|
||||
[ReceiverDefinition0]
|
||||
DeviceName="PLEX PX-W3U4"
|
||||
DeviceGUID="{aa8de3fc-004d-49a4-b976-4250f15a976d}"
|
||||
System="ISDB-S"
|
||||
|
||||
[ReceiverDefinition1]
|
||||
DeviceName="PLEX PX-Q3U4"
|
||||
DeviceGUID="{3c612a36-81dd-4509-b5f7-63594f84f859}"
|
||||
System="ISDB-S"
|
||||
|
||||
[ReceiverDefinition2]
|
||||
DeviceName="PLEX PX-W3PE4"
|
||||
DeviceGUID="{e231e39e-4823-41ff-ab71-f95bf6785ffc}"
|
||||
System="ISDB-S"
|
||||
|
||||
[ReceiverDefinition3]
|
||||
DeviceName="PLEX PX-Q3PE4"
|
||||
DeviceGUID="{89698252-64e8-414a-9e7a-5485f36eef0f}"
|
||||
System="ISDB-S"
|
||||
|
||||
[ReceiverDefinition4]
|
||||
DeviceName="PLEX PX-W3PE5"
|
||||
DeviceGUID="{23937228-f21a-4ac5-a8f6-76b0bc4bc453}"
|
||||
System="ISDB-S"
|
||||
|
||||
[ReceiverDefinition5]
|
||||
DeviceName="PLEX PX-Q3PE5"
|
||||
DeviceGUID="{1c32a5d6-70ad-469e-9a90-5a8d5880082b}"
|
||||
System="ISDB-S"
|
112
winusb/pkg/BonDriver_PX4/BonDriver_PX4-T.ChSet.txt
Normal file
112
winusb/pkg/BonDriver_PX4/BonDriver_PX4-T.ChSet.txt
Normal file
@@ -0,0 +1,112 @@
|
||||
;
|
||||
; BonDriver_PX4 <20>`<60><><EFBFBD><EFBFBD><EFBFBD>l<EFBFBD><6C><EFBFBD><EFBFBD><EFBFBD>`<60>t<EFBFBD>@<40>C<EFBFBD><43> (ISDB-T) (<28><><EFBFBD>{<7B>ɂ<EFBFBD><C982><EFBFBD><EFBFBD><EFBFBD><EFBFBD>n<EFBFBD><6E><EFBFBD>g<EFBFBD>f<EFBFBD>W<EFBFBD>^<5E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>p)
|
||||
; (BonDriver_PT3-ST<53><54>ChSet.txt<78>ƌ݊<C68C><DD8A><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
||||
;
|
||||
; <20>`<60><><EFBFBD><EFBFBD><EFBFBD>l<EFBFBD><6C><EFBFBD><EFBFBD><EFBFBD>Ԓ<EFBFBD><D492>` ($<24>`<60><><EFBFBD><EFBFBD><EFBFBD>l<EFBFBD><6C><EFBFBD><EFBFBD><EFBFBD>Ԗ<EFBFBD><TAB><3E>`<60><><EFBFBD><EFBFBD><EFBFBD>l<EFBFBD><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ID)
|
||||
$<24>n<EFBFBD>f<EFBFBD>W(UHF) 0
|
||||
;$<24>n<EFBFBD>f<EFBFBD>W(CATV) 1
|
||||
;
|
||||
; <20>`<60><><EFBFBD><EFBFBD><EFBFBD>l<EFBFBD><6C><EFBFBD><EFBFBD><EFBFBD>` (<28>`<60><><EFBFBD><EFBFBD><EFBFBD>l<EFBFBD><6C><EFBFBD><EFBFBD><TAB><3E>`<60><><EFBFBD><EFBFBD><EFBFBD>l<EFBFBD><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ID<TAB><3E>`<60><><EFBFBD><EFBFBD><EFBFBD>l<EFBFBD><6C>ID<TAB>PTX<54><58><EFBFBD><EFBFBD><EFBFBD>`<60><><EFBFBD><EFBFBD><EFBFBD>l<EFBFBD><6C>ID<TAB>TSID(ISDB-S<>p))
|
||||
; [<5B>n<EFBFBD>f<EFBFBD>W(UHF)]
|
||||
13Ch 0 0 63 0
|
||||
14Ch 0 1 64 0
|
||||
15Ch 0 2 65 0
|
||||
16Ch 0 3 66 0
|
||||
17Ch 0 4 67 0
|
||||
18Ch 0 5 68 0
|
||||
19Ch 0 6 69 0
|
||||
20Ch 0 7 70 0
|
||||
21Ch 0 8 71 0
|
||||
22Ch 0 9 72 0
|
||||
23Ch 0 10 73 0
|
||||
24Ch 0 11 74 0
|
||||
25Ch 0 12 75 0
|
||||
26Ch 0 13 76 0
|
||||
27Ch 0 14 77 0
|
||||
28Ch 0 15 78 0
|
||||
29Ch 0 16 79 0
|
||||
30Ch 0 17 80 0
|
||||
31Ch 0 18 81 0
|
||||
32Ch 0 19 82 0
|
||||
33Ch 0 20 83 0
|
||||
34Ch 0 21 84 0
|
||||
35Ch 0 22 85 0
|
||||
36Ch 0 23 86 0
|
||||
37Ch 0 24 87 0
|
||||
38Ch 0 25 88 0
|
||||
39Ch 0 26 89 0
|
||||
40Ch 0 27 90 0
|
||||
41Ch 0 28 91 0
|
||||
42Ch 0 29 92 0
|
||||
43Ch 0 30 93 0
|
||||
44Ch 0 31 94 0
|
||||
45Ch 0 32 95 0
|
||||
46Ch 0 33 96 0
|
||||
47Ch 0 34 97 0
|
||||
48Ch 0 35 98 0
|
||||
49Ch 0 36 99 0
|
||||
50Ch 0 37 100 0
|
||||
51Ch 0 38 101 0
|
||||
52Ch 0 39 102 0
|
||||
53Ch 0 40 103 0
|
||||
54Ch 0 41 104 0
|
||||
55Ch 0 42 105 0
|
||||
56Ch 0 43 106 0
|
||||
57Ch 0 44 107 0
|
||||
58Ch 0 45 108 0
|
||||
59Ch 0 46 109 0
|
||||
60Ch 0 47 110 0
|
||||
61Ch 0 48 111 0
|
||||
62Ch 0 49 112 0
|
||||
; [<5B>n<EFBFBD>f<EFBFBD>W(CATV)]
|
||||
C13Ch 1 0 3 0
|
||||
C14Ch 1 1 4 0
|
||||
C15Ch 1 2 5 0
|
||||
C16Ch 1 3 6 0
|
||||
C17Ch 1 4 7 0
|
||||
C18Ch 1 5 8 0
|
||||
C19Ch 1 6 9 0
|
||||
C20Ch 1 7 10 0
|
||||
C21Ch 1 8 11 0
|
||||
C22Ch 1 9 12 0
|
||||
C23Ch 1 10 22 0
|
||||
C24Ch 1 11 23 0
|
||||
C25Ch 1 12 24 0
|
||||
C26Ch 1 13 25 0
|
||||
C27Ch 1 14 26 0
|
||||
C28Ch 1 15 27 0
|
||||
C29Ch 1 16 28 0
|
||||
C30Ch 1 17 29 0
|
||||
C31Ch 1 18 30 0
|
||||
C32Ch 1 19 31 0
|
||||
C33Ch 1 20 32 0
|
||||
C34Ch 1 21 33 0
|
||||
C35Ch 1 22 34 0
|
||||
C36Ch 1 23 35 0
|
||||
C37Ch 1 24 36 0
|
||||
C38Ch 1 25 37 0
|
||||
C39Ch 1 26 38 0
|
||||
C40Ch 1 27 39 0
|
||||
C41Ch 1 28 40 0
|
||||
C42Ch 1 29 41 0
|
||||
C43Ch 1 30 42 0
|
||||
C44Ch 1 31 43 0
|
||||
C45Ch 1 32 44 0
|
||||
C46Ch 1 33 45 0
|
||||
C47Ch 1 34 46 0
|
||||
C48Ch 1 35 47 0
|
||||
C49Ch 1 36 48 0
|
||||
C50Ch 1 37 49 0
|
||||
C51Ch 1 38 50 0
|
||||
C52Ch 1 39 51 0
|
||||
C53Ch 1 40 52 0
|
||||
C54Ch 1 41 53 0
|
||||
C55Ch 1 42 54 0
|
||||
C56Ch 1 43 55 0
|
||||
C57Ch 1 44 56 0
|
||||
C58Ch 1 45 57 0
|
||||
C59Ch 1 46 58 0
|
||||
C60Ch 1 47 59 0
|
||||
C61Ch 1 48 60 0
|
||||
C62Ch 1 49 61 0
|
||||
C63Ch 1 50 62 0
|
44
winusb/pkg/BonDriver_PX4/BonDriver_PX4-T.ini
Normal file
44
winusb/pkg/BonDriver_PX4/BonDriver_PX4-T.ini
Normal file
@@ -0,0 +1,44 @@
|
||||
[BonDriver]
|
||||
Name="PX4 (ISDB-T)"
|
||||
System="ISDB-T"
|
||||
DriverHostPath=".\DriverHost_PX4.exe"
|
||||
PipeConnectTimeout=1000
|
||||
TuneTimeout=5000
|
||||
NumberOfPacketsPerBuffer=1024
|
||||
MaximumNumberOfBuffers=64
|
||||
MinimumNumberOfBuffers=4
|
||||
NumberOfBuffersToIgnoreAfterPurge=0
|
||||
DisplayErrorMessage=0
|
||||
|
||||
[BonDriver.ISDB-T]
|
||||
ChSetPath="BonDriver_PX4-T.ChSet.txt"
|
||||
|
||||
[ReceiverDefinition0]
|
||||
DeviceName="PLEX PX-W3U4"
|
||||
DeviceGUID="{aa8de3fc-004d-49a4-b976-4250f15a976d}"
|
||||
System="ISDB-T"
|
||||
|
||||
[ReceiverDefinition1]
|
||||
DeviceName="PLEX PX-Q3U4"
|
||||
DeviceGUID="{3c612a36-81dd-4509-b5f7-63594f84f859}"
|
||||
System="ISDB-T"
|
||||
|
||||
[ReceiverDefinition2]
|
||||
DeviceName="PLEX PX-W3PE4"
|
||||
DeviceGUID="{e231e39e-4823-41ff-ab71-f95bf6785ffc}"
|
||||
System="ISDB-T"
|
||||
|
||||
[ReceiverDefinition3]
|
||||
DeviceName="PLEX PX-Q3PE4"
|
||||
DeviceGUID="{89698252-64e8-414a-9e7a-5485f36eef0f}"
|
||||
System="ISDB-T"
|
||||
|
||||
[ReceiverDefinition4]
|
||||
DeviceName="PLEX PX-W3PE5"
|
||||
DeviceGUID="{23937228-f21a-4ac5-a8f6-76b0bc4bc453}"
|
||||
System="ISDB-T"
|
||||
|
||||
[ReceiverDefinition5]
|
||||
DeviceName="PLEX PX-Q3PE5"
|
||||
DeviceGUID="{1c32a5d6-70ad-469e-9a90-5a8d5880082b}"
|
||||
System="ISDB-T"
|
508
winusb/pkg/DriverHost_PX4/DriverHost_PX4.ini
Normal file
508
winusb/pkg/DriverHost_PX4/DriverHost_PX4.ini
Normal file
@@ -0,0 +1,508 @@
|
||||
[DriverHost_PX4]
|
||||
PipeTimeout=5000
|
||||
|
||||
[DeviceDefinition0]
|
||||
Name="PLEX PX-W3U4"
|
||||
GUID="{aa8de3fc-004d-49a4-b976-4250f15a976d}"
|
||||
Type="PX4"
|
||||
DeviceInterfaceGUID="{6d78c843-49d8-4bb8-8dfa-286fdee4c8a3}"
|
||||
|
||||
[DeviceDefinition0.Config]
|
||||
XferPackets=816
|
||||
UrbMaxPackets=816
|
||||
MaxUrbs=5
|
||||
NoRawIo=false
|
||||
ReceiverMaxPackets=2048
|
||||
PsbPurgeTimeout=2000
|
||||
DiscardNullPackets=true
|
||||
|
||||
[DeviceDefinition0.Receiver0]
|
||||
Name="PLEX PX-W3U4 ISDB-S Receiver #0"
|
||||
GUID="{641e1543-e26c-4305-9685-fee33882c1d5}"
|
||||
System="ISDB-S"
|
||||
Index=0
|
||||
|
||||
[DeviceDefinition0.Receiver1]
|
||||
Name="PLEX PX-W3U4 ISDB-S Receiver #1"
|
||||
GUID="{3b42cd44-a0ee-4973-8c3e-faffae24bbb4}"
|
||||
System="ISDB-S"
|
||||
Index=1
|
||||
|
||||
[DeviceDefinition0.Receiver2]
|
||||
Name="PLEX PX-W3U4 ISDB-T Receiver #0"
|
||||
GUID="{597215e5-fcc0-40de-b2ba-de642fc69883}"
|
||||
System="ISDB-T"
|
||||
Index=0
|
||||
|
||||
[DeviceDefinition0.Receiver3]
|
||||
Name="PLEX PX-W3U4 ISDB-T Receiver #1"
|
||||
GUID="{1b8bd136-784d-4eef-a0db-cf28ccdc72c6}"
|
||||
System="ISDB-T"
|
||||
Index=1
|
||||
|
||||
[DeviceDefinition1]
|
||||
Name="PLEX PX-Q3U4"
|
||||
GUID="{3c612a36-81dd-4509-b5f7-63594f84f859}"
|
||||
Type="PX4"
|
||||
DeviceInterfaceGUID="{87b25983-d116-4ccf-8896-84d022fabd73}"
|
||||
|
||||
[DeviceDefinition1.Config]
|
||||
XferPackets=816
|
||||
UrbMaxPackets=816
|
||||
MaxUrbs=5
|
||||
NoRawIo=false
|
||||
ReceiverMaxPackets=2048
|
||||
PsbPurgeTimeout=2000
|
||||
DisableMultiDevicePowerControl=false
|
||||
MultiDevicePowerControlMode=all
|
||||
DiscardNullPackets=true
|
||||
|
||||
[DeviceDefinition1.Receiver0]
|
||||
Name="PLEX PX-Q3U4 ISDB-S Receiver #0"
|
||||
GUID="{ea04a8c2-07c7-4626-8b20-c4faeb8af2f8}"
|
||||
System="ISDB-S"
|
||||
Index=0
|
||||
|
||||
[DeviceDefinition1.Receiver1]
|
||||
Name="PLEX PX-Q3U4 ISDB-S Receiver #1"
|
||||
GUID="{23c24fea-a89b-4913-8946-2b95d073a664}"
|
||||
System="ISDB-S"
|
||||
Index=1
|
||||
|
||||
[DeviceDefinition1.Receiver2]
|
||||
Name="PLEX PX-Q3U4 ISDB-T Receiver #0"
|
||||
GUID="{f200efcb-9917-49e5-941b-d16670823c97}"
|
||||
System="ISDB-T"
|
||||
Index=0
|
||||
|
||||
[DeviceDefinition1.Receiver3]
|
||||
Name="PLEX PX-Q3U4 ISDB-T Receiver #1"
|
||||
GUID="{6a8df054-7703-48d2-a98b-2e050335b4b8}"
|
||||
System="ISDB-T"
|
||||
Index=1
|
||||
|
||||
[DeviceDefinition2]
|
||||
Name="PLEX PX-W3PE4"
|
||||
GUID="{e231e39e-4823-41ff-ab71-f95bf6785ffc}"
|
||||
Type="PX4"
|
||||
DeviceInterfaceGUID="{47fc15e3-6791-4e24-8fbe-c4218eee0ad6}"
|
||||
|
||||
[DeviceDefinition2.Config]
|
||||
XferPackets=816
|
||||
UrbMaxPackets=816
|
||||
MaxUrbs=5
|
||||
NoRawIo=false
|
||||
ReceiverMaxPackets=2048
|
||||
PsbPurgeTimeout=2000
|
||||
DiscardNullPackets=true
|
||||
|
||||
[DeviceDefinition2.Receiver0]
|
||||
Name="PLEX PX-W3PE4 ISDB-S Receiver #0"
|
||||
GUID="{892a0139-980f-4046-a166-9d8126f764a7}"
|
||||
System="ISDB-S"
|
||||
Index=0
|
||||
|
||||
[DeviceDefinition2.Receiver1]
|
||||
Name="PLEX PX-W3PE4 ISDB-S Receiver #1"
|
||||
GUID="{721eb5f2-a86c-44ea-bd26-c4194ff396be}"
|
||||
System="ISDB-S"
|
||||
Index=1
|
||||
|
||||
[DeviceDefinition2.Receiver2]
|
||||
Name="PLEX PX-W3PE4 ISDB-T Receiver #0"
|
||||
GUID="{72749cd6-db45-4fbe-9480-02b69ef744f1}"
|
||||
System="ISDB-T"
|
||||
Index=0
|
||||
|
||||
[DeviceDefinition2.Receiver3]
|
||||
Name="PLEX PX-W3PE4 ISDB-T Receiver #1"
|
||||
GUID="{b64d7a5d-1d9c-4d03-aad3-51a67108e92f}"
|
||||
System="ISDB-T"
|
||||
Index=1
|
||||
|
||||
[DeviceDefinition3]
|
||||
Name="PLEX PX-Q3PE4"
|
||||
GUID="{89698252-64e8-414a-9e7a-5485f36eef0f}"
|
||||
Type="PX4"
|
||||
DeviceInterfaceGUID="{60eaf2b6-548f-4aad-ab0b-87055528dfd6}"
|
||||
|
||||
[DeviceDefinition3.Config]
|
||||
XferPackets=816
|
||||
UrbMaxPackets=816
|
||||
MaxUrbs=5
|
||||
NoRawIo=false
|
||||
ReceiverMaxPackets=2048
|
||||
PsbPurgeTimeout=2000
|
||||
DisableMultiDevicePowerControl=false
|
||||
MultiDevicePowerControlMode=all
|
||||
DiscardNullPackets=true
|
||||
|
||||
[DeviceDefinition3.Receiver0]
|
||||
Name="PLEX PX-Q3PE4 ISDB-S Receiver #0"
|
||||
GUID="{29094d7c-86b8-4ae0-878e-c5f0274b3c59}"
|
||||
System="ISDB-S"
|
||||
Index=0
|
||||
|
||||
[DeviceDefinition3.Receiver1]
|
||||
Name="PLEX PX-Q3PE4 ISDB-S Receiver #1"
|
||||
GUID="{fa395f33-9a0f-45a7-92fd-2e8ece6f9a6d}"
|
||||
System="ISDB-S"
|
||||
Index=1
|
||||
|
||||
[DeviceDefinition3.Receiver2]
|
||||
Name="PLEX PX-Q3PE4 ISDB-T Receiver #0"
|
||||
GUID="{e1af4449-4ddd-4f06-9892-295cce6ea0db}"
|
||||
System="ISDB-T"
|
||||
Index=0
|
||||
|
||||
[DeviceDefinition3.Receiver3]
|
||||
Name="PLEX PX-Q3PE4 ISDB-T Receiver #1"
|
||||
GUID="{e87a942d-3c95-47ea-be28-4fad54a3d319}"
|
||||
System="ISDB-T"
|
||||
Index=1
|
||||
|
||||
[DeviceDefinition4]
|
||||
Name="PLEX PX-W3PE5"
|
||||
GUID="{23937228-f21a-4ac5-a8f6-76b0bc4bc453}"
|
||||
Type="PX4"
|
||||
DeviceInterfaceGUID="{3c42fdc6-2438-455e-89db-538011777617}"
|
||||
|
||||
[DeviceDefinition4.Config]
|
||||
XferPackets=816
|
||||
UrbMaxPackets=816
|
||||
MaxUrbs=5
|
||||
NoRawIo=false
|
||||
ReceiverMaxPackets=2048
|
||||
PsbPurgeTimeout=2000
|
||||
DiscardNullPackets=true
|
||||
|
||||
[DeviceDefinition4.Receiver0]
|
||||
Name="PLEX PX-W3PE5 ISDB-S Receiver #0"
|
||||
GUID="{bb0bb5a1-029d-43cd-9db2-e445b7523c9d}"
|
||||
System="ISDB-S"
|
||||
Index=0
|
||||
|
||||
[DeviceDefinition4.Receiver1]
|
||||
Name="PLEX PX-W3PE5 ISDB-S Receiver #1"
|
||||
GUID="{b2c3204f-7566-465d-adaf-59e7ae12bcbc}"
|
||||
System="ISDB-S"
|
||||
Index=1
|
||||
|
||||
[DeviceDefinition4.Receiver2]
|
||||
Name="PLEX PX-W3PE5 ISDB-T Receiver #0"
|
||||
GUID="{dc8de9c5-4ed4-483c-9df3-4fdc70a27bcd}"
|
||||
System="ISDB-T"
|
||||
Index=0
|
||||
|
||||
[DeviceDefinition4.Receiver3]
|
||||
Name="PLEX PX-W3PE5 ISDB-T Receiver #1"
|
||||
GUID="{73e8457f-6f1c-4516-895e-9403dd0ef607}"
|
||||
System="ISDB-T"
|
||||
Index=1
|
||||
|
||||
[DeviceDefinition5]
|
||||
Name="PLEX PX-Q3PE5"
|
||||
GUID="{1c32a5d6-70ad-469e-9a90-5a8d5880082b}"
|
||||
Type="PX4"
|
||||
DeviceInterfaceGUID="{c78aa8ba-8476-4047-a089-7c3ed43503a6}"
|
||||
|
||||
[DeviceDefinition5.Config]
|
||||
XferPackets=816
|
||||
UrbMaxPackets=816
|
||||
MaxUrbs=5
|
||||
NoRawIo=false
|
||||
ReceiverMaxPackets=2048
|
||||
PsbPurgeTimeout=2000
|
||||
DisableMultiDevicePowerControl=false
|
||||
MultiDevicePowerControlMode=all
|
||||
DiscardNullPackets=true
|
||||
|
||||
[DeviceDefinition5.Receiver0]
|
||||
Name="PLEX PX-Q3PE5 ISDB-S Receiver #0"
|
||||
GUID="{f3515ff6-9de0-4fbb-bdcd-d531c2d7a763}"
|
||||
System="ISDB-S"
|
||||
Index=0
|
||||
|
||||
[DeviceDefinition5.Receiver1]
|
||||
Name="PLEX PX-Q3PE5 ISDB-S Receiver #1"
|
||||
GUID="{da688f4e-dd19-44c3-9ea1-97b6f3c16c95}"
|
||||
System="ISDB-S"
|
||||
Index=1
|
||||
|
||||
[DeviceDefinition5.Receiver2]
|
||||
Name="PLEX PX-Q3PE5 ISDB-T Receiver #0"
|
||||
GUID="{d0b81a5c-8d6c-45f0-8825-574d3c2e7feb}"
|
||||
System="ISDB-T"
|
||||
Index=0
|
||||
|
||||
[DeviceDefinition5.Receiver3]
|
||||
Name="PLEX PX-Q3PE5 ISDB-T Receiver #1"
|
||||
GUID="{eb0781df-3ecd-4918-9151-323c7f89dfe0}"
|
||||
System="ISDB-T"
|
||||
Index=1
|
||||
|
||||
[DeviceDefinition6]
|
||||
Name="PLEX PX-MLT5PE"
|
||||
GUID="{b4eeca78-7c7f-423e-8ab8-305416d1c4f2}"
|
||||
Type="PXMLT"
|
||||
DeviceInterfaceGUID="{eeb8e93b-1007-4e3e-8ce9-4f7ebdf3aba1}"
|
||||
|
||||
[DeviceDefinition6.Config]
|
||||
XferPackets=816
|
||||
UrbMaxPackets=816
|
||||
MaxUrbs=5
|
||||
NoRawIo=false
|
||||
ReceiverMaxPackets=2048
|
||||
PsbPurgeTimeout=2000
|
||||
DiscardNullPackets=true
|
||||
|
||||
[DeviceDefinition6.Receiver0]
|
||||
Name="PLEX PX-MLT5PE ISDB-T/S Receiver #0"
|
||||
GUID="{36ba23f9-6ecb-4757-8b11-a245db670dce}"
|
||||
System="ISDB-T,ISDB-S"
|
||||
Index=0
|
||||
|
||||
[DeviceDefinition6.Receiver1]
|
||||
Name="PLEX PX-MLT5PE ISDB-T/S Receiver #1"
|
||||
GUID="{af336592-ae42-4d1e-aa37-2cfd4cd0a5ed}"
|
||||
System="ISDB-T,ISDB-S"
|
||||
Index=1
|
||||
|
||||
[DeviceDefinition6.Receiver2]
|
||||
Name="PLEX PX-MLT5PE ISDB-T/S Receiver #2"
|
||||
GUID="{ee71370b-8a33-4579-be94-577872b92c93}"
|
||||
System="ISDB-T,ISDB-S"
|
||||
Index=2
|
||||
|
||||
[DeviceDefinition6.Receiver3]
|
||||
Name="PLEX PX-MLT5PE ISDB-T/S Receiver #3"
|
||||
GUID="{0f9b59dd-e7b6-4b8f-84f5-65a0758cff70}"
|
||||
System="ISDB-T,ISDB-S"
|
||||
Index=3
|
||||
|
||||
[DeviceDefinition6.Receiver4]
|
||||
Name="PLEX PX-MLT5PE ISDB-T/S Receiver #4"
|
||||
GUID="{cb61f2f7-d088-4ae0-9c88-c215c06ea3a2}"
|
||||
System="ISDB-T,ISDB-S"
|
||||
Index=4
|
||||
|
||||
[DeviceDefinition7]
|
||||
Name="PLEX PX-MLT8PE3"
|
||||
GUID="{a6a02476-1ba2-4686-84ec-c7aa2b045267}"
|
||||
Type="PXMLT"
|
||||
DeviceInterfaceGUID="{bfafd6cd-29f8-46e7-b558-e3b0c493aaba}"
|
||||
|
||||
[DeviceDefinition7.Config]
|
||||
XferPackets=816
|
||||
UrbMaxPackets=816
|
||||
MaxUrbs=5
|
||||
NoRawIo=false
|
||||
ReceiverMaxPackets=2048
|
||||
PsbPurgeTimeout=2000
|
||||
DiscardNullPackets=true
|
||||
|
||||
[DeviceDefinition7.Receiver0]
|
||||
Name="PLEX PX-MLT8PE3 ISDB-T/S Receiver #0"
|
||||
GUID="{e8c7091c-6c3f-49bc-9076-1a323decab1d}"
|
||||
System="ISDB-T,ISDB-S"
|
||||
Index=0
|
||||
|
||||
[DeviceDefinition7.Receiver1]
|
||||
Name="PLEX PX-MLT8PE3 ISDB-T/S Receiver #1"
|
||||
GUID="{b94ca4d7-f9f6-4749-869f-a00feea4e44c}"
|
||||
System="ISDB-T,ISDB-S"
|
||||
Index=1
|
||||
|
||||
[DeviceDefinition7.Receiver2]
|
||||
Name="PLEX PX-MLT8PE3 ISDB-T/S Receiver #2"
|
||||
GUID="{14dfa687-1c02-4883-af27-8e8d7b5e6899}"
|
||||
System="ISDB-T,ISDB-S"
|
||||
Index=2
|
||||
|
||||
[DeviceDefinition8]
|
||||
Name="PLEX PX-MLT8PE5"
|
||||
GUID="{7de16cba-9609-432a-83bf-bc14ba785152}"
|
||||
Type="PXMLT"
|
||||
DeviceInterfaceGUID="{145dce88-a4db-4737-8e5d-d1099814876a}"
|
||||
|
||||
[DeviceDefinition8.Config]
|
||||
XferPackets=816
|
||||
UrbMaxPackets=816
|
||||
MaxUrbs=5
|
||||
NoRawIo=false
|
||||
ReceiverMaxPackets=2048
|
||||
PsbPurgeTimeout=2000
|
||||
DiscardNullPackets=true
|
||||
|
||||
[DeviceDefinition8.Receiver0]
|
||||
Name="PLEX PX-MLT8PE5 ISDB-T/S Receiver #0"
|
||||
GUID="{d93bbdf8-c5f7-4667-8c04-3561e48121a7}"
|
||||
System="ISDB-T,ISDB-S"
|
||||
Index=0
|
||||
|
||||
[DeviceDefinition8.Receiver1]
|
||||
Name="PLEX PX-MLT8PE5 ISDB-T/S Receiver #1"
|
||||
GUID="{4dc6f500-6186-4557-8bbd-934a8543be31}"
|
||||
System="ISDB-T,ISDB-S"
|
||||
Index=1
|
||||
|
||||
[DeviceDefinition8.Receiver2]
|
||||
Name="PLEX PX-MLT8PE5 ISDB-T/S Receiver #2"
|
||||
GUID="{66c141a5-ce50-4bdf-bf5b-1f6ff5c82a91}"
|
||||
System="ISDB-T,ISDB-S"
|
||||
Index=2
|
||||
|
||||
[DeviceDefinition8.Receiver3]
|
||||
Name="PLEX PX-MLT8PE5 ISDB-T/S Receiver #3"
|
||||
GUID="{72fc5f09-2a1d-4ddb-a0bb-9a28306f1a85}"
|
||||
System="ISDB-T,ISDB-S"
|
||||
Index=3
|
||||
|
||||
[DeviceDefinition8.Receiver4]
|
||||
Name="PLEX PX-MLT8PE5 ISDB-T/S Receiver #4"
|
||||
GUID="{73466645-2dfd-4567-906b-90138f02d55c}"
|
||||
System="ISDB-T,ISDB-S"
|
||||
Index=4
|
||||
|
||||
[DeviceDefinition9]
|
||||
Name="Digibest ISDB6014"
|
||||
GUID="{1fbeec9a-a12c-4262-8d33-134966ba7ff4}"
|
||||
Type="PXMLT"
|
||||
DeviceInterfaceGUID="{da23f91d-62ad-401e-812e-a7f054d665af}"
|
||||
|
||||
[DeviceDefinition9.Config]
|
||||
XferPackets=816
|
||||
UrbMaxPackets=816
|
||||
MaxUrbs=5
|
||||
NoRawIo=false
|
||||
ReceiverMaxPackets=2048
|
||||
PsbPurgeTimeout=2000
|
||||
DiscardNullPackets=true
|
||||
|
||||
[DeviceDefinition9.Receiver0]
|
||||
Name="Digibest ISDB6014 ISDB-T/S Receiver #0"
|
||||
GUID="{769c677d-d2a3-451c-8556-970c0fb83c26}"
|
||||
System="ISDB-T,ISDB-S"
|
||||
Index=0
|
||||
|
||||
[DeviceDefinition9.Receiver1]
|
||||
Name="Digibest ISDB6014 ISDB-T/S Receiver #1"
|
||||
GUID="{2ba942a1-1c22-4053-82f5-5afc89b4a658}"
|
||||
System="ISDB-T,ISDB-S"
|
||||
Index=1
|
||||
|
||||
[DeviceDefinition9.Receiver2]
|
||||
Name="Digibest ISDB6014 ISDB-T/S Receiver #2"
|
||||
GUID="{31a41baf-65dc-4de2-9c0e-fbea038489b4}"
|
||||
System="ISDB-T,ISDB-S"
|
||||
Index=2
|
||||
|
||||
[DeviceDefinition9.Receiver3]
|
||||
Name="Digibest ISDB6014 ISDB-T/S Receiver #3"
|
||||
GUID="{2fb006ac-e388-4532-885b-555ba9f72d3d}"
|
||||
System="ISDB-T,ISDB-S"
|
||||
Index=3
|
||||
|
||||
[DeviceDefinition10]
|
||||
Name="Digibest ISDB2056"
|
||||
GUID="{5d04b1e3-6063-4bdd-87ce-64b916aa4180}"
|
||||
Type="ISDB2056"
|
||||
DeviceInterfaceGUID="{1f8fa351-3f75-42c1-b0f1-ec794294448f}"
|
||||
|
||||
[DeviceDefinition10.Config]
|
||||
XferPackets=816
|
||||
UrbMaxPackets=816
|
||||
MaxUrbs=5
|
||||
NoRawIo=false
|
||||
ReceiverMaxPackets=2048
|
||||
PsbPurgeTimeout=2000
|
||||
DiscardNullPackets=true
|
||||
|
||||
[DeviceDefinition10.Receiver0]
|
||||
Name="Digibest ISDB2056 ISDB-T/S Receiver #0"
|
||||
GUID="{0aedb5cd-a9af-4aa0-b9d9-e9b378acfef6}"
|
||||
System="ISDB-T,ISDB-S"
|
||||
Index=0
|
||||
|
||||
[DeviceDefinition11]
|
||||
Name="Digibest ISDB2056N"
|
||||
GUID="{c29c6ef9-6321-470d-bbc9-ae4358e4c6b1}"
|
||||
Type="ISDB2056"
|
||||
DeviceInterfaceGUID="{283639e3-0df2-40bd-a5cc-5051579745a7}"
|
||||
|
||||
[DeviceDefinition11.Config]
|
||||
XferPackets=816
|
||||
UrbMaxPackets=816
|
||||
MaxUrbs=5
|
||||
NoRawIo=false
|
||||
ReceiverMaxPackets=2048
|
||||
PsbPurgeTimeout=2000
|
||||
DiscardNullPackets=true
|
||||
|
||||
[DeviceDefinition11.Receiver0]
|
||||
Name="Digibest ISDB2056N ISDB-T/S Receiver #0"
|
||||
GUID="{0aedb5cd-a9af-4aa0-b9d9-e9b378acfef6}"
|
||||
System="ISDB-T,ISDB-S"
|
||||
Index=0
|
||||
|
||||
[DeviceDefinition12]
|
||||
Name="PLEX PX-M1UR"
|
||||
GUID="{a3c9bf85-13fe-465c-9a33-22441975c190}"
|
||||
Type="ISDB2056"
|
||||
DeviceInterfaceGUID="{28ec1517-6150-4025-acfb-a5447add0a57}"
|
||||
|
||||
[DeviceDefinition12.Config]
|
||||
XferPackets=816
|
||||
UrbMaxPackets=816
|
||||
MaxUrbs=5
|
||||
NoRawIo=false
|
||||
ReceiverMaxPackets=2048
|
||||
PsbPurgeTimeout=2000
|
||||
DiscardNullPackets=true
|
||||
|
||||
[DeviceDefinition12.Receiver0]
|
||||
Name="PLEX PX-M1UR ISDB-T/S Receiver #0"
|
||||
GUID="{0aedb5cd-a9af-4aa0-b9d9-e9b378acfef6}"
|
||||
System="ISDB-T,ISDB-S"
|
||||
Index=0
|
||||
|
||||
[DeviceDefinition13]
|
||||
Name="PLEX PX-S1UR"
|
||||
GUID="{bf4454d8-63c4-4a97-ae0d-19329c4da997}"
|
||||
Type="ISDB2056"
|
||||
DeviceInterfaceGUID="{a3303a3b-ea2c-467f-beae-8e72fb158714}"
|
||||
|
||||
[DeviceDefinition13.Config]
|
||||
XferPackets=816
|
||||
UrbMaxPackets=816
|
||||
MaxUrbs=5
|
||||
NoRawIo=false
|
||||
ReceiverMaxPackets=2048
|
||||
PsbPurgeTimeout=2000
|
||||
DiscardNullPackets=true
|
||||
|
||||
[DeviceDefinition13.Receiver0]
|
||||
Name="PLEX PX-S1UR ISDB-T Receiver #0"
|
||||
GUID="{f060ae2a-98d6-4149-9c9d-e0bfd28f6816}"
|
||||
System="ISDB-T"
|
||||
Index=0
|
||||
|
||||
[DeviceDefinition14]
|
||||
Name="Digibest ISDBT2071"
|
||||
GUID="{3dff00b8-b3f4-41ee-9d68-5e458143086e}"
|
||||
Type="ISDBT2071"
|
||||
DeviceInterfaceGUID="{ac1e5fa2-e265-4819-9b29-2be8a44ce4c9}"
|
||||
|
||||
[DeviceDefinition14.Config]
|
||||
XferPackets=816
|
||||
UrbMaxPackets=816
|
||||
MaxUrbs=5
|
||||
NoRawIo=false
|
||||
ReceiverMaxPackets=2048
|
||||
PsbPurgeTimeout=2000
|
||||
DiscardNullPackets=true
|
||||
[DeviceDefinition14.Receiver0]
|
||||
Name="Digibest ISDBT2071 ISDB-T Receiver #0"
|
||||
GUID="{b1f46b07-89ef-4f64-b531-21295108a393}"
|
||||
System="ISDB-T"
|
||||
Index=0
|
BIN
winusb/pkg/DriverHost_PX4/it930x-firmware.bin
Normal file
BIN
winusb/pkg/DriverHost_PX4/it930x-firmware.bin
Normal file
Binary file not shown.
44
winusb/pkg/inf/DTV02A-1T1S-U_ISDB2056.inf
Normal file
44
winusb/pkg/inf/DTV02A-1T1S-U_ISDB2056.inf
Normal file
@@ -0,0 +1,44 @@
|
||||
;
|
||||
; Digibest ISDB2056 WinUSB
|
||||
;
|
||||
[Version]
|
||||
Signature="$Windows NT$"
|
||||
Class=Media
|
||||
ClassGuid={4d36e96c-e325-11ce-bfc1-08002be10318}
|
||||
Provider=%AuthorName%
|
||||
DriverVer=05/01/2021,21.05.01.00
|
||||
CatalogFile=px4_drv_winusb.cat
|
||||
|
||||
[Manufacturer]
|
||||
%AuthorName%=ISDB2056_WinUSB,ntx86,ntamd64,ntarm64
|
||||
|
||||
[ISDB2056_WinUSB.ntx86]
|
||||
%ISDB2056_WinUSB.DeviceDesc%=ISDB2056_WinUSB.DeviceInstall,USB\VID_0511&PID_004b
|
||||
|
||||
[ISDB2056_WinUSB.ntamd64]
|
||||
%ISDB2056_WinUSB.DeviceDesc%=ISDB2056_WinUSB.DeviceInstall,USB\VID_0511&PID_004b
|
||||
|
||||
[ISDB2056_WinUSB.ntarm64]
|
||||
%ISDB2056_WinUSB.DeviceDesc%=ISDB2056_WinUSB.DeviceInstall,USB\VID_0511&PID_004b
|
||||
|
||||
[ISDB2056_WinUSB.DeviceInstall]
|
||||
Include=winusb.inf
|
||||
Needs=WINUSB.NT
|
||||
AddProperty=ISDB2056_WinUSB.DeviceSetup.AddProperty
|
||||
|
||||
[ISDB2056_WinUSB.DeviceInstall.Services]
|
||||
Include=winusb.inf
|
||||
Needs=WINUSB.NT.Services
|
||||
|
||||
[ISDB2056_WinUSB.DeviceInstall.HW]
|
||||
AddReg=ISDB2056_WinUSB.DeviceSetup.AddReg
|
||||
|
||||
[ISDB2056_WinUSB.DeviceSetup.AddReg]
|
||||
HKR,,DeviceInterfaceGUIDs,0x00010000,"{1f8fa351-3f75-42c1-b0f1-ec794294448f}"
|
||||
|
||||
[ISDB2056_WinUSB.DeviceSetup.AddProperty]
|
||||
{afd97640-86a3-4210-b67c-289c41aabe55},3,0x00000011,,0 ;DEVPKEY_Device_SafeRemovalRequiredOverride=FALSE
|
||||
|
||||
[Strings]
|
||||
AuthorName="nns779"
|
||||
ISDB2056_WinUSB.DeviceDesc="Digibest ISDB2056 ISDB-T/S Receiver Device (WinUSB)"
|
44
winusb/pkg/inf/DTV02A-1T1S-U_ISDB2056N.inf
Normal file
44
winusb/pkg/inf/DTV02A-1T1S-U_ISDB2056N.inf
Normal file
@@ -0,0 +1,44 @@
|
||||
;
|
||||
; Digibest ISDB2056N WinUSB
|
||||
;
|
||||
[Version]
|
||||
Signature="$Windows NT$"
|
||||
Class=Media
|
||||
ClassGuid={4d36e96c-e325-11ce-bfc1-08002be10318}
|
||||
Provider=%AuthorName%
|
||||
DriverVer=05/01/2021,21.05.01.00
|
||||
CatalogFile=px4_drv_winusb.cat
|
||||
|
||||
[Manufacturer]
|
||||
%AuthorName%=ISDB2056N_WinUSB,ntx86,ntamd64,ntarm64
|
||||
|
||||
[ISDB2056N_WinUSB.ntx86]
|
||||
%ISDB2056N_WinUSB.DeviceDesc%=ISDB2056N_WinUSB.DeviceInstall,USB\VID_0511&PID_084b
|
||||
|
||||
[ISDB2056N_WinUSB.ntamd64]
|
||||
%ISDB2056N_WinUSB.DeviceDesc%=ISDB2056N_WinUSB.DeviceInstall,USB\VID_0511&PID_084b
|
||||
|
||||
[ISDB2056N_WinUSB.ntarm64]
|
||||
%ISDB2056N_WinUSB.DeviceDesc%=ISDB2056N_WinUSB.DeviceInstall,USB\VID_0511&PID_084b
|
||||
|
||||
[ISDB2056N_WinUSB.DeviceInstall]
|
||||
Include=winusb.inf
|
||||
Needs=WINUSB.NT
|
||||
AddProperty=ISDB2056N_WinUSB.DeviceSetup.AddProperty
|
||||
|
||||
[ISDB2056N_WinUSB.DeviceInstall.Services]
|
||||
Include=winusb.inf
|
||||
Needs=WINUSB.NT.Services
|
||||
|
||||
[ISDB2056N_WinUSB.DeviceInstall.HW]
|
||||
AddReg=ISDB2056N_WinUSB.DeviceSetup.AddReg
|
||||
|
||||
[ISDB2056N_WinUSB.DeviceSetup.AddReg]
|
||||
HKR,,DeviceInterfaceGUIDs,0x00010000,"{283639e3-0df2-40bd-a5cc-5051579745a7}"
|
||||
|
||||
[ISDB2056N_WinUSB.DeviceSetup.AddProperty]
|
||||
{afd97640-86a3-4210-b67c-289c41aabe55},3,0x00000011,,0 ;DEVPKEY_Device_SafeRemovalRequiredOverride=FALSE
|
||||
|
||||
[Strings]
|
||||
AuthorName="nns779"
|
||||
ISDB2056N_WinUSB.DeviceDesc="Digibest ISDB2056N ISDB-T/S Receiver Device (WinUSB)"
|
44
winusb/pkg/inf/DTV02A-4TS-P.inf
Normal file
44
winusb/pkg/inf/DTV02A-4TS-P.inf
Normal file
@@ -0,0 +1,44 @@
|
||||
;
|
||||
; Digibest ISDB6014 WinUSB
|
||||
;
|
||||
[Version]
|
||||
Signature="$Windows NT$"
|
||||
Class=Media
|
||||
ClassGuid={4d36e96c-e325-11ce-bfc1-08002be10318}
|
||||
Provider=%AuthorName%
|
||||
DriverVer=05/01/2021,21.05.01.00
|
||||
CatalogFile=px4_drv_winusb.cat
|
||||
|
||||
[Manufacturer]
|
||||
%AuthorName%=ISDB6014_WinUSB,ntx86,ntamd64,ntarm64
|
||||
|
||||
[ISDB6014_WinUSB.ntx86]
|
||||
%ISDB6014_WinUSB.DeviceDesc%=ISDB6014_WinUSB.DeviceInstall,USB\VID_0511&PID_0254
|
||||
|
||||
[ISDB6014_WinUSB.ntamd64]
|
||||
%ISDB6014_WinUSB.DeviceDesc%=ISDB6014_WinUSB.DeviceInstall,USB\VID_0511&PID_0254
|
||||
|
||||
[ISDB6014_WinUSB.ntarm64]
|
||||
%ISDB6014_WinUSB.DeviceDesc%=ISDB6014_WinUSB.DeviceInstall,USB\VID_0511&PID_0254
|
||||
|
||||
[ISDB6014_WinUSB.DeviceInstall]
|
||||
Include=winusb.inf
|
||||
Needs=WINUSB.NT
|
||||
AddProperty=ISDB6014_WinUSB.DeviceSetup.AddProperty
|
||||
|
||||
[ISDB6014_WinUSB.DeviceInstall.Services]
|
||||
Include=winusb.inf
|
||||
Needs=WINUSB.NT.Services
|
||||
|
||||
[ISDB6014_WinUSB.DeviceInstall.HW]
|
||||
AddReg=ISDB6014_WinUSB.DeviceSetup.AddReg
|
||||
|
||||
[ISDB6014_WinUSB.DeviceSetup.AddReg]
|
||||
HKR,,DeviceInterfaceGUIDs,0x00010000,"{da23f91d-62ad-401e-812e-a7f054d665af}"
|
||||
|
||||
[ISDB6014_WinUSB.DeviceSetup.AddProperty]
|
||||
{afd97640-86a3-4210-b67c-289c41aabe55},3,0x00000011,,0 ;DEVPKEY_Device_SafeRemovalRequiredOverride=FALSE
|
||||
|
||||
[Strings]
|
||||
AuthorName="nns779"
|
||||
ISDB6014_WinUSB.DeviceDesc="Digibest ISDB6014 ISDB-T/S Receiver Device (WinUSB)"
|
44
winusb/pkg/inf/DTV03A-1TU_ISDBT2071.inf
Normal file
44
winusb/pkg/inf/DTV03A-1TU_ISDBT2071.inf
Normal file
@@ -0,0 +1,44 @@
|
||||
;
|
||||
; Digibest ISDBT2071 (MAXWIN DTV03A-1TU)
|
||||
;
|
||||
[Version]
|
||||
Signature="$Windows NT$"
|
||||
Class=Media
|
||||
ClassGuid={4d36e96c-e325-11ce-bfc1-08002be10318}
|
||||
Provider=%AuthorName%
|
||||
DriverVer=05/01/2021,21.05.01.00
|
||||
CatalogFile=px4_drv_winusb.cat
|
||||
|
||||
[Manufacturer]
|
||||
%AuthorName%=ISDBT2071_WinUSB,ntx86,ntamd64,ntarm64
|
||||
|
||||
[ISDBT2071_WinUSB.ntx86]
|
||||
%ISDBT2071_WinUSB.DeviceDesc%=ISDBT2071_WinUSB.DeviceInstall,USB\VID_0511&PID_0052
|
||||
|
||||
[ISDBT2071_WinUSB.ntamd64]
|
||||
%ISDBT2071_WinUSB.DeviceDesc%=ISDBT2071_WinUSB.DeviceInstall,USB\VID_0511&PID_0052
|
||||
|
||||
[ISDBT2071_WinUSB.ntarm64]
|
||||
%ISDBT2071_WinUSB.DeviceDesc%=ISDBT2071_WinUSB.DeviceInstall,USB\VID_0511&PID_0052
|
||||
|
||||
[ISDBT2071_WinUSB.DeviceInstall]
|
||||
Include=winusb.inf
|
||||
Needs=WINUSB.NT
|
||||
AddProperty=ISDBT2071_WinUSB.DeviceSetup.AddProperty
|
||||
|
||||
[ISDBT2071_WinUSB.DeviceInstall.Services]
|
||||
Include=winusb.inf
|
||||
Needs=WINUSB.NT.Services
|
||||
|
||||
[ISDBT2071_WinUSB.DeviceInstall.HW]
|
||||
AddReg=ISDBT2071_WinUSB.DeviceSetup.AddReg
|
||||
|
||||
[ISDBT2071_WinUSB.DeviceSetup.AddReg]
|
||||
HKR,,DeviceInterfaceGUIDs,0x00010000,"{ac1e5fa2-e265-4819-9b29-2be8a44ce4c9}"
|
||||
|
||||
[ISDBT2071_WinUSB.DeviceSetup.AddProperty]
|
||||
{afd97640-86a3-4210-b67c-289c41aabe55},3,0x00000011,,0 ;DEVPKEY_Device_SafeRemovalRequiredOverride=FALSE
|
||||
|
||||
[Strings]
|
||||
AuthorName="nns779"
|
||||
ISDBT2071_WinUSB.DeviceDesc="Digibest ISDBT2071 (DTV03A-1TU) ISDB-T Receiver Device (WinUSB)"
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user