V4L/DVB (8495): usb/anysee.c: make struct anysee_usb_mutex static
[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_device *d = ptr;
569
570         switch (command) {
571         case XC2028_TUNER_RESET:
572                 deb_info("%s: XC2028_TUNER_RESET %d\n", __func__, arg);
573                 cxusb_bluebird_gpio_pulse(d, 0x01, 1);
574                 break;
575         case XC2028_RESET_CLK:
576                 deb_info("%s: XC2028_RESET_CLK %d\n", __func__, arg);
577                 break;
578         default:
579                 deb_info("%s: unknown command %d, arg %d\n", __func__,
580                          command, arg);
581                 return -EINVAL;
582         }
583
584         return 0;
585 }
586
587 static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap)
588 {
589         struct dvb_frontend      *fe;
590         struct xc2028_config      cfg = {
591                 .i2c_adap  = &adap->dev->i2c_adap,
592                 .i2c_addr  = 0x61,
593                 .callback  = dvico_bluebird_xc2028_callback,
594         };
595         static struct xc2028_ctrl ctl = {
596                 .fname       = "xc3028-dvico-au-01.fw",
597                 .max_len     = 64,
598                 .scode_table = XC3028_FE_ZARLINK456,
599         };
600
601         fe = dvb_attach(xc2028_attach, adap->fe, &cfg);
602         if (fe == NULL || fe->ops.tuner_ops.set_config == NULL)
603                 return -EIO;
604
605         fe->ops.tuner_ops.set_config(fe, &ctl);
606
607         return 0;
608 }
609
610 static int cxusb_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
611 {
612         dvb_attach(mxl5005s_attach, adap->fe,
613                    &adap->dev->i2c_adap, &aver_a868r_tuner);
614         return 0;
615 }
616
617 static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap)
618 {
619         u8 b;
620         if (usb_set_interface(adap->dev->udev, 0, 6) < 0)
621                 err("set interface failed");
622
623         cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, &b, 1);
624
625         if ((adap->fe = dvb_attach(cx22702_attach, &cxusb_cx22702_config,
626                                    &adap->dev->i2c_adap)) != NULL)
627                 return 0;
628
629         return -EIO;
630 }
631
632 static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
633 {
634         if (usb_set_interface(adap->dev->udev, 0, 7) < 0)
635                 err("set interface failed");
636
637         cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
638
639         if ((adap->fe = dvb_attach(lgdt330x_attach, &cxusb_lgdt3303_config,
640                                    &adap->dev->i2c_adap)) != NULL)
641                 return 0;
642
643         return -EIO;
644 }
645
646 static int cxusb_aver_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
647 {
648         adap->fe = dvb_attach(lgdt330x_attach, &cxusb_aver_lgdt3303_config,
649                               &adap->dev->i2c_adap);
650         if (adap->fe != NULL)
651                 return 0;
652
653         return -EIO;
654 }
655
656 static int cxusb_mt352_frontend_attach(struct dvb_usb_adapter *adap)
657 {
658         /* used in both lgz201 and th7579 */
659         if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
660                 err("set interface failed");
661
662         cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
663
664         if ((adap->fe = dvb_attach(mt352_attach, &cxusb_mt352_config,
665                                    &adap->dev->i2c_adap)) != NULL)
666                 return 0;
667
668         return -EIO;
669 }
670
671 static int cxusb_dee1601_frontend_attach(struct dvb_usb_adapter *adap)
672 {
673         if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
674                 err("set interface failed");
675
676         cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
677
678         if (((adap->fe = dvb_attach(mt352_attach, &cxusb_dee1601_config,
679                                     &adap->dev->i2c_adap)) != NULL) ||
680                 ((adap->fe = dvb_attach(zl10353_attach,
681                                         &cxusb_zl10353_dee1601_config,
682                                         &adap->dev->i2c_adap)) != NULL))
683                 return 0;
684
685         return -EIO;
686 }
687
688 static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap)
689 {
690         u8 ircode[4];
691         int i;
692         struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
693                                .buf = ircode, .len = 4 };
694
695         if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
696                 err("set interface failed");
697
698         cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
699
700         /* reset the tuner and demodulator */
701         cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
702         cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
703         cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
704
705         if ((adap->fe = dvb_attach(zl10353_attach,
706                                    &cxusb_zl10353_xc3028_config,
707                                    &adap->dev->i2c_adap)) == NULL)
708                 return -EIO;
709
710         /* try to determine if there is no IR decoder on the I2C bus */
711         for (i = 0; adap->dev->props.rc_key_map != NULL && i < 5; i++) {
712                 msleep(20);
713                 if (cxusb_i2c_xfer(&adap->dev->i2c_adap, &msg, 1) != 1)
714                         goto no_IR;
715                 if (ircode[0] == 0 && ircode[1] == 0)
716                         continue;
717                 if (ircode[2] + ircode[3] != 0xff) {
718 no_IR:
719                         adap->dev->props.rc_key_map = NULL;
720                         info("No IR receiver detected on this device.");
721                         break;
722                 }
723         }
724
725         return 0;
726 }
727
728 static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap)
729 {
730         if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
731                 err("set interface failed");
732
733         cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
734
735         /* reset the tuner and demodulator */
736         cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
737         cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
738         cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
739
740         if ((adap->fe = dvb_attach(zl10353_attach,
741                                    &cxusb_zl10353_xc3028_config,
742                                    &adap->dev->i2c_adap)) != NULL)
743                 return 0;
744
745         if ((adap->fe = dvb_attach(mt352_attach,
746                                    &cxusb_mt352_xc3028_config,
747                                    &adap->dev->i2c_adap)) != NULL)
748                 return 0;
749
750         return -EIO;
751 }
752
753 /*
754  * DViCO has shipped two devices with the same USB ID, but only one of them
755  * needs a firmware download.  Check the device class details to see if they
756  * have non-default values to decide whether the device is actually cold or
757  * not, and forget a match if it turns out we selected the wrong device.
758  */
759 static int bluebird_fx2_identify_state(struct usb_device *udev,
760                                        struct dvb_usb_device_properties *props,
761                                        struct dvb_usb_device_description **desc,
762                                        int *cold)
763 {
764         int wascold = *cold;
765
766         *cold = udev->descriptor.bDeviceClass == 0xff &&
767                 udev->descriptor.bDeviceSubClass == 0xff &&
768                 udev->descriptor.bDeviceProtocol == 0xff;
769
770         if (*cold && !wascold)
771                 *desc = NULL;
772
773         return 0;
774 }
775
776 /*
777  * DViCO bluebird firmware needs the "warm" product ID to be patched into the
778  * firmware file before download.
779  */
780
781 static const int dvico_firmware_id_offsets[] = { 6638, 3204 };
782 static int bluebird_patch_dvico_firmware_download(struct usb_device *udev,
783                                                   const struct firmware *fw)
784 {
785         int pos;
786
787         for (pos = 0; pos < ARRAY_SIZE(dvico_firmware_id_offsets); pos++) {
788                 int idoff = dvico_firmware_id_offsets[pos];
789
790                 if (fw->size < idoff + 4)
791                         continue;
792
793                 if (fw->data[idoff] == (USB_VID_DVICO & 0xff) &&
794                     fw->data[idoff + 1] == USB_VID_DVICO >> 8) {
795                         struct firmware new_fw;
796                         u8 *new_fw_data = vmalloc(fw->size);
797                         int ret;
798
799                         if (!new_fw_data)
800                                 return -ENOMEM;
801
802                         memcpy(new_fw_data, fw->data, fw->size);
803                         new_fw.size = fw->size;
804                         new_fw.data = new_fw_data;
805
806                         new_fw_data[idoff + 2] =
807                                 le16_to_cpu(udev->descriptor.idProduct) + 1;
808                         new_fw_data[idoff + 3] =
809                                 le16_to_cpu(udev->descriptor.idProduct) >> 8;
810
811                         ret = usb_cypress_load_firmware(udev, &new_fw,
812                                                         CYPRESS_FX2);
813                         vfree(new_fw_data);
814                         return ret;
815                 }
816         }
817
818         return -EINVAL;
819 }
820
821 /* DVB USB Driver stuff */
822 static struct dvb_usb_device_properties cxusb_medion_properties;
823 static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties;
824 static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties;
825 static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties;
826 static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties;
827 static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties;
828 static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties;
829 static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties;
830 static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
831
832 static int cxusb_probe(struct usb_interface *intf,
833                        const struct usb_device_id *id)
834 {
835         if (0 == dvb_usb_device_init(intf, &cxusb_medion_properties,
836                                      THIS_MODULE, NULL, adapter_nr) ||
837             0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgh064f_properties,
838                                      THIS_MODULE, NULL, adapter_nr) ||
839             0 == dvb_usb_device_init(intf, &cxusb_bluebird_dee1601_properties,
840                                      THIS_MODULE, NULL, adapter_nr) ||
841             0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgz201_properties,
842                                      THIS_MODULE, NULL, adapter_nr) ||
843             0 == dvb_usb_device_init(intf, &cxusb_bluebird_dtt7579_properties,
844                                      THIS_MODULE, NULL, adapter_nr) ||
845             0 == dvb_usb_device_init(intf, &cxusb_bluebird_dualdig4_properties,
846                                      THIS_MODULE, NULL, adapter_nr) ||
847             0 == dvb_usb_device_init(intf, &cxusb_bluebird_nano2_properties,
848                                      THIS_MODULE, NULL, adapter_nr) ||
849             0 == dvb_usb_device_init(intf,
850                                 &cxusb_bluebird_nano2_needsfirmware_properties,
851                                      THIS_MODULE, NULL, adapter_nr) ||
852             0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties,
853                                      THIS_MODULE, NULL, adapter_nr) ||
854             0)
855                 return 0;
856
857         return -EINVAL;
858 }
859
860 static struct usb_device_id cxusb_table [] = {
861         { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) },
862         { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) },
863         { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_WARM) },
864         { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_COLD) },
865         { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM) },
866         { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_COLD) },
867         { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_WARM) },
868         { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_COLD) },
869         { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_WARM) },
870         { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD) },
871         { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM) },
872         { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD) },
873         { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM) },
874         { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) },
875         { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) },
876         { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) },
877         { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) },
878         {}              /* Terminating entry */
879 };
880 MODULE_DEVICE_TABLE (usb, cxusb_table);
881
882 static struct dvb_usb_device_properties cxusb_medion_properties = {
883         .caps = DVB_USB_IS_AN_I2C_ADAPTER,
884
885         .usb_ctrl = CYPRESS_FX2,
886
887         .size_of_priv     = sizeof(struct cxusb_state),
888
889         .num_adapters = 1,
890         .adapter = {
891                 {
892                         .streaming_ctrl   = cxusb_streaming_ctrl,
893                         .frontend_attach  = cxusb_cx22702_frontend_attach,
894                         .tuner_attach     = cxusb_fmd1216me_tuner_attach,
895                         /* parameter for the MPEG2-data transfer */
896                                         .stream = {
897                                                 .type = USB_BULK,
898                                 .count = 5,
899                                 .endpoint = 0x02,
900                                 .u = {
901                                         .bulk = {
902                                                 .buffersize = 8192,
903                                         }
904                                 }
905                         },
906
907                 },
908         },
909         .power_ctrl       = cxusb_power_ctrl,
910
911         .i2c_algo         = &cxusb_i2c_algo,
912
913         .generic_bulk_ctrl_endpoint = 0x01,
914
915         .num_device_descs = 1,
916         .devices = {
917                 {   "Medion MD95700 (MDUSBTV-HYBRID)",
918                         { NULL },
919                         { &cxusb_table[0], NULL },
920                 },
921         }
922 };
923
924 static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = {
925         .caps = DVB_USB_IS_AN_I2C_ADAPTER,
926
927         .usb_ctrl          = DEVICE_SPECIFIC,
928         .firmware          = "dvb-usb-bluebird-01.fw",
929         .download_firmware = bluebird_patch_dvico_firmware_download,
930         /* use usb alt setting 0 for EP4 transfer (dvb-t),
931            use usb alt setting 7 for EP2 transfer (atsc) */
932
933         .size_of_priv     = sizeof(struct cxusb_state),
934
935         .num_adapters = 1,
936         .adapter = {
937                 {
938                         .streaming_ctrl   = cxusb_streaming_ctrl,
939                         .frontend_attach  = cxusb_lgdt3303_frontend_attach,
940                         .tuner_attach     = cxusb_lgh064f_tuner_attach,
941
942                         /* parameter for the MPEG2-data transfer */
943                                         .stream = {
944                                                 .type = USB_BULK,
945                                 .count = 5,
946                                 .endpoint = 0x02,
947                                 .u = {
948                                         .bulk = {
949                                                 .buffersize = 8192,
950                                         }
951                                 }
952                         },
953                 },
954         },
955
956         .power_ctrl       = cxusb_bluebird_power_ctrl,
957
958         .i2c_algo         = &cxusb_i2c_algo,
959
960         .rc_interval      = 100,
961         .rc_key_map       = dvico_portable_rc_keys,
962         .rc_key_map_size  = ARRAY_SIZE(dvico_portable_rc_keys),
963         .rc_query         = cxusb_rc_query,
964
965         .generic_bulk_ctrl_endpoint = 0x01,
966
967         .num_device_descs = 1,
968         .devices = {
969                 {   "DViCO FusionHDTV5 USB Gold",
970                         { &cxusb_table[1], NULL },
971                         { &cxusb_table[2], NULL },
972                 },
973         }
974 };
975
976 static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = {
977         .caps = DVB_USB_IS_AN_I2C_ADAPTER,
978
979         .usb_ctrl          = DEVICE_SPECIFIC,
980         .firmware          = "dvb-usb-bluebird-01.fw",
981         .download_firmware = bluebird_patch_dvico_firmware_download,
982         /* use usb alt setting 0 for EP4 transfer (dvb-t),
983            use usb alt setting 7 for EP2 transfer (atsc) */
984
985         .size_of_priv     = sizeof(struct cxusb_state),
986
987         .num_adapters = 1,
988         .adapter = {
989                 {
990                         .streaming_ctrl   = cxusb_streaming_ctrl,
991                         .frontend_attach  = cxusb_dee1601_frontend_attach,
992                         .tuner_attach     = cxusb_dee1601_tuner_attach,
993                         /* parameter for the MPEG2-data transfer */
994                         .stream = {
995                                 .type = USB_BULK,
996                                 .count = 5,
997                                 .endpoint = 0x04,
998                                 .u = {
999                                         .bulk = {
1000                                                 .buffersize = 8192,
1001                                         }
1002                                 }
1003                         },
1004                 },
1005         },
1006
1007         .power_ctrl       = cxusb_bluebird_power_ctrl,
1008
1009         .i2c_algo         = &cxusb_i2c_algo,
1010
1011         .rc_interval      = 150,
1012         .rc_key_map       = dvico_mce_rc_keys,
1013         .rc_key_map_size  = ARRAY_SIZE(dvico_mce_rc_keys),
1014         .rc_query         = cxusb_rc_query,
1015
1016         .generic_bulk_ctrl_endpoint = 0x01,
1017
1018         .num_device_descs = 3,
1019         .devices = {
1020                 {   "DViCO FusionHDTV DVB-T Dual USB",
1021                         { &cxusb_table[3], NULL },
1022                         { &cxusb_table[4], NULL },
1023                 },
1024                 {   "DigitalNow DVB-T Dual USB",
1025                         { &cxusb_table[9],  NULL },
1026                         { &cxusb_table[10], NULL },
1027                 },
1028                 {   "DViCO FusionHDTV DVB-T Dual Digital 2",
1029                         { &cxusb_table[11], NULL },
1030                         { &cxusb_table[12], NULL },
1031                 },
1032         }
1033 };
1034
1035 static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = {
1036         .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1037
1038         .usb_ctrl          = DEVICE_SPECIFIC,
1039         .firmware          = "dvb-usb-bluebird-01.fw",
1040         .download_firmware = bluebird_patch_dvico_firmware_download,
1041         /* use usb alt setting 0 for EP4 transfer (dvb-t),
1042            use usb alt setting 7 for EP2 transfer (atsc) */
1043
1044         .size_of_priv     = sizeof(struct cxusb_state),
1045
1046         .num_adapters = 2,
1047         .adapter = {
1048                 {
1049                         .streaming_ctrl   = cxusb_streaming_ctrl,
1050                         .frontend_attach  = cxusb_mt352_frontend_attach,
1051                         .tuner_attach     = cxusb_lgz201_tuner_attach,
1052
1053                         /* parameter for the MPEG2-data transfer */
1054                         .stream = {
1055                                 .type = USB_BULK,
1056                                 .count = 5,
1057                                 .endpoint = 0x04,
1058                                 .u = {
1059                                         .bulk = {
1060                                                 .buffersize = 8192,
1061                                         }
1062                                 }
1063                         },
1064                 },
1065         },
1066         .power_ctrl       = cxusb_bluebird_power_ctrl,
1067
1068         .i2c_algo         = &cxusb_i2c_algo,
1069
1070         .rc_interval      = 100,
1071         .rc_key_map       = dvico_portable_rc_keys,
1072         .rc_key_map_size  = ARRAY_SIZE(dvico_portable_rc_keys),
1073         .rc_query         = cxusb_rc_query,
1074
1075         .generic_bulk_ctrl_endpoint = 0x01,
1076         .num_device_descs = 1,
1077         .devices = {
1078                 {   "DViCO FusionHDTV DVB-T USB (LGZ201)",
1079                         { &cxusb_table[5], NULL },
1080                         { &cxusb_table[6], NULL },
1081                 },
1082         }
1083 };
1084
1085 static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = {
1086         .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1087
1088         .usb_ctrl          = DEVICE_SPECIFIC,
1089         .firmware          = "dvb-usb-bluebird-01.fw",
1090         .download_firmware = bluebird_patch_dvico_firmware_download,
1091         /* use usb alt setting 0 for EP4 transfer (dvb-t),
1092            use usb alt setting 7 for EP2 transfer (atsc) */
1093
1094         .size_of_priv     = sizeof(struct cxusb_state),
1095
1096         .num_adapters = 1,
1097         .adapter = {
1098                 {
1099                         .streaming_ctrl   = cxusb_streaming_ctrl,
1100                         .frontend_attach  = cxusb_mt352_frontend_attach,
1101                         .tuner_attach     = cxusb_dtt7579_tuner_attach,
1102
1103                         /* parameter for the MPEG2-data transfer */
1104                         .stream = {
1105                                 .type = USB_BULK,
1106                                 .count = 5,
1107                                 .endpoint = 0x04,
1108                                 .u = {
1109                                         .bulk = {
1110                                                 .buffersize = 8192,
1111                                         }
1112                                 }
1113                         },
1114                 },
1115         },
1116         .power_ctrl       = cxusb_bluebird_power_ctrl,
1117
1118         .i2c_algo         = &cxusb_i2c_algo,
1119
1120         .rc_interval      = 100,
1121         .rc_key_map       = dvico_portable_rc_keys,
1122         .rc_key_map_size  = ARRAY_SIZE(dvico_portable_rc_keys),
1123         .rc_query         = cxusb_rc_query,
1124
1125         .generic_bulk_ctrl_endpoint = 0x01,
1126
1127         .num_device_descs = 1,
1128         .devices = {
1129                 {   "DViCO FusionHDTV DVB-T USB (TH7579)",
1130                         { &cxusb_table[7], NULL },
1131                         { &cxusb_table[8], NULL },
1132                 },
1133         }
1134 };
1135
1136 static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = {
1137         .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1138
1139         .usb_ctrl         = CYPRESS_FX2,
1140
1141         .size_of_priv     = sizeof(struct cxusb_state),
1142
1143         .num_adapters = 1,
1144         .adapter = {
1145                 {
1146                         .streaming_ctrl   = cxusb_streaming_ctrl,
1147                         .frontend_attach  = cxusb_dualdig4_frontend_attach,
1148                         .tuner_attach     = cxusb_dvico_xc3028_tuner_attach,
1149                         /* parameter for the MPEG2-data transfer */
1150                         .stream = {
1151                                 .type = USB_BULK,
1152                                 .count = 5,
1153                                 .endpoint = 0x02,
1154                                 .u = {
1155                                         .bulk = {
1156                                                 .buffersize = 8192,
1157                                         }
1158                                 }
1159                         },
1160                 },
1161         },
1162
1163         .power_ctrl       = cxusb_power_ctrl,
1164
1165         .i2c_algo         = &cxusb_i2c_algo,
1166
1167         .generic_bulk_ctrl_endpoint = 0x01,
1168
1169         .rc_interval      = 100,
1170         .rc_key_map       = dvico_mce_rc_keys,
1171         .rc_key_map_size  = ARRAY_SIZE(dvico_mce_rc_keys),
1172         .rc_query         = cxusb_bluebird2_rc_query,
1173
1174         .num_device_descs = 1,
1175         .devices = {
1176                 {   "DViCO FusionHDTV DVB-T Dual Digital 4",
1177                         { NULL },
1178                         { &cxusb_table[13], NULL },
1179                 },
1180         }
1181 };
1182
1183 static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = {
1184         .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1185
1186         .usb_ctrl         = CYPRESS_FX2,
1187         .identify_state   = bluebird_fx2_identify_state,
1188
1189         .size_of_priv     = sizeof(struct cxusb_state),
1190
1191         .num_adapters = 1,
1192         .adapter = {
1193                 {
1194                         .streaming_ctrl   = cxusb_streaming_ctrl,
1195                         .frontend_attach  = cxusb_nano2_frontend_attach,
1196                         .tuner_attach     = cxusb_dvico_xc3028_tuner_attach,
1197                         /* parameter for the MPEG2-data transfer */
1198                         .stream = {
1199                                 .type = USB_BULK,
1200                                 .count = 5,
1201                                 .endpoint = 0x02,
1202                                 .u = {
1203                                         .bulk = {
1204                                                 .buffersize = 8192,
1205                                         }
1206                                 }
1207                         },
1208                 },
1209         },
1210
1211         .power_ctrl       = cxusb_nano2_power_ctrl,
1212
1213         .i2c_algo         = &cxusb_i2c_algo,
1214
1215         .generic_bulk_ctrl_endpoint = 0x01,
1216
1217         .rc_interval      = 100,
1218         .rc_key_map       = dvico_portable_rc_keys,
1219         .rc_key_map_size  = ARRAY_SIZE(dvico_portable_rc_keys),
1220         .rc_query         = cxusb_bluebird2_rc_query,
1221
1222         .num_device_descs = 1,
1223         .devices = {
1224                 {   "DViCO FusionHDTV DVB-T NANO2",
1225                         { NULL },
1226                         { &cxusb_table[14], NULL },
1227                 },
1228         }
1229 };
1230
1231 static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties = {
1232         .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1233
1234         .usb_ctrl          = DEVICE_SPECIFIC,
1235         .firmware          = "dvb-usb-bluebird-02.fw",
1236         .download_firmware = bluebird_patch_dvico_firmware_download,
1237         .identify_state    = bluebird_fx2_identify_state,
1238
1239         .size_of_priv      = sizeof(struct cxusb_state),
1240
1241         .num_adapters = 1,
1242         .adapter = {
1243                 {
1244                         .streaming_ctrl   = cxusb_streaming_ctrl,
1245                         .frontend_attach  = cxusb_nano2_frontend_attach,
1246                         .tuner_attach     = cxusb_dvico_xc3028_tuner_attach,
1247                         /* parameter for the MPEG2-data transfer */
1248                         .stream = {
1249                                 .type = USB_BULK,
1250                                 .count = 5,
1251                                 .endpoint = 0x02,
1252                                 .u = {
1253                                         .bulk = {
1254                                                 .buffersize = 8192,
1255                                         }
1256                                 }
1257                         },
1258                 },
1259         },
1260
1261         .power_ctrl       = cxusb_nano2_power_ctrl,
1262
1263         .i2c_algo         = &cxusb_i2c_algo,
1264
1265         .generic_bulk_ctrl_endpoint = 0x01,
1266
1267         .rc_interval      = 100,
1268         .rc_key_map       = dvico_portable_rc_keys,
1269         .rc_key_map_size  = ARRAY_SIZE(dvico_portable_rc_keys),
1270         .rc_query         = cxusb_rc_query,
1271
1272         .num_device_descs = 1,
1273         .devices = {
1274                 {   "DViCO FusionHDTV DVB-T NANO2 w/o firmware",
1275                         { &cxusb_table[14], NULL },
1276                         { &cxusb_table[15], NULL },
1277                 },
1278         }
1279 };
1280
1281 static struct dvb_usb_device_properties cxusb_aver_a868r_properties = {
1282         .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1283
1284         .usb_ctrl         = CYPRESS_FX2,
1285
1286         .size_of_priv     = sizeof(struct cxusb_state),
1287
1288         .num_adapters = 1,
1289         .adapter = {
1290                 {
1291                         .streaming_ctrl   = cxusb_aver_streaming_ctrl,
1292                         .frontend_attach  = cxusb_aver_lgdt3303_frontend_attach,
1293                         .tuner_attach     = cxusb_mxl5003s_tuner_attach,
1294                         /* parameter for the MPEG2-data transfer */
1295                         .stream = {
1296                                 .type = USB_BULK,
1297                                 .count = 5,
1298                                 .endpoint = 0x04,
1299                                 .u = {
1300                                         .bulk = {
1301                                                 .buffersize = 8192,
1302                                         }
1303                                 }
1304                         },
1305
1306                 },
1307         },
1308         .power_ctrl       = cxusb_aver_power_ctrl,
1309
1310         .i2c_algo         = &cxusb_i2c_algo,
1311
1312         .generic_bulk_ctrl_endpoint = 0x01,
1313
1314         .num_device_descs = 1,
1315         .devices = {
1316                 {   "AVerMedia AVerTVHD Volar (A868R)",
1317                         { NULL },
1318                         { &cxusb_table[16], NULL },
1319                 },
1320         }
1321 };
1322
1323 static struct usb_driver cxusb_driver = {
1324         .name           = "dvb_usb_cxusb",
1325         .probe          = cxusb_probe,
1326         .disconnect     = dvb_usb_device_exit,
1327         .id_table       = cxusb_table,
1328 };
1329
1330 /* module stuff */
1331 static int __init cxusb_module_init(void)
1332 {
1333         int result;
1334         if ((result = usb_register(&cxusb_driver))) {
1335                 err("usb_register failed. Error number %d",result);
1336                 return result;
1337         }
1338
1339         return 0;
1340 }
1341
1342 static void __exit cxusb_module_exit(void)
1343 {
1344         /* deregister this driver from the USB subsystem */
1345         usb_deregister(&cxusb_driver);
1346 }
1347
1348 module_init (cxusb_module_init);
1349 module_exit (cxusb_module_exit);
1350
1351 MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
1352 MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
1353 MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
1354 MODULE_DESCRIPTION("Driver for Conexant USB2.0 hybrid reference design");
1355 MODULE_VERSION("1.0-alpha");
1356 MODULE_LICENSE("GPL");