diff options
Diffstat (limited to 'drivers/media/video/em28xx/em28xx-dvb.c')
-rw-r--r-- | drivers/media/video/em28xx/em28xx-dvb.c | 74 |
1 files changed, 72 insertions, 2 deletions
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index e7b47c8da8f3..cf0ac7f2a30d 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #include "lgdt330x.h" | 31 | #include "lgdt330x.h" |
32 | #include "zl10353.h" | 32 | #include "zl10353.h" |
33 | #include "s5h1409.h" | 33 | #include "s5h1409.h" |
34 | #include "mt352.h" | ||
35 | #include "mt352_priv.h" /* FIXME */ | ||
34 | 36 | ||
35 | MODULE_DESCRIPTION("driver for em28xx based DVB cards"); | 37 | MODULE_DESCRIPTION("driver for em28xx based DVB cards"); |
36 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | 38 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); |
@@ -243,6 +245,14 @@ static struct s5h1409_config em28xx_s5h1409_with_xc3028 = { | |||
243 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK | 245 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK |
244 | }; | 246 | }; |
245 | 247 | ||
248 | static struct zl10353_config em28xx_zl10353_xc3028_no_i2c_gate = { | ||
249 | .demod_address = (0x1e >> 1), | ||
250 | .no_tuner = 1, | ||
251 | .disable_i2c_gate_ctrl = 1, | ||
252 | .parallel_ts = 1, | ||
253 | .if2 = 45600, | ||
254 | }; | ||
255 | |||
246 | #ifdef EM28XX_DRX397XD_SUPPORT | 256 | #ifdef EM28XX_DRX397XD_SUPPORT |
247 | /* [TODO] djh - not sure yet what the device config needs to contain */ | 257 | /* [TODO] djh - not sure yet what the device config needs to contain */ |
248 | static struct drx397xD_config em28xx_drx397xD_with_xc3028 = { | 258 | static struct drx397xD_config em28xx_drx397xD_with_xc3028 = { |
@@ -250,6 +260,41 @@ static struct drx397xD_config em28xx_drx397xD_with_xc3028 = { | |||
250 | }; | 260 | }; |
251 | #endif | 261 | #endif |
252 | 262 | ||
263 | static int mt352_terratec_xs_init(struct dvb_frontend *fe) | ||
264 | { | ||
265 | /* Values extracted from a USB trace of the Terratec Windows driver */ | ||
266 | static u8 clock_config[] = { CLOCK_CTL, 0x38, 0x2c }; | ||
267 | static u8 reset[] = { RESET, 0x80 }; | ||
268 | static u8 adc_ctl_1_cfg[] = { ADC_CTL_1, 0x40 }; | ||
269 | static u8 agc_cfg[] = { AGC_TARGET, 0x28, 0xa0 }; | ||
270 | static u8 input_freq_cfg[] = { INPUT_FREQ_1, 0x31, 0xb8 }; | ||
271 | static u8 rs_err_cfg[] = { RS_ERR_PER_1, 0x00, 0x4d }; | ||
272 | static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; | ||
273 | static u8 trl_nom_cfg[] = { TRL_NOMINAL_RATE_1, 0x64, 0x00 }; | ||
274 | static u8 tps_given_cfg[] = { TPS_GIVEN_1, 0x40, 0x80, 0x50 }; | ||
275 | static u8 tuner_go[] = { TUNER_GO, 0x01}; | ||
276 | |||
277 | mt352_write(fe, clock_config, sizeof(clock_config)); | ||
278 | udelay(200); | ||
279 | mt352_write(fe, reset, sizeof(reset)); | ||
280 | mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); | ||
281 | mt352_write(fe, agc_cfg, sizeof(agc_cfg)); | ||
282 | mt352_write(fe, input_freq_cfg, sizeof(input_freq_cfg)); | ||
283 | mt352_write(fe, rs_err_cfg, sizeof(rs_err_cfg)); | ||
284 | mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); | ||
285 | mt352_write(fe, trl_nom_cfg, sizeof(trl_nom_cfg)); | ||
286 | mt352_write(fe, tps_given_cfg, sizeof(tps_given_cfg)); | ||
287 | mt352_write(fe, tuner_go, sizeof(tuner_go)); | ||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | static struct mt352_config terratec_xs_mt352_cfg = { | ||
292 | .demod_address = (0x1e >> 1), | ||
293 | .no_tuner = 1, | ||
294 | .if2 = 45600, | ||
295 | .demod_init = mt352_terratec_xs_init, | ||
296 | }; | ||
297 | |||
253 | /* ------------------------------------------------------------------ */ | 298 | /* ------------------------------------------------------------------ */ |
254 | 299 | ||
255 | static int attach_xc3028(u8 addr, struct em28xx *dev) | 300 | static int attach_xc3028(u8 addr, struct em28xx *dev) |
@@ -432,8 +477,6 @@ static int dvb_init(struct em28xx *dev) | |||
432 | goto out_free; | 477 | goto out_free; |
433 | } | 478 | } |
434 | break; | 479 | break; |
435 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: | ||
436 | case EM2880_BOARD_TERRATEC_HYBRID_XS: | ||
437 | case EM2880_BOARD_KWORLD_DVB_310U: | 480 | case EM2880_BOARD_KWORLD_DVB_310U: |
438 | case EM2880_BOARD_EMPIRE_DUAL_TV: | 481 | case EM2880_BOARD_EMPIRE_DUAL_TV: |
439 | dvb->frontend = dvb_attach(zl10353_attach, | 482 | dvb->frontend = dvb_attach(zl10353_attach, |
@@ -444,6 +487,33 @@ static int dvb_init(struct em28xx *dev) | |||
444 | goto out_free; | 487 | goto out_free; |
445 | } | 488 | } |
446 | break; | 489 | break; |
490 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: | ||
491 | dvb->frontend = dvb_attach(zl10353_attach, | ||
492 | &em28xx_zl10353_xc3028_no_i2c_gate, | ||
493 | &dev->i2c_adap); | ||
494 | if (attach_xc3028(0x61, dev) < 0) { | ||
495 | result = -EINVAL; | ||
496 | goto out_free; | ||
497 | } | ||
498 | break; | ||
499 | case EM2880_BOARD_TERRATEC_HYBRID_XS: | ||
500 | case EM2881_BOARD_PINNACLE_HYBRID_PRO: | ||
501 | dvb->frontend = dvb_attach(zl10353_attach, | ||
502 | &em28xx_zl10353_xc3028_no_i2c_gate, | ||
503 | &dev->i2c_adap); | ||
504 | if (dvb->frontend == NULL) { | ||
505 | /* This board could have either a zl10353 or a mt352. | ||
506 | If the chip id isn't for zl10353, try mt352 */ | ||
507 | dvb->frontend = dvb_attach(mt352_attach, | ||
508 | &terratec_xs_mt352_cfg, | ||
509 | &dev->i2c_adap); | ||
510 | } | ||
511 | |||
512 | if (attach_xc3028(0x61, dev) < 0) { | ||
513 | result = -EINVAL; | ||
514 | goto out_free; | ||
515 | } | ||
516 | break; | ||
447 | case EM2883_BOARD_KWORLD_HYBRID_330U: | 517 | case EM2883_BOARD_KWORLD_HYBRID_330U: |
448 | case EM2882_BOARD_EVGA_INDTUBE: | 518 | case EM2882_BOARD_EVGA_INDTUBE: |
449 | dvb->frontend = dvb_attach(s5h1409_attach, | 519 | dvb->frontend = dvb_attach(s5h1409_attach, |