V4L/DVB (12888): STK7770P: Add support for STK7770P
[safe/jmp/linux-2.6] / drivers / media / dvb / dvb-usb / dib0700_devices.c
1 /* Linux driver for devices based on the DiBcom DiB0700 USB bridge
2  *
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.
6  *
7  *  Copyright (C) 2005-7 DiBcom, SA
8  */
9 #include "dib0700.h"
10
11 #include "dib3000mc.h"
12 #include "dib7000m.h"
13 #include "dib7000p.h"
14 #include "mt2060.h"
15 #include "mt2266.h"
16 #include "tuner-xc2028.h"
17 #include "xc5000.h"
18 #include "s5h1411.h"
19 #include "dib0070.h"
20 #include "lgdt3305.h"
21 #include "mxl5007t.h"
22
23 static int force_lna_activation;
24 module_param(force_lna_activation, int, 0644);
25 MODULE_PARM_DESC(force_lna_activation, "force the activation of Low-Noise-Amplifyer(s) (LNA), "
26                 "if applicable for the device (default: 0=automatic/off).");
27
28 struct dib0700_adapter_state {
29         int (*set_param_save) (struct dvb_frontend *, struct dvb_frontend_parameters *);
30 };
31
32 /* Hauppauge Nova-T 500 (aka Bristol)
33  *  has a LNA on GPIO0 which is enabled by setting 1 */
34 static struct mt2060_config bristol_mt2060_config[2] = {
35         {
36                 .i2c_address = 0x60,
37                 .clock_out   = 3,
38         }, {
39                 .i2c_address = 0x61,
40         }
41 };
42
43
44 static struct dibx000_agc_config bristol_dib3000p_mt2060_agc_config = {
45         .band_caps = BAND_VHF | BAND_UHF,
46         .setup     = (1 << 8) | (5 << 5) | (0 << 4) | (0 << 3) | (0 << 2) | (2 << 0),
47
48         .agc1_max = 42598,
49         .agc1_min = 17694,
50         .agc2_max = 45875,
51         .agc2_min = 0,
52
53         .agc1_pt1 = 0,
54         .agc1_pt2 = 59,
55
56         .agc1_slope1 = 0,
57         .agc1_slope2 = 69,
58
59         .agc2_pt1 = 0,
60         .agc2_pt2 = 59,
61
62         .agc2_slope1 = 111,
63         .agc2_slope2 = 28,
64 };
65
66 static struct dib3000mc_config bristol_dib3000mc_config[2] = {
67         {       .agc          = &bristol_dib3000p_mt2060_agc_config,
68                 .max_time     = 0x196,
69                 .ln_adc_level = 0x1cc7,
70                 .output_mpeg2_in_188_bytes = 1,
71         },
72         {       .agc          = &bristol_dib3000p_mt2060_agc_config,
73                 .max_time     = 0x196,
74                 .ln_adc_level = 0x1cc7,
75                 .output_mpeg2_in_188_bytes = 1,
76         }
77 };
78
79 static int bristol_frontend_attach(struct dvb_usb_adapter *adap)
80 {
81         struct dib0700_state *st = adap->dev->priv;
82         if (adap->id == 0) {
83                 dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 0); msleep(10);
84                 dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 1); msleep(10);
85                 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10);
86                 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(10);
87
88                 if (force_lna_activation)
89                         dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
90                 else
91                         dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0);
92
93                 if (dib3000mc_i2c_enumeration(&adap->dev->i2c_adap, 2, DEFAULT_DIB3000P_I2C_ADDRESS, bristol_dib3000mc_config) != 0) {
94                         dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(10);
95                         return -ENODEV;
96                 }
97         }
98         st->mt2060_if1[adap->id] = 1220;
99         return (adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap,
100                 (10 + adap->id) << 1, &bristol_dib3000mc_config[adap->id])) == NULL ? -ENODEV : 0;
101 }
102
103 static int eeprom_read(struct i2c_adapter *adap,u8 adrs,u8 *pval)
104 {
105         struct i2c_msg msg[2] = {
106                 { .addr = 0x50, .flags = 0,        .buf = &adrs, .len = 1 },
107                 { .addr = 0x50, .flags = I2C_M_RD, .buf = pval,  .len = 1 },
108         };
109         if (i2c_transfer(adap, msg, 2) != 2) return -EREMOTEIO;
110         return 0;
111 }
112
113 static int bristol_tuner_attach(struct dvb_usb_adapter *adap)
114 {
115         struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap;
116         struct i2c_adapter *tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe, 1);
117         s8 a;
118         int if1=1220;
119         if (adap->dev->udev->descriptor.idVendor  == cpu_to_le16(USB_VID_HAUPPAUGE) &&
120                 adap->dev->udev->descriptor.idProduct == cpu_to_le16(USB_PID_HAUPPAUGE_NOVA_T_500_2)) {
121                 if (!eeprom_read(prim_i2c,0x59 + adap->id,&a)) if1=1220+a;
122         }
123         return dvb_attach(mt2060_attach,adap->fe, tun_i2c,&bristol_mt2060_config[adap->id],
124                 if1) == NULL ? -ENODEV : 0;
125 }
126
127 /* STK7700D: Pinnacle/Terratec/Hauppauge Dual DVB-T Diversity */
128
129 /* MT226x */
130 static struct dibx000_agc_config stk7700d_7000p_mt2266_agc_config[2] = {
131         {
132                 BAND_UHF, // band_caps
133
134                 /* 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,
135                 * 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 */
136                 (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup
137
138                 1130,  // inv_gain
139                 21,  // time_stabiliz
140
141                 0,  // alpha_level
142                 118,  // thlock
143
144                 0,     // wbd_inv
145                 3530,  // wbd_ref
146                 1,     // wbd_sel
147                 0,     // wbd_alpha
148
149                 65535,  // agc1_max
150                 33770,  // agc1_min
151                 65535,  // agc2_max
152                 23592,  // agc2_min
153
154                 0,    // agc1_pt1
155                 62,   // agc1_pt2
156                 255,  // agc1_pt3
157                 64,   // agc1_slope1
158                 64,   // agc1_slope2
159                 132,  // agc2_pt1
160                 192,  // agc2_pt2
161                 80,   // agc2_slope1
162                 80,   // agc2_slope2
163
164                 17,  // alpha_mant
165                 27,  // alpha_exp
166                 23,  // beta_mant
167                 51,  // beta_exp
168
169                 1,  // perform_agc_softsplit
170         }, {
171                 BAND_VHF | BAND_LBAND, // band_caps
172
173                 /* 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,
174                 * 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 */
175                 (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
176
177                 2372, // inv_gain
178                 21,   // time_stabiliz
179
180                 0,    // alpha_level
181                 118,  // thlock
182
183                 0,    // wbd_inv
184                 3530, // wbd_ref
185                 1,     // wbd_sel
186                 0,    // wbd_alpha
187
188                 65535, // agc1_max
189                 0,     // agc1_min
190                 65535, // agc2_max
191                 23592, // agc2_min
192
193                 0,    // agc1_pt1
194                 128,  // agc1_pt2
195                 128,  // agc1_pt3
196                 128,  // agc1_slope1
197                 0,    // agc1_slope2
198                 128,  // agc2_pt1
199                 253,  // agc2_pt2
200                 81,   // agc2_slope1
201                 0,    // agc2_slope2
202
203                 17,  // alpha_mant
204                 27,  // alpha_exp
205                 23,  // beta_mant
206                 51,  // beta_exp
207
208                 1,  // perform_agc_softsplit
209         }
210 };
211
212 static struct dibx000_bandwidth_config stk7700d_mt2266_pll_config = {
213         60000, 30000, // internal, sampling
214         1, 8, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
215         0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
216         (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
217         0, // ifreq
218         20452225, // timf
219 };
220
221 static struct dib7000p_config stk7700d_dib7000p_mt2266_config[] = {
222         {       .output_mpeg2_in_188_bytes = 1,
223                 .hostbus_diversity = 1,
224                 .tuner_is_baseband = 1,
225
226                 .agc_config_count = 2,
227                 .agc = stk7700d_7000p_mt2266_agc_config,
228                 .bw  = &stk7700d_mt2266_pll_config,
229
230                 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
231                 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
232                 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
233         },
234         {       .output_mpeg2_in_188_bytes = 1,
235                 .hostbus_diversity = 1,
236                 .tuner_is_baseband = 1,
237
238                 .agc_config_count = 2,
239                 .agc = stk7700d_7000p_mt2266_agc_config,
240                 .bw  = &stk7700d_mt2266_pll_config,
241
242                 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
243                 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
244                 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
245         }
246 };
247
248 static struct mt2266_config stk7700d_mt2266_config[2] = {
249         {       .i2c_address = 0x60
250         },
251         {       .i2c_address = 0x60
252         }
253 };
254
255 static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap)
256 {
257         if (adap->id == 0) {
258                 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
259                 msleep(10);
260                 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
261                 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
262                 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
263                 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
264                 msleep(10);
265                 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
266                 msleep(10);
267                 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
268                                              stk7700d_dib7000p_mt2266_config)
269                     != 0) {
270                         err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n", __func__);
271                         return -ENODEV;
272                 }
273         }
274
275         adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1),
276                                 &stk7700d_dib7000p_mt2266_config[adap->id]);
277
278         return adap->fe == NULL ? -ENODEV : 0;
279 }
280
281 static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap)
282 {
283         if (adap->id == 0) {
284                 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
285                 msleep(10);
286                 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
287                 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
288                 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
289                 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
290                 msleep(10);
291                 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
292                 msleep(10);
293                 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
294                 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
295                                              stk7700d_dib7000p_mt2266_config)
296                     != 0) {
297                         err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n", __func__);
298                         return -ENODEV;
299                 }
300         }
301
302         adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1),
303                                 &stk7700d_dib7000p_mt2266_config[adap->id]);
304
305         return adap->fe == NULL ? -ENODEV : 0;
306 }
307
308 static int stk7700d_tuner_attach(struct dvb_usb_adapter *adap)
309 {
310         struct i2c_adapter *tun_i2c;
311         tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
312         return dvb_attach(mt2266_attach, adap->fe, tun_i2c,
313                 &stk7700d_mt2266_config[adap->id]) == NULL ? -ENODEV : 0;
314 }
315
316 /* STK7700-PH: Digital/Analog Hybrid Tuner, e.h. Cinergy HT USB HE */
317 static struct dibx000_agc_config xc3028_agc_config = {
318         BAND_VHF | BAND_UHF,       /* band_caps */
319
320         /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=0,
321          * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
322          * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
323         (0 << 15) | (0 << 14) | (0 << 11) | (0 << 10) | (0 << 9) | (0 << 8) |
324         (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), /* setup */
325
326         712,    /* inv_gain */
327         21,     /* time_stabiliz */
328
329         0,      /* alpha_level */
330         118,    /* thlock */
331
332         0,      /* wbd_inv */
333         2867,   /* wbd_ref */
334         0,      /* wbd_sel */
335         2,      /* wbd_alpha */
336
337         0,      /* agc1_max */
338         0,      /* agc1_min */
339         39718,  /* agc2_max */
340         9930,   /* agc2_min */
341         0,      /* agc1_pt1 */
342         0,      /* agc1_pt2 */
343         0,      /* agc1_pt3 */
344         0,      /* agc1_slope1 */
345         0,      /* agc1_slope2 */
346         0,      /* agc2_pt1 */
347         128,    /* agc2_pt2 */
348         29,     /* agc2_slope1 */
349         29,     /* agc2_slope2 */
350
351         17,     /* alpha_mant */
352         27,     /* alpha_exp */
353         23,     /* beta_mant */
354         51,     /* beta_exp */
355
356         1,      /* perform_agc_softsplit */
357 };
358
359 /* PLL Configuration for COFDM BW_MHz = 8.00 with external clock = 30.00 */
360 static struct dibx000_bandwidth_config xc3028_bw_config = {
361         60000, 30000, /* internal, sampling */
362         1, 8, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass */
363         0, 0, 1, 1, 0, /* misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc,
364                           modulo */
365         (3 << 14) | (1 << 12) | (524 << 0), /* sad_cfg: refsel, sel, freq_15k */
366         (1 << 25) | 5816102, /* ifreq = 5.200000 MHz */
367         20452225, /* timf */
368         30000000, /* xtal_hz */
369 };
370
371 static struct dib7000p_config stk7700ph_dib7700_xc3028_config = {
372         .output_mpeg2_in_188_bytes = 1,
373         .tuner_is_baseband = 1,
374
375         .agc_config_count = 1,
376         .agc = &xc3028_agc_config,
377         .bw  = &xc3028_bw_config,
378
379         .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
380         .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
381         .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
382 };
383
384 static int stk7700ph_xc3028_callback(void *ptr, int component,
385                                      int command, int arg)
386 {
387         struct dvb_usb_adapter *adap = ptr;
388
389         switch (command) {
390         case XC2028_TUNER_RESET:
391                 /* Send the tuner in then out of reset */
392                 dib7000p_set_gpio(adap->fe, 8, 0, 0); msleep(10);
393                 dib7000p_set_gpio(adap->fe, 8, 0, 1);
394                 break;
395         case XC2028_RESET_CLK:
396                 break;
397         default:
398                 err("%s: unknown command %d, arg %d\n", __func__,
399                         command, arg);
400                 return -EINVAL;
401         }
402         return 0;
403 }
404
405 static struct xc2028_ctrl stk7700ph_xc3028_ctrl = {
406         .fname = XC2028_DEFAULT_FIRMWARE,
407         .max_len = 64,
408         .demod = XC3028_FE_DIBCOM52,
409 };
410
411 static struct xc2028_config stk7700ph_xc3028_config = {
412         .i2c_addr = 0x61,
413         .ctrl = &stk7700ph_xc3028_ctrl,
414 };
415
416 static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap)
417 {
418         struct usb_device_descriptor *desc = &adap->dev->udev->descriptor;
419
420         if (desc->idVendor  == cpu_to_le16(USB_VID_PINNACLE) &&
421             desc->idProduct == cpu_to_le16(USB_PID_PINNACLE_EXPRESSCARD_320CX))
422         dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
423         else
424         dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
425         msleep(20);
426         dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
427         dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
428         dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
429         dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
430         msleep(10);
431         dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
432         msleep(20);
433         dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
434         msleep(10);
435
436         if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
437                                      &stk7700ph_dib7700_xc3028_config) != 0) {
438                 err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
439                     __func__);
440                 return -ENODEV;
441         }
442
443         adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
444                 &stk7700ph_dib7700_xc3028_config);
445
446         return adap->fe == NULL ? -ENODEV : 0;
447 }
448
449 static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap)
450 {
451         struct i2c_adapter *tun_i2c;
452
453         tun_i2c = dib7000p_get_i2c_master(adap->fe,
454                 DIBX000_I2C_INTERFACE_TUNER, 1);
455
456         stk7700ph_xc3028_config.i2c_adap = tun_i2c;
457
458         /* FIXME: generalize & move to common area */
459         adap->fe->callback = stk7700ph_xc3028_callback;
460
461         return dvb_attach(xc2028_attach, adap->fe, &stk7700ph_xc3028_config)
462                 == NULL ? -ENODEV : 0;
463 }
464
465 #define DEFAULT_RC_INTERVAL 50
466
467 static u8 rc_request[] = { REQUEST_POLL_RC, 0 };
468
469 /* Number of keypresses to ignore before start repeating */
470 #define RC_REPEAT_DELAY 6
471 #define RC_REPEAT_DELAY_V1_20 10
472
473
474
475 /* Used by firmware versions < 1.20 (deprecated) */
476 static int dib0700_rc_query_legacy(struct dvb_usb_device *d, u32 *event,
477                                    int *state)
478 {
479         u8 key[4];
480         int i;
481         struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
482         struct dib0700_state *st = d->priv;
483         *event = 0;
484         *state = REMOTE_NO_KEY_PRESSED;
485         i=dib0700_ctrl_rd(d,rc_request,2,key,4);
486         if (i<=0) {
487                 err("RC Query Failed");
488                 return -1;
489         }
490
491         /* losing half of KEY_0 events from Philipps rc5 remotes.. */
492         if (key[0]==0 && key[1]==0 && key[2]==0 && key[3]==0) return 0;
493
494         /* 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]);  */
495
496         dib0700_rc_setup(d); /* reset ir sensor data to prevent false events */
497
498         switch (dvb_usb_dib0700_ir_proto) {
499         case 0: {
500                 /* NEC protocol sends repeat code as 0 0 0 FF */
501                 if ((key[3-2] == 0x00) && (key[3-3] == 0x00) &&
502                     (key[3] == 0xFF)) {
503                         st->rc_counter++;
504                         if (st->rc_counter > RC_REPEAT_DELAY) {
505                                 *event = d->last_event;
506                                 *state = REMOTE_KEY_PRESSED;
507                                 st->rc_counter = RC_REPEAT_DELAY;
508                         }
509                         return 0;
510                 }
511                 for (i=0;i<d->props.rc_key_map_size; i++) {
512                         if (rc5_custom(&keymap[i]) == key[3-2] &&
513                             rc5_data(&keymap[i]) == key[3-3]) {
514                                 st->rc_counter = 0;
515                                 *event = keymap[i].event;
516                                 *state = REMOTE_KEY_PRESSED;
517                                 d->last_event = keymap[i].event;
518                                 return 0;
519                         }
520                 }
521                 break;
522         }
523         default: {
524                 /* RC-5 protocol changes toggle bit on new keypress */
525                 for (i = 0; i < d->props.rc_key_map_size; i++) {
526                         if (rc5_custom(&keymap[i]) == key[3-2] &&
527                             rc5_data(&keymap[i]) == key[3-3]) {
528                                 if (d->last_event == keymap[i].event &&
529                                         key[3-1] == st->rc_toggle) {
530                                         st->rc_counter++;
531                                         /* prevents unwanted double hits */
532                                         if (st->rc_counter > RC_REPEAT_DELAY) {
533                                                 *event = d->last_event;
534                                                 *state = REMOTE_KEY_PRESSED;
535                                                 st->rc_counter = RC_REPEAT_DELAY;
536                                         }
537
538                                         return 0;
539                                 }
540                                 st->rc_counter = 0;
541                                 *event = keymap[i].event;
542                                 *state = REMOTE_KEY_PRESSED;
543                                 st->rc_toggle = key[3-1];
544                                 d->last_event = keymap[i].event;
545                                 return 0;
546                         }
547                 }
548                 break;
549         }
550         }
551         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         d->last_event = 0;
553         return 0;
554 }
555
556 /* This is the structure of the RC response packet starting in firmware 1.20 */
557 struct dib0700_rc_response {
558         u8 report_id;
559         u8 data_state;
560         u8 system_msb;
561         u8 system_lsb;
562         u8 data;
563         u8 not_data;
564 };
565
566 /* This supports the new IR response format for firmware v1.20 */
567 static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event,
568                                   int *state)
569 {
570         struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
571         struct dib0700_state *st = d->priv;
572         struct dib0700_rc_response poll_reply;
573         u8 buf[6];
574         int i;
575         int status;
576         int actlen;
577         int found = 0;
578
579         /* Set initial results in case we exit the function early */
580         *event = 0;
581         *state = REMOTE_NO_KEY_PRESSED;
582
583         /* Firmware v1.20 provides RC data via bulk endpoint 1 */
584         status = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, 1), buf,
585                               sizeof(buf), &actlen, 50);
586         if (status < 0) {
587                 /* No data available (meaning no key press) */
588                 return 0;
589         }
590
591         if (actlen != sizeof(buf)) {
592                 /* We didn't get back the 6 byte message we expected */
593                 err("Unexpected RC response size [%d]", actlen);
594                 return -1;
595         }
596
597         poll_reply.report_id  = buf[0];
598         poll_reply.data_state = buf[1];
599         poll_reply.system_msb = buf[2];
600         poll_reply.system_lsb = buf[3];
601         poll_reply.data       = buf[4];
602         poll_reply.not_data   = buf[5];
603
604         /*
605         info("rid=%02x ds=%02x sm=%02x sl=%02x d=%02x nd=%02x\n",
606              poll_reply.report_id, poll_reply.data_state,
607              poll_reply.system_msb, poll_reply.system_lsb,
608              poll_reply.data, poll_reply.not_data);
609         */
610
611         if ((poll_reply.data + poll_reply.not_data) != 0xff) {
612                 /* Key failed integrity check */
613                 err("key failed integrity check: %02x %02x %02x %02x",
614                     poll_reply.system_msb, poll_reply.system_lsb,
615                     poll_reply.data, poll_reply.not_data);
616                 return -1;
617         }
618
619         /* Find the key in the map */
620         for (i = 0; i < d->props.rc_key_map_size; i++) {
621                 if (rc5_custom(&keymap[i]) == poll_reply.system_lsb &&
622                     rc5_data(&keymap[i]) == poll_reply.data) {
623                         *event = keymap[i].event;
624                         found = 1;
625                         break;
626                 }
627         }
628
629         if (found == 0) {
630                 err("Unknown remote controller key: %02x %02x %02x %02x",
631                     poll_reply.system_msb, poll_reply.system_lsb,
632                     poll_reply.data, poll_reply.not_data);
633                 d->last_event = 0;
634                 return 0;
635         }
636
637         if (poll_reply.data_state == 1) {
638                 /* New key hit */
639                 st->rc_counter = 0;
640                 *event = keymap[i].event;
641                 *state = REMOTE_KEY_PRESSED;
642                 d->last_event = keymap[i].event;
643         } else if (poll_reply.data_state == 2) {
644                 /* Key repeated */
645                 st->rc_counter++;
646
647                 /* prevents unwanted double hits */
648                 if (st->rc_counter > RC_REPEAT_DELAY_V1_20) {
649                         *event = d->last_event;
650                         *state = REMOTE_KEY_PRESSED;
651                         st->rc_counter = RC_REPEAT_DELAY_V1_20;
652                 }
653         } else {
654                 err("Unknown data state [%d]", poll_reply.data_state);
655         }
656
657         return 0;
658 }
659
660 static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
661 {
662         struct dib0700_state *st = d->priv;
663
664         /* Because some people may have improperly named firmware files,
665            let's figure out whether to use the new firmware call or the legacy
666            call based on the firmware version embedded in the file */
667         if (st->rc_func_version == 0) {
668                 u32 hwver, romver, ramver, fwtype;
669                 int ret = dib0700_get_version(d, &hwver, &romver, &ramver,
670                                               &fwtype);
671                 if (ret < 0) {
672                         err("Could not determine version info");
673                         return -1;
674                 }
675                 if (ramver < 0x10200)
676                         st->rc_func_version = 1;
677                 else
678                         st->rc_func_version = 2;
679         }
680
681         if (st->rc_func_version == 2)
682                 return dib0700_rc_query_v1_20(d, event, state);
683         else
684                 return dib0700_rc_query_legacy(d, event, state);
685 }
686
687 static struct dvb_usb_rc_key dib0700_rc_keys[] = {
688         /* Key codes for the tiny Pinnacle remote*/
689         { 0x0700, KEY_MUTE },
690         { 0x0701, KEY_MENU }, /* Pinnacle logo */
691         { 0x0739, KEY_POWER },
692         { 0x0703, KEY_VOLUMEUP },
693         { 0x0709, KEY_VOLUMEDOWN },
694         { 0x0706, KEY_CHANNELUP },
695         { 0x070c, KEY_CHANNELDOWN },
696         { 0x070f, KEY_1 },
697         { 0x0715, KEY_2 },
698         { 0x0710, KEY_3 },
699         { 0x0718, KEY_4 },
700         { 0x071b, KEY_5 },
701         { 0x071e, KEY_6 },
702         { 0x0711, KEY_7 },
703         { 0x0721, KEY_8 },
704         { 0x0712, KEY_9 },
705         { 0x0727, KEY_0 },
706         { 0x0724, KEY_SCREEN }, /* 'Square' key */
707         { 0x072a, KEY_TEXT },   /* 'T' key */
708         { 0x072d, KEY_REWIND },
709         { 0x0730, KEY_PLAY },
710         { 0x0733, KEY_FASTFORWARD },
711         { 0x0736, KEY_RECORD },
712         { 0x073c, KEY_STOP },
713         { 0x073f, KEY_CANCEL }, /* '?' key */
714         /* Key codes for the Terratec Cinergy DT XS Diversity, similar to cinergyT2.c */
715         { 0xeb01, KEY_POWER },
716         { 0xeb02, KEY_1 },
717         { 0xeb03, KEY_2 },
718         { 0xeb04, KEY_3 },
719         { 0xeb05, KEY_4 },
720         { 0xeb06, KEY_5 },
721         { 0xeb07, KEY_6 },
722         { 0xeb08, KEY_7 },
723         { 0xeb09, KEY_8 },
724         { 0xeb0a, KEY_9 },
725         { 0xeb0b, KEY_VIDEO },
726         { 0xeb0c, KEY_0 },
727         { 0xeb0d, KEY_REFRESH },
728         { 0xeb0f, KEY_EPG },
729         { 0xeb10, KEY_UP },
730         { 0xeb11, KEY_LEFT },
731         { 0xeb12, KEY_OK },
732         { 0xeb13, KEY_RIGHT },
733         { 0xeb14, KEY_DOWN },
734         { 0xeb16, KEY_INFO },
735         { 0xeb17, KEY_RED },
736         { 0xeb18, KEY_GREEN },
737         { 0xeb19, KEY_YELLOW },
738         { 0xeb1a, KEY_BLUE },
739         { 0xeb1b, KEY_CHANNELUP },
740         { 0xeb1c, KEY_VOLUMEUP },
741         { 0xeb1d, KEY_MUTE },
742         { 0xeb1e, KEY_VOLUMEDOWN },
743         { 0xeb1f, KEY_CHANNELDOWN },
744         { 0xeb40, KEY_PAUSE },
745         { 0xeb41, KEY_HOME },
746         { 0xeb42, KEY_MENU }, /* DVD Menu */
747         { 0xeb43, KEY_SUBTITLE },
748         { 0xeb44, KEY_TEXT }, /* Teletext */
749         { 0xeb45, KEY_DELETE },
750         { 0xeb46, KEY_TV },
751         { 0xeb47, KEY_DVD },
752         { 0xeb48, KEY_STOP },
753         { 0xeb49, KEY_VIDEO },
754         { 0xeb4a, KEY_AUDIO }, /* Music */
755         { 0xeb4b, KEY_SCREEN }, /* Pic */
756         { 0xeb4c, KEY_PLAY },
757         { 0xeb4d, KEY_BACK },
758         { 0xeb4e, KEY_REWIND },
759         { 0xeb4f, KEY_FASTFORWARD },
760         { 0xeb54, KEY_PREVIOUS },
761         { 0xeb58, KEY_RECORD },
762         { 0xeb5c, KEY_NEXT },
763
764         /* Key codes for the Haupauge WinTV Nova-TD, copied from nova-t-usb2.c (Nova-T USB2) */
765         { 0x1e00, KEY_0 },
766         { 0x1e01, KEY_1 },
767         { 0x1e02, KEY_2 },
768         { 0x1e03, KEY_3 },
769         { 0x1e04, KEY_4 },
770         { 0x1e05, KEY_5 },
771         { 0x1e06, KEY_6 },
772         { 0x1e07, KEY_7 },
773         { 0x1e08, KEY_8 },
774         { 0x1e09, KEY_9 },
775         { 0x1e0a, KEY_KPASTERISK },
776         { 0x1e0b, KEY_RED },
777         { 0x1e0c, KEY_RADIO },
778         { 0x1e0d, KEY_MENU },
779         { 0x1e0e, KEY_GRAVE }, /* # */
780         { 0x1e0f, KEY_MUTE },
781         { 0x1e10, KEY_VOLUMEUP },
782         { 0x1e11, KEY_VOLUMEDOWN },
783         { 0x1e12, KEY_CHANNEL },
784         { 0x1e14, KEY_UP },
785         { 0x1e15, KEY_DOWN },
786         { 0x1e16, KEY_LEFT },
787         { 0x1e17, KEY_RIGHT },
788         { 0x1e18, KEY_VIDEO },
789         { 0x1e19, KEY_AUDIO },
790         { 0x1e1a, KEY_MEDIA },
791         { 0x1e1b, KEY_EPG },
792         { 0x1e1c, KEY_TV },
793         { 0x1e1e, KEY_NEXT },
794         { 0x1e1f, KEY_BACK },
795         { 0x1e20, KEY_CHANNELUP },
796         { 0x1e21, KEY_CHANNELDOWN },
797         { 0x1e24, KEY_LAST }, /* Skip backwards */
798         { 0x1e25, KEY_OK },
799         { 0x1e29, KEY_BLUE},
800         { 0x1e2e, KEY_GREEN },
801         { 0x1e30, KEY_PAUSE },
802         { 0x1e32, KEY_REWIND },
803         { 0x1e34, KEY_FASTFORWARD },
804         { 0x1e35, KEY_PLAY },
805         { 0x1e36, KEY_STOP },
806         { 0x1e37, KEY_RECORD },
807         { 0x1e38, KEY_YELLOW },
808         { 0x1e3b, KEY_GOTO },
809         { 0x1e3d, KEY_POWER },
810
811         /* Key codes for the Leadtek Winfast DTV Dongle */
812         { 0x0042, KEY_POWER },
813         { 0x077c, KEY_TUNER },
814         { 0x0f4e, KEY_PRINT }, /* PREVIEW */
815         { 0x0840, KEY_SCREEN }, /* full screen toggle*/
816         { 0x0f71, KEY_DOT }, /* frequency */
817         { 0x0743, KEY_0 },
818         { 0x0c41, KEY_1 },
819         { 0x0443, KEY_2 },
820         { 0x0b7f, KEY_3 },
821         { 0x0e41, KEY_4 },
822         { 0x0643, KEY_5 },
823         { 0x097f, KEY_6 },
824         { 0x0d7e, KEY_7 },
825         { 0x057c, KEY_8 },
826         { 0x0a40, KEY_9 },
827         { 0x0e4e, KEY_CLEAR },
828         { 0x047c, KEY_CHANNEL }, /* show channel number */
829         { 0x0f41, KEY_LAST }, /* recall */
830         { 0x0342, KEY_MUTE },
831         { 0x064c, KEY_RESERVED }, /* PIP button*/
832         { 0x0172, KEY_SHUFFLE }, /* SNAPSHOT */
833         { 0x0c4e, KEY_PLAYPAUSE }, /* TIMESHIFT */
834         { 0x0b70, KEY_RECORD },
835         { 0x037d, KEY_VOLUMEUP },
836         { 0x017d, KEY_VOLUMEDOWN },
837         { 0x0242, KEY_CHANNELUP },
838         { 0x007d, KEY_CHANNELDOWN },
839
840         /* Key codes for Nova-TD "credit card" remote control. */
841         { 0x1d00, KEY_0 },
842         { 0x1d01, KEY_1 },
843         { 0x1d02, KEY_2 },
844         { 0x1d03, KEY_3 },
845         { 0x1d04, KEY_4 },
846         { 0x1d05, KEY_5 },
847         { 0x1d06, KEY_6 },
848         { 0x1d07, KEY_7 },
849         { 0x1d08, KEY_8 },
850         { 0x1d09, KEY_9 },
851         { 0x1d0a, KEY_TEXT },
852         { 0x1d0d, KEY_MENU },
853         { 0x1d0f, KEY_MUTE },
854         { 0x1d10, KEY_VOLUMEUP },
855         { 0x1d11, KEY_VOLUMEDOWN },
856         { 0x1d12, KEY_CHANNEL },
857         { 0x1d14, KEY_UP },
858         { 0x1d15, KEY_DOWN },
859         { 0x1d16, KEY_LEFT },
860         { 0x1d17, KEY_RIGHT },
861         { 0x1d1c, KEY_TV },
862         { 0x1d1e, KEY_NEXT },
863         { 0x1d1f, KEY_BACK },
864         { 0x1d20, KEY_CHANNELUP },
865         { 0x1d21, KEY_CHANNELDOWN },
866         { 0x1d24, KEY_LAST },
867         { 0x1d25, KEY_OK },
868         { 0x1d30, KEY_PAUSE },
869         { 0x1d32, KEY_REWIND },
870         { 0x1d34, KEY_FASTFORWARD },
871         { 0x1d35, KEY_PLAY },
872         { 0x1d36, KEY_STOP },
873         { 0x1d37, KEY_RECORD },
874         { 0x1d3b, KEY_GOTO },
875         { 0x1d3d, KEY_POWER },
876 };
877
878 /* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
879 static struct dibx000_agc_config stk7700p_7000m_mt2060_agc_config = {
880         BAND_UHF | BAND_VHF,       // band_caps
881
882         /* 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,
883          * 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 */
884         (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
885
886         712,  // inv_gain
887         41,  // time_stabiliz
888
889         0,  // alpha_level
890         118,  // thlock
891
892         0,     // wbd_inv
893         4095,  // wbd_ref
894         0,     // wbd_sel
895         0,     // wbd_alpha
896
897         42598,  // agc1_max
898         17694,  // agc1_min
899         45875,  // agc2_max
900         2621,  // agc2_min
901         0,  // agc1_pt1
902         76,  // agc1_pt2
903         139,  // agc1_pt3
904         52,  // agc1_slope1
905         59,  // agc1_slope2
906         107,  // agc2_pt1
907         172,  // agc2_pt2
908         57,  // agc2_slope1
909         70,  // agc2_slope2
910
911         21,  // alpha_mant
912         25,  // alpha_exp
913         28,  // beta_mant
914         48,  // beta_exp
915
916         1,  // perform_agc_softsplit
917         {  0,     // split_min
918            107,   // split_max
919            51800, // global_split_min
920            24700  // global_split_max
921         },
922 };
923
924 static struct dibx000_agc_config stk7700p_7000p_mt2060_agc_config = {
925         BAND_UHF | BAND_VHF,
926
927         /* 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,
928          * 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 */
929         (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
930
931         712, // inv_gain
932         41,  // time_stabiliz
933
934         0,   // alpha_level
935         118, // thlock
936
937         0,    // wbd_inv
938         4095, // wbd_ref
939         0,    // wbd_sel
940         0,    // wbd_alpha
941
942         42598, // agc1_max
943         16384, // agc1_min
944         42598, // agc2_max
945             0, // agc2_min
946
947           0,   // agc1_pt1
948         137,   // agc1_pt2
949         255,   // agc1_pt3
950
951           0,   // agc1_slope1
952         255,   // agc1_slope2
953
954         0,     // agc2_pt1
955         0,     // agc2_pt2
956
957          0,    // agc2_slope1
958         41,    // agc2_slope2
959
960         15, // alpha_mant
961         25, // alpha_exp
962
963         28, // beta_mant
964         48, // beta_exp
965
966         0, // perform_agc_softsplit
967 };
968
969 static struct dibx000_bandwidth_config stk7700p_pll_config = {
970         60000, 30000, // internal, sampling
971         1, 8, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
972         0, 0, 1, 1, 0, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
973         (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
974         60258167, // ifreq
975         20452225, // timf
976         30000000, // xtal
977 };
978
979 static struct dib7000m_config stk7700p_dib7000m_config = {
980         .dvbt_mode = 1,
981         .output_mpeg2_in_188_bytes = 1,
982         .quartz_direct = 1,
983
984         .agc_config_count = 1,
985         .agc = &stk7700p_7000m_mt2060_agc_config,
986         .bw  = &stk7700p_pll_config,
987
988         .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
989         .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
990         .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
991 };
992
993 static struct dib7000p_config stk7700p_dib7000p_config = {
994         .output_mpeg2_in_188_bytes = 1,
995
996         .agc_config_count = 1,
997         .agc = &stk7700p_7000p_mt2060_agc_config,
998         .bw  = &stk7700p_pll_config,
999
1000         .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
1001         .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
1002         .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
1003 };
1004
1005 static int stk7700p_frontend_attach(struct dvb_usb_adapter *adap)
1006 {
1007         struct dib0700_state *st = adap->dev->priv;
1008         /* unless there is no real power management in DVB - we leave the device on GPIO6 */
1009
1010         dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1011         dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 0); msleep(50);
1012
1013         dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 1); msleep(10);
1014         dib0700_set_gpio(adap->dev, GPIO9,  GPIO_OUT, 1);
1015
1016         dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10);
1017         dib0700_ctrl_clock(adap->dev, 72, 1);
1018         dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(100);
1019
1020         dib0700_set_gpio(adap->dev,  GPIO0, GPIO_OUT, 1);
1021
1022         st->mt2060_if1[0] = 1220;
1023
1024         if (dib7000pc_detection(&adap->dev->i2c_adap)) {
1025                 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000p_config);
1026                 st->is_dib7000pc = 1;
1027         } else
1028                 adap->fe = dvb_attach(dib7000m_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000m_config);
1029
1030         return adap->fe == NULL ? -ENODEV : 0;
1031 }
1032
1033 static struct mt2060_config stk7700p_mt2060_config = {
1034         0x60
1035 };
1036
1037 static int stk7700p_tuner_attach(struct dvb_usb_adapter *adap)
1038 {
1039         struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap;
1040         struct dib0700_state *st = adap->dev->priv;
1041         struct i2c_adapter *tun_i2c;
1042         s8 a;
1043         int if1=1220;
1044         if (adap->dev->udev->descriptor.idVendor  == cpu_to_le16(USB_VID_HAUPPAUGE) &&
1045                 adap->dev->udev->descriptor.idProduct == cpu_to_le16(USB_PID_HAUPPAUGE_NOVA_T_STICK)) {
1046                 if (!eeprom_read(prim_i2c,0x58,&a)) if1=1220+a;
1047         }
1048         if (st->is_dib7000pc)
1049                 tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
1050         else
1051                 tun_i2c = dib7000m_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
1052
1053         return dvb_attach(mt2060_attach, adap->fe, tun_i2c, &stk7700p_mt2060_config,
1054                 if1) == NULL ? -ENODEV : 0;
1055 }
1056
1057 /* DIB7070 generic */
1058 static struct dibx000_agc_config dib7070_agc_config = {
1059         BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
1060         /* 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,
1061          * 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 */
1062         (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup
1063
1064         600, // inv_gain
1065         10,  // time_stabiliz
1066
1067         0,  // alpha_level
1068         118,  // thlock
1069
1070         0,     // wbd_inv
1071         3530,  // wbd_ref
1072         1,     // wbd_sel
1073         5,     // wbd_alpha
1074
1075         65535,  // agc1_max
1076                 0,  // agc1_min
1077
1078         65535,  // agc2_max
1079         0,      // agc2_min
1080
1081         0,      // agc1_pt1
1082         40,     // agc1_pt2
1083         183,    // agc1_pt3
1084         206,    // agc1_slope1
1085         255,    // agc1_slope2
1086         72,     // agc2_pt1
1087         152,    // agc2_pt2
1088         88,     // agc2_slope1
1089         90,     // agc2_slope2
1090
1091         17,  // alpha_mant
1092         27,  // alpha_exp
1093         23,  // beta_mant
1094         51,  // beta_exp
1095
1096         0,  // perform_agc_softsplit
1097 };
1098
1099 static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
1100 {
1101         return dib7000p_set_gpio(fe, 8, 0, !onoff);
1102 }
1103
1104 static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
1105 {
1106         return dib7000p_set_gpio(fe, 9, 0, onoff);
1107 }
1108
1109 static struct dib0070_config dib7070p_dib0070_config[2] = {
1110         {
1111                 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1112                 .reset = dib7070_tuner_reset,
1113                 .sleep = dib7070_tuner_sleep,
1114                 .clock_khz = 12000,
1115                 .clock_pad_drive = 4
1116         }, {
1117                 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1118                 .reset = dib7070_tuner_reset,
1119                 .sleep = dib7070_tuner_sleep,
1120                 .clock_khz = 12000,
1121
1122         }
1123 };
1124
1125 static struct dib0070_config dib7770p_dib0070_config = {
1126          .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1127          .reset = dib7070_tuner_reset,
1128          .sleep = dib7070_tuner_sleep,
1129          .clock_khz = 12000,
1130          .clock_pad_drive = 0,
1131          .flip_chip = 1,
1132 };
1133
1134 static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1135 {
1136         struct dvb_usb_adapter *adap = fe->dvb->priv;
1137         struct dib0700_adapter_state *state = adap->priv;
1138
1139         u16 offset;
1140         u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
1141         switch (band) {
1142                 case BAND_VHF: offset = 950; break;
1143                 case BAND_UHF:
1144                 default: offset = 550; break;
1145         }
1146         deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe));
1147         dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
1148         return state->set_param_save(fe, fep);
1149 }
1150
1151 static int dib7770_set_param_override(struct dvb_frontend *fe,
1152                 struct dvb_frontend_parameters *fep)
1153 {
1154          struct dvb_usb_adapter *adap = fe->dvb->priv;
1155          struct dib0700_adapter_state *state = adap->priv;
1156
1157          u16 offset;
1158          u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
1159          switch (band) {
1160          case BAND_VHF:
1161                   dib7000p_set_gpio(fe, 0, 0, 1);
1162                   offset = 850;
1163                   break;
1164          case BAND_UHF:
1165          default:
1166                   dib7000p_set_gpio(fe, 0, 0, 0);
1167                   offset = 250;
1168                   break;
1169          }
1170          deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe));
1171          dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
1172          return state->set_param_save(fe, fep);
1173 }
1174
1175 static int dib7770p_tuner_attach(struct dvb_usb_adapter *adap)
1176 {
1177          struct dib0700_adapter_state *st = adap->priv;
1178          struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe,
1179                          DIBX000_I2C_INTERFACE_TUNER, 1);
1180
1181          if (dvb_attach(dib0070_attach, adap->fe, tun_i2c,
1182                                  &dib7770p_dib0070_config) == NULL)
1183                  return -ENODEV;
1184
1185          st->set_param_save = adap->fe->ops.tuner_ops.set_params;
1186          adap->fe->ops.tuner_ops.set_params = dib7770_set_param_override;
1187          return 0;
1188 }
1189
1190 static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap)
1191 {
1192         struct dib0700_adapter_state *st = adap->priv;
1193         struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
1194
1195         if (adap->id == 0) {
1196                 if (dvb_attach(dib0070_attach, adap->fe, tun_i2c, &dib7070p_dib0070_config[0]) == NULL)
1197                         return -ENODEV;
1198         } else {
1199                 if (dvb_attach(dib0070_attach, adap->fe, tun_i2c, &dib7070p_dib0070_config[1]) == NULL)
1200                         return -ENODEV;
1201         }
1202
1203         st->set_param_save = adap->fe->ops.tuner_ops.set_params;
1204         adap->fe->ops.tuner_ops.set_params = dib7070_set_param_override;
1205         return 0;
1206 }
1207
1208 static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
1209         60000, 15000, // internal, sampling
1210         1, 20, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
1211         0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
1212         (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
1213         (0 << 25) | 0, // ifreq = 0.000000 MHz
1214         20452225, // timf
1215         12000000, // xtal_hz
1216 };
1217
1218 static struct dib7000p_config dib7070p_dib7000p_config = {
1219         .output_mpeg2_in_188_bytes = 1,
1220
1221         .agc_config_count = 1,
1222         .agc = &dib7070_agc_config,
1223         .bw  = &dib7070_bw_config_12_mhz,
1224         .tuner_is_baseband = 1,
1225         .spur_protect = 1,
1226
1227         .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
1228         .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
1229         .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
1230
1231         .hostbus_diversity = 1,
1232 };
1233
1234 /* STK7070P */
1235 static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
1236 {
1237         struct usb_device_descriptor *p = &adap->dev->udev->descriptor;
1238         if (p->idVendor  == cpu_to_le16(USB_VID_PINNACLE) &&
1239             p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E))
1240                 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
1241         else
1242                 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1243         msleep(10);
1244         dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1245         dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1246         dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1247         dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1248
1249         dib0700_ctrl_clock(adap->dev, 72, 1);
1250
1251         msleep(10);
1252         dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1253         msleep(10);
1254         dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1255
1256         if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
1257                                      &dib7070p_dib7000p_config) != 0) {
1258                 err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
1259                     __func__);
1260                 return -ENODEV;
1261         }
1262
1263         adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
1264                 &dib7070p_dib7000p_config);
1265         return adap->fe == NULL ? -ENODEV : 0;
1266 }
1267
1268 /* STK7070PD */
1269 static struct dib7000p_config stk7070pd_dib7000p_config[2] = {
1270         {
1271                 .output_mpeg2_in_188_bytes = 1,
1272
1273                 .agc_config_count = 1,
1274                 .agc = &dib7070_agc_config,
1275                 .bw  = &dib7070_bw_config_12_mhz,
1276                 .tuner_is_baseband = 1,
1277                 .spur_protect = 1,
1278
1279                 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
1280                 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
1281                 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
1282
1283                 .hostbus_diversity = 1,
1284         }, {
1285                 .output_mpeg2_in_188_bytes = 1,
1286
1287                 .agc_config_count = 1,
1288                 .agc = &dib7070_agc_config,
1289                 .bw  = &dib7070_bw_config_12_mhz,
1290                 .tuner_is_baseband = 1,
1291                 .spur_protect = 1,
1292
1293                 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
1294                 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
1295                 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
1296
1297                 .hostbus_diversity = 1,
1298         }
1299 };
1300
1301 static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap)
1302 {
1303         dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1304         msleep(10);
1305         dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1306         dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1307         dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1308         dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1309
1310         dib0700_ctrl_clock(adap->dev, 72, 1);
1311
1312         msleep(10);
1313         dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1314         msleep(10);
1315         dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1316
1317         if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
1318                                      stk7070pd_dib7000p_config) != 0) {
1319                 err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
1320                     __func__);
1321                 return -ENODEV;
1322         }
1323
1324         adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &stk7070pd_dib7000p_config[0]);
1325         return adap->fe == NULL ? -ENODEV : 0;
1326 }
1327
1328 static int stk7070pd_frontend_attach1(struct dvb_usb_adapter *adap)
1329 {
1330         adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x82, &stk7070pd_dib7000p_config[1]);
1331         return adap->fe == NULL ? -ENODEV : 0;
1332 }
1333
1334 /* S5H1411 */
1335 static struct s5h1411_config pinnacle_801e_config = {
1336         .output_mode   = S5H1411_PARALLEL_OUTPUT,
1337         .gpio          = S5H1411_GPIO_OFF,
1338         .mpeg_timing   = S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK,
1339         .qam_if        = S5H1411_IF_44000,
1340         .vsb_if        = S5H1411_IF_44000,
1341         .inversion     = S5H1411_INVERSION_OFF,
1342         .status_mode   = S5H1411_DEMODLOCKING
1343 };
1344
1345 /* Pinnacle PCTV HD Pro 801e GPIOs map:
1346    GPIO0  - currently unknown
1347    GPIO1  - xc5000 tuner reset
1348    GPIO2  - CX25843 sleep
1349    GPIO3  - currently unknown
1350    GPIO4  - currently unknown
1351    GPIO6  - currently unknown
1352    GPIO7  - currently unknown
1353    GPIO9  - currently unknown
1354    GPIO10 - CX25843 reset
1355  */
1356 static int s5h1411_frontend_attach(struct dvb_usb_adapter *adap)
1357 {
1358         struct dib0700_state *st = adap->dev->priv;
1359
1360         /* Make use of the new i2c functions from FW 1.20 */
1361         st->fw_use_new_i2c_api = 1;
1362
1363         /* The s5h1411 requires the dib0700 to not be in master mode */
1364         st->disable_streaming_master_mode = 1;
1365
1366         /* All msleep values taken from Windows USB trace */
1367         dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0);
1368         dib0700_set_gpio(adap->dev, GPIO3, GPIO_OUT, 0);
1369         dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1370         msleep(400);
1371         dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1372         msleep(60);
1373         dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1374         msleep(30);
1375         dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1376         dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1377         dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1378         dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1379         dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 0);
1380         msleep(30);
1381
1382         /* Put the CX25843 to sleep for now since we're in digital mode */
1383         dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 1);
1384
1385         /* GPIOs are initialized, do the attach */
1386         adap->fe = dvb_attach(s5h1411_attach, &pinnacle_801e_config,
1387                               &adap->dev->i2c_adap);
1388         return adap->fe == NULL ? -ENODEV : 0;
1389 }
1390
1391 static int dib0700_xc5000_tuner_callback(void *priv, int component,
1392                                          int command, int arg)
1393 {
1394         struct dvb_usb_adapter *adap = priv;
1395
1396         if (command == XC5000_TUNER_RESET) {
1397                 /* Reset the tuner */
1398                 dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 0);
1399                 msleep(10);
1400                 dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 1);
1401                 msleep(10);
1402         } else {
1403                 err("xc5000: unknown tuner callback command: %d\n", command);
1404                 return -EINVAL;
1405         }
1406
1407         return 0;
1408 }
1409
1410 static struct xc5000_config s5h1411_xc5000_tunerconfig = {
1411         .i2c_address      = 0x64,
1412         .if_khz           = 5380,
1413 };
1414
1415 static int xc5000_tuner_attach(struct dvb_usb_adapter *adap)
1416 {
1417         /* FIXME: generalize & move to common area */
1418         adap->fe->callback = dib0700_xc5000_tuner_callback;
1419
1420         return dvb_attach(xc5000_attach, adap->fe, &adap->dev->i2c_adap,
1421                           &s5h1411_xc5000_tunerconfig)
1422                 == NULL ? -ENODEV : 0;
1423 }
1424
1425 static struct lgdt3305_config hcw_lgdt3305_config = {
1426         .i2c_addr           = 0x0e,
1427         .mpeg_mode          = LGDT3305_MPEG_PARALLEL,
1428         .tpclk_edge         = LGDT3305_TPCLK_FALLING_EDGE,
1429         .tpvalid_polarity   = LGDT3305_TP_VALID_LOW,
1430         .deny_i2c_rptr      = 0,
1431         .spectral_inversion = 1,
1432         .qam_if_khz         = 6000,
1433         .vsb_if_khz         = 6000,
1434         .usref_8vsb         = 0x0500,
1435 };
1436
1437 static struct mxl5007t_config hcw_mxl5007t_config = {
1438         .xtal_freq_hz = MxL_XTAL_25_MHZ,
1439         .if_freq_hz = MxL_IF_6_MHZ,
1440         .invert_if = 1,
1441 };
1442
1443 /* TIGER-ATSC map:
1444    GPIO0  - LNA_CTR  (H: LNA power enabled, L: LNA power disabled)
1445    GPIO1  - ANT_SEL  (H: VPA, L: MCX)
1446    GPIO4  - SCL2
1447    GPIO6  - EN_TUNER
1448    GPIO7  - SDA2
1449    GPIO10 - DEM_RST
1450
1451    MXL is behind LG's i2c repeater.  LG is on SCL2/SDA2 gpios on the DIB
1452  */
1453 static int lgdt3305_frontend_attach(struct dvb_usb_adapter *adap)
1454 {
1455         struct dib0700_state *st = adap->dev->priv;
1456
1457         /* Make use of the new i2c functions from FW 1.20 */
1458         st->fw_use_new_i2c_api = 1;
1459
1460         st->disable_streaming_master_mode = 1;
1461
1462         /* fe power enable */
1463         dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
1464         msleep(30);
1465         dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1466         msleep(30);
1467
1468         /* demod reset */
1469         dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1470         msleep(30);
1471         dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1472         msleep(30);
1473         dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1474         msleep(30);
1475
1476         adap->fe = dvb_attach(lgdt3305_attach,
1477                               &hcw_lgdt3305_config,
1478                               &adap->dev->i2c_adap);
1479
1480         return adap->fe == NULL ? -ENODEV : 0;
1481 }
1482
1483 static int mxl5007t_tuner_attach(struct dvb_usb_adapter *adap)
1484 {
1485         return dvb_attach(mxl5007t_attach, adap->fe,
1486                           &adap->dev->i2c_adap, 0x60,
1487                           &hcw_mxl5007t_config) == NULL ? -ENODEV : 0;
1488 }
1489
1490
1491 /* DVB-USB and USB stuff follows */
1492 struct usb_device_id dib0700_usb_id_table[] = {
1493 /* 0 */ { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700P) },
1494         { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700P_PC) },
1495         { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500) },
1496         { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_2) },
1497         { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK) },
1498 /* 5 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR) },
1499         { USB_DEVICE(USB_VID_COMPRO,    USB_PID_COMPRO_VIDEOMATE_U500) },
1500         { USB_DEVICE(USB_VID_UNIWILL,   USB_PID_UNIWILL_STK7700P) },
1501         { USB_DEVICE(USB_VID_LEADTEK,   USB_PID_WINFAST_DTV_DONGLE_STK7700P) },
1502         { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_2) },
1503 /* 10 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_2) },
1504         { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV2000E) },
1505         { USB_DEVICE(USB_VID_TERRATEC,
1506                         USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY) },
1507         { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK) },
1508         { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700D) },
1509 /* 15 */{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7070P) },
1510         { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV_DVB_T_FLASH) },
1511         { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7070PD) },
1512         { USB_DEVICE(USB_VID_PINNACLE,
1513                         USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T) },
1514         { USB_DEVICE(USB_VID_COMPRO,    USB_PID_COMPRO_VIDEOMATE_U500_PC) },
1515 /* 20 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_EXPRESS) },
1516         { USB_DEVICE(USB_VID_GIGABYTE,  USB_PID_GIGABYTE_U7000) },
1517         { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14BR) },
1518         { USB_DEVICE(USB_VID_ASUS,      USB_PID_ASUS_U3000) },
1519         { USB_DEVICE(USB_VID_ASUS,      USB_PID_ASUS_U3100) },
1520 /* 25 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_3) },
1521         { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_MYTV_T) },
1522         { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_CINERGY_HT_USB_XE) },
1523         { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_EXPRESSCARD_320CX) },
1524         { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV72E) },
1525 /* 30 */{ USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV73E) },
1526         { USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_EC372S) },
1527         { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_CINERGY_HT_EXPRESS) },
1528         { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_CINERGY_T_XXS) },
1529         { USB_DEVICE(USB_VID_LEADTEK,   USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) },
1530 /* 35 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) },
1531         { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_3) },
1532         { USB_DEVICE(USB_VID_GIGABYTE,  USB_PID_GIGABYTE_U8000) },
1533         { USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_STK7700PH) },
1534         { USB_DEVICE(USB_VID_ASUS,      USB_PID_ASUS_U3000H) },
1535 /* 40 */{ USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV801E) },
1536         { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV801E_SE) },
1537         { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_CINERGY_T_EXPRESS) },
1538         { USB_DEVICE(USB_VID_TERRATEC,
1539                         USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2) },
1540         { USB_DEVICE(USB_VID_SONY,      USB_PID_SONY_PLAYTV) },
1541 /* 45 */{ USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_PD378S) },
1542         { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC) },
1543         { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC_B210) },
1544         { USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_MC770) },
1545         { USB_DEVICE(USB_VID_ELGATO,    USB_PID_ELGATO_EYETV_DTT) },
1546 /* 50 */{ USB_DEVICE(USB_VID_ELGATO,    USB_PID_ELGATO_EYETV_DTT_Dlx) },
1547         { USB_DEVICE(USB_VID_LEADTEK,   USB_PID_WINFAST_DTV_DONGLE_H) },
1548         { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_T3) },
1549         { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_T5) },
1550         { USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_STK7700D) },
1551 /* 55 */{ USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_STK7700D_2) },
1552         { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV73A) },
1553         { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV73ESE) },
1554         { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV282E) },
1555         { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7770P) },
1556         { 0 }           /* Terminating entry */
1557 };
1558 MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
1559
1560 #define DIB0700_DEFAULT_DEVICE_PROPERTIES \
1561         .caps              = DVB_USB_IS_AN_I2C_ADAPTER, \
1562         .usb_ctrl          = DEVICE_SPECIFIC, \
1563         .firmware          = "dvb-usb-dib0700-1.20.fw", \
1564         .download_firmware = dib0700_download_firmware, \
1565         .no_reconnect      = 1, \
1566         .size_of_priv      = sizeof(struct dib0700_state), \
1567         .i2c_algo          = &dib0700_i2c_algo, \
1568         .identify_state    = dib0700_identify_state
1569
1570 #define DIB0700_DEFAULT_STREAMING_CONFIG(ep) \
1571         .streaming_ctrl   = dib0700_streaming_ctrl, \
1572         .stream = { \
1573                 .type = USB_BULK, \
1574                 .count = 4, \
1575                 .endpoint = ep, \
1576                 .u = { \
1577                         .bulk = { \
1578                                 .buffersize = 39480, \
1579                         } \
1580                 } \
1581         }
1582
1583 struct dvb_usb_device_properties dib0700_devices[] = {
1584         {
1585                 DIB0700_DEFAULT_DEVICE_PROPERTIES,
1586
1587                 .num_adapters = 1,
1588                 .adapter = {
1589                         {
1590                                 .frontend_attach  = stk7700p_frontend_attach,
1591                                 .tuner_attach     = stk7700p_tuner_attach,
1592
1593                                 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1594                         },
1595                 },
1596
1597                 .num_device_descs = 8,
1598                 .devices = {
1599                         {   "DiBcom STK7700P reference design",
1600                                 { &dib0700_usb_id_table[0], &dib0700_usb_id_table[1] },
1601                                 { NULL },
1602                         },
1603                         {   "Hauppauge Nova-T Stick",
1604                                 { &dib0700_usb_id_table[4], &dib0700_usb_id_table[9], NULL },
1605                                 { NULL },
1606                         },
1607                         {   "AVerMedia AVerTV DVB-T Volar",
1608                                 { &dib0700_usb_id_table[5], &dib0700_usb_id_table[10] },
1609                                 { NULL },
1610                         },
1611                         {   "Compro Videomate U500",
1612                                 { &dib0700_usb_id_table[6], &dib0700_usb_id_table[19] },
1613                                 { NULL },
1614                         },
1615                         {   "Uniwill STK7700P based (Hama and others)",
1616                                 { &dib0700_usb_id_table[7], NULL },
1617                                 { NULL },
1618                         },
1619                         {   "Leadtek Winfast DTV Dongle (STK7700P based)",
1620                                 { &dib0700_usb_id_table[8], &dib0700_usb_id_table[34] },
1621                                 { NULL },
1622                         },
1623                         {   "AVerMedia AVerTV DVB-T Express",
1624                                 { &dib0700_usb_id_table[20] },
1625                                 { NULL },
1626                         },
1627                         {   "Gigabyte U7000",
1628                                 { &dib0700_usb_id_table[21], NULL },
1629                                 { NULL },
1630                         }
1631                 },
1632
1633                 .rc_interval      = DEFAULT_RC_INTERVAL,
1634                 .rc_key_map       = dib0700_rc_keys,
1635                 .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
1636                 .rc_query         = dib0700_rc_query
1637         }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1638
1639                 .num_adapters = 2,
1640                 .adapter = {
1641                         {
1642                                 .frontend_attach  = bristol_frontend_attach,
1643                                 .tuner_attach     = bristol_tuner_attach,
1644
1645                                 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1646                         }, {
1647                                 .frontend_attach  = bristol_frontend_attach,
1648                                 .tuner_attach     = bristol_tuner_attach,
1649
1650                                 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
1651                         }
1652                 },
1653
1654                 .num_device_descs = 1,
1655                 .devices = {
1656                         {   "Hauppauge Nova-T 500 Dual DVB-T",
1657                                 { &dib0700_usb_id_table[2], &dib0700_usb_id_table[3], NULL },
1658                                 { NULL },
1659                         },
1660                 },
1661
1662                 .rc_interval      = DEFAULT_RC_INTERVAL,
1663                 .rc_key_map       = dib0700_rc_keys,
1664                 .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
1665                 .rc_query         = dib0700_rc_query
1666         }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1667
1668                 .num_adapters = 2,
1669                 .adapter = {
1670                         {
1671                                 .frontend_attach  = stk7700d_frontend_attach,
1672                                 .tuner_attach     = stk7700d_tuner_attach,
1673
1674                                 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1675                         }, {
1676                                 .frontend_attach  = stk7700d_frontend_attach,
1677                                 .tuner_attach     = stk7700d_tuner_attach,
1678
1679                                 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
1680                         }
1681                 },
1682
1683                 .num_device_descs = 5,
1684                 .devices = {
1685                         {   "Pinnacle PCTV 2000e",
1686                                 { &dib0700_usb_id_table[11], NULL },
1687                                 { NULL },
1688                         },
1689                         {   "Terratec Cinergy DT XS Diversity",
1690                                 { &dib0700_usb_id_table[12], NULL },
1691                                 { NULL },
1692                         },
1693                         {   "Hauppauge Nova-TD Stick/Elgato Eye-TV Diversity",
1694                                 { &dib0700_usb_id_table[13], NULL },
1695                                 { NULL },
1696                         },
1697                         {   "DiBcom STK7700D reference design",
1698                                 { &dib0700_usb_id_table[14], NULL },
1699                                 { NULL },
1700                         },
1701                         {   "YUAN High-Tech DiBcom STK7700D",
1702                                 { &dib0700_usb_id_table[55], NULL },
1703                                 { NULL },
1704                         },
1705
1706                 },
1707
1708                 .rc_interval      = DEFAULT_RC_INTERVAL,
1709                 .rc_key_map       = dib0700_rc_keys,
1710                 .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
1711                 .rc_query         = dib0700_rc_query
1712
1713         }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1714
1715                 .num_adapters = 1,
1716                 .adapter = {
1717                         {
1718                                 .frontend_attach  = stk7700P2_frontend_attach,
1719                                 .tuner_attach     = stk7700d_tuner_attach,
1720
1721                                 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1722                         },
1723                 },
1724
1725                 .num_device_descs = 3,
1726                 .devices = {
1727                         {   "ASUS My Cinema U3000 Mini DVBT Tuner",
1728                                 { &dib0700_usb_id_table[23], NULL },
1729                                 { NULL },
1730                         },
1731                         {   "Yuan EC372S",
1732                                 { &dib0700_usb_id_table[31], NULL },
1733                                 { NULL },
1734                         },
1735                         {   "Terratec Cinergy T Express",
1736                                 { &dib0700_usb_id_table[42], NULL },
1737                                 { NULL },
1738                         }
1739                 },
1740
1741                 .rc_interval      = DEFAULT_RC_INTERVAL,
1742                 .rc_key_map       = dib0700_rc_keys,
1743                 .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
1744                 .rc_query         = dib0700_rc_query
1745         }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1746
1747                 .num_adapters = 1,
1748                 .adapter = {
1749                         {
1750                                 .frontend_attach  = stk7070p_frontend_attach,
1751                                 .tuner_attach     = dib7070p_tuner_attach,
1752
1753                                 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1754
1755                                 .size_of_priv     = sizeof(struct dib0700_adapter_state),
1756                         },
1757                 },
1758
1759                 .num_device_descs = 12,
1760                 .devices = {
1761                         {   "DiBcom STK7070P reference design",
1762                                 { &dib0700_usb_id_table[15], NULL },
1763                                 { NULL },
1764                         },
1765                         {   "Pinnacle PCTV DVB-T Flash Stick",
1766                                 { &dib0700_usb_id_table[16], NULL },
1767                                 { NULL },
1768                         },
1769                         {   "Artec T14BR DVB-T",
1770                                 { &dib0700_usb_id_table[22], NULL },
1771                                 { NULL },
1772                         },
1773                         {   "ASUS My Cinema U3100 Mini DVBT Tuner",
1774                                 { &dib0700_usb_id_table[24], NULL },
1775                                 { NULL },
1776                         },
1777                         {   "Hauppauge Nova-T Stick",
1778                                 { &dib0700_usb_id_table[25], NULL },
1779                                 { NULL },
1780                         },
1781                         {   "Hauppauge Nova-T MyTV.t",
1782                                 { &dib0700_usb_id_table[26], NULL },
1783                                 { NULL },
1784                         },
1785                         {   "Pinnacle PCTV 72e",
1786                                 { &dib0700_usb_id_table[29], NULL },
1787                                 { NULL },
1788                         },
1789                         {   "Pinnacle PCTV 73e",
1790                                 { &dib0700_usb_id_table[30], NULL },
1791                                 { NULL },
1792                         },
1793                         {   "Terratec Cinergy T USB XXS/ T3",
1794                                 { &dib0700_usb_id_table[33],
1795                                         &dib0700_usb_id_table[52], NULL },
1796                                 { NULL },
1797                         },
1798                         {   "Elgato EyeTV DTT",
1799                                 { &dib0700_usb_id_table[49], NULL },
1800                                 { NULL },
1801                         },
1802                         {   "Yuan PD378S",
1803                                 { &dib0700_usb_id_table[45], NULL },
1804                                 { NULL },
1805                         },
1806                         {   "Elgato EyeTV Dtt Dlx PD378S",
1807                                 { &dib0700_usb_id_table[50], NULL },
1808                                 { NULL },
1809                         },
1810                 },
1811
1812                 .rc_interval      = DEFAULT_RC_INTERVAL,
1813                 .rc_key_map       = dib0700_rc_keys,
1814                 .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
1815                 .rc_query         = dib0700_rc_query
1816
1817         }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1818
1819                 .num_adapters = 1,
1820                 .adapter = {
1821                         {
1822                                 .frontend_attach  = stk7070p_frontend_attach,
1823                                 .tuner_attach     = dib7070p_tuner_attach,
1824
1825                                 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1826
1827                                 .size_of_priv     = sizeof(struct dib0700_adapter_state),
1828                         },
1829                 },
1830
1831                 .num_device_descs = 3,
1832                 .devices = {
1833                         {   "Pinnacle PCTV 73A",
1834                                 { &dib0700_usb_id_table[56], NULL },
1835                                 { NULL },
1836                         },
1837                         {   "Pinnacle PCTV 73e SE",
1838                                 { &dib0700_usb_id_table[57], NULL },
1839                                 { NULL },
1840                         },
1841                         {   "Pinnacle PCTV 282e",
1842                                 { &dib0700_usb_id_table[58], NULL },
1843                                 { NULL },
1844                         },
1845                 },
1846
1847                 .rc_interval      = DEFAULT_RC_INTERVAL,
1848                 .rc_key_map       = dib0700_rc_keys,
1849                 .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
1850                 .rc_query         = dib0700_rc_query
1851
1852         }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1853
1854                 .num_adapters = 2,
1855                 .adapter = {
1856                         {
1857                                 .frontend_attach  = stk7070pd_frontend_attach0,
1858                                 .tuner_attach     = dib7070p_tuner_attach,
1859
1860                                 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1861
1862                                 .size_of_priv     = sizeof(struct dib0700_adapter_state),
1863                         }, {
1864                                 .frontend_attach  = stk7070pd_frontend_attach1,
1865                                 .tuner_attach     = dib7070p_tuner_attach,
1866
1867                                 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
1868
1869                                 .size_of_priv     = sizeof(struct dib0700_adapter_state),
1870                         }
1871                 },
1872
1873                 .num_device_descs = 6,
1874                 .devices = {
1875                         {   "DiBcom STK7070PD reference design",
1876                                 { &dib0700_usb_id_table[17], NULL },
1877                                 { NULL },
1878                         },
1879                         {   "Pinnacle PCTV Dual DVB-T Diversity Stick",
1880                                 { &dib0700_usb_id_table[18], NULL },
1881                                 { NULL },
1882                         },
1883                         {   "Hauppauge Nova-TD Stick (52009)",
1884                                 { &dib0700_usb_id_table[35], NULL },
1885                                 { NULL },
1886                         },
1887                         {   "Hauppauge Nova-TD-500 (84xxx)",
1888                                 { &dib0700_usb_id_table[36], NULL },
1889                                 { NULL },
1890                         },
1891                         {  "Terratec Cinergy DT USB XS Diversity/ T5",
1892                                 { &dib0700_usb_id_table[43],
1893                                         &dib0700_usb_id_table[53], NULL},
1894                                 { NULL },
1895                         },
1896                         {  "Sony PlayTV",
1897                                 { &dib0700_usb_id_table[44], NULL },
1898                                 { NULL },
1899                         }
1900                 },
1901                 .rc_interval      = DEFAULT_RC_INTERVAL,
1902                 .rc_key_map       = dib0700_rc_keys,
1903                 .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
1904                 .rc_query         = dib0700_rc_query
1905         }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1906
1907                 .num_adapters = 1,
1908                 .adapter = {
1909                         {
1910                                 .frontend_attach  = stk7700ph_frontend_attach,
1911                                 .tuner_attach     = stk7700ph_tuner_attach,
1912
1913                                 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1914
1915                                 .size_of_priv = sizeof(struct
1916                                                 dib0700_adapter_state),
1917                         },
1918                 },
1919
1920                 .num_device_descs = 9,
1921                 .devices = {
1922                         {   "Terratec Cinergy HT USB XE",
1923                                 { &dib0700_usb_id_table[27], NULL },
1924                                 { NULL },
1925                         },
1926                         {   "Pinnacle Expresscard 320cx",
1927                                 { &dib0700_usb_id_table[28], NULL },
1928                                 { NULL },
1929                         },
1930                         {   "Terratec Cinergy HT Express",
1931                                 { &dib0700_usb_id_table[32], NULL },
1932                                 { NULL },
1933                         },
1934                         {   "Gigabyte U8000-RH",
1935                                 { &dib0700_usb_id_table[37], NULL },
1936                                 { NULL },
1937                         },
1938                         {   "YUAN High-Tech STK7700PH",
1939                                 { &dib0700_usb_id_table[38], NULL },
1940                                 { NULL },
1941                         },
1942                         {   "Asus My Cinema-U3000Hybrid",
1943                                 { &dib0700_usb_id_table[39], NULL },
1944                                 { NULL },
1945                         },
1946                         {   "YUAN High-Tech MC770",
1947                                 { &dib0700_usb_id_table[48], NULL },
1948                                 { NULL },
1949                         },
1950                         {   "Leadtek WinFast DTV Dongle H",
1951                                 { &dib0700_usb_id_table[51], NULL },
1952                                 { NULL },
1953                         },
1954                         {   "YUAN High-Tech STK7700D",
1955                                 { &dib0700_usb_id_table[54], NULL },
1956                                 { NULL },
1957                         },
1958                 },
1959                 .rc_interval      = DEFAULT_RC_INTERVAL,
1960                 .rc_key_map       = dib0700_rc_keys,
1961                 .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
1962                 .rc_query         = dib0700_rc_query
1963         }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1964                 .num_adapters = 1,
1965                 .adapter = {
1966                         {
1967                                 .frontend_attach  = s5h1411_frontend_attach,
1968                                 .tuner_attach     = xc5000_tuner_attach,
1969
1970                                 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1971
1972                                 .size_of_priv = sizeof(struct
1973                                                 dib0700_adapter_state),
1974                         },
1975                 },
1976
1977                 .num_device_descs = 2,
1978                 .devices = {
1979                         {   "Pinnacle PCTV HD Pro USB Stick",
1980                                 { &dib0700_usb_id_table[40], NULL },
1981                                 { NULL },
1982                         },
1983                         {   "Pinnacle PCTV HD USB Stick",
1984                                 { &dib0700_usb_id_table[41], NULL },
1985                                 { NULL },
1986                         },
1987                 },
1988                 .rc_interval      = DEFAULT_RC_INTERVAL,
1989                 .rc_key_map       = dib0700_rc_keys,
1990                 .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
1991                 .rc_query         = dib0700_rc_query
1992         }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1993                 .num_adapters = 1,
1994                 .adapter = {
1995                         {
1996                                 .frontend_attach  = lgdt3305_frontend_attach,
1997                                 .tuner_attach     = mxl5007t_tuner_attach,
1998
1999                                 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
2000
2001                                 .size_of_priv = sizeof(struct
2002                                                 dib0700_adapter_state),
2003                         },
2004                 },
2005
2006                 .num_device_descs = 2,
2007                 .devices = {
2008                         {   "Hauppauge ATSC MiniCard (B200)",
2009                                 { &dib0700_usb_id_table[46], NULL },
2010                                 { NULL },
2011                         },
2012                         {   "Hauppauge ATSC MiniCard (B210)",
2013                                 { &dib0700_usb_id_table[47], NULL },
2014                                 { NULL },
2015                         },
2016                 },
2017         }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
2018
2019                 .num_adapters = 1,
2020                 .adapter = {
2021                         {
2022                                 .frontend_attach  = stk7070p_frontend_attach,
2023                                 .tuner_attach     = dib7770p_tuner_attach,
2024
2025                                 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
2026
2027                                 .size_of_priv =
2028                                         sizeof(struct dib0700_adapter_state),
2029                         },
2030                 },
2031
2032                 .num_device_descs = 1,
2033                 .devices = {
2034                         {   "DiBcom STK7770P reference design",
2035                                 { &dib0700_usb_id_table[59], NULL },
2036                                 { NULL },
2037                         },
2038                 },
2039
2040                 .rc_interval      = DEFAULT_RC_INTERVAL,
2041                 .rc_key_map       = dib0700_rc_keys,
2042                 .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
2043                 .rc_query         = dib0700_rc_query
2044         },
2045 };
2046
2047 int dib0700_device_count = ARRAY_SIZE(dib0700_devices);