X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fmedia%2Fdvb%2Fbt8xx%2Fdvb-bt8xx.c;h=3e35931af35d13cd70d14f04eb5ec9fe26cd7db1;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=6f857c6091f34ecbb9c6e5874e0049a3d5406f1e;hpb=f7f1b0f1e2fbadeab12d24236000e778aa9b1ead;p=linux-2.6.git diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c index 6f857c609..3e35931af 100644 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c @@ -32,9 +32,7 @@ #include "dvbdev.h" #include "dvb_demux.h" #include "dvb_frontend.h" - #include "dvb-bt8xx.h" - #include "bt878.h" static int debug; @@ -43,9 +41,11 @@ module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); #define dprintk( args... ) \ - do { \ + do \ if (debug) printk(KERN_DEBUG args); \ - } while (0) + while (0) + +#define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */ static void dvb_bt8xx_task(unsigned long data) { @@ -66,7 +66,7 @@ static void dvb_bt8xx_task(unsigned long data) static int dvb_bt8xx_start_feed(struct dvb_demux_feed *dvbdmxfeed) { - struct dvb_demux *dvbdmx = dvbdmxfeed->demux; + struct dvb_demux*dvbdmx = dvbdmxfeed->demux; struct dvb_bt8xx_card *card = dvbdmx->priv; int rc; @@ -75,13 +75,13 @@ static int dvb_bt8xx_start_feed(struct dvb_demux_feed *dvbdmxfeed) if (!dvbdmx->dmx.frontend) return -EINVAL; - down(&card->lock); + mutex_lock(&card->lock); card->nfeeds++; rc = card->nfeeds; if (card->nfeeds == 1) bt878_start(card->bt, card->gpio_mode, card->op_sync_orin, card->irq_err_ignore); - up(&card->lock); + mutex_unlock(&card->lock); return rc; } @@ -95,11 +95,11 @@ static int dvb_bt8xx_stop_feed(struct dvb_demux_feed *dvbdmxfeed) if (!dvbdmx->dmx.frontend) return -EINVAL; - down(&card->lock); + mutex_lock(&card->lock); card->nfeeds--; if (card->nfeeds == 0) bt878_stop(card->bt); - up(&card->lock); + mutex_unlock(&card->lock); return 0; } @@ -114,19 +114,17 @@ static int is_pci_slot_eq(struct pci_dev* adev, struct pci_dev* bdev) return 0; } -static struct bt878 __init *dvb_bt8xx_878_match(unsigned int bttv_nr, struct pci_dev* bttv_pci_dev) +static struct bt878 __devinit *dvb_bt8xx_878_match(unsigned int bttv_nr, struct pci_dev* bttv_pci_dev) { unsigned int card_nr; /* Hmm, n squared. Hope n is small */ - for (card_nr = 0; card_nr < bt878_num; card_nr++) { + for (card_nr = 0; card_nr < bt878_num; card_nr++) if (is_pci_slot_eq(bt878[card_nr].dev, bttv_pci_dev)) return &bt878[card_nr]; - } return NULL; } - static int thomson_dtt7579_demod_init(struct dvb_frontend* fe) { static u8 mt352_clock_config [] = { 0x89, 0x38, 0x38 }; @@ -148,60 +146,71 @@ static int thomson_dtt7579_demod_init(struct dvb_frontend* fe) return 0; } -static int thomson_dtt7579_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf) +static int thomson_dtt7579_tuner_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf, int buf_len) { u32 div; unsigned char bs = 0; unsigned char cp = 0; - #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */ + if (buf_len < 5) + return -EINVAL; + div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; - if (params->frequency < 542000000) cp = 0xb4; - else if (params->frequency < 771000000) cp = 0xbc; - else cp = 0xf4; + if (params->frequency < 542000000) + cp = 0xb4; + else if (params->frequency < 771000000) + cp = 0xbc; + else + cp = 0xf4; - if (params->frequency == 0) bs = 0x03; - else if (params->frequency < 443250000) bs = 0x02; - else bs = 0x08; + if (params->frequency == 0) + bs = 0x03; + else if (params->frequency < 443250000) + bs = 0x02; + else + bs = 0x08; - pllbuf[0] = 0xc0; // Note: non-linux standard PLL i2c address + pllbuf[0] = 0x60; pllbuf[1] = div >> 8; pllbuf[2] = div & 0xff; pllbuf[3] = cp; pllbuf[4] = bs; - return 0; + return 5; } static struct mt352_config thomson_dtt7579_config = { - .demod_address = 0x0f, .demod_init = thomson_dtt7579_demod_init, - .pll_set = thomson_dtt7579_pll_set, }; -static int cx24108_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) -{ - u32 freq = params->frequency; +static struct zl10353_config thomson_dtt7579_zl10353_config = { + .demod_address = 0x0f, +}; - int i, a, n, pump; - u32 band, pll; +static int cx24108_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +{ + u32 freq = params->frequency; + int i, a, n, pump; + u32 band, pll; - u32 osci[]={950000,1019000,1075000,1178000,1296000,1432000, - 1576000,1718000,1856000,2036000,2150000}; - u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,0x00101000, - 0x00102000,0x00104000,0x00108000,0x00110000, - 0x00120000,0x00140000}; + u32 osci[]={950000,1019000,1075000,1178000,1296000,1432000, + 1576000,1718000,1856000,2036000,2150000}; + u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,0x00101000, + 0x00102000,0x00104000,0x00108000,0x00110000, + 0x00120000,0x00140000}; -#define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */ + #define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */ printk("cx24108 debug: entering SetTunerFreq, freq=%d\n",freq); /* This is really the bit driving the tuner chip cx24108 */ - if(freq<950000) freq=950000; /* kHz */ - if(freq>2150000) freq=2150000; /* satellite IF is 950..2150MHz */ + if (freq<950000) + freq = 950000; /* kHz */ + else if (freq>2150000) + freq = 2150000; /* satellite IF is 950..2150MHz */ /* decide which VCO to use for the input frequency */ for(i=1;(idvb->priv; + + bttv_gpio_enable(card->bttv_nr, 1, 1); /* output */ + bttv_write_gpio(card->bttv_nr, 1, 1); /* relay on */ + + return 0; } +static int pinnsat_tuner_sleep(struct dvb_frontend* fe) +{ + struct dvb_bt8xx_card *card = fe->dvb->priv; -static struct cx24110_config pctvsat_config = { + bttv_write_gpio(card->bttv_nr, 1, 0); /* relay off */ + return 0; +} + +static struct cx24110_config pctvsat_config = { .demod_address = 0x55, - .pll_init = pinnsat_pll_init, - .pll_set = cx24108_pll_set, }; - -static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int microtune_mt7202dtf_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; u8 cfg, cpump, band_select; @@ -258,21 +276,31 @@ static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_front div = (36000000 + params->frequency + 83333) / 166666; cfg = 0x88; - if (params->frequency < 175000000) cpump = 2; - else if (params->frequency < 390000000) cpump = 1; - else if (params->frequency < 470000000) cpump = 2; - else if (params->frequency < 750000000) cpump = 2; - else cpump = 3; + if (params->frequency < 175000000) + cpump = 2; + else if (params->frequency < 390000000) + cpump = 1; + else if (params->frequency < 470000000) + cpump = 2; + else if (params->frequency < 750000000) + cpump = 2; + else + cpump = 3; - if (params->frequency < 175000000) band_select = 0x0e; - else if (params->frequency < 470000000) band_select = 0x05; - else band_select = 0x03; + if (params->frequency < 175000000) + band_select = 0x0e; + else if (params->frequency < 470000000) + band_select = 0x05; + else + band_select = 0x03; data[0] = (div >> 8) & 0x7f; data[1] = div & 0xff; data[2] = ((div >> 10) & 0x60) | cfg; - data[3] = cpump | band_select; + data[3] = (cpump << 6) | band_select; + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); i2c_transfer(card->i2c_adapter, &msg, 1); return (div * 166666 - 36000000); } @@ -285,14 +313,10 @@ static int microtune_mt7202dtf_request_firmware(struct dvb_frontend* fe, const s } static struct sp887x_config microtune_mt7202dtf_config = { - .demod_address = 0x70, - .pll_set = microtune_mt7202dtf_pll_set, .request_firmware = microtune_mt7202dtf_request_firmware, }; - - static int advbt771_samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe) { static u8 mt352_clock_config [] = { 0x89, 0x38, 0x2d }; @@ -303,7 +327,6 @@ static int advbt771_samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe) static u8 mt352_av771_extra[] = { 0xB5, 0x7A }; static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 }; - mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config)); udelay(2000); mt352_write(fe, mt352_reset, sizeof(mt352_reset)); @@ -317,58 +340,72 @@ static int advbt771_samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe) return 0; } -static int advbt771_samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf) +static int advbt771_samsung_tdtc9251dh0_tuner_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf, int buf_len) { u32 div; unsigned char bs = 0; unsigned char cp = 0; - #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */ + if (buf_len < 5) return -EINVAL; + div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; - if (params->frequency < 150000000) cp = 0xB4; - else if (params->frequency < 173000000) cp = 0xBC; - else if (params->frequency < 250000000) cp = 0xB4; - else if (params->frequency < 400000000) cp = 0xBC; - else if (params->frequency < 420000000) cp = 0xF4; - else if (params->frequency < 470000000) cp = 0xFC; - else if (params->frequency < 600000000) cp = 0xBC; - else if (params->frequency < 730000000) cp = 0xF4; - else cp = 0xFC; - - if (params->frequency < 150000000) bs = 0x01; - else if (params->frequency < 173000000) bs = 0x01; - else if (params->frequency < 250000000) bs = 0x02; - else if (params->frequency < 400000000) bs = 0x02; - else if (params->frequency < 420000000) bs = 0x02; - else if (params->frequency < 470000000) bs = 0x02; - else if (params->frequency < 600000000) bs = 0x08; - else if (params->frequency < 730000000) bs = 0x08; - else bs = 0x08; - - pllbuf[0] = 0xc2; // Note: non-linux standard PLL i2c address + if (params->frequency < 150000000) + cp = 0xB4; + else if (params->frequency < 173000000) + cp = 0xBC; + else if (params->frequency < 250000000) + cp = 0xB4; + else if (params->frequency < 400000000) + cp = 0xBC; + else if (params->frequency < 420000000) + cp = 0xF4; + else if (params->frequency < 470000000) + cp = 0xFC; + else if (params->frequency < 600000000) + cp = 0xBC; + else if (params->frequency < 730000000) + cp = 0xF4; + else + cp = 0xFC; + + if (params->frequency < 150000000) + bs = 0x01; + else if (params->frequency < 173000000) + bs = 0x01; + else if (params->frequency < 250000000) + bs = 0x02; + else if (params->frequency < 400000000) + bs = 0x02; + else if (params->frequency < 420000000) + bs = 0x02; + else if (params->frequency < 470000000) + bs = 0x02; + else if (params->frequency < 600000000) + bs = 0x08; + else if (params->frequency < 730000000) + bs = 0x08; + else + bs = 0x08; + + pllbuf[0] = 0x61; pllbuf[1] = div >> 8; pllbuf[2] = div & 0xff; pllbuf[3] = cp; pllbuf[4] = bs; - return 0; + return 5; } static struct mt352_config advbt771_samsung_tdtc9251dh0_config = { - .demod_address = 0x0f, .demod_init = advbt771_samsung_tdtc9251dh0_demod_init, - .pll_set = advbt771_samsung_tdtc9251dh0_pll_set, }; - static struct dst_config dst_config = { - .demod_address = 0x55, }; - static int or51211_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name) { struct dvb_bt8xx_card* bt = (struct dvb_bt8xx_card*) fe->dvb->priv; @@ -398,10 +435,8 @@ static void or51211_reset(struct dvb_frontend * fe) */ /* reset & PRM1,2&4 are outputs */ int ret = bttv_gpio_enable(bt->bttv_nr, 0x001F, 0x001F); - if (ret != 0) { - printk(KERN_WARNING "or51211: Init Error - Can't Reset DVR " - "(%i)\n", ret); - } + if (ret != 0) + printk(KERN_WARNING "or51211: Init Error - Can't Reset DVR (%i)\n", ret); bttv_write_gpio(bt->bttv_nr, 0x001F, 0x0000); /* Reset */ msleep(20); /* Now set for normal operation */ @@ -417,7 +452,6 @@ static void or51211_sleep(struct dvb_frontend * fe) } static struct or51211_config or51211_config = { - .demod_address = 0x15, .request_firmware = or51211_request_firmware, .setmode = or51211_setmode, @@ -425,8 +459,7 @@ static struct or51211_config or51211_config = { .sleep = or51211_sleep, }; - -static int vp3021_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) +static int vp3021_alps_tded4_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; u8 buf[4]; @@ -449,127 +482,238 @@ static int vp3021_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_fronten else return -EINVAL; + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); i2c_transfer(card->i2c_adapter, &msg, 1); return 0; } static struct nxt6000_config vp3021_alps_tded4_config = { - .demod_address = 0x0a, .clock_inversion = 1, - .pll_set = vp3021_alps_tded4_pll_set, }; +static int digitv_alps_tded4_demod_init(struct dvb_frontend* fe) +{ + static u8 mt352_clock_config [] = { 0x89, 0x38, 0x2d }; + static u8 mt352_reset [] = { 0x50, 0x80 }; + static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 }; + static u8 mt352_agc_cfg [] = { 0x67, 0x20, 0xa0 }; + static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 }; + + mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config)); + udelay(2000); + mt352_write(fe, mt352_reset, sizeof(mt352_reset)); + mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg)); + mt352_write(fe, mt352_agc_cfg,sizeof(mt352_agc_cfg)); + mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg)); + + return 0; +} + +static int digitv_alps_tded4_tuner_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf, int buf_len) +{ + u32 div; + struct dvb_ofdm_parameters *op = ¶ms->u.ofdm; + + if (buf_len < 5) + return -EINVAL; + + div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; + + pllbuf[0] = 0x61; + pllbuf[1] = (div >> 8) & 0x7F; + pllbuf[2] = div & 0xFF; + pllbuf[3] = 0x85; + + dprintk("frequency %u, div %u\n", params->frequency, div); + + if (params->frequency < 470000000) + pllbuf[4] = 0x02; + else if (params->frequency > 823000000) + pllbuf[4] = 0x88; + else + pllbuf[4] = 0x08; + + if (op->bandwidth == 8) + pllbuf[4] |= 0x04; + + return 5; +} + +static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt) +{ + /* + * Reset the frontend, must be called before trying + * to initialise the MT352 or mt352_attach + * will fail. Same goes for the nxt6000 frontend. + * + */ + + int ret = bttv_gpio_enable(bt->bttv_nr, 0x08, 0x08); + if (ret != 0) + printk(KERN_WARNING "digitv_alps_tded4: Init Error - Can't Reset DVR (%i)\n", ret); + + /* Pulse the reset line */ + bttv_write_gpio(bt->bttv_nr, 0x08, 0x08); /* High */ + bttv_write_gpio(bt->bttv_nr, 0x08, 0x00); /* Low */ + msleep(100); + + bttv_write_gpio(bt->bttv_nr, 0x08, 0x08); /* High */ +} + +static struct mt352_config digitv_alps_tded4_config = { + .demod_address = 0x0a, + .demod_init = digitv_alps_tded4_demod_init, +}; + +static struct lgdt330x_config tdvs_tua6034_config = { + .demod_address = 0x0e, + .demod_chip = LGDT3303, + .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ +}; + +static void lgdt330x_reset(struct dvb_bt8xx_card *bt) +{ + /* Set pin 27 of the lgdt3303 chip high to reset the frontend */ + + /* Pulse the reset line */ + bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */ + bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000000); /* Low */ + msleep(100); + + bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */ + msleep(100); +} static void frontend_init(struct dvb_bt8xx_card *card, u32 type) { - int ret; struct dst_state* state = NULL; switch(type) { -#ifdef BTTV_DVICO_DVBT_LITE - case BTTV_DVICO_DVBT_LITE: - card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter); + case BTTV_BOARD_DVICO_DVBT_LITE: + card->fe = dvb_attach(mt352_attach, &thomson_dtt7579_config, card->i2c_adapter); + + if (card->fe == NULL) + card->fe = dvb_attach(zl10353_attach, &thomson_dtt7579_zl10353_config, + card->i2c_adapter); + if (card->fe != NULL) { - card->fe->ops->info.frequency_min = 174000000; - card->fe->ops->info.frequency_max = 862000000; - break; + card->fe->ops.tuner_ops.calc_regs = thomson_dtt7579_tuner_calc_regs; + card->fe->ops.info.frequency_min = 174000000; + card->fe->ops.info.frequency_max = 862000000; } break; -#endif - -#ifdef BTTV_TWINHAN_VP3021 - case BTTV_TWINHAN_VP3021: -#else - case BTTV_NEBULA_DIGITV: -#endif - card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter); + + case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: + lgdt330x_reset(card); + card->fe = dvb_attach(lgdt330x_attach, &tdvs_tua6034_config, card->i2c_adapter); if (card->fe != NULL) { - break; + dvb_attach(lgh06xf_attach, card->fe, card->i2c_adapter); + dprintk ("dvb_bt8xx: lgdt330x detected\n"); } break; - case BTTV_AVDVBT_761: - card->fe = sp887x_attach(µtune_mt7202dtf_config, card->i2c_adapter); + case BTTV_BOARD_NEBULA_DIGITV: + /* + * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK); + * this would be a cleaner solution than trying each frontend in turn. + */ + + /* Old Nebula (marked (c)2003 on high profile pci card) has nxt6000 demod */ + digitv_alps_tded4_reset(card); + card->fe = dvb_attach(nxt6000_attach, &vp3021_alps_tded4_config, card->i2c_adapter); if (card->fe != NULL) { + card->fe->ops.tuner_ops.set_params = vp3021_alps_tded4_tuner_set_params; + dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n"); break; } + + /* New Nebula (marked (c)2005 on low profile pci card) has mt352 demod */ + digitv_alps_tded4_reset(card); + card->fe = dvb_attach(mt352_attach, &digitv_alps_tded4_config, card->i2c_adapter); + + if (card->fe != NULL) { + card->fe->ops.tuner_ops.calc_regs = digitv_alps_tded4_tuner_calc_regs; + dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n"); + } break; - case BTTV_AVDVBT_771: - card->fe = mt352_attach(&advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter); + case BTTV_BOARD_AVDVBT_761: + card->fe = dvb_attach(sp887x_attach, µtune_mt7202dtf_config, card->i2c_adapter); + if (card->fe) { + card->fe->ops.tuner_ops.set_params = microtune_mt7202dtf_tuner_set_params; + } + break; + + case BTTV_BOARD_AVDVBT_771: + card->fe = dvb_attach(mt352_attach, &advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter); if (card->fe != NULL) { - card->fe->ops->info.frequency_min = 174000000; - card->fe->ops->info.frequency_max = 862000000; - break; + card->fe->ops.tuner_ops.calc_regs = advbt771_samsung_tdtc9251dh0_tuner_calc_regs; + card->fe->ops.info.frequency_min = 174000000; + card->fe->ops.info.frequency_max = 862000000; } break; - case BTTV_TWINHAN_DST: + case BTTV_BOARD_TWINHAN_DST: /* DST is not a frontend driver !!! */ - state = (struct dst_state *) kmalloc(sizeof (struct dst_state), GFP_KERNEL); + state = kmalloc(sizeof (struct dst_state), GFP_KERNEL); + if (!state) { + printk("dvb_bt8xx: No memory\n"); + break; + } /* Setup the Card */ state->config = &dst_config; state->i2c = card->i2c_adapter; state->bt = card->bt; - + state->dst_ca = NULL; /* DST is not a frontend, attaching the ASIC */ - if ((dst_attach(state, &card->dvb_adapter)) == NULL) { + if (dvb_attach(dst_attach, state, &card->dvb_adapter) == NULL) { printk("%s: Could not find a Twinhan DST.\n", __FUNCTION__); break; } - card->fe = &state->frontend; - /* Attach other DST peripherals if any */ /* Conditional Access device */ - if (state->dst_hw_cap & DST_TYPE_HAS_CA) { - ret = dst_ca_attach(state, &card->dvb_adapter); - } - if (card->fe != NULL) { - break; - } + card->fe = &state->frontend; + if (state->dst_hw_cap & DST_TYPE_HAS_CA) + dvb_attach(dst_ca_attach, state, &card->dvb_adapter); break; - case BTTV_PINNACLESAT: - card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter); - if (card->fe != NULL) { - break; + case BTTV_BOARD_PINNACLESAT: + card->fe = dvb_attach(cx24110_attach, &pctvsat_config, card->i2c_adapter); + if (card->fe) { + card->fe->ops.tuner_ops.init = pinnsat_tuner_init; + card->fe->ops.tuner_ops.sleep = pinnsat_tuner_sleep; + card->fe->ops.tuner_ops.set_params = cx24108_tuner_set_params; } break; - case BTTV_PC_HDTV: - card->fe = or51211_attach(&or51211_config, card->i2c_adapter); - if (card->fe != NULL) { - break; - } + case BTTV_BOARD_PC_HDTV: + card->fe = dvb_attach(or51211_attach, &or51211_config, card->i2c_adapter); break; } - if (card->fe == NULL) { + if (card->fe == NULL) printk("dvb-bt8xx: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n", card->bt->dev->vendor, card->bt->dev->device, card->bt->dev->subsystem_vendor, card->bt->dev->subsystem_device); - } else { + else if (dvb_register_frontend(&card->dvb_adapter, card->fe)) { printk("dvb-bt8xx: Frontend registration failed!\n"); - if (card->fe->ops->release) - card->fe->ops->release(card->fe); + dvb_frontend_detach(card->fe); card->fe = NULL; } - } } -static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type) +static int __devinit dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type) { int result; - if ((result = dvb_register_adapter(&card->dvb_adapter, card->card_name, - THIS_MODULE)) < 0) { + if ((result = dvb_register_adapter(&card->dvb_adapter, card->card_name, THIS_MODULE, &card->bt->dev->dev)) < 0) { printk("dvb_bt8xx: dvb_register_adapter failed (errno = %d)\n", result); return result; - } card->dvb_adapter.priv = card; @@ -648,63 +792,60 @@ static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type) return 0; } -static int dvb_bt8xx_probe(struct device *dev) +static int __devinit dvb_bt8xx_probe(struct bttv_sub_device *sub) { - struct bttv_sub_device *sub = to_bttv_sub_dev(dev); struct dvb_bt8xx_card *card; struct pci_dev* bttv_pci_dev; int ret; - if (!(card = kmalloc(sizeof(struct dvb_bt8xx_card), GFP_KERNEL))) + if (!(card = kzalloc(sizeof(struct dvb_bt8xx_card), GFP_KERNEL))) return -ENOMEM; - memset(card, 0, sizeof(*card)); - init_MUTEX(&card->lock); + mutex_init(&card->lock); card->bttv_nr = sub->core->nr; strncpy(card->card_name, sub->core->name, sizeof(sub->core->name)); card->i2c_adapter = &sub->core->i2c_adap; - switch(sub->core->type) - { - case BTTV_PINNACLESAT: + switch(sub->core->type) { + case BTTV_BOARD_PINNACLESAT: card->gpio_mode = 0x0400c060; /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR, BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */ - card->op_sync_orin = 0; - card->irq_err_ignore = 0; + card->op_sync_orin = BT878_RISC_SYNC_MASK; + card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; break; -#ifdef BTTV_DVICO_DVBT_LITE - case BTTV_DVICO_DVBT_LITE: -#endif + case BTTV_BOARD_DVICO_DVBT_LITE: card->gpio_mode = 0x0400C060; - card->op_sync_orin = 0; - card->irq_err_ignore = 0; + card->op_sync_orin = BT878_RISC_SYNC_MASK; + card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; /* 26, 15, 14, 6, 5 * A_PWRDN DA_DPM DA_SBR DA_IOM_DA * DA_APP(parallel) */ break; -#ifdef BTTV_TWINHAN_VP3021 - case BTTV_TWINHAN_VP3021: -#else - case BTTV_NEBULA_DIGITV: -#endif - case BTTV_AVDVBT_761: + case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: + card->gpio_mode = 0x0400c060; + card->op_sync_orin = BT878_RISC_SYNC_MASK; + card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; + break; + + case BTTV_BOARD_NEBULA_DIGITV: + case BTTV_BOARD_AVDVBT_761: card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5); - card->op_sync_orin = 0; - card->irq_err_ignore = 0; + card->op_sync_orin = BT878_RISC_SYNC_MASK; + card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; /* A_PWRDN DA_SBR DA_APP (high speed serial) */ break; - case BTTV_AVDVBT_771: //case 0x07711461: + case BTTV_BOARD_AVDVBT_771: //case 0x07711461: card->gpio_mode = 0x0400402B; card->op_sync_orin = BT878_RISC_SYNC_MASK; - card->irq_err_ignore = 0; + card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; /* A_PWRDN DA_SBR DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/ break; - case BTTV_TWINHAN_DST: + case BTTV_BOARD_TWINHAN_DST: card->gpio_mode = 0x2204f2c; card->op_sync_orin = BT878_RISC_SYNC_MASK; card->irq_err_ignore = BT878_APABORT | BT878_ARIPERR | @@ -722,10 +863,10 @@ static int dvb_bt8xx_probe(struct device *dev) * RISC+FIFO ENABLE */ break; - case BTTV_PC_HDTV: + case BTTV_BOARD_PC_HDTV: card->gpio_mode = 0x0100EC7B; - card->op_sync_orin = 0; - card->irq_err_ignore = 0; + card->op_sync_orin = BT878_RISC_SYNC_MASK; + card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; break; default: @@ -751,10 +892,9 @@ static int dvb_bt8xx_probe(struct device *dev) kfree(card); return -EFAULT; - } - init_MUTEX(&card->bt->gpio_lock); + mutex_init(&card->bt->gpio_lock); card->bt->bttv_nr = sub->core->nr; if ( (ret = dvb_bt8xx_load_card(card, sub->core->type)) ) { @@ -762,13 +902,13 @@ static int dvb_bt8xx_probe(struct device *dev) return ret; } - dev_set_drvdata(dev, card); + dev_set_drvdata(&sub->dev, card); return 0; } -static int dvb_bt8xx_remove(struct device *dev) +static void dvb_bt8xx_remove(struct bttv_sub_device *sub) { - struct dvb_bt8xx_card *card = dev_get_drvdata(dev); + struct dvb_bt8xx_card *card = dev_get_drvdata(&sub->dev); dprintk("dvb_bt8xx: unloading card%d\n", card->bttv_nr); @@ -779,25 +919,26 @@ static int dvb_bt8xx_remove(struct device *dev) card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw); dvb_dmxdev_release(&card->dmxdev); dvb_dmx_release(&card->demux); - if (card->fe) dvb_unregister_frontend(card->fe); + if (card->fe) { + dvb_unregister_frontend(card->fe); + dvb_frontend_detach(card->fe); + } dvb_unregister_adapter(&card->dvb_adapter); kfree(card); - - return 0; } static struct bttv_sub_driver driver = { .drv = { .name = "dvb-bt8xx", - .probe = dvb_bt8xx_probe, - .remove = dvb_bt8xx_remove, - /* FIXME: - * .shutdown = dvb_bt8xx_shutdown, - * .suspend = dvb_bt8xx_suspend, - * .resume = dvb_bt8xx_resume, - */ }, + .probe = dvb_bt8xx_probe, + .remove = dvb_bt8xx_remove, + /* FIXME: + * .shutdown = dvb_bt8xx_shutdown, + * .suspend = dvb_bt8xx_suspend, + * .resume = dvb_bt8xx_resume, + */ }; static int __init dvb_bt8xx_init(void)