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