diff options
Diffstat (limited to 'drivers/media/video/cx88/cx88-dvb.c')
-rw-r--r-- | drivers/media/video/cx88/cx88-dvb.c | 215 |
1 files changed, 213 insertions, 2 deletions
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index 99ea955f5987..42c012aaa849 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * device driver for Conexant 2388x based TV cards | 3 | * device driver for Conexant 2388x based TV cards |
4 | * MPEG Transport Stream (DVB) routines | 4 | * MPEG Transport Stream (DVB) routines |
5 | * | 5 | * |
6 | * (c) 2004 Chris Pascoe <c.pascoe@itee.uq.edu.au> | 6 | * (c) 2004, 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au> |
7 | * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] | 7 | * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
@@ -31,10 +31,14 @@ | |||
31 | 31 | ||
32 | #include "cx88.h" | 32 | #include "cx88.h" |
33 | #include "dvb-pll.h" | 33 | #include "dvb-pll.h" |
34 | #include <media/v4l2-common.h> | ||
34 | 35 | ||
35 | #ifdef HAVE_MT352 | 36 | #ifdef HAVE_MT352 |
36 | # include "mt352.h" | 37 | # include "mt352.h" |
37 | # include "mt352_priv.h" | 38 | # include "mt352_priv.h" |
39 | # ifdef HAVE_VP3054_I2C | ||
40 | # include "cx88-vp3054-i2c.h" | ||
41 | # endif | ||
38 | #endif | 42 | #endif |
39 | #ifdef HAVE_CX22702 | 43 | #ifdef HAVE_CX22702 |
40 | # include "cx22702.h" | 44 | # include "cx22702.h" |
@@ -48,6 +52,9 @@ | |||
48 | #ifdef HAVE_NXT200X | 52 | #ifdef HAVE_NXT200X |
49 | # include "nxt200x.h" | 53 | # include "nxt200x.h" |
50 | #endif | 54 | #endif |
55 | #ifdef HAVE_CX24123 | ||
56 | # include "cx24123.h" | ||
57 | #endif | ||
51 | 58 | ||
52 | MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); | 59 | MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); |
53 | MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); | 60 | MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); |
@@ -125,6 +132,27 @@ static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe) | |||
125 | return 0; | 132 | return 0; |
126 | } | 133 | } |
127 | 134 | ||
135 | static int dvico_dual_demod_init(struct dvb_frontend *fe) | ||
136 | { | ||
137 | static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x38 }; | ||
138 | static u8 reset [] = { RESET, 0x80 }; | ||
139 | static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; | ||
140 | static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 }; | ||
141 | static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 }; | ||
142 | static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; | ||
143 | |||
144 | mt352_write(fe, clock_config, sizeof(clock_config)); | ||
145 | udelay(200); | ||
146 | mt352_write(fe, reset, sizeof(reset)); | ||
147 | mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); | ||
148 | |||
149 | mt352_write(fe, agc_cfg, sizeof(agc_cfg)); | ||
150 | mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg)); | ||
151 | mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); | ||
152 | |||
153 | return 0; | ||
154 | } | ||
155 | |||
128 | static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe) | 156 | static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe) |
129 | { | 157 | { |
130 | static u8 clock_config [] = { 0x89, 0x38, 0x39 }; | 158 | static u8 clock_config [] = { 0x89, 0x38, 0x39 }; |
@@ -172,6 +200,98 @@ static struct mt352_config dntv_live_dvbt_config = { | |||
172 | .demod_init = dntv_live_dvbt_demod_init, | 200 | .demod_init = dntv_live_dvbt_demod_init, |
173 | .pll_set = mt352_pll_set, | 201 | .pll_set = mt352_pll_set, |
174 | }; | 202 | }; |
203 | |||
204 | static struct mt352_config dvico_fusionhdtv_dual = { | ||
205 | .demod_address = 0x0F, | ||
206 | .demod_init = dvico_dual_demod_init, | ||
207 | .pll_set = mt352_pll_set, | ||
208 | }; | ||
209 | |||
210 | #ifdef HAVE_VP3054_I2C | ||
211 | static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe) | ||
212 | { | ||
213 | static u8 clock_config [] = { 0x89, 0x38, 0x38 }; | ||
214 | static u8 reset [] = { 0x50, 0x80 }; | ||
215 | static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 }; | ||
216 | static u8 agc_cfg [] = { 0x67, 0x10, 0x20, 0x00, 0xFF, 0xFF, | ||
217 | 0x00, 0xFF, 0x00, 0x40, 0x40 }; | ||
218 | static u8 dntv_extra[] = { 0xB5, 0x7A }; | ||
219 | static u8 capt_range_cfg[] = { 0x75, 0x32 }; | ||
220 | |||
221 | mt352_write(fe, clock_config, sizeof(clock_config)); | ||
222 | udelay(2000); | ||
223 | mt352_write(fe, reset, sizeof(reset)); | ||
224 | mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); | ||
225 | |||
226 | mt352_write(fe, agc_cfg, sizeof(agc_cfg)); | ||
227 | udelay(2000); | ||
228 | mt352_write(fe, dntv_extra, sizeof(dntv_extra)); | ||
229 | mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); | ||
230 | |||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | static int philips_fmd1216_pll_init(struct dvb_frontend *fe) | ||
235 | { | ||
236 | struct cx8802_dev *dev= fe->dvb->priv; | ||
237 | |||
238 | /* this message is to set up ATC and ALC */ | ||
239 | static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0xa0 }; | ||
240 | struct i2c_msg msg = | ||
241 | { .addr = dev->core->pll_addr, .flags = 0, | ||
242 | .buf = fmd1216_init, .len = sizeof(fmd1216_init) }; | ||
243 | int err; | ||
244 | |||
245 | if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { | ||
246 | if (err < 0) | ||
247 | return err; | ||
248 | else | ||
249 | return -EREMOTEIO; | ||
250 | } | ||
251 | |||
252 | return 0; | ||
253 | } | ||
254 | |||
255 | static int dntv_live_dvbt_pro_pll_set(struct dvb_frontend* fe, | ||
256 | struct dvb_frontend_parameters* params, | ||
257 | u8* pllbuf) | ||
258 | { | ||
259 | struct cx8802_dev *dev= fe->dvb->priv; | ||
260 | struct i2c_msg msg = | ||
261 | { .addr = dev->core->pll_addr, .flags = 0, | ||
262 | .buf = pllbuf+1, .len = 4 }; | ||
263 | int err; | ||
264 | |||
265 | /* Switch PLL to DVB mode */ | ||
266 | err = philips_fmd1216_pll_init(fe); | ||
267 | if (err) | ||
268 | return err; | ||
269 | |||
270 | /* Tune PLL */ | ||
271 | pllbuf[0] = dev->core->pll_addr << 1; | ||
272 | dvb_pll_configure(dev->core->pll_desc, pllbuf+1, | ||
273 | params->frequency, | ||
274 | params->u.ofdm.bandwidth); | ||
275 | if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { | ||
276 | printk(KERN_WARNING "cx88-dvb: %s error " | ||
277 | "(addr %02x <- %02x, err = %i)\n", | ||
278 | __FUNCTION__, pllbuf[0], pllbuf[1], err); | ||
279 | if (err < 0) | ||
280 | return err; | ||
281 | else | ||
282 | return -EREMOTEIO; | ||
283 | } | ||
284 | |||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | static struct mt352_config dntv_live_dvbt_pro_config = { | ||
289 | .demod_address = 0x0f, | ||
290 | .no_tuner = 1, | ||
291 | .demod_init = dntv_live_dvbt_pro_demod_init, | ||
292 | .pll_set = dntv_live_dvbt_pro_pll_set, | ||
293 | }; | ||
294 | #endif | ||
175 | #endif | 295 | #endif |
176 | 296 | ||
177 | #ifdef HAVE_CX22702 | 297 | #ifdef HAVE_CX22702 |
@@ -188,6 +308,12 @@ static struct cx22702_config hauppauge_novat_config = { | |||
188 | .pll_address = 0x61, | 308 | .pll_address = 0x61, |
189 | .pll_desc = &dvb_pll_thomson_dtt759x, | 309 | .pll_desc = &dvb_pll_thomson_dtt759x, |
190 | }; | 310 | }; |
311 | static struct cx22702_config hauppauge_hvr1100_config = { | ||
312 | .demod_address = 0x63, | ||
313 | .output_mode = CX22702_SERIAL_OUTPUT, | ||
314 | .pll_address = 0x61, | ||
315 | .pll_desc = &dvb_pll_fmd1216me, | ||
316 | }; | ||
191 | #endif | 317 | #endif |
192 | 318 | ||
193 | #ifdef HAVE_OR51132 | 319 | #ifdef HAVE_OR51132 |
@@ -314,6 +440,40 @@ static struct nxt200x_config ati_hdtvwonder = { | |||
314 | }; | 440 | }; |
315 | #endif | 441 | #endif |
316 | 442 | ||
443 | #ifdef HAVE_CX24123 | ||
444 | static int cx24123_set_ts_param(struct dvb_frontend* fe, | ||
445 | int is_punctured) | ||
446 | { | ||
447 | struct cx8802_dev *dev= fe->dvb->priv; | ||
448 | dev->ts_gen_cntrl = 0x2; | ||
449 | return 0; | ||
450 | } | ||
451 | |||
452 | static void cx24123_enable_lnb_voltage(struct dvb_frontend* fe, int on) | ||
453 | { | ||
454 | struct cx8802_dev *dev= fe->dvb->priv; | ||
455 | struct cx88_core *core = dev->core; | ||
456 | |||
457 | if (on) | ||
458 | cx_write(MO_GP0_IO, 0x000006f9); | ||
459 | else | ||
460 | cx_write(MO_GP0_IO, 0x000006fB); | ||
461 | } | ||
462 | |||
463 | static struct cx24123_config hauppauge_novas_config = { | ||
464 | .demod_address = 0x55, | ||
465 | .use_isl6421 = 1, | ||
466 | .set_ts_params = cx24123_set_ts_param, | ||
467 | }; | ||
468 | |||
469 | static struct cx24123_config kworld_dvbs_100_config = { | ||
470 | .demod_address = 0x15, | ||
471 | .use_isl6421 = 0, | ||
472 | .set_ts_params = cx24123_set_ts_param, | ||
473 | .enable_lnb_voltage = cx24123_enable_lnb_voltage, | ||
474 | }; | ||
475 | #endif | ||
476 | |||
317 | static int dvb_register(struct cx8802_dev *dev) | 477 | static int dvb_register(struct cx8802_dev *dev) |
318 | { | 478 | { |
319 | /* init struct videobuf_dvb */ | 479 | /* init struct videobuf_dvb */ |
@@ -329,10 +489,16 @@ static int dvb_register(struct cx8802_dev *dev) | |||
329 | break; | 489 | break; |
330 | case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: | 490 | case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: |
331 | case CX88_BOARD_CONEXANT_DVB_T1: | 491 | case CX88_BOARD_CONEXANT_DVB_T1: |
492 | case CX88_BOARD_KWORLD_DVB_T_CX22702: | ||
332 | case CX88_BOARD_WINFAST_DTV1000: | 493 | case CX88_BOARD_WINFAST_DTV1000: |
333 | dev->dvb.frontend = cx22702_attach(&connexant_refboard_config, | 494 | dev->dvb.frontend = cx22702_attach(&connexant_refboard_config, |
334 | &dev->core->i2c_adap); | 495 | &dev->core->i2c_adap); |
335 | break; | 496 | break; |
497 | case CX88_BOARD_HAUPPAUGE_HVR1100: | ||
498 | case CX88_BOARD_HAUPPAUGE_HVR1100LP: | ||
499 | dev->dvb.frontend = cx22702_attach(&hauppauge_hvr1100_config, | ||
500 | &dev->core->i2c_adap); | ||
501 | break; | ||
336 | #endif | 502 | #endif |
337 | #ifdef HAVE_MT352 | 503 | #ifdef HAVE_MT352 |
338 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: | 504 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: |
@@ -355,6 +521,24 @@ static int dvb_register(struct cx8802_dev *dev) | |||
355 | dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config, | 521 | dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config, |
356 | &dev->core->i2c_adap); | 522 | &dev->core->i2c_adap); |
357 | break; | 523 | break; |
524 | case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: | ||
525 | #ifdef HAVE_VP3054_I2C | ||
526 | dev->core->pll_addr = 0x61; | ||
527 | dev->core->pll_desc = &dvb_pll_fmd1216me; | ||
528 | dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_pro_config, | ||
529 | &((struct vp3054_i2c_state *)dev->card_priv)->adap); | ||
530 | #else | ||
531 | printk("%s: built without vp3054 support\n", dev->core->name); | ||
532 | #endif | ||
533 | break; | ||
534 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: | ||
535 | /* The tin box says DEE1601, but it seems to be DTT7579 | ||
536 | * compatible, with a slightly different MT352 AGC gain. */ | ||
537 | dev->core->pll_addr = 0x61; | ||
538 | dev->core->pll_desc = &dvb_pll_thomson_dtt7579; | ||
539 | dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv_dual, | ||
540 | &dev->core->i2c_adap); | ||
541 | break; | ||
358 | #endif | 542 | #endif |
359 | #ifdef HAVE_OR51132 | 543 | #ifdef HAVE_OR51132 |
360 | case CX88_BOARD_PCHDTV_HD3000: | 544 | case CX88_BOARD_PCHDTV_HD3000: |
@@ -393,7 +577,7 @@ static int dvb_register(struct cx8802_dev *dev) | |||
393 | cx_set(MO_GP0_IO, 9); | 577 | cx_set(MO_GP0_IO, 9); |
394 | mdelay(200); | 578 | mdelay(200); |
395 | dev->core->pll_addr = 0x61; | 579 | dev->core->pll_addr = 0x61; |
396 | dev->core->pll_desc = &dvb_pll_thomson_dtt7611; | 580 | dev->core->pll_desc = &dvb_pll_thomson_dtt761x; |
397 | dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold, | 581 | dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold, |
398 | &dev->core->i2c_adap); | 582 | &dev->core->i2c_adap); |
399 | } | 583 | } |
@@ -421,6 +605,17 @@ static int dvb_register(struct cx8802_dev *dev) | |||
421 | &dev->core->i2c_adap); | 605 | &dev->core->i2c_adap); |
422 | break; | 606 | break; |
423 | #endif | 607 | #endif |
608 | #ifdef HAVE_CX24123 | ||
609 | case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: | ||
610 | case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: | ||
611 | dev->dvb.frontend = cx24123_attach(&hauppauge_novas_config, | ||
612 | &dev->core->i2c_adap); | ||
613 | break; | ||
614 | case CX88_BOARD_KWORLD_DVBS_100: | ||
615 | dev->dvb.frontend = cx24123_attach(&kworld_dvbs_100_config, | ||
616 | &dev->core->i2c_adap); | ||
617 | break; | ||
618 | #endif | ||
424 | default: | 619 | default: |
425 | printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", | 620 | printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", |
426 | dev->core->name); | 621 | dev->core->name); |
@@ -473,6 +668,12 @@ static int __devinit dvb_probe(struct pci_dev *pci_dev, | |||
473 | if (0 != err) | 668 | if (0 != err) |
474 | goto fail_free; | 669 | goto fail_free; |
475 | 670 | ||
671 | #ifdef HAVE_VP3054_I2C | ||
672 | err = vp3054_i2c_probe(dev); | ||
673 | if (0 != err) | ||
674 | goto fail_free; | ||
675 | #endif | ||
676 | |||
476 | /* dvb stuff */ | 677 | /* dvb stuff */ |
477 | printk("%s/2: cx2388x based dvb card\n", core->name); | 678 | printk("%s/2: cx2388x based dvb card\n", core->name); |
478 | videobuf_queue_init(&dev->dvb.dvbq, &dvb_qops, | 679 | videobuf_queue_init(&dev->dvb.dvbq, &dvb_qops, |
@@ -484,6 +685,9 @@ static int __devinit dvb_probe(struct pci_dev *pci_dev, | |||
484 | err = dvb_register(dev); | 685 | err = dvb_register(dev); |
485 | if (0 != err) | 686 | if (0 != err) |
486 | goto fail_fini; | 687 | goto fail_fini; |
688 | |||
689 | /* Maintain a reference to cx88-video can query the 8802 device. */ | ||
690 | core->dvbdev = dev; | ||
487 | return 0; | 691 | return 0; |
488 | 692 | ||
489 | fail_fini: | 693 | fail_fini: |
@@ -499,9 +703,16 @@ static void __devexit dvb_remove(struct pci_dev *pci_dev) | |||
499 | { | 703 | { |
500 | struct cx8802_dev *dev = pci_get_drvdata(pci_dev); | 704 | struct cx8802_dev *dev = pci_get_drvdata(pci_dev); |
501 | 705 | ||
706 | /* Destroy any 8802 reference. */ | ||
707 | dev->core->dvbdev = NULL; | ||
708 | |||
502 | /* dvb */ | 709 | /* dvb */ |
503 | videobuf_dvb_unregister(&dev->dvb); | 710 | videobuf_dvb_unregister(&dev->dvb); |
504 | 711 | ||
712 | #ifdef HAVE_VP3054_I2C | ||
713 | vp3054_i2c_remove(dev); | ||
714 | #endif | ||
715 | |||
505 | /* common */ | 716 | /* common */ |
506 | cx8802_fini_common(dev); | 717 | cx8802_fini_common(dev); |
507 | cx88_core_put(dev->core,dev->pci); | 718 | cx88_core_put(dev->core,dev->pci); |