blob: 563400277a426a5455e0d9036fdb5d608a0e416e [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");
Hans Verkuilc6eb8ea2008-09-03 17:11:54 -0300213 do {} while (!(ret = cxusb_ctrl_msg(d, CMD_POWER_ON, NULL, 0, NULL, 0)) &&
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300214 !(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{
Robert Loweryd483b732008-07-30 19:43:11 -0300568 struct dvb_usb_adapter *adap = ptr;
569 struct dvb_usb_device *d = adap->dev;
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300570
571 switch (command) {
572 case XC2028_TUNER_RESET:
Harvey Harrison708bebd2008-04-08 23:20:00 -0300573 deb_info("%s: XC2028_TUNER_RESET %d\n", __func__, arg);
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300574 cxusb_bluebird_gpio_pulse(d, 0x01, 1);
575 break;
576 case XC2028_RESET_CLK:
Harvey Harrison708bebd2008-04-08 23:20:00 -0300577 deb_info("%s: XC2028_RESET_CLK %d\n", __func__, arg);
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300578 break;
579 default:
Harvey Harrison708bebd2008-04-08 23:20:00 -0300580 deb_info("%s: unknown command %d, arg %d\n", __func__,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300581 command, arg);
582 return -EINVAL;
583 }
584
585 return 0;
586}
587
588static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap)
589{
590 struct dvb_frontend *fe;
591 struct xc2028_config cfg = {
592 .i2c_adap = &adap->dev->i2c_adap,
593 .i2c_addr = 0x61,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300594 .callback = dvico_bluebird_xc2028_callback,
595 };
596 static struct xc2028_ctrl ctl = {
Robert Loweryd483b732008-07-30 19:43:11 -0300597 .fname = "xc3028-v27.fw",
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300598 .max_len = 64,
Robert Loweryd483b732008-07-30 19:43:11 -0300599 .demod = XC3028_FE_ZARLINK456,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300600 };
601
602 fe = dvb_attach(xc2028_attach, adap->fe, &cfg);
603 if (fe == NULL || fe->ops.tuner_ops.set_config == NULL)
604 return -EIO;
605
606 fe->ops.tuner_ops.set_config(fe, &ctl);
607
608 return 0;
609}
610
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300611static int cxusb_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
612{
613 dvb_attach(mxl5005s_attach, adap->fe,
614 &adap->dev->i2c_adap, &aver_a868r_tuner);
615 return 0;
616}
617
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300618static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700619{
Patrick Boettchere2efeab2005-09-09 13:02:51 -0700620 u8 b;
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300621 if (usb_set_interface(adap->dev->udev, 0, 6) < 0)
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700622 err("set interface failed");
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700623
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300624 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, &b, 1);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700625
Michael Krufkyf35db232006-12-05 14:53:39 -0300626 if ((adap->fe = dvb_attach(cx22702_attach, &cxusb_cx22702_config,
627 &adap->dev->i2c_adap)) != NULL)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700628 return 0;
629
630 return -EIO;
631}
632
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300633static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
Michael Krufkyeffee032006-01-09 15:25:47 -0200634{
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300635 if (usb_set_interface(adap->dev->udev, 0, 7) < 0)
Michael Krufkyeffee032006-01-09 15:25:47 -0200636 err("set interface failed");
637
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300638 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
Michael Krufkyeffee032006-01-09 15:25:47 -0200639
Michael Krufkyf35db232006-12-05 14:53:39 -0300640 if ((adap->fe = dvb_attach(lgdt330x_attach, &cxusb_lgdt3303_config,
641 &adap->dev->i2c_adap)) != NULL)
Michael Krufkyeffee032006-01-09 15:25:47 -0200642 return 0;
643
644 return -EIO;
645}
646
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300647static int cxusb_aver_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
648{
649 adap->fe = dvb_attach(lgdt330x_attach, &cxusb_aver_lgdt3303_config,
650 &adap->dev->i2c_adap);
651 if (adap->fe != NULL)
652 return 0;
653
654 return -EIO;
655}
656
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300657static int cxusb_mt352_frontend_attach(struct dvb_usb_adapter *adap)
Chris Pascoe0029ee12006-01-09 18:21:28 -0200658{
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300659 /* used in both lgz201 and th7579 */
660 if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
Chris Pascoe0029ee12006-01-09 18:21:28 -0200661 err("set interface failed");
662
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300663 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
Chris Pascoe0029ee12006-01-09 18:21:28 -0200664
Michael Krufkyf35db232006-12-05 14:53:39 -0300665 if ((adap->fe = dvb_attach(mt352_attach, &cxusb_mt352_config,
666 &adap->dev->i2c_adap)) != NULL)
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300667 return 0;
668
669 return -EIO;
670}
671
672static int cxusb_dee1601_frontend_attach(struct dvb_usb_adapter *adap)
673{
674 if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
675 err("set interface failed");
676
677 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
678
Michael Krufkyf35db232006-12-05 14:53:39 -0300679 if (((adap->fe = dvb_attach(mt352_attach, &cxusb_dee1601_config,
680 &adap->dev->i2c_adap)) != NULL) ||
681 ((adap->fe = dvb_attach(zl10353_attach,
682 &cxusb_zl10353_dee1601_config,
683 &adap->dev->i2c_adap)) != NULL))
Chris Pascoe0029ee12006-01-09 18:21:28 -0200684 return 0;
685
686 return -EIO;
687}
688
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300689static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap)
690{
691 u8 ircode[4];
692 int i;
693 struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
694 .buf = ircode, .len = 4 };
695
696 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
697 err("set interface failed");
698
699 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
700
701 /* reset the tuner and demodulator */
702 cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
703 cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
704 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
705
706 if ((adap->fe = dvb_attach(zl10353_attach,
707 &cxusb_zl10353_xc3028_config,
708 &adap->dev->i2c_adap)) == NULL)
709 return -EIO;
710
711 /* try to determine if there is no IR decoder on the I2C bus */
712 for (i = 0; adap->dev->props.rc_key_map != NULL && i < 5; i++) {
713 msleep(20);
714 if (cxusb_i2c_xfer(&adap->dev->i2c_adap, &msg, 1) != 1)
715 goto no_IR;
716 if (ircode[0] == 0 && ircode[1] == 0)
717 continue;
718 if (ircode[2] + ircode[3] != 0xff) {
719no_IR:
720 adap->dev->props.rc_key_map = NULL;
721 info("No IR receiver detected on this device.");
722 break;
723 }
724 }
725
726 return 0;
727}
728
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300729static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap)
730{
731 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
732 err("set interface failed");
733
734 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
735
736 /* reset the tuner and demodulator */
737 cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
738 cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
739 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
740
741 if ((adap->fe = dvb_attach(zl10353_attach,
742 &cxusb_zl10353_xc3028_config,
743 &adap->dev->i2c_adap)) != NULL)
744 return 0;
745
Chris Pascoe702a6762007-11-20 03:34:11 -0300746 if ((adap->fe = dvb_attach(mt352_attach,
747 &cxusb_mt352_xc3028_config,
748 &adap->dev->i2c_adap)) != NULL)
749 return 0;
750
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300751 return -EIO;
752}
753
Patrick Boettcherf5373782006-01-09 18:21:38 -0200754/*
Chris Pascoe702a6762007-11-20 03:34:11 -0300755 * DViCO has shipped two devices with the same USB ID, but only one of them
756 * needs a firmware download. Check the device class details to see if they
757 * have non-default values to decide whether the device is actually cold or
758 * not, and forget a match if it turns out we selected the wrong device.
759 */
760static int bluebird_fx2_identify_state(struct usb_device *udev,
761 struct dvb_usb_device_properties *props,
762 struct dvb_usb_device_description **desc,
763 int *cold)
764{
765 int wascold = *cold;
766
767 *cold = udev->descriptor.bDeviceClass == 0xff &&
768 udev->descriptor.bDeviceSubClass == 0xff &&
769 udev->descriptor.bDeviceProtocol == 0xff;
770
771 if (*cold && !wascold)
772 *desc = NULL;
773
774 return 0;
775}
776
777/*
Patrick Boettcherf5373782006-01-09 18:21:38 -0200778 * DViCO bluebird firmware needs the "warm" product ID to be patched into the
779 * firmware file before download.
780 */
781
Chris Pascoe702a6762007-11-20 03:34:11 -0300782static const int dvico_firmware_id_offsets[] = { 6638, 3204 };
Michael Krufkyf35db232006-12-05 14:53:39 -0300783static int bluebird_patch_dvico_firmware_download(struct usb_device *udev,
784 const struct firmware *fw)
Patrick Boettcherf5373782006-01-09 18:21:38 -0200785{
Chris Pascoe702a6762007-11-20 03:34:11 -0300786 int pos;
Patrick Boettcherf5373782006-01-09 18:21:38 -0200787
Chris Pascoe702a6762007-11-20 03:34:11 -0300788 for (pos = 0; pos < ARRAY_SIZE(dvico_firmware_id_offsets); pos++) {
789 int idoff = dvico_firmware_id_offsets[pos];
Patrick Boettcherf5373782006-01-09 18:21:38 -0200790
Chris Pascoe702a6762007-11-20 03:34:11 -0300791 if (fw->size < idoff + 4)
792 continue;
Patrick Boettcherf5373782006-01-09 18:21:38 -0200793
Chris Pascoe702a6762007-11-20 03:34:11 -0300794 if (fw->data[idoff] == (USB_VID_DVICO & 0xff) &&
795 fw->data[idoff + 1] == USB_VID_DVICO >> 8) {
David Woodhousee62f89f2008-05-24 00:12:42 +0100796 struct firmware new_fw;
797 u8 *new_fw_data = vmalloc(fw->size);
798 int ret;
799
800 if (!new_fw_data)
801 return -ENOMEM;
802
803 memcpy(new_fw_data, fw->data, fw->size);
804 new_fw.size = fw->size;
805 new_fw.data = new_fw_data;
806
807 new_fw_data[idoff + 2] =
Chris Pascoe702a6762007-11-20 03:34:11 -0300808 le16_to_cpu(udev->descriptor.idProduct) + 1;
David Woodhousee62f89f2008-05-24 00:12:42 +0100809 new_fw_data[idoff + 3] =
Chris Pascoe702a6762007-11-20 03:34:11 -0300810 le16_to_cpu(udev->descriptor.idProduct) >> 8;
811
David Woodhousee62f89f2008-05-24 00:12:42 +0100812 ret = usb_cypress_load_firmware(udev, &new_fw,
813 CYPRESS_FX2);
814 vfree(new_fw_data);
815 return ret;
Chris Pascoe702a6762007-11-20 03:34:11 -0300816 }
Patrick Boettcherf5373782006-01-09 18:21:38 -0200817 }
818
819 return -EINVAL;
820}
821
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700822/* DVB USB Driver stuff */
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300823static struct dvb_usb_device_properties cxusb_medion_properties;
824static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties;
825static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties;
826static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties;
827static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties;
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300828static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties;
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300829static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties;
Chris Pascoe702a6762007-11-20 03:34:11 -0300830static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties;
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300831static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700832
833static int cxusb_probe(struct usb_interface *intf,
Michael Krufkyf35db232006-12-05 14:53:39 -0300834 const struct usb_device_id *id)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700835{
Janne Grunau78e92002008-04-09 19:13:13 -0300836 if (0 == dvb_usb_device_init(intf, &cxusb_medion_properties,
837 THIS_MODULE, NULL, adapter_nr) ||
838 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgh064f_properties,
839 THIS_MODULE, NULL, adapter_nr) ||
840 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dee1601_properties,
841 THIS_MODULE, NULL, adapter_nr) ||
842 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgz201_properties,
843 THIS_MODULE, NULL, adapter_nr) ||
844 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dtt7579_properties,
845 THIS_MODULE, NULL, adapter_nr) ||
846 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dualdig4_properties,
847 THIS_MODULE, NULL, adapter_nr) ||
848 0 == dvb_usb_device_init(intf, &cxusb_bluebird_nano2_properties,
849 THIS_MODULE, NULL, adapter_nr) ||
850 0 == dvb_usb_device_init(intf,
851 &cxusb_bluebird_nano2_needsfirmware_properties,
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300852 THIS_MODULE, NULL, adapter_nr) ||
853 0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties,
854 THIS_MODULE, NULL, adapter_nr) ||
855 0)
Michael Krufkyeffee032006-01-09 15:25:47 -0200856 return 0;
Michael Krufkyeffee032006-01-09 15:25:47 -0200857
858 return -EINVAL;
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700859}
860
861static struct usb_device_id cxusb_table [] = {
Michael Krufkyf35db232006-12-05 14:53:39 -0300862 { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) },
863 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) },
864 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_WARM) },
865 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_COLD) },
866 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM) },
867 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_COLD) },
868 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_WARM) },
869 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_COLD) },
870 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_WARM) },
871 { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD) },
872 { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM) },
873 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD) },
874 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM) },
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300875 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) },
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300876 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) },
Chris Pascoe702a6762007-11-20 03:34:11 -0300877 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) },
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300878 { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) },
Michael Krufkyf35db232006-12-05 14:53:39 -0300879 {} /* Terminating entry */
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700880};
881MODULE_DEVICE_TABLE (usb, cxusb_table);
882
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300883static struct dvb_usb_device_properties cxusb_medion_properties = {
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700884 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
885
886 .usb_ctrl = CYPRESS_FX2,
887
888 .size_of_priv = sizeof(struct cxusb_state),
889
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300890 .num_adapters = 1,
891 .adapter = {
892 {
Patrick Boettcher01451e72006-10-13 11:34:46 -0300893 .streaming_ctrl = cxusb_streaming_ctrl,
894 .frontend_attach = cxusb_cx22702_frontend_attach,
895 .tuner_attach = cxusb_fmd1216me_tuner_attach,
896 /* parameter for the MPEG2-data transfer */
897 .stream = {
898 .type = USB_BULK,
899 .count = 5,
900 .endpoint = 0x02,
901 .u = {
902 .bulk = {
903 .buffersize = 8192,
904 }
905 }
906 },
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700907
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300908 },
909 },
910 .power_ctrl = cxusb_power_ctrl,
911
912 .i2c_algo = &cxusb_i2c_algo,
913
914 .generic_bulk_ctrl_endpoint = 0x01,
915
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700916 .num_device_descs = 1,
917 .devices = {
918 { "Medion MD95700 (MDUSBTV-HYBRID)",
919 { NULL },
920 { &cxusb_table[0], NULL },
921 },
922 }
923};
924
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300925static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = {
Michael Krufkyeffee032006-01-09 15:25:47 -0200926 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
927
Patrick Boettcherf5373782006-01-09 18:21:38 -0200928 .usb_ctrl = DEVICE_SPECIFIC,
929 .firmware = "dvb-usb-bluebird-01.fw",
930 .download_firmware = bluebird_patch_dvico_firmware_download,
Michael Krufky37bdfa02006-01-09 15:25:47 -0200931 /* use usb alt setting 0 for EP4 transfer (dvb-t),
932 use usb alt setting 7 for EP2 transfer (atsc) */
Michael Krufkyeffee032006-01-09 15:25:47 -0200933
934 .size_of_priv = sizeof(struct cxusb_state),
935
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300936 .num_adapters = 1,
937 .adapter = {
938 {
Patrick Boettcher01451e72006-10-13 11:34:46 -0300939 .streaming_ctrl = cxusb_streaming_ctrl,
940 .frontend_attach = cxusb_lgdt3303_frontend_attach,
Michael Krufkyf71a56c2006-10-13 21:55:57 -0300941 .tuner_attach = cxusb_lgh064f_tuner_attach,
Michael Krufkyeffee032006-01-09 15:25:47 -0200942
Patrick Boettcher01451e72006-10-13 11:34:46 -0300943 /* parameter for the MPEG2-data transfer */
944 .stream = {
945 .type = USB_BULK,
946 .count = 5,
947 .endpoint = 0x02,
948 .u = {
949 .bulk = {
950 .buffersize = 8192,
951 }
952 }
953 },
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300954 },
955 },
956
957 .power_ctrl = cxusb_bluebird_power_ctrl,
958
Michael Krufkyeffee032006-01-09 15:25:47 -0200959 .i2c_algo = &cxusb_i2c_algo,
960
Michael Krufkyc1501782006-03-26 05:43:36 -0300961 .rc_interval = 100,
962 .rc_key_map = dvico_portable_rc_keys,
963 .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys),
964 .rc_query = cxusb_rc_query,
965
Michael Krufkyeffee032006-01-09 15:25:47 -0200966 .generic_bulk_ctrl_endpoint = 0x01,
Michael Krufkyeffee032006-01-09 15:25:47 -0200967
968 .num_device_descs = 1,
969 .devices = {
970 { "DViCO FusionHDTV5 USB Gold",
971 { &cxusb_table[1], NULL },
972 { &cxusb_table[2], NULL },
973 },
974 }
975};
976
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300977static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = {
Chris Pascoe0029ee12006-01-09 18:21:28 -0200978 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
979
Patrick Boettcherf5373782006-01-09 18:21:38 -0200980 .usb_ctrl = DEVICE_SPECIFIC,
981 .firmware = "dvb-usb-bluebird-01.fw",
982 .download_firmware = bluebird_patch_dvico_firmware_download,
Chris Pascoe0029ee12006-01-09 18:21:28 -0200983 /* use usb alt setting 0 for EP4 transfer (dvb-t),
984 use usb alt setting 7 for EP2 transfer (atsc) */
985
986 .size_of_priv = sizeof(struct cxusb_state),
987
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300988 .num_adapters = 1,
989 .adapter = {
990 {
Patrick Boettcher01451e72006-10-13 11:34:46 -0300991 .streaming_ctrl = cxusb_streaming_ctrl,
992 .frontend_attach = cxusb_dee1601_frontend_attach,
993 .tuner_attach = cxusb_dee1601_tuner_attach,
994 /* parameter for the MPEG2-data transfer */
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300995 .stream = {
996 .type = USB_BULK,
Patrick Boettcher01451e72006-10-13 11:34:46 -0300997 .count = 5,
998 .endpoint = 0x04,
999 .u = {
1000 .bulk = {
1001 .buffersize = 8192,
1002 }
1003 }
1004 },
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001005 },
1006 },
1007
1008 .power_ctrl = cxusb_bluebird_power_ctrl,
Chris Pascoe0029ee12006-01-09 18:21:28 -02001009
1010 .i2c_algo = &cxusb_i2c_algo,
1011
Chris Pascoe7c239702006-01-09 18:21:29 -02001012 .rc_interval = 150,
1013 .rc_key_map = dvico_mce_rc_keys,
1014 .rc_key_map_size = ARRAY_SIZE(dvico_mce_rc_keys),
1015 .rc_query = cxusb_rc_query,
1016
Chris Pascoe0029ee12006-01-09 18:21:28 -02001017 .generic_bulk_ctrl_endpoint = 0x01,
Chris Pascoe0029ee12006-01-09 18:21:28 -02001018
Michael Krufky587c03d2006-09-28 02:16:01 -03001019 .num_device_descs = 3,
Chris Pascoe0029ee12006-01-09 18:21:28 -02001020 .devices = {
1021 { "DViCO FusionHDTV DVB-T Dual USB",
1022 { &cxusb_table[3], NULL },
1023 { &cxusb_table[4], NULL },
1024 },
Michael Krufkyac9ffb92006-01-11 23:21:00 -02001025 { "DigitalNow DVB-T Dual USB",
1026 { &cxusb_table[9], NULL },
1027 { &cxusb_table[10], NULL },
1028 },
Michael Krufky587c03d2006-09-28 02:16:01 -03001029 { "DViCO FusionHDTV DVB-T Dual Digital 2",
1030 { &cxusb_table[11], NULL },
1031 { &cxusb_table[12], NULL },
1032 },
Chris Pascoe0029ee12006-01-09 18:21:28 -02001033 }
1034};
1035
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001036static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = {
Michael Krufky6f447252006-01-11 19:40:33 -02001037 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1038
1039 .usb_ctrl = DEVICE_SPECIFIC,
1040 .firmware = "dvb-usb-bluebird-01.fw",
1041 .download_firmware = bluebird_patch_dvico_firmware_download,
1042 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1043 use usb alt setting 7 for EP2 transfer (atsc) */
1044
1045 .size_of_priv = sizeof(struct cxusb_state),
1046
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001047 .num_adapters = 2,
1048 .adapter = {
1049 {
Patrick Boettcher01451e72006-10-13 11:34:46 -03001050 .streaming_ctrl = cxusb_streaming_ctrl,
1051 .frontend_attach = cxusb_mt352_frontend_attach,
1052 .tuner_attach = cxusb_lgz201_tuner_attach,
Michael Krufky6f447252006-01-11 19:40:33 -02001053
Patrick Boettcher01451e72006-10-13 11:34:46 -03001054 /* parameter for the MPEG2-data transfer */
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001055 .stream = {
1056 .type = USB_BULK,
Patrick Boettcher01451e72006-10-13 11:34:46 -03001057 .count = 5,
1058 .endpoint = 0x04,
1059 .u = {
1060 .bulk = {
1061 .buffersize = 8192,
1062 }
1063 }
1064 },
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001065 },
1066 },
1067 .power_ctrl = cxusb_bluebird_power_ctrl,
1068
Michael Krufky6f447252006-01-11 19:40:33 -02001069 .i2c_algo = &cxusb_i2c_algo,
1070
Michael Krufkyc1501782006-03-26 05:43:36 -03001071 .rc_interval = 100,
1072 .rc_key_map = dvico_portable_rc_keys,
1073 .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys),
1074 .rc_query = cxusb_rc_query,
1075
Michael Krufky6f447252006-01-11 19:40:33 -02001076 .generic_bulk_ctrl_endpoint = 0x01,
Michael Krufky6f447252006-01-11 19:40:33 -02001077 .num_device_descs = 1,
1078 .devices = {
1079 { "DViCO FusionHDTV DVB-T USB (LGZ201)",
1080 { &cxusb_table[5], NULL },
1081 { &cxusb_table[6], NULL },
1082 },
1083 }
1084};
1085
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001086static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = {
Michael Krufky6f447252006-01-11 19:40:33 -02001087 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1088
1089 .usb_ctrl = DEVICE_SPECIFIC,
1090 .firmware = "dvb-usb-bluebird-01.fw",
1091 .download_firmware = bluebird_patch_dvico_firmware_download,
1092 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1093 use usb alt setting 7 for EP2 transfer (atsc) */
1094
1095 .size_of_priv = sizeof(struct cxusb_state),
1096
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001097 .num_adapters = 1,
1098 .adapter = {
1099 {
Patrick Boettcher01451e72006-10-13 11:34:46 -03001100 .streaming_ctrl = cxusb_streaming_ctrl,
1101 .frontend_attach = cxusb_mt352_frontend_attach,
1102 .tuner_attach = cxusb_dtt7579_tuner_attach,
Michael Krufky6f447252006-01-11 19:40:33 -02001103
Patrick Boettcher01451e72006-10-13 11:34:46 -03001104 /* parameter for the MPEG2-data transfer */
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001105 .stream = {
1106 .type = USB_BULK,
Patrick Boettcher01451e72006-10-13 11:34:46 -03001107 .count = 5,
1108 .endpoint = 0x04,
1109 .u = {
1110 .bulk = {
1111 .buffersize = 8192,
1112 }
1113 }
1114 },
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001115 },
1116 },
1117 .power_ctrl = cxusb_bluebird_power_ctrl,
1118
Michael Krufky6f447252006-01-11 19:40:33 -02001119 .i2c_algo = &cxusb_i2c_algo,
1120
Michael Krufkyc1501782006-03-26 05:43:36 -03001121 .rc_interval = 100,
1122 .rc_key_map = dvico_portable_rc_keys,
1123 .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys),
1124 .rc_query = cxusb_rc_query,
1125
Michael Krufky6f447252006-01-11 19:40:33 -02001126 .generic_bulk_ctrl_endpoint = 0x01,
Michael Krufky6f447252006-01-11 19:40:33 -02001127
1128 .num_device_descs = 1,
1129 .devices = {
1130 { "DViCO FusionHDTV DVB-T USB (TH7579)",
1131 { &cxusb_table[7], NULL },
1132 { &cxusb_table[8], NULL },
1133 },
1134 }
1135};
1136
Chris Pascoeaeb012b2007-11-19 21:57:10 -03001137static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = {
1138 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1139
1140 .usb_ctrl = CYPRESS_FX2,
1141
1142 .size_of_priv = sizeof(struct cxusb_state),
1143
1144 .num_adapters = 1,
1145 .adapter = {
1146 {
1147 .streaming_ctrl = cxusb_streaming_ctrl,
1148 .frontend_attach = cxusb_dualdig4_frontend_attach,
1149 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1150 /* parameter for the MPEG2-data transfer */
1151 .stream = {
1152 .type = USB_BULK,
1153 .count = 5,
1154 .endpoint = 0x02,
1155 .u = {
1156 .bulk = {
1157 .buffersize = 8192,
1158 }
1159 }
1160 },
1161 },
1162 },
1163
1164 .power_ctrl = cxusb_power_ctrl,
1165
1166 .i2c_algo = &cxusb_i2c_algo,
1167
1168 .generic_bulk_ctrl_endpoint = 0x01,
1169
1170 .rc_interval = 100,
1171 .rc_key_map = dvico_mce_rc_keys,
1172 .rc_key_map_size = ARRAY_SIZE(dvico_mce_rc_keys),
1173 .rc_query = cxusb_bluebird2_rc_query,
1174
1175 .num_device_descs = 1,
1176 .devices = {
1177 { "DViCO FusionHDTV DVB-T Dual Digital 4",
1178 { NULL },
1179 { &cxusb_table[13], NULL },
1180 },
1181 }
1182};
1183
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001184static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = {
1185 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1186
1187 .usb_ctrl = CYPRESS_FX2,
Chris Pascoe702a6762007-11-20 03:34:11 -03001188 .identify_state = bluebird_fx2_identify_state,
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001189
1190 .size_of_priv = sizeof(struct cxusb_state),
1191
1192 .num_adapters = 1,
1193 .adapter = {
1194 {
1195 .streaming_ctrl = cxusb_streaming_ctrl,
1196 .frontend_attach = cxusb_nano2_frontend_attach,
1197 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1198 /* parameter for the MPEG2-data transfer */
1199 .stream = {
1200 .type = USB_BULK,
1201 .count = 5,
1202 .endpoint = 0x02,
1203 .u = {
1204 .bulk = {
1205 .buffersize = 8192,
1206 }
1207 }
1208 },
1209 },
1210 },
1211
1212 .power_ctrl = cxusb_nano2_power_ctrl,
1213
1214 .i2c_algo = &cxusb_i2c_algo,
1215
1216 .generic_bulk_ctrl_endpoint = 0x01,
1217
1218 .rc_interval = 100,
1219 .rc_key_map = dvico_portable_rc_keys,
1220 .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys),
1221 .rc_query = cxusb_bluebird2_rc_query,
1222
1223 .num_device_descs = 1,
1224 .devices = {
1225 { "DViCO FusionHDTV DVB-T NANO2",
1226 { NULL },
1227 { &cxusb_table[14], NULL },
1228 },
1229 }
1230};
1231
Chris Pascoe702a6762007-11-20 03:34:11 -03001232static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties = {
1233 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1234
1235 .usb_ctrl = DEVICE_SPECIFIC,
1236 .firmware = "dvb-usb-bluebird-02.fw",
1237 .download_firmware = bluebird_patch_dvico_firmware_download,
1238 .identify_state = bluebird_fx2_identify_state,
1239
1240 .size_of_priv = sizeof(struct cxusb_state),
1241
1242 .num_adapters = 1,
1243 .adapter = {
1244 {
1245 .streaming_ctrl = cxusb_streaming_ctrl,
1246 .frontend_attach = cxusb_nano2_frontend_attach,
1247 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1248 /* parameter for the MPEG2-data transfer */
1249 .stream = {
1250 .type = USB_BULK,
1251 .count = 5,
1252 .endpoint = 0x02,
1253 .u = {
1254 .bulk = {
1255 .buffersize = 8192,
1256 }
1257 }
1258 },
1259 },
1260 },
1261
1262 .power_ctrl = cxusb_nano2_power_ctrl,
1263
1264 .i2c_algo = &cxusb_i2c_algo,
1265
1266 .generic_bulk_ctrl_endpoint = 0x01,
1267
1268 .rc_interval = 100,
1269 .rc_key_map = dvico_portable_rc_keys,
1270 .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys),
1271 .rc_query = cxusb_rc_query,
1272
1273 .num_device_descs = 1,
1274 .devices = {
1275 { "DViCO FusionHDTV DVB-T NANO2 w/o firmware",
1276 { &cxusb_table[14], NULL },
1277 { &cxusb_table[15], NULL },
1278 },
1279 }
1280};
1281
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03001282static struct dvb_usb_device_properties cxusb_aver_a868r_properties = {
1283 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1284
1285 .usb_ctrl = CYPRESS_FX2,
1286
1287 .size_of_priv = sizeof(struct cxusb_state),
1288
1289 .num_adapters = 1,
1290 .adapter = {
1291 {
1292 .streaming_ctrl = cxusb_aver_streaming_ctrl,
1293 .frontend_attach = cxusb_aver_lgdt3303_frontend_attach,
1294 .tuner_attach = cxusb_mxl5003s_tuner_attach,
1295 /* parameter for the MPEG2-data transfer */
1296 .stream = {
1297 .type = USB_BULK,
1298 .count = 5,
1299 .endpoint = 0x04,
1300 .u = {
1301 .bulk = {
1302 .buffersize = 8192,
1303 }
1304 }
1305 },
1306
1307 },
1308 },
1309 .power_ctrl = cxusb_aver_power_ctrl,
1310
1311 .i2c_algo = &cxusb_i2c_algo,
1312
1313 .generic_bulk_ctrl_endpoint = 0x01,
1314
1315 .num_device_descs = 1,
1316 .devices = {
1317 { "AVerMedia AVerTVHD Volar (A868R)",
1318 { NULL },
1319 { &cxusb_table[16], NULL },
1320 },
1321 }
1322};
1323
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001324static struct usb_driver cxusb_driver = {
Patrick Boettcher63b5c1c2005-07-07 17:58:30 -07001325 .name = "dvb_usb_cxusb",
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001326 .probe = cxusb_probe,
Michael Krufkyf35db232006-12-05 14:53:39 -03001327 .disconnect = dvb_usb_device_exit,
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001328 .id_table = cxusb_table,
1329};
1330
1331/* module stuff */
1332static int __init cxusb_module_init(void)
1333{
1334 int result;
1335 if ((result = usb_register(&cxusb_driver))) {
1336 err("usb_register failed. Error number %d",result);
1337 return result;
1338 }
1339
1340 return 0;
1341}
1342
1343static void __exit cxusb_module_exit(void)
1344{
1345 /* deregister this driver from the USB subsystem */
1346 usb_deregister(&cxusb_driver);
1347}
1348
1349module_init (cxusb_module_init);
1350module_exit (cxusb_module_exit);
1351
1352MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
Michael Krufky5b9ed282006-10-15 14:51:08 -03001353MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
Michael Krufkyf4efb4d2006-01-13 14:10:25 -02001354MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001355MODULE_DESCRIPTION("Driver for Conexant USB2.0 hybrid reference design");
1356MODULE_VERSION("1.0-alpha");
1357MODULE_LICENSE("GPL");