V4L/DVB (10823): saa7134: add DVB support for Avermedia A700 cards
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / media / dvb / dvb-usb / dib0700_devices.c
CommitLineData
b7f54910
PB
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 *
b6884a17 7 * Copyright (C) 2005-7 DiBcom, SA
b7f54910
PB
8 */
9#include "dib0700.h"
10
11#include "dib3000mc.h"
91bb9be6 12#include "dib7000m.h"
a75763ff 13#include "dib7000p.h"
b7f54910 14#include "mt2060.h"
54d75eba 15#include "mt2266.h"
6ca8f0b9 16#include "tuner-xc2028.h"
cb22cb52
DH
17#include "xc5000.h"
18#include "s5h1411.h"
01373a5c 19#include "dib0070.h"
b7f54910 20
7fb3fc0c
PB
21static int force_lna_activation;
22module_param(force_lna_activation, int, 0644);
23MODULE_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
01373a5c
PB
26struct dib0700_adapter_state {
27 int (*set_param_save) (struct dvb_frontend *, struct dvb_frontend_parameters *);
28};
29
30/* Hauppauge Nova-T 500 (aka Bristol)
b7f54910
PB
31 * has a LNA on GPIO0 which is enabled by setting 1 */
32static struct mt2060_config bristol_mt2060_config[2] = {
33 {
34 .i2c_address = 0x60,
303cbeaa 35 .clock_out = 3,
b7f54910
PB
36 }, {
37 .i2c_address = 0x61,
38 }
39};
40
99afb989 41
b7f54910
PB
42static struct dibx000_agc_config bristol_dib3000p_mt2060_agc_config = {
43 .band_caps = BAND_VHF | BAND_UHF,
01b4bf31 44 .setup = (1 << 8) | (5 << 5) | (0 << 4) | (0 << 3) | (0 << 2) | (2 << 0),
b7f54910 45
6958effe
PB
46 .agc1_max = 42598,
47 .agc1_min = 17694,
48 .agc2_max = 45875,
49 .agc2_min = 0,
b7f54910 50
6958effe
PB
51 .agc1_pt1 = 0,
52 .agc1_pt2 = 59,
b7f54910 53
6958effe
PB
54 .agc1_slope1 = 0,
55 .agc1_slope2 = 69,
b7f54910
PB
56
57 .agc2_pt1 = 0,
6958effe 58 .agc2_pt2 = 59,
b7f54910 59
6958effe
PB
60 .agc2_slope1 = 111,
61 .agc2_slope2 = 28,
b7f54910
PB
62};
63
64static 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
77static int bristol_frontend_attach(struct dvb_usb_adapter *adap)
78{
6958effe 79 struct dib0700_state *st = adap->dev->priv;
b7f54910
PB
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
7fb3fc0c
PB
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);
6958effe 90
b7f54910
PB
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 }
6958effe
PB
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;
b7f54910
PB
99}
100
4a2b1083 101static int eeprom_read(struct i2c_adapter *adap,u8 adrs,u8 *pval)
c52344fd
OD
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
b7f54910
PB
111static int bristol_tuner_attach(struct dvb_usb_adapter *adap)
112{
c52344fd 113 struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap;
b7f54910 114 struct i2c_adapter *tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe, 1);
c52344fd
OD
115 s8 a;
116 int if1=1220;
da5ee486
AV
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)) {
c52344fd
OD
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;
b7f54910
PB
123}
124
01373a5c 125/* STK7700D: Pinnacle/Terratec/Hauppauge Dual DVB-T Diversity */
54d75eba 126
b6884a17
PB
127/* MT226x */
128static 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 }
54d75eba
OD
208};
209
210static 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
219static struct dib7000p_config stk7700d_dib7000p_mt2266_config[] = {
220 { .output_mpeg2_in_188_bytes = 1,
221 .hostbus_diversity = 1,
222 .tuner_is_baseband = 1,
223
b6884a17
PB
224 .agc_config_count = 2,
225 .agc = stk7700d_7000p_mt2266_agc_config,
54d75eba
OD
226 .bw = &stk7700d_mt2266_pll_config,
227
b6884a17
PB
228 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
229 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
230 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
54d75eba
OD
231 },
232 { .output_mpeg2_in_188_bytes = 1,
233 .hostbus_diversity = 1,
234 .tuner_is_baseband = 1,
235
b6884a17
PB
236 .agc_config_count = 2,
237 .agc = stk7700d_7000p_mt2266_agc_config,
54d75eba
OD
238 .bw = &stk7700d_mt2266_pll_config,
239
b6884a17
PB
240 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
241 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
242 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
54d75eba
OD
243 }
244};
245
246static struct mt2266_config stk7700d_mt2266_config[2] = {
247 { .i2c_address = 0x60
248 },
249 { .i2c_address = 0x60
250 }
251};
252
132c3188
DG
253static 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);
83c4fdf7
DH
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 }
132c3188
DG
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
54d75eba
OD
279static 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);
83c4fdf7
DH
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 }
54d75eba
OD
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
306static 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
6ca8f0b9 314/* STK7700-PH: Digital/Analog Hybrid Tuner, e.h. Cinergy HT USB HE */
b1721d0d 315static struct dibx000_agc_config xc3028_agc_config = {
6ca8f0b9
AC
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 */
b1721d0d 358static struct dibx000_bandwidth_config xc3028_bw_config = {
6ca8f0b9
AC
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
369static 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
d7cba043
MK
382static int stk7700ph_xc3028_callback(void *ptr, int component,
383 int command, int arg)
6ca8f0b9
AC
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
403static struct xc2028_ctrl stk7700ph_xc3028_ctrl = {
404 .fname = XC2028_DEFAULT_FIRMWARE,
405 .max_len = 64,
406 .demod = XC3028_FE_DIBCOM52,
407};
408
409static struct xc2028_config stk7700ph_xc3028_config = {
410 .i2c_addr = 0x61,
6ca8f0b9
AC
411 .ctrl = &stk7700ph_xc3028_ctrl,
412};
413
414static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap)
415{
416 struct usb_device_descriptor *desc = &adap->dev->udev->descriptor;
417
da5ee486
AV
418 if (desc->idVendor == cpu_to_le16(USB_VID_PINNACLE) &&
419 desc->idProduct == cpu_to_le16(USB_PID_PINNACLE_EXPRESSCARD_320CX))
6ca8f0b9
AC
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
83c4fdf7
DH
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 }
6ca8f0b9
AC
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
447static 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;
d7cba043
MK
455
456 /* FIXME: generalize & move to common area */
457 adap->fe->callback = stk7700ph_xc3028_callback;
6ca8f0b9
AC
458
459 return dvb_attach(xc2028_attach, adap->fe, &stk7700ph_xc3028_config)
460 == NULL ? -ENODEV : 0;
461}
462
4b330bee 463#define DEFAULT_RC_INTERVAL 50
54d75eba
OD
464
465static u8 rc_request[] = { REQUEST_POLL_RC, 0 };
466
58e6f95e 467/* Number of keypresses to ignore before start repeating */
4b330bee
DH
468#define RC_REPEAT_DELAY 6
469#define RC_REPEAT_DELAY_V1_20 10
58e6f95e 470
99afb989
DH
471
472
473/* Used by firmware versions < 1.20 (deprecated) */
474static int dib0700_rc_query_legacy(struct dvb_usb_device *d, u32 *event,
475 int *state)
54d75eba
OD
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) {
034d65ed 485 err("RC Query Failed");
89f4267d 486 return -1;
54d75eba 487 }
58e6f95e
PB
488
489 /* losing half of KEY_0 events from Philipps rc5 remotes.. */
54d75eba 490 if (key[0]==0 && key[1]==0 && key[2]==0 && key[3]==0) return 0;
58e6f95e
PB
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 }
54d75eba 509 for (i=0;i<d->props.rc_key_map_size; i++) {
89f4267d 510 if (keymap[i].custom == key[3-2] && keymap[i].data == key[3-3]) {
58e6f95e
PB
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;
54d75eba
OD
537 *event = keymap[i].event;
538 *state = REMOTE_KEY_PRESSED;
58e6f95e
PB
539 st->rc_toggle = key[3-1];
540 d->last_event = keymap[i].event;
54d75eba
OD
541 return 0;
542 }
543 }
58e6f95e
PB
544 break;
545 }
54d75eba 546 }
58e6f95e
PB
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;
54d75eba
OD
549 return 0;
550}
551
99afb989
DH
552/* This is the structure of the RC response packet starting in firmware 1.20 */
553struct 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 */
563static 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
656static 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
82f3d559 683static struct dvb_usb_rc_key dib0700_rc_keys[] = {
54d75eba
OD
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 },
7161f27f 737 { 0xeb, 0x1d, KEY_MUTE },
54d75eba
OD
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 },
7161f27f
JG
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 },
48e6a017
JB
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 },
48aa7391
CR
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 },
82f3d559 872};
54d75eba 873
b7f54910 874/* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
a75763ff 875static struct dibx000_agc_config stk7700p_7000m_mt2060_agc_config = {
69ea31e7
PB
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
a75763ff
PB
920static 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
965static struct dibx000_bandwidth_config stk7700p_pll_config = {
69ea31e7
PB
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
3db78e59 972 30000000, // xtal
69ea31e7
PB
973};
974
975static 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,
a75763ff
PB
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
989static struct dib7000p_config stk7700p_dib7000p_config = {
990 .output_mpeg2_in_188_bytes = 1,
991
b6884a17 992 .agc_config_count = 1,
a75763ff
PB
993 .agc = &stk7700p_7000p_mt2060_agc_config,
994 .bw = &stk7700p_pll_config,
69ea31e7
PB
995
996 .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
997 .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
998 .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
b7f54910
PB
999};
1000
1001static int stk7700p_frontend_attach(struct dvb_usb_adapter *adap)
1002{
69ea31e7 1003 struct dib0700_state *st = adap->dev->priv;
b7f54910 1004 /* unless there is no real power management in DVB - we leave the device on GPIO6 */
a75763ff
PB
1005
1006 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1007 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(50);
1008
69ea31e7 1009 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10);
a75763ff
PB
1010 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1011
b7f54910 1012 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10);
a75763ff
PB
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);
b7f54910 1017
69ea31e7 1018 st->mt2060_if1[0] = 1220;
a75763ff
PB
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;
b7f54910
PB
1027}
1028
69ea31e7
PB
1029static struct mt2060_config stk7700p_mt2060_config = {
1030 0x60
1031};
1032
b7f54910
PB
1033static int stk7700p_tuner_attach(struct dvb_usb_adapter *adap)
1034{
c52344fd 1035 struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap;
69ea31e7 1036 struct dib0700_state *st = adap->dev->priv;
a75763ff 1037 struct i2c_adapter *tun_i2c;
c52344fd
OD
1038 s8 a;
1039 int if1=1220;
da5ee486
AV
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)) {
c52344fd
OD
1042 if (!eeprom_read(prim_i2c,0x58,&a)) if1=1220+a;
1043 }
a75763ff
PB
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,
c52344fd 1050 if1) == NULL ? -ENODEV : 0;
b7f54910
PB
1051}
1052
01373a5c
PB
1053/* DIB7070 generic */
1054static 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
1095static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
1096{
1097 return dib7000p_set_gpio(fe, 8, 0, !onoff);
1098}
1099
1100static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
1101{
1102 return dib7000p_set_gpio(fe, 9, 0, onoff);
1103}
1104
1105static 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
1121static 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
1138static 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
1156static 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
1166static 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,
3cb2c39d
PB
1172 .tuner_is_baseband = 1,
1173 .spur_protect = 1,
01373a5c
PB
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 */
1183static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
1184{
da5ee486
AV
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);
6ca8f0b9 1189 else
da5ee486 1190 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
01373a5c
PB
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
83c4fdf7
DH
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 }
01373a5c 1210
6ca8f0b9
AC
1211 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
1212 &dib7070p_dib7000p_config);
01373a5c
PB
1213 return adap->fe == NULL ? -ENODEV : 0;
1214}
1215
1216/* STK7070PD */
1217static 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,
3cb2c39d
PB
1224 .tuner_is_baseband = 1,
1225 .spur_protect = 1,
01373a5c
PB
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,
3cb2c39d
PB
1238 .tuner_is_baseband = 1,
1239 .spur_protect = 1,
01373a5c
PB
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
1249static 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
83c4fdf7
DH
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 }
01373a5c
PB
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
1276static 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
cb22cb52
DH
1282/* S5H1411 */
1283static 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 */
1304static 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
767f3b3b
MK
1339static int dib0700_xc5000_tuner_callback(void *priv, int component,
1340 int command, int arg)
cb22cb52
DH
1341{
1342 struct dvb_usb_adapter *adap = priv;
1343
79025a9e
DH
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 }
cb22cb52
DH
1354
1355 return 0;
1356}
1357
1358static struct xc5000_config s5h1411_xc5000_tunerconfig = {
1359 .i2c_address = 0x64,
1360 .if_khz = 5380,
cb22cb52
DH
1361};
1362
1363static int xc5000_tuner_attach(struct dvb_usb_adapter *adap)
1364{
79025a9e
DH
1365 /* FIXME: generalize & move to common area */
1366 adap->fe->callback = dib0700_xc5000_tuner_callback;
1367
cb22cb52 1368 return dvb_attach(xc5000_attach, adap->fe, &adap->dev->i2c_adap,
767f3b3b 1369 &s5h1411_xc5000_tunerconfig)
cb22cb52
DH
1370 == NULL ? -ENODEV : 0;
1371}
1372
01373a5c 1373/* DVB-USB and USB stuff follows */
b7f54910 1374struct usb_device_id dib0700_usb_id_table[] = {
01373a5c 1375/* 0 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P) },
6ca8f0b9
AC
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) },
01373a5c 1380/* 5 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR) },
6ca8f0b9
AC
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) },
01373a5c 1385/* 10 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_2) },
6ca8f0b9
AC
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) },
01373a5c 1391/* 15 */{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7070P) },
6ca8f0b9
AC
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) },
fa3b877e 1397/* 20 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_EXPRESS) },
6ca8f0b9
AC
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) },
dc88807e 1410 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS) },
5da4e2c6 1411 { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) },
af2a887c 1412/* 35 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) },
9a0c04a1 1413 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_3) },
17a370bc 1414 { USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U8000) },
8751aaa6 1415 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700PH) },
5769743a 1416 { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000H) },
cb22cb52 1417/* 40 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E) },
d2fc3bfc 1418 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E_SE) },
bb1b082e 1419 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_EXPRESS) },
db4b2d19
NF
1420 { USB_DEVICE(USB_VID_TERRATEC,
1421 USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2) },
6ca8f0b9 1422 { 0 } /* Terminating entry */
b7f54910
PB
1423};
1424MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
1425
1426#define DIB0700_DEFAULT_DEVICE_PROPERTIES \
1427 .caps = DVB_USB_IS_AN_I2C_ADAPTER, \
1428 .usb_ctrl = DEVICE_SPECIFIC, \
bdc203e1 1429 .firmware = "dvb-usb-dib0700-1.20.fw", \
b7f54910 1430 .download_firmware = dib0700_download_firmware, \
6958effe 1431 .no_reconnect = 1, \
b7f54910 1432 .size_of_priv = sizeof(struct dib0700_state), \
6958effe
PB
1433 .i2c_algo = &dib0700_i2c_algo, \
1434 .identify_state = dib0700_identify_state
b7f54910
PB
1435
1436#define DIB0700_DEFAULT_STREAMING_CONFIG(ep) \
1437 .streaming_ctrl = dib0700_streaming_ctrl, \
1438 .stream = { \
1439 .type = USB_BULK, \
1440 .count = 4, \
1441 .endpoint = ep, \
1442 .u = { \
1443 .bulk = { \
1444 .buffersize = 39480, \
1445 } \
1446 } \
1447 }
1448
1449struct dvb_usb_device_properties dib0700_devices[] = {
1450 {
1451 DIB0700_DEFAULT_DEVICE_PROPERTIES,
1452
1453 .num_adapters = 1,
1454 .adapter = {
1455 {
1456 .frontend_attach = stk7700p_frontend_attach,
1457 .tuner_attach = stk7700p_tuner_attach,
1458
1459 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1460 },
1461 },
1462
67053a40 1463 .num_device_descs = 8,
b7f54910
PB
1464 .devices = {
1465 { "DiBcom STK7700P reference design",
49a1376c 1466 { &dib0700_usb_id_table[0], &dib0700_usb_id_table[1] },
b7f54910
PB
1467 { NULL },
1468 },
1469 { "Hauppauge Nova-T Stick",
f9aeba45 1470 { &dib0700_usb_id_table[4], &dib0700_usb_id_table[9], NULL },
b7f54910
PB
1471 { NULL },
1472 },
1473 { "AVerMedia AVerTV DVB-T Volar",
ced8feca 1474 { &dib0700_usb_id_table[5], &dib0700_usb_id_table[10] },
b7f54910
PB
1475 { NULL },
1476 },
49a1376c 1477 { "Compro Videomate U500",
1f8ca4b3 1478 { &dib0700_usb_id_table[6], &dib0700_usb_id_table[19] },
49a1376c 1479 { NULL },
0ce215e1
HS
1480 },
1481 { "Uniwill STK7700P based (Hama and others)",
1482 { &dib0700_usb_id_table[7], NULL },
1483 { NULL },
8637a875
MK
1484 },
1485 { "Leadtek Winfast DTV Dongle (STK7700P based)",
5da4e2c6 1486 { &dib0700_usb_id_table[8], &dib0700_usb_id_table[34] },
8637a875 1487 { NULL },
fa3b877e
JS
1488 },
1489 { "AVerMedia AVerTV DVB-T Express",
1490 { &dib0700_usb_id_table[20] },
1491 { NULL },
67053a40 1492 },
67053a40 1493 { "Gigabyte U7000",
1494 { &dib0700_usb_id_table[21], NULL },
1495 { NULL },
49a1376c 1496 }
b1139e35
DS
1497 },
1498
1499 .rc_interval = DEFAULT_RC_INTERVAL,
1500 .rc_key_map = dib0700_rc_keys,
1501 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
1502 .rc_query = dib0700_rc_query
b7f54910
PB
1503 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1504
1505 .num_adapters = 2,
1506 .adapter = {
1507 {
1508 .frontend_attach = bristol_frontend_attach,
1509 .tuner_attach = bristol_tuner_attach,
1510
1511 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1512 }, {
1513 .frontend_attach = bristol_frontend_attach,
1514 .tuner_attach = bristol_tuner_attach,
1515
1516 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
1517 }
1518 },
1519
1520 .num_device_descs = 1,
1521 .devices = {
1522 { "Hauppauge Nova-T 500 Dual DVB-T",
49a1376c 1523 { &dib0700_usb_id_table[2], &dib0700_usb_id_table[3], NULL },
b7f54910
PB
1524 { NULL },
1525 },
82f3d559
JG
1526 },
1527
1528 .rc_interval = DEFAULT_RC_INTERVAL,
1529 .rc_key_map = dib0700_rc_keys,
8779737b 1530 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
82f3d559 1531 .rc_query = dib0700_rc_query
54d75eba
OD
1532 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1533
1534 .num_adapters = 2,
1535 .adapter = {
1536 {
1537 .frontend_attach = stk7700d_frontend_attach,
1538 .tuner_attach = stk7700d_tuner_attach,
1539
1540 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1541 }, {
1542 .frontend_attach = stk7700d_frontend_attach,
1543 .tuner_attach = stk7700d_tuner_attach,
1544
1545 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
1546 }
1547 },
1548
b6884a17 1549 .num_device_descs = 4,
54d75eba
OD
1550 .devices = {
1551 { "Pinnacle PCTV 2000e",
1552 { &dib0700_usb_id_table[11], NULL },
1553 { NULL },
1554 },
1555 { "Terratec Cinergy DT XS Diversity",
1556 { &dib0700_usb_id_table[12], NULL },
1557 { NULL },
1558 },
faebb914 1559 { "Hauppauge Nova-TD Stick/Elgato Eye-TV Diversity",
54d75eba
OD
1560 { &dib0700_usb_id_table[13], NULL },
1561 { NULL },
1562 },
01373a5c 1563 { "DiBcom STK7700D reference design",
b6884a17
PB
1564 { &dib0700_usb_id_table[14], NULL },
1565 { NULL },
bb1b082e
YA
1566 },
1567
54d75eba 1568 },
82f3d559 1569
54d75eba 1570 .rc_interval = DEFAULT_RC_INTERVAL,
82f3d559 1571 .rc_key_map = dib0700_rc_keys,
8779737b 1572 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
82f3d559 1573 .rc_query = dib0700_rc_query
01373a5c 1574
132c3188
DG
1575 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1576
1577 .num_adapters = 1,
1578 .adapter = {
1579 {
1580 .frontend_attach = stk7700P2_frontend_attach,
1581 .tuner_attach = stk7700d_tuner_attach,
1582
1583 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1584 },
1585 },
1586
bb1b082e 1587 .num_device_descs = 3,
132c3188
DG
1588 .devices = {
1589 { "ASUS My Cinema U3000 Mini DVBT Tuner",
1590 { &dib0700_usb_id_table[23], NULL },
1591 { NULL },
1592 },
6ca8f0b9
AC
1593 { "Yuan EC372S",
1594 { &dib0700_usb_id_table[31], NULL },
1595 { NULL },
bb1b082e
YA
1596 },
1597 { "Terratec Cinergy T Express",
1598 { &dib0700_usb_id_table[42], NULL },
1599 { NULL },
6ca8f0b9 1600 }
48aa7391
CR
1601 },
1602
1603 .rc_interval = DEFAULT_RC_INTERVAL,
1604 .rc_key_map = dib0700_rc_keys,
1605 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
1606 .rc_query = dib0700_rc_query
01373a5c
PB
1607 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1608
1609 .num_adapters = 1,
1610 .adapter = {
1611 {
1612 .frontend_attach = stk7070p_frontend_attach,
1613 .tuner_attach = dib7070p_tuner_attach,
1614
1615 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1616
1617 .size_of_priv = sizeof(struct dib0700_adapter_state),
1618 },
1619 },
1620
dc88807e 1621 .num_device_descs = 9,
01373a5c
PB
1622 .devices = {
1623 { "DiBcom STK7070P reference design",
1624 { &dib0700_usb_id_table[15], NULL },
1625 { NULL },
1626 },
1627 { "Pinnacle PCTV DVB-T Flash Stick",
1628 { &dib0700_usb_id_table[16], NULL },
1629 { NULL },
1630 },
7999a816
YL
1631 { "Artec T14BR DVB-T",
1632 { &dib0700_usb_id_table[22], NULL },
1633 { NULL },
132c3188
DG
1634 },
1635 { "ASUS My Cinema U3100 Mini DVBT Tuner",
1636 { &dib0700_usb_id_table[24], NULL },
1637 { NULL },
1638 },
c7637b1a
TT
1639 { "Hauppauge Nova-T Stick",
1640 { &dib0700_usb_id_table[25], NULL },
1641 { NULL },
1642 },
13b83b5d
DS
1643 { "Hauppauge Nova-T MyTV.t",
1644 { &dib0700_usb_id_table[26], NULL },
1645 { NULL },
1646 },
6ca8f0b9
AC
1647 { "Pinnacle PCTV 72e",
1648 { &dib0700_usb_id_table[29], NULL },
1649 { NULL },
1650 },
1651 { "Pinnacle PCTV 73e",
1652 { &dib0700_usb_id_table[30], NULL },
1653 { NULL },
1654 },
dc88807e
AS
1655 { "Terratec Cinergy T USB XXS",
1656 { &dib0700_usb_id_table[33], NULL },
1657 { NULL },
1658 },
c7637b1a
TT
1659 },
1660
1661 .rc_interval = DEFAULT_RC_INTERVAL,
1662 .rc_key_map = dib0700_rc_keys,
1663 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
1664 .rc_query = dib0700_rc_query
1665
01373a5c
PB
1666 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1667
1668 .num_adapters = 2,
1669 .adapter = {
1670 {
1671 .frontend_attach = stk7070pd_frontend_attach0,
1672 .tuner_attach = dib7070p_tuner_attach,
1673
1674 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1675
1676 .size_of_priv = sizeof(struct dib0700_adapter_state),
1677 }, {
1678 .frontend_attach = stk7070pd_frontend_attach1,
1679 .tuner_attach = dib7070p_tuner_attach,
1680
1681 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
1682
1683 .size_of_priv = sizeof(struct dib0700_adapter_state),
1684 }
1685 },
1686
db4b2d19 1687 .num_device_descs = 5,
01373a5c
PB
1688 .devices = {
1689 { "DiBcom STK7070PD reference design",
1690 { &dib0700_usb_id_table[17], NULL },
1691 { NULL },
1692 },
1693 { "Pinnacle PCTV Dual DVB-T Diversity Stick",
1694 { &dib0700_usb_id_table[18], NULL },
1695 { NULL },
d01eb2dc
MK
1696 },
1697 { "Hauppauge Nova-TD Stick (52009)",
1698 { &dib0700_usb_id_table[35], NULL },
1699 { NULL },
9a0c04a1
MK
1700 },
1701 { "Hauppauge Nova-TD-500 (84xxx)",
1702 { &dib0700_usb_id_table[36], NULL },
1703 { NULL },
db4b2d19
NF
1704 },
1705 { "Terratec Cinergy DT USB XS Diversity",
1706 { &dib0700_usb_id_table[43], NULL },
1707 { NULL },
67053a40 1708 }
c985a8dc
AL
1709 },
1710 .rc_interval = DEFAULT_RC_INTERVAL,
1711 .rc_key_map = dib0700_rc_keys,
1712 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
1713 .rc_query = dib0700_rc_query
6ca8f0b9
AC
1714 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1715
1716 .num_adapters = 1,
1717 .adapter = {
1718 {
1719 .frontend_attach = stk7700ph_frontend_attach,
1720 .tuner_attach = stk7700ph_tuner_attach,
1721
1722 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1723
1724 .size_of_priv = sizeof(struct
1725 dib0700_adapter_state),
1726 },
1727 },
1728
8751aaa6 1729 .num_device_descs = 5,
6ca8f0b9
AC
1730 .devices = {
1731 { "Terratec Cinergy HT USB XE",
1732 { &dib0700_usb_id_table[27], NULL },
1733 { NULL },
1734 },
1735 { "Pinnacle Expresscard 320cx",
1736 { &dib0700_usb_id_table[28], NULL },
1737 { NULL },
1738 },
1739 { "Terratec Cinergy HT Express",
1740 { &dib0700_usb_id_table[32], NULL },
1741 { NULL },
1742 },
17a370bc
FT
1743 { "Gigabyte U8000-RH",
1744 { &dib0700_usb_id_table[37], NULL },
1745 { NULL },
1746 },
8751aaa6
DON
1747 { "YUAN High-Tech STK7700PH",
1748 { &dib0700_usb_id_table[38], NULL },
1749 { NULL },
1750 },
5769743a
AC
1751 { "Asus My Cinema-U3000Hybrid",
1752 { &dib0700_usb_id_table[39], NULL },
1753 { NULL },
1754 },
6ca8f0b9
AC
1755 },
1756 .rc_interval = DEFAULT_RC_INTERVAL,
1757 .rc_key_map = dib0700_rc_keys,
1758 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
1759 .rc_query = dib0700_rc_query
cb22cb52
DH
1760 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1761 .num_adapters = 1,
1762 .adapter = {
1763 {
1764 .frontend_attach = s5h1411_frontend_attach,
1765 .tuner_attach = xc5000_tuner_attach,
1766
1767 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1768
1769 .size_of_priv = sizeof(struct
1770 dib0700_adapter_state),
1771 },
1772 },
1773
d2fc3bfc 1774 .num_device_descs = 2,
cb22cb52
DH
1775 .devices = {
1776 { "Pinnacle PCTV HD Pro USB Stick",
1777 { &dib0700_usb_id_table[40], NULL },
1778 { NULL },
1779 },
d2fc3bfc
DH
1780 { "Pinnacle PCTV HD USB Stick",
1781 { &dib0700_usb_id_table[41], NULL },
1782 { NULL },
1783 },
cb22cb52
DH
1784 },
1785 .rc_interval = DEFAULT_RC_INTERVAL,
1786 .rc_key_map = dib0700_rc_keys,
1787 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
1788 .rc_query = dib0700_rc_query
01373a5c 1789 },
b7f54910
PB
1790};
1791
1792int dib0700_device_count = ARRAY_SIZE(dib0700_devices);