1 /* Linux driver for devices based on the DiBcom DiB0700 USB bridge
3 * This program is free software; you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License as published by the Free
5 * Software Foundation, version 2.
7 * Copyright (C) 2005-7 DiBcom, SA
11 #include "dib3000mc.h"
16 #include "tuner-xc2028.h"
21 static int force_lna_activation;
22 module_param(force_lna_activation, int, 0644);
23 MODULE_PARM_DESC(force_lna_activation, "force the activation of Low-Noise-Amplifyer(s) (LNA), "
24 "if applicable for the device (default: 0=automatic/off).");
26 struct dib0700_adapter_state {
27 int (*set_param_save) (struct dvb_frontend *, struct dvb_frontend_parameters *);
30 /* Hauppauge Nova-T 500 (aka Bristol)
31 * has a LNA on GPIO0 which is enabled by setting 1 */
32 static struct mt2060_config bristol_mt2060_config[2] = {
42 static struct dibx000_agc_config bristol_dib3000p_mt2060_agc_config = {
43 .band_caps = BAND_VHF | BAND_UHF,
44 .setup = (1 << 8) | (5 << 5) | (0 << 4) | (0 << 3) | (0 << 2) | (2 << 0),
64 static struct dib3000mc_config bristol_dib3000mc_config[2] = {
65 { .agc = &bristol_dib3000p_mt2060_agc_config,
67 .ln_adc_level = 0x1cc7,
68 .output_mpeg2_in_188_bytes = 1,
70 { .agc = &bristol_dib3000p_mt2060_agc_config,
72 .ln_adc_level = 0x1cc7,
73 .output_mpeg2_in_188_bytes = 1,
77 static int bristol_frontend_attach(struct dvb_usb_adapter *adap)
79 struct dib0700_state *st = adap->dev->priv;
81 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(10);
82 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10);
83 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10);
84 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(10);
86 if (force_lna_activation)
87 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
89 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0);
91 if (dib3000mc_i2c_enumeration(&adap->dev->i2c_adap, 2, DEFAULT_DIB3000P_I2C_ADDRESS, bristol_dib3000mc_config) != 0) {
92 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(10);
96 st->mt2060_if1[adap->id] = 1220;
97 return (adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap,
98 (10 + adap->id) << 1, &bristol_dib3000mc_config[adap->id])) == NULL ? -ENODEV : 0;
101 static int eeprom_read(struct i2c_adapter *adap,u8 adrs,u8 *pval)
103 struct i2c_msg msg[2] = {
104 { .addr = 0x50, .flags = 0, .buf = &adrs, .len = 1 },
105 { .addr = 0x50, .flags = I2C_M_RD, .buf = pval, .len = 1 },
107 if (i2c_transfer(adap, msg, 2) != 2) return -EREMOTEIO;
111 static int bristol_tuner_attach(struct dvb_usb_adapter *adap)
113 struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap;
114 struct i2c_adapter *tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe, 1);
117 if (adap->dev->udev->descriptor.idVendor == cpu_to_le16(USB_VID_HAUPPAUGE) &&
118 adap->dev->udev->descriptor.idProduct == cpu_to_le16(USB_PID_HAUPPAUGE_NOVA_T_500_2)) {
119 if (!eeprom_read(prim_i2c,0x59 + adap->id,&a)) if1=1220+a;
121 return dvb_attach(mt2060_attach,adap->fe, tun_i2c,&bristol_mt2060_config[adap->id],
122 if1) == NULL ? -ENODEV : 0;
125 /* STK7700D: Pinnacle/Terratec/Hauppauge Dual DVB-T Diversity */
128 static struct dibx000_agc_config stk7700d_7000p_mt2266_agc_config[2] = {
130 BAND_UHF, // band_caps
132 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1,
133 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
134 (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup
167 1, // perform_agc_softsplit
169 BAND_VHF | BAND_LBAND, // band_caps
171 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1,
172 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
173 (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
206 1, // perform_agc_softsplit
210 static struct dibx000_bandwidth_config stk7700d_mt2266_pll_config = {
211 60000, 30000, // internal, sampling
212 1, 8, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
213 0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
214 (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
219 static struct dib7000p_config stk7700d_dib7000p_mt2266_config[] = {
220 { .output_mpeg2_in_188_bytes = 1,
221 .hostbus_diversity = 1,
222 .tuner_is_baseband = 1,
224 .agc_config_count = 2,
225 .agc = stk7700d_7000p_mt2266_agc_config,
226 .bw = &stk7700d_mt2266_pll_config,
228 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
229 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
230 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
232 { .output_mpeg2_in_188_bytes = 1,
233 .hostbus_diversity = 1,
234 .tuner_is_baseband = 1,
236 .agc_config_count = 2,
237 .agc = stk7700d_7000p_mt2266_agc_config,
238 .bw = &stk7700d_mt2266_pll_config,
240 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
241 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
242 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
246 static struct mt2266_config stk7700d_mt2266_config[2] = {
247 { .i2c_address = 0x60
249 { .i2c_address = 0x60
253 static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap)
256 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
258 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
259 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
260 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
261 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
263 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
265 dib7000p_i2c_enumeration(&adap->dev->i2c_adap,1,18,stk7700d_dib7000p_mt2266_config);
268 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1),
269 &stk7700d_dib7000p_mt2266_config[adap->id]);
271 return adap->fe == NULL ? -ENODEV : 0;
274 static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap)
277 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
279 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
280 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
281 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
282 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
284 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
286 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
287 dib7000p_i2c_enumeration(&adap->dev->i2c_adap,2,18,stk7700d_dib7000p_mt2266_config);
290 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1),
291 &stk7700d_dib7000p_mt2266_config[adap->id]);
293 return adap->fe == NULL ? -ENODEV : 0;
296 static int stk7700d_tuner_attach(struct dvb_usb_adapter *adap)
298 struct i2c_adapter *tun_i2c;
299 tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
300 return dvb_attach(mt2266_attach, adap->fe, tun_i2c,
301 &stk7700d_mt2266_config[adap->id]) == NULL ? -ENODEV : 0;;
304 /* STK7700-PH: Digital/Analog Hybrid Tuner, e.h. Cinergy HT USB HE */
305 static struct dibx000_agc_config xc3028_agc_config = {
306 BAND_VHF | BAND_UHF, /* band_caps */
308 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=0,
309 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
310 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
311 (0 << 15) | (0 << 14) | (0 << 11) | (0 << 10) | (0 << 9) | (0 << 8) |
312 (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), /* setup */
315 21, /* time_stabiliz */
327 39718, /* agc2_max */
336 29, /* agc2_slope1 */
337 29, /* agc2_slope2 */
344 1, /* perform_agc_softsplit */
347 /* PLL Configuration for COFDM BW_MHz = 8.00 with external clock = 30.00 */
348 static struct dibx000_bandwidth_config xc3028_bw_config = {
349 60000, 30000, /* internal, sampling */
350 1, 8, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass */
351 0, 0, 1, 1, 0, /* misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc,
353 (3 << 14) | (1 << 12) | (524 << 0), /* sad_cfg: refsel, sel, freq_15k */
354 (1 << 25) | 5816102, /* ifreq = 5.200000 MHz */
356 30000000, /* xtal_hz */
359 static struct dib7000p_config stk7700ph_dib7700_xc3028_config = {
360 .output_mpeg2_in_188_bytes = 1,
361 .tuner_is_baseband = 1,
363 .agc_config_count = 1,
364 .agc = &xc3028_agc_config,
365 .bw = &xc3028_bw_config,
367 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
368 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
369 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
372 static int stk7700ph_xc3028_callback(void *ptr, int component,
373 int command, int arg)
375 struct dvb_usb_adapter *adap = ptr;
378 case XC2028_TUNER_RESET:
379 /* Send the tuner in then out of reset */
380 dib7000p_set_gpio(adap->fe, 8, 0, 0); msleep(10);
381 dib7000p_set_gpio(adap->fe, 8, 0, 1);
383 case XC2028_RESET_CLK:
386 err("%s: unknown command %d, arg %d\n", __func__,
393 static struct xc2028_ctrl stk7700ph_xc3028_ctrl = {
394 .fname = XC2028_DEFAULT_FIRMWARE,
396 .demod = XC3028_FE_DIBCOM52,
399 static struct xc2028_config stk7700ph_xc3028_config = {
401 .ctrl = &stk7700ph_xc3028_ctrl,
404 static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap)
406 struct usb_device_descriptor *desc = &adap->dev->udev->descriptor;
408 if (desc->idVendor == cpu_to_le16(USB_VID_PINNACLE) &&
409 desc->idProduct == cpu_to_le16(USB_PID_PINNACLE_EXPRESSCARD_320CX))
410 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
412 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
414 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
415 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
416 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
417 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
419 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
421 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
424 dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
425 &stk7700ph_dib7700_xc3028_config);
427 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
428 &stk7700ph_dib7700_xc3028_config);
430 return adap->fe == NULL ? -ENODEV : 0;
433 static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap)
435 struct i2c_adapter *tun_i2c;
437 tun_i2c = dib7000p_get_i2c_master(adap->fe,
438 DIBX000_I2C_INTERFACE_TUNER, 1);
440 stk7700ph_xc3028_config.i2c_adap = tun_i2c;
442 /* FIXME: generalize & move to common area */
443 adap->fe->callback = stk7700ph_xc3028_callback;
445 return dvb_attach(xc2028_attach, adap->fe, &stk7700ph_xc3028_config)
446 == NULL ? -ENODEV : 0;
449 #define DEFAULT_RC_INTERVAL 150
451 static u8 rc_request[] = { REQUEST_POLL_RC, 0 };
453 /* Number of keypresses to ignore before start repeating */
454 #define RC_REPEAT_DELAY 2
455 #define RC_REPEAT_DELAY_V1_20 5
459 /* Used by firmware versions < 1.20 (deprecated) */
460 static int dib0700_rc_query_legacy(struct dvb_usb_device *d, u32 *event,
465 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
466 struct dib0700_state *st = d->priv;
468 *state = REMOTE_NO_KEY_PRESSED;
469 i=dib0700_ctrl_rd(d,rc_request,2,key,4);
471 err("RC Query Failed");
475 /* losing half of KEY_0 events from Philipps rc5 remotes.. */
476 if (key[0]==0 && key[1]==0 && key[2]==0 && key[3]==0) return 0;
478 /* info("%d: %2X %2X %2X %2X",dvb_usb_dib0700_ir_proto,(int)key[3-2],(int)key[3-3],(int)key[3-1],(int)key[3]); */
480 dib0700_rc_setup(d); /* reset ir sensor data to prevent false events */
482 switch (dvb_usb_dib0700_ir_proto) {
484 /* NEC protocol sends repeat code as 0 0 0 FF */
485 if ((key[3-2] == 0x00) && (key[3-3] == 0x00) &&
488 if (st->rc_counter > RC_REPEAT_DELAY) {
489 *event = d->last_event;
490 *state = REMOTE_KEY_PRESSED;
491 st->rc_counter = RC_REPEAT_DELAY;
495 for (i=0;i<d->props.rc_key_map_size; i++) {
496 if (keymap[i].custom == key[3-2] && keymap[i].data == key[3-3]) {
498 *event = keymap[i].event;
499 *state = REMOTE_KEY_PRESSED;
500 d->last_event = keymap[i].event;
507 /* RC-5 protocol changes toggle bit on new keypress */
508 for (i = 0; i < d->props.rc_key_map_size; i++) {
509 if (keymap[i].custom == key[3-2] && keymap[i].data == key[3-3]) {
510 if (d->last_event == keymap[i].event &&
511 key[3-1] == st->rc_toggle) {
513 /* prevents unwanted double hits */
514 if (st->rc_counter > RC_REPEAT_DELAY) {
515 *event = d->last_event;
516 *state = REMOTE_KEY_PRESSED;
517 st->rc_counter = RC_REPEAT_DELAY;
523 *event = keymap[i].event;
524 *state = REMOTE_KEY_PRESSED;
525 st->rc_toggle = key[3-1];
526 d->last_event = keymap[i].event;
533 err("Unknown remote controller key: %2X %2X %2X %2X", (int) key[3-2], (int) key[3-3], (int) key[3-1], (int) key[3]);
538 /* This is the structure of the RC response packet starting in firmware 1.20 */
539 struct dib0700_rc_response {
548 /* This supports the new IR response format for firmware v1.20 */
549 static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event,
552 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
553 struct dib0700_state *st = d->priv;
554 struct dib0700_rc_response poll_reply;
561 /* Set initial results in case we exit the function early */
563 *state = REMOTE_NO_KEY_PRESSED;
565 /* Firmware v1.20 provides RC data via bulk endpoint 1 */
566 status = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, 1), buf,
567 sizeof(buf), &actlen, 50);
569 /* No data available (meaning no key press) */
573 if (actlen != sizeof(buf)) {
574 /* We didn't get back the 6 byte message we expected */
575 err("Unexpected RC response size [%d]", actlen);
579 poll_reply.report_id = buf[0];
580 poll_reply.data_state = buf[1];
581 poll_reply.system_msb = buf[2];
582 poll_reply.system_lsb = buf[3];
583 poll_reply.data = buf[4];
584 poll_reply.not_data = buf[5];
587 info("rid=%02x ds=%02x sm=%02x sl=%02x d=%02x nd=%02x\n",
588 poll_reply.report_id, poll_reply.data_state,
589 poll_reply.system_msb, poll_reply.system_lsb,
590 poll_reply.data, poll_reply.not_data);
593 if ((poll_reply.data + poll_reply.not_data) != 0xff) {
594 /* Key failed integrity check */
595 err("key failed integrity check: %02x %02x %02x %02x",
596 poll_reply.system_msb, poll_reply.system_lsb,
597 poll_reply.data, poll_reply.not_data);
601 /* Find the key in the map */
602 for (i = 0; i < d->props.rc_key_map_size; i++) {
603 if (keymap[i].custom == poll_reply.system_lsb &&
604 keymap[i].data == poll_reply.data) {
605 *event = keymap[i].event;
612 err("Unknown remote controller key: %02x %02x %02x %02x",
613 poll_reply.system_msb, poll_reply.system_lsb,
614 poll_reply.data, poll_reply.not_data);
619 if (poll_reply.data_state == 1) {
622 *event = keymap[i].event;
623 *state = REMOTE_KEY_PRESSED;
624 d->last_event = keymap[i].event;
625 } else if (poll_reply.data_state == 2) {
629 /* prevents unwanted double hits */
630 if (st->rc_counter > RC_REPEAT_DELAY_V1_20) {
631 *event = d->last_event;
632 *state = REMOTE_KEY_PRESSED;
633 st->rc_counter = RC_REPEAT_DELAY_V1_20;
636 err("Unknown data state [%d]", poll_reply.data_state);
642 static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
644 struct dib0700_state *st = d->priv;
646 /* Because some people may have improperly named firmware files,
647 let's figure out whether to use the new firmware call or the legacy
648 call based on the firmware version embedded in the file */
649 if (st->rc_func_version == 0) {
650 u32 hwver, romver, ramver, fwtype;
651 int ret = dib0700_get_version(d, &hwver, &romver, &ramver,
654 err("Could not determine version info");
657 if (ramver < 0x10200)
658 st->rc_func_version = 1;
660 st->rc_func_version = 2;
663 if (st->rc_func_version == 2)
664 return dib0700_rc_query_v1_20(d, event, state);
666 return dib0700_rc_query_legacy(d, event, state);
669 static struct dvb_usb_rc_key dib0700_rc_keys[] = {
670 /* Key codes for the tiny Pinnacle remote*/
671 { 0x07, 0x00, KEY_MUTE },
672 { 0x07, 0x01, KEY_MENU }, // Pinnacle logo
673 { 0x07, 0x39, KEY_POWER },
674 { 0x07, 0x03, KEY_VOLUMEUP },
675 { 0x07, 0x09, KEY_VOLUMEDOWN },
676 { 0x07, 0x06, KEY_CHANNELUP },
677 { 0x07, 0x0c, KEY_CHANNELDOWN },
678 { 0x07, 0x0f, KEY_1 },
679 { 0x07, 0x15, KEY_2 },
680 { 0x07, 0x10, KEY_3 },
681 { 0x07, 0x18, KEY_4 },
682 { 0x07, 0x1b, KEY_5 },
683 { 0x07, 0x1e, KEY_6 },
684 { 0x07, 0x11, KEY_7 },
685 { 0x07, 0x21, KEY_8 },
686 { 0x07, 0x12, KEY_9 },
687 { 0x07, 0x27, KEY_0 },
688 { 0x07, 0x24, KEY_SCREEN }, // 'Square' key
689 { 0x07, 0x2a, KEY_TEXT }, // 'T' key
690 { 0x07, 0x2d, KEY_REWIND },
691 { 0x07, 0x30, KEY_PLAY },
692 { 0x07, 0x33, KEY_FASTFORWARD },
693 { 0x07, 0x36, KEY_RECORD },
694 { 0x07, 0x3c, KEY_STOP },
695 { 0x07, 0x3f, KEY_CANCEL }, // '?' key
696 /* Key codes for the Terratec Cinergy DT XS Diversity, similar to cinergyT2.c */
697 { 0xeb, 0x01, KEY_POWER },
698 { 0xeb, 0x02, KEY_1 },
699 { 0xeb, 0x03, KEY_2 },
700 { 0xeb, 0x04, KEY_3 },
701 { 0xeb, 0x05, KEY_4 },
702 { 0xeb, 0x06, KEY_5 },
703 { 0xeb, 0x07, KEY_6 },
704 { 0xeb, 0x08, KEY_7 },
705 { 0xeb, 0x09, KEY_8 },
706 { 0xeb, 0x0a, KEY_9 },
707 { 0xeb, 0x0b, KEY_VIDEO },
708 { 0xeb, 0x0c, KEY_0 },
709 { 0xeb, 0x0d, KEY_REFRESH },
710 { 0xeb, 0x0f, KEY_EPG },
711 { 0xeb, 0x10, KEY_UP },
712 { 0xeb, 0x11, KEY_LEFT },
713 { 0xeb, 0x12, KEY_OK },
714 { 0xeb, 0x13, KEY_RIGHT },
715 { 0xeb, 0x14, KEY_DOWN },
716 { 0xeb, 0x16, KEY_INFO },
717 { 0xeb, 0x17, KEY_RED },
718 { 0xeb, 0x18, KEY_GREEN },
719 { 0xeb, 0x19, KEY_YELLOW },
720 { 0xeb, 0x1a, KEY_BLUE },
721 { 0xeb, 0x1b, KEY_CHANNELUP },
722 { 0xeb, 0x1c, KEY_VOLUMEUP },
723 { 0xeb, 0x1d, KEY_MUTE },
724 { 0xeb, 0x1e, KEY_VOLUMEDOWN },
725 { 0xeb, 0x1f, KEY_CHANNELDOWN },
726 { 0xeb, 0x40, KEY_PAUSE },
727 { 0xeb, 0x41, KEY_HOME },
728 { 0xeb, 0x42, KEY_MENU }, /* DVD Menu */
729 { 0xeb, 0x43, KEY_SUBTITLE },
730 { 0xeb, 0x44, KEY_TEXT }, /* Teletext */
731 { 0xeb, 0x45, KEY_DELETE },
732 { 0xeb, 0x46, KEY_TV },
733 { 0xeb, 0x47, KEY_DVD },
734 { 0xeb, 0x48, KEY_STOP },
735 { 0xeb, 0x49, KEY_VIDEO },
736 { 0xeb, 0x4a, KEY_AUDIO }, /* Music */
737 { 0xeb, 0x4b, KEY_SCREEN }, /* Pic */
738 { 0xeb, 0x4c, KEY_PLAY },
739 { 0xeb, 0x4d, KEY_BACK },
740 { 0xeb, 0x4e, KEY_REWIND },
741 { 0xeb, 0x4f, KEY_FASTFORWARD },
742 { 0xeb, 0x54, KEY_PREVIOUS },
743 { 0xeb, 0x58, KEY_RECORD },
744 { 0xeb, 0x5c, KEY_NEXT },
746 /* Key codes for the Haupauge WinTV Nova-TD, copied from nova-t-usb2.c (Nova-T USB2) */
747 { 0x1e, 0x00, KEY_0 },
748 { 0x1e, 0x01, KEY_1 },
749 { 0x1e, 0x02, KEY_2 },
750 { 0x1e, 0x03, KEY_3 },
751 { 0x1e, 0x04, KEY_4 },
752 { 0x1e, 0x05, KEY_5 },
753 { 0x1e, 0x06, KEY_6 },
754 { 0x1e, 0x07, KEY_7 },
755 { 0x1e, 0x08, KEY_8 },
756 { 0x1e, 0x09, KEY_9 },
757 { 0x1e, 0x0a, KEY_KPASTERISK },
758 { 0x1e, 0x0b, KEY_RED },
759 { 0x1e, 0x0c, KEY_RADIO },
760 { 0x1e, 0x0d, KEY_MENU },
761 { 0x1e, 0x0e, KEY_GRAVE }, /* # */
762 { 0x1e, 0x0f, KEY_MUTE },
763 { 0x1e, 0x10, KEY_VOLUMEUP },
764 { 0x1e, 0x11, KEY_VOLUMEDOWN },
765 { 0x1e, 0x12, KEY_CHANNEL },
766 { 0x1e, 0x14, KEY_UP },
767 { 0x1e, 0x15, KEY_DOWN },
768 { 0x1e, 0x16, KEY_LEFT },
769 { 0x1e, 0x17, KEY_RIGHT },
770 { 0x1e, 0x18, KEY_VIDEO },
771 { 0x1e, 0x19, KEY_AUDIO },
772 { 0x1e, 0x1a, KEY_MEDIA },
773 { 0x1e, 0x1b, KEY_EPG },
774 { 0x1e, 0x1c, KEY_TV },
775 { 0x1e, 0x1e, KEY_NEXT },
776 { 0x1e, 0x1f, KEY_BACK },
777 { 0x1e, 0x20, KEY_CHANNELUP },
778 { 0x1e, 0x21, KEY_CHANNELDOWN },
779 { 0x1e, 0x24, KEY_LAST }, /* Skip backwards */
780 { 0x1e, 0x25, KEY_OK },
781 { 0x1e, 0x29, KEY_BLUE},
782 { 0x1e, 0x2e, KEY_GREEN },
783 { 0x1e, 0x30, KEY_PAUSE },
784 { 0x1e, 0x32, KEY_REWIND },
785 { 0x1e, 0x34, KEY_FASTFORWARD },
786 { 0x1e, 0x35, KEY_PLAY },
787 { 0x1e, 0x36, KEY_STOP },
788 { 0x1e, 0x37, KEY_RECORD },
789 { 0x1e, 0x38, KEY_YELLOW },
790 { 0x1e, 0x3b, KEY_GOTO },
791 { 0x1e, 0x3d, KEY_POWER },
793 /* Key codes for the Leadtek Winfast DTV Dongle */
794 { 0x00, 0x42, KEY_POWER },
795 { 0x07, 0x7c, KEY_TUNER },
796 { 0x0f, 0x4e, KEY_PRINT }, /* PREVIEW */
797 { 0x08, 0x40, KEY_SCREEN }, /* full screen toggle*/
798 { 0x0f, 0x71, KEY_DOT }, /* frequency */
799 { 0x07, 0x43, KEY_0 },
800 { 0x0c, 0x41, KEY_1 },
801 { 0x04, 0x43, KEY_2 },
802 { 0x0b, 0x7f, KEY_3 },
803 { 0x0e, 0x41, KEY_4 },
804 { 0x06, 0x43, KEY_5 },
805 { 0x09, 0x7f, KEY_6 },
806 { 0x0d, 0x7e, KEY_7 },
807 { 0x05, 0x7c, KEY_8 },
808 { 0x0a, 0x40, KEY_9 },
809 { 0x0e, 0x4e, KEY_CLEAR },
810 { 0x04, 0x7c, KEY_CHANNEL }, /* show channel number */
811 { 0x0f, 0x41, KEY_LAST }, /* recall */
812 { 0x03, 0x42, KEY_MUTE },
813 { 0x06, 0x4c, KEY_RESERVED }, /* PIP button*/
814 { 0x01, 0x72, KEY_SHUFFLE }, /* SNAPSHOT */
815 { 0x0c, 0x4e, KEY_PLAYPAUSE }, /* TIMESHIFT */
816 { 0x0b, 0x70, KEY_RECORD },
817 { 0x03, 0x7d, KEY_VOLUMEUP },
818 { 0x01, 0x7d, KEY_VOLUMEDOWN },
819 { 0x02, 0x42, KEY_CHANNELUP },
820 { 0x00, 0x7d, KEY_CHANNELDOWN },
822 /* Key codes for Nova-TD "credit card" remote control. */
823 { 0x1d, 0x00, KEY_0 },
824 { 0x1d, 0x01, KEY_1 },
825 { 0x1d, 0x02, KEY_2 },
826 { 0x1d, 0x03, KEY_3 },
827 { 0x1d, 0x04, KEY_4 },
828 { 0x1d, 0x05, KEY_5 },
829 { 0x1d, 0x06, KEY_6 },
830 { 0x1d, 0x07, KEY_7 },
831 { 0x1d, 0x08, KEY_8 },
832 { 0x1d, 0x09, KEY_9 },
833 { 0x1d, 0x0a, KEY_TEXT },
834 { 0x1d, 0x0d, KEY_MENU },
835 { 0x1d, 0x0f, KEY_MUTE },
836 { 0x1d, 0x10, KEY_VOLUMEUP },
837 { 0x1d, 0x11, KEY_VOLUMEDOWN },
838 { 0x1d, 0x12, KEY_CHANNEL },
839 { 0x1d, 0x14, KEY_UP },
840 { 0x1d, 0x15, KEY_DOWN },
841 { 0x1d, 0x16, KEY_LEFT },
842 { 0x1d, 0x17, KEY_RIGHT },
843 { 0x1d, 0x1c, KEY_TV },
844 { 0x1d, 0x1e, KEY_NEXT },
845 { 0x1d, 0x1f, KEY_BACK },
846 { 0x1d, 0x20, KEY_CHANNELUP },
847 { 0x1d, 0x21, KEY_CHANNELDOWN },
848 { 0x1d, 0x24, KEY_LAST },
849 { 0x1d, 0x25, KEY_OK },
850 { 0x1d, 0x30, KEY_PAUSE },
851 { 0x1d, 0x32, KEY_REWIND },
852 { 0x1d, 0x34, KEY_FASTFORWARD },
853 { 0x1d, 0x35, KEY_PLAY },
854 { 0x1d, 0x36, KEY_STOP },
855 { 0x1d, 0x37, KEY_RECORD },
856 { 0x1d, 0x3b, KEY_GOTO },
857 { 0x1d, 0x3d, KEY_POWER },
860 /* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
861 static struct dibx000_agc_config stk7700p_7000m_mt2060_agc_config = {
862 BAND_UHF | BAND_VHF, // band_caps
864 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
865 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
866 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
898 1, // perform_agc_softsplit
901 51800, // global_split_min
902 24700 // global_split_max
906 static struct dibx000_agc_config stk7700p_7000p_mt2060_agc_config = {
909 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
910 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
911 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
948 0, // perform_agc_softsplit
951 static struct dibx000_bandwidth_config stk7700p_pll_config = {
952 60000, 30000, // internal, sampling
953 1, 8, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
954 0, 0, 1, 1, 0, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
955 (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
961 static struct dib7000m_config stk7700p_dib7000m_config = {
963 .output_mpeg2_in_188_bytes = 1,
966 .agc_config_count = 1,
967 .agc = &stk7700p_7000m_mt2060_agc_config,
968 .bw = &stk7700p_pll_config,
970 .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
971 .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
972 .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
975 static struct dib7000p_config stk7700p_dib7000p_config = {
976 .output_mpeg2_in_188_bytes = 1,
978 .agc_config_count = 1,
979 .agc = &stk7700p_7000p_mt2060_agc_config,
980 .bw = &stk7700p_pll_config,
982 .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
983 .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
984 .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
987 static int stk7700p_frontend_attach(struct dvb_usb_adapter *adap)
989 struct dib0700_state *st = adap->dev->priv;
990 /* unless there is no real power management in DVB - we leave the device on GPIO6 */
992 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
993 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(50);
995 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10);
996 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
998 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10);
999 dib0700_ctrl_clock(adap->dev, 72, 1);
1000 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(100);
1002 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1004 st->mt2060_if1[0] = 1220;
1006 if (dib7000pc_detection(&adap->dev->i2c_adap)) {
1007 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000p_config);
1008 st->is_dib7000pc = 1;
1010 adap->fe = dvb_attach(dib7000m_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000m_config);
1012 return adap->fe == NULL ? -ENODEV : 0;
1015 static struct mt2060_config stk7700p_mt2060_config = {
1019 static int stk7700p_tuner_attach(struct dvb_usb_adapter *adap)
1021 struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap;
1022 struct dib0700_state *st = adap->dev->priv;
1023 struct i2c_adapter *tun_i2c;
1026 if (adap->dev->udev->descriptor.idVendor == cpu_to_le16(USB_VID_HAUPPAUGE) &&
1027 adap->dev->udev->descriptor.idProduct == cpu_to_le16(USB_PID_HAUPPAUGE_NOVA_T_STICK)) {
1028 if (!eeprom_read(prim_i2c,0x58,&a)) if1=1220+a;
1030 if (st->is_dib7000pc)
1031 tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
1033 tun_i2c = dib7000m_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
1035 return dvb_attach(mt2060_attach, adap->fe, tun_i2c, &stk7700p_mt2060_config,
1036 if1) == NULL ? -ENODEV : 0;
1039 /* DIB7070 generic */
1040 static struct dibx000_agc_config dib7070_agc_config = {
1041 BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
1042 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
1043 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
1044 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup
1047 10, // time_stabiliz
1078 0, // perform_agc_softsplit
1081 static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
1083 return dib7000p_set_gpio(fe, 8, 0, !onoff);
1086 static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
1088 return dib7000p_set_gpio(fe, 9, 0, onoff);
1091 static struct dib0070_config dib7070p_dib0070_config[2] = {
1093 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1094 .reset = dib7070_tuner_reset,
1095 .sleep = dib7070_tuner_sleep,
1097 .clock_pad_drive = 4
1099 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1100 .reset = dib7070_tuner_reset,
1101 .sleep = dib7070_tuner_sleep,
1107 static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1109 struct dvb_usb_adapter *adap = fe->dvb->priv;
1110 struct dib0700_adapter_state *state = adap->priv;
1113 u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
1115 case BAND_VHF: offset = 950; break;
1117 default: offset = 550; break;
1119 deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe));
1120 dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
1121 return state->set_param_save(fe, fep);
1124 static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap)
1126 struct dib0700_adapter_state *st = adap->priv;
1127 struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
1129 if (adap->id == 0) {
1130 if (dvb_attach(dib0070_attach, adap->fe, tun_i2c, &dib7070p_dib0070_config[0]) == NULL)
1133 if (dvb_attach(dib0070_attach, adap->fe, tun_i2c, &dib7070p_dib0070_config[1]) == NULL)
1137 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
1138 adap->fe->ops.tuner_ops.set_params = dib7070_set_param_override;
1142 static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
1143 60000, 15000, // internal, sampling
1144 1, 20, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
1145 0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
1146 (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
1147 (0 << 25) | 0, // ifreq = 0.000000 MHz
1149 12000000, // xtal_hz
1152 static struct dib7000p_config dib7070p_dib7000p_config = {
1153 .output_mpeg2_in_188_bytes = 1,
1155 .agc_config_count = 1,
1156 .agc = &dib7070_agc_config,
1157 .bw = &dib7070_bw_config_12_mhz,
1158 .tuner_is_baseband = 1,
1161 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
1162 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
1163 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
1165 .hostbus_diversity = 1,
1169 static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
1171 struct usb_device_descriptor *p = &adap->dev->udev->descriptor;
1172 if (p->idVendor == cpu_to_le16(USB_VID_PINNACLE) &&
1173 p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E))
1174 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
1176 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1178 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1179 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1180 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1181 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1183 dib0700_ctrl_clock(adap->dev, 72, 1);
1186 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1188 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1190 dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
1191 &dib7070p_dib7000p_config);
1193 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
1194 &dib7070p_dib7000p_config);
1195 return adap->fe == NULL ? -ENODEV : 0;
1199 static struct dib7000p_config stk7070pd_dib7000p_config[2] = {
1201 .output_mpeg2_in_188_bytes = 1,
1203 .agc_config_count = 1,
1204 .agc = &dib7070_agc_config,
1205 .bw = &dib7070_bw_config_12_mhz,
1206 .tuner_is_baseband = 1,
1209 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
1210 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
1211 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
1213 .hostbus_diversity = 1,
1215 .output_mpeg2_in_188_bytes = 1,
1217 .agc_config_count = 1,
1218 .agc = &dib7070_agc_config,
1219 .bw = &dib7070_bw_config_12_mhz,
1220 .tuner_is_baseband = 1,
1223 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
1224 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
1225 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
1227 .hostbus_diversity = 1,
1231 static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap)
1233 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1235 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1236 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1237 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1238 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1240 dib0700_ctrl_clock(adap->dev, 72, 1);
1243 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1245 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1247 dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, stk7070pd_dib7000p_config);
1249 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &stk7070pd_dib7000p_config[0]);
1250 return adap->fe == NULL ? -ENODEV : 0;
1253 static int stk7070pd_frontend_attach1(struct dvb_usb_adapter *adap)
1255 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x82, &stk7070pd_dib7000p_config[1]);
1256 return adap->fe == NULL ? -ENODEV : 0;
1260 static struct s5h1411_config pinnacle_801e_config = {
1261 .output_mode = S5H1411_PARALLEL_OUTPUT,
1262 .gpio = S5H1411_GPIO_OFF,
1263 .mpeg_timing = S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK,
1264 .qam_if = S5H1411_IF_44000,
1265 .vsb_if = S5H1411_IF_44000,
1266 .inversion = S5H1411_INVERSION_OFF,
1267 .status_mode = S5H1411_DEMODLOCKING
1270 /* Pinnacle PCTV HD Pro 801e GPIOs map:
1271 GPIO0 - currently unknown
1272 GPIO1 - xc5000 tuner reset
1273 GPIO2 - CX25843 sleep
1274 GPIO3 - currently unknown
1275 GPIO4 - currently unknown
1276 GPIO6 - currently unknown
1277 GPIO7 - currently unknown
1278 GPIO9 - currently unknown
1279 GPIO10 - CX25843 reset
1281 static int s5h1411_frontend_attach(struct dvb_usb_adapter *adap)
1283 struct dib0700_state *st = adap->dev->priv;
1285 /* Make use of the new i2c functions from FW 1.20 */
1286 st->fw_use_new_i2c_api = 1;
1288 /* The s5h1411 requires the dib0700 to not be in master mode */
1289 st->disable_streaming_master_mode = 1;
1291 /* All msleep values taken from Windows USB trace */
1292 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0);
1293 dib0700_set_gpio(adap->dev, GPIO3, GPIO_OUT, 0);
1294 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1296 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1298 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1300 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1301 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1302 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1303 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1304 dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 0);
1307 /* Put the CX25843 to sleep for now since we're in digital mode */
1308 dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 1);
1310 /* GPIOs are initialized, do the attach */
1311 adap->fe = dvb_attach(s5h1411_attach, &pinnacle_801e_config,
1312 &adap->dev->i2c_adap);
1313 return adap->fe == NULL ? -ENODEV : 0;
1316 static int dib0700_xc5000_tuner_callback(void *priv, int component,
1317 int command, int arg)
1319 struct dvb_usb_adapter *adap = priv;
1321 if (command == XC5000_TUNER_RESET) {
1322 /* Reset the tuner */
1323 dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 0);
1324 msleep(330); /* from Windows USB trace */
1325 dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 1);
1326 msleep(330); /* from Windows USB trace */
1328 err("xc5000: unknown tuner callback command: %d\n", command);
1335 static struct xc5000_config s5h1411_xc5000_tunerconfig = {
1336 .i2c_address = 0x64,
1340 static int xc5000_tuner_attach(struct dvb_usb_adapter *adap)
1342 /* FIXME: generalize & move to common area */
1343 adap->fe->callback = dib0700_xc5000_tuner_callback;
1345 return dvb_attach(xc5000_attach, adap->fe, &adap->dev->i2c_adap,
1346 &s5h1411_xc5000_tunerconfig)
1347 == NULL ? -ENODEV : 0;
1350 /* DVB-USB and USB stuff follows */
1351 struct usb_device_id dib0700_usb_id_table[] = {
1352 /* 0 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P) },
1353 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P_PC) },
1354 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500) },
1355 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_2) },
1356 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK) },
1357 /* 5 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR) },
1358 { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_VIDEOMATE_U500) },
1359 { USB_DEVICE(USB_VID_UNIWILL, USB_PID_UNIWILL_STK7700P) },
1360 { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P) },
1361 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_2) },
1362 /* 10 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_2) },
1363 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV2000E) },
1364 { USB_DEVICE(USB_VID_TERRATEC,
1365 USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY) },
1366 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK) },
1367 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700D) },
1368 /* 15 */{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7070P) },
1369 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV_DVB_T_FLASH) },
1370 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7070PD) },
1371 { USB_DEVICE(USB_VID_PINNACLE,
1372 USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T) },
1373 { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_VIDEOMATE_U500_PC) },
1374 /* 20 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_EXPRESS) },
1375 { USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U7000) },
1376 { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14BR) },
1377 { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000) },
1378 { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3100) },
1379 /* 25 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_3) },
1380 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_MYTV_T) },
1381 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_USB_XE) },
1382 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_EXPRESSCARD_320CX) },
1383 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV72E) },
1384 /* 30 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73E) },
1385 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_EC372S) },
1386 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_EXPRESS) },
1387 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS) },
1388 { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) },
1389 /* 35 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) },
1390 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_3) },
1391 { USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U8000) },
1392 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700PH) },
1393 { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000H) },
1394 /* 40 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E) },
1395 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E_SE) },
1396 { 0 } /* Terminating entry */
1398 MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
1400 #define DIB0700_DEFAULT_DEVICE_PROPERTIES \
1401 .caps = DVB_USB_IS_AN_I2C_ADAPTER, \
1402 .usb_ctrl = DEVICE_SPECIFIC, \
1403 .firmware = "dvb-usb-dib0700-1.20.fw", \
1404 .download_firmware = dib0700_download_firmware, \
1405 .no_reconnect = 1, \
1406 .size_of_priv = sizeof(struct dib0700_state), \
1407 .i2c_algo = &dib0700_i2c_algo, \
1408 .identify_state = dib0700_identify_state
1410 #define DIB0700_DEFAULT_STREAMING_CONFIG(ep) \
1411 .streaming_ctrl = dib0700_streaming_ctrl, \
1418 .buffersize = 39480, \
1423 struct dvb_usb_device_properties dib0700_devices[] = {
1425 DIB0700_DEFAULT_DEVICE_PROPERTIES,
1430 .frontend_attach = stk7700p_frontend_attach,
1431 .tuner_attach = stk7700p_tuner_attach,
1433 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1437 .num_device_descs = 8,
1439 { "DiBcom STK7700P reference design",
1440 { &dib0700_usb_id_table[0], &dib0700_usb_id_table[1] },
1443 { "Hauppauge Nova-T Stick",
1444 { &dib0700_usb_id_table[4], &dib0700_usb_id_table[9], NULL },
1447 { "AVerMedia AVerTV DVB-T Volar",
1448 { &dib0700_usb_id_table[5], &dib0700_usb_id_table[10] },
1451 { "Compro Videomate U500",
1452 { &dib0700_usb_id_table[6], &dib0700_usb_id_table[19] },
1455 { "Uniwill STK7700P based (Hama and others)",
1456 { &dib0700_usb_id_table[7], NULL },
1459 { "Leadtek Winfast DTV Dongle (STK7700P based)",
1460 { &dib0700_usb_id_table[8], &dib0700_usb_id_table[34] },
1463 { "AVerMedia AVerTV DVB-T Express",
1464 { &dib0700_usb_id_table[20] },
1468 { &dib0700_usb_id_table[21], NULL },
1473 .rc_interval = DEFAULT_RC_INTERVAL,
1474 .rc_key_map = dib0700_rc_keys,
1475 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
1476 .rc_query = dib0700_rc_query
1477 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1482 .frontend_attach = bristol_frontend_attach,
1483 .tuner_attach = bristol_tuner_attach,
1485 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1487 .frontend_attach = bristol_frontend_attach,
1488 .tuner_attach = bristol_tuner_attach,
1490 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
1494 .num_device_descs = 1,
1496 { "Hauppauge Nova-T 500 Dual DVB-T",
1497 { &dib0700_usb_id_table[2], &dib0700_usb_id_table[3], NULL },
1502 .rc_interval = DEFAULT_RC_INTERVAL,
1503 .rc_key_map = dib0700_rc_keys,
1504 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
1505 .rc_query = dib0700_rc_query
1506 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1511 .frontend_attach = stk7700d_frontend_attach,
1512 .tuner_attach = stk7700d_tuner_attach,
1514 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1516 .frontend_attach = stk7700d_frontend_attach,
1517 .tuner_attach = stk7700d_tuner_attach,
1519 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
1523 .num_device_descs = 4,
1525 { "Pinnacle PCTV 2000e",
1526 { &dib0700_usb_id_table[11], NULL },
1529 { "Terratec Cinergy DT XS Diversity",
1530 { &dib0700_usb_id_table[12], NULL },
1533 { "Hauppauge Nova-TD Stick/Elgato Eye-TV Diversity",
1534 { &dib0700_usb_id_table[13], NULL },
1537 { "DiBcom STK7700D reference design",
1538 { &dib0700_usb_id_table[14], NULL },
1543 .rc_interval = DEFAULT_RC_INTERVAL,
1544 .rc_key_map = dib0700_rc_keys,
1545 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
1546 .rc_query = dib0700_rc_query
1548 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1553 .frontend_attach = stk7700P2_frontend_attach,
1554 .tuner_attach = stk7700d_tuner_attach,
1556 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1560 .num_device_descs = 2,
1562 { "ASUS My Cinema U3000 Mini DVBT Tuner",
1563 { &dib0700_usb_id_table[23], NULL },
1567 { &dib0700_usb_id_table[31], NULL },
1572 .rc_interval = DEFAULT_RC_INTERVAL,
1573 .rc_key_map = dib0700_rc_keys,
1574 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
1575 .rc_query = dib0700_rc_query
1576 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1581 .frontend_attach = stk7070p_frontend_attach,
1582 .tuner_attach = dib7070p_tuner_attach,
1584 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1586 .size_of_priv = sizeof(struct dib0700_adapter_state),
1590 .num_device_descs = 9,
1592 { "DiBcom STK7070P reference design",
1593 { &dib0700_usb_id_table[15], NULL },
1596 { "Pinnacle PCTV DVB-T Flash Stick",
1597 { &dib0700_usb_id_table[16], NULL },
1600 { "Artec T14BR DVB-T",
1601 { &dib0700_usb_id_table[22], NULL },
1604 { "ASUS My Cinema U3100 Mini DVBT Tuner",
1605 { &dib0700_usb_id_table[24], NULL },
1608 { "Hauppauge Nova-T Stick",
1609 { &dib0700_usb_id_table[25], NULL },
1612 { "Hauppauge Nova-T MyTV.t",
1613 { &dib0700_usb_id_table[26], NULL },
1616 { "Pinnacle PCTV 72e",
1617 { &dib0700_usb_id_table[29], NULL },
1620 { "Pinnacle PCTV 73e",
1621 { &dib0700_usb_id_table[30], NULL },
1624 { "Terratec Cinergy T USB XXS",
1625 { &dib0700_usb_id_table[33], NULL },
1630 .rc_interval = DEFAULT_RC_INTERVAL,
1631 .rc_key_map = dib0700_rc_keys,
1632 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
1633 .rc_query = dib0700_rc_query
1635 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1640 .frontend_attach = stk7070pd_frontend_attach0,
1641 .tuner_attach = dib7070p_tuner_attach,
1643 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1645 .size_of_priv = sizeof(struct dib0700_adapter_state),
1647 .frontend_attach = stk7070pd_frontend_attach1,
1648 .tuner_attach = dib7070p_tuner_attach,
1650 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
1652 .size_of_priv = sizeof(struct dib0700_adapter_state),
1656 .num_device_descs = 4,
1658 { "DiBcom STK7070PD reference design",
1659 { &dib0700_usb_id_table[17], NULL },
1662 { "Pinnacle PCTV Dual DVB-T Diversity Stick",
1663 { &dib0700_usb_id_table[18], NULL },
1666 { "Hauppauge Nova-TD Stick (52009)",
1667 { &dib0700_usb_id_table[35], NULL },
1670 { "Hauppauge Nova-TD-500 (84xxx)",
1671 { &dib0700_usb_id_table[36], NULL },
1675 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1680 .frontend_attach = stk7700ph_frontend_attach,
1681 .tuner_attach = stk7700ph_tuner_attach,
1683 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1685 .size_of_priv = sizeof(struct
1686 dib0700_adapter_state),
1690 .num_device_descs = 5,
1692 { "Terratec Cinergy HT USB XE",
1693 { &dib0700_usb_id_table[27], NULL },
1696 { "Pinnacle Expresscard 320cx",
1697 { &dib0700_usb_id_table[28], NULL },
1700 { "Terratec Cinergy HT Express",
1701 { &dib0700_usb_id_table[32], NULL },
1704 { "Gigabyte U8000-RH",
1705 { &dib0700_usb_id_table[37], NULL },
1708 { "YUAN High-Tech STK7700PH",
1709 { &dib0700_usb_id_table[38], NULL },
1712 { "Asus My Cinema-U3000Hybrid",
1713 { &dib0700_usb_id_table[39], NULL },
1717 .rc_interval = DEFAULT_RC_INTERVAL,
1718 .rc_key_map = dib0700_rc_keys,
1719 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
1720 .rc_query = dib0700_rc_query
1721 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1725 .frontend_attach = s5h1411_frontend_attach,
1726 .tuner_attach = xc5000_tuner_attach,
1728 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1730 .size_of_priv = sizeof(struct
1731 dib0700_adapter_state),
1735 .num_device_descs = 2,
1737 { "Pinnacle PCTV HD Pro USB Stick",
1738 { &dib0700_usb_id_table[40], NULL },
1741 { "Pinnacle PCTV HD USB Stick",
1742 { &dib0700_usb_id_table[41], NULL },
1746 .rc_interval = DEFAULT_RC_INTERVAL,
1747 .rc_key_map = dib0700_rc_keys,
1748 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
1749 .rc_query = dib0700_rc_query
1753 int dib0700_device_count = ARRAY_SIZE(dib0700_devices);