TV in Linux using the Geniatech MyGica USB TV tuner Stick T230A

Updated 1 May 2023

I brought this stick based on compatible USB Geniatech T230 listed at the LinuxTV Wiki

I, however, wasn't paying enough attention and instead brought a T230A, which is a different stick!

The vendor does link to Linux drivers at https://www.mygica.com/support/, however they didn't build on Linux Mint 20 and I didn't want to use some non-supported drivers that will probably disappear off the Internet in a few years.

Rather than go through the pain of returning the stick back to China, I did some research to figure out myself how to get it working in order to setup a TV tuner/PVR myself

Update 1st May 2023: Ubuntu 22.04 / Linux Mint 21 with Kernel 5.15 or higher supports this stick natively. DO NOT follow the Drivers setup below - it'll break. You might still need Firmware.

Update: I have tried a rebuild using the built in media modules using Ubuntu HWE/Linux Mint Edge kernel 5.13.0-35-generic and they still don't work, meaning you must clone and compile the GIT repos below. I have now got a working thinned down dkms build that will allow the drivers to survive kernel updates.

I've also removed the v4l-utils and DTV scan tables info - they are not needed to get the TV stick working with NextPVR at least.

These instructions should work on all versions Ubuntu 20.04 and dependent distros such as Linux Mint 20, Pop!OS 20.04, Zorin OS 16 etc.

The steps are these:

  • Download, compile and install drivers
  • Download and move stick firmware to the correct place
  • Install PVR software
  • Install media centre/home theatre software

Drivers

The best place for info and drivers I found is at https://github.com/tbsdtv/linux_media/wiki

Here are my updated steps for installing a thinned down set of drivers that (as of today and almost the past year) work with the MyGica T230A.

This thinned down set of modules means that these drivers will work only for that particular stick. Specifically, the hardware ID (if you run lsusb) is vendor 0572, product 689a:

Bus 003 Device 002: ID 0572:689a Conexant Systems (Rockwell), Inc. USB Stick

These are the command steps that worked on Linux Mint 20 (and should work for Ubuntu 20.04 too)

Note: This assumes that you've also installed a GUI

sudo apt install build-essential git linux-headers-generic patchutils libproc-processtable-perl gcc dkms

git clone https://github.com/tbsdtv/media_build.git
git clone --depth=1 https://github.com/tbsdtv/linux_media.git -b latest ./media

cd media_build

Tip, the git clone is quite slow, so if fiddling and you want to go back to the initial version and build again, I suggest to tar the media and media_build directories so that if you need to you can quickly restore them instead of cloning again - e.g. "tar cf media.tar media".

Note: If you've enabled secure boot, they won't load. I hit this challenge with my laptop, but I didn't spend any more time with it as my laptop was not the intended PC I was going to use for it anyway. There are many drivers installed by this package and you'd probably need to sign them all and not just the immediate driver dvb-usb-dvbsky.

For the thinned down dkms install, follow these next steps carefully. There are some less than elegant mods here to make it work as desired on the Ubuntu kernels, without needing the full kernel source or building all of the modules!

Step 1 - modv4l.config

Make sure you are in your media_build folder, cloned above. Create a new file named modv4l.config:

nano modv4l.config

Put the contents as below. Once complete, use Ctrl+O to save, Ctrl+X to exit nano.

CONFIG_DVB_CORE=m
CONFIG_DVB_NET=m
CONFIG_DVB_MMAP=m
CONFIG_MEDIA_SUPPORT=m
CONFIG_MEDIA_SUPPORT_FILTER=y
CONFIG_VIDEO_DEV=m
CONFIG_CEC_CORE=m
CONFIG_DVB_M88DS3103=m
CONFIG_DVB_USB_V2=m
CONFIG_DVB_USB_DVBSKY=m
CONFIG_DVB_SP2=m
CONFIG_MEDIA_TUNER_SI2157=m
CONFIG_DVB_SI2168=m
CONFIG_DVB_TS2020=m
Step 2 - build_all.sh

Now edit build_all.sh

nano build_all.sh

Find the line with 'make stagingconfig' (use Ctrl+W to find in nano), then add the line 'cp modv4l.config v4l/.config'. Note the indentation.

...
                make stagingconfig
                # Patch in simplified config  - added after line above
                cp modv4l.config v4l/.config

                import_options
...

