Merge branch 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied...
[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 (keymap[i].custom == key[3-2] && keymap[i].data == key[3-3]) {
513                                 st->rc_counter = 0;
514                                 *event = keymap[i].event;
515                                 *state = REMOTE_KEY_PRESSED;
516                                 d->last_event = keymap[i].event;
517                                 return 0;
518                         }
519                 }
520                 break;
521         }
522         default: {
523                 /* RC-5 protocol changes toggle bit on new keypress */
524                 for (i = 0; i < d->props.rc_key_map_size; i++) {
525                         if (keymap[i].custom == key[3-2] && keymap[i].data == key[3-3]) {
526                                 if (d->last_event == keymap[i].event &&
527                                         key[3-1] == st->rc_toggle) {
528                                         st->rc_counter++;
529                                         /* prevents unwanted double hits */
530                                         if (st->rc_counter > RC_REPEAT_DELAY) {
531                                                 *event = d->last_event;
532                                                 *state = REMOTE_KEY_PRESSED;
533                                                 st->rc_counter = RC_REPEAT_DELAY;
534                                         }
535
536                                         return 0;
537                                 }
538                                 st->rc_counter = 0;
539                                 *event = keymap[i].event;
540                                 *state = REMOTE_KEY_PRESSED;
541                                 st->rc_toggle = key[3-1];
542                                 d->last_event = keymap[i].event;
543                                 return 0;
544                         }
545                 }
546                 break;
547         }
548         }
549         err("Unknown remote controller key: %2X %2X %2X %2X", (int) key[3-2], (int) key[3-3], (int) key[3-1], (int) key[3]);
550         d->last_event = 0;
551         return 0;
552 }
553
554 /* This is the structure of the RC response packet starting in firmware 1.20 */
555 struct dib0700_rc_response {
556         u8 report_id;
557         u8 data_state;
558         u8 system_msb;
559         u8 system_lsb;
560         u8 data;
561         u8 not_data;
562 };
563
564 /* This supports the new IR response format for firmware v1.20 */
565 static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event,
566                                   int *state)
567 {
568         struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
569         struct dib0700_state *st = d->priv;
570         struct dib0700_rc_response poll_reply;
571         u8 buf[6];
572         int i;
573         int status;
574         int actlen;
575         int found = 0;
576
577         /* Set initial results in case we exit the function early */
578         *event = 0;
579         *state = REMOTE_NO_KEY_PRESSED;
580
581         /* Firmware v1.20 provides RC data via bulk endpoint 1 */
582         status = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, 1), buf,
583                               sizeof(buf), &actlen, 50);
584         if (status < 0) {
585                 /* No data available (meaning no key press) */
586                 return 0;
587         }
588
589         if (actlen != sizeof(buf)) {
590                 /* We didn't get back the 6 byte message we expected */
591                 err("Unexpected RC response size [%d]", actlen);
592                 return -1;
593         }
594
595         poll_reply.report_id  = buf[0];
596         poll_reply.data_state = buf[1];
597         poll_reply.system_msb = buf[2];
598         poll_reply.system_lsb = buf[3];
599         poll_reply.data       = buf[4];
600         poll_reply.not_data   = buf[5];
601
602         /*
603         info("rid=%02x ds=%02x sm=%02x sl=%02x d=%02x nd=%02x\n",
604              poll_reply.report_id, poll_reply.data_state,
605              poll_reply.system_msb, poll_reply.system_lsb,
606              poll_reply.data, poll_reply.not_data);
607         */
608
609         if ((poll_reply.data + poll_reply.not_data) != 0xff) {
610                 /* Key failed integrity check */
611                 err("key failed integrity check: %02x %02x %02x %02x",
612                     poll_reply.system_msb, poll_reply.system_lsb,
613                     poll_reply.data, poll_reply.not_data);
614                 return -1;
615         }
616
617         /* Find the key in the map */
618         for (i = 0; i < d->props.rc_key_map_size; i++) {
619                 if (keymap[i].custom == poll_reply.system_lsb &&
620                     keymap[i].data == poll_reply.data) {
621                         *event = keymap[i].event;
622                         found = 1;
623                         break;
624                 }
625         }
626
627         if (found == 0) {
628                 err("Unknown remote controller key: %02x %02x %02x %02x",
629                     poll_reply.system_msb, poll_reply.system_lsb,
630                     poll_reply.data, poll_reply.not_data);
631                 d->last_event = 0;
632                 return 0;
633         }
634
635         if (poll_reply.data_state == 1) {
636                 /* New key hit */
637                 st->rc_counter = 0;
638                 *event = keymap[i].event;
639                 *state = REMOTE_KEY_PRESSED;
640                 d->last_event = keymap[i].event;
641         } else if (poll_reply.data_state == 2) {
642                 /* Key repeated */
643                 st->rc_counter++;
644
645                 /* prevents unwanted double hits */
646                 if (st->rc_counter > RC_REPEAT_DELAY_V1_20) {
647                         *event = d->last_event;
648                         *state = REMOTE_KEY_PRESSED;
649                         st->rc_counter = RC_REPEAT_DELAY_V1_20;
650                 }
651         } else {
652                 err("Unknown data state [%d]", poll_reply.data_state);
653         }
654
655         return 0;
656 }
657
658 static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
659 {
660         struct dib0700_state *st = d->priv;
661
662         /* Because some people may have improperly named firmware files,
663            let's figure out whether to use the new firmware call or the legacy
664            call based on the firmware version embedded in the file */
665         if (st->rc_func_version == 0) {
666                 u32 hwver, romver, ramver, fwtype;
667                 int ret = dib0700_get_version(d, &hwver, &romver, &ramver,
668                                               &fwtype);
669                 if (ret < 0) {
670                         err("Could not determine version info");
671                         return -1;
672                 }
673                 if (ramver < 0x10200)
674                         st->rc_func_version = 1;
675                 else
676                         st->rc_func_version = 2;
677         }
678
679         if (st->rc_func_version == 2)
680                 return dib0700_rc_query_v1_20(d, event, state);
681         else
682                 return dib0700_rc_query_legacy(d, event, state);
683 }
684
685 static struct dvb_usb_rc_key dib0700_rc_keys[] = {
686         /* Key codes for the tiny Pinnacle remote*/
687         { 0x07, 0x00, KEY_MUTE },
688         { 0x07, 0x01, KEY_MENU }, // Pinnacle logo
689         { 0x07, 0x39, KEY_POWER },
690         { 0x07, 0x03, KEY_VOLUMEUP },
691         { 0x07, 0x09, KEY_VOLUMEDOWN },
692         { 0x07, 0x06, KEY_CHANNELUP },
693         { 0x07, 0x0c, KEY_CHANNELDOWN },
694         { 0x07, 0x0f, KEY_1 },
695         { 0x07, 0x15, KEY_2 },
696         { 0x07, 0x10, KEY_3 },
697         { 0x07, 0x18, KEY_4 },
698         { 0x07, 0x1b, KEY_5 },
699         { 0x07, 0x1e, KEY_6 },
700         { 0x07, 0x11, KEY_7 },
701         { 0x07, 0x21, KEY_8 },
702         { 0x07, 0x12, KEY_9 },
703         { 0x07, 0x27, KEY_0 },
704         { 0x07, 0x24, KEY_SCREEN }, // 'Square' key
705         { 0x07, 0x2a, KEY_TEXT },   // 'T' key
706         { 0x07, 0x2d, KEY_REWIND },
707         { 0x07, 0x30, KEY_PLAY },
708         { 0x07, 0x33, KEY_FASTFORWARD },
709         { 0x07, 0x36, KEY_RECORD },
710         { 0x07, 0x3c, KEY_STOP },
711         { 0x07, 0x3f, KEY_CANCEL }, // '?' key
712         /* Key codes for the Terratec Cinergy DT XS Diversity, similar to cinergyT2.c */
713         { 0xeb, 0x01, KEY_POWER },
714         { 0xeb, 0x02, KEY_1 },
715         { 0xeb, 0x03, KEY_2 },
716         { 0xeb, 0x04, KEY_3 },
717         { 0xeb, 0x05, KEY_4 },
718         { 0xeb, 0x06, KEY_5 },
719         { 0xeb, 0x07, KEY_6 },
720         { 0xeb, 0x08, KEY_7 },
721         { 0xeb, 0x09, KEY_8 },
722         { 0xeb, 0x0a, KEY_9 },
723         { 0xeb, 0x0b, KEY_VIDEO },
724         { 0xeb, 0x0c, KEY_0 },
725         { 0xeb, 0x0d, KEY_REFRESH },
726         { 0xeb, 0x0f, KEY_EPG },
727         { 0xeb, 0x10, KEY_UP },
728         { 0xeb, 0x11, KEY_LEFT },
729         { 0xeb, 0x12, KEY_OK },
730         { 0xeb, 0x13, KEY_RIGHT },
731         { 0xeb, 0x14, KEY_DOWN },
732         { 0xeb, 0x16, KEY_INFO },
733         { 0xeb, 0x17, KEY_RED },
734         { 0xeb, 0x18, KEY_GREEN },
735         { 0xeb, 0x19, KEY_YELLOW },
736         { 0xeb, 0x1a, KEY_BLUE },
737         { 0xeb, 0x1b, KEY_CHANNELUP },
738         { 0xeb, 0x1c, KEY_VOLUMEUP },
739         { 0xeb, 0x1d, KEY_MUTE },
740         { 0xeb, 0x1e, KEY_VOLUMEDOWN },
741         { 0xeb, 0x1f, KEY_CHANNELDOWN },
742         { 0xeb, 0x40, KEY_PAUSE },
743         { 0xeb, 0x41, KEY_HOME },
744         { 0xeb, 0x42, KEY_MENU }, /* DVD Menu */
745         { 0xeb, 0x43, KEY_SUBTITLE },
746         { 0xeb, 0x44, KEY_TEXT }, /* Teletext */
747         { 0xeb, 0x45, KEY_DELETE },
748         { 0xeb, 0x46, KEY_TV },
749         { 0xeb, 0x47, KEY_DVD },
750         { 0xeb, 0x48, KEY_STOP },
751         { 0xeb, 0x49, KEY_VIDEO },
752         { 0xeb, 0x4a, KEY_AUDIO }, /* Music */
753         { 0xeb, 0x4b, KEY_SCREEN }, /* Pic */
754         { 0xeb, 0x4c, KEY_PLAY },
755         { 0xeb, 0x4d, KEY_BACK },
756         { 0xeb, 0x4e, KEY_REWIND },
757         { 0xeb, 0x4f, KEY_FASTFORWARD },
758         { 0xeb, 0x54, KEY_PREVIOUS },
759         { 0xeb, 0x58, KEY_RECORD },
760         { 0xeb, 0x5c, KEY_NEXT },
761
762         /* Key codes for the Haupauge WinTV Nova-TD, copied from nova-t-usb2.c (Nova-T USB2) */
763         { 0x1e, 0x00, KEY_0 },
764         { 0x1e, 0x01, KEY_1 },
765         { 0x1e, 0x02, KEY_2 },
766         { 0x1e, 0x03, KEY_3 },
767         { 0x1e, 0x04, KEY_4 },
768         { 0x1e, 0x05, KEY_5 },
769         { 0x1e, 0x06, KEY_6 },
770         { 0x1e, 0x07, KEY_7 },
771         { 0x1e, 0x08, KEY_8 },
772         { 0x1e, 0x09, KEY_9 },
773         { 0x1e, 0x0a, KEY_KPASTERISK },
774         { 0x1e, 0x0b, KEY_RED },
775         { 0x1e, 0x0c, KEY_RADIO },
776         { 0x1e, 0x0d, KEY_MENU },
777         { 0x1e, 0x0e, KEY_GRAVE }, /* # */
778         { 0x1e, 0x0f, KEY_MUTE },
779         { 0x1e, 0x10, KEY_VOLUMEUP },
780         { 0x1e, 0x11, KEY_VOLUMEDOWN },
781         { 0x1e, 0x12, KEY_CHANNEL },
782         { 0x1e, 0x14, KEY_UP },
783         { 0x1e, 0x15, KEY_DOWN },
784         { 0x1e, 0x16, KEY_LEFT },
785         { 0x1e, 0x17, KEY_RIGHT },
786         { 0x1e, 0x18, KEY_VIDEO },
787         { 0x1e, 0x19, KEY_AUDIO },
788         { 0x1e, 0x1a, KEY_MEDIA },
789         { 0x1e, 0x1b, KEY_EPG },
790         { 0x1e, 0x1c, KEY_TV },
791         { 0x1e, 0x1e, KEY_NEXT },
792         { 0x1e, 0x1f, KEY_BACK },
793         { 0x1e, 0x20, KEY_CHANNELUP },
794         { 0x1e, 0x21, KEY_CHANNELDOWN },
795         { 0x1e, 0x24, KEY_LAST }, /* Skip backwards */
796         { 0x1e, 0x25, KEY_OK },
797         { 0x1e, 0x29, KEY_BLUE},
798         { 0x1e, 0x2e, KEY_GREEN },
799         { 0x1e, 0x30, KEY_PAUSE },
800         { 0x1e, 0x32, KEY_REWIND },
801         { 0x1e, 0x34, KEY_FASTFORWARD },
802         { 0x1e, 0x35, KEY_PLAY },
803         { 0x1e, 0x36, KEY_STOP },
804         { 0x1e, 0x37, KEY_RECORD },
805         { 0x1e, 0x38, KEY_YELLOW },
806         { 0x1e, 0x3b, KEY_GOTO },
807         { 0x1e, 0x3d, KEY_POWER },
808
809         /* Key codes for the Leadtek Winfast DTV Dongle */
810         { 0x00, 0x42, KEY_POWER },
811         { 0x07, 0x7c, KEY_TUNER },
812         { 0x0f, 0x4e, KEY_PRINT }, /* PREVIEW */
813         { 0x08, 0x40, KEY_SCREEN }, /* full screen toggle*/
814         { 0x0f, 0x71, KEY_DOT }, /* frequency */
815         { 0x07, 0x43, KEY_0 },
816         { 0x0c, 0x41, KEY_1 },
817         { 0x04, 0x43, KEY_2 },
818         { 0x0b, 0x7f, KEY_3 },
819         { 0x0e, 0x41, KEY_4 },
820         { 0x06, 0x43, KEY_5 },
821         { 0x09, 0x7f, KEY_6 },
822         { 0x0d, 0x7e, KEY_7 },
823         { 0x05, 0x7c, KEY_8 },
824         { 0x0a, 0x40, KEY_9 },
825         { 0x0e, 0x4e, KEY_CLEAR },
826         { 0x04, 0x7c, KEY_CHANNEL }, /* show channel number */
827         { 0x0f, 0x41, KEY_LAST }, /* recall */
828         { 0x03, 0x42, KEY_MUTE },
829         { 0x06, 0x4c, KEY_RESERVED }, /* PIP button*/
830         { 0x01, 0x72, KEY_SHUFFLE }, /* SNAPSHOT */
831         { 0x0c, 0x4e, KEY_PLAYPAUSE }, /* TIMESHIFT */
832         { 0x0b, 0x70, KEY_RECORD },
833         { 0x03, 0x7d, KEY_VOLUMEUP },
834         { 0x01, 0x7d, KEY_VOLUMEDOWN },
835         { 0x02, 0x42, KEY_CHANNELUP },
836         { 0x00, 0x7d, KEY_CHANNELDOWN },
837
838         /* Key codes for Nova-TD "credit card" remote control. */
839         { 0x1d, 0x00, KEY_0 },
840         { 0x1d, 0x01, KEY_1 },
841         { 0x1d, 0x02, KEY_2 },
842         { 0x1d, 0x03, KEY_3 },
843         { 0x1d, 0x04, KEY_4 },
844         { 0x1d, 0x05, KEY_5 },
845         { 0x1d, 0x06, KEY_6 },
846         { 0x1d, 0x07, KEY_7 },
847         { 0x1d, 0x08, KEY_8 },
848         { 0x1d, 0x09, KEY_9 },
849         { 0x1d, 0x0a, KEY_TEXT },
850         { 0x1d, 0x0d, KEY_MENU },
851         { 0x1d, 0x0f, KEY_MUTE },
852         { 0x1d, 0x10, KEY_VOLUMEUP },
853         { 0x1d, 0x11, KEY_VOLUMEDOWN },
854         { 0x1d, 0x12, KEY_CHANNEL },
855         { 0x1d, 0x14, KEY_UP },
856         { 0x1d, 0x15, KEY_DOWN },
857         { 0x1d, 0x16, KEY_LEFT },
858         { 0x1d, 0x17, KEY_RIGHT },
859         { 0x1d, 0x1c, KEY_TV },
860         { 0x1d, 0x1e, KEY_NEXT },
861         { 0x1d, 0x1f, KEY_BACK },
862         { 0x1d, 0x20, KEY_CHANNELUP },
863         { 0x1d, 0x21, KEY_CHANNELDOWN },
864         { 0x1d, 0x24, KEY_LAST },
865         { 0x1d, 0x25, KEY_OK },
866         { 0x1d, 0x30, KEY_PAUSE },
867         { 0x1d, 0x32, KEY_REWIND },
868         { 0x1d, 0x34, KEY_FASTFORWARD },
869         { 0x1d, 0x35, KEY_PLAY },
870         { 0x1d, 0x36, KEY_STOP },
871         { 0x1d, 0x37, KEY_RECORD },
872         { 0x1d, 0x3b, KEY_GOTO },
873         { 0x1d, 0x3d, KEY_POWER },
874 };
875
876 /* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
877 static struct dibx000_agc_config stk7700p_7000m_mt2060_agc_config = {
878         BAND_UHF | BAND_VHF,       // band_caps
879
880         /* 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,
881          * 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 */
882         (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
883
884         712,  // inv_gain
885         41,  // time_stabiliz
886
887         0,  // alpha_level
888         118,  // thlock
889
890         0,     // wbd_inv
891         4095,  // wbd_ref
892         0,     // wbd_sel
893         0,     // wbd_alpha
894
895         42598,  // agc1_max
896         17694,  // agc1_min
897         45875,  // agc2_max
898         2621,  // agc2_min
899         0,  // agc1_pt1
900         76,  // agc1_pt2
901         139,  // agc1_pt3
902         52,  // agc1_slope1
903         59,  // agc1_slope2
904         107,  // agc2_pt1
905         172,  // agc2_pt2
906         57,  // agc2_slope1
907         70,  // agc2_slope2
908
909         21,  // alpha_mant
910         25,  // alpha_exp
911         28,  // beta_mant
912         48,  // beta_exp
913
914         1,  // perform_agc_softsplit
915         {  0,     // split_min
916            107,   // split_max
917            51800, // global_split_min
918            24700  // global_split_max
919         },
920 };
921
922 static struct dibx000_agc_config stk7700p_7000p_mt2060_agc_config = {
923         BAND_UHF | BAND_VHF,
924
925         /* 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,
926          * 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 */
927         (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
928
929         712, // inv_gain
930         41,  // time_stabiliz
931
932         0,   // alpha_level
933         118, // thlock
934
935         0,    // wbd_inv
936         4095, // wbd_ref
937         0,    // wbd_sel
938         0,    // wbd_alpha
939
940         42598, // agc1_max
941         16384, // agc1_min
942         42598, // agc2_max
943             0, // agc2_min
944
945           0,   // agc1_pt1
946         137,   // agc1_pt2
947         255,   // agc1_pt3
948
949           0,   // agc1_slope1
950         255,   // agc1_slope2
951
952         0,     // agc2_pt1
953         0,     // agc2_pt2
954
955          0,    // agc2_slope1
956         41,    // agc2_slope2
957
958         15, // alpha_mant
959         25, // alpha_exp
960
961         28, // beta_mant
962         48, // beta_exp
963
964         0, // perform_agc_softsplit
965 };
966
967 static struct dibx000_bandwidth_config stk7700p_pll_config = {
968         60000, 30000, // internal, sampling
969         1, 8, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
970         0, 0, 1, 1, 0, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
971         (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
972         60258167, // ifreq
973         20452225, // timf
974         30000000, // xtal
975 };
976
977 static struct dib7000m_config stk7700p_dib7000m_config = {
978         .dvbt_mode = 1,
979         .output_mpeg2_in_188_bytes = 1,
980         .quartz_direct = 1,
981
982         .agc_config_count = 1,
983         .agc = &stk7700p_7000m_mt2060_agc_config,
984         .bw  = &stk7700p_pll_config,
985
986         .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
987         .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
988         .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
989 };
990
991 static struct dib7000p_config stk7700p_dib7000p_config = {
992         .output_mpeg2_in_188_bytes = 1,
993
994         .agc_config_count = 1,
995         .agc = &stk7700p_7000p_mt2060_agc_config,
996         .bw  = &stk7700p_pll_config,
997
998         .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
999         .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
1000         .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
1001 };
1002
1003 static int stk7700p_frontend_attach(struct dvb_usb_adapter *adap)
1004 {
1005         struct dib0700_state *st = adap->dev->priv;
1006         /* unless there is no real power management in DVB - we leave the device on GPIO6 */
1007
1008         dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1009         dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 0); msleep(50);
1010
1011         dib0700_set_gpio(adap->dev, GPIO6,  GPIO_OUT, 1); msleep(10);
1012         dib0700_set_gpio(adap->dev, GPIO9,  GPIO_OUT, 1);
1013
1014         dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10);
1015         dib0700_ctrl_clock(adap->dev, 72, 1);
1016         dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(100);
1017
1018         dib0700_set_gpio(adap->dev,  GPIO0, GPIO_OUT, 1);
1019
1020         st->mt2060_if1[0] = 1220;
1021
1022         if (dib7000pc_detection(&adap->dev->i2c_adap)) {
1023                 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000p_config);
1024                 st->is_dib7000pc = 1;
1025         } else
1026                 adap->fe = dvb_attach(dib7000m_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000m_config);
1027
1028         return adap->fe == NULL ? -ENODEV : 0;
1029 }
1030
1031 static struct mt2060_config stk7700p_mt2060_config = {
1032         0x60
1033 };
1034
1035 static int stk7700p_tuner_attach(struct dvb_usb_adapter *adap)
1036 {
1037         struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap;
1038         struct dib0700_state *st = adap->dev->priv;
1039         struct i2c_adapter *tun_i2c;
1040         s8 a;
1041         int if1=1220;
1042         if (adap->dev->udev->descriptor.idVendor  == cpu_to_le16(USB_VID_HAUPPAUGE) &&
1043                 adap->dev->udev->descriptor.idProduct == cpu_to_le16(USB_PID_HAUPPAUGE_NOVA_T_STICK)) {
1044                 if (!eeprom_read(prim_i2c,0x58,&a)) if1=1220+a;
1045         }
1046         if (st->is_dib7000pc)
1047                 tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
1048         else
1049                 tun_i2c = dib7000m_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
1050
1051         return dvb_attach(mt2060_attach, adap->fe, tun_i2c, &stk7700p_mt2060_config,
1052                 if1) == NULL ? -ENODEV : 0;
1053 }
1054
1055 /* DIB7070 generic */
1056 static struct dibx000_agc_config dib7070_agc_config = {
1057         BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
1058         /* 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,
1059          * 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 */
1060         (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup
1061
1062         600, // inv_gain
1063         10,  // time_stabiliz
1064
1065         0,  // alpha_level
1066         118,  // thlock
1067
1068         0,     // wbd_inv
1069         3530,  // wbd_ref
1070         1,     // wbd_sel
1071         5,     // wbd_alpha
1072
1073         65535,  // agc1_max
1074                 0,  // agc1_min
1075
1076         65535,  // agc2_max
1077         0,      // agc2_min
1078
1079         0,      // agc1_pt1
1080         40,     // agc1_pt2
1081         183,    // agc1_pt3
1082         206,    // agc1_slope1
1083         255,    // agc1_slope2
1084         72,     // agc2_pt1
1085         152,    // agc2_pt2
1086         88,     // agc2_slope1
1087         90,     // agc2_slope2
1088
1089         17,  // alpha_mant
1090         27,  // alpha_exp
1091         23,  // beta_mant
1092         51,  // beta_exp
1093
1094         0,  // perform_agc_softsplit
1095 };
1096
1097 static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
1098 {
1099         return dib7000p_set_gpio(fe, 8, 0, !onoff);
1100 }
1101
1102 static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
1103 {
1104         return dib7000p_set_gpio(fe, 9, 0, onoff);
1105 }
1106
1107 static struct dib0070_config dib7070p_dib0070_config[2] = {
1108         {
1109                 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1110                 .reset = dib7070_tuner_reset,
1111                 .sleep = dib7070_tuner_sleep,
1112                 .clock_khz = 12000,
1113                 .clock_pad_drive = 4
1114         }, {
1115                 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1116                 .reset = dib7070_tuner_reset,
1117                 .sleep = dib7070_tuner_sleep,
1118                 .clock_khz = 12000,
1119
1120         }
1121 };
1122
1123 static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1124 {
1125         struct dvb_usb_adapter *adap = fe->dvb->priv;
1126         struct dib0700_adapter_state *state = adap->priv;
1127
1128         u16 offset;
1129         u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
1130         switch (band) {
1131                 case BAND_VHF: offset = 950; break;
1132                 case BAND_UHF:
1133                 default: offset = 550; break;
1134         }
1135         deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe));
1136         dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
1137         return state->set_param_save(fe, fep);
1138 }
1139
1140 static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap)
1141 {
1142         struct dib0700_adapter_state *st = adap->priv;
1143         struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
1144
1145         if (adap->id == 0) {
1146                 if (dvb_attach(dib0070_attach, adap->fe, tun_i2c, &dib7070p_dib0070_config[0]) == NULL)
1147                         return -ENODEV;
1148         } else {
1149                 if (dvb_attach(dib0070_attach, adap->fe, tun_i2c, &dib7070p_dib0070_config[1]) == NULL)
1150                         return -ENODEV;
1151         }
1152
1153         st->set_param_save = adap->fe->ops.tuner_ops.set_params;
1154         adap->fe->ops.tuner_ops.set_params = dib7070_set_param_override;
1155         return 0;
1156 }
1157
1158 static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
1159         60000, 15000, // internal, sampling
1160         1, 20, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
1161         0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
1162         (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
1163         (0 << 25) | 0, // ifreq = 0.000000 MHz
1164         20452225, // timf
1165         12000000, // xtal_hz
1166 };
1167
1168 static struct dib7000p_config dib7070p_dib7000p_config = {
1169         .output_mpeg2_in_188_bytes = 1,
1170
1171         .agc_config_count = 1,
1172         .agc = &dib7070_agc_config,
1173         .bw  = &dib7070_bw_config_12_mhz,
1174         .tuner_is_baseband = 1,
1175         .spur_protect = 1,
1176
1177         .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
1178         .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
1179         .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
1180
1181         .hostbus_diversity = 1,
1182 };
1183
1184 /* STK7070P */
1185 static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
1186 {
1187         struct usb_device_descriptor *p = &adap->dev->udev->descriptor;
1188         if (p->idVendor  == cpu_to_le16(USB_VID_PINNACLE) &&
1189             p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E))
1190                 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
1191         else
1192                 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1193         msleep(10);
1194         dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1195         dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1196         dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1197         dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1198
1199         dib0700_ctrl_clock(adap->dev, 72, 1);
1200
1201         msleep(10);
1202         dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1203         msleep(10);
1204         dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1205
1206         if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
1207                                      &dib7070p_dib7000p_config) != 0) {
1208                 err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
1209                     __func__);
1210                 return -ENODEV;
1211         }
1212
1213         adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
1214                 &dib7070p_dib7000p_config);
1215         return adap->fe == NULL ? -ENODEV : 0;
1216 }
1217
1218 /* STK7070PD */
1219 static struct dib7000p_config stk7070pd_dib7000p_config[2] = {
1220         {
1221                 .output_mpeg2_in_188_bytes = 1,
1222
1223                 .agc_config_count = 1,
1224                 .agc = &dib7070_agc_config,
1225                 .bw  = &dib7070_bw_config_12_mhz,
1226                 .tuner_is_baseband = 1,
1227                 .spur_protect = 1,
1228
1229                 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
1230                 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
1231                 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
1232
1233                 .hostbus_diversity = 1,
1234         }, {
1235                 .output_mpeg2_in_188_bytes = 1,
1236
1237                 .agc_config_count = 1,
1238                 .agc = &dib7070_agc_config,
1239                 .bw  = &dib7070_bw_config_12_mhz,
1240                 .tuner_is_baseband = 1,
1241                 .spur_protect = 1,
1242
1243                 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
1244                 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
1245                 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
1246
1247                 .hostbus_diversity = 1,
1248         }
1249 };
1250
1251 static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap)
1252 {
1253         dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1254         msleep(10);
1255         dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1256         dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1257         dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1258         dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1259
1260         dib0700_ctrl_clock(adap->dev, 72, 1);
1261
1262         msleep(10);
1263         dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1264         msleep(10);
1265         dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1266
1267         if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
1268                                      stk7070pd_dib7000p_config) != 0) {
1269                 err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
1270                     __func__);
1271                 return -ENODEV;
1272         }
1273
1274         adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &stk7070pd_dib7000p_config[0]);
1275         return adap->fe == NULL ? -ENODEV : 0;
1276 }
1277
1278 static int stk7070pd_frontend_attach1(struct dvb_usb_adapter *adap)
1279 {
1280         adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x82, &stk7070pd_dib7000p_config[1]);
1281         return adap->fe == NULL ? -ENODEV : 0;
1282 }
1283
1284 /* S5H1411 */
1285 static struct s5h1411_config pinnacle_801e_config = {
1286         .output_mode   = S5H1411_PARALLEL_OUTPUT,
1287         .gpio          = S5H1411_GPIO_OFF,
1288         .mpeg_timing   = S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK,
1289         .qam_if        = S5H1411_IF_44000,
1290         .vsb_if        = S5H1411_IF_44000,
1291         .inversion     = S5H1411_INVERSION_OFF,
1292         .status_mode   = S5H1411_DEMODLOCKING
1293 };
1294
1295 /* Pinnacle PCTV HD Pro 801e GPIOs map:
1296    GPIO0  - currently unknown
1297    GPIO1  - xc5000 tuner reset
1298    GPIO2  - CX25843 sleep
1299    GPIO3  - currently unknown
1300    GPIO4  - currently unknown
1301    GPIO6  - currently unknown
1302    GPIO7  - currently unknown
1303    GPIO9  - currently unknown
1304    GPIO10 - CX25843 reset
1305  */
1306 static int s5h1411_frontend_attach(struct dvb_usb_adapter *adap)
1307 {
1308         struct dib0700_state *st = adap->dev->priv;
1309
1310         /* Make use of the new i2c functions from FW 1.20 */
1311         st->fw_use_new_i2c_api = 1;
1312
1313         /* The s5h1411 requires the dib0700 to not be in master mode */
1314         st->disable_streaming_master_mode = 1;
1315
1316         /* All msleep values taken from Windows USB trace */
1317         dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0);
1318         dib0700_set_gpio(adap->dev, GPIO3, GPIO_OUT, 0);
1319         dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1320         msleep(400);
1321         dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1322         msleep(60);
1323         dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1324         msleep(30);
1325         dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1326         dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1327         dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1328         dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1329         dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 0);
1330         msleep(30);
1331
1332         /* Put the CX25843 to sleep for now since we're in digital mode */
1333         dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 1);
1334
1335         /* GPIOs are initialized, do the attach */
1336         adap->fe = dvb_attach(s5h1411_attach, &pinnacle_801e_config,
1337                               &adap->dev->i2c_adap);
1338         return adap->fe == NULL ? -ENODEV : 0;
1339 }
1340
1341 static int dib0700_xc5000_tuner_callback(void *priv, int component,
1342                                          int command, int arg)
1343 {
1344         struct dvb_usb_adapter *adap = priv;
1345
1346         if (command == XC5000_TUNER_RESET) {
1347                 /* Reset the tuner */
1348                 dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 0);
1349                 msleep(330); /* from Windows USB trace */
1350                 dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 1);
1351                 msleep(330); /* from Windows USB trace */
1352         } else {
1353                 err("xc5000: unknown tuner callback command: %d\n", command);
1354                 return -EINVAL;
1355         }
1356
1357         return 0;
1358 }
1359
1360 static struct xc5000_config s5h1411_xc5000_tunerconfig = {
1361         .i2c_address      = 0x64,
1362         .if_khz           = 5380,
1363 };
1364
1365 static int xc5000_tuner_attach(struct dvb_usb_adapter *adap)
1366 {
1367         /* FIXME: generalize & move to common area */
1368         adap->fe->callback = dib0700_xc5000_tuner_callback;
1369
1370         return dvb_attach(xc5000_attach, adap->fe, &adap->dev->i2c_adap,
1371                           &s5h1411_xc5000_tunerconfig)
1372                 == NULL ? -ENODEV : 0;
1373 }
1374
1375 static struct lgdt3305_config hcw_lgdt3305_config = {
1376         .i2c_addr           = 0x0e,
1377         .mpeg_mode          = LGDT3305_MPEG_PARALLEL,
1378         .tpclk_edge         = LGDT3305_TPCLK_FALLING_EDGE,
1379         .tpvalid_polarity   = LGDT3305_TP_VALID_LOW,
1380         .deny_i2c_rptr      = 0,
1381         .spectral_inversion = 1,
1382         .qam_if_khz         = 6000,
1383         .vsb_if_khz         = 6000,
1384         .usref_8vsb         = 0x0500,
1385 };
1386
1387 static struct mxl5007t_config hcw_mxl5007t_config = {
1388         .xtal_freq_hz = MxL_XTAL_25_MHZ,
1389         .if_freq_hz = MxL_IF_6_MHZ,
1390         .invert_if = 1,
1391 };
1392
1393 /* TIGER-ATSC map:
1394    GPIO0  - LNA_CTR  (H: LNA power enabled, L: LNA power disabled)
1395    GPIO1  - ANT_SEL  (H: VPA, L: MCX)
1396    GPIO4  - SCL2
1397    GPIO6  - EN_TUNER
1398    GPIO7  - SDA2
1399    GPIO10 - DEM_RST
1400
1401    MXL is behind LG's i2c repeater.  LG is on SCL2/SDA2 gpios on the DIB
1402  */
1403 static int lgdt3305_frontend_attach(struct dvb_usb_adapter *adap)
1404 {
1405         struct dib0700_state *st = adap->dev->priv;
1406
1407         /* Make use of the new i2c functions from FW 1.20 */
1408         st->fw_use_new_i2c_api = 1;
1409
1410         st->disable_streaming_master_mode = 1;
1411
1412         /* fe power enable */
1413         dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
1414         msleep(30);
1415         dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1416         msleep(30);
1417
1418         /* demod reset */
1419         dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1420         msleep(30);
1421         dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1422         msleep(30);
1423         dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1424         msleep(30);
1425
1426         adap->fe = dvb_attach(lgdt3305_attach,
1427                               &hcw_lgdt3305_config,
1428                               &adap->dev->i2c_adap);
1429
1430         return adap->fe == NULL ? -ENODEV : 0;
1431 }
1432
1433 static int mxl5007t_tuner_attach(struct dvb_usb_adapter *adap)
1434 {
1435         return dvb_attach(mxl5007t_attach, adap->fe,
1436                           &adap->dev->i2c_adap, 0x60,
1437                           &hcw_mxl5007t_config) == NULL ? -ENODEV : 0;
1438 }
1439
1440
1441 /* DVB-USB and USB stuff follows */
1442 struct usb_device_id dib0700_usb_id_table[] = {
1443 /* 0 */ { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700P) },
1444         { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700P_PC) },
1445         { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500) },
1446         { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_2) },
1447         { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK) },
1448 /* 5 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR) },
1449         { USB_DEVICE(USB_VID_COMPRO,    USB_PID_COMPRO_VIDEOMATE_U500) },
1450         { USB_DEVICE(USB_VID_UNIWILL,   USB_PID_UNIWILL_STK7700P) },
1451         { USB_DEVICE(USB_VID_LEADTEK,   USB_PID_WINFAST_DTV_DONGLE_STK7700P) },
1452         { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_2) },
1453 /* 10 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_2) },
1454         { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV2000E) },
1455         { USB_DEVICE(USB_VID_TERRATEC,
1456                         USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY) },
1457         { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK) },
1458         { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700D) },
1459 /* 15 */{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7070P) },
1460         { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV_DVB_T_FLASH) },
1461         { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7070PD) },
1462         { USB_DEVICE(USB_VID_PINNACLE,
1463                         USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T) },
1464         { USB_DEVICE(USB_VID_COMPRO,    USB_PID_COMPRO_VIDEOMATE_U500_PC) },
1465 /* 20 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_EXPRESS) },
1466         { USB_DEVICE(USB_VID_GIGABYTE,  USB_PID_GIGABYTE_U7000) },
1467         { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14BR) },
1468         { USB_DEVICE(USB_VID_ASUS,      USB_PID_ASUS_U3000) },
1469         { USB_DEVICE(USB_VID_ASUS,      USB_PID_ASUS_U3100) },
1470 /* 25 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_3) },
1471         { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_MYTV_T) },
1472         { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_CINERGY_HT_USB_XE) },
1473         { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_EXPRESSCARD_320CX) },
1474         { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV72E) },
1475 /* 30 */{ USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV73E) },
1476         { USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_EC372S) },
1477         { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_CINERGY_HT_EXPRESS) },
1478         { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_CINERGY_T_XXS) },
1479         { USB_DEVICE(USB_VID_LEADTEK,   USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) },
1480 /* 35 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) },
1481         { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_3) },
1482         { USB_DEVICE(USB_VID_GIGABYTE,  USB_PID_GIGABYTE_U8000) },
1483         { USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_STK7700PH) },
1484         { USB_DEVICE(USB_VID_ASUS,      USB_PID_ASUS_U3000H) },
1485 /* 40 */{ USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV801E) },
1486         { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV801E_SE) },
1487         { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_CINERGY_T_EXPRESS) },
1488         { USB_DEVICE(USB_VID_TERRATEC,
1489                         USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2) },
1490         { USB_DEVICE(USB_VID_SONY,      USB_PID_SONY_PLAYTV) },
1491 /* 45 */{ USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_PD378S) },
1492         { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC) },
1493         { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC_B210) },
1494         { USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_MC770) },
1495         { USB_DEVICE(USB_VID_ELGATO,    USB_PID_ELGATO_EYETV_DTT) },
1496         { 0 }           /* Terminating entry */
1497 };
1498 MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
1499
1500 #define DIB0700_DEFAULT_DEVICE_PROPERTIES \
1501         .caps              = DVB_USB_IS_AN_I2C_ADAPTER, \
1502         .usb_ctrl          = DEVICE_SPECIFIC, \
1503         .firmware          = "dvb-usb-dib0700-1.20.fw", \
1504         .download_firmware = dib0700_download_firmware, \
1505         .no_reconnect      = 1, \
1506         .size_of_priv      = sizeof(struct dib0700_state), \
1507         .i2c_algo          = &dib0700_i2c_algo, \
1508         .identify_state    = dib0700_identify_state
1509
1510 #define DIB0700_DEFAULT_STREAMING_CONFIG(ep) \
1511         .streaming_ctrl   = dib0700_streaming_ctrl, \
1512         .stream = { \
1513                 .type = USB_BULK, \
1514                 .count = 4, \
1515                 .endpoint = ep, \
1516                 .u = { \
1517                         .bulk = { \
1518                                 .buffersize = 39480, \
1519                         } \
1520                 } \
1521         }
1522
1523 struct dvb_usb_device_properties dib0700_devices[] = {
1524         {
1525                 DIB0700_DEFAULT_DEVICE_PROPERTIES,
1526
1527                 .num_adapters = 1,
1528                 .adapter = {
1529                         {
1530                                 .frontend_attach  = stk7700p_frontend_attach,
1531                                 .tuner_attach     = stk7700p_tuner_attach,
1532
1533                                 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1534                         },
1535                 },
1536
1537                 .num_device_descs = 8,
1538                 .devices = {
1539                         {   "DiBcom STK7700P reference design",
1540                                 { &dib0700_usb_id_table[0], &dib0700_usb_id_table[1] },
1541                                 { NULL },
1542                         },
1543                         {   "Hauppauge Nova-T Stick",
1544                                 { &dib0700_usb_id_table[4], &dib0700_usb_id_table[9], NULL },
1545                                 { NULL },
1546                         },
1547                         {   "AVerMedia AVerTV DVB-T Volar",
1548                                 { &dib0700_usb_id_table[5], &dib0700_usb_id_table[10] },
1549                                 { NULL },
1550                         },
1551                         {   "Compro Videomate U500",
1552                                 { &dib0700_usb_id_table[6], &dib0700_usb_id_table[19] },
1553                                 { NULL },
1554                         },
1555                         {   "Uniwill STK7700P based (Hama and others)",
1556                                 { &dib0700_usb_id_table[7], NULL },
1557                                 { NULL },
1558                         },
1559                         {   "Leadtek Winfast DTV Dongle (STK7700P based)",
1560                                 { &dib0700_usb_id_table[8], &dib0700_usb_id_table[34] },
1561                                 { NULL },
1562                         },
1563                         {   "AVerMedia AVerTV DVB-T Express",
1564                                 { &dib0700_usb_id_table[20] },
1565                                 { NULL },
1566                         },
1567                         {   "Gigabyte U7000",
1568                                 { &dib0700_usb_id_table[21], NULL },
1569                                 { NULL },
1570                         }
1571                 },
1572
1573                 .rc_interval      = DEFAULT_RC_INTERVAL,
1574                 .rc_key_map       = dib0700_rc_keys,
1575                 .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
1576                 .rc_query         = dib0700_rc_query
1577         }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1578
1579                 .num_adapters = 2,
1580                 .adapter = {
1581                         {
1582                                 .frontend_attach  = bristol_frontend_attach,
1583                                 .tuner_attach     = bristol_tuner_attach,
1584
1585                                 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1586                         }, {
1587                                 .frontend_attach  = bristol_frontend_attach,
1588                                 .tuner_attach     = bristol_tuner_attach,
1589
1590                                 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
1591                         }
1592                 },
1593
1594                 .num_device_descs = 1,
1595                 .devices = {
1596                         {   "Hauppauge Nova-T 500 Dual DVB-T",
1597                                 { &dib0700_usb_id_table[2], &dib0700_usb_id_table[3], NULL },
1598                                 { NULL },
1599                         },
1600                 },
1601
1602                 .rc_interval      = DEFAULT_RC_INTERVAL,
1603                 .rc_key_map       = dib0700_rc_keys,
1604                 .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
1605                 .rc_query         = dib0700_rc_query
1606         }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1607
1608                 .num_adapters = 2,
1609                 .adapter = {
1610                         {
1611                                 .frontend_attach  = stk7700d_frontend_attach,
1612                                 .tuner_attach     = stk7700d_tuner_attach,
1613
1614                                 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1615                         }, {
1616                                 .frontend_attach  = stk7700d_frontend_attach,
1617                                 .tuner_attach     = stk7700d_tuner_attach,
1618
1619                                 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
1620                         }
1621                 },
1622
1623                 .num_device_descs = 4,
1624                 .devices = {
1625                         {   "Pinnacle PCTV 2000e",
1626                                 { &dib0700_usb_id_table[11], NULL },
1627                                 { NULL },
1628                         },
1629                         {   "Terratec Cinergy DT XS Diversity",
1630                                 { &dib0700_usb_id_table[12], NULL },
1631                                 { NULL },
1632                         },
1633                         {   "Hauppauge Nova-TD Stick/Elgato Eye-TV Diversity",
1634                                 { &dib0700_usb_id_table[13], NULL },
1635                                 { NULL },
1636                         },
1637                         {   "DiBcom STK7700D reference design",
1638                                 { &dib0700_usb_id_table[14], NULL },
1639                                 { NULL },
1640                         },
1641
1642                 },
1643
1644                 .rc_interval      = DEFAULT_RC_INTERVAL,
1645                 .rc_key_map       = dib0700_rc_keys,
1646                 .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
1647                 .rc_query         = dib0700_rc_query
1648
1649         }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1650
1651                 .num_adapters = 1,
1652                 .adapter = {
1653                         {
1654                                 .frontend_attach  = stk7700P2_frontend_attach,
1655                                 .tuner_attach     = stk7700d_tuner_attach,
1656
1657                                 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1658                         },
1659                 },
1660
1661                 .num_device_descs = 3,
1662                 .devices = {
1663                         {   "ASUS My Cinema U3000 Mini DVBT Tuner",
1664                                 { &dib0700_usb_id_table[23], NULL },
1665                                 { NULL },
1666                         },
1667                         {   "Yuan EC372S",
1668                                 { &dib0700_usb_id_table[31], NULL },
1669                                 { NULL },
1670                         },
1671                         {   "Terratec Cinergy T Express",
1672                                 { &dib0700_usb_id_table[42], NULL },
1673                                 { NULL },
1674                         }
1675                 },
1676
1677                 .rc_interval      = DEFAULT_RC_INTERVAL,
1678                 .rc_key_map       = dib0700_rc_keys,
1679                 .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
1680                 .rc_query         = dib0700_rc_query
1681         }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1682
1683                 .num_adapters = 1,
1684                 .adapter = {
1685                         {
1686                                 .frontend_attach  = stk7070p_frontend_attach,
1687                                 .tuner_attach     = dib7070p_tuner_attach,
1688
1689                                 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1690
1691                                 .size_of_priv     = sizeof(struct dib0700_adapter_state),
1692                         },
1693                 },
1694
1695                 .num_device_descs = 11,
1696                 .devices = {
1697                         {   "DiBcom STK7070P reference design",
1698                                 { &dib0700_usb_id_table[15], NULL },
1699                                 { NULL },
1700                         },
1701                         {   "Pinnacle PCTV DVB-T Flash Stick",
1702                                 { &dib0700_usb_id_table[16], NULL },
1703                                 { NULL },
1704                         },
1705                         {   "Artec T14BR DVB-T",
1706                                 { &dib0700_usb_id_table[22], NULL },
1707                                 { NULL },
1708                         },
1709                         {   "ASUS My Cinema U3100 Mini DVBT Tuner",
1710                                 { &dib0700_usb_id_table[24], NULL },
1711                                 { NULL },
1712                         },
1713                         {   "Hauppauge Nova-T Stick",
1714                                 { &dib0700_usb_id_table[25], NULL },
1715                                 { NULL },
1716                         },
1717                         {   "Hauppauge Nova-T MyTV.t",
1718                                 { &dib0700_usb_id_table[26], NULL },
1719                                 { NULL },
1720                         },
1721                         {   "Pinnacle PCTV 72e",
1722                                 { &dib0700_usb_id_table[29], NULL },
1723                                 { NULL },
1724                         },
1725                         {   "Pinnacle PCTV 73e",
1726                                 { &dib0700_usb_id_table[30], NULL },
1727                                 { NULL },
1728                         },
1729                         {   "Terratec Cinergy T USB XXS",
1730                                 { &dib0700_usb_id_table[33], NULL },
1731                                 { NULL },
1732                         },
1733                         {   "Elgato EyeTV DTT",
1734                                 { &dib0700_usb_id_table[49], NULL },
1735                                 { NULL },
1736                         },
1737                         {   "Yuan PD378S",
1738                                 { &dib0700_usb_id_table[45], NULL },
1739                                 { NULL },
1740                         },
1741                 },
1742
1743                 .rc_interval      = DEFAULT_RC_INTERVAL,
1744                 .rc_key_map       = dib0700_rc_keys,
1745                 .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
1746                 .rc_query         = dib0700_rc_query
1747
1748         }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1749
1750                 .num_adapters = 2,
1751                 .adapter = {
1752                         {
1753                                 .frontend_attach  = stk7070pd_frontend_attach0,
1754                                 .tuner_attach     = dib7070p_tuner_attach,
1755
1756                                 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1757
1758                                 .size_of_priv     = sizeof(struct dib0700_adapter_state),
1759                         }, {
1760                                 .frontend_attach  = stk7070pd_frontend_attach1,
1761                                 .tuner_attach     = dib7070p_tuner_attach,
1762
1763                                 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
1764
1765                                 .size_of_priv     = sizeof(struct dib0700_adapter_state),
1766                         }
1767                 },
1768
1769                 .num_device_descs = 6,
1770                 .devices = {
1771                         {   "DiBcom STK7070PD reference design",
1772                                 { &dib0700_usb_id_table[17], NULL },
1773                                 { NULL },
1774                         },
1775                         {   "Pinnacle PCTV Dual DVB-T Diversity Stick",
1776                                 { &dib0700_usb_id_table[18], NULL },
1777                                 { NULL },
1778                         },
1779                         {   "Hauppauge Nova-TD Stick (52009)",
1780                                 { &dib0700_usb_id_table[35], NULL },
1781                                 { NULL },
1782                         },
1783                         {   "Hauppauge Nova-TD-500 (84xxx)",
1784                                 { &dib0700_usb_id_table[36], NULL },
1785                                 { NULL },
1786                         },
1787                         {  "Terratec Cinergy DT USB XS Diversity",
1788                                 { &dib0700_usb_id_table[43], NULL },
1789                                 { NULL },
1790                         },
1791                         {  "Sony PlayTV",
1792                                 { &dib0700_usb_id_table[44], NULL },
1793                                 { NULL },
1794                         }
1795                 },
1796                 .rc_interval      = DEFAULT_RC_INTERVAL,
1797                 .rc_key_map       = dib0700_rc_keys,
1798                 .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
1799                 .rc_query         = dib0700_rc_query
1800         }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1801
1802                 .num_adapters = 1,
1803                 .adapter = {
1804                         {
1805                                 .frontend_attach  = stk7700ph_frontend_attach,
1806                                 .tuner_attach     = stk7700ph_tuner_attach,
1807
1808                                 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1809
1810                                 .size_of_priv = sizeof(struct
1811                                                 dib0700_adapter_state),
1812                         },
1813                 },
1814
1815                 .num_device_descs = 7,
1816                 .devices = {
1817                         {   "Terratec Cinergy HT USB XE",
1818                                 { &dib0700_usb_id_table[27], NULL },
1819                                 { NULL },
1820                         },
1821                         {   "Pinnacle Expresscard 320cx",
1822                                 { &dib0700_usb_id_table[28], NULL },
1823                                 { NULL },
1824                         },
1825                         {   "Terratec Cinergy HT Express",
1826                                 { &dib0700_usb_id_table[32], NULL },
1827                                 { NULL },
1828                         },
1829                         {   "Gigabyte U8000-RH",
1830                                 { &dib0700_usb_id_table[37], NULL },
1831                                 { NULL },
1832                         },
1833                         {   "YUAN High-Tech STK7700PH",
1834                                 { &dib0700_usb_id_table[38], NULL },
1835                                 { NULL },
1836                         },
1837                         {   "Asus My Cinema-U3000Hybrid",
1838                                 { &dib0700_usb_id_table[39], NULL },
1839                                 { NULL },
1840                         },
1841                         {   "YUAN High-Tech MC770",
1842                                 { &dib0700_usb_id_table[48], NULL },
1843                                 { NULL },
1844                         },
1845                 },
1846                 .rc_interval      = DEFAULT_RC_INTERVAL,
1847                 .rc_key_map       = dib0700_rc_keys,
1848                 .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
1849                 .rc_query         = dib0700_rc_query
1850         }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1851                 .num_adapters = 1,
1852                 .adapter = {
1853                         {
1854                                 .frontend_attach  = s5h1411_frontend_attach,
1855                                 .tuner_attach     = xc5000_tuner_attach,
1856
1857                                 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1858
1859                                 .size_of_priv = sizeof(struct
1860                                                 dib0700_adapter_state),
1861                         },
1862                 },
1863
1864                 .num_device_descs = 2,
1865                 .devices = {
1866                         {   "Pinnacle PCTV HD Pro USB Stick",
1867                                 { &dib0700_usb_id_table[40], NULL },
1868                                 { NULL },
1869                         },
1870                         {   "Pinnacle PCTV HD USB Stick",
1871                                 { &dib0700_usb_id_table[41], NULL },
1872                                 { NULL },
1873                         },
1874                 },
1875                 .rc_interval      = DEFAULT_RC_INTERVAL,
1876                 .rc_key_map       = dib0700_rc_keys,
1877                 .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
1878                 .rc_query         = dib0700_rc_query
1879         }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1880                 .num_adapters = 1,
1881                 .adapter = {
1882                         {
1883                                 .frontend_attach  = lgdt3305_frontend_attach,
1884                                 .tuner_attach     = mxl5007t_tuner_attach,
1885
1886                                 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1887
1888                                 .size_of_priv = sizeof(struct
1889                                                 dib0700_adapter_state),
1890                         },
1891                 },
1892
1893                 .num_device_descs = 2,
1894                 .devices = {
1895                         {   "Hauppauge ATSC MiniCard (B200)",
1896                                 { &dib0700_usb_id_table[46], NULL },
1897                                 { NULL },
1898                         },
1899                         {   "Hauppauge ATSC MiniCard (B210)",
1900                                 { &dib0700_usb_id_table[47], NULL },
1901                                 { NULL },
1902                         },
1903                 },
1904         },
1905 };
1906
1907 int dib0700_device_count = ARRAY_SIZE(dib0700_devices);