Three USB DVB devices, one Debian box with a mainline kernel, and three completely different ways to get a driver working in 2026:
In the end all three work, and I captured live Turksat 42E transponders with the two tuners and looped a TS file out of the modulator. This post is the long version of how.
A couple of years ago I wrote about each of these devices separately
(DTU-315,
TBS5530). Since then I
moved to Debian (forky/sid) running a self-built mainline kernel
(7.0.0-...-dcn31fix), and the driver story changed for every single device. So
this is a 2026 refresh: same hardware, new OS, new kernel, new gotchas.
My goal this time was a bit bigger: drive all three devices from one machine so I can capture live satellite TS with the tuners and play back TS files through the modulator (a self-contained RF loopback on the bench).
Here are the three devices:
DTU-315 (DVB modulator):

TBS5530 (DVB-S/T/C tuner):

WinTV-NOVA-S2, also sold as PCTV 461e (DVB-S2 tuner):

Last time I used the tsduck/dektec-dkms GitHub project for the kernel module.
Don’t do that anymore. That project is now archived, and its README says it
all:
Starting with version 2024.06.0, the Dektec LinuxSDK includes its own DKMS installation and this specific project is no longer necessary.
Its last release does not even compile on a modern kernel. The correct source in 2026 is the Dektec LinuxSDK, downloaded straight from the Dektec website:
# https://www.dektec.com/products/SDK/DTAPI/Downloads/LinuxSDK_v2026.05.0.tar.gz
tar xzf LinuxSDK_v2026.05.0.tar.gz # creates ./LinuxSDK/
cd LinuxSDK/Drivers
sudo ./Install_Dtu # DKMS install of the Dtu USB driver
The SDK ships the driver source, its own DKMS scripts, and the DTAPI C++
library (precompiled) that TSDuck’s dektec plugin needs later. One annoyance:
the SDK’s Install script has a buggy kernel-headers precheck:
[[ -d "/lib/modules/$KERNEL/build/kernel" ]] || error "kernel headers are not installed"
Debian’s linux-headers packages don’t ship a build/kernel/ subdir, so this
wrongly fails even though the headers are fine and the module builds. I changed
it to a correct check:
[[ -f "/lib/modules/$KERNEL/build/Makefile" ]] || error "kernel headers are not installed"
That’s the only change needed; the driver itself compiles cleanly on kernel 7.0.0. After that:
$ sudo modprobe Dtu
$ dmesg | grep Dtu
Dtu: The Dtu driver V4.15.5.93 has loaded successfully.
Dtu: < EzUsbInit > FX3 firmware uploaded
usbcore: registered new interface driver Dtu
$ ls -l /dev/Dtu*
crw------- 1 root root 180, 4 ... /dev/Dtu4
The DTU-315 is a Cypress FX3 device; the driver uploads the FX3 firmware and
creates /dev/Dtu4. Done.
One hardware gotcha: when the DTU-315 starts actively modulating it draws
noticeably more current. On a bus-powered USB hub it browned out and dropped off
the bus with DTAPI_E_EVENT_POWER mid-stream. Moving it to a direct,
self-powered USB port fixed it completely.
There is still no mainline driver for the TBS5530. TBS’s own linux_media fork
used to crash for me (I had to patch an array-overflow last time). This round I
used the cleaner community driver
koreapyj/cxd28xx (Sony CXD2878 +
Montage M88RS6060), which builds out-of-tree via DKMS:
git clone --depth 1 https://github.com/koreapyj/cxd28xx.git
cd cxd28xx
make
sudo dkms add .
sudo dkms build cxd28xx/0.0.1
sudo dkms install cxd28xx/0.0.1 --force
Like every TBS device, it needs firmware or the probe fails with
Direct firmware load for dvb-usb-id5530.fw failed with error -2:
curl -fL -o tbs-fw.tar.bz2 \
http://www.tbsdtv.com/download/document/linux/tbs-tuner-firmwares_v1.0.tar.bz2
mkdir -p /tmp/tbs-fw && tar xjf tbs-fw.tar.bz2 -C /tmp/tbs-fw
sudo install -m644 /tmp/tbs-fw/dvb-usb-id5530.fw \
/tmp/tbs-fw/dvb-demod-m88rs6060.fw /lib/firmware/
sudo modprobe -r tbs5530; sudo modprobe tbs5530
Nice surprise: it compiled cleanly on kernel 7.0.0 with no source patching this time. After the cold->warm firmware cycle:
dvbdev: DVB: registering new adapter (TurboSight TBS 5530)
i2c: Detect CXD2878/CXD6802(SiP) chip.
DVB: registering adapter 0 frontend 0 (... DVB-T/T2/C/C2,ISDB-T/C,ATSC,J83B,ATSC3)
i2c: found a 'Montage m88rs6060' ... warm state, firmware version:30
DVB: registering adapter X frontend Y (TurboSight TBS 5530 DVB-S/S2/S2X)
tbs5530: TurboSight TBS 5530 attached
You get two frontends: one for DVB-T/T2/C/ATSC and one for DVB-S/S2/S2X. This device was the most painless of the three.
This is the one that ate a whole evening. The stick (USB id 2013:0462) is the
461e v3 / “BBH9” revision. It looks identical to the older one, but Hauppauge
quietly swapped the demodulator from the Montage M88DS3103B to the newer
M88DS3103C. That tiny change means:
m88ds3103 driver does not know the C revision, and2013:0462 is not in the em28xx device table.So on a stock kernel the stick shows up in lsusb but no driver binds and no
/dev/dvb/adapter* appears.
Support was only submitted to linux-media on 2026-03-17 by Bradford Love (two patches: m88ds3103: Implement 3103c chip support and em28xx: Add Hauppauge 461e v3). It has since landed in the mainline tree, but it is not in the v6.17 / v7.0 tags, so my kernel didn’t have it. Since I build my own kernel anyway, I applied the two patches and rebuilt:
0002-m88ds3103-Implement-3103c-chip-support.patch # the whole 3103c code path
0003-em28xx-Add-Hauppauge-461e-v3.patch # board entry + 2013:0462 id
And - this is the step everyone forgets - the demod firmware is never bundled in the kernel; you install it by hand:
sudo curl -fL -o /lib/firmware/dvb-demod-m88ds3103c.fw \
https://hauppauge.s3.us-east-1.amazonaws.com/linux/dvb-demod-m88ds3103c.fw
After a reboot into the patched kernel the whole chain comes up:
em28xx 1-3:1.0: Identified as PCTV DVB-S2 Stick (461e v3) (card=108)
ts2020 ...: Montage Technology TS2022 successfully identified
a8293 ...: Allegro A8293 SEC successfully attached
em28xx ...: DVB: registering adapter 0 frontend 0 (Montage Technology M88DS3103C)
m88ds3103 ...: downloading firmware from file 'dvb-demod-m88ds3103c.fw'
m88ds3103 ...: firmware version: 3.8
Full chain: em28178 USB bridge + m88ds3103c demod + ts2022 tuner + a8293 LNB
power controller. /dev/dvb/adapterN finally appears.
I spent a long time chasing “no lock” on the 461e, so let me save you the pain.
Gotcha A - is the LNB actually powered? Connected directly to a dish, the 461e has to power the LNB itself through its A8293 chip. When it didn’t lock, I suspected the LNB power path. So I grabbed a multimeter and measured the voltage right at the F-connector while forcing the driver to command 13 V and then 18 V:
| Commanded | Measured |
|---|---|
| 13 V (vertical) | 12.69 V |
| 18 V (horizontal) | 17.65 V |
Both healthy - so the SEC/LNB power was fine and the driver was innocent. (A multimeter is an underrated DVB debugging tool.)
Gotcha B - DVB-S vs DVB-S2. This was the real culprit. On Turksat 42E some transponders are DVB-S2 (8PSK) and some older ones are plain DVB-S (QPSK). DVB-S is always QPSK. I had two transponders listed as DVB-S2 in my notes that are actually DVB-S. If you tell the demod to look for DVB-S2 on a DVB-S carrier, it tunes, sees signal, but never locks - which looks exactly like a demod bug. Set the correct delivery system and it locks instantly.
With everything up, I tuned my four reference Turksat 42E transponders. I used
dvbv5-zap for raw lock/quality and a small TSDuck-based helper for recording.
A working DVB-S2 channel file looks like:
[TRT_HD]
DELIVERY_SYSTEM = DVBS2
FREQUENCY = 11054000
POLARIZATION = VERTICAL
SYMBOL_RATE = 30000000
INNER_FEC = 3/4
MODULATION = PSK/8
SAT_NUMBER = 0
and a DVB-S one (note DVBS + QPSK):
[TRT_SD]
DELIVERY_SYSTEM = DVBS
FREQUENCY = 11096000
POLARIZATION = HORIZONTAL
SYMBOL_RATE = 30000000
INNER_FEC = AUTO
MODULATION = QPSK
SAT_NUMBER = 0
A healthy lock reports something like:
Lock (0x1f) Signal= -79.03dBm C/N= 13.42dB postBER= 0
Results on the PCTV 461e (all four lock and record, both with a direct LNB and through a multiswitch on DiSEqC port A):
| Transponder | Delivery | Modulation | Result |
|---|---|---|---|
| 11054 V 30000 | DVB-S2 | 8PSK | lock, C/N ~13 dB |
| 11096 H 30000 | DVB-S | QPSK | lock, 27 services |
| 12245 H 27500 | DVB-S2 | 8PSK | lock, C/N ~18 dB |
| 12380 V 27500 | DVB-S | QPSK | lock, 20 services |
The TBS5530 locks the same transponders on its DVB-S/S2 frontend. And for a fully self-contained bench test, I played a captured TS file out of the DTU-315 (as DVB-S2 8PSK on an L-band IF) straight into the TBS5530’s tuner input - a closed RF loopback with no dish involved. The re-captured stream carried the same TS id and service list as the source, which is exactly what you want to confirm the play -> modulate -> demodulate -> capture path end to end.
koreapyj/cxd28xx driver builds cleanly and
needs the TBS firmware files.m88ds3103c + 461e v3
(mainline has it now, but not in v6.17/v7.0), plus the
dvb-demod-m88ds3103c.fw firmware. The driver is fine; watch out for LNB power
and DVB-S-vs-DVB-S2.Once each device is up, they are just standard Linux DVB/Dektec nodes, so TSDuck can capture, analyze and modulate transport streams across all of them - which is exactly the toolbox I was after.