Next, find the line 'if [ "${do_linux}" = "y" -o "${do_linux}" = "d" ] ; then'. Add the two lines highlighted below (the ln and make dir)

Note: Alter /home/user/media to the real path where you cloned the media repository above

...
if [ "${do_linux}" = "y" -o "${do_linux}" = "d" ] ; then
        ln -s /home/user/media ${kernelsourcedir/_media_inst/..}
        make dir DIR=../media 
        make_linux ${kernelsourcedir}
fi
...

Save and exit

Step 3 - linux/Makefile

Make sure you are in your media_build folder, cloned above. Create a file named modv4l.config:

nano linux/Makefile

Find the line 'patch -s -f -N -p1 -i ../backports/$$i --dry-run || exit 1; \' and put a # in front.

...
                echo patch -s -f -N -p1 -i ../backports/$$i; \
                #patch -s -f -N -p1 -i ../backports/$$i --dry-run || exit 1; \
                patch -s -f -N -p1 -i ../backports/$$i; \
...
Step 4 - gen_dkms_dyn_conf.sh

The last edit is to gen_dkms_dyn_conf.sh.

nano gen_dkms_dyn_conf.sh

Find the line 'if [[ ${mod_build_dir} =~ (.*)${mod_build_loc_base}(.*) ]] ; then'. Add a # in front, then add the line as shown below, with indentation.

...
    mod_build_dir=$(dirname ${1})
    #if [[ ${mod_build_dir} =~ (.*)${mod_build_loc_base}(.*) ]] ; then
    if [[ ${mod_build_dir} =~ (.*)${mod_build_loc_base}(.*) || ${mod_build_dir} =~ (.*)/updates(.*) ]] ; then
        mod_dest_location="${mod_dest_loc_base}${BASH_REMATCH[2]}"
...
Step 5 - dkms.conf

Update: - I found that during real kernel updates, the depmod was only loading dvb-core, ignoring the dynamic dkms.conf generated by gen_dkms_dyn_conf.sh. Solution for now is to put the required modules into the dkms.conf,

nano dkms.conf

Find the lines BUILT_MODULE_NAME, BUILT_MODULE_LOCATION and DEST_MODULE_LOCATION and replace this setup with the below:

...

# There have to be at least one module defined in the top DKMS configuration
# file, otherwise DKMS throws an error.
# Note: This definition gets overridden later by the dynamically generated
#       DKMS configuration file.
#
BUILT_MODULE_NAME[0]=cec
BUILT_MODULE_NAME[1]=m88ds3103
BUILT_MODULE_NAME[2]=sp2
BUILT_MODULE_NAME[3]=si2168
BUILT_MODULE_NAME[4]=ts2020
BUILT_MODULE_NAME[5]=si2157
BUILT_MODULE_NAME[6]=dvb_usb_v2
BUILT_MODULE_NAME[7]=dvb-usb-dvbsky
BUILT_MODULE_NAME[8]=dvb-core

#
# We use here the real build location, because the file needs to exist to
# finish the build step.
BUILT_MODULE_LOCATION[0]=./v4l
BUILT_MODULE_LOCATION[1]=./v4l
BUILT_MODULE_LOCATION[2]=./v4l
BUILT_MODULE_LOCATION[3]=./v4l
BUILT_MODULE_LOCATION[4]=./v4l
BUILT_MODULE_LOCATION[5]=./v4l
BUILT_MODULE_LOCATION[6]=./v4l
BUILT_MODULE_LOCATION[7]=./v4l
BUILT_MODULE_LOCATION[8]=./v4l
#
# It is important to use the real module path here, so that the uninstall
# command works correctly
DEST_MODULE_LOCATION[0]=/kernel/extra/media/cec/core
DEST_MODULE_LOCATION[1]=/kernel/extra/media/dvb-frontends
DEST_MODULE_LOCATION[2]=/kernel/extra/media/dvb-frontends
DEST_MODULE_LOCATION[3]=/kernel/extra/media/dvb-frontends
DEST_MODULE_LOCATION[4]=/kernel/extra/media/dvb-frontends
DEST_MODULE_LOCATION[5]=/kernel/extra/media/tuners
DEST_MODULE_LOCATION[6]=/kernel/extra/media/usb/dvb-usb-v2
DEST_MODULE_LOCATION[7]=/kernel/extra/media/usb/dvb-usb-v2
DEST_MODULE_LOCATION[8]=/kernel/extra/media/dvb-core

...
Step 6 - module version

