blob: 338c819ca7397391480de560d58711321aba9f59 [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
Michael Krufkya2dc86b2008-08-09 13:06:26 -0300819 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
820 &cxusb_dualdig4_rev2_config);
821 if (adap->fe == NULL)
Anton Blanchard8d798982008-08-09 12:23:15 -0300822 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) {
Michael Krufkya2dc86b2008-08-09 13:06:26 -0300858 case BAND_VHF: offset = 950; break;
859 default:
860 case BAND_UHF: offset = 550; break;
Anton Blanchard8d798982008-08-09 12:23:15 -0300861 }
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;
Michael Krufkya2dc86b2008-08-09 13:06:26 -0300871 struct i2c_adapter *tun_i2c =
872 dib7000p_get_i2c_master(adap->fe,
873 DIBX000_I2C_INTERFACE_TUNER, 1);
Anton Blanchard8d798982008-08-09 12:23:15 -0300874
875 if (dvb_attach(dib0070_attach, adap->fe, tun_i2c,
876 &dib7070p_dib0070_config) == NULL)
877 return -ENODEV;
878
879 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
880 adap->fe->ops.tuner_ops.set_params = dib7070_set_param_override;
881 return 0;
882}
883
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300884static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap)
885{
886 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
887 err("set interface failed");
888
889 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
890
891 /* reset the tuner and demodulator */
892 cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
893 cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
894 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
895
896 if ((adap->fe = dvb_attach(zl10353_attach,
897 &cxusb_zl10353_xc3028_config,
898 &adap->dev->i2c_adap)) != NULL)
899 return 0;
900
Chris Pascoe702a6762007-11-20 03:34:11 -0300901 if ((adap->fe = dvb_attach(mt352_attach,
902 &cxusb_mt352_xc3028_config,
903 &adap->dev->i2c_adap)) != NULL)
904 return 0;
905
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300906 return -EIO;
907}
908
Patrick Boettcherf5373782006-01-09 18:21:38 -0200909/*
Chris Pascoe702a6762007-11-20 03:34:11 -0300910 * DViCO has shipped two devices with the same USB ID, but only one of them
911 * needs a firmware download. Check the device class details to see if they
912 * have non-default values to decide whether the device is actually cold or
913 * not, and forget a match if it turns out we selected the wrong device.
914 */
915static int bluebird_fx2_identify_state(struct usb_device *udev,
916 struct dvb_usb_device_properties *props,
917 struct dvb_usb_device_description **desc,
918 int *cold)
919{
920 int wascold = *cold;
921
922 *cold = udev->descriptor.bDeviceClass == 0xff &&
923 udev->descriptor.bDeviceSubClass == 0xff &&
924 udev->descriptor.bDeviceProtocol == 0xff;
925
926 if (*cold && !wascold)
927 *desc = NULL;
928
929 return 0;
930}
931
932/*
Patrick Boettcherf5373782006-01-09 18:21:38 -0200933 * DViCO bluebird firmware needs the "warm" product ID to be patched into the
934 * firmware file before download.
935 */
936
Chris Pascoe702a6762007-11-20 03:34:11 -0300937static const int dvico_firmware_id_offsets[] = { 6638, 3204 };
Michael Krufkyf35db232006-12-05 14:53:39 -0300938static int bluebird_patch_dvico_firmware_download(struct usb_device *udev,
939 const struct firmware *fw)
Patrick Boettcherf5373782006-01-09 18:21:38 -0200940{
Chris Pascoe702a6762007-11-20 03:34:11 -0300941 int pos;
Patrick Boettcherf5373782006-01-09 18:21:38 -0200942
Chris Pascoe702a6762007-11-20 03:34:11 -0300943 for (pos = 0; pos < ARRAY_SIZE(dvico_firmware_id_offsets); pos++) {
944 int idoff = dvico_firmware_id_offsets[pos];
Patrick Boettcherf5373782006-01-09 18:21:38 -0200945
Chris Pascoe702a6762007-11-20 03:34:11 -0300946 if (fw->size < idoff + 4)
947 continue;
Patrick Boettcherf5373782006-01-09 18:21:38 -0200948
Chris Pascoe702a6762007-11-20 03:34:11 -0300949 if (fw->data[idoff] == (USB_VID_DVICO & 0xff) &&
950 fw->data[idoff + 1] == USB_VID_DVICO >> 8) {
David Woodhousee62f89f2008-05-24 00:12:42 +0100951 struct firmware new_fw;
952 u8 *new_fw_data = vmalloc(fw->size);
953 int ret;
954
955 if (!new_fw_data)
956 return -ENOMEM;
957
958 memcpy(new_fw_data, fw->data, fw->size);
959 new_fw.size = fw->size;
960 new_fw.data = new_fw_data;
961
962 new_fw_data[idoff + 2] =
Chris Pascoe702a6762007-11-20 03:34:11 -0300963 le16_to_cpu(udev->descriptor.idProduct) + 1;
David Woodhousee62f89f2008-05-24 00:12:42 +0100964 new_fw_data[idoff + 3] =
Chris Pascoe702a6762007-11-20 03:34:11 -0300965 le16_to_cpu(udev->descriptor.idProduct) >> 8;
966
David Woodhousee62f89f2008-05-24 00:12:42 +0100967 ret = usb_cypress_load_firmware(udev, &new_fw,
968 CYPRESS_FX2);
969 vfree(new_fw_data);
970 return ret;
Chris Pascoe702a6762007-11-20 03:34:11 -0300971 }
Patrick Boettcherf5373782006-01-09 18:21:38 -0200972 }
973
974 return -EINVAL;
975}
976
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700977/* DVB USB Driver stuff */
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300978static struct dvb_usb_device_properties cxusb_medion_properties;
979static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties;
980static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties;
981static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties;
982static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties;
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300983static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties;
Anton Blanchard8d798982008-08-09 12:23:15 -0300984static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties;
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300985static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties;
Chris Pascoe702a6762007-11-20 03:34:11 -0300986static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties;
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300987static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700988
989static int cxusb_probe(struct usb_interface *intf,
Michael Krufkyf35db232006-12-05 14:53:39 -0300990 const struct usb_device_id *id)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700991{
Janne Grunau78e92002008-04-09 19:13:13 -0300992 if (0 == dvb_usb_device_init(intf, &cxusb_medion_properties,
993 THIS_MODULE, NULL, adapter_nr) ||
994 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgh064f_properties,
995 THIS_MODULE, NULL, adapter_nr) ||
996 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dee1601_properties,
997 THIS_MODULE, NULL, adapter_nr) ||
998 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgz201_properties,
999 THIS_MODULE, NULL, adapter_nr) ||
1000 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dtt7579_properties,
1001 THIS_MODULE, NULL, adapter_nr) ||
1002 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dualdig4_properties,
1003 THIS_MODULE, NULL, adapter_nr) ||
1004 0 == dvb_usb_device_init(intf, &cxusb_bluebird_nano2_properties,
1005 THIS_MODULE, NULL, adapter_nr) ||
1006 0 == dvb_usb_device_init(intf,
1007 &cxusb_bluebird_nano2_needsfirmware_properties,
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03001008 THIS_MODULE, NULL, adapter_nr) ||
1009 0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties,
1010 THIS_MODULE, NULL, adapter_nr) ||
Anton Blanchard8d798982008-08-09 12:23:15 -03001011 0 == dvb_usb_device_init(intf,
1012 &cxusb_bluebird_dualdig4_rev2_properties,
1013 THIS_MODULE, NULL, adapter_nr) ||
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03001014 0)
Michael Krufkyeffee032006-01-09 15:25:47 -02001015 return 0;
Michael Krufkyeffee032006-01-09 15:25:47 -02001016
1017 return -EINVAL;
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001018}
1019
1020static struct usb_device_id cxusb_table [] = {
Michael Krufkyf35db232006-12-05 14:53:39 -03001021 { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) },
1022 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) },
1023 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_WARM) },
1024 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_COLD) },
1025 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM) },
1026 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_COLD) },
1027 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_WARM) },
1028 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_COLD) },
1029 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_WARM) },
1030 { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD) },
1031 { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM) },
1032 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD) },
1033 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM) },
Chris Pascoeaeb012b2007-11-19 21:57:10 -03001034 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) },
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001035 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) },
Chris Pascoe702a6762007-11-20 03:34:11 -03001036 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) },
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03001037 { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) },
Anton Blanchard8d798982008-08-09 12:23:15 -03001038 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) },
Michael Krufkyf35db232006-12-05 14:53:39 -03001039 {} /* Terminating entry */
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001040};
1041MODULE_DEVICE_TABLE (usb, cxusb_table);
1042
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001043static struct dvb_usb_device_properties cxusb_medion_properties = {
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001044 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1045
1046 .usb_ctrl = CYPRESS_FX2,
1047
1048 .size_of_priv = sizeof(struct cxusb_state),
1049
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001050 .num_adapters = 1,
1051 .adapter = {
1052 {
Patrick Boettcher01451e72006-10-13 11:34:46 -03001053 .streaming_ctrl = cxusb_streaming_ctrl,
1054 .frontend_attach = cxusb_cx22702_frontend_attach,
1055 .tuner_attach = cxusb_fmd1216me_tuner_attach,
1056 /* parameter for the MPEG2-data transfer */
1057 .stream = {
1058 .type = USB_BULK,
1059 .count = 5,
1060 .endpoint = 0x02,
1061 .u = {
1062 .bulk = {
1063 .buffersize = 8192,
1064 }
1065 }
1066 },
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001067
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001068 },
1069 },
1070 .power_ctrl = cxusb_power_ctrl,
1071
1072 .i2c_algo = &cxusb_i2c_algo,
1073
1074 .generic_bulk_ctrl_endpoint = 0x01,
1075
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001076 .num_device_descs = 1,
1077 .devices = {
1078 { "Medion MD95700 (MDUSBTV-HYBRID)",
1079 { NULL },
1080 { &cxusb_table[0], NULL },
1081 },
1082 }
1083};
1084
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001085static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = {
Michael Krufkyeffee032006-01-09 15:25:47 -02001086 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1087
Patrick Boettcherf5373782006-01-09 18:21:38 -02001088 .usb_ctrl = DEVICE_SPECIFIC,
1089 .firmware = "dvb-usb-bluebird-01.fw",
1090 .download_firmware = bluebird_patch_dvico_firmware_download,
Michael Krufky37bdfa02006-01-09 15:25:47 -02001091 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1092 use usb alt setting 7 for EP2 transfer (atsc) */
Michael Krufkyeffee032006-01-09 15:25:47 -02001093
1094 .size_of_priv = sizeof(struct cxusb_state),
1095
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001096 .num_adapters = 1,
1097 .adapter = {
1098 {
Patrick Boettcher01451e72006-10-13 11:34:46 -03001099 .streaming_ctrl = cxusb_streaming_ctrl,
1100 .frontend_attach = cxusb_lgdt3303_frontend_attach,
Michael Krufkyf71a56c2006-10-13 21:55:57 -03001101 .tuner_attach = cxusb_lgh064f_tuner_attach,
Michael Krufkyeffee032006-01-09 15:25:47 -02001102
Patrick Boettcher01451e72006-10-13 11:34:46 -03001103 /* parameter for the MPEG2-data transfer */
1104 .stream = {
1105 .type = USB_BULK,
1106 .count = 5,
1107 .endpoint = 0x02,
1108 .u = {
1109 .bulk = {
1110 .buffersize = 8192,
1111 }
1112 }
1113 },
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001114 },
1115 },
1116
1117 .power_ctrl = cxusb_bluebird_power_ctrl,
1118
Michael Krufkyeffee032006-01-09 15:25:47 -02001119 .i2c_algo = &cxusb_i2c_algo,
1120
Michael Krufkyc1501782006-03-26 05:43:36 -03001121 .rc_interval = 100,
1122 .rc_key_map = dvico_portable_rc_keys,
1123 .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys),
1124 .rc_query = cxusb_rc_query,
1125
Michael Krufkyeffee032006-01-09 15:25:47 -02001126 .generic_bulk_ctrl_endpoint = 0x01,
Michael Krufkyeffee032006-01-09 15:25:47 -02001127
1128 .num_device_descs = 1,
1129 .devices = {
1130 { "DViCO FusionHDTV5 USB Gold",
1131 { &cxusb_table[1], NULL },
1132 { &cxusb_table[2], NULL },
1133 },
1134 }
1135};
1136
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001137static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = {
Chris Pascoe0029ee12006-01-09 18:21:28 -02001138 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1139
Patrick Boettcherf5373782006-01-09 18:21:38 -02001140 .usb_ctrl = DEVICE_SPECIFIC,
1141 .firmware = "dvb-usb-bluebird-01.fw",
1142 .download_firmware = bluebird_patch_dvico_firmware_download,
Chris Pascoe0029ee12006-01-09 18:21:28 -02001143 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1144 use usb alt setting 7 for EP2 transfer (atsc) */
1145
1146 .size_of_priv = sizeof(struct cxusb_state),
1147
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001148 .num_adapters = 1,
1149 .adapter = {
1150 {
Patrick Boettcher01451e72006-10-13 11:34:46 -03001151 .streaming_ctrl = cxusb_streaming_ctrl,
1152 .frontend_attach = cxusb_dee1601_frontend_attach,
1153 .tuner_attach = cxusb_dee1601_tuner_attach,
1154 /* parameter for the MPEG2-data transfer */
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001155 .stream = {
1156 .type = USB_BULK,
Patrick Boettcher01451e72006-10-13 11:34:46 -03001157 .count = 5,
1158 .endpoint = 0x04,
1159 .u = {
1160 .bulk = {
1161 .buffersize = 8192,
1162 }
1163 }
1164 },
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001165 },
1166 },
1167
1168 .power_ctrl = cxusb_bluebird_power_ctrl,
Chris Pascoe0029ee12006-01-09 18:21:28 -02001169
1170 .i2c_algo = &cxusb_i2c_algo,
1171
Chris Pascoe7c239702006-01-09 18:21:29 -02001172 .rc_interval = 150,
1173 .rc_key_map = dvico_mce_rc_keys,
1174 .rc_key_map_size = ARRAY_SIZE(dvico_mce_rc_keys),
1175 .rc_query = cxusb_rc_query,
1176
Chris Pascoe0029ee12006-01-09 18:21:28 -02001177 .generic_bulk_ctrl_endpoint = 0x01,
Chris Pascoe0029ee12006-01-09 18:21:28 -02001178
Michael Krufky587c03d2006-09-28 02:16:01 -03001179 .num_device_descs = 3,
Chris Pascoe0029ee12006-01-09 18:21:28 -02001180 .devices = {
1181 { "DViCO FusionHDTV DVB-T Dual USB",
1182 { &cxusb_table[3], NULL },
1183 { &cxusb_table[4], NULL },
1184 },
Michael Krufkyac9ffb92006-01-11 23:21:00 -02001185 { "DigitalNow DVB-T Dual USB",
1186 { &cxusb_table[9], NULL },
1187 { &cxusb_table[10], NULL },
1188 },
Michael Krufky587c03d2006-09-28 02:16:01 -03001189 { "DViCO FusionHDTV DVB-T Dual Digital 2",
1190 { &cxusb_table[11], NULL },
1191 { &cxusb_table[12], NULL },
1192 },
Chris Pascoe0029ee12006-01-09 18:21:28 -02001193 }
1194};
1195
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001196static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = {
Michael Krufky6f447252006-01-11 19:40:33 -02001197 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1198
1199 .usb_ctrl = DEVICE_SPECIFIC,
1200 .firmware = "dvb-usb-bluebird-01.fw",
1201 .download_firmware = bluebird_patch_dvico_firmware_download,
1202 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1203 use usb alt setting 7 for EP2 transfer (atsc) */
1204
1205 .size_of_priv = sizeof(struct cxusb_state),
1206
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001207 .num_adapters = 2,
1208 .adapter = {
1209 {
Patrick Boettcher01451e72006-10-13 11:34:46 -03001210 .streaming_ctrl = cxusb_streaming_ctrl,
1211 .frontend_attach = cxusb_mt352_frontend_attach,
1212 .tuner_attach = cxusb_lgz201_tuner_attach,
Michael Krufky6f447252006-01-11 19:40:33 -02001213
Patrick Boettcher01451e72006-10-13 11:34:46 -03001214 /* parameter for the MPEG2-data transfer */
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001215 .stream = {
1216 .type = USB_BULK,
Patrick Boettcher01451e72006-10-13 11:34:46 -03001217 .count = 5,
1218 .endpoint = 0x04,
1219 .u = {
1220 .bulk = {
1221 .buffersize = 8192,
1222 }
1223 }
1224 },
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001225 },
1226 },
1227 .power_ctrl = cxusb_bluebird_power_ctrl,
1228
Michael Krufky6f447252006-01-11 19:40:33 -02001229 .i2c_algo = &cxusb_i2c_algo,
1230
Michael Krufkyc1501782006-03-26 05:43:36 -03001231 .rc_interval = 100,
1232 .rc_key_map = dvico_portable_rc_keys,
1233 .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys),
1234 .rc_query = cxusb_rc_query,
1235
Michael Krufky6f447252006-01-11 19:40:33 -02001236 .generic_bulk_ctrl_endpoint = 0x01,
Michael Krufky6f447252006-01-11 19:40:33 -02001237 .num_device_descs = 1,
1238 .devices = {
1239 { "DViCO FusionHDTV DVB-T USB (LGZ201)",
1240 { &cxusb_table[5], NULL },
1241 { &cxusb_table[6], NULL },
1242 },
1243 }
1244};
1245
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001246static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = {
Michael Krufky6f447252006-01-11 19:40:33 -02001247 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1248
1249 .usb_ctrl = DEVICE_SPECIFIC,
1250 .firmware = "dvb-usb-bluebird-01.fw",
1251 .download_firmware = bluebird_patch_dvico_firmware_download,
1252 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1253 use usb alt setting 7 for EP2 transfer (atsc) */
1254
1255 .size_of_priv = sizeof(struct cxusb_state),
1256
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001257 .num_adapters = 1,
1258 .adapter = {
1259 {
Patrick Boettcher01451e72006-10-13 11:34:46 -03001260 .streaming_ctrl = cxusb_streaming_ctrl,
1261 .frontend_attach = cxusb_mt352_frontend_attach,
1262 .tuner_attach = cxusb_dtt7579_tuner_attach,
Michael Krufky6f447252006-01-11 19:40:33 -02001263
Patrick Boettcher01451e72006-10-13 11:34:46 -03001264 /* parameter for the MPEG2-data transfer */
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001265 .stream = {
1266 .type = USB_BULK,
Patrick Boettcher01451e72006-10-13 11:34:46 -03001267 .count = 5,
1268 .endpoint = 0x04,
1269 .u = {
1270 .bulk = {
1271 .buffersize = 8192,
1272 }
1273 }
1274 },
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001275 },
1276 },
1277 .power_ctrl = cxusb_bluebird_power_ctrl,
1278
Michael Krufky6f447252006-01-11 19:40:33 -02001279 .i2c_algo = &cxusb_i2c_algo,
1280
Michael Krufkyc1501782006-03-26 05:43:36 -03001281 .rc_interval = 100,
1282 .rc_key_map = dvico_portable_rc_keys,
1283 .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys),
1284 .rc_query = cxusb_rc_query,
1285
Michael Krufky6f447252006-01-11 19:40:33 -02001286 .generic_bulk_ctrl_endpoint = 0x01,
Michael Krufky6f447252006-01-11 19:40:33 -02001287
1288 .num_device_descs = 1,
1289 .devices = {
1290 { "DViCO FusionHDTV DVB-T USB (TH7579)",
1291 { &cxusb_table[7], NULL },
1292 { &cxusb_table[8], NULL },
1293 },
1294 }
1295};
1296
Chris Pascoeaeb012b2007-11-19 21:57:10 -03001297static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = {
1298 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1299
1300 .usb_ctrl = CYPRESS_FX2,
1301
1302 .size_of_priv = sizeof(struct cxusb_state),
1303
1304 .num_adapters = 1,
1305 .adapter = {
1306 {
1307 .streaming_ctrl = cxusb_streaming_ctrl,
1308 .frontend_attach = cxusb_dualdig4_frontend_attach,
1309 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1310 /* parameter for the MPEG2-data transfer */
1311 .stream = {
1312 .type = USB_BULK,
1313 .count = 5,
1314 .endpoint = 0x02,
1315 .u = {
1316 .bulk = {
1317 .buffersize = 8192,
1318 }
1319 }
1320 },
1321 },
1322 },
1323
1324 .power_ctrl = cxusb_power_ctrl,
1325
1326 .i2c_algo = &cxusb_i2c_algo,
1327
1328 .generic_bulk_ctrl_endpoint = 0x01,
1329
1330 .rc_interval = 100,
1331 .rc_key_map = dvico_mce_rc_keys,
1332 .rc_key_map_size = ARRAY_SIZE(dvico_mce_rc_keys),
1333 .rc_query = cxusb_bluebird2_rc_query,
1334
1335 .num_device_descs = 1,
1336 .devices = {
1337 { "DViCO FusionHDTV DVB-T Dual Digital 4",
1338 { NULL },
1339 { &cxusb_table[13], NULL },
1340 },
1341 }
1342};
1343
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001344static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = {
1345 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1346
1347 .usb_ctrl = CYPRESS_FX2,
Chris Pascoe702a6762007-11-20 03:34:11 -03001348 .identify_state = bluebird_fx2_identify_state,
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001349
1350 .size_of_priv = sizeof(struct cxusb_state),
1351
1352 .num_adapters = 1,
1353 .adapter = {
1354 {
1355 .streaming_ctrl = cxusb_streaming_ctrl,
1356 .frontend_attach = cxusb_nano2_frontend_attach,
1357 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1358 /* parameter for the MPEG2-data transfer */
1359 .stream = {
1360 .type = USB_BULK,
1361 .count = 5,
1362 .endpoint = 0x02,
1363 .u = {
1364 .bulk = {
1365 .buffersize = 8192,
1366 }
1367 }
1368 },
1369 },
1370 },
1371
1372 .power_ctrl = cxusb_nano2_power_ctrl,
1373
1374 .i2c_algo = &cxusb_i2c_algo,
1375
1376 .generic_bulk_ctrl_endpoint = 0x01,
1377
1378 .rc_interval = 100,
1379 .rc_key_map = dvico_portable_rc_keys,
1380 .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys),
1381 .rc_query = cxusb_bluebird2_rc_query,
1382
1383 .num_device_descs = 1,
1384 .devices = {
1385 { "DViCO FusionHDTV DVB-T NANO2",
1386 { NULL },
1387 { &cxusb_table[14], NULL },
1388 },
1389 }
1390};
1391
Chris Pascoe702a6762007-11-20 03:34:11 -03001392static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties = {
1393 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1394
1395 .usb_ctrl = DEVICE_SPECIFIC,
1396 .firmware = "dvb-usb-bluebird-02.fw",
1397 .download_firmware = bluebird_patch_dvico_firmware_download,
1398 .identify_state = bluebird_fx2_identify_state,
1399
1400 .size_of_priv = sizeof(struct cxusb_state),
1401
1402 .num_adapters = 1,
1403 .adapter = {
1404 {
1405 .streaming_ctrl = cxusb_streaming_ctrl,
1406 .frontend_attach = cxusb_nano2_frontend_attach,
1407 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1408 /* parameter for the MPEG2-data transfer */
1409 .stream = {
1410 .type = USB_BULK,
1411 .count = 5,
1412 .endpoint = 0x02,
1413 .u = {
1414 .bulk = {
1415 .buffersize = 8192,
1416 }
1417 }
1418 },
1419 },
1420 },
1421
1422 .power_ctrl = cxusb_nano2_power_ctrl,
1423
1424 .i2c_algo = &cxusb_i2c_algo,
1425
1426 .generic_bulk_ctrl_endpoint = 0x01,
1427
1428 .rc_interval = 100,
1429 .rc_key_map = dvico_portable_rc_keys,
1430 .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys),
1431 .rc_query = cxusb_rc_query,
1432
1433 .num_device_descs = 1,
1434 .devices = {
1435 { "DViCO FusionHDTV DVB-T NANO2 w/o firmware",
1436 { &cxusb_table[14], NULL },
1437 { &cxusb_table[15], NULL },
1438 },
1439 }
1440};
1441
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03001442static struct dvb_usb_device_properties cxusb_aver_a868r_properties = {
1443 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1444
1445 .usb_ctrl = CYPRESS_FX2,
1446
1447 .size_of_priv = sizeof(struct cxusb_state),
1448
1449 .num_adapters = 1,
1450 .adapter = {
1451 {
1452 .streaming_ctrl = cxusb_aver_streaming_ctrl,
1453 .frontend_attach = cxusb_aver_lgdt3303_frontend_attach,
1454 .tuner_attach = cxusb_mxl5003s_tuner_attach,
1455 /* parameter for the MPEG2-data transfer */
1456 .stream = {
1457 .type = USB_BULK,
1458 .count = 5,
1459 .endpoint = 0x04,
1460 .u = {
1461 .bulk = {
1462 .buffersize = 8192,
1463 }
1464 }
1465 },
1466
1467 },
1468 },
1469 .power_ctrl = cxusb_aver_power_ctrl,
1470
1471 .i2c_algo = &cxusb_i2c_algo,
1472
1473 .generic_bulk_ctrl_endpoint = 0x01,
1474
1475 .num_device_descs = 1,
1476 .devices = {
1477 { "AVerMedia AVerTVHD Volar (A868R)",
1478 { NULL },
1479 { &cxusb_table[16], NULL },
1480 },
1481 }
1482};
1483
Michael Krufkya2dc86b2008-08-09 13:06:26 -03001484static
1485struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = {
Anton Blanchard8d798982008-08-09 12:23:15 -03001486 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1487
1488 .usb_ctrl = CYPRESS_FX2,
1489
1490 .size_of_priv = sizeof(struct cxusb_state),
1491
1492 .num_adapters = 1,
1493 .adapter = {
1494 {
Michael Krufkya2dc86b2008-08-09 13:06:26 -03001495 .streaming_ctrl = cxusb_streaming_ctrl,
1496 .frontend_attach = cxusb_dualdig4_rev2_frontend_attach,
1497 .tuner_attach = cxusb_dualdig4_rev2_tuner_attach,
1498 .size_of_priv = sizeof(struct dib0700_adapter_state),
Anton Blanchard8d798982008-08-09 12:23:15 -03001499 /* parameter for the MPEG2-data transfer */
1500 .stream = {
1501 .type = USB_BULK,
1502 .count = 7,
1503 .endpoint = 0x02,
1504 .u = {
1505 .bulk = {
1506 .buffersize = 4096,
1507 }
1508 }
1509 },
1510 },
1511 },
1512
1513 .power_ctrl = cxusb_bluebird_power_ctrl,
1514
1515 .i2c_algo = &cxusb_i2c_algo,
1516
1517 .generic_bulk_ctrl_endpoint = 0x01,
1518
1519 .rc_interval = 100,
1520 .rc_key_map = dvico_mce_rc_keys,
1521 .rc_key_map_size = ARRAY_SIZE(dvico_mce_rc_keys),
1522 .rc_query = cxusb_rc_query,
1523
1524 .num_device_descs = 1,
1525 .devices = {
1526 { "DViCO FusionHDTV DVB-T Dual Digital 4 (rev 2)",
1527 { NULL },
1528 { &cxusb_table[17], NULL },
1529 },
1530 }
1531};
1532
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001533static struct usb_driver cxusb_driver = {
Patrick Boettcher63b5c1c2005-07-07 17:58:30 -07001534 .name = "dvb_usb_cxusb",
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001535 .probe = cxusb_probe,
Michael Krufkyf35db232006-12-05 14:53:39 -03001536 .disconnect = dvb_usb_device_exit,
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001537 .id_table = cxusb_table,
1538};
1539
1540/* module stuff */
1541static int __init cxusb_module_init(void)
1542{
1543 int result;
1544 if ((result = usb_register(&cxusb_driver))) {
1545 err("usb_register failed. Error number %d",result);
1546 return result;
1547 }
1548
1549 return 0;
1550}
1551
1552static void __exit cxusb_module_exit(void)
1553{
1554 /* deregister this driver from the USB subsystem */
1555 usb_deregister(&cxusb_driver);
1556}
1557
1558module_init (cxusb_module_init);
1559module_exit (cxusb_module_exit);
1560
1561MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
Michael Krufky5b9ed282006-10-15 14:51:08 -03001562MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
Michael Krufkyf4efb4d2006-01-13 14:10:25 -02001563MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001564MODULE_DESCRIPTION("Driver for Conexant USB2.0 hybrid reference design");
1565MODULE_VERSION("1.0-alpha");
1566MODULE_LICENSE("GPL");