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 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
266 stk7700d_dib7000p_mt2266_config)
268 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
273 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1),
274 &stk7700d_dib7000p_mt2266_config[adap->id]);
276 return adap->fe == NULL ? -ENODEV : 0;
279 static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap)
282 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
284 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
285 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
286 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
287 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
289 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
291 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
292 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
293 stk7700d_dib7000p_mt2266_config)
295 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
300 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1),
301 &stk7700d_dib7000p_mt2266_config[adap->id]);
303 return adap->fe == NULL ? -ENODEV : 0;
306 static int stk7700d_tuner_attach(struct dvb_usb_adapter *adap)
308 struct i2c_adapter *tun_i2c;
309 tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
310 return dvb_attach(mt2266_attach, adap->fe, tun_i2c,
311 &stk7700d_mt2266_config[adap->id]) == NULL ? -ENODEV : 0;;
314 /* STK7700-PH: Digital/Analog Hybrid Tuner, e.h. Cinergy HT USB HE */
315 static struct dibx000_agc_config xc3028_agc_config = {
316 BAND_VHF | BAND_UHF, /* band_caps */
318 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=0,
319 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
320 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
321 (0 << 15) | (0 << 14) | (0 << 11) | (0 << 10) | (0 << 9) | (0 << 8) |
322 (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), /* setup */
325 21, /* time_stabiliz */
337 39718, /* agc2_max */
346 29, /* agc2_slope1 */
347 29, /* agc2_slope2 */
354 1, /* perform_agc_softsplit */
357 /* PLL Configuration for COFDM BW_MHz = 8.00 with external clock = 30.00 */
358 static struct dibx000_bandwidth_config xc3028_bw_config = {
359 60000, 30000, /* internal, sampling */
360 1, 8, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass */
361 0, 0, 1, 1, 0, /* misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc,
363 (3 << 14) | (1 << 12) | (524 << 0), /* sad_cfg: refsel, sel, freq_15k */
364 (1 << 25) | 5816102, /* ifreq = 5.200000 MHz */
366 30000000, /* xtal_hz */
369 static struct dib7000p_config stk7700ph_dib7700_xc3028_config = {
370 .output_mpeg2_in_188_bytes = 1,
371 .tuner_is_baseband = 1,
373 .agc_config_count = 1,
374 .agc = &xc3028_agc_config,
375 .bw = &xc3028_bw_config,
377 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
378 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
379 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
382 static int stk7700ph_xc3028_callback(void *ptr, int component,
383 int command, int arg)
385 struct dvb_usb_adapter *adap = ptr;
388 case XC2028_TUNER_RESET:
389 /* Send the tuner in then out of reset */
390 dib7000p_set_gpio(adap->fe, 8, 0, 0); msleep(10);
391 dib7000p_set_gpio(adap->fe, 8, 0, 1);
393 case XC2028_RESET_CLK:
396 err("%s: unknown command %d, arg %d\n", __func__,
403 static struct xc2028_ctrl stk7700ph_xc3028_ctrl = {
404 .fname = XC2028_DEFAULT_FIRMWARE,
406 .demod = XC3028_FE_DIBCOM52,
409 static struct xc2028_config stk7700ph_xc3028_config = {
411 .ctrl = &stk7700ph_xc3028_ctrl,
414 static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap)
416 struct usb_device_descriptor *desc = &adap->dev->udev->descriptor;
418 if (desc->idVendor == cpu_to_le16(USB_VID_PINNACLE) &&
419 desc->idProduct == cpu_to_le16(USB_PID_PINNACLE_EXPRESSCARD_320CX))
420 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
422 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
424 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
425 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
426 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
427 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
429 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
431 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
434 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
435 &stk7700ph_dib7700_xc3028_config) != 0) {
436 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
441 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
442 &stk7700ph_dib7700_xc3028_config);
444 return adap->fe == NULL ? -ENODEV : 0;
447 static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap)
449 struct i2c_adapter *tun_i2c;
451 tun_i2c = dib7000p_get_i2c_master(adap->fe,
452 DIBX000_I2C_INTERFACE_TUNER, 1);
454 stk7700ph_xc3028_config.i2c_adap = tun_i2c;
456 /* FIXME: generalize & move to common area */
457 adap->fe->callback = stk7700ph_xc3028_callback;
459 return dvb_attach(xc2028_attach, adap->fe, &stk7700ph_xc3028_config)
460 == NULL ? -ENODEV : 0;
463 #define DEFAULT_RC_INTERVAL 50
465 static u8 rc_request[] = { REQUEST_POLL_RC, 0 };
467 /* Number of keypresses to ignore before start repeating */
468 #define RC_REPEAT_DELAY 6
469 #define RC_REPEAT_DELAY_V1_20 10
473 /* Used by firmware versions < 1.20 (deprecated) */
474 static int dib0700_rc_query_legacy(struct dvb_usb_device *d, u32 *event,
479 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
480 struct dib0700_state *st = d->priv;
482 *state = REMOTE_NO_KEY_PRESSED;
483 i=dib0700_ctrl_rd(d,rc_request,2,key,4);
485 err("RC Query Failed");
489 /* losing half of KEY_0 events from Philipps rc5 remotes.. */
490 if (key[0]==0 && key[1]==0 && key[2]==0 && key[3]==0) return 0;
492 /* 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]); */
494 dib0700_rc_setup(d); /* reset ir sensor data to prevent false events */
496 switch (dvb_usb_dib0700_ir_proto) {
498 /* NEC protocol sends repeat code as 0 0 0 FF */
499 if ((key[3-2] == 0x00) && (key[3-3] == 0x00) &&
502 if (st->rc_counter > RC_REPEAT_DELAY) {
503 *event = d->last_event;
504 *state = REMOTE_KEY_PRESSED;
505 st->rc_counter = RC_REPEAT_DELAY;
509 for (i=0;i<d->props.rc_key_map_size; i++) {
510 if (keymap[i].custom == key[3-2] && keymap[i].data == key[3-3]) {
512 *event = keymap[i].event;
513 *state = REMOTE_KEY_PRESSED;
514 d->last_event = keymap[i].event;
521 /* RC-5 protocol changes toggle bit on new keypress */
522 for (i = 0; i < d->props.rc_key_map_size; i++) {
523 if (keymap[i].custom == key[3-2] && keymap[i].data == key[3-3]) {
524 if (d->last_event == keymap[i].event &&
525 key[3-1] == st->rc_toggle) {
527 /* prevents unwanted double hits */
528 if (st->rc_counter > RC_REPEAT_DELAY) {
529 *event = d->last_event;
530 *state = REMOTE_KEY_PRESSED;
531 st->rc_counter = RC_REPEAT_DELAY;
537 *event = keymap[i].event;
538 *state = REMOTE_KEY_PRESSED;
539 st->rc_toggle = key[3-1];
540 d->last_event = keymap[i].event;
547 err("Unknown remote controller key: %2X %2X %2X %2X", (int) key[3-2], (int) key[3-3], (int) key[3-1], (int) key[3]);
552 /* This is the structure of the RC response packet starting in firmware 1.20 */
553 struct dib0700_rc_response {
562 /* This supports the new IR response format for firmware v1.20 */
563 static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event,
566 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
567 struct dib0700_state *st = d->priv;
568 struct dib0700_rc_response poll_reply;
575 /* Set initial results in case we exit the function early */
577 *state = REMOTE_NO_KEY_PRESSED;
579 /* Firmware v1.20 provides RC data via bulk endpoint 1 */
580 status = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, 1), buf,
581 sizeof(buf), &actlen, 50);
583 /* No data available (meaning no key press) */
587 if (actlen != sizeof(buf)) {
588 /* We didn't get back the 6 byte message we expected */
589 err("Unexpected RC response size [%d]", actlen);
593 poll_reply.report_id = buf[0];
594 poll_reply.data_state = buf[1];
595 poll_reply.system_msb = buf[2];
596 poll_reply.system_lsb = buf[3];
597 poll_reply.data = buf[4];
598 poll_reply.not_data = buf[5];
601 info("rid=%02x ds=%02x sm=%02x sl=%02x d=%02x nd=%02x\n",
602 poll_reply.report_id, poll_reply.data_state,
603 poll_reply.system_msb, poll_reply.system_lsb,
604 poll_reply.data, poll_reply.not_data);
607 if ((poll_reply.data + poll_reply.not_data) != 0xff) {
608 /* Key failed integrity check */
609 err("key failed integrity check: %02x %02x %02x %02x",
610 poll_reply.system_msb, poll_reply.system_lsb,
611 poll_reply.data, poll_reply.not_data);
615 /* Find the key in the map */
616 for (i = 0; i < d->props.rc_key_map_size; i++) {
617 if (keymap[i].custom == poll_reply.system_lsb &&
618 keymap[i].data == poll_reply.data) {
619 *event = keymap[i].event;
626 err("Unknown remote controller key: %02x %02x %02x %02x",
627 poll_reply.system_msb, poll_reply.system_lsb,
628 poll_reply.data, poll_reply.not_data);
633 if (poll_reply.data_state == 1) {
636 *event = keymap[i].event;
637 *state = REMOTE_KEY_PRESSED;
638 d->last_event = keymap[i].event;
639 } else if (poll_reply.data_state == 2) {
643 /* prevents unwanted double hits */
644 if (st->rc_counter > RC_REPEAT_DELAY_V1_20) {
645 *event = d->last_event;
646 *state = REMOTE_KEY_PRESSED;
647 st->rc_counter = RC_REPEAT_DELAY_V1_20;
650 err("Unknown data state [%d]", poll_reply.data_state);
656 static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
658 struct dib0700_state *st = d->priv;
660 /* Because some people may have improperly named firmware files,
661 let's figure out whether to use the new firmware call or the legacy
662 call based on the firmware version embedded in the file */
663 if (st->rc_func_version == 0) {
664 u32 hwver, romver, ramver, fwtype;
665 int ret = dib0700_get_version(d, &hwver, &romver, &ramver,
668 err("Could not determine version info");
671 if (ramver < 0x10200)
672 st->rc_func_version = 1;
674 st->rc_func_version = 2;
677 if (st->rc_func_version == 2)
678 return dib0700_rc_query_v1_20(d, event, state);
680 return dib0700_rc_query_legacy(d, event, state);
683 static struct dvb_usb_rc_key dib0700_rc_keys[] = {
684 /* Key codes for the tiny Pinnacle remote*/
685 { 0x07, 0x00, KEY_MUTE },
686 { 0x07, 0x01, KEY_MENU }, // Pinnacle logo
687 { 0x07, 0x39, KEY_POWER },
688 { 0x07, 0x03, KEY_VOLUMEUP },
689 { 0x07, 0x09, KEY_VOLUMEDOWN },
690 { 0x07, 0x06, KEY_CHANNELUP },
691 { 0x07, 0x0c, KEY_CHANNELDOWN },
692 { 0x07, 0x0f, KEY_1 },
693 { 0x07, 0x15, KEY_2 },
694 { 0x07, 0x10, KEY_3 },
695 { 0x07, 0x18, KEY_4 },
696 { 0x07, 0x1b, KEY_5 },
697 { 0x07, 0x1e, KEY_6 },
698 { 0x07, 0x11, KEY_7 },
699 { 0x07, 0x21, KEY_8 },
700 { 0x07, 0x12, KEY_9 },
701 { 0x07, 0x27, KEY_0 },
702 { 0x07, 0x24, KEY_SCREEN }, // 'Square' key
703 { 0x07, 0x2a, KEY_TEXT }, // 'T' key
704 { 0x07, 0x2d, KEY_REWIND },
705 { 0x07, 0x30, KEY_PLAY },
706 { 0x07, 0x33, KEY_FASTFORWARD },
707 { 0x07, 0x36, KEY_RECORD },
708 { 0x07, 0x3c, KEY_STOP },
709 { 0x07, 0x3f, KEY_CANCEL }, // '?' key
710 /* Key codes for the Terratec Cinergy DT XS Diversity, similar to cinergyT2.c */
711 { 0xeb, 0x01, KEY_POWER },
712 { 0xeb, 0x02, KEY_1 },
713 { 0xeb, 0x03, KEY_2 },
714 { 0xeb, 0x04, KEY_3 },
715 { 0xeb, 0x05, KEY_4 },
716 { 0xeb, 0x06, KEY_5 },
717 { 0xeb, 0x07, KEY_6 },
718 { 0xeb, 0x08, KEY_7 },
719 { 0xeb, 0x09, KEY_8 },
720 { 0xeb, 0x0a, KEY_9 },
721 { 0xeb, 0x0b, KEY_VIDEO },
722 { 0xeb, 0x0c, KEY_0 },
723 { 0xeb, 0x0d, KEY_REFRESH },
724 { 0xeb, 0x0f, KEY_EPG },
725 { 0xeb, 0x10, KEY_UP },
726 { 0xeb, 0x11, KEY_LEFT },
727 { 0xeb, 0x12, KEY_OK },
728 { 0xeb, 0x13, KEY_RIGHT },
729 { 0xeb, 0x14, KEY_DOWN },
730 { 0xeb, 0x16, KEY_INFO },
731 { 0xeb, 0x17, KEY_RED },
732 { 0xeb, 0x18, KEY_GREEN },
733 { 0xeb, 0x19, KEY_YELLOW },
734 { 0xeb, 0x1a, KEY_BLUE },
735 { 0xeb, 0x1b, KEY_CHANNELUP },
736 { 0xeb, 0x1c, KEY_VOLUMEUP },
737 { 0xeb, 0x1d, KEY_MUTE },
738 { 0xeb, 0x1e, KEY_VOLUMEDOWN },
739 { 0xeb, 0x1f, KEY_CHANNELDOWN },
740 { 0xeb, 0x40, KEY_PAUSE },
741 { 0xeb, 0x41, KEY_HOME },
742 { 0xeb, 0x42, KEY_MENU }, /* DVD Menu */
743 { 0xeb, 0x43, KEY_SUBTITLE },
744 { 0xeb, 0x44, KEY_TEXT }, /* Teletext */
745 { 0xeb, 0x45, KEY_DELETE },
746 { 0xeb, 0x46, KEY_TV },
747 { 0xeb, 0x47, KEY_DVD },
748 { 0xeb, 0x48, KEY_STOP },
749 { 0xeb, 0x49, KEY_VIDEO },
750 { 0xeb, 0x4a, KEY_AUDIO }, /* Music */
751 { 0xeb, 0x4b, KEY_SCREEN }, /* Pic */
752 { 0xeb, 0x4c, KEY_PLAY },
753 { 0xeb, 0x4d, KEY_BACK },
754 { 0xeb, 0x4e, KEY_REWIND },
755 { 0xeb, 0x4f, KEY_FASTFORWARD },
756 { 0xeb, 0x54, KEY_PREVIOUS },
757 { 0xeb, 0x58, KEY_RECORD },
758 { 0xeb, 0x5c, KEY_NEXT },
760 /* Key codes for the Haupauge WinTV Nova-TD, copied from nova-t-usb2.c (Nova-T USB2) */
761 { 0x1e, 0x00, KEY_0 },
762 { 0x1e, 0x01, KEY_1 },
763 { 0x1e, 0x02, KEY_2 },
764 { 0x1e, 0x03, KEY_3 },
765 { 0x1e, 0x04, KEY_4 },
766 { 0x1e, 0x05, KEY_5 },
767 { 0x1e, 0x06, KEY_6 },
768 { 0x1e, 0x07, KEY_7 },
769 { 0x1e, 0x08, KEY_8 },
770 { 0x1e, 0x09, KEY_9 },
771 { 0x1e, 0x0a, KEY_KPASTERISK },
772 { 0x1e, 0x0b, KEY_RED },
773 { 0x1e, 0x0c, KEY_RADIO },
774 { 0x1e, 0x0d, KEY_MENU },
775 { 0x1e, 0x0e, KEY_GRAVE }, /* # */
776 { 0x1e, 0x0f, KEY_MUTE },
777 { 0x1e, 0x10, KEY_VOLUMEUP },
778 { 0x1e, 0x11, KEY_VOLUMEDOWN },
779 { 0x1e, 0x12, KEY_CHANNEL },
780 { 0x1e, 0x14, KEY_UP },
781 { 0x1e, 0x15, KEY_DOWN },
782 { 0x1e, 0x16, KEY_LEFT },
783 { 0x1e, 0x17, KEY_RIGHT },
784 { 0x1e, 0x18, KEY_VIDEO },
785 { 0x1e, 0x19, KEY_AUDIO },
786 { 0x1e, 0x1a, KEY_MEDIA },
787 { 0x1e, 0x1b, KEY_EPG },
788 { 0x1e, 0x1c, KEY_TV },
789 { 0x1e, 0x1e, KEY_NEXT },
790 { 0x1e, 0x1f, KEY_BACK },
791 { 0x1e, 0x20, KEY_CHANNELUP },
792 { 0x1e, 0x21, KEY_CHANNELDOWN },
793 { 0x1e, 0x24, KEY_LAST }, /* Skip backwards */
794 { 0x1e, 0x25, KEY_OK },
795 { 0x1e, 0x29, KEY_BLUE},
796 { 0x1e, 0x2e, KEY_GREEN },
797 { 0x1e, 0x30, KEY_PAUSE },
798 { 0x1e, 0x32, KEY_REWIND },
799 { 0x1e, 0x34, KEY_FASTFORWARD },
800 { 0x1e, 0x35, KEY_PLAY },
801 { 0x1e, 0x36, KEY_STOP },
802 { 0x1e, 0x37, KEY_RECORD },
803 { 0x1e, 0x38, KEY_YELLOW },
804 { 0x1e, 0x3b, KEY_GOTO },
805 { 0x1e, 0x3d, KEY_POWER },
807 /* Key codes for the Leadtek Winfast DTV Dongle */
808 { 0x00, 0x42, KEY_POWER },
809 { 0x07, 0x7c, KEY_TUNER },
810 { 0x0f, 0x4e, KEY_PRINT }, /* PREVIEW */
811 { 0x08, 0x40, KEY_SCREEN }, /* full screen toggle*/
812 { 0x0f, 0x71, KEY_DOT }, /* frequency */
813 { 0x07, 0x43, KEY_0 },
814 { 0x0c, 0x41, KEY_1 },
815 { 0x04, 0x43, KEY_2 },
816 { 0x0b, 0x7f, KEY_3 },
817 { 0x0e, 0x41, KEY_4 },
818 { 0x06, 0x43, KEY_5 },
819 { 0x09, 0x7f, KEY_6 },
820 { 0x0d, 0x7e, KEY_7 },
821 { 0x05, 0x7c, KEY_8 },
822 { 0x0a, 0x40, KEY_9 },
823 { 0x0e, 0x4e, KEY_CLEAR },
824 { 0x04, 0x7c, KEY_CHANNEL }, /* show channel number */
825 { 0x0f, 0x41, KEY_LAST }, /* recall */
826 { 0x03, 0x42, KEY_MUTE },
827 { 0x06, 0x4c, KEY_RESERVED }, /* PIP button*/
828 { 0x01, 0x72, KEY_SHUFFLE }, /* SNAPSHOT */
829 { 0x0c, 0x4e, KEY_PLAYPAUSE }, /* TIMESHIFT */
830 { 0x0b, 0x70, KEY_RECORD },
831 { 0x03, 0x7d, KEY_VOLUMEUP },
832 { 0x01, 0x7d, KEY_VOLUMEDOWN },
833 { 0x02, 0x42, KEY_CHANNELUP },
834 { 0x00, 0x7d, KEY_CHANNELDOWN },
836 /* Key codes for Nova-TD "credit card" remote control. */
837 { 0x1d, 0x00, KEY_0 },
838 { 0x1d, 0x01, KEY_1 },
839 { 0x1d, 0x02, KEY_2 },
840 { 0x1d, 0x03, KEY_3 },
841 { 0x1d, 0x04, KEY_4 },
842 { 0x1d, 0x05, KEY_5 },
843 { 0x1d, 0x06, KEY_6 },
844 { 0x1d, 0x07, KEY_7 },
845 { 0x1d, 0x08, KEY_8 },
846 { 0x1d, 0x09, KEY_9 },
847 { 0x1d, 0x0a, KEY_TEXT },
848 { 0x1d, 0x0d, KEY_MENU },
849 { 0x1d, 0x0f, KEY_MUTE },
850 { 0x1d, 0x10, KEY_VOLUMEUP },
851 { 0x1d, 0x11, KEY_VOLUMEDOWN },
852 { 0x1d, 0x12, KEY_CHANNEL },
853 { 0x1d, 0x14, KEY_UP },
854 { 0x1d, 0x15, KEY_DOWN },
855 { 0x1d, 0x16, KEY_LEFT },
856 { 0x1d, 0x17, KEY_RIGHT },
857 { 0x1d, 0x1c, KEY_TV },
858 { 0x1d, 0x1e, KEY_NEXT },
859 { 0x1d, 0x1f, KEY_BACK },
860 { 0x1d, 0x20, KEY_CHANNELUP },
861 { 0x1d, 0x21, KEY_CHANNELDOWN },
862 { 0x1d, 0x24, KEY_LAST },
863 { 0x1d, 0x25, KEY_OK },
864 { 0x1d, 0x30, KEY_PAUSE },
865 { 0x1d, 0x32, KEY_REWIND },
866 { 0x1d, 0x34, KEY_FASTFORWARD },
867 { 0x1d, 0x35, KEY_PLAY },
868 { 0x1d, 0x36, KEY_STOP },
869 { 0x1d, 0x37, KEY_RECORD },
870 { 0x1d, 0x3b, KEY_GOTO },
871 { 0x1d, 0x3d, KEY_POWER },
874 /* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
875 static struct dibx000_agc_config stk7700p_7000m_mt2060_agc_config = {
876 BAND_UHF | BAND_VHF, // band_caps
878 /* 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,
879 * 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 */
880 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
912 1, // perform_agc_softsplit
915 51800, // global_split_min
916 24700 // global_split_max
920 static struct dibx000_agc_config stk7700p_7000p_mt2060_agc_config = {
923 /* 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,
924 * 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 */
925 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
962 0, // perform_agc_softsplit
965 static struct dibx000_bandwidth_config stk7700p_pll_config = {
966 60000, 30000, // internal, sampling
967 1, 8, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
968 0, 0, 1, 1, 0, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
969 (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
975 static struct dib7000m_config stk7700p_dib7000m_config = {
977 .output_mpeg2_in_188_bytes = 1,
980 .agc_config_count = 1,
981 .agc = &stk7700p_7000m_mt2060_agc_config,
982 .bw = &stk7700p_pll_config,
984 .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
985 .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
986 .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
989 static struct dib7000p_config stk7700p_dib7000p_config = {
990 .output_mpeg2_in_188_bytes = 1,
992 .agc_config_count = 1,
993 .agc = &stk7700p_7000p_mt2060_agc_config,
994 .bw = &stk7700p_pll_config,
996 .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
997 .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
998 .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
1001 static int stk7700p_frontend_attach(struct dvb_usb_adapter *adap)
1003 struct dib0700_state *st = adap->dev->priv;
1004 /* unless there is no real power management in DVB - we leave the device on GPIO6 */
1006 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1007 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(50);
1009 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10);
1010 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1012 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10);
1013 dib0700_ctrl_clock(adap->dev, 72, 1);
1014 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(100);
1016 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1018 st->mt2060_if1[0] = 1220;
1020 if (dib7000pc_detection(&adap->dev->i2c_adap)) {
1021 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000p_config);
1022 st->is_dib7000pc = 1;
1024 adap->fe = dvb_attach(dib7000m_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000m_config);
1026 return adap->fe == NULL ? -ENODEV : 0;
1029 static struct mt2060_config stk7700p_mt2060_config = {
1033 static int stk7700p_tuner_attach(struct dvb_usb_adapter *adap)
1035 struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap;
1036 struct dib0700_state *st = adap->dev->priv;
1037 struct i2c_adapter *tun_i2c;
1040 if (adap->dev->udev->descriptor.idVendor == cpu_to_le16(USB_VID_HAUPPAUGE) &&
1041 adap->dev->udev->descriptor.idProduct == cpu_to_le16(USB_PID_HAUPPAUGE_NOVA_T_STICK)) {
1042 if (!eeprom_read(prim_i2c,0x58,&a)) if1=1220+a;
1044 if (st->is_dib7000pc)
1045 tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
1047 tun_i2c = dib7000m_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
1049 return dvb_attach(mt2060_attach, adap->fe, tun_i2c, &stk7700p_mt2060_config,
1050 if1) == NULL ? -ENODEV : 0;
1053 /* DIB7070 generic */
1054 static struct dibx000_agc_config dib7070_agc_config = {
1055 BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
1056 /* 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,
1057 * 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 */
1058 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup
1061 10, // time_stabiliz
1092 0, // perform_agc_softsplit
1095 static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
1097 return dib7000p_set_gpio(fe, 8, 0, !onoff);
1100 static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
1102 return dib7000p_set_gpio(fe, 9, 0, onoff);
1105 static struct dib0070_config dib7070p_dib0070_config[2] = {
1107 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1108 .reset = dib7070_tuner_reset,
1109 .sleep = dib7070_tuner_sleep,
1111 .clock_pad_drive = 4
1113 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1114 .reset = dib7070_tuner_reset,
1115 .sleep = dib7070_tuner_sleep,
1121 static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1123 struct dvb_usb_adapter *adap = fe->dvb->priv;
1124 struct dib0700_adapter_state *state = adap->priv;
1127 u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
1129 case BAND_VHF: offset = 950; break;
1131 default: offset = 550; break;
1133 deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe));
1134 dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
1135 return state->set_param_save(fe, fep);
1138 static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap)
1140 struct dib0700_adapter_state *st = adap->priv;
1141 struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
1143 if (adap->id == 0) {
1144 if (dvb_attach(dib0070_attach, adap->fe, tun_i2c, &dib7070p_dib0070_config[0]) == NULL)
1147 if (dvb_attach(dib0070_attach, adap->fe, tun_i2c, &dib7070p_dib0070_config[1]) == NULL)
1151 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
1152 adap->fe->ops.tuner_ops.set_params = dib7070_set_param_override;
1156 static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
1157 60000, 15000, // internal, sampling
1158 1, 20, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
1159 0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
1160 (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
1161 (0 << 25) | 0, // ifreq = 0.000000 MHz
1163 12000000, // xtal_hz
1166 static struct dib7000p_config dib7070p_dib7000p_config = {
1167 .output_mpeg2_in_188_bytes = 1,
1169 .agc_config_count = 1,
1170 .agc = &dib7070_agc_config,
1171 .bw = &dib7070_bw_config_12_mhz,
1172 .tuner_is_baseband = 1,
1175 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
1176 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
1177 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
1179 .hostbus_diversity = 1,
1183 static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
1185 struct usb_device_descriptor *p = &adap->dev->udev->descriptor;
1186 if (p->idVendor == cpu_to_le16(USB_VID_PINNACLE) &&
1187 p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E))
1188 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
1190 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1192 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1193 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1194 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1195 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1197 dib0700_ctrl_clock(adap->dev, 72, 1);
1200 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1202 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1204 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
1205 &dib7070p_dib7000p_config) != 0) {
1206 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
1211 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
1212 &dib7070p_dib7000p_config);
1213 return adap->fe == NULL ? -ENODEV : 0;
1217 static struct dib7000p_config stk7070pd_dib7000p_config[2] = {
1219 .output_mpeg2_in_188_bytes = 1,
1221 .agc_config_count = 1,
1222 .agc = &dib7070_agc_config,
1223 .bw = &dib7070_bw_config_12_mhz,
1224 .tuner_is_baseband = 1,
1227 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
1228 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
1229 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
1231 .hostbus_diversity = 1,
1233 .output_mpeg2_in_188_bytes = 1,
1235 .agc_config_count = 1,
1236 .agc = &dib7070_agc_config,
1237 .bw = &dib7070_bw_config_12_mhz,
1238 .tuner_is_baseband = 1,
1241 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
1242 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
1243 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
1245 .hostbus_diversity = 1,
1249 static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap)
1251 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1253 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1254 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1255 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1256 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1258 dib0700_ctrl_clock(adap->dev, 72, 1);
1261 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1263 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1265 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
1266 stk7070pd_dib7000p_config) != 0) {
1267 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
1272 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &stk7070pd_dib7000p_config[0]);
1273 return adap->fe == NULL ? -ENODEV : 0;
1276 static int stk7070pd_frontend_attach1(struct dvb_usb_adapter *adap)
1278 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x82, &stk7070pd_dib7000p_config[1]);
1279 return adap->fe == NULL ? -ENODEV : 0;
1283 static struct s5h1411_config pinnacle_801e_config = {
1284 .output_mode = S5H1411_PARALLEL_OUTPUT,
1285 .gpio = S5H1411_GPIO_OFF,
1286 .mpeg_timing = S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK,
1287 .qam_if = S5H1411_IF_44000,
1288 .vsb_if = S5H1411_IF_44000,
1289 .inversion = S5H1411_INVERSION_OFF,
1290 .status_mode = S5H1411_DEMODLOCKING
1293 /* Pinnacle PCTV HD Pro 801e GPIOs map:
1294 GPIO0 - currently unknown
1295 GPIO1 - xc5000 tuner reset
1296 GPIO2 - CX25843 sleep
1297 GPIO3 - currently unknown
1298 GPIO4 - currently unknown
1299 GPIO6 - currently unknown
1300 GPIO7 - currently unknown
1301 GPIO9 - currently unknown
1302 GPIO10 - CX25843 reset
1304 static int s5h1411_frontend_attach(struct dvb_usb_adapter *adap)
1306 struct dib0700_state *st = adap->dev->priv;
1308 /* Make use of the new i2c functions from FW 1.20 */
1309 st->fw_use_new_i2c_api = 1;
1311 /* The s5h1411 requires the dib0700 to not be in master mode */
1312 st->disable_streaming_master_mode = 1;
1314 /* All msleep values taken from Windows USB trace */
1315 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0);
1316 dib0700_set_gpio(adap->dev, GPIO3, GPIO_OUT, 0);
1317 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1319 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1321 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1323 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1324 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1325 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1326 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1327 dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 0);
1330 /* Put the CX25843 to sleep for now since we're in digital mode */
1331 dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 1);
1333 /* GPIOs are initialized, do the attach */
1334 adap->fe = dvb_attach(s5h1411_attach, &pinnacle_801e_config,
1335 &adap->dev->i2c_adap);
1336 return adap->fe == NULL ? -ENODEV : 0;
1339 static int dib0700_xc5000_tuner_callback(void *priv, int component,
1340 int command, int arg)
1342 struct dvb_usb_adapter *adap = priv;
1344 if (command == XC5000_TUNER_RESET) {
1345 /* Reset the tuner */
1346 dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 0);
1347 msleep(330); /* from Windows USB trace */
1348 dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 1);
1349 msleep(330); /* from Windows USB trace */
1351 err("xc5000: unknown tuner callback command: %d\n", command);
1358 static struct xc5000_config s5h1411_xc5000_tunerconfig = {
1359 .i2c_address = 0x64,
1363 static int xc5000_tuner_attach(struct dvb_usb_adapter *adap)
1365 /* FIXME: generalize & move to common area */
1366 adap->fe->callback = dib0700_xc5000_tuner_callback;
1368 return dvb_attach(xc5000_attach, adap->fe, &adap->dev->i2c_adap,
1369 &s5h1411_xc5000_tunerconfig)
1370 == NULL ? -ENODEV : 0;
1373 /* DVB-USB and USB stuff follows */
1374 struct usb_device_id dib0700_usb_id_table[] = {
1375 /* 0 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P) },
1376 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P_PC) },
1377 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500) },
1378 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_2) },
1379 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK) },
1380 /* 5 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR) },
1381 { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_VIDEOMATE_U500) },
1382 { USB_DEVICE(USB_VID_UNIWILL, USB_PID_UNIWILL_STK7700P) },
1383 { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P) },
1384 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_2) },
1385 /* 10 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_2) },
1386 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV2000E) },
1387 { USB_DEVICE(USB_VID_TERRATEC,
1388 USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY) },
1389 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK) },
1390 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700D) },
1391 /* 15 */{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7070P) },
1392 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV_DVB_T_FLASH) },
1393 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7070PD) },
1394 { USB_DEVICE(USB_VID_PINNACLE,
1395 USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T) },
1396 { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_VIDEOMATE_U500_PC) },
1397 /* 20 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_EXPRESS) },
1398 { USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U7000) },
1399 { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14BR) },
1400 { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000) },
1401 { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3100) },
1402 /* 25 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_3) },
1403 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_MYTV_T) },
1404 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_USB_XE) },
1405 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_EXPRESSCARD_320CX) },
1406 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV72E) },
1407 /* 30 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73E) },
1408 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_EC372S) },
1409 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_EXPRESS) },
1410 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS) },
1411 { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) },
1412 /* 35 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) },
1413 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_3) },
1414 { USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U8000) },
1415 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700PH) },
1416 { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000H) },
1417 /* 40 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E) },
1418 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E_SE) },
1419 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_EXPRESS) },
1420 { USB_DEVICE(USB_VID_TERRATEC,
1421 USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2) },
1422 { USB_DEVICE(USB_VID_SONY, USB_PID_SONY_PLAYTV) },
1423 /* 45 */{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_PD378S) },
1424 { 0 } /* Terminating entry */
1426 MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
1428 #define DIB0700_DEFAULT_DEVICE_PROPERTIES \
1429 .caps = DVB_USB_IS_AN_I2C_ADAPTER, \
1430 .usb_ctrl = DEVICE_SPECIFIC, \
1431 .firmware = "dvb-usb-dib0700-1.20.fw", \
1432 .download_firmware = dib0700_download_firmware, \
1433 .no_reconnect = 1, \
1434 .size_of_priv = sizeof(struct dib0700_state), \
1435 .i2c_algo = &dib0700_i2c_algo, \
1436 .identify_state = dib0700_identify_state
1438 #define DIB0700_DEFAULT_STREAMING_CONFIG(ep) \
1439 .streaming_ctrl = dib0700_streaming_ctrl, \
1446 .buffersize = 39480, \
1451 struct dvb_usb_device_properties dib0700_devices[] = {
1453 DIB0700_DEFAULT_DEVICE_PROPERTIES,
1458 .frontend_attach = stk7700p_frontend_attach,
1459 .tuner_attach = stk7700p_tuner_attach,
1461 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1465 .num_device_descs = 8,
1467 { "DiBcom STK7700P reference design",
1468 { &dib0700_usb_id_table[0], &dib0700_usb_id_table[1] },
1471 { "Hauppauge Nova-T Stick",
1472 { &dib0700_usb_id_table[4], &dib0700_usb_id_table[9], NULL },
1475 { "AVerMedia AVerTV DVB-T Volar",
1476 { &dib0700_usb_id_table[5], &dib0700_usb_id_table[10] },
1479 { "Compro Videomate U500",
1480 { &dib0700_usb_id_table[6], &dib0700_usb_id_table[19] },
1483 { "Uniwill STK7700P based (Hama and others)",
1484 { &dib0700_usb_id_table[7], NULL },
1487 { "Leadtek Winfast DTV Dongle (STK7700P based)",
1488 { &dib0700_usb_id_table[8], &dib0700_usb_id_table[34] },
1491 { "AVerMedia AVerTV DVB-T Express",
1492 { &dib0700_usb_id_table[20] },
1496 { &dib0700_usb_id_table[21], NULL },
1501 .rc_interval = DEFAULT_RC_INTERVAL,
1502 .rc_key_map = dib0700_rc_keys,
1503 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
1504 .rc_query = dib0700_rc_query
1505 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1510 .frontend_attach = bristol_frontend_attach,
1511 .tuner_attach = bristol_tuner_attach,
1513 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1515 .frontend_attach = bristol_frontend_attach,
1516 .tuner_attach = bristol_tuner_attach,
1518 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
1522 .num_device_descs = 1,
1524 { "Hauppauge Nova-T 500 Dual DVB-T",
1525 { &dib0700_usb_id_table[2], &dib0700_usb_id_table[3], NULL },
1530 .rc_interval = DEFAULT_RC_INTERVAL,
1531 .rc_key_map = dib0700_rc_keys,
1532 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
1533 .rc_query = dib0700_rc_query
1534 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1539 .frontend_attach = stk7700d_frontend_attach,
1540 .tuner_attach = stk7700d_tuner_attach,
1542 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1544 .frontend_attach = stk7700d_frontend_attach,
1545 .tuner_attach = stk7700d_tuner_attach,
1547 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
1551 .num_device_descs = 4,
1553 { "Pinnacle PCTV 2000e",
1554 { &dib0700_usb_id_table[11], NULL },
1557 { "Terratec Cinergy DT XS Diversity",
1558 { &dib0700_usb_id_table[12], NULL },
1561 { "Hauppauge Nova-TD Stick/Elgato Eye-TV Diversity",
1562 { &dib0700_usb_id_table[13], NULL },
1565 { "DiBcom STK7700D reference design",
1566 { &dib0700_usb_id_table[14], 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
1577 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1582 .frontend_attach = stk7700P2_frontend_attach,
1583 .tuner_attach = stk7700d_tuner_attach,
1585 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1589 .num_device_descs = 3,
1591 { "ASUS My Cinema U3000 Mini DVBT Tuner",
1592 { &dib0700_usb_id_table[23], NULL },
1596 { &dib0700_usb_id_table[31], NULL },
1599 { "Terratec Cinergy T Express",
1600 { &dib0700_usb_id_table[42], NULL },
1605 .rc_interval = DEFAULT_RC_INTERVAL,
1606 .rc_key_map = dib0700_rc_keys,
1607 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
1608 .rc_query = dib0700_rc_query
1609 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1614 .frontend_attach = stk7070p_frontend_attach,
1615 .tuner_attach = dib7070p_tuner_attach,
1617 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1619 .size_of_priv = sizeof(struct dib0700_adapter_state),
1623 .num_device_descs = 10,
1625 { "DiBcom STK7070P reference design",
1626 { &dib0700_usb_id_table[15], NULL },
1629 { "Pinnacle PCTV DVB-T Flash Stick",
1630 { &dib0700_usb_id_table[16], NULL },
1633 { "Artec T14BR DVB-T",
1634 { &dib0700_usb_id_table[22], NULL },
1637 { "ASUS My Cinema U3100 Mini DVBT Tuner",
1638 { &dib0700_usb_id_table[24], NULL },
1641 { "Hauppauge Nova-T Stick",
1642 { &dib0700_usb_id_table[25], NULL },
1645 { "Hauppauge Nova-T MyTV.t",
1646 { &dib0700_usb_id_table[26], NULL },
1649 { "Pinnacle PCTV 72e",
1650 { &dib0700_usb_id_table[29], NULL },
1653 { "Pinnacle PCTV 73e",
1654 { &dib0700_usb_id_table[30], NULL },
1657 { "Terratec Cinergy T USB XXS",
1658 { &dib0700_usb_id_table[33], NULL },
1662 { &dib0700_usb_id_table[45], NULL },
1667 .rc_interval = DEFAULT_RC_INTERVAL,
1668 .rc_key_map = dib0700_rc_keys,
1669 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
1670 .rc_query = dib0700_rc_query
1672 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1677 .frontend_attach = stk7070pd_frontend_attach0,
1678 .tuner_attach = dib7070p_tuner_attach,
1680 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1682 .size_of_priv = sizeof(struct dib0700_adapter_state),
1684 .frontend_attach = stk7070pd_frontend_attach1,
1685 .tuner_attach = dib7070p_tuner_attach,
1687 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
1689 .size_of_priv = sizeof(struct dib0700_adapter_state),
1693 .num_device_descs = 6,
1695 { "DiBcom STK7070PD reference design",
1696 { &dib0700_usb_id_table[17], NULL },
1699 { "Pinnacle PCTV Dual DVB-T Diversity Stick",
1700 { &dib0700_usb_id_table[18], NULL },
1703 { "Hauppauge Nova-TD Stick (52009)",
1704 { &dib0700_usb_id_table[35], NULL },
1707 { "Hauppauge Nova-TD-500 (84xxx)",
1708 { &dib0700_usb_id_table[36], NULL },
1711 { "Terratec Cinergy DT USB XS Diversity",
1712 { &dib0700_usb_id_table[43], NULL },
1716 { &dib0700_usb_id_table[44], NULL },
1720 .rc_interval = DEFAULT_RC_INTERVAL,
1721 .rc_key_map = dib0700_rc_keys,
1722 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
1723 .rc_query = dib0700_rc_query
1724 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1729 .frontend_attach = stk7700ph_frontend_attach,
1730 .tuner_attach = stk7700ph_tuner_attach,
1732 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1734 .size_of_priv = sizeof(struct
1735 dib0700_adapter_state),
1739 .num_device_descs = 5,
1741 { "Terratec Cinergy HT USB XE",
1742 { &dib0700_usb_id_table[27], NULL },
1745 { "Pinnacle Expresscard 320cx",
1746 { &dib0700_usb_id_table[28], NULL },
1749 { "Terratec Cinergy HT Express",
1750 { &dib0700_usb_id_table[32], NULL },
1753 { "Gigabyte U8000-RH",
1754 { &dib0700_usb_id_table[37], NULL },
1757 { "YUAN High-Tech STK7700PH",
1758 { &dib0700_usb_id_table[38], NULL },
1761 { "Asus My Cinema-U3000Hybrid",
1762 { &dib0700_usb_id_table[39], NULL },
1766 .rc_interval = DEFAULT_RC_INTERVAL,
1767 .rc_key_map = dib0700_rc_keys,
1768 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
1769 .rc_query = dib0700_rc_query
1770 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1774 .frontend_attach = s5h1411_frontend_attach,
1775 .tuner_attach = xc5000_tuner_attach,
1777 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1779 .size_of_priv = sizeof(struct
1780 dib0700_adapter_state),
1784 .num_device_descs = 2,
1786 { "Pinnacle PCTV HD Pro USB Stick",
1787 { &dib0700_usb_id_table[40], NULL },
1790 { "Pinnacle PCTV HD USB Stick",
1791 { &dib0700_usb_id_table[41], NULL },
1795 .rc_interval = DEFAULT_RC_INTERVAL,
1796 .rc_key_map = dib0700_rc_keys,
1797 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
1798 .rc_query = dib0700_rc_query
1802 int dib0700_device_count = ARRAY_SIZE(dib0700_devices);