Update: - another issue during real updates - even with --force on the install, the dkms updates would ignore taking dvb_usb_v2.ko into the new kernel due to the module version being the same. I can't see a way to force it, so my not so nice fix is to change the module version in the file itself:

nano ../media/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c

Find the lines MODULE_VERSION (near the end) and change 2.0 to something higher:

...
EXPORT_SYMBOL(dvb_usbv2_reset_resume);

MODULE_VERSION("2.1");
MODULE_AUTHOR("Patrick Boettcher ");
...
DKMS add, build and install

Now you're ready to build and install

sudo dkms add .
sudo dkms build media-build/0002
sudo dkms install media-build/0002

It should output like below. If there are build errors, it will tell you where the log file can be found. Remove the existing link first by running 'sudo dkms remove media-build/0002 --all'. Note kernel version will vary to whatever one you have active (mine is currently 5.13.0-35-generic).

user@bedroom-tv:~/media_build$ sudo dkms add .

Creating symlink /var/lib/dkms/media-build/0002/source ->
                 /usr/src/media-build-0002

DKMS: add completed.
user@bedroom-tv:~/media_build$ sudo dkms build media-build/0002

Kernel preparation unnecessary for this kernel.  Skipping...

Building module:
cleaning build area...
make -j4 KERNELRELEASE=5.13.0-35-generic MEDIA_INST_DIR=/var/lib/dkms/media-build/0002/build/_media_inst -f Makefile.dkms build...........

Running the post_build script:
Done!
cleaning build area....

DKMS: build completed.
user@bedroom-tv:~/media_build$ sudo dkms install media-build/0002 --force

cec.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/5.13.0-35-generic/updates/dkms/

m88ds3103.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/5.13.0-35-generic/updates/dkms/

sp2.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/5.13.0-35-generic/updates/dkms/

si2168.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/5.13.0-35-generic/updates/dkms/

ts2020.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/5.13.0-35-generic/updates/dkms/

si2157.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/5.13.0-35-generic/updates/dkms/

dvb_usb_v2.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/5.13.0-35-generic/updates/dkms/

dvb-usb-dvbsky.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/5.13.0-35-generic/updates/dkms/

dvb-core.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/5.13.0-35-generic/updates/dkms/

depmod...

DKMS: install completed.

Reboot!

Keep your media and media_build directories intact i.e. do not delete them to save space. This is because the dkms will depend on them.

