Merge branches 'metronomefb', 'pxa-cm2xx', 'pxa-gumstix', 'pxa-misc', 'pxa-mitac...
[linux-2.6] / drivers / media / dvb / dvb-usb / cxusb.c
1 /* DVB USB compliant linux driver for Conexant USB reference design.
2  *
3  * The Conexant reference design I saw on their website was only for analogue
4  * capturing (using the cx25842). The box I took to write this driver (reverse
5  * engineered) is the one labeled Medion MD95700. In addition to the cx25842
6  * for analogue capturing it also has a cx22702 DVB-T demodulator on the main
7  * board. Besides it has a atiremote (X10) and a USB2.0 hub onboard.
8  *
9  * Maybe it is a little bit premature to call this driver cxusb, but I assume
10  * the USB protocol is identical or at least inherited from the reference
11  * design, so it can be reused for the "analogue-only" device (if it will
12  * appear at all).
13  *
14  * TODO: Use the cx25840-driver for the analogue part
15  *
16  * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
17  * Copyright (C) 2006 Michael Krufky (mkrufky@linuxtv.org)
18  * Copyright (C) 2006, 2007 Chris Pascoe (c.pascoe@itee.uq.edu.au)
19  *
20  *   This program is free software; you can redistribute it and/or modify it
21  *   under the terms of the GNU General Public License as published by the Free
22  *   Software Foundation, version 2.
23  *
24  * see Documentation/dvb/README.dvb-usb for more information
25  */
26 #include <media/tuner.h>
27 #include <linux/vmalloc.h>
28
29 #include "cxusb.h"
30
31 #include "cx22702.h"
32 #include "lgdt330x.h"
33 #include "mt352.h"
34 #include "mt352_priv.h"
35 #include "zl10353.h"
36 #include "tuner-xc2028.h"
37 #include "tuner-simple.h"
38 #include "mxl5005s.h"
39
40 /* debug */
41 static int dvb_usb_cxusb_debug;
42 module_param_named(debug, dvb_usb_cxusb_debug, int, 0644);
43 MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
44
45 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
46
47 #define deb_info(args...)   dprintk(dvb_usb_cxusb_debug, 0x03, args)
48 #define deb_i2c(args...)    dprintk(dvb_usb_cxusb_debug, 0x02, args)
49
50 static int cxusb_ctrl_msg(struct dvb_usb_device *d,
51                           u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
52 {
53         int wo = (rbuf == NULL || rlen == 0); /* write-only */
54         u8 sndbuf[1+wlen];
55         memset(sndbuf, 0, 1+wlen);
56
57         sndbuf[0] = cmd;
58         memcpy(&sndbuf[1], wbuf, wlen);
59         if (wo)
60                 return dvb_usb_generic_write(d, sndbuf, 1+wlen);
61         else
62                 return dvb_usb_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen, 0);
63 }
64
65 /* GPIO */
66 static void cxusb_gpio_tuner(struct dvb_usb_device *d, int onoff)
67 {
68         struct cxusb_state *st = d->priv;
69         u8 o[2], i;
70
71         if (st->gpio_write_state[GPIO_TUNER] == onoff)
72                 return;
73
74         o[0] = GPIO_TUNER;
75         o[1] = onoff;
76         cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
77
78         if (i != 0x01)
79                 deb_info("gpio_write failed.\n");
80
81         st->gpio_write_state[GPIO_TUNER] = onoff;
82 }
83
84 static int cxusb_bluebird_gpio_rw(struct dvb_usb_device *d, u8 changemask,
85                                  u8 newval)
86 {
87         u8 o[2], gpio_state;
88         int rc;
89
90         o[0] = 0xff & ~changemask;      /* mask of bits to keep */
91         o[1] = newval & changemask;     /* new values for bits  */
92
93         rc = cxusb_ctrl_msg(d, CMD_BLUEBIRD_GPIO_RW, o, 2, &gpio_state, 1);
94         if (rc < 0 || (gpio_state & changemask) != (newval & changemask))
95                 deb_info("bluebird_gpio_write failed.\n");
96
97         return rc < 0 ? rc : gpio_state;
98 }
99
100 static void cxusb_bluebird_gpio_pulse(struct dvb_usb_device *d, u8 pin, int low)
101 {
102         cxusb_bluebird_gpio_rw(d, pin, low ? 0 : pin);
103         msleep(5);
104         cxusb_bluebird_gpio_rw(d, pin, low ? pin : 0);
105 }
106
107 static void cxusb_nano2_led(struct dvb_usb_device *d, int onoff)
108 {
109         cxusb_bluebird_gpio_rw(d, 0x40, onoff ? 0 : 0x40);
110 }
111
112 /* I2C */
113 static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
114                           int num)
115 {
116         struct dvb_usb_device *d = i2c_get_adapdata(adap);
117         int i;
118
119         if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
120                 return -EAGAIN;
121
122         for (i = 0; i < num; i++) {
123
124                 if (d->udev->descriptor.idVendor == USB_VID_MEDION)
125                         switch (msg[i].addr) {
126                         case 0x63:
127                                 cxusb_gpio_tuner(d, 0);
128                                 break;
129                         default:
130                                 cxusb_gpio_tuner(d, 1);
131                                 break;
132                         }
133
134                 if (msg[i].flags & I2C_M_RD) {
135                         /* read only */
136                         u8 obuf[3], ibuf[1+msg[i].len];
137                         obuf[0] = 0;
138                         obuf[1] = msg[i].len;
139                         obuf[2] = msg[i].addr;
140                         if (cxusb_ctrl_msg(d, CMD_I2C_READ,
141                                            obuf, 3,
142                                            ibuf, 1+msg[i].len) < 0) {
143                                 warn("i2c read failed");
144                                 break;
145                         }
146                         memcpy(msg[i].buf, &ibuf[1], msg[i].len);
147                 } else if (i+1 < num && (msg[i+1].flags & I2C_M_RD) &&
148                            msg[i].addr == msg[i+1].addr) {
149                         /* write to then read from same address */
150                         u8 obuf[3+msg[i].len], ibuf[1+msg[i+1].len];
151                         obuf[0] = msg[i].len;
152                         obuf[1] = msg[i+1].len;
153                         obuf[2] = msg[i].addr;
154                         memcpy(&obuf[3], msg[i].buf, msg[i].len);
155
156                         if (cxusb_ctrl_msg(d, CMD_I2C_READ,
157                                            obuf, 3+msg[i].len,
158                                            ibuf, 1+msg[i+1].len) < 0)
159                                 break;
160
161                         if (ibuf[0] != 0x08)
162                                 deb_i2c("i2c read may have failed\n");
163
164                         memcpy(msg[i+1].buf, &ibuf[1], msg[i+1].len);
165
166                         i++;
167                 } else {
168                         /* write only */
169                         u8 obuf[2+msg[i].len], ibuf;
170                         obuf[0] = msg[i].addr;
171                         obuf[1] = msg[i].len;
172                         memcpy(&obuf[2], msg[i].buf, msg[i].len);
173
174                         if (cxusb_ctrl_msg(d, CMD_I2C_WRITE, obuf,
175                                            2+msg[i].len, &ibuf,1) < 0)
176                                 break;
177                         if (ibuf != 0x08)
178                                 deb_i2c("i2c write may have failed\n");
179                 }
180         }
181
182         mutex_unlock(&d->i2c_mutex);
183         return i == num ? num : -EREMOTEIO;
184 }
185
186 static u32 cxusb_i2c_func(struct i2c_adapter *adapter)
187 {
188         return I2C_FUNC_I2C;
189 }
190
191 static struct i2c_algorithm cxusb_i2c_algo = {
192         .master_xfer   = cxusb_i2c_xfer,
193         .functionality = cxusb_i2c_func,
194 };
195
196 static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff)
197 {
198         u8 b = 0;
199         if (onoff)
200                 return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
201         else
202                 return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0);
203 }
204
205 static int cxusb_aver_power_ctrl(struct dvb_usb_device *d, int onoff)
206 {
207         int ret;
208         if (!onoff)
209                 return cxusb_ctrl_msg(d, CMD_POWER_OFF, NULL, 0, NULL, 0);
210         if (d->state == DVB_USB_STATE_INIT &&
211             usb_set_interface(d->udev, 0, 0) < 0)
212                 err("set interface failed");
213         do {} while (!(ret = cxusb_ctrl_msg(d, CMD_POWER_ON, NULL, 0, NULL, 0)) &&
214                    !(ret = cxusb_ctrl_msg(d, 0x15, NULL, 0, NULL, 0)) &&
215                    !(ret = cxusb_ctrl_msg(d, 0x17, NULL, 0, NULL, 0)) && 0);
216         if (!ret) {
217                 /* FIXME: We don't know why, but we need to configure the
218                  * lgdt3303 with the register settings below on resume */
219                 int i;
220                 u8 buf, bufs[] = {
221                         0x0e, 0x2, 0x00, 0x7f,
222                         0x0e, 0x2, 0x02, 0xfe,
223                         0x0e, 0x2, 0x02, 0x01,
224                         0x0e, 0x2, 0x00, 0x03,
225                         0x0e, 0x2, 0x0d, 0x40,
226                         0x0e, 0x2, 0x0e, 0x87,
227                         0x0e, 0x2, 0x0f, 0x8e,
228                         0x0e, 0x2, 0x10, 0x01,
229                         0x0e, 0x2, 0x14, 0xd7,
230                         0x0e, 0x2, 0x47, 0x88,
231                 };
232                 msleep(20);
233                 for (i = 0; i < sizeof(bufs)/sizeof(u8); i += 4/sizeof(u8)) {
234                         ret = cxusb_ctrl_msg(d, CMD_I2C_WRITE,
235                                              bufs+i, 4, &buf, 1);
236                         if (ret)
237                                 break;
238                         if (buf != 0x8)
239                                 return -EREMOTEIO;
240                 }
241         }
242         return ret;
243 }
244
245 static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff)
246 {
247         u8 b = 0;
248         if (onoff)
249                 return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
250         else
251                 return 0;
252 }
253
254 static int cxusb_nano2_power_ctrl(struct dvb_usb_device *d, int onoff)
255 {
256         int rc = 0;
257
258         rc = cxusb_power_ctrl(d, onoff);
259         if (!onoff)
260                 cxusb_nano2_led(d, 0);
261
262         return rc;
263 }
264
265 static int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
266 {
267         u8 buf[2] = { 0x03, 0x00 };
268         if (onoff)
269                 cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON, buf, 2, NULL, 0);
270         else
271                 cxusb_ctrl_msg(adap->dev, CMD_STREAMING_OFF, NULL, 0, NULL, 0);
272
273         return 0;
274 }
275
276 static int cxusb_aver_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
277 {
278         if (onoff)
279                 cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_ON, NULL, 0, NULL, 0);
280         else
281                 cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_OFF,
282                                NULL, 0, NULL, 0);
283         return 0;
284 }
285
286 static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
287 {
288         struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
289         u8 ircode[4];
290         int i;
291
292         cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4);
293
294         *event = 0;
295         *state = REMOTE_NO_KEY_PRESSED;
296
297         for (i = 0; i < d->props.rc_key_map_size; i++) {
298                 if (keymap[i].custom == ircode[2] &&
299                     keymap[i].data == ircode[3]) {
300                         *event = keymap[i].event;
301                         *state = REMOTE_KEY_PRESSED;
302
303                         return 0;
304                 }
305         }
306
307         return 0;
308 }
309
310 static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event,
311                                     int *state)
312 {
313         struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
314         u8 ircode[4];
315         int i;
316         struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
317                                .buf = ircode, .len = 4 };
318
319         *event = 0;
320         *state = REMOTE_NO_KEY_PRESSED;
321
322         if (cxusb_i2c_xfer(&d->i2c_adap, &msg, 1) != 1)
323                 return 0;
324
325         for (i = 0; i < d->props.rc_key_map_size; i++) {
326                 if (keymap[i].custom == ircode[1] &&
327                     keymap[i].data == ircode[2]) {
328                         *event = keymap[i].event;
329                         *state = REMOTE_KEY_PRESSED;
330
331                         return 0;
332                 }
333         }
334
335         return 0;
336 }
337
338 static struct dvb_usb_rc_key dvico_mce_rc_keys[] = {
339         { 0xfe, 0x02, KEY_TV },
340         { 0xfe, 0x0e, KEY_MP3 },
341         { 0xfe, 0x1a, KEY_DVD },
342         { 0xfe, 0x1e, KEY_FAVORITES },
343         { 0xfe, 0x16, KEY_SETUP },
344         { 0xfe, 0x46, KEY_POWER2 },
345         { 0xfe, 0x0a, KEY_EPG },
346         { 0xfe, 0x49, KEY_BACK },
347         { 0xfe, 0x4d, KEY_MENU },
348         { 0xfe, 0x51, KEY_UP },
349         { 0xfe, 0x5b, KEY_LEFT },
350         { 0xfe, 0x5f, KEY_RIGHT },
351         { 0xfe, 0x53, KEY_DOWN },
352         { 0xfe, 0x5e, KEY_OK },
353         { 0xfe, 0x59, KEY_INFO },
354         { 0xfe, 0x55, KEY_TAB },
355         { 0xfe, 0x0f, KEY_PREVIOUSSONG },/* Replay */
356         { 0xfe, 0x12, KEY_NEXTSONG },   /* Skip */
357         { 0xfe, 0x42, KEY_ENTER  },     /* Windows/Start */
358         { 0xfe, 0x15, KEY_VOLUMEUP },
359         { 0xfe, 0x05, KEY_VOLUMEDOWN },
360         { 0xfe, 0x11, KEY_CHANNELUP },
361         { 0xfe, 0x09, KEY_CHANNELDOWN },
362         { 0xfe, 0x52, KEY_CAMERA },
363         { 0xfe, 0x5a, KEY_TUNER },      /* Live */
364         { 0xfe, 0x19, KEY_OPEN },
365         { 0xfe, 0x0b, KEY_1 },
366         { 0xfe, 0x17, KEY_2 },
367         { 0xfe, 0x1b, KEY_3 },
368         { 0xfe, 0x07, KEY_4 },
369         { 0xfe, 0x50, KEY_5 },
370         { 0xfe, 0x54, KEY_6 },
371         { 0xfe, 0x48, KEY_7 },
372         { 0xfe, 0x4c, KEY_8 },
373         { 0xfe, 0x58, KEY_9 },
374         { 0xfe, 0x13, KEY_ANGLE },      /* Aspect */
375         { 0xfe, 0x03, KEY_0 },
376         { 0xfe, 0x1f, KEY_ZOOM },
377         { 0xfe, 0x43, KEY_REWIND },
378         { 0xfe, 0x47, KEY_PLAYPAUSE },
379         { 0xfe, 0x4f, KEY_FASTFORWARD },
380         { 0xfe, 0x57, KEY_MUTE },
381         { 0xfe, 0x0d, KEY_STOP },
382         { 0xfe, 0x01, KEY_RECORD },
383         { 0xfe, 0x4e, KEY_POWER },
384 };
385
386 static struct dvb_usb_rc_key dvico_portable_rc_keys[] = {
387         { 0xfc, 0x02, KEY_SETUP },       /* Profile */
388         { 0xfc, 0x43, KEY_POWER2 },
389         { 0xfc, 0x06, KEY_EPG },
390         { 0xfc, 0x5a, KEY_BACK },
391         { 0xfc, 0x05, KEY_MENU },
392         { 0xfc, 0x47, KEY_INFO },
393         { 0xfc, 0x01, KEY_TAB },
394         { 0xfc, 0x42, KEY_PREVIOUSSONG },/* Replay */
395         { 0xfc, 0x49, KEY_VOLUMEUP },
396         { 0xfc, 0x09, KEY_VOLUMEDOWN },
397         { 0xfc, 0x54, KEY_CHANNELUP },
398         { 0xfc, 0x0b, KEY_CHANNELDOWN },
399         { 0xfc, 0x16, KEY_CAMERA },
400         { 0xfc, 0x40, KEY_TUNER },      /* ATV/DTV */
401         { 0xfc, 0x45, KEY_OPEN },
402         { 0xfc, 0x19, KEY_1 },
403         { 0xfc, 0x18, KEY_2 },
404         { 0xfc, 0x1b, KEY_3 },
405         { 0xfc, 0x1a, KEY_4 },
406         { 0xfc, 0x58, KEY_5 },
407         { 0xfc, 0x59, KEY_6 },
408         { 0xfc, 0x15, KEY_7 },
409         { 0xfc, 0x14, KEY_8 },
410         { 0xfc, 0x17, KEY_9 },
411         { 0xfc, 0x44, KEY_ANGLE },      /* Aspect */
412         { 0xfc, 0x55, KEY_0 },
413         { 0xfc, 0x07, KEY_ZOOM },
414         { 0xfc, 0x0a, KEY_REWIND },
415         { 0xfc, 0x08, KEY_PLAYPAUSE },
416         { 0xfc, 0x4b, KEY_FASTFORWARD },
417         { 0xfc, 0x5b, KEY_MUTE },
418         { 0xfc, 0x04, KEY_STOP },
419         { 0xfc, 0x56, KEY_RECORD },
420         { 0xfc, 0x57, KEY_POWER },
421         { 0xfc, 0x41, KEY_UNKNOWN },    /* INPUT */
422         { 0xfc, 0x00, KEY_UNKNOWN },    /* HD */
423 };
424
425 static int cxusb_dee1601_demod_init(struct dvb_frontend* fe)
426 {
427         static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x28 };
428         static u8 reset []         = { RESET,      0x80 };
429         static u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
430         static u8 agc_cfg []       = { AGC_TARGET, 0x28, 0x20 };
431         static u8 gpp_ctl_cfg []   = { GPP_CTL,    0x33 };
432         static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
433
434         mt352_write(fe, clock_config,   sizeof(clock_config));
435         udelay(200);
436         mt352_write(fe, reset,          sizeof(reset));
437         mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
438
439         mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
440         mt352_write(fe, gpp_ctl_cfg,    sizeof(gpp_ctl_cfg));
441         mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
442
443         return 0;
444 }
445
446 static int cxusb_mt352_demod_init(struct dvb_frontend* fe)
447 {       /* used in both lgz201 and th7579 */
448         static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x29 };
449         static u8 reset []         = { RESET,      0x80 };
450         static u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
451         static u8 agc_cfg []       = { AGC_TARGET, 0x24, 0x20 };
452         static u8 gpp_ctl_cfg []   = { GPP_CTL,    0x33 };
453         static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
454
455         mt352_write(fe, clock_config,   sizeof(clock_config));
456         udelay(200);
457         mt352_write(fe, reset,          sizeof(reset));
458         mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
459
460         mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
461         mt352_write(fe, gpp_ctl_cfg,    sizeof(gpp_ctl_cfg));
462         mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
463         return 0;
464 }
465
466 static struct cx22702_config cxusb_cx22702_config = {
467         .demod_address = 0x63,
468         .output_mode = CX22702_PARALLEL_OUTPUT,
469 };
470
471 static struct lgdt330x_config cxusb_lgdt3303_config = {
472         .demod_address = 0x0e,
473         .demod_chip    = LGDT3303,
474 };
475
476 static struct lgdt330x_config cxusb_aver_lgdt3303_config = {
477         .demod_address       = 0x0e,
478         .demod_chip          = LGDT3303,
479         .clock_polarity_flip = 2,
480 };
481
482 static struct mt352_config cxusb_dee1601_config = {
483         .demod_address = 0x0f,
484         .demod_init    = cxusb_dee1601_demod_init,
485 };
486
487 static struct zl10353_config cxusb_zl10353_dee1601_config = {
488         .demod_address = 0x0f,
489         .parallel_ts = 1,
490 };
491
492 static struct mt352_config cxusb_mt352_config = {
493         /* used in both lgz201 and th7579 */
494         .demod_address = 0x0f,
495         .demod_init    = cxusb_mt352_demod_init,
496 };
497
498 static struct zl10353_config cxusb_zl10353_xc3028_config = {
499         .demod_address = 0x0f,
500         .if2 = 45600,
501         .no_tuner = 1,
502         .parallel_ts = 1,
503 };
504
505 static struct mt352_config cxusb_mt352_xc3028_config = {
506         .demod_address = 0x0f,
507         .if2 = 4560,
508         .no_tuner = 1,
509         .demod_init = cxusb_mt352_demod_init,
510 };
511
512 /* FIXME: needs tweaking */
513 static struct mxl5005s_config aver_a868r_tuner = {
514         .i2c_address     = 0x63,
515         .if_freq         = 6000000UL,
516         .xtal_freq       = CRYSTAL_FREQ_16000000HZ,
517         .agc_mode        = MXL_SINGLE_AGC,
518         .tracking_filter = MXL_TF_C,
519         .rssi_enable     = MXL_RSSI_ENABLE,
520         .cap_select      = MXL_CAP_SEL_ENABLE,
521         .div_out         = MXL_DIV_OUT_4,
522         .clock_out       = MXL_CLOCK_OUT_DISABLE,
523         .output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
524         .top             = MXL5005S_TOP_25P2,
525         .mod_mode        = MXL_DIGITAL_MODE,
526         .if_mode         = MXL_ZERO_IF,
527         .AgcMasterByte   = 0x00,
528 };
529
530 /* Callbacks for DVB USB */
531 static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
532 {
533         dvb_attach(simple_tuner_attach, adap->fe,
534                    &adap->dev->i2c_adap, 0x61,
535                    TUNER_PHILIPS_FMD1216ME_MK3);
536         return 0;
537 }
538
539 static int cxusb_dee1601_tuner_attach(struct dvb_usb_adapter *adap)
540 {
541         dvb_attach(dvb_pll_attach, adap->fe, 0x61,
542                    NULL, DVB_PLL_THOMSON_DTT7579);
543         return 0;
544 }
545
546 static int cxusb_lgz201_tuner_attach(struct dvb_usb_adapter *adap)
547 {
548         dvb_attach(dvb_pll_attach, adap->fe, 0x61, NULL, DVB_PLL_LG_Z201);
549         return 0;
550 }
551
552 static int cxusb_dtt7579_tuner_attach(struct dvb_usb_adapter *adap)
553 {
554         dvb_attach(dvb_pll_attach, adap->fe, 0x60,
555                    NULL, DVB_PLL_THOMSON_DTT7579);
556         return 0;
557 }
558
559 static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap)
560 {
561         dvb_attach(simple_tuner_attach, adap->fe,
562                    &adap->dev->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF);
563         return 0;
564 }
565
566 static int dvico_bluebird_xc2028_callback(void *ptr, int command, int arg)
567 {
568         struct dvb_usb_adapter *adap = ptr;
569         struct dvb_usb_device *d = adap->dev;
570
571         switch (command) {
572         case XC2028_TUNER_RESET:
573                 deb_info("%s: XC2028_TUNER_RESET %d\n", __func__, arg);
574                 cxusb_bluebird_gpio_pulse(d, 0x01, 1);
575                 break;
576         case XC2028_RESET_CLK:
577                 deb_info("%s: XC2028_RESET_CLK %d\n", __func__, arg);
578                 break;
579         default:
580                 deb_info("%s: unknown command %d, arg %d\n", __func__,
581                          command, arg);
582                 return -EINVAL;
583         }
584
585         return 0;
586 }
587
588 static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap)
589 {
590         struct dvb_frontend      *fe;
591         struct xc2028_config      cfg = {
592                 .i2c_adap  = &adap->dev->i2c_adap,
593                 .i2c_addr  = 0x61,
594                 .callback  = dvico_bluebird_xc2028_callback,
595         };
596         static struct xc2028_ctrl ctl = {
597                 .fname       = "xc3028-v27.fw",
598                 .max_len     = 64,
599                 .demod       = XC3028_FE_ZARLINK456,
600         };
601
602         fe = dvb_attach(xc2028_attach, adap->fe, &cfg);
603         if (fe == NULL || fe->ops.tuner_ops.set_config == NULL)
604                 return -EIO;
605
606         fe->ops.tuner_ops.set_config(fe, &ctl);
607
608         return 0;
609 }
610
611 static int cxusb_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
612 {
613         dvb_attach(mxl5005s_attach, adap->fe,
614                    &adap->dev->i2c_adap, &aver_a868r_tuner);
615         return 0;
616 }
617
618 static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap)
619 {
620         u8 b;
621         if (usb_set_interface(adap->dev->udev, 0, 6) < 0)
622                 err("set interface failed");
623
624         cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, &b, 1);
625
626         if ((adap->fe = dvb_attach(cx22702_attach, &cxusb_cx22702_config,
627                                    &adap->dev->i2c_adap)) != NULL)
628                 return 0;
629
630         return -EIO;
631 }
632
633 static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
634 {
635         if (usb_set_interface(adap->dev->udev, 0, 7) < 0)
636                 err("set interface failed");
637
638         cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
639
640         if ((adap->fe = dvb_attach(lgdt330x_attach, &cxusb_lgdt3303_config,
641                                    &adap->dev->i2c_adap)) != NULL)
642                 return 0;
643
644         return -EIO;
645 }
646
647 static int cxusb_aver_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
648 {
649         adap->fe = dvb_attach(lgdt330x_attach, &cxusb_aver_lgdt3303_config,
650                               &adap->dev->i2c_adap);
651         if (adap->fe != NULL)
652                 return 0;
653
654         return -EIO;
655 }
656
657 static int cxusb_mt352_frontend_attach(struct dvb_usb_adapter *adap)
658 {
659         /* used in both lgz201 and th7579 */
660         if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
661                 err("set interface failed");
662
663         cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
664
665         if ((adap->fe = dvb_attach(mt352_attach, &cxusb_mt352_config,
666                                    &adap->dev->i2c_adap)) != NULL)
667                 return 0;
668
669         return -EIO;
670 }
671
672 static int cxusb_dee1601_frontend_attach(struct dvb_usb_adapter *adap)
673 {
674         if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
675                 err("set interface failed");
676
677         cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
678
679         if (((adap->fe = dvb_attach(mt352_attach, &cxusb_dee1601_config,
680                                     &adap->dev->i2c_adap)) != NULL) ||
681                 ((adap->fe = dvb_attach(zl10353_attach,
682                                         &cxusb_zl10353_dee1601_config,
683                                         &adap->dev->i2c_adap)) != NULL))
684                 return 0;
685
686         return -EIO;
687 }
688
689 static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap)
690 {
691         u8 ircode[4];
692         int i;
693         struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
694                                .buf = ircode, .len = 4 };
695
696         if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
697                 err("set interface failed");
698
699         cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
700
701         /* reset the tuner and demodulator */
702         cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
703         cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
704         cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
705
706         if ((adap->fe = dvb_attach(zl10353_attach,
707                                    &cxusb_zl10353_xc3028_config,
708                                    &adap->dev->i2c_adap)) == NULL)
709                 return -EIO;
710
711         /* try to determine if there is no IR decoder on the I2C bus */
712         for (i = 0; adap->dev->props.rc_key_map != NULL && i < 5; i++) {
713                 msleep(20);
714                 if (cxusb_i2c_xfer(&adap->dev->i2c_adap, &msg, 1) != 1)
715                         goto no_IR;
716                 if (ircode[0] == 0 && ircode[1] == 0)
717                         continue;
718                 if (ircode[2] + ircode[3] != 0xff) {
719 no_IR:
720                         adap->dev->props.rc_key_map = NULL;
721                         info("No IR receiver detected on this device.");
722                         break;
723                 }
724         }
725
726         return 0;
727 }
728
729 static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap)
730 {
731         if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
732                 err("set interface failed");
733
734         cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
735
736         /* reset the tuner and demodulator */
737         cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
738         cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
739         cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
740
741         if ((adap->fe = dvb_attach(zl10353_attach,
742                                    &cxusb_zl10353_xc3028_config,
743                                    &adap->dev->i2c_adap)) != NULL)
744                 return 0;
745
746         if ((adap->fe = dvb_attach(mt352_attach,
747                                    &cxusb_mt352_xc3028_config,
748                                    &adap->dev->i2c_adap)) != NULL)
749                 return 0;
750
751         return -EIO;
752 }
753
754 /*
755  * DViCO has shipped two devices with the same USB ID, but only one of them
756  * needs a firmware download.  Check the device class details to see if they
757  * have non-default values to decide whether the device is actually cold or
758  * not, and forget a match if it turns out we selected the wrong device.
759  */
760 static int bluebird_fx2_identify_state(struct usb_device *udev,
761                                        struct dvb_usb_device_properties *props,
762                                        struct dvb_usb_device_description **desc,
763                                        int *cold)
764 {
765         int wascold = *cold;
766
767         *cold = udev->descriptor.bDeviceClass == 0xff &&
768                 udev->descriptor.bDeviceSubClass == 0xff &&
769                 udev->descriptor.bDeviceProtocol == 0xff;
770
771         if (*cold && !wascold)
772                 *desc = NULL;
773
774         return 0;
775 }
776
777 /*
778  * DViCO bluebird firmware needs the "warm" product ID to be patched into the
779  * firmware file before download.
780  */
781
782 static const int dvico_firmware_id_offsets[] = { 6638, 3204 };
783 static int bluebird_patch_dvico_firmware_download(struct usb_device *udev,
784                                                   const struct firmware *fw)
785 {
786         int pos;
787
788         for (pos = 0; pos < ARRAY_SIZE(dvico_firmware_id_offsets); pos++) {
789                 int idoff = dvico_firmware_id_offsets[pos];
790
791                 if (fw->size < idoff + 4)
792                         continue;
793
794                 if (fw->data[idoff] == (USB_VID_DVICO & 0xff) &&
795                     fw->data[idoff + 1] == USB_VID_DVICO >> 8) {
796                         struct firmware new_fw;
797                         u8 *new_fw_data = vmalloc(fw->size);
798                         int ret;
799
800                         if (!new_fw_data)
801                                 return -ENOMEM;
802
803                         memcpy(new_fw_data, fw->data, fw->size);
804                         new_fw.size = fw->size;
805                         new_fw.data = new_fw_data;
806
807                         new_fw_data[idoff + 2] =
808                                 le16_to_cpu(udev->descriptor.idProduct) + 1;
809                         new_fw_data[idoff + 3] =
810                                 le16_to_cpu(udev->descriptor.idProduct) >> 8;
811
812                         ret = usb_cypress_load_firmware(udev, &new_fw,
813                                                         CYPRESS_FX2);
814                         vfree(new_fw_data);
815                         return ret;
816                 }
817         }
818
819         return -EINVAL;
820 }
821
822 /* DVB USB Driver stuff */
823 static struct dvb_usb_device_properties cxusb_medion_properties;
824 static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties;
825 static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties;
826 static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties;
827 static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties;
828 static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties;
829 static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties;
830 static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties;
831 static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
832
833 static int cxusb_probe(struct usb_interface *intf,
834                        const struct usb_device_id *id)
835 {
836         if (0 == dvb_usb_device_init(intf, &cxusb_medion_properties,
837                                      THIS_MODULE, NULL, adapter_nr) ||
838             0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgh064f_properties,
839                                      THIS_MODULE, NULL, adapter_nr) ||
840             0 == dvb_usb_device_init(intf, &cxusb_bluebird_dee1601_properties,
841                                      THIS_MODULE, NULL, adapter_nr) ||
842             0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgz201_properties,
843                                      THIS_MODULE, NULL, adapter_nr) ||
844             0 == dvb_usb_device_init(intf, &cxusb_bluebird_dtt7579_properties,
845                                      THIS_MODULE, NULL, adapter_nr) ||
846             0 == dvb_usb_device_init(intf, &cxusb_bluebird_dualdig4_properties,
847                                      THIS_MODULE, NULL, adapter_nr) ||
848             0 == dvb_usb_device_init(intf, &cxusb_bluebird_nano2_properties,
849                                      THIS_MODULE, NULL, adapter_nr) ||
850             0 == dvb_usb_device_init(intf,
851                                 &cxusb_bluebird_nano2_needsfirmware_properties,
852                                      THIS_MODULE, NULL, adapter_nr) ||
853             0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties,
854                                      THIS_MODULE, NULL, adapter_nr) ||
855             0)
856                 return 0;
857
858         return -EINVAL;
859 }
860
861 static struct usb_device_id cxusb_table [] = {
862         { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) },
863         { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) },
864         { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_WARM) },
865         { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_COLD) },
866         { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM) },
867         { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_COLD) },
868         { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_WARM) },
869         { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_COLD) },
870         { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_WARM) },
871         { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD) },
872         { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM) },
873         { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD) },
874         { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM) },
875         { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) },
876         { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) },
877         { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) },
878         { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) },
879         {}              /* Terminating entry */
880 };
881 MODULE_DEVICE_TABLE (usb, cxusb_table);
882
883 static struct dvb_usb_device_properties cxusb_medion_properties = {
884         .caps = DVB_USB_IS_AN_I2C_ADAPTER,
885
886         .usb_ctrl = CYPRESS_FX2,
887
888         .size_of_priv     = sizeof(struct cxusb_state),
889
890         .num_adapters = 1,
891         .adapter = {
892                 {
893                         .streaming_ctrl   = cxusb_streaming_ctrl,
894                         .frontend_attach  = cxusb_cx22702_frontend_attach,
895                         .tuner_attach     = cxusb_fmd1216me_tuner_attach,
896                         /* parameter for the MPEG2-data transfer */
897                                         .stream = {
898                                                 .type = USB_BULK,
899                                 .count = 5,
900                                 .endpoint = 0x02,
901                                 .u = {
902                                         .bulk = {
903                                                 .buffersize = 8192,
904                                         }
905                                 }
906                         },
907
908                 },
909         },
910         .power_ctrl       = cxusb_power_ctrl,
911
912         .i2c_algo         = &cxusb_i2c_algo,
913
914         .generic_bulk_ctrl_endpoint = 0x01,
915
916         .num_device_descs = 1,
917         .devices = {
918                 {   "Medion MD95700 (MDUSBTV-HYBRID)",
919                         { NULL },
920                         { &cxusb_table[0], NULL },
921                 },
922         }
923 };
924
925 static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = {
926         .caps = DVB_USB_IS_AN_I2C_ADAPTER,
927
928         .usb_ctrl          = DEVICE_SPECIFIC,
929         .firmware          = "dvb-usb-bluebird-01.fw",
930         .download_firmware = bluebird_patch_dvico_firmware_download,
931         /* use usb alt setting 0 for EP4 transfer (dvb-t),
932            use usb alt setting 7 for EP2 transfer (atsc) */
933
934         .size_of_priv     = sizeof(struct cxusb_state),
935
936         .num_adapters = 1,
937         .adapter = {
938                 {
939                         .streaming_ctrl   = cxusb_streaming_ctrl,
940                         .frontend_attach  = cxusb_lgdt3303_frontend_attach,
941                         .tuner_attach     = cxusb_lgh064f_tuner_attach,
942
943                         /* parameter for the MPEG2-data transfer */
944                                         .stream = {
945                                                 .type = USB_BULK,
946                                 .count = 5,
947                                 .endpoint = 0x02,
948                                 .u = {
949                                         .bulk = {
950                                                 .buffersize = 8192,
951                                         }
952                                 }
953                         },
954                 },
955         },
956
957         .power_ctrl       = cxusb_bluebird_power_ctrl,
958
959         .i2c_algo         = &cxusb_i2c_algo,
960
961         .rc_interval      = 100,
962         .rc_key_map       = dvico_portable_rc_keys,
963         .rc_key_map_size  = ARRAY_SIZE(dvico_portable_rc_keys),
964         .rc_query         = cxusb_rc_query,
965
966         .generic_bulk_ctrl_endpoint = 0x01,
967
968         .num_device_descs = 1,
969         .devices = {
970                 {   "DViCO FusionHDTV5 USB Gold",
971                         { &cxusb_table[1], NULL },
972                         { &cxusb_table[2], NULL },
973                 },
974         }
975 };
976
977 static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = {
978         .caps = DVB_USB_IS_AN_I2C_ADAPTER,
979
980         .usb_ctrl          = DEVICE_SPECIFIC,
981         .firmware          = "dvb-usb-bluebird-01.fw",
982         .download_firmware = bluebird_patch_dvico_firmware_download,
983         /* use usb alt setting 0 for EP4 transfer (dvb-t),
984            use usb alt setting 7 for EP2 transfer (atsc) */
985
986         .size_of_priv     = sizeof(struct cxusb_state),
987
988         .num_adapters = 1,
989         .adapter = {
990                 {
991                         .streaming_ctrl   = cxusb_streaming_ctrl,
992                         .frontend_attach  = cxusb_dee1601_frontend_attach,
993                         .tuner_attach     = cxusb_dee1601_tuner_attach,
994                         /* parameter for the MPEG2-data transfer */
995                         .stream = {
996                                 .type = USB_BULK,
997                                 .count = 5,
998                                 .endpoint = 0x04,
999                                 .u = {
1000                                         .bulk = {
1001                                                 .buffersize = 8192,
1002                                         }
1003                                 }
1004                         },
1005                 },
1006         },
1007
1008         .power_ctrl       = cxusb_bluebird_power_ctrl,
1009
1010         .i2c_algo         = &cxusb_i2c_algo,
1011
1012         .rc_interval      = 150,
1013         .rc_key_map       = dvico_mce_rc_keys,
1014         .rc_key_map_size  = ARRAY_SIZE(dvico_mce_rc_keys),
1015         .rc_query         = cxusb_rc_query,
1016
1017         .generic_bulk_ctrl_endpoint = 0x01,
1018
1019         .num_device_descs = 3,
1020         .devices = {
1021                 {   "DViCO FusionHDTV DVB-T Dual USB",
1022                         { &cxusb_table[3], NULL },
1023                         { &cxusb_table[4], NULL },
1024                 },
1025                 {   "DigitalNow DVB-T Dual USB",
1026                         { &cxusb_table[9],  NULL },
1027                         { &cxusb_table[10], NULL },
1028                 },
1029                 {   "DViCO FusionHDTV DVB-T Dual Digital 2",
1030                         { &cxusb_table[11], NULL },
1031                         { &cxusb_table[12], NULL },
1032                 },
1033         }
1034 };
1035
1036 static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = {
1037         .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1038
1039         .usb_ctrl          = DEVICE_SPECIFIC,
1040         .firmware          = "dvb-usb-bluebird-01.fw",
1041         .download_firmware = bluebird_patch_dvico_firmware_download,
1042         /* use usb alt setting 0 for EP4 transfer (dvb-t),
1043            use usb alt setting 7 for EP2 transfer (atsc) */
1044
1045         .size_of_priv     = sizeof(struct cxusb_state),
1046
1047         .num_adapters = 2,
1048         .adapter = {
1049                 {
1050                         .streaming_ctrl   = cxusb_streaming_ctrl,
1051                         .frontend_attach  = cxusb_mt352_frontend_attach,
1052                         .tuner_attach     = cxusb_lgz201_tuner_attach,
1053
1054                         /* parameter for the MPEG2-data transfer */
1055                         .stream = {
1056                                 .type = USB_BULK,
1057                                 .count = 5,
1058                                 .endpoint = 0x04,
1059                                 .u = {
1060                                         .bulk = {
1061                                                 .buffersize = 8192,
1062                                         }
1063                                 }
1064                         },
1065                 },
1066         },
1067         .power_ctrl       = cxusb_bluebird_power_ctrl,
1068
1069         .i2c_algo         = &cxusb_i2c_algo,
1070
1071         .rc_interval      = 100,
1072         .rc_key_map       = dvico_portable_rc_keys,
1073         .rc_key_map_size  = ARRAY_SIZE(dvico_portable_rc_keys),
1074         .rc_query         = cxusb_rc_query,
1075
1076         .generic_bulk_ctrl_endpoint = 0x01,
1077         .num_device_descs = 1,
1078         .devices = {
1079                 {   "DViCO FusionHDTV DVB-T USB (LGZ201)",
1080                         { &cxusb_table[5], NULL },
1081                         { &cxusb_table[6], NULL },
1082                 },
1083         }
1084 };
1085
1086 static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = {
1087         .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1088
1089         .usb_ctrl          = DEVICE_SPECIFIC,
1090         .firmware          = "dvb-usb-bluebird-01.fw",
1091         .download_firmware = bluebird_patch_dvico_firmware_download,
1092         /* use usb alt setting 0 for EP4 transfer (dvb-t),
1093            use usb alt setting 7 for EP2 transfer (atsc) */
1094
1095         .size_of_priv     = sizeof(struct cxusb_state),
1096
1097         .num_adapters = 1,
1098         .adapter = {
1099                 {
1100                         .streaming_ctrl   = cxusb_streaming_ctrl,
1101                         .frontend_attach  = cxusb_mt352_frontend_attach,
1102                         .tuner_attach     = cxusb_dtt7579_tuner_attach,
1103
1104                         /* parameter for the MPEG2-data transfer */
1105                         .stream = {
1106                                 .type = USB_BULK,
1107                                 .count = 5,
1108                                 .endpoint = 0x04,
1109                                 .u = {
1110                                         .bulk = {
1111                                                 .buffersize = 8192,
1112                                         }
1113                                 }
1114                         },
1115                 },
1116         },
1117         .power_ctrl       = cxusb_bluebird_power_ctrl,
1118
1119         .i2c_algo         = &cxusb_i2c_algo,
1120
1121         .rc_interval      = 100,
1122         .rc_key_map       = dvico_portable_rc_keys,
1123         .rc_key_map_size  = ARRAY_SIZE(dvico_portable_rc_keys),
1124         .rc_query         = cxusb_rc_query,
1125
1126         .generic_bulk_ctrl_endpoint = 0x01,
1127
1128         .num_device_descs = 1,
1129         .devices = {
1130                 {   "DViCO FusionHDTV DVB-T USB (TH7579)",
1131                         { &cxusb_table[7], NULL },
1132                         { &cxusb_table[8], NULL },
1133                 },
1134         }
1135 };
1136
1137 static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = {
1138         .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1139
1140         .usb_ctrl         = CYPRESS_FX2,
1141
1142         .size_of_priv     = sizeof(struct cxusb_state),
1143
1144         .num_adapters = 1,
1145         .adapter = {
1146                 {
1147                         .streaming_ctrl   = cxusb_streaming_ctrl,
1148                         .frontend_attach  = cxusb_dualdig4_frontend_attach,
1149                         .tuner_attach     = cxusb_dvico_xc3028_tuner_attach,
1150                         /* parameter for the MPEG2-data transfer */
1151                         .stream = {
1152                                 .type = USB_BULK,
1153                                 .count = 5,
1154                                 .endpoint = 0x02,
1155                                 .u = {
1156                                         .bulk = {
1157                                                 .buffersize = 8192,
1158                                         }
1159                                 }
1160                         },
1161                 },
1162         },
1163
1164         .power_ctrl       = cxusb_power_ctrl,
1165
1166         .i2c_algo         = &cxusb_i2c_algo,
1167
1168         .generic_bulk_ctrl_endpoint = 0x01,
1169
1170         .rc_interval      = 100,
1171         .rc_key_map       = dvico_mce_rc_keys,
1172         .rc_key_map_size  = ARRAY_SIZE(dvico_mce_rc_keys),
1173         .rc_query         = cxusb_bluebird2_rc_query,
1174
1175         .num_device_descs = 1,
1176         .devices = {
1177                 {   "DViCO FusionHDTV DVB-T Dual Digital 4",
1178                         { NULL },
1179                         { &cxusb_table[13], NULL },
1180                 },
1181         }
1182 };
1183
1184 static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = {
1185         .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1186
1187         .usb_ctrl         = CYPRESS_FX2,
1188         .identify_state   = bluebird_fx2_identify_state,
1189
1190         .size_of_priv     = sizeof(struct cxusb_state),
1191
1192         .num_adapters = 1,
1193         .adapter = {
1194                 {
1195                         .streaming_ctrl   = cxusb_streaming_ctrl,
1196                         .frontend_attach  = cxusb_nano2_frontend_attach,
1197                         .tuner_attach     = cxusb_dvico_xc3028_tuner_attach,
1198                         /* parameter for the MPEG2-data transfer */
1199                         .stream = {
1200                                 .type = USB_BULK,
1201                                 .count = 5,
1202                                 .endpoint = 0x02,
1203                                 .u = {
1204                                         .bulk = {
1205                                                 .buffersize = 8192,
1206                                         }
1207                                 }
1208                         },
1209                 },
1210         },
1211
1212         .power_ctrl       = cxusb_nano2_power_ctrl,
1213
1214         .i2c_algo         = &cxusb_i2c_algo,
1215
1216         .generic_bulk_ctrl_endpoint = 0x01,
1217
1218         .rc_interval      = 100,
1219         .rc_key_map       = dvico_portable_rc_keys,
1220         .rc_key_map_size  = ARRAY_SIZE(dvico_portable_rc_keys),
1221         .rc_query         = cxusb_bluebird2_rc_query,
1222
1223         .num_device_descs = 1,
1224         .devices = {
1225                 {   "DViCO FusionHDTV DVB-T NANO2",
1226                         { NULL },
1227                         { &cxusb_table[14], NULL },
1228                 },
1229         }
1230 };
1231
1232 static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties = {
1233         .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1234
1235         .usb_ctrl          = DEVICE_SPECIFIC,
1236         .firmware          = "dvb-usb-bluebird-02.fw",
1237         .download_firmware = bluebird_patch_dvico_firmware_download,
1238         .identify_state    = bluebird_fx2_identify_state,
1239
1240         .size_of_priv      = sizeof(struct cxusb_state),
1241
1242         .num_adapters = 1,
1243         .adapter = {
1244                 {
1245                         .streaming_ctrl   = cxusb_streaming_ctrl,
1246                         .frontend_attach  = cxusb_nano2_frontend_attach,
1247                         .tuner_attach     = cxusb_dvico_xc3028_tuner_attach,
1248                         /* parameter for the MPEG2-data transfer */
1249                         .stream = {
1250                                 .type = USB_BULK,
1251                                 .count = 5,
1252                                 .endpoint = 0x02,
1253                                 .u = {
1254                                         .bulk = {
1255                                                 .buffersize = 8192,
1256                                         }
1257                                 }
1258                         },
1259                 },
1260         },
1261
1262         .power_ctrl       = cxusb_nano2_power_ctrl,
1263
1264         .i2c_algo         = &cxusb_i2c_algo,
1265
1266         .generic_bulk_ctrl_endpoint = 0x01,
1267
1268         .rc_interval      = 100,
1269         .rc_key_map       = dvico_portable_rc_keys,
1270         .rc_key_map_size  = ARRAY_SIZE(dvico_portable_rc_keys),
1271         .rc_query         = cxusb_rc_query,
1272
1273         .num_device_descs = 1,
1274         .devices = {
1275                 {   "DViCO FusionHDTV DVB-T NANO2 w/o firmware",
1276                         { &cxusb_table[14], NULL },
1277                         { &cxusb_table[15], NULL },
1278                 },
1279         }
1280 };
1281
1282 static struct dvb_usb_device_properties cxusb_aver_a868r_properties = {
1283         .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1284
1285         .usb_ctrl         = CYPRESS_FX2,
1286
1287         .size_of_priv     = sizeof(struct cxusb_state),
1288
1289         .num_adapters = 1,
1290         .adapter = {
1291                 {
1292                         .streaming_ctrl   = cxusb_aver_streaming_ctrl,
1293                         .frontend_attach  = cxusb_aver_lgdt3303_frontend_attach,
1294                         .tuner_attach     = cxusb_mxl5003s_tuner_attach,
1295                         /* parameter for the MPEG2-data transfer */
1296                         .stream = {
1297                                 .type = USB_BULK,
1298                                 .count = 5,
1299                                 .endpoint = 0x04,
1300                                 .u = {
1301                                         .bulk = {
1302                                                 .buffersize = 8192,
1303                                         }
1304                                 }
1305                         },
1306
1307                 },
1308         },
1309         .power_ctrl       = cxusb_aver_power_ctrl,
1310
1311         .i2c_algo         = &cxusb_i2c_algo,
1312
1313         .generic_bulk_ctrl_endpoint = 0x01,
1314
1315         .num_device_descs = 1,
1316         .devices = {
1317                 {   "AVerMedia AVerTVHD Volar (A868R)",
1318                         { NULL },
1319                         { &cxusb_table[16], NULL },
1320                 },
1321         }
1322 };
1323
1324 static struct usb_driver cxusb_driver = {
1325         .name           = "dvb_usb_cxusb",
1326         .probe          = cxusb_probe,
1327         .disconnect     = dvb_usb_device_exit,
1328         .id_table       = cxusb_table,
1329 };
1330
1331 /* module stuff */
1332 static int __init cxusb_module_init(void)
1333 {
1334         int result;
1335         if ((result = usb_register(&cxusb_driver))) {
1336                 err("usb_register failed. Error number %d",result);
1337                 return result;
1338         }
1339
1340         return 0;
1341 }
1342
1343 static void __exit cxusb_module_exit(void)
1344 {
1345         /* deregister this driver from the USB subsystem */
1346         usb_deregister(&cxusb_driver);
1347 }
1348
1349 module_init (cxusb_module_init);
1350 module_exit (cxusb_module_exit);
1351
1352 MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
1353 MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
1354 MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
1355 MODULE_DESCRIPTION("Driver for Conexant USB2.0 hybrid reference design");
1356 MODULE_VERSION("1.0-alpha");
1357 MODULE_LICENSE("GPL");