blob: 720fcd1c3c1d75caad387932f9bc56329c42ff47 [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>
27
Patrick Boettcher22c6d932005-07-07 17:58:10 -070028#include "cxusb.h"
29
30#include "cx22702.h"
Michael Krufkyeffee032006-01-09 15:25:47 -020031#include "lgdt330x.h"
Chris Pascoe0029ee12006-01-09 18:21:28 -020032#include "mt352.h"
33#include "mt352_priv.h"
Michael Krufkyc9ce3942006-06-11 04:24:31 -030034#include "zl10353.h"
Chris Pascoeaeb012b2007-11-19 21:57:10 -030035#include "tuner-xc2028.h"
Michael Krufky827855d2008-04-22 14:46:16 -030036#include "tuner-simple.h"
Patrick Boettcher22c6d932005-07-07 17:58:10 -070037
38/* debug */
Adrian Bunk53133af2007-11-05 14:07:06 -030039static int dvb_usb_cxusb_debug;
Michael Krufkyf35db232006-12-05 14:53:39 -030040module_param_named(debug, dvb_usb_cxusb_debug, int, 0644);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070041MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
Janne Grunau78e92002008-04-09 19:13:13 -030042
43DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
44
Adrian Bunk53133af2007-11-05 14:07:06 -030045#define deb_info(args...) dprintk(dvb_usb_cxusb_debug,0x01,args)
46#define deb_i2c(args...) if (d->udev->descriptor.idVendor == USB_VID_MEDION) \
47 dprintk(dvb_usb_cxusb_debug,0x01,args)
Patrick Boettcher22c6d932005-07-07 17:58:10 -070048
49static int cxusb_ctrl_msg(struct dvb_usb_device *d,
Michael Krufkyf35db232006-12-05 14:53:39 -030050 u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
Patrick Boettcher22c6d932005-07-07 17:58:10 -070051{
52 int wo = (rbuf == NULL || rlen == 0); /* write-only */
53 u8 sndbuf[1+wlen];
Michael Krufkyf35db232006-12-05 14:53:39 -030054 memset(sndbuf, 0, 1+wlen);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070055
56 sndbuf[0] = cmd;
Michael Krufkyf35db232006-12-05 14:53:39 -030057 memcpy(&sndbuf[1], wbuf, wlen);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070058 if (wo)
Chris Pascoeb17f1092007-11-19 02:42:44 -030059 return dvb_usb_generic_write(d, sndbuf, 1+wlen);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070060 else
Chris Pascoeb17f1092007-11-19 02:42:44 -030061 return dvb_usb_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen, 0);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070062}
63
Patrick Boettchere2efeab2005-09-09 13:02:51 -070064/* GPIO */
65static void cxusb_gpio_tuner(struct dvb_usb_device *d, int onoff)
Patrick Boettcher22c6d932005-07-07 17:58:10 -070066{
67 struct cxusb_state *st = d->priv;
Michael Krufkyf35db232006-12-05 14:53:39 -030068 u8 o[2], i;
Patrick Boettcher22c6d932005-07-07 17:58:10 -070069
Patrick Boettchere2efeab2005-09-09 13:02:51 -070070 if (st->gpio_write_state[GPIO_TUNER] == onoff)
Patrick Boettcher22c6d932005-07-07 17:58:10 -070071 return;
72
Patrick Boettchere2efeab2005-09-09 13:02:51 -070073 o[0] = GPIO_TUNER;
74 o[1] = onoff;
Michael Krufkyf35db232006-12-05 14:53:39 -030075 cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070076
77 if (i != 0x01)
Patrick Boettchere2efeab2005-09-09 13:02:51 -070078 deb_info("gpio_write failed.\n");
Patrick Boettcher22c6d932005-07-07 17:58:10 -070079
Patrick Boettchere2efeab2005-09-09 13:02:51 -070080 st->gpio_write_state[GPIO_TUNER] = onoff;
Patrick Boettcher22c6d932005-07-07 17:58:10 -070081}
82
Chris Pascoeaeb012b2007-11-19 21:57:10 -030083static int cxusb_bluebird_gpio_rw(struct dvb_usb_device *d, u8 changemask,
84 u8 newval)
85{
86 u8 o[2], gpio_state;
87 int rc;
88
89 o[0] = 0xff & ~changemask; /* mask of bits to keep */
90 o[1] = newval & changemask; /* new values for bits */
91
92 rc = cxusb_ctrl_msg(d, CMD_BLUEBIRD_GPIO_RW, o, 2, &gpio_state, 1);
93 if (rc < 0 || (gpio_state & changemask) != (newval & changemask))
94 deb_info("bluebird_gpio_write failed.\n");
95
96 return rc < 0 ? rc : gpio_state;
97}
98
99static void cxusb_bluebird_gpio_pulse(struct dvb_usb_device *d, u8 pin, int low)
100{
101 cxusb_bluebird_gpio_rw(d, pin, low ? 0 : pin);
102 msleep(5);
103 cxusb_bluebird_gpio_rw(d, pin, low ? pin : 0);
104}
105
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300106static void cxusb_nano2_led(struct dvb_usb_device *d, int onoff)
107{
108 cxusb_bluebird_gpio_rw(d, 0x40, onoff ? 0 : 0x40);
109}
110
Patrick Boettchere2efeab2005-09-09 13:02:51 -0700111/* I2C */
Michael Krufkyf35db232006-12-05 14:53:39 -0300112static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
113 int num)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700114{
115 struct dvb_usb_device *d = i2c_get_adapdata(adap);
116 int i;
117
Ingo Molnar3593cab2006-02-07 06:49:14 -0200118 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700119 return -EAGAIN;
120
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700121 for (i = 0; i < num; i++) {
122
Michael Krufky5e805ef2006-03-23 00:01:34 -0300123 if (d->udev->descriptor.idVendor == USB_VID_MEDION)
124 switch (msg[i].addr) {
Michael Krufkyf35db232006-12-05 14:53:39 -0300125 case 0x63:
126 cxusb_gpio_tuner(d, 0);
127 break;
128 default:
129 cxusb_gpio_tuner(d, 1);
130 break;
Michael Krufky5e805ef2006-03-23 00:01:34 -0300131 }
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700132
Chris Pascoe272479d72007-11-19 03:01:22 -0300133 if (msg[i].flags & I2C_M_RD) {
134 /* read only */
135 u8 obuf[3], ibuf[1+msg[i].len];
136 obuf[0] = 0;
137 obuf[1] = msg[i].len;
138 obuf[2] = msg[i].addr;
139 if (cxusb_ctrl_msg(d, CMD_I2C_READ,
140 obuf, 3,
141 ibuf, 1+msg[i].len) < 0) {
142 warn("i2c read failed");
143 break;
144 }
145 memcpy(msg[i].buf, &ibuf[1], msg[i].len);
Chris Pascoea644e4a2007-11-19 03:05:09 -0300146 } else if (i+1 < num && (msg[i+1].flags & I2C_M_RD) &&
147 msg[i].addr == msg[i+1].addr) {
148 /* write to then read from same address */
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700149 u8 obuf[3+msg[i].len], ibuf[1+msg[i+1].len];
150 obuf[0] = msg[i].len;
151 obuf[1] = msg[i+1].len;
152 obuf[2] = msg[i].addr;
Michael Krufkyf35db232006-12-05 14:53:39 -0300153 memcpy(&obuf[3], msg[i].buf, msg[i].len);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700154
155 if (cxusb_ctrl_msg(d, CMD_I2C_READ,
Michael Krufkyf35db232006-12-05 14:53:39 -0300156 obuf, 3+msg[i].len,
157 ibuf, 1+msg[i+1].len) < 0)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700158 break;
159
160 if (ibuf[0] != 0x08)
Michael Krufkyae62e3d2006-03-23 01:11:18 -0300161 deb_i2c("i2c read may have failed\n");
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700162
Michael Krufkyf35db232006-12-05 14:53:39 -0300163 memcpy(msg[i+1].buf, &ibuf[1], msg[i+1].len);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700164
165 i++;
Chris Pascoe272479d72007-11-19 03:01:22 -0300166 } else {
167 /* write only */
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700168 u8 obuf[2+msg[i].len], ibuf;
169 obuf[0] = msg[i].addr;
170 obuf[1] = msg[i].len;
Michael Krufkyf35db232006-12-05 14:53:39 -0300171 memcpy(&obuf[2], msg[i].buf, msg[i].len);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700172
Michael Krufkyf35db232006-12-05 14:53:39 -0300173 if (cxusb_ctrl_msg(d, CMD_I2C_WRITE, obuf,
174 2+msg[i].len, &ibuf,1) < 0)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700175 break;
176 if (ibuf != 0x08)
Michael Krufkyae62e3d2006-03-23 01:11:18 -0300177 deb_i2c("i2c write may have failed\n");
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700178 }
179 }
180
Ingo Molnar3593cab2006-02-07 06:49:14 -0200181 mutex_unlock(&d->i2c_mutex);
Chris Pascoe13e001d2007-11-19 02:48:27 -0300182 return i == num ? num : -EREMOTEIO;
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700183}
184
185static u32 cxusb_i2c_func(struct i2c_adapter *adapter)
186{
187 return I2C_FUNC_I2C;
188}
189
190static struct i2c_algorithm cxusb_i2c_algo = {
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700191 .master_xfer = cxusb_i2c_xfer,
192 .functionality = cxusb_i2c_func,
193};
194
195static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff)
196{
Patrick Boettchere2efeab2005-09-09 13:02:51 -0700197 u8 b = 0;
198 if (onoff)
199 return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
200 else
201 return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700202}
203
Michael Krufky5691c842006-04-19 20:40:01 -0300204static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff)
205{
206 u8 b = 0;
207 if (onoff)
208 return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
209 else
210 return 0;
211}
212
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300213static int cxusb_nano2_power_ctrl(struct dvb_usb_device *d, int onoff)
214{
215 int rc = 0;
216
217 rc = cxusb_power_ctrl(d, onoff);
218 if (!onoff)
219 cxusb_nano2_led(d, 0);
220
221 return rc;
222}
223
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300224static int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700225{
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700226 u8 buf[2] = { 0x03, 0x00 };
227 if (onoff)
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300228 cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON, buf, 2, NULL, 0);
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700229 else
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300230 cxusb_ctrl_msg(adap->dev, CMD_STREAMING_OFF, NULL, 0, NULL, 0);
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700231
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700232 return 0;
233}
234
Chris Pascoe7c239702006-01-09 18:21:29 -0200235static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
236{
237 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
Michael Krufkya07e6092006-01-09 18:21:31 -0200238 u8 ircode[4];
Chris Pascoe7c239702006-01-09 18:21:29 -0200239 int i;
240
Michael Krufkya07e6092006-01-09 18:21:31 -0200241 cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4);
Chris Pascoe7c239702006-01-09 18:21:29 -0200242
243 *event = 0;
244 *state = REMOTE_NO_KEY_PRESSED;
245
246 for (i = 0; i < d->props.rc_key_map_size; i++) {
Michael Krufkya07e6092006-01-09 18:21:31 -0200247 if (keymap[i].custom == ircode[2] &&
248 keymap[i].data == ircode[3]) {
Chris Pascoe7c239702006-01-09 18:21:29 -0200249 *event = keymap[i].event;
250 *state = REMOTE_KEY_PRESSED;
251
252 return 0;
253 }
254 }
255
256 return 0;
257}
258
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300259static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event,
260 int *state)
261{
262 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
263 u8 ircode[4];
264 int i;
265 struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
266 .buf = ircode, .len = 4 };
267
268 *event = 0;
269 *state = REMOTE_NO_KEY_PRESSED;
270
271 if (cxusb_i2c_xfer(&d->i2c_adap, &msg, 1) != 1)
272 return 0;
273
274 for (i = 0; i < d->props.rc_key_map_size; i++) {
275 if (keymap[i].custom == ircode[1] &&
276 keymap[i].data == ircode[2]) {
277 *event = keymap[i].event;
278 *state = REMOTE_KEY_PRESSED;
279
280 return 0;
281 }
282 }
283
284 return 0;
285}
286
Adrian Bunk703cb2c2006-01-23 17:11:09 -0200287static struct dvb_usb_rc_key dvico_mce_rc_keys[] = {
Michael Krufkya07e6092006-01-09 18:21:31 -0200288 { 0xfe, 0x02, KEY_TV },
289 { 0xfe, 0x0e, KEY_MP3 },
290 { 0xfe, 0x1a, KEY_DVD },
291 { 0xfe, 0x1e, KEY_FAVORITES },
292 { 0xfe, 0x16, KEY_SETUP },
293 { 0xfe, 0x46, KEY_POWER2 },
294 { 0xfe, 0x0a, KEY_EPG },
295 { 0xfe, 0x49, KEY_BACK },
296 { 0xfe, 0x4d, KEY_MENU },
297 { 0xfe, 0x51, KEY_UP },
298 { 0xfe, 0x5b, KEY_LEFT },
299 { 0xfe, 0x5f, KEY_RIGHT },
300 { 0xfe, 0x53, KEY_DOWN },
301 { 0xfe, 0x5e, KEY_OK },
302 { 0xfe, 0x59, KEY_INFO },
303 { 0xfe, 0x55, KEY_TAB },
304 { 0xfe, 0x0f, KEY_PREVIOUSSONG },/* Replay */
305 { 0xfe, 0x12, KEY_NEXTSONG }, /* Skip */
306 { 0xfe, 0x42, KEY_ENTER }, /* Windows/Start */
307 { 0xfe, 0x15, KEY_VOLUMEUP },
308 { 0xfe, 0x05, KEY_VOLUMEDOWN },
309 { 0xfe, 0x11, KEY_CHANNELUP },
310 { 0xfe, 0x09, KEY_CHANNELDOWN },
311 { 0xfe, 0x52, KEY_CAMERA },
312 { 0xfe, 0x5a, KEY_TUNER }, /* Live */
313 { 0xfe, 0x19, KEY_OPEN },
314 { 0xfe, 0x0b, KEY_1 },
315 { 0xfe, 0x17, KEY_2 },
316 { 0xfe, 0x1b, KEY_3 },
317 { 0xfe, 0x07, KEY_4 },
318 { 0xfe, 0x50, KEY_5 },
319 { 0xfe, 0x54, KEY_6 },
320 { 0xfe, 0x48, KEY_7 },
321 { 0xfe, 0x4c, KEY_8 },
322 { 0xfe, 0x58, KEY_9 },
323 { 0xfe, 0x13, KEY_ANGLE }, /* Aspect */
324 { 0xfe, 0x03, KEY_0 },
325 { 0xfe, 0x1f, KEY_ZOOM },
326 { 0xfe, 0x43, KEY_REWIND },
327 { 0xfe, 0x47, KEY_PLAYPAUSE },
328 { 0xfe, 0x4f, KEY_FASTFORWARD },
329 { 0xfe, 0x57, KEY_MUTE },
330 { 0xfe, 0x0d, KEY_STOP },
331 { 0xfe, 0x01, KEY_RECORD },
332 { 0xfe, 0x4e, KEY_POWER },
333};
334
Michael Krufkyc1501782006-03-26 05:43:36 -0300335static struct dvb_usb_rc_key dvico_portable_rc_keys[] = {
336 { 0xfc, 0x02, KEY_SETUP }, /* Profile */
337 { 0xfc, 0x43, KEY_POWER2 },
338 { 0xfc, 0x06, KEY_EPG },
339 { 0xfc, 0x5a, KEY_BACK },
340 { 0xfc, 0x05, KEY_MENU },
341 { 0xfc, 0x47, KEY_INFO },
342 { 0xfc, 0x01, KEY_TAB },
343 { 0xfc, 0x42, KEY_PREVIOUSSONG },/* Replay */
344 { 0xfc, 0x49, KEY_VOLUMEUP },
345 { 0xfc, 0x09, KEY_VOLUMEDOWN },
346 { 0xfc, 0x54, KEY_CHANNELUP },
347 { 0xfc, 0x0b, KEY_CHANNELDOWN },
Michael Krufkydbcb86e2006-03-26 18:59:45 -0300348 { 0xfc, 0x16, KEY_CAMERA },
Michael Krufkyc1501782006-03-26 05:43:36 -0300349 { 0xfc, 0x40, KEY_TUNER }, /* ATV/DTV */
350 { 0xfc, 0x45, KEY_OPEN },
351 { 0xfc, 0x19, KEY_1 },
352 { 0xfc, 0x18, KEY_2 },
353 { 0xfc, 0x1b, KEY_3 },
354 { 0xfc, 0x1a, KEY_4 },
355 { 0xfc, 0x58, KEY_5 },
356 { 0xfc, 0x59, KEY_6 },
357 { 0xfc, 0x15, KEY_7 },
358 { 0xfc, 0x14, KEY_8 },
359 { 0xfc, 0x17, KEY_9 },
360 { 0xfc, 0x44, KEY_ANGLE }, /* Aspect */
361 { 0xfc, 0x55, KEY_0 },
362 { 0xfc, 0x07, KEY_ZOOM },
363 { 0xfc, 0x0a, KEY_REWIND },
364 { 0xfc, 0x08, KEY_PLAYPAUSE },
365 { 0xfc, 0x4b, KEY_FASTFORWARD },
366 { 0xfc, 0x5b, KEY_MUTE },
367 { 0xfc, 0x04, KEY_STOP },
368 { 0xfc, 0x56, KEY_RECORD },
369 { 0xfc, 0x57, KEY_POWER },
370 { 0xfc, 0x41, KEY_UNKNOWN }, /* INPUT */
371 { 0xfc, 0x00, KEY_UNKNOWN }, /* HD */
372};
373
Chris Pascoe0029ee12006-01-09 18:21:28 -0200374static int cxusb_dee1601_demod_init(struct dvb_frontend* fe)
375{
Chris Pascoed9ed8812006-02-07 06:49:11 -0200376 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 };
Chris Pascoe0029ee12006-01-09 18:21:28 -0200377 static u8 reset [] = { RESET, 0x80 };
378 static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
379 static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 };
380 static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
381 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
382
383 mt352_write(fe, clock_config, sizeof(clock_config));
384 udelay(200);
385 mt352_write(fe, reset, sizeof(reset));
386 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
387
388 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
389 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
390 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
391
392 return 0;
393}
394
Michael Krufky6f447252006-01-11 19:40:33 -0200395static int cxusb_mt352_demod_init(struct dvb_frontend* fe)
396{ /* used in both lgz201 and th7579 */
Michael Krufkyfb51fd22006-02-07 06:49:12 -0200397 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x29 };
Michael Krufky6f447252006-01-11 19:40:33 -0200398 static u8 reset [] = { RESET, 0x80 };
399 static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
400 static u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 };
401 static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
402 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
403
404 mt352_write(fe, clock_config, sizeof(clock_config));
405 udelay(200);
406 mt352_write(fe, reset, sizeof(reset));
407 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
408
409 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
410 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
411 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
412 return 0;
413}
414
Adrian Bunk703cb2c2006-01-23 17:11:09 -0200415static struct cx22702_config cxusb_cx22702_config = {
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700416 .demod_address = 0x63,
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700417 .output_mode = CX22702_PARALLEL_OUTPUT,
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700418};
419
Michael Krufkyfddd6322006-02-27 00:08:17 -0300420static struct lgdt330x_config cxusb_lgdt3303_config = {
Michael Krufkyeffee032006-01-09 15:25:47 -0200421 .demod_address = 0x0e,
422 .demod_chip = LGDT3303,
Michael Krufkyeffee032006-01-09 15:25:47 -0200423};
424
Adrian Bunk703cb2c2006-01-23 17:11:09 -0200425static struct mt352_config cxusb_dee1601_config = {
Chris Pascoe0029ee12006-01-09 18:21:28 -0200426 .demod_address = 0x0f,
427 .demod_init = cxusb_dee1601_demod_init,
Chris Pascoe0029ee12006-01-09 18:21:28 -0200428};
429
Michael Krufkyc9ce3942006-06-11 04:24:31 -0300430static struct zl10353_config cxusb_zl10353_dee1601_config = {
431 .demod_address = 0x0f,
Chris Pascoe8fb95782006-08-10 03:17:16 -0300432 .parallel_ts = 1,
Michael Krufkyc9ce3942006-06-11 04:24:31 -0300433};
434
Adrian Bunk6fe00b02006-04-19 20:49:28 -0300435static struct mt352_config cxusb_mt352_config = {
Michael Krufky6f447252006-01-11 19:40:33 -0200436 /* used in both lgz201 and th7579 */
437 .demod_address = 0x0f,
438 .demod_init = cxusb_mt352_demod_init,
Michael Krufky6f447252006-01-11 19:40:33 -0200439};
440
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300441static struct zl10353_config cxusb_zl10353_xc3028_config = {
442 .demod_address = 0x0f,
Chris Pascoea1dcd9d2007-11-20 08:17:54 -0300443 .if2 = 45600,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300444 .no_tuner = 1,
445 .parallel_ts = 1,
446};
447
Chris Pascoe702a6762007-11-20 03:34:11 -0300448static struct mt352_config cxusb_mt352_xc3028_config = {
449 .demod_address = 0x0f,
450 .if2 = 4560,
451 .no_tuner = 1,
452 .demod_init = cxusb_mt352_demod_init,
453};
454
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700455/* Callbacks for DVB USB */
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300456static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700457{
Michael Krufkycb89cd32008-04-22 14:46:16 -0300458 dvb_attach(simple_tuner_attach, adap->fe,
459 &adap->dev->i2c_adap, 0x61,
460 TUNER_PHILIPS_FMD1216ME_MK3);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700461 return 0;
462}
463
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300464static int cxusb_dee1601_tuner_attach(struct dvb_usb_adapter *adap)
Chris Pascoe0029ee12006-01-09 18:21:28 -0200465{
Michael Krufky79a54cb2006-12-05 14:20:06 -0300466 dvb_attach(dvb_pll_attach, adap->fe, 0x61,
Michael Krufky47a99912007-06-12 16:10:51 -0300467 NULL, DVB_PLL_THOMSON_DTT7579);
Chris Pascoe0029ee12006-01-09 18:21:28 -0200468 return 0;
469}
470
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300471static int cxusb_lgz201_tuner_attach(struct dvb_usb_adapter *adap)
Michael Krufky6f447252006-01-11 19:40:33 -0200472{
Michael Krufky47a99912007-06-12 16:10:51 -0300473 dvb_attach(dvb_pll_attach, adap->fe, 0x61, NULL, DVB_PLL_LG_Z201);
Michael Krufky6f447252006-01-11 19:40:33 -0200474 return 0;
475}
476
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300477static int cxusb_dtt7579_tuner_attach(struct dvb_usb_adapter *adap)
Michael Krufky6f447252006-01-11 19:40:33 -0200478{
Michael Krufky79a54cb2006-12-05 14:20:06 -0300479 dvb_attach(dvb_pll_attach, adap->fe, 0x60,
Michael Krufky47a99912007-06-12 16:10:51 -0300480 NULL, DVB_PLL_THOMSON_DTT7579);
Patrick Boettcher332bed52006-05-14 04:49:00 -0300481 return 0;
482}
483
Michael Krufkyf71a56c2006-10-13 21:55:57 -0300484static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap)
Patrick Boettcher332bed52006-05-14 04:49:00 -0300485{
Michael Krufky827855d2008-04-22 14:46:16 -0300486 dvb_attach(simple_tuner_attach, adap->fe,
487 &adap->dev->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF);
Michael Krufky6f447252006-01-11 19:40:33 -0200488 return 0;
489}
490
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300491static int dvico_bluebird_xc2028_callback(void *ptr, int command, int arg)
492{
493 struct dvb_usb_device *d = ptr;
494
495 switch (command) {
496 case XC2028_TUNER_RESET:
Harvey Harrison708bebd2008-04-08 23:20:00 -0300497 deb_info("%s: XC2028_TUNER_RESET %d\n", __func__, arg);
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300498 cxusb_bluebird_gpio_pulse(d, 0x01, 1);
499 break;
500 case XC2028_RESET_CLK:
Harvey Harrison708bebd2008-04-08 23:20:00 -0300501 deb_info("%s: XC2028_RESET_CLK %d\n", __func__, arg);
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300502 break;
503 default:
Harvey Harrison708bebd2008-04-08 23:20:00 -0300504 deb_info("%s: unknown command %d, arg %d\n", __func__,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300505 command, arg);
506 return -EINVAL;
507 }
508
509 return 0;
510}
511
512static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap)
513{
514 struct dvb_frontend *fe;
515 struct xc2028_config cfg = {
516 .i2c_adap = &adap->dev->i2c_adap,
517 .i2c_addr = 0x61,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300518 .callback = dvico_bluebird_xc2028_callback,
519 };
520 static struct xc2028_ctrl ctl = {
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300521 .fname = "xc3028-dvico-au-01.fw",
522 .max_len = 64,
Mauro Carvalho Chehab33e53162008-04-21 06:58:48 -0300523 .scode_table = XC3028_FE_ZARLINK456,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300524 };
525
526 fe = dvb_attach(xc2028_attach, adap->fe, &cfg);
527 if (fe == NULL || fe->ops.tuner_ops.set_config == NULL)
528 return -EIO;
529
530 fe->ops.tuner_ops.set_config(fe, &ctl);
531
532 return 0;
533}
534
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300535static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700536{
Patrick Boettchere2efeab2005-09-09 13:02:51 -0700537 u8 b;
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300538 if (usb_set_interface(adap->dev->udev, 0, 6) < 0)
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700539 err("set interface failed");
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700540
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300541 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, &b, 1);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700542
Michael Krufkyf35db232006-12-05 14:53:39 -0300543 if ((adap->fe = dvb_attach(cx22702_attach, &cxusb_cx22702_config,
544 &adap->dev->i2c_adap)) != NULL)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700545 return 0;
546
547 return -EIO;
548}
549
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300550static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
Michael Krufkyeffee032006-01-09 15:25:47 -0200551{
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300552 if (usb_set_interface(adap->dev->udev, 0, 7) < 0)
Michael Krufkyeffee032006-01-09 15:25:47 -0200553 err("set interface failed");
554
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300555 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
Michael Krufkyeffee032006-01-09 15:25:47 -0200556
Michael Krufkyf35db232006-12-05 14:53:39 -0300557 if ((adap->fe = dvb_attach(lgdt330x_attach, &cxusb_lgdt3303_config,
558 &adap->dev->i2c_adap)) != NULL)
Michael Krufkyeffee032006-01-09 15:25:47 -0200559 return 0;
560
561 return -EIO;
562}
563
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300564static int cxusb_mt352_frontend_attach(struct dvb_usb_adapter *adap)
Chris Pascoe0029ee12006-01-09 18:21:28 -0200565{
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300566 /* used in both lgz201 and th7579 */
567 if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
Chris Pascoe0029ee12006-01-09 18:21:28 -0200568 err("set interface failed");
569
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300570 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
Chris Pascoe0029ee12006-01-09 18:21:28 -0200571
Michael Krufkyf35db232006-12-05 14:53:39 -0300572 if ((adap->fe = dvb_attach(mt352_attach, &cxusb_mt352_config,
573 &adap->dev->i2c_adap)) != NULL)
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300574 return 0;
575
576 return -EIO;
577}
578
579static int cxusb_dee1601_frontend_attach(struct dvb_usb_adapter *adap)
580{
581 if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
582 err("set interface failed");
583
584 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
585
Michael Krufkyf35db232006-12-05 14:53:39 -0300586 if (((adap->fe = dvb_attach(mt352_attach, &cxusb_dee1601_config,
587 &adap->dev->i2c_adap)) != NULL) ||
588 ((adap->fe = dvb_attach(zl10353_attach,
589 &cxusb_zl10353_dee1601_config,
590 &adap->dev->i2c_adap)) != NULL))
Chris Pascoe0029ee12006-01-09 18:21:28 -0200591 return 0;
592
593 return -EIO;
594}
595
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300596static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap)
597{
598 u8 ircode[4];
599 int i;
600 struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
601 .buf = ircode, .len = 4 };
602
603 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
604 err("set interface failed");
605
606 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
607
608 /* reset the tuner and demodulator */
609 cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
610 cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
611 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
612
613 if ((adap->fe = dvb_attach(zl10353_attach,
614 &cxusb_zl10353_xc3028_config,
615 &adap->dev->i2c_adap)) == NULL)
616 return -EIO;
617
618 /* try to determine if there is no IR decoder on the I2C bus */
619 for (i = 0; adap->dev->props.rc_key_map != NULL && i < 5; i++) {
620 msleep(20);
621 if (cxusb_i2c_xfer(&adap->dev->i2c_adap, &msg, 1) != 1)
622 goto no_IR;
623 if (ircode[0] == 0 && ircode[1] == 0)
624 continue;
625 if (ircode[2] + ircode[3] != 0xff) {
626no_IR:
627 adap->dev->props.rc_key_map = NULL;
628 info("No IR receiver detected on this device.");
629 break;
630 }
631 }
632
633 return 0;
634}
635
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300636static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap)
637{
638 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
639 err("set interface failed");
640
641 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
642
643 /* reset the tuner and demodulator */
644 cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
645 cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
646 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
647
648 if ((adap->fe = dvb_attach(zl10353_attach,
649 &cxusb_zl10353_xc3028_config,
650 &adap->dev->i2c_adap)) != NULL)
651 return 0;
652
Chris Pascoe702a6762007-11-20 03:34:11 -0300653 if ((adap->fe = dvb_attach(mt352_attach,
654 &cxusb_mt352_xc3028_config,
655 &adap->dev->i2c_adap)) != NULL)
656 return 0;
657
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300658 return -EIO;
659}
660
Patrick Boettcherf5373782006-01-09 18:21:38 -0200661/*
Chris Pascoe702a6762007-11-20 03:34:11 -0300662 * DViCO has shipped two devices with the same USB ID, but only one of them
663 * needs a firmware download. Check the device class details to see if they
664 * have non-default values to decide whether the device is actually cold or
665 * not, and forget a match if it turns out we selected the wrong device.
666 */
667static int bluebird_fx2_identify_state(struct usb_device *udev,
668 struct dvb_usb_device_properties *props,
669 struct dvb_usb_device_description **desc,
670 int *cold)
671{
672 int wascold = *cold;
673
674 *cold = udev->descriptor.bDeviceClass == 0xff &&
675 udev->descriptor.bDeviceSubClass == 0xff &&
676 udev->descriptor.bDeviceProtocol == 0xff;
677
678 if (*cold && !wascold)
679 *desc = NULL;
680
681 return 0;
682}
683
684/*
Patrick Boettcherf5373782006-01-09 18:21:38 -0200685 * DViCO bluebird firmware needs the "warm" product ID to be patched into the
686 * firmware file before download.
687 */
688
Chris Pascoe702a6762007-11-20 03:34:11 -0300689static const int dvico_firmware_id_offsets[] = { 6638, 3204 };
Michael Krufkyf35db232006-12-05 14:53:39 -0300690static int bluebird_patch_dvico_firmware_download(struct usb_device *udev,
691 const struct firmware *fw)
Patrick Boettcherf5373782006-01-09 18:21:38 -0200692{
Chris Pascoe702a6762007-11-20 03:34:11 -0300693 int pos;
Patrick Boettcherf5373782006-01-09 18:21:38 -0200694
Chris Pascoe702a6762007-11-20 03:34:11 -0300695 for (pos = 0; pos < ARRAY_SIZE(dvico_firmware_id_offsets); pos++) {
696 int idoff = dvico_firmware_id_offsets[pos];
Patrick Boettcherf5373782006-01-09 18:21:38 -0200697
Chris Pascoe702a6762007-11-20 03:34:11 -0300698 if (fw->size < idoff + 4)
699 continue;
Patrick Boettcherf5373782006-01-09 18:21:38 -0200700
Chris Pascoe702a6762007-11-20 03:34:11 -0300701 if (fw->data[idoff] == (USB_VID_DVICO & 0xff) &&
702 fw->data[idoff + 1] == USB_VID_DVICO >> 8) {
703 fw->data[idoff + 2] =
704 le16_to_cpu(udev->descriptor.idProduct) + 1;
705 fw->data[idoff + 3] =
706 le16_to_cpu(udev->descriptor.idProduct) >> 8;
707
708 return usb_cypress_load_firmware(udev, fw, CYPRESS_FX2);
709 }
Patrick Boettcherf5373782006-01-09 18:21:38 -0200710 }
711
712 return -EINVAL;
713}
714
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700715/* DVB USB Driver stuff */
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300716static struct dvb_usb_device_properties cxusb_medion_properties;
717static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties;
718static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties;
719static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties;
720static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties;
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300721static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties;
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300722static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties;
Chris Pascoe702a6762007-11-20 03:34:11 -0300723static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties;
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700724
725static int cxusb_probe(struct usb_interface *intf,
Michael Krufkyf35db232006-12-05 14:53:39 -0300726 const struct usb_device_id *id)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700727{
Janne Grunau78e92002008-04-09 19:13:13 -0300728 if (0 == dvb_usb_device_init(intf, &cxusb_medion_properties,
729 THIS_MODULE, NULL, adapter_nr) ||
730 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgh064f_properties,
731 THIS_MODULE, NULL, adapter_nr) ||
732 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dee1601_properties,
733 THIS_MODULE, NULL, adapter_nr) ||
734 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgz201_properties,
735 THIS_MODULE, NULL, adapter_nr) ||
736 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dtt7579_properties,
737 THIS_MODULE, NULL, adapter_nr) ||
738 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dualdig4_properties,
739 THIS_MODULE, NULL, adapter_nr) ||
740 0 == dvb_usb_device_init(intf, &cxusb_bluebird_nano2_properties,
741 THIS_MODULE, NULL, adapter_nr) ||
742 0 == dvb_usb_device_init(intf,
743 &cxusb_bluebird_nano2_needsfirmware_properties,
744 THIS_MODULE, NULL, adapter_nr))
Michael Krufkyeffee032006-01-09 15:25:47 -0200745 return 0;
Michael Krufkyeffee032006-01-09 15:25:47 -0200746
747 return -EINVAL;
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700748}
749
750static struct usb_device_id cxusb_table [] = {
Michael Krufkyf35db232006-12-05 14:53:39 -0300751 { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) },
752 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) },
753 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_WARM) },
754 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_COLD) },
755 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM) },
756 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_COLD) },
757 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_WARM) },
758 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_COLD) },
759 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_WARM) },
760 { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD) },
761 { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM) },
762 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD) },
763 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM) },
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300764 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) },
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300765 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) },
Chris Pascoe702a6762007-11-20 03:34:11 -0300766 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) },
Michael Krufkyf35db232006-12-05 14:53:39 -0300767 {} /* Terminating entry */
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700768};
769MODULE_DEVICE_TABLE (usb, cxusb_table);
770
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300771static struct dvb_usb_device_properties cxusb_medion_properties = {
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700772 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
773
774 .usb_ctrl = CYPRESS_FX2,
775
776 .size_of_priv = sizeof(struct cxusb_state),
777
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300778 .num_adapters = 1,
779 .adapter = {
780 {
Patrick Boettcher01451e72006-10-13 11:34:46 -0300781 .streaming_ctrl = cxusb_streaming_ctrl,
782 .frontend_attach = cxusb_cx22702_frontend_attach,
783 .tuner_attach = cxusb_fmd1216me_tuner_attach,
784 /* parameter for the MPEG2-data transfer */
785 .stream = {
786 .type = USB_BULK,
787 .count = 5,
788 .endpoint = 0x02,
789 .u = {
790 .bulk = {
791 .buffersize = 8192,
792 }
793 }
794 },
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700795
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300796 },
797 },
798 .power_ctrl = cxusb_power_ctrl,
799
800 .i2c_algo = &cxusb_i2c_algo,
801
802 .generic_bulk_ctrl_endpoint = 0x01,
803
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700804 .num_device_descs = 1,
805 .devices = {
806 { "Medion MD95700 (MDUSBTV-HYBRID)",
807 { NULL },
808 { &cxusb_table[0], NULL },
809 },
810 }
811};
812
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300813static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = {
Michael Krufkyeffee032006-01-09 15:25:47 -0200814 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
815
Patrick Boettcherf5373782006-01-09 18:21:38 -0200816 .usb_ctrl = DEVICE_SPECIFIC,
817 .firmware = "dvb-usb-bluebird-01.fw",
818 .download_firmware = bluebird_patch_dvico_firmware_download,
Michael Krufky37bdfa02006-01-09 15:25:47 -0200819 /* use usb alt setting 0 for EP4 transfer (dvb-t),
820 use usb alt setting 7 for EP2 transfer (atsc) */
Michael Krufkyeffee032006-01-09 15:25:47 -0200821
822 .size_of_priv = sizeof(struct cxusb_state),
823
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300824 .num_adapters = 1,
825 .adapter = {
826 {
Patrick Boettcher01451e72006-10-13 11:34:46 -0300827 .streaming_ctrl = cxusb_streaming_ctrl,
828 .frontend_attach = cxusb_lgdt3303_frontend_attach,
Michael Krufkyf71a56c2006-10-13 21:55:57 -0300829 .tuner_attach = cxusb_lgh064f_tuner_attach,
Michael Krufkyeffee032006-01-09 15:25:47 -0200830
Patrick Boettcher01451e72006-10-13 11:34:46 -0300831 /* parameter for the MPEG2-data transfer */
832 .stream = {
833 .type = USB_BULK,
834 .count = 5,
835 .endpoint = 0x02,
836 .u = {
837 .bulk = {
838 .buffersize = 8192,
839 }
840 }
841 },
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300842 },
843 },
844
845 .power_ctrl = cxusb_bluebird_power_ctrl,
846
Michael Krufkyeffee032006-01-09 15:25:47 -0200847 .i2c_algo = &cxusb_i2c_algo,
848
Michael Krufkyc1501782006-03-26 05:43:36 -0300849 .rc_interval = 100,
850 .rc_key_map = dvico_portable_rc_keys,
851 .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys),
852 .rc_query = cxusb_rc_query,
853
Michael Krufkyeffee032006-01-09 15:25:47 -0200854 .generic_bulk_ctrl_endpoint = 0x01,
Michael Krufkyeffee032006-01-09 15:25:47 -0200855
856 .num_device_descs = 1,
857 .devices = {
858 { "DViCO FusionHDTV5 USB Gold",
859 { &cxusb_table[1], NULL },
860 { &cxusb_table[2], NULL },
861 },
862 }
863};
864
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300865static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = {
Chris Pascoe0029ee12006-01-09 18:21:28 -0200866 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
867
Patrick Boettcherf5373782006-01-09 18:21:38 -0200868 .usb_ctrl = DEVICE_SPECIFIC,
869 .firmware = "dvb-usb-bluebird-01.fw",
870 .download_firmware = bluebird_patch_dvico_firmware_download,
Chris Pascoe0029ee12006-01-09 18:21:28 -0200871 /* use usb alt setting 0 for EP4 transfer (dvb-t),
872 use usb alt setting 7 for EP2 transfer (atsc) */
873
874 .size_of_priv = sizeof(struct cxusb_state),
875
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300876 .num_adapters = 1,
877 .adapter = {
878 {
Patrick Boettcher01451e72006-10-13 11:34:46 -0300879 .streaming_ctrl = cxusb_streaming_ctrl,
880 .frontend_attach = cxusb_dee1601_frontend_attach,
881 .tuner_attach = cxusb_dee1601_tuner_attach,
882 /* parameter for the MPEG2-data transfer */
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300883 .stream = {
884 .type = USB_BULK,
Patrick Boettcher01451e72006-10-13 11:34:46 -0300885 .count = 5,
886 .endpoint = 0x04,
887 .u = {
888 .bulk = {
889 .buffersize = 8192,
890 }
891 }
892 },
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300893 },
894 },
895
896 .power_ctrl = cxusb_bluebird_power_ctrl,
Chris Pascoe0029ee12006-01-09 18:21:28 -0200897
898 .i2c_algo = &cxusb_i2c_algo,
899
Chris Pascoe7c239702006-01-09 18:21:29 -0200900 .rc_interval = 150,
901 .rc_key_map = dvico_mce_rc_keys,
902 .rc_key_map_size = ARRAY_SIZE(dvico_mce_rc_keys),
903 .rc_query = cxusb_rc_query,
904
Chris Pascoe0029ee12006-01-09 18:21:28 -0200905 .generic_bulk_ctrl_endpoint = 0x01,
Chris Pascoe0029ee12006-01-09 18:21:28 -0200906
Michael Krufky587c03d2006-09-28 02:16:01 -0300907 .num_device_descs = 3,
Chris Pascoe0029ee12006-01-09 18:21:28 -0200908 .devices = {
909 { "DViCO FusionHDTV DVB-T Dual USB",
910 { &cxusb_table[3], NULL },
911 { &cxusb_table[4], NULL },
912 },
Michael Krufkyac9ffb92006-01-11 23:21:00 -0200913 { "DigitalNow DVB-T Dual USB",
914 { &cxusb_table[9], NULL },
915 { &cxusb_table[10], NULL },
916 },
Michael Krufky587c03d2006-09-28 02:16:01 -0300917 { "DViCO FusionHDTV DVB-T Dual Digital 2",
918 { &cxusb_table[11], NULL },
919 { &cxusb_table[12], NULL },
920 },
Chris Pascoe0029ee12006-01-09 18:21:28 -0200921 }
922};
923
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300924static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = {
Michael Krufky6f447252006-01-11 19:40:33 -0200925 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
926
927 .usb_ctrl = DEVICE_SPECIFIC,
928 .firmware = "dvb-usb-bluebird-01.fw",
929 .download_firmware = bluebird_patch_dvico_firmware_download,
930 /* use usb alt setting 0 for EP4 transfer (dvb-t),
931 use usb alt setting 7 for EP2 transfer (atsc) */
932
933 .size_of_priv = sizeof(struct cxusb_state),
934
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300935 .num_adapters = 2,
936 .adapter = {
937 {
Patrick Boettcher01451e72006-10-13 11:34:46 -0300938 .streaming_ctrl = cxusb_streaming_ctrl,
939 .frontend_attach = cxusb_mt352_frontend_attach,
940 .tuner_attach = cxusb_lgz201_tuner_attach,
Michael Krufky6f447252006-01-11 19:40:33 -0200941
Patrick Boettcher01451e72006-10-13 11:34:46 -0300942 /* parameter for the MPEG2-data transfer */
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300943 .stream = {
944 .type = USB_BULK,
Patrick Boettcher01451e72006-10-13 11:34:46 -0300945 .count = 5,
946 .endpoint = 0x04,
947 .u = {
948 .bulk = {
949 .buffersize = 8192,
950 }
951 }
952 },
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300953 },
954 },
955 .power_ctrl = cxusb_bluebird_power_ctrl,
956
Michael Krufky6f447252006-01-11 19:40:33 -0200957 .i2c_algo = &cxusb_i2c_algo,
958
Michael Krufkyc1501782006-03-26 05:43:36 -0300959 .rc_interval = 100,
960 .rc_key_map = dvico_portable_rc_keys,
961 .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys),
962 .rc_query = cxusb_rc_query,
963
Michael Krufky6f447252006-01-11 19:40:33 -0200964 .generic_bulk_ctrl_endpoint = 0x01,
Michael Krufky6f447252006-01-11 19:40:33 -0200965 .num_device_descs = 1,
966 .devices = {
967 { "DViCO FusionHDTV DVB-T USB (LGZ201)",
968 { &cxusb_table[5], NULL },
969 { &cxusb_table[6], NULL },
970 },
971 }
972};
973
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300974static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = {
Michael Krufky6f447252006-01-11 19:40:33 -0200975 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
976
977 .usb_ctrl = DEVICE_SPECIFIC,
978 .firmware = "dvb-usb-bluebird-01.fw",
979 .download_firmware = bluebird_patch_dvico_firmware_download,
980 /* use usb alt setting 0 for EP4 transfer (dvb-t),
981 use usb alt setting 7 for EP2 transfer (atsc) */
982
983 .size_of_priv = sizeof(struct cxusb_state),
984
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300985 .num_adapters = 1,
986 .adapter = {
987 {
Patrick Boettcher01451e72006-10-13 11:34:46 -0300988 .streaming_ctrl = cxusb_streaming_ctrl,
989 .frontend_attach = cxusb_mt352_frontend_attach,
990 .tuner_attach = cxusb_dtt7579_tuner_attach,
Michael Krufky6f447252006-01-11 19:40:33 -0200991
Patrick Boettcher01451e72006-10-13 11:34:46 -0300992 /* parameter for the MPEG2-data transfer */
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300993 .stream = {
994 .type = USB_BULK,
Patrick Boettcher01451e72006-10-13 11:34:46 -0300995 .count = 5,
996 .endpoint = 0x04,
997 .u = {
998 .bulk = {
999 .buffersize = 8192,
1000 }
1001 }
1002 },
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001003 },
1004 },
1005 .power_ctrl = cxusb_bluebird_power_ctrl,
1006
Michael Krufky6f447252006-01-11 19:40:33 -02001007 .i2c_algo = &cxusb_i2c_algo,
1008
Michael Krufkyc1501782006-03-26 05:43:36 -03001009 .rc_interval = 100,
1010 .rc_key_map = dvico_portable_rc_keys,
1011 .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys),
1012 .rc_query = cxusb_rc_query,
1013
Michael Krufky6f447252006-01-11 19:40:33 -02001014 .generic_bulk_ctrl_endpoint = 0x01,
Michael Krufky6f447252006-01-11 19:40:33 -02001015
1016 .num_device_descs = 1,
1017 .devices = {
1018 { "DViCO FusionHDTV DVB-T USB (TH7579)",
1019 { &cxusb_table[7], NULL },
1020 { &cxusb_table[8], NULL },
1021 },
1022 }
1023};
1024
Chris Pascoeaeb012b2007-11-19 21:57:10 -03001025static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = {
1026 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1027
1028 .usb_ctrl = CYPRESS_FX2,
1029
1030 .size_of_priv = sizeof(struct cxusb_state),
1031
1032 .num_adapters = 1,
1033 .adapter = {
1034 {
1035 .streaming_ctrl = cxusb_streaming_ctrl,
1036 .frontend_attach = cxusb_dualdig4_frontend_attach,
1037 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1038 /* parameter for the MPEG2-data transfer */
1039 .stream = {
1040 .type = USB_BULK,
1041 .count = 5,
1042 .endpoint = 0x02,
1043 .u = {
1044 .bulk = {
1045 .buffersize = 8192,
1046 }
1047 }
1048 },
1049 },
1050 },
1051
1052 .power_ctrl = cxusb_power_ctrl,
1053
1054 .i2c_algo = &cxusb_i2c_algo,
1055
1056 .generic_bulk_ctrl_endpoint = 0x01,
1057
1058 .rc_interval = 100,
1059 .rc_key_map = dvico_mce_rc_keys,
1060 .rc_key_map_size = ARRAY_SIZE(dvico_mce_rc_keys),
1061 .rc_query = cxusb_bluebird2_rc_query,
1062
1063 .num_device_descs = 1,
1064 .devices = {
1065 { "DViCO FusionHDTV DVB-T Dual Digital 4",
1066 { NULL },
1067 { &cxusb_table[13], NULL },
1068 },
1069 }
1070};
1071
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001072static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = {
1073 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1074
1075 .usb_ctrl = CYPRESS_FX2,
Chris Pascoe702a6762007-11-20 03:34:11 -03001076 .identify_state = bluebird_fx2_identify_state,
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001077
1078 .size_of_priv = sizeof(struct cxusb_state),
1079
1080 .num_adapters = 1,
1081 .adapter = {
1082 {
1083 .streaming_ctrl = cxusb_streaming_ctrl,
1084 .frontend_attach = cxusb_nano2_frontend_attach,
1085 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1086 /* parameter for the MPEG2-data transfer */
1087 .stream = {
1088 .type = USB_BULK,
1089 .count = 5,
1090 .endpoint = 0x02,
1091 .u = {
1092 .bulk = {
1093 .buffersize = 8192,
1094 }
1095 }
1096 },
1097 },
1098 },
1099
1100 .power_ctrl = cxusb_nano2_power_ctrl,
1101
1102 .i2c_algo = &cxusb_i2c_algo,
1103
1104 .generic_bulk_ctrl_endpoint = 0x01,
1105
1106 .rc_interval = 100,
1107 .rc_key_map = dvico_portable_rc_keys,
1108 .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys),
1109 .rc_query = cxusb_bluebird2_rc_query,
1110
1111 .num_device_descs = 1,
1112 .devices = {
1113 { "DViCO FusionHDTV DVB-T NANO2",
1114 { NULL },
1115 { &cxusb_table[14], NULL },
1116 },
1117 }
1118};
1119
Chris Pascoe702a6762007-11-20 03:34:11 -03001120static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties = {
1121 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1122
1123 .usb_ctrl = DEVICE_SPECIFIC,
1124 .firmware = "dvb-usb-bluebird-02.fw",
1125 .download_firmware = bluebird_patch_dvico_firmware_download,
1126 .identify_state = bluebird_fx2_identify_state,
1127
1128 .size_of_priv = sizeof(struct cxusb_state),
1129
1130 .num_adapters = 1,
1131 .adapter = {
1132 {
1133 .streaming_ctrl = cxusb_streaming_ctrl,
1134 .frontend_attach = cxusb_nano2_frontend_attach,
1135 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1136 /* parameter for the MPEG2-data transfer */
1137 .stream = {
1138 .type = USB_BULK,
1139 .count = 5,
1140 .endpoint = 0x02,
1141 .u = {
1142 .bulk = {
1143 .buffersize = 8192,
1144 }
1145 }
1146 },
1147 },
1148 },
1149
1150 .power_ctrl = cxusb_nano2_power_ctrl,
1151
1152 .i2c_algo = &cxusb_i2c_algo,
1153
1154 .generic_bulk_ctrl_endpoint = 0x01,
1155
1156 .rc_interval = 100,
1157 .rc_key_map = dvico_portable_rc_keys,
1158 .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys),
1159 .rc_query = cxusb_rc_query,
1160
1161 .num_device_descs = 1,
1162 .devices = {
1163 { "DViCO FusionHDTV DVB-T NANO2 w/o firmware",
1164 { &cxusb_table[14], NULL },
1165 { &cxusb_table[15], NULL },
1166 },
1167 }
1168};
1169
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001170static struct usb_driver cxusb_driver = {
Patrick Boettcher63b5c1c2005-07-07 17:58:30 -07001171 .name = "dvb_usb_cxusb",
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001172 .probe = cxusb_probe,
Michael Krufkyf35db232006-12-05 14:53:39 -03001173 .disconnect = dvb_usb_device_exit,
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001174 .id_table = cxusb_table,
1175};
1176
1177/* module stuff */
1178static int __init cxusb_module_init(void)
1179{
1180 int result;
1181 if ((result = usb_register(&cxusb_driver))) {
1182 err("usb_register failed. Error number %d",result);
1183 return result;
1184 }
1185
1186 return 0;
1187}
1188
1189static void __exit cxusb_module_exit(void)
1190{
1191 /* deregister this driver from the USB subsystem */
1192 usb_deregister(&cxusb_driver);
1193}
1194
1195module_init (cxusb_module_init);
1196module_exit (cxusb_module_exit);
1197
1198MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
Michael Krufky5b9ed282006-10-15 14:51:08 -03001199MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
Michael Krufkyf4efb4d2006-01-13 14:10:25 -02001200MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001201MODULE_DESCRIPTION("Driver for Conexant USB2.0 hybrid reference design");
1202MODULE_VERSION("1.0-alpha");
1203MODULE_LICENSE("GPL");