For reference, below are the commands I used to use to build all the modules and install directly (this won't survive kernel updates):

cd media_build
make dir DIR=../media
make allyesconfig
make -j4
sudo make install

Update 29/08/2021: I managed to hack the config up a bit to make it compile much faster, though I've not yet got it working with dkms.

Basically, after running "make allyesconfig", stop there and edit the v4l/.config file and replace it with the contents of the modv4l.config above.

This basically sets the flags needed just for the Geniatech MyGica T230A drivers and their dependencies. I've tested in so far that the driver loads on reboot and that I can update the EPG and record/browse UK TV channels (DVB-T) through NextPVR. Compiling and installing just the necessary drivers cuts the time down from 20 minutes to just a few seconds.

Updates

You can update from the latest git repo by going into your existing directories and running a git pull. This will adjust the code since your last update or initial clone.

Then follow the install instructions above with the patches. When I tried March 5th 2023, none of the files I patched were updated so all of the patches were still present so I just had to do a dkms remove and install.

cd media_build
git pull https://github.com/tbsdtv/media_build.git
cd media
git pull https://github.com/tbsdtv/linux_media.git

Firmware

This is also required. The drivers look for dvb-demod-si2168-d60-01.fw and dvb-tuner-si2141-a10-01.fw in /lib/firmware

You can get them move them with these commands

wget https://github.com/osmc/dvb-firmware-osmc/raw/master/dvb-demod-si2168-d60-01.fw
wget https://github.com/osmc/dvb-firmware-osmc/raw/master/dvb-tuner-si2141-a10-01.fw
sudo mv dvb-*.fw /lib/firmware/

PVR

I didn't explore PVR options much, I just wanted one that worked, has a good interface and a Kodi plugin.

NextPVR was the first I tried, and it's pretty good. To install it:

curl https://nextpvr.com/nextpvr-helper.deb -O
sudo apt install ./nextpvr-helper.deb --install-recommends

Once installed, the settings option should be able to find the device as both DVD-T and DVB-C. The UK uses DVB-T so select that device and it will then offer to do a scan. Connect a good aerial before running a scan - the free one that comes with the stick didn't pick up anything! It may work outdoors, on top of a hill but I suspect it's not worth the bother for most people!

When you scan, you will need to know the location of the closest transmitter. I'm currently in London so that's uk-CrystalPalace.

Optional - hardware transcoding

To record or stream, NextPVR needs to do some transcoding. CPU transcoding is the default option but many Intel CPUs have graphics chips that can do the transcoding more efficiently. The VAAPI option did not work initially in Linux Mint 20 though on my Sandy Bridge i5 2500S CPU (Intel HD 2000 graphics) - showing "Stream Failed Transcoder Exited" in the browser.

To get it to work, I had to the below line in to /etc/environment

LIBVA_DRIVER_NAME=i965

and run this:

sudo chmod 666 /dev/dri/renderD128

Not entirely sure if the first was necessary in the end, but it stops the vainfo from printing an error anyway.

This was only a temporary fix, so to ensure that hardware decoding survives a reboot I researched further and found that the nextpvr user needs to be added to the "render" group in order to use /dev/dri/renderD128

sudo usermod -aG render nextpvr
sudo service nextpvr-server stop
sudo service nextpvr-server start

Note: i965 is for old Intel CPUs - pre-Broadwell - so 5th generation or never should not need the i965 setting.

For info, NextPVR logs are quite large, but they can be useful to find the error. Find them in less /var/opt/nextpvr/logs. The nrecord.log file showed transcoding errors.

Home Theatre Software

Kodi is well-known and it's really good. The TV option works once you install a plugin for NextPVR

To get both:

sudo apt install kodi
sudo apt install kodi-pvr-nextpvr

Diagnosis

Issues with the drivers etc will usually appear in dmesg, so just type dmesg in the terminal and review the output. I've picked out some key lines in mine for you below to show the USB stick detected and loaded, and when it downloads firmware when it's used.

[    4.538488] usb 3-2: New USB device found, idVendor=0572, idProduct=689a, bcdDevice= 8.00
[    4.563885] usb 3-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[    4.615750] usb 3-2: Product: USB Stick
[    4.615753] usb 3-2: Manufacturer: Gen
[    4.667688] usb 3-2: SerialNumber: 2017.12.09

...

[    9.669497] dvb_core: loading out-of-tree module taints kernel.
[    9.669599] dvb_core: module verification failed: signature and/or required key missing - tainting kernel
[    9.670572] WARNING: You are using an experimental version of the media stack.
               	As the driver is backported to an older kernel, it doesn't offer
               	enough quality for its usage in production.
               	Use it with care.
               Latest git patches (needed if you report a bug to linux-media@vger.kernel.org):
               	d52672855db69ff41d021ed57e243f7322ec0ec4 fixed some errors for cxd2878 module
...

[    9.931073] usb 3-2: dvb_usb_v2: found a 'MyGica Mini DVB-(T/T2/C) USB Stick T230A' in warm state
[    9.931196] usb 3-2: dvb_usb_v2: will pass the complete MPEG2 transport stream to the software demuxer
[    9.931207] dvbdev: DVB: registering new adapter (MyGica Mini DVB-(T/T2/C) USB Stick T230A)
[    9.945949] i2c i2c-10: Added multiplexed i2c bus 11
[    9.945956] si2168 10-0064: Silicon Labs Si2168-D60 successfully identified
[    9.945959] si2168 10-0064: firmware version: D 6.0.1
[    9.956961] si2157 11-0060: Silicon Labs Si2141 successfully attached
[    9.956995] usb 3-2: DVB: registering adapter 0 frontend 0 (Silicon Labs Si2168)...
[    9.957055] usb 3-2: dvb_usb_v2: 'MyGica Mini DVB-(T/T2/C) USB Stick T230A' successfully initialized and connected

...

[   18.271479] si2168 10-0064: downloading firmware from file 'dvb-demod-si2168-d60-01.fw'
[   18.406490] si2168 10-0064: firmware version: D 6.0.2
...

That's all - hope this helps anyone get their Linux TV PVR up and running! For me it's given life to an old Mini ITX desktop (Core i5 2500S, 4GB RAM, 64GB SSD, 500GB HDD). Linux is free (though do donate!), and I've now got a very capable media centre for a cheap cost!

Labels

DIY | Linux | Linux Mint | TV | Ubuntu