diff options
Diffstat (limited to 'drivers/media/video/em28xx/em28xx-dvb.c')
-rw-r--r-- | drivers/media/video/em28xx/em28xx-dvb.c | 62 |
1 files changed, 53 insertions, 9 deletions
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index 3da97c32b8fa..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,7 +245,7 @@ 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 | ||
246 | static struct zl10353_config em28xx_terratec_xs_zl10353_xc3028 = { | 248 | static struct zl10353_config em28xx_zl10353_xc3028_no_i2c_gate = { |
247 | .demod_address = (0x1e >> 1), | 249 | .demod_address = (0x1e >> 1), |
248 | .no_tuner = 1, | 250 | .no_tuner = 1, |
249 | .disable_i2c_gate_ctrl = 1, | 251 | .disable_i2c_gate_ctrl = 1, |
@@ -258,6 +260,41 @@ static struct drx397xD_config em28xx_drx397xD_with_xc3028 = { | |||
258 | }; | 260 | }; |
259 | #endif | 261 | #endif |
260 | 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 | |||
261 | /* ------------------------------------------------------------------ */ | 298 | /* ------------------------------------------------------------------ */ |
262 | 299 | ||
263 | static int attach_xc3028(u8 addr, struct em28xx *dev) | 300 | static int attach_xc3028(u8 addr, struct em28xx *dev) |
@@ -440,7 +477,6 @@ static int dvb_init(struct em28xx *dev) | |||
440 | goto out_free; | 477 | goto out_free; |
441 | } | 478 | } |
442 | break; | 479 | break; |
443 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: | ||
444 | case EM2880_BOARD_KWORLD_DVB_310U: | 480 | case EM2880_BOARD_KWORLD_DVB_310U: |
445 | case EM2880_BOARD_EMPIRE_DUAL_TV: | 481 | case EM2880_BOARD_EMPIRE_DUAL_TV: |
446 | dvb->frontend = dvb_attach(zl10353_attach, | 482 | dvb->frontend = dvb_attach(zl10353_attach, |
@@ -451,20 +487,28 @@ static int dvb_init(struct em28xx *dev) | |||
451 | goto out_free; | 487 | goto out_free; |
452 | } | 488 | } |
453 | 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; | ||
454 | case EM2880_BOARD_TERRATEC_HYBRID_XS: | 499 | case EM2880_BOARD_TERRATEC_HYBRID_XS: |
500 | case EM2881_BOARD_PINNACLE_HYBRID_PRO: | ||
455 | dvb->frontend = dvb_attach(zl10353_attach, | 501 | dvb->frontend = dvb_attach(zl10353_attach, |
456 | &em28xx_terratec_xs_zl10353_xc3028, | 502 | &em28xx_zl10353_xc3028_no_i2c_gate, |
457 | &dev->i2c_adap); | 503 | &dev->i2c_adap); |
458 | if (dvb->frontend == NULL) { | 504 | if (dvb->frontend == NULL) { |
459 | /* This board could have either a zl10353 or a mt352. | 505 | /* This board could have either a zl10353 or a mt352. |
460 | If the chip id isn't for zl10353, try mt352 */ | 506 | If the chip id isn't for zl10353, try mt352 */ |
461 | 507 | dvb->frontend = dvb_attach(mt352_attach, | |
462 | /* FIXME: make support for mt352 work */ | 508 | &terratec_xs_mt352_cfg, |
463 | printk(KERN_ERR "version of this board with mt352 not " | 509 | &dev->i2c_adap); |
464 | "currently supported\n"); | ||
465 | result = -EINVAL; | ||
466 | goto out_free; | ||
467 | } | 510 | } |
511 | |||
468 | if (attach_xc3028(0x61, dev) < 0) { | 512 | if (attach_xc3028(0x61, dev) < 0) { |
469 | result = -EINVAL; | 513 | result = -EINVAL; |
470 | goto out_free; | 514 | goto out_free; |