Jan Krupa

DVB-S – Výběr karty a rozcházení v Linuxu

April 4th, 2006

Delší dobu jsem pátral po vhodné DVB-S kartě s CI modulem pro provoz v Linuxu. Byl jsem pevně rozhodnut zakoupit Hauppauge WinTV-NOVA-S-CI PCI. Bohužel po několik týdnů byla nedostupná a následně se ukázalo, že se přestala vyrábět. Po znovuprozkoumání LinuxTV.org PCI DVB-S Wiki jsem zakoupil Twinhan VP-1030A (v Alzasoftu prodávaná pod označením TwinhanDTV Sat-CI, PCI, DVB-S přijímač (Digital SAT) TV + Radio + Internet, DO, CI slot).

Karta se v systému hlásí takto:

0000:00:08.0 Multimedia video controller: Brooktree Corporation Bt878 Video Capture (rev 11)
0000:00:08.0 0400: 109e:036e (rev 11)

0000:00:08.1 Multimedia controller: Brooktree Corporation Bt878 Audio Capture (rev 11)
0000:00:08.1 0480: 109e:0878 (rev 11)

Pro správnou funkčnost doporučuju použít ovladače z Linuxtv.org Mercurial repository. Stáhnout se dají následujícím způsobem:

hg clone http://linuxtv.org/hg/v4l-dvb

Update je pak možné provést přes:

cd v4l-dvb
hg pull -u http://linuxtv.org/hg/v4l-dvb

Nejprve je třeba zkompilovat kernel s následujícím nastavením:

Device Drivers  --->
  Multimedia devices  --->
    <M> Video For Linux
    Digital Video Broadcasting Devices  --->
      [*] DVB For Linux
      <M>   DVB Core Support

Po rebootu do nového kernelu pak zkompilovat ovladače pro v4l-dvb:

make
make install

Zavést moduly pro kartu:

modprobe dvb_core
modprobe bttv
modprobe bt878
modprobe dst
modprobe dvb_bt8xx

V ideálním případě by výpis dmesg měl končit hláškou:

DVB: registering frontend 0 (DST DVB-S)...

Bohužel během prvních pokusů jsem takové štěstí neměl a pokus o natažení modulu dvb_bt8×x končil následovně:

DVB: registering new adapter (bttv0).
dst_probe: unknown device.
frontend_init: Could not find a Twinhan DST.
dvb-bt8xx: A frontend driver was not found for device 109e/0878
subsystem 1822/0001

Při zapnutém verbose=4 logovani modulu dst takhle:

DVB: registering new adapter (bttv0).
rdc_8820_reset: Resetting DST
dst_gpio_outb: mask=[0004], enbb=[0004], outhigh=[0000]
dst_gpio_outb: mask=[0004], enbb=[0004], outhigh=[0004]
dst_comm_init: Initializing DST.
dst_gpio_outb: mask=[ffffffff], enbb=[0001], outhigh=[0000]
rdc_reset_state: Resetting state machine
dst_gpio_outb: mask=[0002], enbb=[0002], outhigh=[0000]
dst_gpio_outb: mask=[0002], enbb=[0002], outhigh=[0002]
writing [ 00 06 00 00 00 00 00 fa ]
write_dst: _write_dst error (err == -5, len == 0x08, b0 == 0x00)
dst_error_recovery: Trying to return from previous errors.
dst_gpio_outb: mask=[ffffffff], enbb=[0000], outhigh=[0000]
dst_gpio_outb: mask=[ffffffff], enbb=[0001], outhigh=[0000]
write_dst: _write_dst error (err == -5, len == 0x08, b0 == 0x00)
dst_error_recovery: Trying to return from previous errors.
dst_gpio_outb: mask=[ffffffff], enbb=[0000], outhigh=[0000]
dst_gpio_outb: mask=[ffffffff], enbb=[0001], outhigh=[0000]
write_dst: RDC 8820 RESET
dst_error_bailout: Trying to bailout from previous error.
rdc_8820_reset: Resetting DST
dst_gpio_outb: mask=[0004], enbb=[0004], outhigh=[0000]
dst_gpio_outb: mask=[0004], enbb=[0004], outhigh=[0004]
dst_gpio_outb: mask=[ffffffff], enbb=[0000], outhigh=[0000]
dst_probe: unknown device.
frontend_init: Could not find a Twinhan DST.
dvb-bt8xx: A frontend driver was not found for device 109e/0878
subsystem 1822/0001

