blob: 578afce6884c554701f77c4a15af93faabb712c1 [file] [log] [blame]
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001/* 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 *
Michael Krufky81481e92006-01-09 18:21:38 -020014 * TODO: Use the cx25840-driver for the analogue part
Patrick Boettcher22c6d932005-07-07 17:58:10 -070015 *
Patrick Boettcher22c6d932005-07-07 17:58:10 -070016 * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
Michael Krufky5b9ed282006-10-15 14:51:08 -030017 * Copyright (C) 2006 Michael Krufky (mkrufky@linuxtv.org)
Chris Pascoeaeb012b2007-11-19 21:57:10 -030018 * Copyright (C) 2006, 2007 Chris Pascoe (c.pascoe@itee.uq.edu.au)
Patrick Boettcher22c6d932005-07-07 17:58:10 -070019 *
Michael Krufkyf35db232006-12-05 14:53:39 -030020 * 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.
Patrick Boettcher22c6d932005-07-07 17:58:10 -070023 *
24 * see Documentation/dvb/README.dvb-usb for more information
25 */
Michael Krufky827855d2008-04-22 14:46:16 -030026#include <media/tuner.h>
David Woodhousee62f89f2008-05-24 00:12:42 +010027#include <linux/vmalloc.h>
Michael Krufky827855d2008-04-22 14:46:16 -030028
Patrick Boettcher22c6d932005-07-07 17:58:10 -070029#include "cxusb.h"
30
31#include "cx22702.h"
Michael Krufkyeffee032006-01-09 15:25:47 -020032#include "lgdt330x.h"
Chris Pascoe0029ee12006-01-09 18:21:28 -020033#include "mt352.h"
34#include "mt352_priv.h"
Michael Krufkyc9ce3942006-06-11 04:24:31 -030035#include "zl10353.h"
Chris Pascoeaeb012b2007-11-19 21:57:10 -030036#include "tuner-xc2028.h"
Michael Krufky827855d2008-04-22 14:46:16 -030037#include "tuner-simple.h"
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -030038#include "mxl5005s.h"
Patrick Boettcher22c6d932005-07-07 17:58:10 -070039
40/* debug */
Adrian Bunk53133af2007-11-05 14:07:06 -030041static int dvb_usb_cxusb_debug;
Michael Krufkyf35db232006-12-05 14:53:39 -030042module_param_named(debug, dvb_usb_cxusb_debug, int, 0644);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070043MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
Janne Grunau78e92002008-04-09 19:13:13 -030044
45DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
46
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -030047#define deb_info(args...) dprintk(dvb_usb_cxusb_debug, 0x03, args)
48#define deb_i2c(args...) dprintk(dvb_usb_cxusb_debug, 0x02, args)
Patrick Boettcher22c6d932005-07-07 17:58:10 -070049
50static int cxusb_ctrl_msg(struct dvb_usb_device *d,
Michael Krufkyf35db232006-12-05 14:53:39 -030051 u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
Patrick Boettcher22c6d932005-07-07 17:58:10 -070052{
53 int wo = (rbuf == NULL || rlen == 0); /* write-only */
54 u8 sndbuf[1+wlen];
Michael Krufkyf35db232006-12-05 14:53:39 -030055 memset(sndbuf, 0, 1+wlen);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070056
57 sndbuf[0] = cmd;
Michael Krufkyf35db232006-12-05 14:53:39 -030058 memcpy(&sndbuf[1], wbuf, wlen);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070059 if (wo)
Chris Pascoeb17f1092007-11-19 02:42:44 -030060 return dvb_usb_generic_write(d, sndbuf, 1+wlen);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070061 else
Chris Pascoeb17f1092007-11-19 02:42:44 -030062 return dvb_usb_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen, 0);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070063}
64
Patrick Boettchere2efeab2005-09-09 13:02:51 -070065/* GPIO */
66static void cxusb_gpio_tuner(struct dvb_usb_device *d, int onoff)
Patrick Boettcher22c6d932005-07-07 17:58:10 -070067{
68 struct cxusb_state *st = d->priv;
Michael Krufkyf35db232006-12-05 14:53:39 -030069 u8 o[2], i;
Patrick Boettcher22c6d932005-07-07 17:58:10 -070070
Patrick Boettchere2efeab2005-09-09 13:02:51 -070071 if (st->gpio_write_state[GPIO_TUNER] == onoff)
Patrick Boettcher22c6d932005-07-07 17:58:10 -070072 return;
73
Patrick Boettchere2efeab2005-09-09 13:02:51 -070074 o[0] = GPIO_TUNER;
75 o[1] = onoff;
Michael Krufkyf35db232006-12-05 14:53:39 -030076 cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070077
78 if (i != 0x01)
Patrick Boettchere2efeab2005-09-09 13:02:51 -070079 deb_info("gpio_write failed.\n");
Patrick Boettcher22c6d932005-07-07 17:58:10 -070080
Patrick Boettchere2efeab2005-09-09 13:02:51 -070081 st->gpio_write_state[GPIO_TUNER] = onoff;
Patrick Boettcher22c6d932005-07-07 17:58:10 -070082}
83
Chris Pascoeaeb012b2007-11-19 21:57:10 -030084static 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
100static 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
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300107static void cxusb_nano2_led(struct dvb_usb_device *d, int onoff)
108{
109 cxusb_bluebird_gpio_rw(d, 0x40, onoff ? 0 : 0x40);
110}
111
Patrick Boettchere2efeab2005-09-09 13:02:51 -0700112/* I2C */
Michael Krufkyf35db232006-12-05 14:53:39 -0300113static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
114 int num)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700115{
116 struct dvb_usb_device *d = i2c_get_adapdata(adap);
117 int i;
118
Ingo Molnar3593cab2006-02-07 06:49:14 -0200119 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700120 return -EAGAIN;
121
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700122 for (i = 0; i < num; i++) {
123
Michael Krufky5e805ef2006-03-23 00:01:34 -0300124 if (d->udev->descriptor.idVendor == USB_VID_MEDION)
125 switch (msg[i].addr) {
Michael Krufkyf35db232006-12-05 14:53:39 -0300126 case 0x63:
127 cxusb_gpio_tuner(d, 0);
128 break;
129 default:
130 cxusb_gpio_tuner(d, 1);
131 break;
Michael Krufky5e805ef2006-03-23 00:01:34 -0300132 }
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700133
Chris Pascoe272479d72007-11-19 03:01:22 -0300134 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);
Chris Pascoea644e4a2007-11-19 03:05:09 -0300147 } 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 */
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700150 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;
Michael Krufkyf35db232006-12-05 14:53:39 -0300154 memcpy(&obuf[3], msg[i].buf, msg[i].len);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700155
156 if (cxusb_ctrl_msg(d, CMD_I2C_READ,
Michael Krufkyf35db232006-12-05 14:53:39 -0300157 obuf, 3+msg[i].len,
158 ibuf, 1+msg[i+1].len) < 0)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700159 break;
160
161 if (ibuf[0] != 0x08)
Michael Krufkyae62e3d2006-03-23 01:11:18 -0300162 deb_i2c("i2c read may have failed\n");
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700163
Michael Krufkyf35db232006-12-05 14:53:39 -0300164 memcpy(msg[i+1].buf, &ibuf[1], msg[i+1].len);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700165
166 i++;
Chris Pascoe272479d72007-11-19 03:01:22 -0300167 } else {
168 /* write only */
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700169 u8 obuf[2+msg[i].len], ibuf;
170 obuf[0] = msg[i].addr;
171 obuf[1] = msg[i].len;
Michael Krufkyf35db232006-12-05 14:53:39 -0300172 memcpy(&obuf[2], msg[i].buf, msg[i].len);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700173
Michael Krufkyf35db232006-12-05 14:53:39 -0300174 if (cxusb_ctrl_msg(d, CMD_I2C_WRITE, obuf,
175 2+msg[i].len, &ibuf,1) < 0)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700176 break;
177 if (ibuf != 0x08)
Michael Krufkyae62e3d2006-03-23 01:11:18 -0300178 deb_i2c("i2c write may have failed\n");
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700179 }
180 }
181
Ingo Molnar3593cab2006-02-07 06:49:14 -0200182 mutex_unlock(&d->i2c_mutex);
Chris Pascoe13e001d2007-11-19 02:48:27 -0300183 return i == num ? num : -EREMOTEIO;
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700184}
185
186static u32 cxusb_i2c_func(struct i2c_adapter *adapter)
187{
188 return I2C_FUNC_I2C;
189}
190
191static struct i2c_algorithm cxusb_i2c_algo = {
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700192 .master_xfer = cxusb_i2c_xfer,
193 .functionality = cxusb_i2c_func,
194};
195
196static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff)
197{
Patrick Boettchere2efeab2005-09-09 13:02:51 -0700198 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);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700203}
204
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300205static 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
Michael Krufky5691c842006-04-19 20:40:01 -0300245static 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
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300254static 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
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300265static int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700266{
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700267 u8 buf[2] = { 0x03, 0x00 };
268 if (onoff)
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300269 cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON, buf, 2, NULL, 0);
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700270 else
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300271 cxusb_ctrl_msg(adap->dev, CMD_STREAMING_OFF, NULL, 0, NULL, 0);
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700272
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700273 return 0;
274}
275
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300276static 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
Chris Pascoe7c239702006-01-09 18:21:29 -0200286static 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;
Michael Krufkya07e6092006-01-09 18:21:31 -0200289 u8 ircode[4];
Chris Pascoe7c239702006-01-09 18:21:29 -0200290 int i;
291
Michael Krufkya07e6092006-01-09 18:21:31 -0200292 cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4);
Chris Pascoe7c239702006-01-09 18:21:29 -0200293
294 *event = 0;
295 *state = REMOTE_NO_KEY_PRESSED;
296
297 for (i = 0; i < d->props.rc_key_map_size; i++) {
Michael Krufkya07e6092006-01-09 18:21:31 -0200298 if (keymap[i].custom == ircode[2] &&
299 keymap[i].data == ircode[3]) {
Chris Pascoe7c239702006-01-09 18:21:29 -0200300 *event = keymap[i].event;
301 *state = REMOTE_KEY_PRESSED;
302
303 return 0;
304 }
305 }
306
307 return 0;
308}
309
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300310static 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
Adrian Bunk703cb2c2006-01-23 17:11:09 -0200338static struct dvb_usb_rc_key dvico_mce_rc_keys[] = {
Michael Krufkya07e6092006-01-09 18:21:31 -0200339 { 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
Michael Krufkyc1501782006-03-26 05:43:36 -0300386static 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 },
Michael Krufkydbcb86e2006-03-26 18:59:45 -0300399 { 0xfc, 0x16, KEY_CAMERA },
Michael Krufkyc1501782006-03-26 05:43:36 -0300400 { 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
Chris Pascoe0029ee12006-01-09 18:21:28 -0200425static int cxusb_dee1601_demod_init(struct dvb_frontend* fe)
426{
Chris Pascoed9ed8812006-02-07 06:49:11 -0200427 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 };
Chris Pascoe0029ee12006-01-09 18:21:28 -0200428 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
Michael Krufky6f447252006-01-11 19:40:33 -0200446static int cxusb_mt352_demod_init(struct dvb_frontend* fe)
447{ /* used in both lgz201 and th7579 */
Michael Krufkyfb51fd22006-02-07 06:49:12 -0200448 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x29 };
Michael Krufky6f447252006-01-11 19:40:33 -0200449 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
Adrian Bunk703cb2c2006-01-23 17:11:09 -0200466static struct cx22702_config cxusb_cx22702_config = {
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700467 .demod_address = 0x63,
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700468 .output_mode = CX22702_PARALLEL_OUTPUT,
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700469};
470
Michael Krufkyfddd6322006-02-27 00:08:17 -0300471static struct lgdt330x_config cxusb_lgdt3303_config = {
Michael Krufkyeffee032006-01-09 15:25:47 -0200472 .demod_address = 0x0e,
473 .demod_chip = LGDT3303,
Michael Krufkyeffee032006-01-09 15:25:47 -0200474};
475
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300476static struct lgdt330x_config cxusb_aver_lgdt3303_config = {
477 .demod_address = 0x0e,
478 .demod_chip = LGDT3303,
479 .clock_polarity_flip = 2,
480};
481
Adrian Bunk703cb2c2006-01-23 17:11:09 -0200482static struct mt352_config cxusb_dee1601_config = {
Chris Pascoe0029ee12006-01-09 18:21:28 -0200483 .demod_address = 0x0f,
484 .demod_init = cxusb_dee1601_demod_init,
Chris Pascoe0029ee12006-01-09 18:21:28 -0200485};
486
Michael Krufkyc9ce3942006-06-11 04:24:31 -0300487static struct zl10353_config cxusb_zl10353_dee1601_config = {
488 .demod_address = 0x0f,
Chris Pascoe8fb95782006-08-10 03:17:16 -0300489 .parallel_ts = 1,
Michael Krufkyc9ce3942006-06-11 04:24:31 -0300490};
491
Adrian Bunk6fe00b02006-04-19 20:49:28 -0300492static struct mt352_config cxusb_mt352_config = {
Michael Krufky6f447252006-01-11 19:40:33 -0200493 /* used in both lgz201 and th7579 */
494 .demod_address = 0x0f,
495 .demod_init = cxusb_mt352_demod_init,
Michael Krufky6f447252006-01-11 19:40:33 -0200496};
497
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300498static struct zl10353_config cxusb_zl10353_xc3028_config = {
499 .demod_address = 0x0f,
Chris Pascoea1dcd9d2007-11-20 08:17:54 -0300500 .if2 = 45600,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300501 .no_tuner = 1,
502 .parallel_ts = 1,
503};
504
Chris Pascoe702a6762007-11-20 03:34:11 -0300505static 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
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300512/* FIXME: needs tweaking */
513static 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
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700530/* Callbacks for DVB USB */
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300531static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700532{
Michael Krufkycb89cd32008-04-22 14:46:16 -0300533 dvb_attach(simple_tuner_attach, adap->fe,
534 &adap->dev->i2c_adap, 0x61,
535 TUNER_PHILIPS_FMD1216ME_MK3);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700536 return 0;
537}
538
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300539static int cxusb_dee1601_tuner_attach(struct dvb_usb_adapter *adap)
Chris Pascoe0029ee12006-01-09 18:21:28 -0200540{
Michael Krufky79a54cb2006-12-05 14:20:06 -0300541 dvb_attach(dvb_pll_attach, adap->fe, 0x61,
Michael Krufky47a99912007-06-12 16:10:51 -0300542 NULL, DVB_PLL_THOMSON_DTT7579);
Chris Pascoe0029ee12006-01-09 18:21:28 -0200543 return 0;
544}
545
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300546static int cxusb_lgz201_tuner_attach(struct dvb_usb_adapter *adap)
Michael Krufky6f447252006-01-11 19:40:33 -0200547{
Michael Krufky47a99912007-06-12 16:10:51 -0300548 dvb_attach(dvb_pll_attach, adap->fe, 0x61, NULL, DVB_PLL_LG_Z201);
Michael Krufky6f447252006-01-11 19:40:33 -0200549 return 0;
550}
551
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300552static int cxusb_dtt7579_tuner_attach(struct dvb_usb_adapter *adap)
Michael Krufky6f447252006-01-11 19:40:33 -0200553{
Michael Krufky79a54cb2006-12-05 14:20:06 -0300554 dvb_attach(dvb_pll_attach, adap->fe, 0x60,
Michael Krufky47a99912007-06-12 16:10:51 -0300555 NULL, DVB_PLL_THOMSON_DTT7579);
Patrick Boettcher332bed52006-05-14 04:49:00 -0300556 return 0;
557}
558
Michael Krufkyf71a56c2006-10-13 21:55:57 -0300559static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap)
Patrick Boettcher332bed52006-05-14 04:49:00 -0300560{
Michael Krufky827855d2008-04-22 14:46:16 -0300561 dvb_attach(simple_tuner_attach, adap->fe,
562 &adap->dev->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF);
Michael Krufky6f447252006-01-11 19:40:33 -0200563 return 0;
564}
565
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300566static 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:
Harvey Harrison708bebd2008-04-08 23:20:00 -0300572 deb_info("%s: XC2028_TUNER_RESET %d\n", __func__, arg);
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300573 cxusb_bluebird_gpio_pulse(d, 0x01, 1);
574 break;
575 case XC2028_RESET_CLK:
Harvey Harrison708bebd2008-04-08 23:20:00 -0300576 deb_info("%s: XC2028_RESET_CLK %d\n", __func__, arg);
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300577 break;
578 default:
Harvey Harrison708bebd2008-04-08 23:20:00 -0300579 deb_info("%s: unknown command %d, arg %d\n", __func__,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300580 command, arg);
581 return -EINVAL;
582 }
583
584 return 0;
585}
586
587static 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,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300593 .callback = dvico_bluebird_xc2028_callback,
594 };
595 static struct xc2028_ctrl ctl = {
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300596 .fname = "xc3028-dvico-au-01.fw",
597 .max_len = 64,
Mauro Carvalho Chehab33e53162008-04-21 06:58:48 -0300598 .scode_table = XC3028_FE_ZARLINK456,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300599 };
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
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300610static 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
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300617static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700618{
Patrick Boettchere2efeab2005-09-09 13:02:51 -0700619 u8 b;
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300620 if (usb_set_interface(adap->dev->udev, 0, 6) < 0)
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700621 err("set interface failed");
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700622
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300623 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, &b, 1);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700624
Michael Krufkyf35db232006-12-05 14:53:39 -0300625 if ((adap->fe = dvb_attach(cx22702_attach, &cxusb_cx22702_config,
626 &adap->dev->i2c_adap)) != NULL)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700627 return 0;
628
629 return -EIO;
630}
631
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300632static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
Michael Krufkyeffee032006-01-09 15:25:47 -0200633{
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300634 if (usb_set_interface(adap->dev->udev, 0, 7) < 0)
Michael Krufkyeffee032006-01-09 15:25:47 -0200635 err("set interface failed");
636
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300637 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
Michael Krufkyeffee032006-01-09 15:25:47 -0200638
Michael Krufkyf35db232006-12-05 14:53:39 -0300639 if ((adap->fe = dvb_attach(lgdt330x_attach, &cxusb_lgdt3303_config,
640 &adap->dev->i2c_adap)) != NULL)
Michael Krufkyeffee032006-01-09 15:25:47 -0200641 return 0;
642
643 return -EIO;
644}
645
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300646static 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
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300656static int cxusb_mt352_frontend_attach(struct dvb_usb_adapter *adap)
Chris Pascoe0029ee12006-01-09 18:21:28 -0200657{
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300658 /* used in both lgz201 and th7579 */
659 if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
Chris Pascoe0029ee12006-01-09 18:21:28 -0200660 err("set interface failed");
661
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300662 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
Chris Pascoe0029ee12006-01-09 18:21:28 -0200663
Michael Krufkyf35db232006-12-05 14:53:39 -0300664 if ((adap->fe = dvb_attach(mt352_attach, &cxusb_mt352_config,
665 &adap->dev->i2c_adap)) != NULL)
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300666 return 0;
667
668 return -EIO;
669}
670
671static 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
Michael Krufkyf35db232006-12-05 14:53:39 -0300678 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))
Chris Pascoe0029ee12006-01-09 18:21:28 -0200683 return 0;
684
685 return -EIO;
686}
687
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300688static 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) {
718no_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
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300728static 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
Chris Pascoe702a6762007-11-20 03:34:11 -0300745 if ((adap->fe = dvb_attach(mt352_attach,
746 &cxusb_mt352_xc3028_config,
747 &adap->dev->i2c_adap)) != NULL)
748 return 0;
749
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300750 return -EIO;
751}
752
Patrick Boettcherf5373782006-01-09 18:21:38 -0200753/*
Chris Pascoe702a6762007-11-20 03:34:11 -0300754 * 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 */
759static 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/*
Patrick Boettcherf5373782006-01-09 18:21:38 -0200777 * DViCO bluebird firmware needs the "warm" product ID to be patched into the
778 * firmware file before download.
779 */
780
Chris Pascoe702a6762007-11-20 03:34:11 -0300781static const int dvico_firmware_id_offsets[] = { 6638, 3204 };
Michael Krufkyf35db232006-12-05 14:53:39 -0300782static int bluebird_patch_dvico_firmware_download(struct usb_device *udev,
783 const struct firmware *fw)
Patrick Boettcherf5373782006-01-09 18:21:38 -0200784{
Chris Pascoe702a6762007-11-20 03:34:11 -0300785 int pos;
Patrick Boettcherf5373782006-01-09 18:21:38 -0200786
Chris Pascoe702a6762007-11-20 03:34:11 -0300787 for (pos = 0; pos < ARRAY_SIZE(dvico_firmware_id_offsets); pos++) {
788 int idoff = dvico_firmware_id_offsets[pos];
Patrick Boettcherf5373782006-01-09 18:21:38 -0200789
Chris Pascoe702a6762007-11-20 03:34:11 -0300790 if (fw->size < idoff + 4)
791 continue;
Patrick Boettcherf5373782006-01-09 18:21:38 -0200792
Chris Pascoe702a6762007-11-20 03:34:11 -0300793 if (fw->data[idoff] == (USB_VID_DVICO & 0xff) &&
794 fw->data[idoff + 1] == USB_VID_DVICO >> 8) {
David Woodhousee62f89f2008-05-24 00:12:42 +0100795 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] =
Chris Pascoe702a6762007-11-20 03:34:11 -0300807 le16_to_cpu(udev->descriptor.idProduct) + 1;
David Woodhousee62f89f2008-05-24 00:12:42 +0100808 new_fw_data[idoff + 3] =
Chris Pascoe702a6762007-11-20 03:34:11 -0300809 le16_to_cpu(udev->descriptor.idProduct) >> 8;
810
David Woodhousee62f89f2008-05-24 00:12:42 +0100811 ret = usb_cypress_load_firmware(udev, &new_fw,
812 CYPRESS_FX2);
813 vfree(new_fw_data);
814 return ret;
Chris Pascoe702a6762007-11-20 03:34:11 -0300815 }
Patrick Boettcherf5373782006-01-09 18:21:38 -0200816 }
817
818 return -EINVAL;
819}
820
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700821/* DVB USB Driver stuff */
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300822static struct dvb_usb_device_properties cxusb_medion_properties;
823static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties;
824static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties;
825static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties;
826static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties;
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300827static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties;
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300828static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties;
Chris Pascoe702a6762007-11-20 03:34:11 -0300829static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties;
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300830static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700831
832static int cxusb_probe(struct usb_interface *intf,
Michael Krufkyf35db232006-12-05 14:53:39 -0300833 const struct usb_device_id *id)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700834{
Janne Grunau78e92002008-04-09 19:13:13 -0300835 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,
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300851 THIS_MODULE, NULL, adapter_nr) ||
852 0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties,
853 THIS_MODULE, NULL, adapter_nr) ||
854 0)
Michael Krufkyeffee032006-01-09 15:25:47 -0200855 return 0;
Michael Krufkyeffee032006-01-09 15:25:47 -0200856
857 return -EINVAL;
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700858}
859
860static struct usb_device_id cxusb_table [] = {
Michael Krufkyf35db232006-12-05 14:53:39 -0300861 { 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) },
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300874 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) },
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300875 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) },
Chris Pascoe702a6762007-11-20 03:34:11 -0300876 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) },
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300877 { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) },
Michael Krufkyf35db232006-12-05 14:53:39 -0300878 {} /* Terminating entry */
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700879};
880MODULE_DEVICE_TABLE (usb, cxusb_table);
881
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300882static struct dvb_usb_device_properties cxusb_medion_properties = {
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700883 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
884
885 .usb_ctrl = CYPRESS_FX2,
886
887 .size_of_priv = sizeof(struct cxusb_state),
888
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300889 .num_adapters = 1,
890 .adapter = {
891 {
Patrick Boettcher01451e72006-10-13 11:34:46 -0300892 .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 },
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700906
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300907 },
908 },
909 .power_ctrl = cxusb_power_ctrl,
910
911 .i2c_algo = &cxusb_i2c_algo,
912
913 .generic_bulk_ctrl_endpoint = 0x01,
914
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700915 .num_device_descs = 1,
916 .devices = {
917 { "Medion MD95700 (MDUSBTV-HYBRID)",
918 { NULL },
919 { &cxusb_table[0], NULL },
920 },
921 }
922};
923
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300924static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = {
Michael Krufkyeffee032006-01-09 15:25:47 -0200925 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
926
Patrick Boettcherf5373782006-01-09 18:21:38 -0200927 .usb_ctrl = DEVICE_SPECIFIC,
928 .firmware = "dvb-usb-bluebird-01.fw",
929 .download_firmware = bluebird_patch_dvico_firmware_download,
Michael Krufky37bdfa02006-01-09 15:25:47 -0200930 /* use usb alt setting 0 for EP4 transfer (dvb-t),
931 use usb alt setting 7 for EP2 transfer (atsc) */
Michael Krufkyeffee032006-01-09 15:25:47 -0200932
933 .size_of_priv = sizeof(struct cxusb_state),
934
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300935 .num_adapters = 1,
936 .adapter = {
937 {
Patrick Boettcher01451e72006-10-13 11:34:46 -0300938 .streaming_ctrl = cxusb_streaming_ctrl,
939 .frontend_attach = cxusb_lgdt3303_frontend_attach,
Michael Krufkyf71a56c2006-10-13 21:55:57 -0300940 .tuner_attach = cxusb_lgh064f_tuner_attach,
Michael Krufkyeffee032006-01-09 15:25:47 -0200941
Patrick Boettcher01451e72006-10-13 11:34:46 -0300942 /* 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 },
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300953 },
954 },
955
956 .power_ctrl = cxusb_bluebird_power_ctrl,
957
Michael Krufkyeffee032006-01-09 15:25:47 -0200958 .i2c_algo = &cxusb_i2c_algo,
959
Michael Krufkyc1501782006-03-26 05:43:36 -0300960 .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
Michael Krufkyeffee032006-01-09 15:25:47 -0200965 .generic_bulk_ctrl_endpoint = 0x01,
Michael Krufkyeffee032006-01-09 15:25:47 -0200966
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
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300976static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = {
Chris Pascoe0029ee12006-01-09 18:21:28 -0200977 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
978
Patrick Boettcherf5373782006-01-09 18:21:38 -0200979 .usb_ctrl = DEVICE_SPECIFIC,
980 .firmware = "dvb-usb-bluebird-01.fw",
981 .download_firmware = bluebird_patch_dvico_firmware_download,
Chris Pascoe0029ee12006-01-09 18:21:28 -0200982 /* 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
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300987 .num_adapters = 1,
988 .adapter = {
989 {
Patrick Boettcher01451e72006-10-13 11:34:46 -0300990 .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 */
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300994 .stream = {
995 .type = USB_BULK,
Patrick Boettcher01451e72006-10-13 11:34:46 -0300996 .count = 5,
997 .endpoint = 0x04,
998 .u = {
999 .bulk = {
1000 .buffersize = 8192,
1001 }
1002 }
1003 },
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001004 },
1005 },
1006
1007 .power_ctrl = cxusb_bluebird_power_ctrl,
Chris Pascoe0029ee12006-01-09 18:21:28 -02001008
1009 .i2c_algo = &cxusb_i2c_algo,
1010
Chris Pascoe7c239702006-01-09 18:21:29 -02001011 .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
Chris Pascoe0029ee12006-01-09 18:21:28 -02001016 .generic_bulk_ctrl_endpoint = 0x01,
Chris Pascoe0029ee12006-01-09 18:21:28 -02001017
Michael Krufky587c03d2006-09-28 02:16:01 -03001018 .num_device_descs = 3,
Chris Pascoe0029ee12006-01-09 18:21:28 -02001019 .devices = {
1020 { "DViCO FusionHDTV DVB-T Dual USB",
1021 { &cxusb_table[3], NULL },
1022 { &cxusb_table[4], NULL },
1023 },
Michael Krufkyac9ffb92006-01-11 23:21:00 -02001024 { "DigitalNow DVB-T Dual USB",
1025 { &cxusb_table[9], NULL },
1026 { &cxusb_table[10], NULL },
1027 },
Michael Krufky587c03d2006-09-28 02:16:01 -03001028 { "DViCO FusionHDTV DVB-T Dual Digital 2",
1029 { &cxusb_table[11], NULL },
1030 { &cxusb_table[12], NULL },
1031 },
Chris Pascoe0029ee12006-01-09 18:21:28 -02001032 }
1033};
1034
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001035static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = {
Michael Krufky6f447252006-01-11 19:40:33 -02001036 .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
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001046 .num_adapters = 2,
1047 .adapter = {
1048 {
Patrick Boettcher01451e72006-10-13 11:34:46 -03001049 .streaming_ctrl = cxusb_streaming_ctrl,
1050 .frontend_attach = cxusb_mt352_frontend_attach,
1051 .tuner_attach = cxusb_lgz201_tuner_attach,
Michael Krufky6f447252006-01-11 19:40:33 -02001052
Patrick Boettcher01451e72006-10-13 11:34:46 -03001053 /* parameter for the MPEG2-data transfer */
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001054 .stream = {
1055 .type = USB_BULK,
Patrick Boettcher01451e72006-10-13 11:34:46 -03001056 .count = 5,
1057 .endpoint = 0x04,
1058 .u = {
1059 .bulk = {
1060 .buffersize = 8192,
1061 }
1062 }
1063 },
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001064 },
1065 },
1066 .power_ctrl = cxusb_bluebird_power_ctrl,
1067
Michael Krufky6f447252006-01-11 19:40:33 -02001068 .i2c_algo = &cxusb_i2c_algo,
1069
Michael Krufkyc1501782006-03-26 05:43:36 -03001070 .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
Michael Krufky6f447252006-01-11 19:40:33 -02001075 .generic_bulk_ctrl_endpoint = 0x01,
Michael Krufky6f447252006-01-11 19:40:33 -02001076 .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
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001085static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = {
Michael Krufky6f447252006-01-11 19:40:33 -02001086 .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
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001096 .num_adapters = 1,
1097 .adapter = {
1098 {
Patrick Boettcher01451e72006-10-13 11:34:46 -03001099 .streaming_ctrl = cxusb_streaming_ctrl,
1100 .frontend_attach = cxusb_mt352_frontend_attach,
1101 .tuner_attach = cxusb_dtt7579_tuner_attach,
Michael Krufky6f447252006-01-11 19:40:33 -02001102
Patrick Boettcher01451e72006-10-13 11:34:46 -03001103 /* parameter for the MPEG2-data transfer */
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001104 .stream = {
1105 .type = USB_BULK,
Patrick Boettcher01451e72006-10-13 11:34:46 -03001106 .count = 5,
1107 .endpoint = 0x04,
1108 .u = {
1109 .bulk = {
1110 .buffersize = 8192,
1111 }
1112 }
1113 },
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001114 },
1115 },
1116 .power_ctrl = cxusb_bluebird_power_ctrl,
1117
Michael Krufky6f447252006-01-11 19:40:33 -02001118 .i2c_algo = &cxusb_i2c_algo,
1119
Michael Krufkyc1501782006-03-26 05:43:36 -03001120 .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
Michael Krufky6f447252006-01-11 19:40:33 -02001125 .generic_bulk_ctrl_endpoint = 0x01,
Michael Krufky6f447252006-01-11 19:40:33 -02001126
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
Chris Pascoeaeb012b2007-11-19 21:57:10 -03001136static 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
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001183static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = {
1184 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1185
1186 .usb_ctrl = CYPRESS_FX2,
Chris Pascoe702a6762007-11-20 03:34:11 -03001187 .identify_state = bluebird_fx2_identify_state,
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001188
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
Chris Pascoe702a6762007-11-20 03:34:11 -03001231static 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
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03001281static 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
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001323static struct usb_driver cxusb_driver = {
Patrick Boettcher63b5c1c2005-07-07 17:58:30 -07001324 .name = "dvb_usb_cxusb",
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001325 .probe = cxusb_probe,
Michael Krufkyf35db232006-12-05 14:53:39 -03001326 .disconnect = dvb_usb_device_exit,
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001327 .id_table = cxusb_table,
1328};
1329
1330/* module stuff */
1331static 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
1342static void __exit cxusb_module_exit(void)
1343{
1344 /* deregister this driver from the USB subsystem */
1345 usb_deregister(&cxusb_driver);
1346}
1347
1348module_init (cxusb_module_init);
1349module_exit (cxusb_module_exit);
1350
1351MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
Michael Krufky5b9ed282006-10-15 14:51:08 -03001352MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
Michael Krufkyf4efb4d2006-01-13 14:10:25 -02001353MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001354MODULE_DESCRIPTION("Driver for Conexant USB2.0 hybrid reference design");
1355MODULE_VERSION("1.0-alpha");
1356MODULE_LICENSE("GPL");