blob: 1de3678a294ba2544ff067314d982357c669e42d [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"
Anton Blanchard8d798982008-08-09 12:23:15 -030039#include "dib7000p.h"
40#include "dib0070.h"
Patrick Boettcher22c6d932005-07-07 17:58:10 -070041
42/* debug */
Adrian Bunk53133af2007-11-05 14:07:06 -030043static int dvb_usb_cxusb_debug;
Michael Krufkyf35db232006-12-05 14:53:39 -030044module_param_named(debug, dvb_usb_cxusb_debug, int, 0644);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070045MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
Janne Grunau78e92002008-04-09 19:13:13 -030046
47DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
48
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -030049#define deb_info(args...) dprintk(dvb_usb_cxusb_debug, 0x03, args)
50#define deb_i2c(args...) dprintk(dvb_usb_cxusb_debug, 0x02, args)
Patrick Boettcher22c6d932005-07-07 17:58:10 -070051
52static int cxusb_ctrl_msg(struct dvb_usb_device *d,
Michael Krufkyf35db232006-12-05 14:53:39 -030053 u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
Patrick Boettcher22c6d932005-07-07 17:58:10 -070054{
55 int wo = (rbuf == NULL || rlen == 0); /* write-only */
56 u8 sndbuf[1+wlen];
Michael Krufkyf35db232006-12-05 14:53:39 -030057 memset(sndbuf, 0, 1+wlen);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070058
59 sndbuf[0] = cmd;
Michael Krufkyf35db232006-12-05 14:53:39 -030060 memcpy(&sndbuf[1], wbuf, wlen);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070061 if (wo)
Chris Pascoeb17f1092007-11-19 02:42:44 -030062 return dvb_usb_generic_write(d, sndbuf, 1+wlen);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070063 else
Chris Pascoeb17f1092007-11-19 02:42:44 -030064 return dvb_usb_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen, 0);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070065}
66
Patrick Boettchere2efeab2005-09-09 13:02:51 -070067/* GPIO */
68static void cxusb_gpio_tuner(struct dvb_usb_device *d, int onoff)
Patrick Boettcher22c6d932005-07-07 17:58:10 -070069{
70 struct cxusb_state *st = d->priv;
Michael Krufkyf35db232006-12-05 14:53:39 -030071 u8 o[2], i;
Patrick Boettcher22c6d932005-07-07 17:58:10 -070072
Patrick Boettchere2efeab2005-09-09 13:02:51 -070073 if (st->gpio_write_state[GPIO_TUNER] == onoff)
Patrick Boettcher22c6d932005-07-07 17:58:10 -070074 return;
75
Patrick Boettchere2efeab2005-09-09 13:02:51 -070076 o[0] = GPIO_TUNER;
77 o[1] = onoff;
Michael Krufkyf35db232006-12-05 14:53:39 -030078 cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070079
80 if (i != 0x01)
Patrick Boettchere2efeab2005-09-09 13:02:51 -070081 deb_info("gpio_write failed.\n");
Patrick Boettcher22c6d932005-07-07 17:58:10 -070082
Patrick Boettchere2efeab2005-09-09 13:02:51 -070083 st->gpio_write_state[GPIO_TUNER] = onoff;
Patrick Boettcher22c6d932005-07-07 17:58:10 -070084}
85
Chris Pascoeaeb012b2007-11-19 21:57:10 -030086static int cxusb_bluebird_gpio_rw(struct dvb_usb_device *d, u8 changemask,
87 u8 newval)
88{
89 u8 o[2], gpio_state;
90 int rc;
91
92 o[0] = 0xff & ~changemask; /* mask of bits to keep */
93 o[1] = newval & changemask; /* new values for bits */
94
95 rc = cxusb_ctrl_msg(d, CMD_BLUEBIRD_GPIO_RW, o, 2, &gpio_state, 1);
96 if (rc < 0 || (gpio_state & changemask) != (newval & changemask))
97 deb_info("bluebird_gpio_write failed.\n");
98
99 return rc < 0 ? rc : gpio_state;
100}
101
102static void cxusb_bluebird_gpio_pulse(struct dvb_usb_device *d, u8 pin, int low)
103{
104 cxusb_bluebird_gpio_rw(d, pin, low ? 0 : pin);
105 msleep(5);
106 cxusb_bluebird_gpio_rw(d, pin, low ? pin : 0);
107}
108
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300109static void cxusb_nano2_led(struct dvb_usb_device *d, int onoff)
110{
111 cxusb_bluebird_gpio_rw(d, 0x40, onoff ? 0 : 0x40);
112}
113
Patrick Boettchere2efeab2005-09-09 13:02:51 -0700114/* I2C */
Michael Krufkyf35db232006-12-05 14:53:39 -0300115static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
116 int num)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700117{
118 struct dvb_usb_device *d = i2c_get_adapdata(adap);
119 int i;
120
Ingo Molnar3593cab2006-02-07 06:49:14 -0200121 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700122 return -EAGAIN;
123
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700124 for (i = 0; i < num; i++) {
125
Michael Krufky5e805ef2006-03-23 00:01:34 -0300126 if (d->udev->descriptor.idVendor == USB_VID_MEDION)
127 switch (msg[i].addr) {
Michael Krufkyf35db232006-12-05 14:53:39 -0300128 case 0x63:
129 cxusb_gpio_tuner(d, 0);
130 break;
131 default:
132 cxusb_gpio_tuner(d, 1);
133 break;
Michael Krufky5e805ef2006-03-23 00:01:34 -0300134 }
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700135
Chris Pascoe272479d72007-11-19 03:01:22 -0300136 if (msg[i].flags & I2C_M_RD) {
137 /* read only */
138 u8 obuf[3], ibuf[1+msg[i].len];
139 obuf[0] = 0;
140 obuf[1] = msg[i].len;
141 obuf[2] = msg[i].addr;
142 if (cxusb_ctrl_msg(d, CMD_I2C_READ,
143 obuf, 3,
144 ibuf, 1+msg[i].len) < 0) {
145 warn("i2c read failed");
146 break;
147 }
148 memcpy(msg[i].buf, &ibuf[1], msg[i].len);
Chris Pascoea644e4a2007-11-19 03:05:09 -0300149 } else if (i+1 < num && (msg[i+1].flags & I2C_M_RD) &&
150 msg[i].addr == msg[i+1].addr) {
151 /* write to then read from same address */
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700152 u8 obuf[3+msg[i].len], ibuf[1+msg[i+1].len];
153 obuf[0] = msg[i].len;
154 obuf[1] = msg[i+1].len;
155 obuf[2] = msg[i].addr;
Michael Krufkyf35db232006-12-05 14:53:39 -0300156 memcpy(&obuf[3], msg[i].buf, msg[i].len);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700157
158 if (cxusb_ctrl_msg(d, CMD_I2C_READ,
Michael Krufkyf35db232006-12-05 14:53:39 -0300159 obuf, 3+msg[i].len,
160 ibuf, 1+msg[i+1].len) < 0)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700161 break;
162
163 if (ibuf[0] != 0x08)
Michael Krufkyae62e3d2006-03-23 01:11:18 -0300164 deb_i2c("i2c read may have failed\n");
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700165
Michael Krufkyf35db232006-12-05 14:53:39 -0300166 memcpy(msg[i+1].buf, &ibuf[1], msg[i+1].len);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700167
168 i++;
Chris Pascoe272479d72007-11-19 03:01:22 -0300169 } else {
170 /* write only */
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700171 u8 obuf[2+msg[i].len], ibuf;
172 obuf[0] = msg[i].addr;
173 obuf[1] = msg[i].len;
Michael Krufkyf35db232006-12-05 14:53:39 -0300174 memcpy(&obuf[2], msg[i].buf, msg[i].len);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700175
Michael Krufkyf35db232006-12-05 14:53:39 -0300176 if (cxusb_ctrl_msg(d, CMD_I2C_WRITE, obuf,
177 2+msg[i].len, &ibuf,1) < 0)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700178 break;
179 if (ibuf != 0x08)
Michael Krufkyae62e3d2006-03-23 01:11:18 -0300180 deb_i2c("i2c write may have failed\n");
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700181 }
182 }
183
Ingo Molnar3593cab2006-02-07 06:49:14 -0200184 mutex_unlock(&d->i2c_mutex);
Chris Pascoe13e001d2007-11-19 02:48:27 -0300185 return i == num ? num : -EREMOTEIO;
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700186}
187
188static u32 cxusb_i2c_func(struct i2c_adapter *adapter)
189{
190 return I2C_FUNC_I2C;
191}
192
193static struct i2c_algorithm cxusb_i2c_algo = {
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700194 .master_xfer = cxusb_i2c_xfer,
195 .functionality = cxusb_i2c_func,
196};
197
198static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff)
199{
Patrick Boettchere2efeab2005-09-09 13:02:51 -0700200 u8 b = 0;
201 if (onoff)
202 return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
203 else
204 return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700205}
206
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300207static int cxusb_aver_power_ctrl(struct dvb_usb_device *d, int onoff)
208{
209 int ret;
210 if (!onoff)
211 return cxusb_ctrl_msg(d, CMD_POWER_OFF, NULL, 0, NULL, 0);
212 if (d->state == DVB_USB_STATE_INIT &&
213 usb_set_interface(d->udev, 0, 0) < 0)
214 err("set interface failed");
Hans Verkuilc6eb8ea2008-09-03 17:11:54 -0300215 do {} while (!(ret = cxusb_ctrl_msg(d, CMD_POWER_ON, NULL, 0, NULL, 0)) &&
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300216 !(ret = cxusb_ctrl_msg(d, 0x15, NULL, 0, NULL, 0)) &&
217 !(ret = cxusb_ctrl_msg(d, 0x17, NULL, 0, NULL, 0)) && 0);
218 if (!ret) {
219 /* FIXME: We don't know why, but we need to configure the
220 * lgdt3303 with the register settings below on resume */
221 int i;
222 u8 buf, bufs[] = {
223 0x0e, 0x2, 0x00, 0x7f,
224 0x0e, 0x2, 0x02, 0xfe,
225 0x0e, 0x2, 0x02, 0x01,
226 0x0e, 0x2, 0x00, 0x03,
227 0x0e, 0x2, 0x0d, 0x40,
228 0x0e, 0x2, 0x0e, 0x87,
229 0x0e, 0x2, 0x0f, 0x8e,
230 0x0e, 0x2, 0x10, 0x01,
231 0x0e, 0x2, 0x14, 0xd7,
232 0x0e, 0x2, 0x47, 0x88,
233 };
234 msleep(20);
235 for (i = 0; i < sizeof(bufs)/sizeof(u8); i += 4/sizeof(u8)) {
236 ret = cxusb_ctrl_msg(d, CMD_I2C_WRITE,
237 bufs+i, 4, &buf, 1);
238 if (ret)
239 break;
240 if (buf != 0x8)
241 return -EREMOTEIO;
242 }
243 }
244 return ret;
245}
246
Michael Krufky5691c842006-04-19 20:40:01 -0300247static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff)
248{
249 u8 b = 0;
250 if (onoff)
251 return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
252 else
253 return 0;
254}
255
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300256static int cxusb_nano2_power_ctrl(struct dvb_usb_device *d, int onoff)
257{
258 int rc = 0;
259
260 rc = cxusb_power_ctrl(d, onoff);
261 if (!onoff)
262 cxusb_nano2_led(d, 0);
263
264 return rc;
265}
266
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300267static int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700268{
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700269 u8 buf[2] = { 0x03, 0x00 };
270 if (onoff)
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300271 cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON, buf, 2, NULL, 0);
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700272 else
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300273 cxusb_ctrl_msg(adap->dev, CMD_STREAMING_OFF, NULL, 0, NULL, 0);
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700274
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700275 return 0;
276}
277
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300278static int cxusb_aver_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
279{
280 if (onoff)
281 cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_ON, NULL, 0, NULL, 0);
282 else
283 cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_OFF,
284 NULL, 0, NULL, 0);
285 return 0;
286}
287
Chris Pascoe7c239702006-01-09 18:21:29 -0200288static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
289{
290 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
Michael Krufkya07e6092006-01-09 18:21:31 -0200291 u8 ircode[4];
Chris Pascoe7c239702006-01-09 18:21:29 -0200292 int i;
293
Michael Krufkya07e6092006-01-09 18:21:31 -0200294 cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4);
Chris Pascoe7c239702006-01-09 18:21:29 -0200295
296 *event = 0;
297 *state = REMOTE_NO_KEY_PRESSED;
298
299 for (i = 0; i < d->props.rc_key_map_size; i++) {
Michael Krufkya07e6092006-01-09 18:21:31 -0200300 if (keymap[i].custom == ircode[2] &&
301 keymap[i].data == ircode[3]) {
Chris Pascoe7c239702006-01-09 18:21:29 -0200302 *event = keymap[i].event;
303 *state = REMOTE_KEY_PRESSED;
304
305 return 0;
306 }
307 }
308
309 return 0;
310}
311
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300312static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event,
313 int *state)
314{
315 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
316 u8 ircode[4];
317 int i;
318 struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
319 .buf = ircode, .len = 4 };
320
321 *event = 0;
322 *state = REMOTE_NO_KEY_PRESSED;
323
324 if (cxusb_i2c_xfer(&d->i2c_adap, &msg, 1) != 1)
325 return 0;
326
327 for (i = 0; i < d->props.rc_key_map_size; i++) {
328 if (keymap[i].custom == ircode[1] &&
329 keymap[i].data == ircode[2]) {
330 *event = keymap[i].event;
331 *state = REMOTE_KEY_PRESSED;
332
333 return 0;
334 }
335 }
336
337 return 0;
338}
339
Adrian Bunk703cb2c2006-01-23 17:11:09 -0200340static struct dvb_usb_rc_key dvico_mce_rc_keys[] = {
Michael Krufkya07e6092006-01-09 18:21:31 -0200341 { 0xfe, 0x02, KEY_TV },
342 { 0xfe, 0x0e, KEY_MP3 },
343 { 0xfe, 0x1a, KEY_DVD },
344 { 0xfe, 0x1e, KEY_FAVORITES },
345 { 0xfe, 0x16, KEY_SETUP },
346 { 0xfe, 0x46, KEY_POWER2 },
347 { 0xfe, 0x0a, KEY_EPG },
348 { 0xfe, 0x49, KEY_BACK },
349 { 0xfe, 0x4d, KEY_MENU },
350 { 0xfe, 0x51, KEY_UP },
351 { 0xfe, 0x5b, KEY_LEFT },
352 { 0xfe, 0x5f, KEY_RIGHT },
353 { 0xfe, 0x53, KEY_DOWN },
354 { 0xfe, 0x5e, KEY_OK },
355 { 0xfe, 0x59, KEY_INFO },
356 { 0xfe, 0x55, KEY_TAB },
357 { 0xfe, 0x0f, KEY_PREVIOUSSONG },/* Replay */
358 { 0xfe, 0x12, KEY_NEXTSONG }, /* Skip */
359 { 0xfe, 0x42, KEY_ENTER }, /* Windows/Start */
360 { 0xfe, 0x15, KEY_VOLUMEUP },
361 { 0xfe, 0x05, KEY_VOLUMEDOWN },
362 { 0xfe, 0x11, KEY_CHANNELUP },
363 { 0xfe, 0x09, KEY_CHANNELDOWN },
364 { 0xfe, 0x52, KEY_CAMERA },
365 { 0xfe, 0x5a, KEY_TUNER }, /* Live */
366 { 0xfe, 0x19, KEY_OPEN },
367 { 0xfe, 0x0b, KEY_1 },
368 { 0xfe, 0x17, KEY_2 },
369 { 0xfe, 0x1b, KEY_3 },
370 { 0xfe, 0x07, KEY_4 },
371 { 0xfe, 0x50, KEY_5 },
372 { 0xfe, 0x54, KEY_6 },
373 { 0xfe, 0x48, KEY_7 },
374 { 0xfe, 0x4c, KEY_8 },
375 { 0xfe, 0x58, KEY_9 },
376 { 0xfe, 0x13, KEY_ANGLE }, /* Aspect */
377 { 0xfe, 0x03, KEY_0 },
378 { 0xfe, 0x1f, KEY_ZOOM },
379 { 0xfe, 0x43, KEY_REWIND },
380 { 0xfe, 0x47, KEY_PLAYPAUSE },
381 { 0xfe, 0x4f, KEY_FASTFORWARD },
382 { 0xfe, 0x57, KEY_MUTE },
383 { 0xfe, 0x0d, KEY_STOP },
384 { 0xfe, 0x01, KEY_RECORD },
385 { 0xfe, 0x4e, KEY_POWER },
386};
387
Michael Krufkyc1501782006-03-26 05:43:36 -0300388static struct dvb_usb_rc_key dvico_portable_rc_keys[] = {
389 { 0xfc, 0x02, KEY_SETUP }, /* Profile */
390 { 0xfc, 0x43, KEY_POWER2 },
391 { 0xfc, 0x06, KEY_EPG },
392 { 0xfc, 0x5a, KEY_BACK },
393 { 0xfc, 0x05, KEY_MENU },
394 { 0xfc, 0x47, KEY_INFO },
395 { 0xfc, 0x01, KEY_TAB },
396 { 0xfc, 0x42, KEY_PREVIOUSSONG },/* Replay */
397 { 0xfc, 0x49, KEY_VOLUMEUP },
398 { 0xfc, 0x09, KEY_VOLUMEDOWN },
399 { 0xfc, 0x54, KEY_CHANNELUP },
400 { 0xfc, 0x0b, KEY_CHANNELDOWN },
Michael Krufkydbcb86e2006-03-26 18:59:45 -0300401 { 0xfc, 0x16, KEY_CAMERA },
Michael Krufkyc1501782006-03-26 05:43:36 -0300402 { 0xfc, 0x40, KEY_TUNER }, /* ATV/DTV */
403 { 0xfc, 0x45, KEY_OPEN },
404 { 0xfc, 0x19, KEY_1 },
405 { 0xfc, 0x18, KEY_2 },
406 { 0xfc, 0x1b, KEY_3 },
407 { 0xfc, 0x1a, KEY_4 },
408 { 0xfc, 0x58, KEY_5 },
409 { 0xfc, 0x59, KEY_6 },
410 { 0xfc, 0x15, KEY_7 },
411 { 0xfc, 0x14, KEY_8 },
412 { 0xfc, 0x17, KEY_9 },
413 { 0xfc, 0x44, KEY_ANGLE }, /* Aspect */
414 { 0xfc, 0x55, KEY_0 },
415 { 0xfc, 0x07, KEY_ZOOM },
416 { 0xfc, 0x0a, KEY_REWIND },
417 { 0xfc, 0x08, KEY_PLAYPAUSE },
418 { 0xfc, 0x4b, KEY_FASTFORWARD },
419 { 0xfc, 0x5b, KEY_MUTE },
420 { 0xfc, 0x04, KEY_STOP },
421 { 0xfc, 0x56, KEY_RECORD },
422 { 0xfc, 0x57, KEY_POWER },
423 { 0xfc, 0x41, KEY_UNKNOWN }, /* INPUT */
424 { 0xfc, 0x00, KEY_UNKNOWN }, /* HD */
425};
426
Chris Pascoe0029ee12006-01-09 18:21:28 -0200427static int cxusb_dee1601_demod_init(struct dvb_frontend* fe)
428{
Chris Pascoed9ed8812006-02-07 06:49:11 -0200429 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 };
Chris Pascoe0029ee12006-01-09 18:21:28 -0200430 static u8 reset [] = { RESET, 0x80 };
431 static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
432 static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 };
433 static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
434 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
435
436 mt352_write(fe, clock_config, sizeof(clock_config));
437 udelay(200);
438 mt352_write(fe, reset, sizeof(reset));
439 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
440
441 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
442 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
443 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
444
445 return 0;
446}
447
Michael Krufky6f447252006-01-11 19:40:33 -0200448static int cxusb_mt352_demod_init(struct dvb_frontend* fe)
449{ /* used in both lgz201 and th7579 */
Michael Krufkyfb51fd22006-02-07 06:49:12 -0200450 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x29 };
Michael Krufky6f447252006-01-11 19:40:33 -0200451 static u8 reset [] = { RESET, 0x80 };
452 static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
453 static u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 };
454 static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
455 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
456
457 mt352_write(fe, clock_config, sizeof(clock_config));
458 udelay(200);
459 mt352_write(fe, reset, sizeof(reset));
460 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
461
462 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
463 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
464 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
465 return 0;
466}
467
Adrian Bunk703cb2c2006-01-23 17:11:09 -0200468static struct cx22702_config cxusb_cx22702_config = {
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700469 .demod_address = 0x63,
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700470 .output_mode = CX22702_PARALLEL_OUTPUT,
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700471};
472
Michael Krufkyfddd6322006-02-27 00:08:17 -0300473static struct lgdt330x_config cxusb_lgdt3303_config = {
Michael Krufkyeffee032006-01-09 15:25:47 -0200474 .demod_address = 0x0e,
475 .demod_chip = LGDT3303,
Michael Krufkyeffee032006-01-09 15:25:47 -0200476};
477
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300478static struct lgdt330x_config cxusb_aver_lgdt3303_config = {
479 .demod_address = 0x0e,
480 .demod_chip = LGDT3303,
481 .clock_polarity_flip = 2,
482};
483
Adrian Bunk703cb2c2006-01-23 17:11:09 -0200484static struct mt352_config cxusb_dee1601_config = {
Chris Pascoe0029ee12006-01-09 18:21:28 -0200485 .demod_address = 0x0f,
486 .demod_init = cxusb_dee1601_demod_init,
Chris Pascoe0029ee12006-01-09 18:21:28 -0200487};
488
Michael Krufkyc9ce3942006-06-11 04:24:31 -0300489static struct zl10353_config cxusb_zl10353_dee1601_config = {
490 .demod_address = 0x0f,
Chris Pascoe8fb95782006-08-10 03:17:16 -0300491 .parallel_ts = 1,
Michael Krufkyc9ce3942006-06-11 04:24:31 -0300492};
493
Adrian Bunk6fe00b02006-04-19 20:49:28 -0300494static struct mt352_config cxusb_mt352_config = {
Michael Krufky6f447252006-01-11 19:40:33 -0200495 /* used in both lgz201 and th7579 */
496 .demod_address = 0x0f,
497 .demod_init = cxusb_mt352_demod_init,
Michael Krufky6f447252006-01-11 19:40:33 -0200498};
499
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300500static struct zl10353_config cxusb_zl10353_xc3028_config = {
501 .demod_address = 0x0f,
Chris Pascoea1dcd9d2007-11-20 08:17:54 -0300502 .if2 = 45600,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300503 .no_tuner = 1,
504 .parallel_ts = 1,
505};
506
Chris Pascoe702a6762007-11-20 03:34:11 -0300507static struct mt352_config cxusb_mt352_xc3028_config = {
508 .demod_address = 0x0f,
509 .if2 = 4560,
510 .no_tuner = 1,
511 .demod_init = cxusb_mt352_demod_init,
512};
513
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300514/* FIXME: needs tweaking */
515static struct mxl5005s_config aver_a868r_tuner = {
516 .i2c_address = 0x63,
517 .if_freq = 6000000UL,
518 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
519 .agc_mode = MXL_SINGLE_AGC,
520 .tracking_filter = MXL_TF_C,
521 .rssi_enable = MXL_RSSI_ENABLE,
522 .cap_select = MXL_CAP_SEL_ENABLE,
523 .div_out = MXL_DIV_OUT_4,
524 .clock_out = MXL_CLOCK_OUT_DISABLE,
525 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
526 .top = MXL5005S_TOP_25P2,
527 .mod_mode = MXL_DIGITAL_MODE,
528 .if_mode = MXL_ZERO_IF,
529 .AgcMasterByte = 0x00,
530};
531
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700532/* Callbacks for DVB USB */
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300533static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700534{
Michael Krufkycb89cd32008-04-22 14:46:16 -0300535 dvb_attach(simple_tuner_attach, adap->fe,
536 &adap->dev->i2c_adap, 0x61,
537 TUNER_PHILIPS_FMD1216ME_MK3);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700538 return 0;
539}
540
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300541static int cxusb_dee1601_tuner_attach(struct dvb_usb_adapter *adap)
Chris Pascoe0029ee12006-01-09 18:21:28 -0200542{
Michael Krufky79a54cb2006-12-05 14:20:06 -0300543 dvb_attach(dvb_pll_attach, adap->fe, 0x61,
Michael Krufky47a99912007-06-12 16:10:51 -0300544 NULL, DVB_PLL_THOMSON_DTT7579);
Chris Pascoe0029ee12006-01-09 18:21:28 -0200545 return 0;
546}
547
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300548static int cxusb_lgz201_tuner_attach(struct dvb_usb_adapter *adap)
Michael Krufky6f447252006-01-11 19:40:33 -0200549{
Michael Krufky47a99912007-06-12 16:10:51 -0300550 dvb_attach(dvb_pll_attach, adap->fe, 0x61, NULL, DVB_PLL_LG_Z201);
Michael Krufky6f447252006-01-11 19:40:33 -0200551 return 0;
552}
553
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300554static int cxusb_dtt7579_tuner_attach(struct dvb_usb_adapter *adap)
Michael Krufky6f447252006-01-11 19:40:33 -0200555{
Michael Krufky79a54cb2006-12-05 14:20:06 -0300556 dvb_attach(dvb_pll_attach, adap->fe, 0x60,
Michael Krufky47a99912007-06-12 16:10:51 -0300557 NULL, DVB_PLL_THOMSON_DTT7579);
Patrick Boettcher332bed52006-05-14 04:49:00 -0300558 return 0;
559}
560
Michael Krufkyf71a56c2006-10-13 21:55:57 -0300561static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap)
Patrick Boettcher332bed52006-05-14 04:49:00 -0300562{
Michael Krufky827855d2008-04-22 14:46:16 -0300563 dvb_attach(simple_tuner_attach, adap->fe,
564 &adap->dev->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF);
Michael Krufky6f447252006-01-11 19:40:33 -0200565 return 0;
566}
567
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300568static int dvico_bluebird_xc2028_callback(void *ptr, int command, int arg)
569{
Robert Loweryd483b732008-07-30 19:43:11 -0300570 struct dvb_usb_adapter *adap = ptr;
571 struct dvb_usb_device *d = adap->dev;
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300572
573 switch (command) {
574 case XC2028_TUNER_RESET:
Harvey Harrison708bebd2008-04-08 23:20:00 -0300575 deb_info("%s: XC2028_TUNER_RESET %d\n", __func__, arg);
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300576 cxusb_bluebird_gpio_pulse(d, 0x01, 1);
577 break;
578 case XC2028_RESET_CLK:
Harvey Harrison708bebd2008-04-08 23:20:00 -0300579 deb_info("%s: XC2028_RESET_CLK %d\n", __func__, arg);
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300580 break;
581 default:
Harvey Harrison708bebd2008-04-08 23:20:00 -0300582 deb_info("%s: unknown command %d, arg %d\n", __func__,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300583 command, arg);
584 return -EINVAL;
585 }
586
587 return 0;
588}
589
590static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap)
591{
592 struct dvb_frontend *fe;
593 struct xc2028_config cfg = {
594 .i2c_adap = &adap->dev->i2c_adap,
595 .i2c_addr = 0x61,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300596 .callback = dvico_bluebird_xc2028_callback,
597 };
598 static struct xc2028_ctrl ctl = {
Robert Loweryd483b732008-07-30 19:43:11 -0300599 .fname = "xc3028-v27.fw",
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300600 .max_len = 64,
Robert Loweryd483b732008-07-30 19:43:11 -0300601 .demod = XC3028_FE_ZARLINK456,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300602 };
603
604 fe = dvb_attach(xc2028_attach, adap->fe, &cfg);
605 if (fe == NULL || fe->ops.tuner_ops.set_config == NULL)
606 return -EIO;
607
608 fe->ops.tuner_ops.set_config(fe, &ctl);
609
610 return 0;
611}
612
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300613static int cxusb_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
614{
615 dvb_attach(mxl5005s_attach, adap->fe,
616 &adap->dev->i2c_adap, &aver_a868r_tuner);
617 return 0;
618}
619
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300620static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700621{
Patrick Boettchere2efeab2005-09-09 13:02:51 -0700622 u8 b;
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300623 if (usb_set_interface(adap->dev->udev, 0, 6) < 0)
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700624 err("set interface failed");
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700625
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300626 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, &b, 1);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700627
Michael Krufkyf35db232006-12-05 14:53:39 -0300628 if ((adap->fe = dvb_attach(cx22702_attach, &cxusb_cx22702_config,
629 &adap->dev->i2c_adap)) != NULL)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700630 return 0;
631
632 return -EIO;
633}
634
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300635static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
Michael Krufkyeffee032006-01-09 15:25:47 -0200636{
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300637 if (usb_set_interface(adap->dev->udev, 0, 7) < 0)
Michael Krufkyeffee032006-01-09 15:25:47 -0200638 err("set interface failed");
639
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300640 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
Michael Krufkyeffee032006-01-09 15:25:47 -0200641
Michael Krufkyf35db232006-12-05 14:53:39 -0300642 if ((adap->fe = dvb_attach(lgdt330x_attach, &cxusb_lgdt3303_config,
643 &adap->dev->i2c_adap)) != NULL)
Michael Krufkyeffee032006-01-09 15:25:47 -0200644 return 0;
645
646 return -EIO;
647}
648
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300649static int cxusb_aver_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
650{
651 adap->fe = dvb_attach(lgdt330x_attach, &cxusb_aver_lgdt3303_config,
652 &adap->dev->i2c_adap);
653 if (adap->fe != NULL)
654 return 0;
655
656 return -EIO;
657}
658
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300659static int cxusb_mt352_frontend_attach(struct dvb_usb_adapter *adap)
Chris Pascoe0029ee12006-01-09 18:21:28 -0200660{
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300661 /* used in both lgz201 and th7579 */
662 if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
Chris Pascoe0029ee12006-01-09 18:21:28 -0200663 err("set interface failed");
664
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300665 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
Chris Pascoe0029ee12006-01-09 18:21:28 -0200666
Michael Krufkyf35db232006-12-05 14:53:39 -0300667 if ((adap->fe = dvb_attach(mt352_attach, &cxusb_mt352_config,
668 &adap->dev->i2c_adap)) != NULL)
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300669 return 0;
670
671 return -EIO;
672}
673
674static int cxusb_dee1601_frontend_attach(struct dvb_usb_adapter *adap)
675{
676 if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
677 err("set interface failed");
678
679 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
680
Michael Krufkyf35db232006-12-05 14:53:39 -0300681 if (((adap->fe = dvb_attach(mt352_attach, &cxusb_dee1601_config,
682 &adap->dev->i2c_adap)) != NULL) ||
683 ((adap->fe = dvb_attach(zl10353_attach,
684 &cxusb_zl10353_dee1601_config,
685 &adap->dev->i2c_adap)) != NULL))
Chris Pascoe0029ee12006-01-09 18:21:28 -0200686 return 0;
687
688 return -EIO;
689}
690
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300691static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap)
692{
693 u8 ircode[4];
694 int i;
695 struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
696 .buf = ircode, .len = 4 };
697
698 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
699 err("set interface failed");
700
701 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
702
703 /* reset the tuner and demodulator */
704 cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
705 cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
706 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
707
708 if ((adap->fe = dvb_attach(zl10353_attach,
709 &cxusb_zl10353_xc3028_config,
710 &adap->dev->i2c_adap)) == NULL)
711 return -EIO;
712
713 /* try to determine if there is no IR decoder on the I2C bus */
714 for (i = 0; adap->dev->props.rc_key_map != NULL && i < 5; i++) {
715 msleep(20);
716 if (cxusb_i2c_xfer(&adap->dev->i2c_adap, &msg, 1) != 1)
717 goto no_IR;
718 if (ircode[0] == 0 && ircode[1] == 0)
719 continue;
720 if (ircode[2] + ircode[3] != 0xff) {
721no_IR:
722 adap->dev->props.rc_key_map = NULL;
723 info("No IR receiver detected on this device.");
724 break;
725 }
726 }
727
728 return 0;
729}
730
Anton Blanchard8d798982008-08-09 12:23:15 -0300731static struct dibx000_agc_config dib7070_agc_config = {
732 .band_caps = BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
733
734 /*
735 * P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5,
736 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
737 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0
738 */
739 .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) |
740 (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
741 .inv_gain = 600,
742 .time_stabiliz = 10,
743 .alpha_level = 0,
744 .thlock = 118,
745 .wbd_inv = 0,
746 .wbd_ref = 3530,
747 .wbd_sel = 1,
748 .wbd_alpha = 5,
749 .agc1_max = 65535,
750 .agc1_min = 0,
751 .agc2_max = 65535,
752 .agc2_min = 0,
753 .agc1_pt1 = 0,
754 .agc1_pt2 = 40,
755 .agc1_pt3 = 183,
756 .agc1_slope1 = 206,
757 .agc1_slope2 = 255,
758 .agc2_pt1 = 72,
759 .agc2_pt2 = 152,
760 .agc2_slope1 = 88,
761 .agc2_slope2 = 90,
762 .alpha_mant = 17,
763 .alpha_exp = 27,
764 .beta_mant = 23,
765 .beta_exp = 51,
766 .perform_agc_softsplit = 0,
767};
768
769static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
770 .internal = 60000,
771 .sampling = 15000,
772 .pll_prediv = 1,
773 .pll_ratio = 20,
774 .pll_range = 3,
775 .pll_reset = 1,
776 .pll_bypass = 0,
777 .enable_refdiv = 0,
778 .bypclk_div = 0,
779 .IO_CLK_en_core = 1,
780 .ADClkSrc = 1,
781 .modulo = 2,
782 /* refsel, sel, freq_15k */
783 .sad_cfg = (3 << 14) | (1 << 12) | (524 << 0),
784 .ifreq = (0 << 25) | 0,
785 .timf = 20452225,
786 .xtal_hz = 12000000,
787};
788
789static struct dib7000p_config cxusb_dualdig4_rev2_config = {
790 .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK,
791 .output_mpeg2_in_188_bytes = 1,
792
793 .agc_config_count = 1,
794 .agc = &dib7070_agc_config,
795 .bw = &dib7070_bw_config_12_mhz,
796 .tuner_is_baseband = 1,
797 .spur_protect = 1,
798
799 .gpio_dir = 0xfcef,
800 .gpio_val = 0x0110,
801
802 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
803
804 .hostbus_diversity = 1,
805};
806
807static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap)
808{
809 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
810 err("set interface failed");
811
812 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
813
814 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
815
816 dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
817 &cxusb_dualdig4_rev2_config);
818
819 if ((adap->fe = dvb_attach(dib7000p_attach,
820 &adap->dev->i2c_adap, 0x80,
821 &cxusb_dualdig4_rev2_config)) == NULL)
822 return -EIO;
823
824 return 0;
825}
826
827static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
828{
829 return dib7000p_set_gpio(fe, 8, 0, !onoff);
830}
831
832static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
833{
834 return 0;
835}
836
837static struct dib0070_config dib7070p_dib0070_config = {
838 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
839 .reset = dib7070_tuner_reset,
840 .sleep = dib7070_tuner_sleep,
841 .clock_khz = 12000,
842};
843
844struct dib0700_adapter_state {
845 int (*set_param_save) (struct dvb_frontend *,
846 struct dvb_frontend_parameters *);
847};
848
849static int dib7070_set_param_override(struct dvb_frontend *fe,
850 struct dvb_frontend_parameters *fep)
851{
852 struct dvb_usb_adapter *adap = fe->dvb->priv;
853 struct dib0700_adapter_state *state = adap->priv;
854
855 u16 offset;
856 u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
857 switch (band) {
858 case BAND_VHF: offset = 950; break;
859 case BAND_UHF:
860 default: offset = 550; break;
861 }
862
863 dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
864
865 return state->set_param_save(fe, fep);
866}
867
868static int cxusb_dualdig4_rev2_tuner_attach(struct dvb_usb_adapter *adap)
869{
870 struct dib0700_adapter_state *st = adap->priv;
871 struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
872
873 if (dvb_attach(dib0070_attach, adap->fe, tun_i2c,
874 &dib7070p_dib0070_config) == NULL)
875 return -ENODEV;
876
877 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
878 adap->fe->ops.tuner_ops.set_params = dib7070_set_param_override;
879 return 0;
880}
881
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300882static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap)
883{
884 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
885 err("set interface failed");
886
887 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
888
889 /* reset the tuner and demodulator */
890 cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
891 cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
892 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
893
894 if ((adap->fe = dvb_attach(zl10353_attach,
895 &cxusb_zl10353_xc3028_config,
896 &adap->dev->i2c_adap)) != NULL)
897 return 0;
898
Chris Pascoe702a6762007-11-20 03:34:11 -0300899 if ((adap->fe = dvb_attach(mt352_attach,
900 &cxusb_mt352_xc3028_config,
901 &adap->dev->i2c_adap)) != NULL)
902 return 0;
903
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300904 return -EIO;
905}
906
Patrick Boettcherf5373782006-01-09 18:21:38 -0200907/*
Chris Pascoe702a6762007-11-20 03:34:11 -0300908 * DViCO has shipped two devices with the same USB ID, but only one of them
909 * needs a firmware download. Check the device class details to see if they
910 * have non-default values to decide whether the device is actually cold or
911 * not, and forget a match if it turns out we selected the wrong device.
912 */
913static int bluebird_fx2_identify_state(struct usb_device *udev,
914 struct dvb_usb_device_properties *props,
915 struct dvb_usb_device_description **desc,
916 int *cold)
917{
918 int wascold = *cold;
919
920 *cold = udev->descriptor.bDeviceClass == 0xff &&
921 udev->descriptor.bDeviceSubClass == 0xff &&
922 udev->descriptor.bDeviceProtocol == 0xff;
923
924 if (*cold && !wascold)
925 *desc = NULL;
926
927 return 0;
928}
929
930/*
Patrick Boettcherf5373782006-01-09 18:21:38 -0200931 * DViCO bluebird firmware needs the "warm" product ID to be patched into the
932 * firmware file before download.
933 */
934
Chris Pascoe702a6762007-11-20 03:34:11 -0300935static const int dvico_firmware_id_offsets[] = { 6638, 3204 };
Michael Krufkyf35db232006-12-05 14:53:39 -0300936static int bluebird_patch_dvico_firmware_download(struct usb_device *udev,
937 const struct firmware *fw)
Patrick Boettcherf5373782006-01-09 18:21:38 -0200938{
Chris Pascoe702a6762007-11-20 03:34:11 -0300939 int pos;
Patrick Boettcherf5373782006-01-09 18:21:38 -0200940
Chris Pascoe702a6762007-11-20 03:34:11 -0300941 for (pos = 0; pos < ARRAY_SIZE(dvico_firmware_id_offsets); pos++) {
942 int idoff = dvico_firmware_id_offsets[pos];
Patrick Boettcherf5373782006-01-09 18:21:38 -0200943
Chris Pascoe702a6762007-11-20 03:34:11 -0300944 if (fw->size < idoff + 4)
945 continue;
Patrick Boettcherf5373782006-01-09 18:21:38 -0200946
Chris Pascoe702a6762007-11-20 03:34:11 -0300947 if (fw->data[idoff] == (USB_VID_DVICO & 0xff) &&
948 fw->data[idoff + 1] == USB_VID_DVICO >> 8) {
David Woodhousee62f89f2008-05-24 00:12:42 +0100949 struct firmware new_fw;
950 u8 *new_fw_data = vmalloc(fw->size);
951 int ret;
952
953 if (!new_fw_data)
954 return -ENOMEM;
955
956 memcpy(new_fw_data, fw->data, fw->size);
957 new_fw.size = fw->size;
958 new_fw.data = new_fw_data;
959
960 new_fw_data[idoff + 2] =
Chris Pascoe702a6762007-11-20 03:34:11 -0300961 le16_to_cpu(udev->descriptor.idProduct) + 1;
David Woodhousee62f89f2008-05-24 00:12:42 +0100962 new_fw_data[idoff + 3] =
Chris Pascoe702a6762007-11-20 03:34:11 -0300963 le16_to_cpu(udev->descriptor.idProduct) >> 8;
964
David Woodhousee62f89f2008-05-24 00:12:42 +0100965 ret = usb_cypress_load_firmware(udev, &new_fw,
966 CYPRESS_FX2);
967 vfree(new_fw_data);
968 return ret;
Chris Pascoe702a6762007-11-20 03:34:11 -0300969 }
Patrick Boettcherf5373782006-01-09 18:21:38 -0200970 }
971
972 return -EINVAL;
973}
974
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700975/* DVB USB Driver stuff */
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300976static struct dvb_usb_device_properties cxusb_medion_properties;
977static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties;
978static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties;
979static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties;
980static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties;
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300981static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties;
Anton Blanchard8d798982008-08-09 12:23:15 -0300982static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties;
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300983static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties;
Chris Pascoe702a6762007-11-20 03:34:11 -0300984static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties;
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300985static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700986
987static int cxusb_probe(struct usb_interface *intf,
Michael Krufkyf35db232006-12-05 14:53:39 -0300988 const struct usb_device_id *id)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700989{
Janne Grunau78e92002008-04-09 19:13:13 -0300990 if (0 == dvb_usb_device_init(intf, &cxusb_medion_properties,
991 THIS_MODULE, NULL, adapter_nr) ||
992 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgh064f_properties,
993 THIS_MODULE, NULL, adapter_nr) ||
994 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dee1601_properties,
995 THIS_MODULE, NULL, adapter_nr) ||
996 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgz201_properties,
997 THIS_MODULE, NULL, adapter_nr) ||
998 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dtt7579_properties,
999 THIS_MODULE, NULL, adapter_nr) ||
1000 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dualdig4_properties,
1001 THIS_MODULE, NULL, adapter_nr) ||
1002 0 == dvb_usb_device_init(intf, &cxusb_bluebird_nano2_properties,
1003 THIS_MODULE, NULL, adapter_nr) ||
1004 0 == dvb_usb_device_init(intf,
1005 &cxusb_bluebird_nano2_needsfirmware_properties,
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03001006 THIS_MODULE, NULL, adapter_nr) ||
1007 0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties,
1008 THIS_MODULE, NULL, adapter_nr) ||
Anton Blanchard8d798982008-08-09 12:23:15 -03001009 0 == dvb_usb_device_init(intf,
1010 &cxusb_bluebird_dualdig4_rev2_properties,
1011 THIS_MODULE, NULL, adapter_nr) ||
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03001012 0)
Michael Krufkyeffee032006-01-09 15:25:47 -02001013 return 0;
Michael Krufkyeffee032006-01-09 15:25:47 -02001014
1015 return -EINVAL;
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001016}
1017
1018static struct usb_device_id cxusb_table [] = {
Michael Krufkyf35db232006-12-05 14:53:39 -03001019 { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) },
1020 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) },
1021 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_WARM) },
1022 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_COLD) },
1023 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM) },
1024 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_COLD) },
1025 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_WARM) },
1026 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_COLD) },
1027 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_WARM) },
1028 { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD) },
1029 { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM) },
1030 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD) },
1031 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM) },
Chris Pascoeaeb012b2007-11-19 21:57:10 -03001032 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) },
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001033 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) },
Chris Pascoe702a6762007-11-20 03:34:11 -03001034 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) },
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03001035 { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) },
Anton Blanchard8d798982008-08-09 12:23:15 -03001036 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) },
Michael Krufkyf35db232006-12-05 14:53:39 -03001037 {} /* Terminating entry */
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001038};
1039MODULE_DEVICE_TABLE (usb, cxusb_table);
1040
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001041static struct dvb_usb_device_properties cxusb_medion_properties = {
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001042 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1043
1044 .usb_ctrl = CYPRESS_FX2,
1045
1046 .size_of_priv = sizeof(struct cxusb_state),
1047
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001048 .num_adapters = 1,
1049 .adapter = {
1050 {
Patrick Boettcher01451e72006-10-13 11:34:46 -03001051 .streaming_ctrl = cxusb_streaming_ctrl,
1052 .frontend_attach = cxusb_cx22702_frontend_attach,
1053 .tuner_attach = cxusb_fmd1216me_tuner_attach,
1054 /* parameter for the MPEG2-data transfer */
1055 .stream = {
1056 .type = USB_BULK,
1057 .count = 5,
1058 .endpoint = 0x02,
1059 .u = {
1060 .bulk = {
1061 .buffersize = 8192,
1062 }
1063 }
1064 },
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001065
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001066 },
1067 },
1068 .power_ctrl = cxusb_power_ctrl,
1069
1070 .i2c_algo = &cxusb_i2c_algo,
1071
1072 .generic_bulk_ctrl_endpoint = 0x01,
1073
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001074 .num_device_descs = 1,
1075 .devices = {
1076 { "Medion MD95700 (MDUSBTV-HYBRID)",
1077 { NULL },
1078 { &cxusb_table[0], NULL },
1079 },
1080 }
1081};
1082
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001083static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = {
Michael Krufkyeffee032006-01-09 15:25:47 -02001084 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1085
Patrick Boettcherf5373782006-01-09 18:21:38 -02001086 .usb_ctrl = DEVICE_SPECIFIC,
1087 .firmware = "dvb-usb-bluebird-01.fw",
1088 .download_firmware = bluebird_patch_dvico_firmware_download,
Michael Krufky37bdfa02006-01-09 15:25:47 -02001089 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1090 use usb alt setting 7 for EP2 transfer (atsc) */
Michael Krufkyeffee032006-01-09 15:25:47 -02001091
1092 .size_of_priv = sizeof(struct cxusb_state),
1093
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001094 .num_adapters = 1,
1095 .adapter = {
1096 {
Patrick Boettcher01451e72006-10-13 11:34:46 -03001097 .streaming_ctrl = cxusb_streaming_ctrl,
1098 .frontend_attach = cxusb_lgdt3303_frontend_attach,
Michael Krufkyf71a56c2006-10-13 21:55:57 -03001099 .tuner_attach = cxusb_lgh064f_tuner_attach,
Michael Krufkyeffee032006-01-09 15:25:47 -02001100
Patrick Boettcher01451e72006-10-13 11:34:46 -03001101 /* parameter for the MPEG2-data transfer */
1102 .stream = {
1103 .type = USB_BULK,
1104 .count = 5,
1105 .endpoint = 0x02,
1106 .u = {
1107 .bulk = {
1108 .buffersize = 8192,
1109 }
1110 }
1111 },
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001112 },
1113 },
1114
1115 .power_ctrl = cxusb_bluebird_power_ctrl,
1116
Michael Krufkyeffee032006-01-09 15:25:47 -02001117 .i2c_algo = &cxusb_i2c_algo,
1118
Michael Krufkyc1501782006-03-26 05:43:36 -03001119 .rc_interval = 100,
1120 .rc_key_map = dvico_portable_rc_keys,
1121 .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys),
1122 .rc_query = cxusb_rc_query,
1123
Michael Krufkyeffee032006-01-09 15:25:47 -02001124 .generic_bulk_ctrl_endpoint = 0x01,
Michael Krufkyeffee032006-01-09 15:25:47 -02001125
1126 .num_device_descs = 1,
1127 .devices = {
1128 { "DViCO FusionHDTV5 USB Gold",
1129 { &cxusb_table[1], NULL },
1130 { &cxusb_table[2], NULL },
1131 },
1132 }
1133};
1134
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001135static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = {
Chris Pascoe0029ee12006-01-09 18:21:28 -02001136 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1137
Patrick Boettcherf5373782006-01-09 18:21:38 -02001138 .usb_ctrl = DEVICE_SPECIFIC,
1139 .firmware = "dvb-usb-bluebird-01.fw",
1140 .download_firmware = bluebird_patch_dvico_firmware_download,
Chris Pascoe0029ee12006-01-09 18:21:28 -02001141 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1142 use usb alt setting 7 for EP2 transfer (atsc) */
1143
1144 .size_of_priv = sizeof(struct cxusb_state),
1145
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001146 .num_adapters = 1,
1147 .adapter = {
1148 {
Patrick Boettcher01451e72006-10-13 11:34:46 -03001149 .streaming_ctrl = cxusb_streaming_ctrl,
1150 .frontend_attach = cxusb_dee1601_frontend_attach,
1151 .tuner_attach = cxusb_dee1601_tuner_attach,
1152 /* parameter for the MPEG2-data transfer */
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001153 .stream = {
1154 .type = USB_BULK,
Patrick Boettcher01451e72006-10-13 11:34:46 -03001155 .count = 5,
1156 .endpoint = 0x04,
1157 .u = {
1158 .bulk = {
1159 .buffersize = 8192,
1160 }
1161 }
1162 },
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001163 },
1164 },
1165
1166 .power_ctrl = cxusb_bluebird_power_ctrl,
Chris Pascoe0029ee12006-01-09 18:21:28 -02001167
1168 .i2c_algo = &cxusb_i2c_algo,
1169
Chris Pascoe7c239702006-01-09 18:21:29 -02001170 .rc_interval = 150,
1171 .rc_key_map = dvico_mce_rc_keys,
1172 .rc_key_map_size = ARRAY_SIZE(dvico_mce_rc_keys),
1173 .rc_query = cxusb_rc_query,
1174
Chris Pascoe0029ee12006-01-09 18:21:28 -02001175 .generic_bulk_ctrl_endpoint = 0x01,
Chris Pascoe0029ee12006-01-09 18:21:28 -02001176
Michael Krufky587c03d2006-09-28 02:16:01 -03001177 .num_device_descs = 3,
Chris Pascoe0029ee12006-01-09 18:21:28 -02001178 .devices = {
1179 { "DViCO FusionHDTV DVB-T Dual USB",
1180 { &cxusb_table[3], NULL },
1181 { &cxusb_table[4], NULL },
1182 },
Michael Krufkyac9ffb92006-01-11 23:21:00 -02001183 { "DigitalNow DVB-T Dual USB",
1184 { &cxusb_table[9], NULL },
1185 { &cxusb_table[10], NULL },
1186 },
Michael Krufky587c03d2006-09-28 02:16:01 -03001187 { "DViCO FusionHDTV DVB-T Dual Digital 2",
1188 { &cxusb_table[11], NULL },
1189 { &cxusb_table[12], NULL },
1190 },
Chris Pascoe0029ee12006-01-09 18:21:28 -02001191 }
1192};
1193
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001194static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = {
Michael Krufky6f447252006-01-11 19:40:33 -02001195 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1196
1197 .usb_ctrl = DEVICE_SPECIFIC,
1198 .firmware = "dvb-usb-bluebird-01.fw",
1199 .download_firmware = bluebird_patch_dvico_firmware_download,
1200 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1201 use usb alt setting 7 for EP2 transfer (atsc) */
1202
1203 .size_of_priv = sizeof(struct cxusb_state),
1204
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001205 .num_adapters = 2,
1206 .adapter = {
1207 {
Patrick Boettcher01451e72006-10-13 11:34:46 -03001208 .streaming_ctrl = cxusb_streaming_ctrl,
1209 .frontend_attach = cxusb_mt352_frontend_attach,
1210 .tuner_attach = cxusb_lgz201_tuner_attach,
Michael Krufky6f447252006-01-11 19:40:33 -02001211
Patrick Boettcher01451e72006-10-13 11:34:46 -03001212 /* parameter for the MPEG2-data transfer */
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001213 .stream = {
1214 .type = USB_BULK,
Patrick Boettcher01451e72006-10-13 11:34:46 -03001215 .count = 5,
1216 .endpoint = 0x04,
1217 .u = {
1218 .bulk = {
1219 .buffersize = 8192,
1220 }
1221 }
1222 },
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001223 },
1224 },
1225 .power_ctrl = cxusb_bluebird_power_ctrl,
1226
Michael Krufky6f447252006-01-11 19:40:33 -02001227 .i2c_algo = &cxusb_i2c_algo,
1228
Michael Krufkyc1501782006-03-26 05:43:36 -03001229 .rc_interval = 100,
1230 .rc_key_map = dvico_portable_rc_keys,
1231 .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys),
1232 .rc_query = cxusb_rc_query,
1233
Michael Krufky6f447252006-01-11 19:40:33 -02001234 .generic_bulk_ctrl_endpoint = 0x01,
Michael Krufky6f447252006-01-11 19:40:33 -02001235 .num_device_descs = 1,
1236 .devices = {
1237 { "DViCO FusionHDTV DVB-T USB (LGZ201)",
1238 { &cxusb_table[5], NULL },
1239 { &cxusb_table[6], NULL },
1240 },
1241 }
1242};
1243
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001244static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = {
Michael Krufky6f447252006-01-11 19:40:33 -02001245 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1246
1247 .usb_ctrl = DEVICE_SPECIFIC,
1248 .firmware = "dvb-usb-bluebird-01.fw",
1249 .download_firmware = bluebird_patch_dvico_firmware_download,
1250 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1251 use usb alt setting 7 for EP2 transfer (atsc) */
1252
1253 .size_of_priv = sizeof(struct cxusb_state),
1254
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001255 .num_adapters = 1,
1256 .adapter = {
1257 {
Patrick Boettcher01451e72006-10-13 11:34:46 -03001258 .streaming_ctrl = cxusb_streaming_ctrl,
1259 .frontend_attach = cxusb_mt352_frontend_attach,
1260 .tuner_attach = cxusb_dtt7579_tuner_attach,
Michael Krufky6f447252006-01-11 19:40:33 -02001261
Patrick Boettcher01451e72006-10-13 11:34:46 -03001262 /* parameter for the MPEG2-data transfer */
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001263 .stream = {
1264 .type = USB_BULK,
Patrick Boettcher01451e72006-10-13 11:34:46 -03001265 .count = 5,
1266 .endpoint = 0x04,
1267 .u = {
1268 .bulk = {
1269 .buffersize = 8192,
1270 }
1271 }
1272 },
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001273 },
1274 },
1275 .power_ctrl = cxusb_bluebird_power_ctrl,
1276
Michael Krufky6f447252006-01-11 19:40:33 -02001277 .i2c_algo = &cxusb_i2c_algo,
1278
Michael Krufkyc1501782006-03-26 05:43:36 -03001279 .rc_interval = 100,
1280 .rc_key_map = dvico_portable_rc_keys,
1281 .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys),
1282 .rc_query = cxusb_rc_query,
1283
Michael Krufky6f447252006-01-11 19:40:33 -02001284 .generic_bulk_ctrl_endpoint = 0x01,
Michael Krufky6f447252006-01-11 19:40:33 -02001285
1286 .num_device_descs = 1,
1287 .devices = {
1288 { "DViCO FusionHDTV DVB-T USB (TH7579)",
1289 { &cxusb_table[7], NULL },
1290 { &cxusb_table[8], NULL },
1291 },
1292 }
1293};
1294
Chris Pascoeaeb012b2007-11-19 21:57:10 -03001295static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = {
1296 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1297
1298 .usb_ctrl = CYPRESS_FX2,
1299
1300 .size_of_priv = sizeof(struct cxusb_state),
1301
1302 .num_adapters = 1,
1303 .adapter = {
1304 {
1305 .streaming_ctrl = cxusb_streaming_ctrl,
1306 .frontend_attach = cxusb_dualdig4_frontend_attach,
1307 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1308 /* parameter for the MPEG2-data transfer */
1309 .stream = {
1310 .type = USB_BULK,
1311 .count = 5,
1312 .endpoint = 0x02,
1313 .u = {
1314 .bulk = {
1315 .buffersize = 8192,
1316 }
1317 }
1318 },
1319 },
1320 },
1321
1322 .power_ctrl = cxusb_power_ctrl,
1323
1324 .i2c_algo = &cxusb_i2c_algo,
1325
1326 .generic_bulk_ctrl_endpoint = 0x01,
1327
1328 .rc_interval = 100,
1329 .rc_key_map = dvico_mce_rc_keys,
1330 .rc_key_map_size = ARRAY_SIZE(dvico_mce_rc_keys),
1331 .rc_query = cxusb_bluebird2_rc_query,
1332
1333 .num_device_descs = 1,
1334 .devices = {
1335 { "DViCO FusionHDTV DVB-T Dual Digital 4",
1336 { NULL },
1337 { &cxusb_table[13], NULL },
1338 },
1339 }
1340};
1341
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001342static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = {
1343 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1344
1345 .usb_ctrl = CYPRESS_FX2,
Chris Pascoe702a6762007-11-20 03:34:11 -03001346 .identify_state = bluebird_fx2_identify_state,
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001347
1348 .size_of_priv = sizeof(struct cxusb_state),
1349
1350 .num_adapters = 1,
1351 .adapter = {
1352 {
1353 .streaming_ctrl = cxusb_streaming_ctrl,
1354 .frontend_attach = cxusb_nano2_frontend_attach,
1355 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1356 /* parameter for the MPEG2-data transfer */
1357 .stream = {
1358 .type = USB_BULK,
1359 .count = 5,
1360 .endpoint = 0x02,
1361 .u = {
1362 .bulk = {
1363 .buffersize = 8192,
1364 }
1365 }
1366 },
1367 },
1368 },
1369
1370 .power_ctrl = cxusb_nano2_power_ctrl,
1371
1372 .i2c_algo = &cxusb_i2c_algo,
1373
1374 .generic_bulk_ctrl_endpoint = 0x01,
1375
1376 .rc_interval = 100,
1377 .rc_key_map = dvico_portable_rc_keys,
1378 .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys),
1379 .rc_query = cxusb_bluebird2_rc_query,
1380
1381 .num_device_descs = 1,
1382 .devices = {
1383 { "DViCO FusionHDTV DVB-T NANO2",
1384 { NULL },
1385 { &cxusb_table[14], NULL },
1386 },
1387 }
1388};
1389
Chris Pascoe702a6762007-11-20 03:34:11 -03001390static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties = {
1391 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1392
1393 .usb_ctrl = DEVICE_SPECIFIC,
1394 .firmware = "dvb-usb-bluebird-02.fw",
1395 .download_firmware = bluebird_patch_dvico_firmware_download,
1396 .identify_state = bluebird_fx2_identify_state,
1397
1398 .size_of_priv = sizeof(struct cxusb_state),
1399
1400 .num_adapters = 1,
1401 .adapter = {
1402 {
1403 .streaming_ctrl = cxusb_streaming_ctrl,
1404 .frontend_attach = cxusb_nano2_frontend_attach,
1405 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1406 /* parameter for the MPEG2-data transfer */
1407 .stream = {
1408 .type = USB_BULK,
1409 .count = 5,
1410 .endpoint = 0x02,
1411 .u = {
1412 .bulk = {
1413 .buffersize = 8192,
1414 }
1415 }
1416 },
1417 },
1418 },
1419
1420 .power_ctrl = cxusb_nano2_power_ctrl,
1421
1422 .i2c_algo = &cxusb_i2c_algo,
1423
1424 .generic_bulk_ctrl_endpoint = 0x01,
1425
1426 .rc_interval = 100,
1427 .rc_key_map = dvico_portable_rc_keys,
1428 .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys),
1429 .rc_query = cxusb_rc_query,
1430
1431 .num_device_descs = 1,
1432 .devices = {
1433 { "DViCO FusionHDTV DVB-T NANO2 w/o firmware",
1434 { &cxusb_table[14], NULL },
1435 { &cxusb_table[15], NULL },
1436 },
1437 }
1438};
1439
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03001440static struct dvb_usb_device_properties cxusb_aver_a868r_properties = {
1441 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1442
1443 .usb_ctrl = CYPRESS_FX2,
1444
1445 .size_of_priv = sizeof(struct cxusb_state),
1446
1447 .num_adapters = 1,
1448 .adapter = {
1449 {
1450 .streaming_ctrl = cxusb_aver_streaming_ctrl,
1451 .frontend_attach = cxusb_aver_lgdt3303_frontend_attach,
1452 .tuner_attach = cxusb_mxl5003s_tuner_attach,
1453 /* parameter for the MPEG2-data transfer */
1454 .stream = {
1455 .type = USB_BULK,
1456 .count = 5,
1457 .endpoint = 0x04,
1458 .u = {
1459 .bulk = {
1460 .buffersize = 8192,
1461 }
1462 }
1463 },
1464
1465 },
1466 },
1467 .power_ctrl = cxusb_aver_power_ctrl,
1468
1469 .i2c_algo = &cxusb_i2c_algo,
1470
1471 .generic_bulk_ctrl_endpoint = 0x01,
1472
1473 .num_device_descs = 1,
1474 .devices = {
1475 { "AVerMedia AVerTVHD Volar (A868R)",
1476 { NULL },
1477 { &cxusb_table[16], NULL },
1478 },
1479 }
1480};
1481
Anton Blanchard8d798982008-08-09 12:23:15 -03001482static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = {
1483 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1484
1485 .usb_ctrl = CYPRESS_FX2,
1486
1487 .size_of_priv = sizeof(struct cxusb_state),
1488
1489 .num_adapters = 1,
1490 .adapter = {
1491 {
1492 .streaming_ctrl = cxusb_streaming_ctrl,
1493 .frontend_attach = cxusb_dualdig4_rev2_frontend_attach,
1494 .tuner_attach = cxusb_dualdig4_rev2_tuner_attach,
1495 .size_of_priv = sizeof(struct dib0700_adapter_state),
1496 /* parameter for the MPEG2-data transfer */
1497 .stream = {
1498 .type = USB_BULK,
1499 .count = 7,
1500 .endpoint = 0x02,
1501 .u = {
1502 .bulk = {
1503 .buffersize = 4096,
1504 }
1505 }
1506 },
1507 },
1508 },
1509
1510 .power_ctrl = cxusb_bluebird_power_ctrl,
1511
1512 .i2c_algo = &cxusb_i2c_algo,
1513
1514 .generic_bulk_ctrl_endpoint = 0x01,
1515
1516 .rc_interval = 100,
1517 .rc_key_map = dvico_mce_rc_keys,
1518 .rc_key_map_size = ARRAY_SIZE(dvico_mce_rc_keys),
1519 .rc_query = cxusb_rc_query,
1520
1521 .num_device_descs = 1,
1522 .devices = {
1523 { "DViCO FusionHDTV DVB-T Dual Digital 4 (rev 2)",
1524 { NULL },
1525 { &cxusb_table[17], NULL },
1526 },
1527 }
1528};
1529
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001530static struct usb_driver cxusb_driver = {
Patrick Boettcher63b5c1c2005-07-07 17:58:30 -07001531 .name = "dvb_usb_cxusb",
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001532 .probe = cxusb_probe,
Michael Krufkyf35db232006-12-05 14:53:39 -03001533 .disconnect = dvb_usb_device_exit,
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001534 .id_table = cxusb_table,
1535};
1536
1537/* module stuff */
1538static int __init cxusb_module_init(void)
1539{
1540 int result;
1541 if ((result = usb_register(&cxusb_driver))) {
1542 err("usb_register failed. Error number %d",result);
1543 return result;
1544 }
1545
1546 return 0;
1547}
1548
1549static void __exit cxusb_module_exit(void)
1550{
1551 /* deregister this driver from the USB subsystem */
1552 usb_deregister(&cxusb_driver);
1553}
1554
1555module_init (cxusb_module_init);
1556module_exit (cxusb_module_exit);
1557
1558MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
Michael Krufky5b9ed282006-10-15 14:51:08 -03001559MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
Michael Krufkyf4efb4d2006-01-13 14:10:25 -02001560MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001561MODULE_DESCRIPTION("Driver for Conexant USB2.0 hybrid reference design");
1562MODULE_VERSION("1.0-alpha");
1563MODULE_LICENSE("GPL");