Po snížení hodnoty „PCI Latency Timer“ z 64 na 32 v nastavení BIOSu začalo vše fungovat.

1 Comment »

  1. Problem is with ir-kbd-i2c.c. recompile with this diff. You will need in grub/lilo ir-kbd-i2c.twinhan=1, or else modprobe ir-kbd-i2c twinhan=1

    Let me know how you get on.

    diff –git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c

    index 59edf58..0ab2db6 100644
    — a/drivers/media/video/ir-kbd-i2c.c
    +++ b/drivers/media/video/ir-kbd-i2c.c
    @@ -52,8 +54,11 @@ module_param(debug, int, 0644); /* de

    static int hauppauge = 0;
    module_param(hauppauge, int, 0644); /* Choose Hauppauge remote */

    -MODULE_PARM_DESC(hauppauge, “Specify Hauppauge remote: 0=black, 1=grey
    (defaults to 0)”); +MODULE_PARM_DESC(hauppauge, “Specify Hauppauge remote:
    0=black, 1=grey (defaults to 0)”)

    +static int twinhan = 0;
    +module_param(twinhan, int, 0644); /* Fix for Twinhan cards */

    +MODULE_PARM_DESC(twinhan, “Workaround for Twinhan _write_dst error which causes
    dst_probe to fail: 1=on, 0=off (default 0)”);

    @@ -447,51 +452,55 @@ static int ir_probe(struct i2c_adapter *

    That’s why we probe 0x1a (~0×34) first. CB
    */
    -
    - static const int probe_bttv[] = { 0x1a, 0×18, 0x4b, 0×64, 0×30, -1};
    - static const int probe_saa7134[] = { 0x7a, 0×47, 0×71, -1 };
    - static const int probe_em28XX[] = { 0×30, 0×47, -1 };
    - const int *probe = NULL;
    - struct i2c_client c;
    - unsigned char buf;
    - int i,rc;
    -
    - switch (adap->id) {
    - case I2C_HW_B_BT848:
    - probe = probe_bttv;
    - break;
    - case I2C_HW_B_CX2341X:
    - probe = probe_bttv;
    - break;
    - case I2C_HW_SAA7134:
    - probe = probe_saa7134;
    - break;
    - case I2C_HW_B_EM28XX:
    - probe = probe_em28XX;
    - break;
    - }
    - if (NULL == probe)
    + if (twinhan == 1) {
    + dprintk(1,”Twinhan option specified. IR disabled.\n”);
    return 0;
    -
    - memset(&c,0,sizeof(c));
    - c.adapter = adap;
    - for (i = 0; -1 != probe[i]; i++) {
    - c.addr = probe[i];
    - rc = i2c_master_recv(&c,&buf,0);
    - dprintk(1,”probe 0x%02x @ %s: %s\n”,
    - probe[i], adap->name,
    - (0 == rc) ? “yes” : “no”);
    - if (0 == rc) {
    - ir_attach(adap,probe[i],0,0);
    + } else {

    + static const int probe_bttv[] = { 0x1a, 0×18, 0x4b, 0×64, 0×30, -1};

    + static const int probe_saa7134[] = { 0x7a, 0×47, 0×71, -1 };
    + static const int probe_em28XX[] = { 0×30, 0×47, -1 };
    + const int *probe = NULL;
    + struct i2c_client c;
    + unsigned char buf;
    + int i,rc;
    +
    + switch (adap->id) {
    + case I2C_HW_B_BT848:
    + probe = probe_bttv;
    + break;
    + case I2C_HW_B_CX2341X:
    + probe = probe_bttv;
    + break;
    + case I2C_HW_SAA7134:
    + probe = probe_saa7134;
    + break;
    + case I2C_HW_B_EM28XX:
    + probe = probe_em28XX;
    break;
    }
    + if (NULL == probe)
    + return 0;
    +
    + memset(&c,0,sizeof(c));
    + c.adapter = adap;
    + for (i = 0; -1 != probe[i]; i++) {
    + c.addr = probe[i];
    + rc = i2c_master_recv(&c,&buf,0);
    + dprintk(1,”probe 0x%02x @ %s: %s\n”,
    + probe[i], adap->name,
    + (0 == rc) ? “yes” : “no”);
    + if (0 == rc) {
    + ir_attach(adap,probe[i],0,0);
    + break;
    + }
    + }
    + return 0;
    }
    - return 0;
    }

    Comment by Matthew Hagan — February 12, 2007 @ 1:15 am

RSS feed for comments on this post.

Leave a comment

Enter this code: