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