33 Commits

Author SHA1 Message Date
tsukumi
b4a6f9a9f5 Merge pull request #34 from masnagam/fix-driver-init_exit
driver: `__init` と `__exit` を指定
2025-07-20 12:18:25 +09:00
masnagam
fe259b52b7 driver: __init__exit を指定
モジュールの初期化および終了関数にそれぞれ `__init` と `__exit` を指定
した.これらマクロを使用していなくても大きな問題は発生しないと考えられ
るが,一般的な作法として追加した.

これらマクロの説明は以下を参照:

* https://tldp.org/LDP/lkmpg/2.4/html/x281.htm
* https://fastbitlab.com/linux-device-driver-programming-lecture-18-__init-and-__exit-macros/
* https://shnoh171.github.io/linux%20kernel/2019/09/01/linux-kernel-module-basics.html
2025-07-20 08:52:02 +09:00
tsukumi
5ac1fca737 Merge pull request #33 from knight-ryu12/objtool_ibt
moduleの書き方を変更することで、Errorを回避する
2025-07-07 03:31:48 +09:00
Chromaryu
26e8327823 driver_module: VERSION定義を追加 2025-07-06 20:34:57 +09:00
Chromaryu
62cfb11290 moduleのIBT対応 2025-06-25 14:19:35 +09:00
tsukumi
12a1213912 v0.5.4 2025-06-08 03:28:15 +09:00
tsukumi
17496bed2c driver: Oracle Linux 9 でビルドできないらしい問題を修正
新しい GCC バージョンだと、予期しない fall through を防ぐため、明示的に fallthrough; を使わないとビルドできなくなっているらしい
以下フォークでの変更を取り込んだ
ref: 57cec596b4
2025-06-08 03:14:24 +09:00
tsukumi
d2053ae4de README: DTV03A-1TU 対応に関して追記 2025-06-08 03:07:43 +09:00
tsukumi
419f1dea5a Merge pull request #30 from hendecarows/feature/isdbt2071
DTV03A-1TU(ISDBT2071)製造ロット2022-11月以降のLinux対応
2025-06-08 02:39:16 +09:00
tsukumi
5892e3bfde Merge pull request #29 from hendecarows/fix/dkms-post-remove
Ubuntu 24.04環境でdkms後処理スクリプトが本来削除すべきではない99-px4video.rulesとit930x-firmware.binを削除してしまう問題を修正
2025-06-08 02:33:07 +09:00
hendecarows
0a63d0c9fa Ubuntu 24.04環境でdkms後処理スクリプトが本来削除すべきではない99-px4video.rulesとit930x-firmware.binを削除してしまう問題を修正 2025-06-05 20:09:24 +09:00
hendecarows
51134d6d74 DTV03A-1TU(ISDBT2071)製造ロット2022-11月以降のLinux対応
WinUSB版同様チャンネル変更後はエラーやドロップを多量に含む不安定なTSが出力される。録画用途での使用は厳しい。
2025-05-11 00:44:05 +09:00
tsukumi
d6baacdcbc v0.5.3 2025-05-07 02:39:16 +09:00
tsukumi
f0d3a52f1f Merge pull request #26 from kounoike/actions-build-on-container
ホストを24.04にして20.04のコンテナを使ってdebをビルド、dkms動作のチェック&buildのみを行うPRワークフロー追加
2025-04-30 02:28:43 +09:00
tsukumi
b13ef1c959 Merge pull request #27 from kounoike/dont-unload-at-dkms
新しいカーネルをインストールするとdkmsでモジュールがアンロードされてしまう問題の対策
2025-04-30 02:25:36 +09:00
KOUNOIKE Yuusuke
3829363fae dkmsのフックスクリプトでは今動いてるカーネルのモジュールには触らない 2025-04-30 01:47:52 +09:00
KOUNOIKE Yuusuke
8f6a0dbaa7 ホストを24.04にして20.04のコンテナを使ってdebをビルド、dkms動作のチェック&buildのみを行うPRワークフロー追加 2025-04-30 00:38:40 +09:00
tsukumi
4c647926c7 README: ドキュメントを加筆修正 2025-04-04 01:09:52 +09:00
tsukumi
63ed9e67d7 README: ドキュメントを加筆修正 (Close #16, #25) 2025-04-04 01:00:49 +09:00
tsukumi
ee968631a3 driver: ptx_chrdev_context_reserve() のヘッダー上の定義が欠落していたのを修正
現状全く使われていない関数なので残しておく必要があるのか…?とはなるが…
2025-01-22 01:41:34 +09:00
tsukumi
c2a33ddd2a driver: バージョン情報を更新するシェルスクリプトを追加 2025-01-22 01:37:31 +09:00
tsukumi
d9c3f9e24c Merge pull request #20 from kounoike/fix-ubsan
fix UBSAN false positive
2025-01-12 21:43:31 +09:00
KOUNOIKE Yuusuke
f282d1c100 fix UBSAN false positive 2025-01-12 17:08:46 +09:00
tsukumi
70d12956d2 winusb: pkg: BonDriver_ISDBT2071 には不要な BS/CS 向けチャンネル定義ファイルを同梱してしまっていたのを修正 2025-01-11 16:47:24 +09:00
tsukumi
2e62d1fe76 README: DTV03A-1TU の型番ミスを修正 2025-01-11 16:41:16 +09:00
tsukumi
cf161dd1ed v0.5.2 2025-01-11 08:55:50 +09:00
tsukumi
cc6c5b83ee Update: DTV03A-1TU 向けの BonDriver_ISDBT2071 をビルドするように設定 2025-01-11 08:52:04 +09:00
tsukumi
72363fcca1 README: ドキュメントを加筆修正 2025-01-11 08:48:26 +09:00
tsukumi
e2c5f170c3 winusb: pkg: BonDriver_PX4: 2024年10月~2025年1月のBSトランスポンダ再編・BS10 開局を ChSet.txt に反映 2025-01-11 08:39:22 +09:00
tsukumi
764e0e9c29 winusb: pkg: コミットし忘れていた署名ツールを追加
./sign.ps1 で新しいカタログ署名ファイルをビルドできる
2025-01-11 08:17:07 +09:00
tsukumi
dd518c7155 winusb: pkg: inf ファイルの追加に伴い、カタログ署名を更新 2025-01-11 08:16:32 +09:00
tsukumi
b97c90e398 Merge pull request #19 from hendecarows/feature/isdbt2071
Windows版に対してISDBT2071(DTV03A-1TU シリアル202111以降)への暫定的な対応を追加
2025-01-11 07:44:56 +09:00
hendecarows
adf8f45b5b Windows版に対してISDBT2071(DTV03A-1TU シリアル202111以降)への暫定的な対応を追加
TVTestで視聴は可能であるが、チャンネル変更後10秒程度、TS転送が不安定で、ドロップ及びエラーパケットが多量にカウントされる。デバイスの電源がOFFの状態で時間が経つと発生する様で、TVTest起動直後の初回チャンネル表示時には発生するが、2回目以降のチャンネル変更ではほぼ発生しない。TVTestを終了し、5分程度待った後、再度TVTestを起動すると発生する場合が多い。公式ドライバでも同様の事が起こること、2個のデバイスで同じことが起こることを確認している。ドライバ側での解決方法は発見できていない。
2024-10-23 00:26:27 +09:00
35 changed files with 1571 additions and 424 deletions

44
.github/workflows/build.yml vendored Normal file
View 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

View File

@@ -3,28 +3,48 @@ name: Build and Release Debian Package
on:
push:
tags:
- '*'
- "*"
jobs:
build_and_release:
name: Build and Release Debian Package
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
container:
image: ubuntu:20.04
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install DKMS
run: sudo apt-get install -y debhelper devscripts dh-exec dkms dpkg
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@v1
uses: softprops/action-gh-release@v2
with:
generate_release_notes: true
files: |

View File

@@ -12,7 +12,8 @@ PLEX 社の [Webサイト](http://plex-net.co.jp) にて配布されている公
- エラー発生時の MessageBox を表示しない設定を追加
- BonDriver の ini 内の `DisplayErrorMessage` を 1 に設定すると今まで通り MessageBox が表示される
- [hendecarows 氏のフォーク](https://github.com/hendecarows/px4_drv/tree/feature/isdb2056) での更新を取り込み、DTV02A-1T1S-U / PX-M1UR / PX-S1UR に対応
- 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 でもインストールできるようにする
@@ -40,8 +41,9 @@ PLEX 社の [Webサイト](http://plex-net.co.jp) にて配布されている公
- チップ構成が一部変更された、ロット番号 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 変更に対応
- [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) の作成とインストールに対応
@@ -70,14 +72,22 @@ PLEX 社の [Webサイト](http://plex-net.co.jp) にて配布されている公
- チップ構成が一部変更された、ロット番号 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 / 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)
@@ -107,6 +117,7 @@ Driver フォルダには、各機種ごとのドライバのインストール
- 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`
@@ -147,17 +158,17 @@ BonDriver と同じフォルダに DriverHost_PX4.exe / DriverHost_PX4.ini / it9
Debian パッケージを使用してインストールすると依存パッケージも自動インストールされるほか、DKMS のソースコード管理も透過的に行われます。
Ubuntu / Debian 環境では Debian パッケージを使用してインストールすることを強く推奨します。
$ wget https://github.com/tsukumijima/px4_drv/releases/download/v0.5.1/px4-drv-dkms_0.5.1_all.deb
$ sudo apt install -y ./px4-drv-dkms_0.5.1_all.deb
$ 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.1_all.deb` という名前の 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.1_all.deb
> $ sudo apt install -y ../px4-drv-dkms_0.5.4_all.deb
> ```
> 上記コマンドで、生成した px4_drv の Debian パッケージをインストールできます。
@@ -165,9 +176,9 @@ Ubuntu / Debian 環境では Debian パッケージを使用してインスト
gcc, make, カーネルソース/ヘッダ, dkms がインストールされている必要があります。
$ sudo cp -a ./ /usr/src/px4_drv-0.5.1
$ sudo dkms add px4_drv/0.5.1
$ sudo dkms install px4_drv/0.5.1
$ 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 を使用せずにインストールする
@@ -254,6 +265,13 @@ gcc, make, カーネルソース/ヘッダ, dkms がインストールされて
すべてのチューナーにおいて、ISDB-T のみ受信可能です。
##### e-Better DTV03A-1TU を接続した場合
$ ls /dev/isdbt2071video*
/dev/isdbt2071video0
すべてのチューナーにおいて、ISDB-T のみ受信可能です。
##### e-Better DTV02-1T1S-U/DTV02A-1T1S-U を接続した場合
$ ls /dev/isdb2056video*
@@ -262,7 +280,7 @@ gcc, make, カーネルソース/ヘッダ, dkms がインストールされて
すべてのチューナーにおいて、ISDB-T と ISDB-S のどちらも受信可能です。
> [!NOTE]
> ロット番号 2309 以降の DTV02A-1T1S-U を接続した場合も、デバイスファイル名は `/dev/isdb2056video*` となります。
> ロット番号 2309 以降の DTV02A-1T1S-U を接続した場合も、デバイスファイル名は `/dev/isdb2056video*` となります。
> `/dev/isdb2056nvideo*` ではないので注意してください。
##### e-Better DTV02A-4TS-P を接続した場合
@@ -294,8 +312,8 @@ gcc, make, カーネルソース/ヘッダ, dkms がインストールされて
#### DKMS を使用してインストールした場合
$ sudo dkms remove px4_drv/0.5.1 --all
$ sudo rm -rf /usr/src/px4_drv-0.5.1
$ sudo dkms remove px4_drv/0.5.4 --all
$ sudo rm -rf /usr/src/px4_drv-0.5.4
#### DKMS を使用せずにインストールした場合
@@ -344,7 +362,7 @@ Windows では、BonDriver_PX4-S.ini に記載の `LNBPower=0` を `LNBPower=1`
対応していないものとされていましたが、5ch の有志により、正しく LNB 電源を出力できることが確認されています ([参考](https://mevius.5ch.net/test/read.cgi/avi/1648542476/267-288))。
### e-Better DTV02-1T1S-U/DTV02A-1T1S-U
### PLEX PX-M1UR / e-Better DTV02-1T1S-U/DTV02A-1T1S-U
対応しておりません。

View File

@@ -1,5 +1,5 @@
PACKAGE_NAME="px4_drv"
PACKAGE_VERSION="0.5.1"
PACKAGE_VERSION="0.5.4"
CLEAN="cd ./driver; make clean"
MAKE="cd ./driver; make KVER=${kernelver} px4_drv.ko"
BUILT_MODULE_LOCATION="driver"

View File

@@ -1,11 +1,5 @@
#!/bin/sh
# Unload previous driver
KVER=`uname -r`
if [ `grep -e '^px4_drv' /proc/modules | wc -l` -ne 0 ]; then
modprobe -r px4_drv
fi
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

View File

@@ -1,12 +1,6 @@
#!/bin/sh
# Unload previous driver
KVER=`uname -r`
if [ `grep -e '^px4_drv' /proc/modules | wc -l` -ne 0 ]; then
modprobe -r px4_drv
fi
if [ `find /lib/modules/ -name px4_drv.ko | wc -l` -eq 0 ]; then
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

View File

@@ -9,6 +9,7 @@ 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
@@ -39,6 +40,9 @@ 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

View File

@@ -61,7 +61,7 @@ uninstall:
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 \
$(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)

View File

@@ -10,12 +10,17 @@
#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;
@@ -47,11 +52,20 @@ int init_module(void)
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");

View File

@@ -3,6 +3,6 @@
#ifndef __DRIVER_MODULE_H__
#define __DRIVER_MODULE_H__
#define PX4_DRV_VERSION "0.5.1"
#define PX4_DRV_VERSION "0.5.4"
#endif

View File

@@ -807,7 +807,7 @@ int ptx_chrdev_context_add_group(struct ptx_chrdev_context *chrdev_ctx,
base, num,
PTX_CHRDEV_MINOR_IN_USE);
group = kzalloc(sizeof(*group) + (sizeof(group->chrdev[0]) * (num - 1)),
group = kzalloc(sizeof(*group) + (sizeof(group->chrdev[0]) * num),
GFP_KERNEL);
if (!group) {
ret = -ENOMEM;

View File

@@ -100,7 +100,7 @@ struct ptx_chrdev_group {
void (*owner_kref_release)(struct kref *);
unsigned int minor_base;
unsigned int chrdev_num;
struct ptx_chrdev chrdev[1];
struct ptx_chrdev chrdev[];
};
#define PTX_CHRDEV_MINOR_FREE 0
@@ -124,6 +124,8 @@ 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,

View File

@@ -61,6 +61,11 @@
#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;
@@ -134,7 +139,7 @@ static int px4_usb_probe(struct usb_interface *intf,
dev_info(dev, "Multi-device power control: %s\n",
(px4_use_mldev) ? "enabled" : "disabled");
/* fall through */
fallthrough;
case USB_PID_PX_W3U4:
case USB_PID_PX_W3PE4:
case USB_PID_PX_W3PE5:
@@ -152,7 +157,7 @@ static int px4_usb_probe(struct usb_interface *intf,
case USB_PID_PX_MLT5U:
pxmlt5_model = PXMLT5U_MODEL;
/* fall through */
fallthrough;
case USB_PID_PX_MLT5PE:
ret = px4_usb_init_bridge(dev, usb_dev,
&ctx->ctx.pxmlt.it930x);
@@ -167,7 +172,7 @@ static int px4_usb_probe(struct usb_interface *intf,
case USB_PID_PX_MLT8PE3:
pxmlt8_model = PXMLT8PE3_MODEL;
/* fall through */
fallthrough;
case USB_PID_PX_MLT8PE5:
ret = px4_usb_init_bridge(dev, usb_dev,
&ctx->ctx.pxmlt.it930x);
@@ -236,9 +241,22 @@ static int px4_usb_probe(struct usb_interface *intf,
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:
@@ -305,6 +323,7 @@ static void px4_usb_disconnect(struct usb_interface *intf)
break;
case PXS1UR_USB_DEVICE:
case ISDBT2071_USB_DEVICE:
s1ur_device_term(&ctx->ctx.s1ur);
wait_for_completion(&ctx->quit_completion);
break;
@@ -348,6 +367,7 @@ static const struct usb_device_id px4_usb_ids[] = {
{ 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 }
};
@@ -373,6 +393,7 @@ int px4_usb_register()
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));
@@ -432,6 +453,14 @@ int px4_usb_register()
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");
@@ -441,14 +470,17 @@ int px4_usb_register()
return 0;
fail_usb:
ptx_chrdev_context_destroy(px4_usb_chrdev_ctx[ISDB6014_4TS_USB_DEVICE]);
ptx_chrdev_context_destroy(px4_usb_chrdev_ctx[ISDBT2071_USB_DEVICE]);
fail_pxs1ur:
fail_isdbt2071:
ptx_chrdev_context_destroy(px4_usb_chrdev_ctx[PXS1UR_USB_DEVICE]);
fail_pxm1ur:
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]);
@@ -468,6 +500,7 @@ fail:
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]);

View File

@@ -23,6 +23,7 @@
#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 {
@@ -34,6 +35,7 @@ enum px4_usb_device_type {
ISDB6014_4TS_USB_DEVICE,
PXM1UR_USB_DEVICE,
PXS1UR_USB_DEVICE,
ISDBT2071_USB_DEVICE,
//----
MAX_USB_DEVICE_TYPE,
};

View File

@@ -1,8 +1,10 @@
// 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"
@@ -71,12 +73,21 @@ static int s1ur_backend_init(struct s1ur_device *s1ur)
return ret;
}
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;
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);
@@ -87,15 +98,6 @@ static int s1ur_backend_init(struct s1ur_device *s1ur)
return ret;
}
#if 0
ret = rt710_init(&chrdevs1ur->rt710);
if (ret) {
dev_err(s1ur->dev,
"s1ur_backend_init: rt710_init() failed. (ret: %d)\n",
ret);
return ret;
}
#endif
return 0;
}
@@ -104,9 +106,6 @@ static int s1ur_backend_term(struct s1ur_device *s1ur)
struct s1ur_chrdev *chrdevs1ur = &s1ur->chrdevs1ur;
r850_term(&chrdevs1ur->r850);
#if 0
rt710_term(&chrdevs1ur->rt710);
#endif
tc90522_term(&chrdevs1ur->tc90522_t);
tc90522_term(&chrdevs1ur->tc90522_s);
@@ -201,7 +200,7 @@ static int s1ur_chrdev_init(struct ptx_chrdev *chrdev)
{
dev_dbg(chrdev->parent->dev, "s1ur_chrdev_init\n");
chrdev->params.system = PTX_UNSPECIFIED_SYSTEM;
chrdev->params.system = PTX_ISDB_T_SYSTEM;
return 0;
}
@@ -211,7 +210,7 @@ static int s1ur_chrdev_term(struct ptx_chrdev *chrdev)
return 0;
}
static struct tc90522_regbuf tc_init_t[] = {
static struct tc90522_regbuf tc_init_s1ur[] = {
{ 0xb0, NULL, { 0xa0 } },
{ 0xb2, NULL, { 0x3d } },
{ 0xb3, NULL, { 0x25 } },
@@ -222,12 +221,25 @@ static struct tc90522_regbuf tc_init_t[] = {
{ 0xb8, NULL, { 0xc0 } },
};
#if 0
static struct tc90522_regbuf tc_init_s[] = {
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 } },
{ 0x1d, 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 } },
};
#endif
static int s1ur_chrdev_open(struct ptx_chrdev *chrdev)
{
@@ -259,9 +271,18 @@ static int s1ur_chrdev_open(struct ptx_chrdev *chrdev)
}
/* 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;
ret = tc90522_write_multiple_regs(&chrdevs1ur->tc90522_t,
tc_init_t, ARRAY_SIZE(tc_init_t));
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",
@@ -278,8 +299,8 @@ static int s1ur_chrdev_open(struct ptx_chrdev *chrdev)
return ret;
}
/* sleep */
ret = tc90522_sleep_t(&chrdevs1ur->tc90522_t, true);
/* 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",
@@ -287,6 +308,14 @@ static int s1ur_chrdev_open(struct ptx_chrdev *chrdev)
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;
@@ -299,36 +328,32 @@ static int s1ur_chrdev_open(struct ptx_chrdev *chrdev)
return ret;
}
#if 0
/* Initialization for ISDB-S */
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;
}
ret = tc90522_write_multiple_regs(&chrdevs1ur->tc90522_s,
tc_init_s, ARRAY_SIZE(tc_init_s));
if (ret) {
dev_err(s1ur->dev,
"s1ur_chrdev_open %u: tc90522_write_multiple_regs(tc_init_s) 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;
}
/* 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;
}
#endif
kref_get(&s1ur->kref);
return 0;
@@ -371,7 +396,6 @@ static int s1ur_chrdev_tune(struct ptx_chrdev *chrdev,
struct s1ur_device,
chrdevs1ur);
bool tuner_locked;
/* s32 ss; */
dev_dbg(s1ur->dev,
"s1ur_chrdev_tune %u\n", chrdev_group->id);
@@ -390,50 +414,58 @@ static int s1ur_chrdev_tune(struct ptx_chrdev *chrdev,
break;
}
ret = tc90522_sleep_s(&chrdevs1ur->tc90522_s, true);
if (ret) {
dev_err(s1ur->dev,
"s1ur_chrdev_tune %u: tc90522_sleep_s(true) failed. (ret: %d)\n",
chrdev_group->id, ret);
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;
}
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_sleep_t(&chrdevs1ur->tc90522_t, false);
if (ret) {
dev_err(s1ur->dev,
"s1ur_chrdev_tune %u: tc90522_sleep_t(false) failed. (ret: %d)\n",
chrdev_group->id, 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;
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);
break;
}
ret = r850_set_frequency(&chrdevs1ur->r850, params->freq);
if (ret) {
dev_err(s1ur->dev,
@@ -478,124 +510,31 @@ static int s1ur_chrdev_tune(struct ptx_chrdev *chrdev,
break;
}
ret = tc90522_write_reg(&chrdevs1ur->tc90522_t, 0x71, 0x01);
if (ret)
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;
ret = tc90522_write_reg(&chrdevs1ur->tc90522_t, 0x72, 0x25);
if (ret)
break;
ret = tc90522_write_reg(&chrdevs1ur->tc90522_t, 0x75, 0x00);
if (ret)
case ISDBT2071_MODEL:
break;
}
msleep(100);
break;
#if 0
case PTX_ISDB_S_SYSTEM:
ret = tc90522_set_agc_s(&chrdevs1ur->tc90522_s, false);
if (ret) {
dev_err(s1ur->dev,
"s1ur_chrdev_tune %u: tc90522_set_agc_s(false) failed. (ret: %d)\n",
chrdev_group->id, ret);
break;
}
ret = tc90522_write_reg(&chrdevs1ur->tc90522_t, 0x0e, 0x11);
if (ret)
break;
ret = tc90522_write_reg(&chrdevs1ur->tc90522_t, 0x0f, 0x70);
if (ret)
break;
ret = tc90522_sleep_t(&chrdevs1ur->tc90522_t, true);
if (ret) {
dev_err(s1ur->dev,
"s1ur_chrdev_tune %u: tc90522_sleep_t(true) failed. (ret: %d)\n",
chrdev_group->id, ret);
break;
}
ret = tc90522_write_reg(&chrdevs1ur->tc90522_s, 0x07, 0x77);
if (ret)
break;
ret = tc90522_write_reg(&chrdevs1ur->tc90522_s, 0x08, 0x10);
if (ret)
break;
ret = tc90522_sleep_s(&chrdevs1ur->tc90522_s, false);
if (ret) {
dev_err(s1ur->dev,
"s1ur_chrdev_tune %u: tc90522_sleep_s(false) failed. (ret: %d)\n",
chrdev_group->id, ret);
break;
}
ret = tc90522_write_reg(&chrdevs1ur->tc90522_s, 0x04, 0x02);
if (ret)
break;
ret = tc90522_write_reg(&chrdevs1ur->tc90522_s, 0x8e, 0x02);
if (ret)
break;
ret = tc90522_write_reg(&chrdevs1ur->tc90522_t, 0x1f, 0x20);
if (ret)
break;
ret = rt710_set_params(&chrdevs1ur->rt710,
params->freq, 28860, 4);
if (ret) {
dev_err(s1ur->dev,
"s1ur_chrdev_tune %u: rt710_set_params(%u, 28860, 4) failed. (ret: %d)\n",
chrdev_group->id, params->freq, ret);
break;
}
i = 50;
while (i--) {
ret = rt710_is_pll_locked(&chrdevs1ur->rt710,
&tuner_locked);
if (!ret && tuner_locked)
break;
msleep(10);
}
if (ret) {
dev_err(s1ur->dev,
"s1ur_chrdev_tune %u: rt710_is_pll_locked() failed. (ret: %d)\n",
chrdev_group->id, ret);
break;
} else if (!tuner_locked) {
/* PLL error */
dev_err(s1ur->dev,
"s1ur_chrdev_tune %u: PLL is NOT locked.\n",
chrdev_group->id);
ret = -EAGAIN;
break;
}
rt710_get_rf_signal_strength(&chrdevs1ur->rt710, &ss);
dev_dbg(s1ur->dev,
"s1ur_chrdev_tune %u: PLL is locked. count: %d, signal strength: %d.%03ddBm\n",
chrdev_group->id, i, ss / 1000, -ss % 1000);
ret = tc90522_set_agc_s(&chrdevs1ur->tc90522_s, true);
if (ret) {
dev_err(s1ur->dev,
"s1ur_chrdev_tune %u: tc90522_set_agc_s(true) failed. (ret: %d)\n",
chrdev_group->id, ret);
break;
}
break;
#endif
default:
ret = -EINVAL;
break;
@@ -614,12 +553,7 @@ static int s1ur_chrdev_check_lock(struct ptx_chrdev *chrdev, bool *locked)
ret = tc90522_is_signal_locked_t(&chrdevs1ur->tc90522_t,
locked);
break;
#if 0
case PTX_ISDB_S_SYSTEM:
ret = tc90522_is_signal_locked_s(&chrdevs1ur->tc90522_s,
locked);
break;
#endif
default:
ret = -EINVAL;
break;
@@ -628,75 +562,6 @@ static int s1ur_chrdev_check_lock(struct ptx_chrdev *chrdev, bool *locked)
return ret;
}
static int s1ur_chrdev_set_stream_id(struct ptx_chrdev *chrdev,
u16 stream_id)
{
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);
struct tc90522_demod *tc90522_s = &chrdevs1ur->tc90522_s;
u16 tsid, tsid2;
dev_dbg(s1ur->dev,
"s1ur_chrdev_set_stream_id %u\n", chrdev_group->id);
if (chrdev->current_system != PTX_ISDB_S_SYSTEM)
return -EINVAL;
if (stream_id < 12) {
i = 100;
while (i--) {
ret = tc90522_tmcc_get_tsid_s(tc90522_s,
stream_id, &tsid);
if ((!ret && tsid) || ret == -EINVAL)
break;
msleep(10);
}
if (ret) {
dev_err(s1ur->dev,
"s1ur_chrdev_set_stream_id_s %u: tc90522_tmcc_get_tsid_s() failed. (ret: %d)\n",
chrdev_group->id, ret);
return ret;
}
if (!tsid) {
ret = -EAGAIN;
return ret;
}
} else {
tsid = stream_id;
}
ret = tc90522_set_tsid_s(tc90522_s, tsid);
if (ret) {
dev_err(s1ur->dev,
"s1ur_chrdev_set_stream_id_s %u: tc90522_set_tsid_s(0x%x) failed. (ret: %d)\n",
chrdev_group->id, tsid, ret);
return ret;
}
/* check slot */
i = 100;
while(i--) {
ret = tc90522_get_tsid_s(tc90522_s, &tsid2);
if (!ret && tsid2 == tsid)
break;
msleep(10);
}
if (tsid2 != tsid)
ret = -EAGAIN;
return ret;
}
static int s1ur_chrdev_start_capture(struct ptx_chrdev *chrdev)
{
int ret = 0;
@@ -730,18 +595,8 @@ static int s1ur_chrdev_start_capture(struct ptx_chrdev *chrdev)
break;
#if 0
case PTX_ISDB_S_SYSTEM:
ret = tc90522_enable_ts_pins_s(&chrdevs1ur->tc90522_s, true);
if (ret)
dev_err(s1ur->dev,
"s1ur_chrdev_start_capture %u: tc90522_enable_ts_pins_s(true) failed. (ret: %d)\n",
chrdev_group->id, ret);
break;
#endif
default:
ret = -EINVAL;
break;
}
@@ -770,13 +625,8 @@ fail_tc:
tc90522_enable_ts_pins_t(&chrdevs1ur->tc90522_t, false);
break;
#if 0
case PTX_ISDB_S_SYSTEM:
tc90522_enable_ts_pins_s(&chrdevs1ur->tc90522_s, false);
break;
#endif
default:
ret = -EINVAL;
break;
}
@@ -805,11 +655,6 @@ static int s1ur_chrdev_stop_capture(struct ptx_chrdev *chrdev)
tc90522_enable_ts_pins_t(&chrdevs1ur->tc90522_t, false);
break;
#if 0
case PTX_ISDB_S_SYSTEM:
tc90522_enable_ts_pins_s(&chrdevs1ur->tc90522_s, false);
break;
#endif
default:
break;
}
@@ -833,11 +678,6 @@ static int s1ur_chrdev_read_cnr_raw(struct ptx_chrdev *chrdev, u32 *value)
ret = tc90522_get_cndat_t(&chrdevs1ur->tc90522_t, value);
break;
#if 0
case PTX_ISDB_S_SYSTEM:
ret = tc90522_get_cn_s(&chrdevs1ur->tc90522_s, (u16 *)value);
break;
#endif
default:
ret = -EINVAL;
break;
@@ -853,7 +693,7 @@ static struct ptx_chrdev_operations s1ur_chrdev_ops = {
.release = s1ur_chrdev_release,
.tune = s1ur_chrdev_tune,
.check_lock = s1ur_chrdev_check_lock,
.set_stream_id = s1ur_chrdev_set_stream_id,
.set_stream_id = NULL,
.set_lnb_voltage = NULL,
.set_capture = s1ur_chrdev_set_capture,
.read_signal_strength = NULL,
@@ -881,7 +721,7 @@ static int s1ur_device_load_config(struct s1ur_device *s1ur,
return ret;
}
chrdev_config->system_cap = PTX_ISDB_T_SYSTEM | PTX_ISDB_S_SYSTEM;
chrdev_config->system_cap = PTX_ISDB_T_SYSTEM;
input->enable = true;
input->is_parallel = false;
@@ -911,31 +751,34 @@ static int s1ur_device_load_config(struct s1ur_device *s1ur,
chrdevs1ur->r850.config.no_imr_calibration = true;
chrdevs1ur->r850.config.no_lpf_calibration = true;
#if 0
chrdevs1ur->rt710.dev = dev;
chrdevs1ur->rt710.i2c = &chrdevs1ur->tc90522_s.i2c_master;
chrdevs1ur->rt710.i2c_addr = 0x7a;
chrdevs1ur->rt710.config.xtal = 24000;
chrdevs1ur->rt710.config.loop_through = false;
chrdevs1ur->rt710.config.clock_out = false;
chrdevs1ur->rt710.config.signal_output_mode = RT710_SIGNAL_OUTPUT_DIFFERENTIAL;
chrdevs1ur->rt710.config.agc_mode = RT710_AGC_POSITIVE;
chrdevs1ur->rt710.config.vga_atten_mode = RT710_VGA_ATTEN_OFF;
chrdevs1ur->rt710.config.fine_gain = RT710_FINE_GAIN_3DB;
chrdevs1ur->rt710.config.scan_mode = RT710_SCAN_MANUAL;
#endif
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;
for (i = 1; i < 5; i++) {
it930x->config.input[i].enable = false;
it930x->config.input[i].port_number = i;
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,
struct ptx_chrdev_context *chrdev_ctx,
struct completion *quit_completion)
enum s1ur_model s1ur_model,
struct ptx_chrdev_context *chrdev_ctx,
struct completion *quit_completion)
{
int ret = 0;
struct it930x_bridge *it930x;
@@ -954,6 +797,7 @@ int s1ur_device_init(struct s1ur_device *s1ur, struct 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);
@@ -1015,17 +859,6 @@ int s1ur_device_init(struct s1ur_device *s1ur, struct device *dev,
if (ret)
goto fail_device;
#if 0
ret = it930x_set_gpio_mode(it930x, 11, IT930X_GPIO_OUT, true);
if (ret)
goto fail_device;
/* LNB power supply: off */
ret = it930x_write_gpio(it930x, 11, false);
if (ret)
goto fail_device;
#endif
if (px4_device_params.discard_null_packets) {
struct it930x_pid_filter filter;

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* PTX driver definitions for PLEX PX-S1UR device (s1ur_device.h)
* PTX driver definitions for PLEX PX-S1UR and DIGIBEST ISDBT2071 (DTV03A-1TU) devices (s1ur_device.h)
*
* Copyright (c) 2023 techma.
*/
@@ -20,19 +20,25 @@
#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 rt710_tuner rt710;*/
};
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;
@@ -41,8 +47,9 @@ struct s1ur_device {
};
int s1ur_device_init(struct s1ur_device *s1ur, struct device *dev,
struct ptx_chrdev_context *chrdev_ctx,
struct completion *quit_completion);
enum s1ur_model s1ur_model,
struct ptx_chrdev_context *chrdev_ctx,
struct completion *quit_completion);
void s1ur_device_term(struct s1ur_device *s1ur);
#endif

View File

@@ -5,6 +5,7 @@ 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"

39
update_version.sh Executable file
View 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

View File

@@ -32,6 +32,8 @@ 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
@@ -131,6 +133,22 @@ Copy-Item build/x64/Release-static/DriverHost_PX4.exe dist/BonDriver_PX-M1UR_64b
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

View 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"

View File

@@ -1,42 +1,39 @@
;
; BonDriver_PX4 <EFBFBD>`<60><><EFBFBD><EFBFBD><EFBFBD>l<EFBFBD><6C><EFBFBD><EFBFBD><EFBFBD>`<60>t<EFBFBD>@<40>C<EFBFBD><43> (ISDB-S) (<28><><EFBFBD>{<7B>ɂ<EFBFBD><C982><EFBFBD><EFBFBD><EFBFBD><EFBFBD>q<EFBFBD><71><EFBFBD>g<EFBFBD>f<EFBFBD>W<EFBFBD>^<5E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>p)
; (BonDriver_PT3-ST<EFBFBD><EFBFBD>ChSet.txt<EFBFBD>ƌ݊<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
; BonDriver_PX4 チャンネル定義ファイル (ISDB-S) (日本における衛星波デジタル放送用)
; (BonDriver_PT3-STChSet.txtと互換性あり)
;
; <EFBFBD>`<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)
; チャンネル空間定義 ($チャンネル空間名<TAB>チャンネル空間ID)
$BS 0
$CS110 1
;
; <EFBFBD>`<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<EFBFBD>p))
; チャンネル定義 (チャンネル名<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 16433
BS05/TS0 0 5 2 17488
BS05/TS1 0 6 2 17489
BS09/TS0 0 7 4 16528
BS09/TS1 0 8 4 16529
BS09/TS2 0 9 4 16530
BS11/TS1 0 10 5 18097
BS11/TS2 0 11 5 18098
BS11/TS3 0 12 5 18099
BS13/TS0 0 13 6 16592
BS13/TS1 0 14 6 16593
BS13/TS2 0 15 6 18130
BS15/TS0 0 16 7 16625
BS15/TS1 0 17 7 16626
BS19/TS0 0 18 9 18224
BS19/TS1 0 19 9 18225
BS19/TS2 0 20 9 18226
BS19/TS3 0 21 9 18227
BS21/TS0 0 22 10 18256
BS21/TS1 0 23 10 18257
BS21/TS2 0 24 10 18258
BS23/TS0 0 25 11 18288
BS23/TS1 0 26 11 18801
BS23/TS2 0 27 11 18802
BS23/TS3 0 28 11 18803
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

View File

@@ -486,3 +486,23 @@ 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

View 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)"

Binary file not shown.

1
winusb/pkg/signing-tools/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
!*.exe

Binary file not shown.

Binary file not shown.

View File

@@ -4,11 +4,11 @@
#include <windows.h>
#define VER_FILE 0,5,1,0
#define VER_FILE_STR "0.5.1"
#define VER_FILE 0,5,4,0
#define VER_FILE_STR "0.5.4"
#define VER_PRODUCT 0,5,1,0
#define VER_PRODUCT_STR "0.5.1"
#define VER_PRODUCT 0,5,4,0
#define VER_PRODUCT_STR "0.5.4"
#define VER_COMMENTS_STR ""
#define VER_COMPANYNAME_STR "nns779"

View File

@@ -260,6 +260,7 @@
<ClCompile Include="device_notifier.cpp" />
<ClCompile Include="driver_host.cpp" />
<ClCompile Include="isdb2056_device.cpp" />
<ClCompile Include="isdbt2071_device.cpp" />
<ClCompile Include="itedtv_bus_winusb.c" />
<ClCompile Include="main.cpp" />
<ClCompile Include="misc_win.c" />
@@ -296,6 +297,7 @@
<ClInclude Include="device_notifier.hpp" />
<ClInclude Include="driver_host.hpp" />
<ClInclude Include="isdb2056_device.hpp" />
<ClInclude Include="isdbt2071_device.hpp" />
<ClInclude Include="misc_win.h" />
<ClInclude Include="notify_icon.hpp" />
<ClInclude Include="pipe_server.hpp" />

View File

@@ -108,6 +108,9 @@
<ClCompile Include="isdb2056_device.cpp">
<Filter>ソース ファイル</Filter>
</ClCompile>
<ClCompile Include="isdbt2071_device.cpp">
<Filter>ソース ファイル</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\driver\cxd2856er.h">
@@ -212,6 +215,9 @@
<ClInclude Include="isdb2056_device.hpp">
<Filter>ヘッダー ファイル</Filter>
</ClInclude>
<ClInclude Include="isdbt2071_device.hpp">
<Filter>ヘッダー ファイル</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\pkg\DriverHost_PX4\DriverHost_PX4.ini">

View File

@@ -10,6 +10,7 @@
#include "px4_device.hpp"
#include "pxmlt_device.hpp"
#include "isdb2056_device.hpp"
#include "isdbt2071_device.hpp"
namespace px4 {
@@ -50,6 +51,8 @@ DeviceManager::DeviceManager(const px4::DeviceDefinitionSet &device_defs, px4::R
type = DeviceType::PXMLT;
else if (it->first == L"ISDB2056")
type = DeviceType::ISDB2056;
else if (it->first == L"ISDBT2071")
type = DeviceType::ISDBT2071;
if (type == DeviceType::UNKNOWN)
continue;
@@ -149,6 +152,16 @@ void DeviceManager::Add(const std::wstring &path, const std::pair<DeviceType, px
break;
}
case px4::DeviceType::ISDBT2071:
{
auto dev = std::make_unique<Isdbt2071Device>(path, def.second, ++index_, receiver_manager_);
if (!dev->Init())
devices_.emplace(path, std::move(dev));
break;
}
default:
break;
}

View File

@@ -24,6 +24,7 @@ enum class DeviceType : std::uint32_t {
PX4,
PXMLT,
ISDB2056,
ISDBT2071,
};
class DeviceManager final {

View File

@@ -0,0 +1,872 @@
// isdbt2071_device.cpp
#include "isdbt2071_device.hpp"
#include <cassert>
#include <cmath>
#include "type.hpp"
#include "command.hpp"
#include "misc_win.h"
namespace px4 {
Isdbt2071Device::Isdbt2071Device(const std::wstring &path, const px4::DeviceDefinition &device_def, std::uintptr_t index, px4::ReceiverManager &receiver_manager)
: DeviceBase(path, device_def, index, receiver_manager),
model_(Isdbt2071DeviceModel::ISDBT2071),
config_(),
lock_(),
available_(true),
init_(false),
streaming_count_(0)
{
if (usb_dev_.descriptor.idVendor != 0x0511 || usb_dev_.descriptor.idProduct != 0x0052)
throw DeviceError("px4::Isdbt2071Device::Isdbt2071Device: unsupported device. (unknown vendor id or product id)");
LoadConfig();
memset(&it930x_, 0, sizeof(it930x_));
memset(&stream_ctx_, 0, sizeof(stream_ctx_));
}
Isdbt2071Device::~Isdbt2071Device()
{
Term();
}
void Isdbt2071Device::LoadConfig()
{
auto &configs = device_def_.configs;
if (configs.Exists(L"XferPackets"))
config_.usb.xfer_packets = px4::util::wtoui(configs.Get(L"XferPackets"));
if (configs.Exists(L"UrbMaxPackets"))
config_.usb.urb_max_packets = px4::util::wtoui(configs.Get(L"UrbMaxPackets"));
if (configs.Exists(L"MaxUrbs"))
config_.usb.max_urbs = px4::util::wtoui(configs.Get(L"MaxUrbs"));
if (configs.Exists(L"NoRawIo"))
config_.usb.no_raw_io = px4::util::wtob(configs.Get(L"NoRawIo"));
if (configs.Exists(L"ReceiverMaxPackets"))
config_.device.receiver_max_packets = px4::util::wtoui(configs.Get(L"ReceiverMaxPackets"));
if (configs.Exists(L"PsbPurgeTimeout"))
config_.device.psb_purge_timeout = px4::util::wtoi(configs.Get(L"PsbPurgeTimeout"));
if (configs.Exists(L"DiscardNullPackets"))
config_.device.discard_null_packets = px4::util::wtob(configs.Get(L"DiscardNullPackets"));
dev_dbg(&dev_, "px4::Isdbt2071Device::LoadConfig: model: %d\n", model_);
dev_dbg(&dev_, "px4::Isdbt2071Device::LoadConfig: xfer_packets: %u\n", config_.usb.xfer_packets);
dev_dbg(&dev_, "px4::Isdbt2071Device::LoadConfig: urb_max_packets: %u\n", config_.usb.urb_max_packets);
dev_dbg(&dev_, "px4::Isdbt2071Device::LoadConfig: max_urbs: %u\n", config_.usb.max_urbs);
dev_dbg(&dev_, "px4::Isdbt2071Device::LoadConfig: no_raw_io: %s\n", (config_.usb.no_raw_io) ? "true" : "false");
dev_dbg(&dev_, "px4::Isdbt2071Device::LoadConfig: receiver_max_packets: %u\n", config_.device.receiver_max_packets);
dev_dbg(&dev_, "px4::Isdbt2071Device::LoadConfig: psb_purge_timeout: %i\n", config_.device.psb_purge_timeout);
dev_dbg(&dev_, "px4::Isdbt2071Device::LoadConfig: discard_null_packets: %s\n", (config_.device.discard_null_packets) ? "true" : "false");
return;
}
int Isdbt2071Device::Init()
{
dev_dbg(&dev_, "px4::Isdbt2071Device::Init: init_: %s\n", (init_) ? "true" : "false");
std::lock_guard<std::recursive_mutex> lock(lock_);
if (init_)
return -EALREADY;
int ret = 0;
itedtv_bus &bus = it930x_.bus;
it930x_stream_input& input = it930x_.config.input[0];
bus.dev = &dev_;
bus.type = ITEDTV_BUS_USB;
bus.usb.dev = &usb_dev_;
bus.usb.ctrl_timeout = 3000;
it930x_.dev = &dev_;
it930x_.config.xfer_size = 188 * config_.usb.xfer_packets;
it930x_.config.i2c_speed = 0x07;
ret = itedtv_bus_init(&bus);
if (ret)
goto fail_bus;
ret = it930x_init(&it930x_);
if (ret)
goto fail_bridge;
input.enable = true;
input.is_parallel = false;
input.port_number = 4;
input.slave_number = 0;
input.i2c_bus = 3;
input.i2c_addr = 0x18;
input.packet_len = 188;
input.sync_byte = 0x47;
for (int i = 1; i < 5; i++) {
it930x_.config.input[i].enable = false;
it930x_.config.input[i].port_number = i - 1;
}
receiver_.reset(new Isdbt2071Receiver(*this, 0));
stream_ctx_.stream_buf = receiver_->GetStreamBuffer();
ret = it930x_raise(&it930x_);
if (ret)
goto fail_device;
ret = it930x_load_firmware(&it930x_, "it930x-firmware.bin");
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 (config_.device.discard_null_packets) {
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;
}
init_ = true;
for (auto it = device_def_.receivers.cbegin(); it != device_def_.receivers.cend(); ++it) {
px4::command::ReceiverInfo ri;
wcscpy_s(ri.device_name, device_def_.name.c_str());
ri.device_guid = device_def_.guid;
wcscpy_s(ri.receiver_name, it->name.c_str());
ri.receiver_guid = it->guid;
ri.systems = it->systems;
ri.index = it->index;
ri.data_id = 0;
receiver_manager_.Register(ri, receiver_.get());
}
return 0;
fail_device:
stream_ctx_.stream_buf = nullptr;
receiver_.reset();
it930x_term(&it930x_);
fail_bridge:
itedtv_bus_term(&bus);
fail_bus:
return ret;
}
void Isdbt2071Device::Term()
{
dev_dbg(&dev_, "px4::Isdbt2071Device::Term: init_: %s\n", (init_) ? "true" : "false");
std::unique_lock<std::recursive_mutex> lock(lock_);
if (!init_)
return;
receiver_manager_.Unregister(receiver_.get());
lock.unlock();
stream_ctx_.stream_buf = nullptr;
receiver_.reset();
lock.lock();
it930x_term(&it930x_);
itedtv_bus_term(&it930x_.bus);
init_ = false;
return;
}
void Isdbt2071Device::SetAvailability(bool available)
{
available_ = available;
}
ReceiverBase* Isdbt2071Device::GetReceiver(int id) const
{
if (id != 0)
throw std::out_of_range("receiver id out of range");
return receiver_.get();
}
const i2c_comm_master& Isdbt2071Device::GetI2cMaster(int bus) const
{
if (bus < 1 || bus > 3)
throw std::out_of_range("bus number out of range");
return it930x_.i2c_master[bus - 1];
}
int Isdbt2071Device::SetBackendPower(bool state)
{
dev_dbg(&dev_, "px4::Isdbt2071Device::SetBackendPower: %s\n", (state) ? "true" : "false");
int ret = 0;
std::lock_guard<std::recursive_mutex> lock(lock_);
if (!state && !available_)
return 0;
if (state) {
ret = it930x_write_gpio(&it930x_, 3, false);
if (ret)
return ret;
Sleep(100);
ret = it930x_write_gpio(&it930x_, 2, true);
if (ret)
return ret;
Sleep(20);
} else {
it930x_write_gpio(&it930x_, 2, false);
it930x_write_gpio(&it930x_, 3, true);
}
return 0;
}
int Isdbt2071Device::SetLnbVoltage(std::int32_t voltage)
{
dev_dbg(&dev_, "px4::Isdbt2071Device::SetBackendPower: voltage: %d\n", voltage);
return 0;
}
int Isdbt2071Device::PrepareCapture()
{
dev_dbg(&dev_, "px4::Isdbt2071Device::PrepareCapture\n");
int ret = 0;
std::lock_guard<std::recursive_mutex> lock(lock_);
if (streaming_count_)
return 0;
ret = it930x_purge_psb(&it930x_, config_.device.psb_purge_timeout);
if (ret)
dev_err(&dev_, "px4::Isdbt2071Device::PrepareCapture: it930x_purge_psb() failed. (ret: %d)\n", ret);
return (ret && ret != -ETIMEDOUT) ? ret : 0;
}
int Isdbt2071Device::StartCapture()
{
dev_dbg(&dev_, "px4::Isdbt2071Device::StartCapture\n");
int ret = 0;
std::lock_guard<std::recursive_mutex> lock(lock_);
if (!streaming_count_) {
it930x_.bus.usb.streaming.urb_buffer_size = 188 * config_.usb.urb_max_packets;
it930x_.bus.usb.streaming.urb_num = config_.usb.max_urbs;
it930x_.bus.usb.streaming.no_dma = true;
it930x_.bus.usb.streaming.no_raw_io = config_.usb.no_raw_io;
stream_ctx_.remain_len = 0;
ret = itedtv_bus_start_streaming(&it930x_.bus, StreamHandler, this);
if (ret) {
dev_err(&dev_, "px4::Isdbt2071Device::StartCapture: itedtv_bus_start_streaming() failed. (ret: %d)\n", ret);
return ret;
}
streaming_count_++;
}
dev_dbg(&dev_, "px4::Isdbt2071Device::StartCapture: streaming_count_: %u\n", streaming_count_);
return 0;
}
int Isdbt2071Device::StopCapture()
{
dev_dbg(&dev_, "px4::Isdbt2071Device::StopCapture\n");
std::lock_guard<std::recursive_mutex> lock(lock_);
if (streaming_count_) {
dev_dbg(&dev_, "px4::Isdbt2071Device::StopCapture: stopping...\n");
itedtv_bus_stop_streaming(&it930x_.bus);
streaming_count_ = 0;
}
return 0;
}
void Isdbt2071Device::StreamProcess(std::shared_ptr<px4::ReceiverBase::StreamBuffer> stream_buf, std::uint8_t **buf, std::size_t &len)
{
std::uint8_t *p = *buf;
std::size_t remain = len;
while (remain) {
std::size_t i = 0;
bool sync_remain = false;
while (true) {
if (((i + 1) * 188) <= remain) {
if (p[i * 188] == 0x47)
break;
} else {
sync_remain = true;
break;
}
i++;
}
if (i < ISDBT2071_DEVICE_TS_SYNC_COUNT) {
p++;
remain--;
continue;
}
std::size_t pkt_len = 188 * i;
stream_buf->Write(p, pkt_len);
p += 188 * i;
remain -= 188 * i;
if (sync_remain)
break;
}
stream_buf->NotifyWrite();
*buf = p;
len = remain;
return;
}
int Isdbt2071Device::StreamHandler(void *context, void *buf, std::uint32_t len)
{
Isdbt2071Device &obj = *static_cast<Isdbt2071Device*>(context);
StreamContext &stream_ctx = obj.stream_ctx_;
std::uint8_t *p = static_cast<std::uint8_t*>(buf);
std::size_t remain = len;
if (stream_ctx.remain_len) {
if ((stream_ctx.remain_len + len) >= ISDBT2071_DEVICE_TS_SYNC_SIZE) {
std::uint8_t * remain_buf = stream_ctx.remain_buf;
std::size_t t = ISDBT2071_DEVICE_TS_SYNC_SIZE - stream_ctx.remain_len;
memcpy(remain_buf + stream_ctx.remain_len, p, t);
stream_ctx.remain_len = ISDBT2071_DEVICE_TS_SYNC_SIZE;
StreamProcess(stream_ctx.stream_buf, &remain_buf, stream_ctx.remain_len);
if (!stream_ctx.remain_len) {
p += t;
remain -= t;
}
stream_ctx.remain_len = 0;
} else {
memcpy(stream_ctx.remain_buf + stream_ctx.remain_len, p, len);
stream_ctx.remain_len += len;
return 0;
}
}
StreamProcess(stream_ctx.stream_buf, &p, remain);
if (remain) {
memcpy(stream_ctx.remain_buf, p, remain);
stream_ctx.remain_len = remain;
}
return 0;
}
struct tc90522_regbuf Isdbt2071Device::Isdbt2071Receiver::tc_init_t_[] = {
{ 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 } },
};
Isdbt2071Device::Isdbt2071Receiver::Isdbt2071Receiver(Isdbt2071Device &parent, std::uintptr_t index)
: ReceiverBase(RECEIVER_WAIT_AFTER_LOCK_TC_T),
parent_(parent),
index_(index),
lock_(),
init_(false),
open_(false),
system_(px4::SystemType::ISDB_T),
streaming_(false)
{
memset(&r850_, 0, sizeof(r850_));
const device *dev = &parent_.GetDevice();
const i2c_comm_master *i2c = &parent_.GetI2cMaster(parent_.it930x_.config.input[0].i2c_bus);
tc90522_t_.dev = dev;
tc90522_t_.i2c = i2c;
tc90522_t_.i2c_addr = 0x18;
tc90522_t_.is_secondary = false;
r850_.dev = dev;
r850_.i2c = &tc90522_t_.i2c_master;
r850_.i2c_addr = 0x7c;
r850_.config.xtal = 24000;
r850_.config.loop_through = !tc90522_t_.is_secondary;
r850_.config.clock_out = false;
r850_.config.no_imr_calibration = true;
r850_.config.no_lpf_calibration = true;
}
Isdbt2071Device::Isdbt2071Receiver::~Isdbt2071Receiver()
{
dev_dbg(&parent_.dev_, "px4::Isdbt2071Device::Isdbt2071Receiver::~Isdbt2071Receiver(%u)\n", index_);
std::unique_lock<std::mutex> lock(lock_);
close_cond_.wait(lock, [this] { return !open_; });
dev_dbg(&parent_.dev_, "px4::Isdbt2071Device::Isdbt2071Receiver::~Isdbt2071Receiver(%u): exit\n", index_);
}
int Isdbt2071Device::Isdbt2071Receiver::Init(bool sleep)
{
dev_dbg(&parent_.dev_, "px4::Isdbt2071Device::Isdbt2071Receiver::Init(%u): init_: %s, sleep: %s\n", index_, (init_) ? "true" : "false", (sleep) ? "true" : "false");
int ret = 0;
std::lock_guard<std::recursive_mutex> dev_lock(parent_.lock_);
if (init_)
return 0;
ret = tc90522_init(&tc90522_t_);
if (ret) {
dev_err(&parent_.dev_, "px4::Isdbt2071Device::Isdbt2071Receiver::Init(%u): tc90522_init() (t) failed. (ret: %d)\n", index_, ret);
return ret;
}
ret = r850_init(&r850_);
if (ret) {
dev_err(&parent_.dev_, "px4::Isdbt2071Device::Isdbt2071Receiver::Init(%u): r850_init() failed. (ret: %d)\n", index_, ret);
return ret;
}
if (sleep) {
ret = r850_sleep(&r850_);
if (ret) {
dev_err(&parent_.dev_, "px4::Isdbt2071Device::Isdbt2071Receiver::Init(%u): r850_sleep() failed. (ret: %d)\n", index_, ret);
return ret;
}
ret = tc90522_sleep_t(&tc90522_t_, true);
if (ret) {
dev_err(&parent_.dev_, "px4::Isdbt2071Device::Isdbt2071Receiver::Init(%u): tc90522_sleep_t(true) failed. (ret: %d)\n", index_, ret);
return ret;
}
}
if (!ret)
init_.store(true);
return ret;
}
void Isdbt2071Device::Isdbt2071Receiver::Term()
{
dev_dbg(&parent_.dev_, "px4::Isdbt2071Device::Isdbt2071Receiver::Term(%u): init_: %s\n", index_, (init_) ? "true" : "false");
std::lock_guard<std::recursive_mutex> dev_lock(parent_.lock_);
if (!init_)
return;
r850_term(&r850_);
tc90522_term(&tc90522_t_);
init_ = false;
return;
}
int Isdbt2071Device::Isdbt2071Receiver::Open()
{
dev_dbg(&parent_.dev_, "px4::Isdbt2071Device::Isdbt2071Receiver::Open(%u): init_: %s, open_: %s\n", index_, (init_) ? "true" : "false", (open_) ? "true" : "false");
int ret = 0;
std::unique_lock<std::mutex> lock(lock_);
std::unique_lock<std::recursive_mutex> dev_lock(parent_.lock_);
if (open_)
return (!init_) ? -EINVAL : -EALREADY;
ret = parent_.SetBackendPower(true);
if (ret) {
dev_err(&parent_.dev_, "px4::Isdbt2071Device::Isdbt2071Receiver::Open(%u): parent_.SetBackendPower(true) failed. (ret: %d)\n", index_, ret);
return ret;
}
ret = parent_.receiver_->Init(true);
if (ret) {
dev_err(&parent_.dev_, "px4::Isdbt2071Device::Isdbt2071Receiver::Open(%u): parent_.reciver_->Init(true) failed. (ret: %d)\n", index_, ret);
parent_.SetBackendPower(false);
return ret;
}
ret = tc90522_write_multiple_regs(&tc90522_t_, tc_init_t_, ARRAY_SIZE(tc_init_t_));
if (ret) {
dev_err(&parent_.dev_, "px4::Isdbt2071Device::Isdbt2071Receiver::Open(%u): tc90522_write_multiple_regs(tc_init_t) failed. (ret: %d)\n", index_, ret);
goto fail;
}
ret = tc90522_enable_ts_pins_t(&tc90522_t_, false);
if (ret) {
dev_err(&parent_.dev_, "px4::Isdbt2071Device::Isdbt2071Receiver::Open(%u): tc90522_enable_ts_pins_t(false) failed. (ret: %d)\n", index_, ret);
goto fail;
}
ret = tc90522_sleep_t(&tc90522_t_, false);
if (ret) {
dev_err(&parent_.dev_, "px4::Isdbt2071Device::Isdbt2071Receiver::Open(%u): tc90522_sleep_t(false) failed. (ret: %d)\n", index_, ret);
goto fail;
}
ret = r850_wakeup(&r850_);
if (ret) {
dev_err(&parent_.dev_, "px4::Isdbt2071Device::Isdbt2071Receiver::Open(%u): r850_wakeup() failed. (ret: %d)\n", index_, ret);
goto fail;
}
r850_system_config sys;
sys.system = R850_SYSTEM_ISDB_T;
sys.bandwidth = R850_BANDWIDTH_6M;
sys.if_freq = 4063;
ret = r850_set_system(&r850_, &sys);
if (ret) {
dev_err(&parent_.dev_, "px4::Isdbt2071Device::Isdbt2071Receiver::Open(%u): r850_set_system() failed. (ret: %d)\n", index_, ret);
goto fail;
}
open_ = true;
return ret;
fail:
parent_.Term();
parent_.SetBackendPower(false);
return ret;
}
void Isdbt2071Device::Isdbt2071Receiver::Close()
{
dev_dbg(&parent_.dev_, "px4::Isdbt2071Device::Isdbt2071Receiver::Close(%u): init_: %s, open_: %s\n", index_, (init_) ? "true" : "false", (open_) ? "true" : "false");
if (!init_ || !open_)
return;
SetCapture(false);
SetLnbVoltage(0);
std::unique_lock<std::mutex> lock(lock_);
std::lock_guard<std::recursive_mutex> dev_lock(parent_.lock_);
parent_.receiver_->Term();
parent_.SetBackendPower(false);
open_ = false;
lock.unlock();
close_cond_.notify_all();
return;
}
int Isdbt2071Device::Isdbt2071Receiver::SetFrequency()
{
if (!init_ || !open_)
return -EINVAL;
dev_dbg(&parent_.dev_, "px4::Isdbt2071Device::Isdbt2071Receiver::SetFrequency(%u): system: %d freq: %u\n", index_, params_.system, params_.freq);
int ret = 0;
std::lock_guard<std::mutex> lock(lock_);
switch (params_.system) {
case px4::SystemType::ISDB_T:
{
ret = tc90522_set_agc_t(&tc90522_t_, false);
if (ret) {
dev_err(&parent_.dev_, "px4::Isdbt2071Device::Isdbt2071Receiver::SetFrequency(%u): tc90522_set_agc_t(false) failed. (ret: %d)\n", index_, ret);
break;
}
ret = tc90522_write_reg(&tc90522_t_, 0x76, 0x03);
if (ret)
break;
ret = tc90522_write_reg(&tc90522_t_, 0x77, 0x01);
if (ret)
break;
ret = tc90522_write_reg(&tc90522_t_, 0x3b, 0x10);
if (ret)
break;
ret = tc90522_write_reg(&tc90522_t_, 0x3c, 0x10);
if (ret)
break;
ret = tc90522_write_reg(&tc90522_t_, 0x47, 0x30);
if (ret)
break;
ret = tc90522_write_reg(&tc90522_t_, 0x3d, 0x24);
if (ret)
break;
ret = r850_set_frequency(&r850_, params_.freq);
if (ret) {
dev_err(&parent_.dev_, "px4::Isdbt2071Device::Isdbt2071Receiver::SetFrequecy(%u): r850_set_frequency(%u) failed. (ret: %d)\n", index_, params_.freq, ret);
break;
}
bool tuner_locked = false;
for (int i = 25; i; i--) {
ret = r850_is_pll_locked(&r850_, &tuner_locked);
if (!ret && tuner_locked)
break;
Sleep(20);
}
if (ret)
break;
if (!tuner_locked) {
dev_dbg(&parent_.dev_, "px4::Isdbt2071Device::Isdbt2071Receiver::SetFrequency(%u): tuner is NOT locked.\n", index_);
ret = -EAGAIN;
break;
}
ret = tc90522_set_agc_t(&tc90522_t_, true);
if (ret) {
dev_err(&parent_.dev_, "px4::Isdbt2071Device::Isdbt2071Receiver::SetFrequency(%u): tc90522_set_agc_t(true) failed. (ret: %d)\n", index_, ret);
break;
}
break;
}
default:
ret = -EINVAL;
break;
}
dev_dbg(&parent_.dev_, "px4::Isdbt2071Device::Isdbt2071Receiver::SetFrequency(%u): %s.\n", index_, (!ret) ? "succeeded" : "failed");
return ret;
}
int Isdbt2071Device::Isdbt2071Receiver::CheckLock(bool &locked)
{
if (!init_ || !open_)
return -EINVAL;
int ret = 0;
std::lock_guard<std::mutex> lock(lock_);
switch (system_) {
case px4::SystemType::ISDB_T:
ret = tc90522_is_signal_locked_t(&tc90522_t_, &locked);
break;
default:
ret = -EINVAL;
break;
}
if (locked) {
dev_dbg(&parent_.dev_, "px4::Isdbt2071Device::Isdbt2071Receiver::CheckLock(%u): system: %d locked: true\n", index_, system_);
lock_.unlock();
ret = SetCapture(true);
lock_.lock();
}
return ret;
}
int Isdbt2071Device::Isdbt2071Receiver::SetStreamId()
{
return -EINVAL;
}
int Isdbt2071Device::Isdbt2071Receiver::SetLnbVoltage(std::int32_t voltage)
{
return 0;
}
int Isdbt2071Device::Isdbt2071Receiver::SetCapture(bool capture)
{
if (!init_ || !open_)
return -EINVAL;
dev_dbg(&parent_.dev_, "px4::Isdbt2071Device::Isdbt2071Receiver::SetCapture(%u): capture: %s\n", index_, (capture) ? "true" : "false");
int ret = 0;
std::lock_guard<std::mutex> lock(lock_);
switch (system_) {
case px4::SystemType::ISDB_T:
ret = tc90522_enable_ts_pins_t(&tc90522_t_, capture);
if (ret)
dev_err(&parent_.dev_, "px4::Isdbt2071Device::Isdbt2071Receiver::SetCapture(%u): tc90522_enable_ts_pins_t() failed.\n", index_);
break;
default:
return 0;
}
if (ret)
return ret;
if (capture) {
ret = parent_.PrepareCapture();
if (ret)
return ret;
ret = parent_.StartCapture();
if (ret)
return ret;
std::size_t size = 188 * parent_.config_.device.receiver_max_packets;
if (!streaming_) {
stream_buf_->Alloc(size);
stream_buf_->SetThresholdSize(size / 10);
stream_buf_->Start();
streaming_ = true;
} else {
stream_buf_->Purge();
}
} else {
ret = parent_.StopCapture();
if (ret)
return ret;
stream_buf_->Stop();
streaming_ = false;
}
dev_dbg(&parent_.dev_, "px4::Isdbt2071Device::Isdbt2071Receiver::SetCapture(%u): succeeded.\n", index_);
return ret;
}
int Isdbt2071Device::Isdbt2071Receiver::ReadStat(px4::command::StatType type, std::int32_t &value)
{
if (!init_ || !open_)
return -EINVAL;
int ret = 0;
std::lock_guard<std::mutex> lock(lock_);
value = 0;
switch (type) {
case px4::command::StatType::SIGNAL_STRENGTH:
// not implemented
ret = -ENOSYS;
break;
case px4::command::StatType::CNR:
switch (system_) {
case px4::SystemType::ISDB_T:
{
std::uint32_t cndat;
ret = tc90522_get_cndat_t(&tc90522_t_, &cndat);
if (ret)
break;
if (!cndat)
break;
double p, cnr;
p = 10 * std::log10(5505024 / (double)cndat);
cnr = (0.024 * p * p * p * p) - (1.6 * p * p * p) + (39.8 * p * p) + (549.1 * p) + 3096.5;
if (!std::isnan(cnr))
value = static_cast<std::int32_t>(cnr);
break;
}
default:
ret = -EINVAL;
break;
}
break;
default:
ret = -EINVAL;
break;
}
return ret;
}
} // namespace px4

View File

@@ -0,0 +1,149 @@
// isdbt2071_device.hpp
#pragma once
#include <cstdint>
#include <memory>
#include <atomic>
#include <string>
#include <mutex>
#include <condition_variable>
#include "device_definition_set.hpp"
#include "device_base.hpp"
#include "receiver_base.hpp"
#include "receiver_manager.hpp"
#include "ringbuffer.hpp"
#include "winusb_compat.h"
#include "i2c_comm.h"
#include "it930x.h"
#include "itedtv_bus.h"
#include "tc90522.h"
#include "r850.h"
namespace px4 {
#define ISDBT2071_DEVICE_TS_SYNC_COUNT 4U
#define ISDBT2071_DEVICE_TS_SYNC_SIZE (188U * ISDBT2071_DEVICE_TS_SYNC_COUNT)
enum class Isdbt2071DeviceModel {
ISDBT2071 = 0,
OTHER,
};
struct Isdbt2071DeviceConfig final {
Isdbt2071DeviceConfig()
: usb{ 816, 816, 5, false },
device{ 2048, 2000, true }
{}
struct {
unsigned int xfer_packets;
unsigned int urb_max_packets;
unsigned int max_urbs;
bool no_raw_io;
} usb;
struct {
unsigned int receiver_max_packets;
int psb_purge_timeout;
bool discard_null_packets;
} device;
};
class Isdbt2071Device final : public px4::DeviceBase {
public:
Isdbt2071Device() = delete;
Isdbt2071Device(const std::wstring &path, const px4::DeviceDefinition &device_def, std::uintptr_t index, px4::ReceiverManager &receiver_manager);
~Isdbt2071Device();
// cannot copy
Isdbt2071Device(const Isdbt2071Device &) = delete;
Isdbt2071Device& operator=(const Isdbt2071Device &) = delete;
// cannot move
Isdbt2071Device(Isdbt2071Device &&) = delete;
Isdbt2071Device& operator=(Isdbt2071Device &&) = delete;
int Init() override;
void Term() override;
void SetAvailability(bool available) override;
px4::ReceiverBase * GetReceiver(int id) const override;
private:
struct StreamContext final {
std::shared_ptr<px4::ReceiverBase::StreamBuffer> stream_buf;
std::uint8_t remain_buf[ISDBT2071_DEVICE_TS_SYNC_SIZE];
std::size_t remain_len;
};
class Isdbt2071Receiver final : public px4::ReceiverBase {
public:
Isdbt2071Receiver() = delete;
Isdbt2071Receiver(Isdbt2071Device &parent, std::uintptr_t index);
~Isdbt2071Receiver();
// cannot copy
Isdbt2071Receiver(const Isdbt2071Receiver &) = delete;
Isdbt2071Receiver& operator=(const Isdbt2071Receiver &) = delete;
// cannot move
Isdbt2071Receiver(Isdbt2071Receiver &&) = delete;
Isdbt2071Receiver& operator=(Isdbt2071Receiver &&) = delete;
int Init(bool sleep);
void Term();
int Open() override;
void Close() override;
int CheckLock(bool &locked) override;
int SetLnbVoltage(std::int32_t voltage) override;
int SetCapture(bool capture) override;
int ReadStat(px4::command::StatType type, std::int32_t &value) override;
protected:
int SetFrequency() override;
int SetStreamId() override;
private:
static struct tc90522_regbuf tc_init_t_[];
Isdbt2071Device &parent_;
std::uintptr_t index_;
std::mutex lock_;
std::atomic_bool init_;
std::atomic_bool open_;
std::condition_variable close_cond_;
tc90522_demod tc90522_t_;
r850_tuner r850_;
px4::SystemType system_;
std::atomic_bool streaming_;
};
void LoadConfig();
const i2c_comm_master& GetI2cMaster(int bus) const;
int SetBackendPower(bool state);
int SetLnbVoltage(std::int32_t voltage);
int PrepareCapture();
int StartCapture();
int StopCapture();
static void StreamProcess(std::shared_ptr<px4::ReceiverBase::StreamBuffer> stream_buf, std::uint8_t **buf, std::size_t &len);
static int StreamHandler(void *context, void *buf, std::uint32_t len);
Isdbt2071DeviceModel model_;
Isdbt2071DeviceConfig config_;
std::recursive_mutex lock_;
std::atomic_bool available_;
std::atomic_bool init_;
unsigned int streaming_count_;
std::unique_ptr<Isdbt2071Receiver> receiver_;
it930x_bridge it930x_;
StreamContext stream_ctx_;
};
} // namespace px4

View File

@@ -4,11 +4,11 @@
#include <windows.h>
#define VER_FILE 0,5,1,0
#define VER_FILE_STR "0.5.1"
#define VER_FILE 0,5,4,0
#define VER_FILE_STR "0.5.4"
#define VER_PRODUCT 0,5,1,0
#define VER_PRODUCT_STR "0.5.1"
#define VER_PRODUCT 0,5,4,0
#define VER_PRODUCT_STR "0.5.4"
#define VER_COMMENTS_STR ""
#define VER_COMPANYNAME_STR "nns779"