blob: a1c641e18362ad288ebd1972c389831d2abb1db3 [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>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090028#include <linux/slab.h>
Michael Krufky827855d2008-04-22 14:46:16 -030029
Patrick Boettcher22c6d932005-07-07 17:58:10 -070030#include "cxusb.h"
31
32#include "cx22702.h"
Michael Krufkyeffee032006-01-09 15:25:47 -020033#include "lgdt330x.h"
Chris Pascoe0029ee12006-01-09 18:21:28 -020034#include "mt352.h"
35#include "mt352_priv.h"
Michael Krufkyc9ce3942006-06-11 04:24:31 -030036#include "zl10353.h"
Chris Pascoeaeb012b2007-11-19 21:57:10 -030037#include "tuner-xc2028.h"
Michael Krufky827855d2008-04-22 14:46:16 -030038#include "tuner-simple.h"
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -030039#include "mxl5005s.h"
David Wongb18bd1d2009-10-26 09:41:22 -030040#include "max2165.h"
Anton Blanchard8d798982008-08-09 12:23:15 -030041#include "dib7000p.h"
42#include "dib0070.h"
David T.L. Wong6bf1a992009-08-05 13:07:10 -030043#include "lgs8gxx.h"
David Wongb18bd1d2009-10-26 09:41:22 -030044#include "atbm8830.h"
Patrick Boettcher22c6d932005-07-07 17:58:10 -070045
Mauro Carvalho Chehab64f7ef82013-11-02 07:18:09 -030046/* Max transfer size done by I2C transfer functions */
47#define MAX_XFER_SIZE 64
48
Patrick Boettcher22c6d932005-07-07 17:58:10 -070049/* debug */
Adrian Bunk53133af2007-11-05 14:07:06 -030050static int dvb_usb_cxusb_debug;
Michael Krufkyf35db232006-12-05 14:53:39 -030051module_param_named(debug, dvb_usb_cxusb_debug, int, 0644);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070052MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
Janne Grunau78e92002008-04-09 19:13:13 -030053
54DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
55
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -030056#define deb_info(args...) dprintk(dvb_usb_cxusb_debug, 0x03, args)
57#define deb_i2c(args...) dprintk(dvb_usb_cxusb_debug, 0x02, args)
Patrick Boettcher22c6d932005-07-07 17:58:10 -070058
59static int cxusb_ctrl_msg(struct dvb_usb_device *d,
Michael Krufkyf35db232006-12-05 14:53:39 -030060 u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
Patrick Boettcher22c6d932005-07-07 17:58:10 -070061{
62 int wo = (rbuf == NULL || rlen == 0); /* write-only */
Mauro Carvalho Chehab64f7ef82013-11-02 07:18:09 -030063 u8 sndbuf[MAX_XFER_SIZE];
64
65 if (1 + wlen > sizeof(sndbuf)) {
66 warn("i2c wr: len=%d is too big!\n",
67 wlen);
68 return -EOPNOTSUPP;
69 }
70
Michael Krufkyf35db232006-12-05 14:53:39 -030071 memset(sndbuf, 0, 1+wlen);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070072
73 sndbuf[0] = cmd;
Michael Krufkyf35db232006-12-05 14:53:39 -030074 memcpy(&sndbuf[1], wbuf, wlen);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070075 if (wo)
Chris Pascoeb17f1092007-11-19 02:42:44 -030076 return dvb_usb_generic_write(d, sndbuf, 1+wlen);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070077 else
Chris Pascoeb17f1092007-11-19 02:42:44 -030078 return dvb_usb_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen, 0);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070079}
80
Patrick Boettchere2efeab2005-09-09 13:02:51 -070081/* GPIO */
82static void cxusb_gpio_tuner(struct dvb_usb_device *d, int onoff)
Patrick Boettcher22c6d932005-07-07 17:58:10 -070083{
84 struct cxusb_state *st = d->priv;
Michael Krufkyf35db232006-12-05 14:53:39 -030085 u8 o[2], i;
Patrick Boettcher22c6d932005-07-07 17:58:10 -070086
Patrick Boettchere2efeab2005-09-09 13:02:51 -070087 if (st->gpio_write_state[GPIO_TUNER] == onoff)
Patrick Boettcher22c6d932005-07-07 17:58:10 -070088 return;
89
Patrick Boettchere2efeab2005-09-09 13:02:51 -070090 o[0] = GPIO_TUNER;
91 o[1] = onoff;
Michael Krufkyf35db232006-12-05 14:53:39 -030092 cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070093
94 if (i != 0x01)
Patrick Boettchere2efeab2005-09-09 13:02:51 -070095 deb_info("gpio_write failed.\n");
Patrick Boettcher22c6d932005-07-07 17:58:10 -070096
Patrick Boettchere2efeab2005-09-09 13:02:51 -070097 st->gpio_write_state[GPIO_TUNER] = onoff;
Patrick Boettcher22c6d932005-07-07 17:58:10 -070098}
99
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300100static int cxusb_bluebird_gpio_rw(struct dvb_usb_device *d, u8 changemask,
101 u8 newval)
102{
103 u8 o[2], gpio_state;
104 int rc;
105
106 o[0] = 0xff & ~changemask; /* mask of bits to keep */
107 o[1] = newval & changemask; /* new values for bits */
108
109 rc = cxusb_ctrl_msg(d, CMD_BLUEBIRD_GPIO_RW, o, 2, &gpio_state, 1);
110 if (rc < 0 || (gpio_state & changemask) != (newval & changemask))
111 deb_info("bluebird_gpio_write failed.\n");
112
113 return rc < 0 ? rc : gpio_state;
114}
115
116static void cxusb_bluebird_gpio_pulse(struct dvb_usb_device *d, u8 pin, int low)
117{
118 cxusb_bluebird_gpio_rw(d, pin, low ? 0 : pin);
119 msleep(5);
120 cxusb_bluebird_gpio_rw(d, pin, low ? pin : 0);
121}
122
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300123static void cxusb_nano2_led(struct dvb_usb_device *d, int onoff)
124{
125 cxusb_bluebird_gpio_rw(d, 0x40, onoff ? 0 : 0x40);
126}
127
Timothy Leedfbdce02008-08-09 13:36:51 -0300128static int cxusb_d680_dmb_gpio_tuner(struct dvb_usb_device *d,
129 u8 addr, int onoff)
130{
131 u8 o[2] = {addr, onoff};
132 u8 i;
133 int rc;
134
135 rc = cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
136
137 if (rc < 0)
138 return rc;
139 if (i == 0x01)
140 return 0;
141 else {
142 deb_info("gpio_write failed.\n");
143 return -EIO;
144 }
145}
146
Patrick Boettchere2efeab2005-09-09 13:02:51 -0700147/* I2C */
Michael Krufkyf35db232006-12-05 14:53:39 -0300148static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
149 int num)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700150{
151 struct dvb_usb_device *d = i2c_get_adapdata(adap);
Dan Carpenter1cdbcc52013-11-22 04:55:43 -0300152 int ret;
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700153 int i;
154
Ingo Molnar3593cab2006-02-07 06:49:14 -0200155 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700156 return -EAGAIN;
157
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700158 for (i = 0; i < num; i++) {
159
Michael Krufky5e805ef2006-03-23 00:01:34 -0300160 if (d->udev->descriptor.idVendor == USB_VID_MEDION)
161 switch (msg[i].addr) {
Michael Krufkyf35db232006-12-05 14:53:39 -0300162 case 0x63:
163 cxusb_gpio_tuner(d, 0);
164 break;
165 default:
166 cxusb_gpio_tuner(d, 1);
167 break;
Michael Krufky5e805ef2006-03-23 00:01:34 -0300168 }
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700169
Chris Pascoe272479d72007-11-19 03:01:22 -0300170 if (msg[i].flags & I2C_M_RD) {
171 /* read only */
Mauro Carvalho Chehab64f7ef82013-11-02 07:18:09 -0300172 u8 obuf[3], ibuf[MAX_XFER_SIZE];
173
174 if (1 + msg[i].len > sizeof(ibuf)) {
175 warn("i2c rd: len=%d is too big!\n",
176 msg[i].len);
Dan Carpenter1cdbcc52013-11-22 04:55:43 -0300177 ret = -EOPNOTSUPP;
178 goto unlock;
Mauro Carvalho Chehab64f7ef82013-11-02 07:18:09 -0300179 }
Chris Pascoe272479d72007-11-19 03:01:22 -0300180 obuf[0] = 0;
181 obuf[1] = msg[i].len;
182 obuf[2] = msg[i].addr;
183 if (cxusb_ctrl_msg(d, CMD_I2C_READ,
184 obuf, 3,
185 ibuf, 1+msg[i].len) < 0) {
186 warn("i2c read failed");
187 break;
188 }
189 memcpy(msg[i].buf, &ibuf[1], msg[i].len);
Chris Pascoea644e4a2007-11-19 03:05:09 -0300190 } else if (i+1 < num && (msg[i+1].flags & I2C_M_RD) &&
191 msg[i].addr == msg[i+1].addr) {
192 /* write to then read from same address */
Mauro Carvalho Chehab64f7ef82013-11-02 07:18:09 -0300193 u8 obuf[MAX_XFER_SIZE], ibuf[MAX_XFER_SIZE];
194
195 if (3 + msg[i].len > sizeof(obuf)) {
196 warn("i2c wr: len=%d is too big!\n",
197 msg[i].len);
Dan Carpenter1cdbcc52013-11-22 04:55:43 -0300198 ret = -EOPNOTSUPP;
199 goto unlock;
Mauro Carvalho Chehab64f7ef82013-11-02 07:18:09 -0300200 }
201 if (1 + msg[i + 1].len > sizeof(ibuf)) {
202 warn("i2c rd: len=%d is too big!\n",
203 msg[i + 1].len);
Dan Carpenter1cdbcc52013-11-22 04:55:43 -0300204 ret = -EOPNOTSUPP;
205 goto unlock;
Mauro Carvalho Chehab64f7ef82013-11-02 07:18:09 -0300206 }
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700207 obuf[0] = msg[i].len;
208 obuf[1] = msg[i+1].len;
209 obuf[2] = msg[i].addr;
Michael Krufkyf35db232006-12-05 14:53:39 -0300210 memcpy(&obuf[3], msg[i].buf, msg[i].len);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700211
212 if (cxusb_ctrl_msg(d, CMD_I2C_READ,
Michael Krufkyf35db232006-12-05 14:53:39 -0300213 obuf, 3+msg[i].len,
214 ibuf, 1+msg[i+1].len) < 0)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700215 break;
216
217 if (ibuf[0] != 0x08)
Michael Krufkyae62e3d2006-03-23 01:11:18 -0300218 deb_i2c("i2c read may have failed\n");
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700219
Michael Krufkyf35db232006-12-05 14:53:39 -0300220 memcpy(msg[i+1].buf, &ibuf[1], msg[i+1].len);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700221
222 i++;
Chris Pascoe272479d72007-11-19 03:01:22 -0300223 } else {
224 /* write only */
Mauro Carvalho Chehab64f7ef82013-11-02 07:18:09 -0300225 u8 obuf[MAX_XFER_SIZE], ibuf;
226
227 if (2 + msg[i].len > sizeof(obuf)) {
228 warn("i2c wr: len=%d is too big!\n",
229 msg[i].len);
Dan Carpenter1cdbcc52013-11-22 04:55:43 -0300230 ret = -EOPNOTSUPP;
231 goto unlock;
Mauro Carvalho Chehab64f7ef82013-11-02 07:18:09 -0300232 }
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700233 obuf[0] = msg[i].addr;
234 obuf[1] = msg[i].len;
Michael Krufkyf35db232006-12-05 14:53:39 -0300235 memcpy(&obuf[2], msg[i].buf, msg[i].len);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700236
Michael Krufkyf35db232006-12-05 14:53:39 -0300237 if (cxusb_ctrl_msg(d, CMD_I2C_WRITE, obuf,
238 2+msg[i].len, &ibuf,1) < 0)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700239 break;
240 if (ibuf != 0x08)
Michael Krufkyae62e3d2006-03-23 01:11:18 -0300241 deb_i2c("i2c write may have failed\n");
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700242 }
243 }
244
Dan Carpenter1cdbcc52013-11-22 04:55:43 -0300245 if (i == num)
246 ret = num;
247 else
248 ret = -EREMOTEIO;
249
250unlock:
Ingo Molnar3593cab2006-02-07 06:49:14 -0200251 mutex_unlock(&d->i2c_mutex);
Dan Carpenter1cdbcc52013-11-22 04:55:43 -0300252 return ret;
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700253}
254
255static u32 cxusb_i2c_func(struct i2c_adapter *adapter)
256{
257 return I2C_FUNC_I2C;
258}
259
260static struct i2c_algorithm cxusb_i2c_algo = {
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700261 .master_xfer = cxusb_i2c_xfer,
262 .functionality = cxusb_i2c_func,
263};
264
265static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff)
266{
Patrick Boettchere2efeab2005-09-09 13:02:51 -0700267 u8 b = 0;
268 if (onoff)
269 return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
270 else
271 return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700272}
273
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300274static int cxusb_aver_power_ctrl(struct dvb_usb_device *d, int onoff)
275{
276 int ret;
277 if (!onoff)
278 return cxusb_ctrl_msg(d, CMD_POWER_OFF, NULL, 0, NULL, 0);
279 if (d->state == DVB_USB_STATE_INIT &&
280 usb_set_interface(d->udev, 0, 0) < 0)
281 err("set interface failed");
Hans Verkuilc6eb8ea2008-09-03 17:11:54 -0300282 do {} while (!(ret = cxusb_ctrl_msg(d, CMD_POWER_ON, NULL, 0, NULL, 0)) &&
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300283 !(ret = cxusb_ctrl_msg(d, 0x15, NULL, 0, NULL, 0)) &&
284 !(ret = cxusb_ctrl_msg(d, 0x17, NULL, 0, NULL, 0)) && 0);
285 if (!ret) {
286 /* FIXME: We don't know why, but we need to configure the
287 * lgdt3303 with the register settings below on resume */
288 int i;
289 u8 buf, bufs[] = {
290 0x0e, 0x2, 0x00, 0x7f,
291 0x0e, 0x2, 0x02, 0xfe,
292 0x0e, 0x2, 0x02, 0x01,
293 0x0e, 0x2, 0x00, 0x03,
294 0x0e, 0x2, 0x0d, 0x40,
295 0x0e, 0x2, 0x0e, 0x87,
296 0x0e, 0x2, 0x0f, 0x8e,
297 0x0e, 0x2, 0x10, 0x01,
298 0x0e, 0x2, 0x14, 0xd7,
299 0x0e, 0x2, 0x47, 0x88,
300 };
301 msleep(20);
302 for (i = 0; i < sizeof(bufs)/sizeof(u8); i += 4/sizeof(u8)) {
303 ret = cxusb_ctrl_msg(d, CMD_I2C_WRITE,
304 bufs+i, 4, &buf, 1);
305 if (ret)
306 break;
307 if (buf != 0x8)
308 return -EREMOTEIO;
309 }
310 }
311 return ret;
312}
313
Michael Krufky5691c842006-04-19 20:40:01 -0300314static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff)
315{
316 u8 b = 0;
317 if (onoff)
318 return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
319 else
320 return 0;
321}
322
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300323static int cxusb_nano2_power_ctrl(struct dvb_usb_device *d, int onoff)
324{
325 int rc = 0;
326
327 rc = cxusb_power_ctrl(d, onoff);
328 if (!onoff)
329 cxusb_nano2_led(d, 0);
330
331 return rc;
332}
333
Timothy Leedfbdce02008-08-09 13:36:51 -0300334static int cxusb_d680_dmb_power_ctrl(struct dvb_usb_device *d, int onoff)
335{
336 int ret;
337 u8 b;
338 ret = cxusb_power_ctrl(d, onoff);
339 if (!onoff)
340 return ret;
341
342 msleep(128);
343 cxusb_ctrl_msg(d, CMD_DIGITAL, NULL, 0, &b, 1);
344 msleep(100);
345 return ret;
346}
347
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300348static int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700349{
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700350 u8 buf[2] = { 0x03, 0x00 };
351 if (onoff)
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300352 cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON, buf, 2, NULL, 0);
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700353 else
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300354 cxusb_ctrl_msg(adap->dev, CMD_STREAMING_OFF, NULL, 0, NULL, 0);
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700355
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700356 return 0;
357}
358
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300359static int cxusb_aver_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
360{
361 if (onoff)
362 cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_ON, NULL, 0, NULL, 0);
363 else
364 cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_OFF,
365 NULL, 0, NULL, 0);
366 return 0;
367}
368
Timothy Leedfbdce02008-08-09 13:36:51 -0300369static void cxusb_d680_dmb_drain_message(struct dvb_usb_device *d)
370{
371 int ep = d->props.generic_bulk_ctrl_endpoint;
372 const int timeout = 100;
373 const int junk_len = 32;
374 u8 *junk;
375 int rd_count;
376
377 /* Discard remaining data in video pipe */
378 junk = kmalloc(junk_len, GFP_KERNEL);
379 if (!junk)
380 return;
381 while (1) {
382 if (usb_bulk_msg(d->udev,
383 usb_rcvbulkpipe(d->udev, ep),
384 junk, junk_len, &rd_count, timeout) < 0)
385 break;
386 if (!rd_count)
387 break;
388 }
389 kfree(junk);
390}
391
392static void cxusb_d680_dmb_drain_video(struct dvb_usb_device *d)
393{
Michael Krufky77eed212011-09-06 09:31:57 -0300394 struct usb_data_stream_properties *p = &d->props.adapter[0].fe[0].stream;
Timothy Leedfbdce02008-08-09 13:36:51 -0300395 const int timeout = 100;
396 const int junk_len = p->u.bulk.buffersize;
397 u8 *junk;
398 int rd_count;
399
400 /* Discard remaining data in video pipe */
401 junk = kmalloc(junk_len, GFP_KERNEL);
402 if (!junk)
403 return;
404 while (1) {
405 if (usb_bulk_msg(d->udev,
406 usb_rcvbulkpipe(d->udev, p->endpoint),
407 junk, junk_len, &rd_count, timeout) < 0)
408 break;
409 if (!rd_count)
410 break;
411 }
412 kfree(junk);
413}
414
415static int cxusb_d680_dmb_streaming_ctrl(
416 struct dvb_usb_adapter *adap, int onoff)
417{
418 if (onoff) {
419 u8 buf[2] = { 0x03, 0x00 };
420 cxusb_d680_dmb_drain_video(adap->dev);
421 return cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON,
422 buf, sizeof(buf), NULL, 0);
423 } else {
424 int ret = cxusb_ctrl_msg(adap->dev,
425 CMD_STREAMING_OFF, NULL, 0, NULL, 0);
426 return ret;
427 }
428}
429
Chris Pascoe7c239702006-01-09 18:21:29 -0200430static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
431{
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300432 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
Michael Krufkya07e6092006-01-09 18:21:31 -0200433 u8 ircode[4];
Chris Pascoe7c239702006-01-09 18:21:29 -0200434 int i;
435
Michael Krufkya07e6092006-01-09 18:21:31 -0200436 cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4);
Chris Pascoe7c239702006-01-09 18:21:29 -0200437
438 *event = 0;
439 *state = REMOTE_NO_KEY_PRESSED;
440
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300441 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
Mauro Carvalho Chehab2e365882009-08-29 15:19:31 -0300442 if (rc5_custom(&keymap[i]) == ircode[2] &&
443 rc5_data(&keymap[i]) == ircode[3]) {
Mauro Carvalho Chehab34abf212010-07-31 11:24:57 -0300444 *event = keymap[i].keycode;
Chris Pascoe7c239702006-01-09 18:21:29 -0200445 *state = REMOTE_KEY_PRESSED;
446
447 return 0;
448 }
449 }
450
451 return 0;
452}
453
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300454static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event,
455 int *state)
456{
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300457 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300458 u8 ircode[4];
459 int i;
460 struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
461 .buf = ircode, .len = 4 };
462
463 *event = 0;
464 *state = REMOTE_NO_KEY_PRESSED;
465
466 if (cxusb_i2c_xfer(&d->i2c_adap, &msg, 1) != 1)
467 return 0;
468
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300469 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
Mauro Carvalho Chehab2e365882009-08-29 15:19:31 -0300470 if (rc5_custom(&keymap[i]) == ircode[1] &&
471 rc5_data(&keymap[i]) == ircode[2]) {
Mauro Carvalho Chehab34abf212010-07-31 11:24:57 -0300472 *event = keymap[i].keycode;
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300473 *state = REMOTE_KEY_PRESSED;
474
475 return 0;
476 }
477 }
478
479 return 0;
480}
481
Timothy Leedfbdce02008-08-09 13:36:51 -0300482static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
483 int *state)
484{
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300485 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
Timothy Leedfbdce02008-08-09 13:36:51 -0300486 u8 ircode[2];
487 int i;
488
489 *event = 0;
490 *state = REMOTE_NO_KEY_PRESSED;
491
492 if (cxusb_ctrl_msg(d, 0x10, NULL, 0, ircode, 2) < 0)
493 return 0;
494
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300495 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
Mauro Carvalho Chehab2e365882009-08-29 15:19:31 -0300496 if (rc5_custom(&keymap[i]) == ircode[0] &&
497 rc5_data(&keymap[i]) == ircode[1]) {
Mauro Carvalho Chehab34abf212010-07-31 11:24:57 -0300498 *event = keymap[i].keycode;
Timothy Leedfbdce02008-08-09 13:36:51 -0300499 *state = REMOTE_KEY_PRESSED;
500
501 return 0;
502 }
503 }
504
505 return 0;
506}
507
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300508static struct rc_map_table rc_map_dvico_mce_table[] = {
Mauro Carvalho Chehab2e365882009-08-29 15:19:31 -0300509 { 0xfe02, KEY_TV },
510 { 0xfe0e, KEY_MP3 },
511 { 0xfe1a, KEY_DVD },
512 { 0xfe1e, KEY_FAVORITES },
513 { 0xfe16, KEY_SETUP },
514 { 0xfe46, KEY_POWER2 },
515 { 0xfe0a, KEY_EPG },
516 { 0xfe49, KEY_BACK },
517 { 0xfe4d, KEY_MENU },
518 { 0xfe51, KEY_UP },
519 { 0xfe5b, KEY_LEFT },
520 { 0xfe5f, KEY_RIGHT },
521 { 0xfe53, KEY_DOWN },
522 { 0xfe5e, KEY_OK },
523 { 0xfe59, KEY_INFO },
524 { 0xfe55, KEY_TAB },
525 { 0xfe0f, KEY_PREVIOUSSONG },/* Replay */
526 { 0xfe12, KEY_NEXTSONG }, /* Skip */
527 { 0xfe42, KEY_ENTER }, /* Windows/Start */
528 { 0xfe15, KEY_VOLUMEUP },
529 { 0xfe05, KEY_VOLUMEDOWN },
530 { 0xfe11, KEY_CHANNELUP },
531 { 0xfe09, KEY_CHANNELDOWN },
532 { 0xfe52, KEY_CAMERA },
533 { 0xfe5a, KEY_TUNER }, /* Live */
534 { 0xfe19, KEY_OPEN },
535 { 0xfe0b, KEY_1 },
536 { 0xfe17, KEY_2 },
537 { 0xfe1b, KEY_3 },
538 { 0xfe07, KEY_4 },
539 { 0xfe50, KEY_5 },
540 { 0xfe54, KEY_6 },
541 { 0xfe48, KEY_7 },
542 { 0xfe4c, KEY_8 },
543 { 0xfe58, KEY_9 },
544 { 0xfe13, KEY_ANGLE }, /* Aspect */
545 { 0xfe03, KEY_0 },
546 { 0xfe1f, KEY_ZOOM },
547 { 0xfe43, KEY_REWIND },
548 { 0xfe47, KEY_PLAYPAUSE },
549 { 0xfe4f, KEY_FASTFORWARD },
550 { 0xfe57, KEY_MUTE },
551 { 0xfe0d, KEY_STOP },
552 { 0xfe01, KEY_RECORD },
553 { 0xfe4e, KEY_POWER },
Michael Krufkya07e6092006-01-09 18:21:31 -0200554};
555
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300556static struct rc_map_table rc_map_dvico_portable_table[] = {
Mauro Carvalho Chehab2e365882009-08-29 15:19:31 -0300557 { 0xfc02, KEY_SETUP }, /* Profile */
558 { 0xfc43, KEY_POWER2 },
559 { 0xfc06, KEY_EPG },
560 { 0xfc5a, KEY_BACK },
561 { 0xfc05, KEY_MENU },
562 { 0xfc47, KEY_INFO },
563 { 0xfc01, KEY_TAB },
564 { 0xfc42, KEY_PREVIOUSSONG },/* Replay */
565 { 0xfc49, KEY_VOLUMEUP },
566 { 0xfc09, KEY_VOLUMEDOWN },
567 { 0xfc54, KEY_CHANNELUP },
568 { 0xfc0b, KEY_CHANNELDOWN },
569 { 0xfc16, KEY_CAMERA },
570 { 0xfc40, KEY_TUNER }, /* ATV/DTV */
571 { 0xfc45, KEY_OPEN },
572 { 0xfc19, KEY_1 },
573 { 0xfc18, KEY_2 },
574 { 0xfc1b, KEY_3 },
575 { 0xfc1a, KEY_4 },
576 { 0xfc58, KEY_5 },
577 { 0xfc59, KEY_6 },
578 { 0xfc15, KEY_7 },
579 { 0xfc14, KEY_8 },
580 { 0xfc17, KEY_9 },
581 { 0xfc44, KEY_ANGLE }, /* Aspect */
582 { 0xfc55, KEY_0 },
583 { 0xfc07, KEY_ZOOM },
584 { 0xfc0a, KEY_REWIND },
585 { 0xfc08, KEY_PLAYPAUSE },
586 { 0xfc4b, KEY_FASTFORWARD },
587 { 0xfc5b, KEY_MUTE },
588 { 0xfc04, KEY_STOP },
589 { 0xfc56, KEY_RECORD },
590 { 0xfc57, KEY_POWER },
591 { 0xfc41, KEY_UNKNOWN }, /* INPUT */
592 { 0xfc00, KEY_UNKNOWN }, /* HD */
Michael Krufkyc1501782006-03-26 05:43:36 -0300593};
594
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300595static struct rc_map_table rc_map_d680_dmb_table[] = {
Mauro Carvalho Chehab2e365882009-08-29 15:19:31 -0300596 { 0x0038, KEY_UNKNOWN }, /* TV/AV */
597 { 0x080c, KEY_ZOOM },
598 { 0x0800, KEY_0 },
599 { 0x0001, KEY_1 },
600 { 0x0802, KEY_2 },
601 { 0x0003, KEY_3 },
602 { 0x0804, KEY_4 },
603 { 0x0005, KEY_5 },
604 { 0x0806, KEY_6 },
605 { 0x0007, KEY_7 },
606 { 0x0808, KEY_8 },
607 { 0x0009, KEY_9 },
608 { 0x000a, KEY_MUTE },
609 { 0x0829, KEY_BACK },
610 { 0x0012, KEY_CHANNELUP },
611 { 0x0813, KEY_CHANNELDOWN },
612 { 0x002b, KEY_VOLUMEUP },
613 { 0x082c, KEY_VOLUMEDOWN },
614 { 0x0020, KEY_UP },
615 { 0x0821, KEY_DOWN },
616 { 0x0011, KEY_LEFT },
617 { 0x0810, KEY_RIGHT },
618 { 0x000d, KEY_OK },
619 { 0x081f, KEY_RECORD },
620 { 0x0017, KEY_PLAYPAUSE },
621 { 0x0816, KEY_PLAYPAUSE },
622 { 0x000b, KEY_STOP },
623 { 0x0827, KEY_FASTFORWARD },
624 { 0x0026, KEY_REWIND },
625 { 0x081e, KEY_UNKNOWN }, /* Time Shift */
626 { 0x000e, KEY_UNKNOWN }, /* Snapshot */
627 { 0x082d, KEY_UNKNOWN }, /* Mouse Cursor */
628 { 0x000f, KEY_UNKNOWN }, /* Minimize/Maximize */
629 { 0x0814, KEY_UNKNOWN }, /* Shuffle */
630 { 0x0025, KEY_POWER },
Timothy Leedfbdce02008-08-09 13:36:51 -0300631};
632
Chris Pascoe0029ee12006-01-09 18:21:28 -0200633static int cxusb_dee1601_demod_init(struct dvb_frontend* fe)
634{
Chris Pascoed9ed8812006-02-07 06:49:11 -0200635 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 };
Chris Pascoe0029ee12006-01-09 18:21:28 -0200636 static u8 reset [] = { RESET, 0x80 };
637 static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
638 static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 };
639 static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
640 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
641
642 mt352_write(fe, clock_config, sizeof(clock_config));
643 udelay(200);
644 mt352_write(fe, reset, sizeof(reset));
645 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
646
647 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
648 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
649 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
650
651 return 0;
652}
653
Michael Krufky6f447252006-01-11 19:40:33 -0200654static int cxusb_mt352_demod_init(struct dvb_frontend* fe)
655{ /* used in both lgz201 and th7579 */
Michael Krufkyfb51fd22006-02-07 06:49:12 -0200656 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x29 };
Michael Krufky6f447252006-01-11 19:40:33 -0200657 static u8 reset [] = { RESET, 0x80 };
658 static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
659 static u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 };
660 static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
661 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
662
663 mt352_write(fe, clock_config, sizeof(clock_config));
664 udelay(200);
665 mt352_write(fe, reset, sizeof(reset));
666 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
667
668 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
669 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
670 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
671 return 0;
672}
673
Adrian Bunk703cb2c2006-01-23 17:11:09 -0200674static struct cx22702_config cxusb_cx22702_config = {
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700675 .demod_address = 0x63,
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700676 .output_mode = CX22702_PARALLEL_OUTPUT,
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700677};
678
Michael Krufkyfddd6322006-02-27 00:08:17 -0300679static struct lgdt330x_config cxusb_lgdt3303_config = {
Michael Krufkyeffee032006-01-09 15:25:47 -0200680 .demod_address = 0x0e,
681 .demod_chip = LGDT3303,
Michael Krufkyeffee032006-01-09 15:25:47 -0200682};
683
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300684static struct lgdt330x_config cxusb_aver_lgdt3303_config = {
685 .demod_address = 0x0e,
686 .demod_chip = LGDT3303,
687 .clock_polarity_flip = 2,
688};
689
Adrian Bunk703cb2c2006-01-23 17:11:09 -0200690static struct mt352_config cxusb_dee1601_config = {
Chris Pascoe0029ee12006-01-09 18:21:28 -0200691 .demod_address = 0x0f,
692 .demod_init = cxusb_dee1601_demod_init,
Chris Pascoe0029ee12006-01-09 18:21:28 -0200693};
694
Michael Krufkyc9ce3942006-06-11 04:24:31 -0300695static struct zl10353_config cxusb_zl10353_dee1601_config = {
696 .demod_address = 0x0f,
Chris Pascoe8fb95782006-08-10 03:17:16 -0300697 .parallel_ts = 1,
Michael Krufkyc9ce3942006-06-11 04:24:31 -0300698};
699
Adrian Bunk6fe00b02006-04-19 20:49:28 -0300700static struct mt352_config cxusb_mt352_config = {
Michael Krufky6f447252006-01-11 19:40:33 -0200701 /* used in both lgz201 and th7579 */
702 .demod_address = 0x0f,
703 .demod_init = cxusb_mt352_demod_init,
Michael Krufky6f447252006-01-11 19:40:33 -0200704};
705
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300706static struct zl10353_config cxusb_zl10353_xc3028_config = {
707 .demod_address = 0x0f,
Chris Pascoea1dcd9d2007-11-20 08:17:54 -0300708 .if2 = 45600,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300709 .no_tuner = 1,
710 .parallel_ts = 1,
711};
712
Robert Lowery0bc35182009-11-08 00:00:11 -0300713static struct zl10353_config cxusb_zl10353_xc3028_config_no_i2c_gate = {
714 .demod_address = 0x0f,
715 .if2 = 45600,
716 .no_tuner = 1,
717 .parallel_ts = 1,
718 .disable_i2c_gate_ctrl = 1,
719};
720
Chris Pascoe702a6762007-11-20 03:34:11 -0300721static struct mt352_config cxusb_mt352_xc3028_config = {
722 .demod_address = 0x0f,
723 .if2 = 4560,
724 .no_tuner = 1,
725 .demod_init = cxusb_mt352_demod_init,
726};
727
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300728/* FIXME: needs tweaking */
729static struct mxl5005s_config aver_a868r_tuner = {
730 .i2c_address = 0x63,
731 .if_freq = 6000000UL,
732 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
733 .agc_mode = MXL_SINGLE_AGC,
734 .tracking_filter = MXL_TF_C,
735 .rssi_enable = MXL_RSSI_ENABLE,
736 .cap_select = MXL_CAP_SEL_ENABLE,
737 .div_out = MXL_DIV_OUT_4,
738 .clock_out = MXL_CLOCK_OUT_DISABLE,
739 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
740 .top = MXL5005S_TOP_25P2,
741 .mod_mode = MXL_DIGITAL_MODE,
742 .if_mode = MXL_ZERO_IF,
743 .AgcMasterByte = 0x00,
744};
745
Timothy Leedfbdce02008-08-09 13:36:51 -0300746/* FIXME: needs tweaking */
747static struct mxl5005s_config d680_dmb_tuner = {
748 .i2c_address = 0x63,
749 .if_freq = 36125000UL,
750 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
751 .agc_mode = MXL_SINGLE_AGC,
752 .tracking_filter = MXL_TF_C,
753 .rssi_enable = MXL_RSSI_ENABLE,
754 .cap_select = MXL_CAP_SEL_ENABLE,
755 .div_out = MXL_DIV_OUT_4,
756 .clock_out = MXL_CLOCK_OUT_DISABLE,
757 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
758 .top = MXL5005S_TOP_25P2,
759 .mod_mode = MXL_DIGITAL_MODE,
760 .if_mode = MXL_ZERO_IF,
761 .AgcMasterByte = 0x00,
762};
763
David Wongb18bd1d2009-10-26 09:41:22 -0300764static struct max2165_config mygica_d689_max2165_cfg = {
765 .i2c_address = 0x60,
766 .osc_clk = 20
767};
768
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700769/* Callbacks for DVB USB */
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300770static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700771{
Michael Krufky77eed212011-09-06 09:31:57 -0300772 dvb_attach(simple_tuner_attach, adap->fe_adap[0].fe,
Michael Krufkycb89cd32008-04-22 14:46:16 -0300773 &adap->dev->i2c_adap, 0x61,
774 TUNER_PHILIPS_FMD1216ME_MK3);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700775 return 0;
776}
777
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300778static int cxusb_dee1601_tuner_attach(struct dvb_usb_adapter *adap)
Chris Pascoe0029ee12006-01-09 18:21:28 -0200779{
Michael Krufky77eed212011-09-06 09:31:57 -0300780 dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61,
Michael Krufky47a99912007-06-12 16:10:51 -0300781 NULL, DVB_PLL_THOMSON_DTT7579);
Chris Pascoe0029ee12006-01-09 18:21:28 -0200782 return 0;
783}
784
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300785static int cxusb_lgz201_tuner_attach(struct dvb_usb_adapter *adap)
Michael Krufky6f447252006-01-11 19:40:33 -0200786{
Michael Krufky77eed212011-09-06 09:31:57 -0300787 dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61, NULL, DVB_PLL_LG_Z201);
Michael Krufky6f447252006-01-11 19:40:33 -0200788 return 0;
789}
790
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300791static int cxusb_dtt7579_tuner_attach(struct dvb_usb_adapter *adap)
Michael Krufky6f447252006-01-11 19:40:33 -0200792{
Michael Krufky77eed212011-09-06 09:31:57 -0300793 dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60,
Michael Krufky47a99912007-06-12 16:10:51 -0300794 NULL, DVB_PLL_THOMSON_DTT7579);
Patrick Boettcher332bed52006-05-14 04:49:00 -0300795 return 0;
796}
797
Michael Krufkyf71a56c2006-10-13 21:55:57 -0300798static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap)
Patrick Boettcher332bed52006-05-14 04:49:00 -0300799{
Michael Krufky77eed212011-09-06 09:31:57 -0300800 dvb_attach(simple_tuner_attach, adap->fe_adap[0].fe,
Michael Krufky827855d2008-04-22 14:46:16 -0300801 &adap->dev->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF);
Michael Krufky6f447252006-01-11 19:40:33 -0200802 return 0;
803}
804
Michael Krufkyd7cba042008-09-12 13:31:45 -0300805static int dvico_bluebird_xc2028_callback(void *ptr, int component,
806 int command, int arg)
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300807{
Robert Loweryd483b732008-07-30 19:43:11 -0300808 struct dvb_usb_adapter *adap = ptr;
809 struct dvb_usb_device *d = adap->dev;
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300810
811 switch (command) {
812 case XC2028_TUNER_RESET:
Harvey Harrison708bebd2008-04-08 23:20:00 -0300813 deb_info("%s: XC2028_TUNER_RESET %d\n", __func__, arg);
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300814 cxusb_bluebird_gpio_pulse(d, 0x01, 1);
815 break;
816 case XC2028_RESET_CLK:
Harvey Harrison708bebd2008-04-08 23:20:00 -0300817 deb_info("%s: XC2028_RESET_CLK %d\n", __func__, arg);
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300818 break;
819 default:
Harvey Harrison708bebd2008-04-08 23:20:00 -0300820 deb_info("%s: unknown command %d, arg %d\n", __func__,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300821 command, arg);
822 return -EINVAL;
823 }
824
825 return 0;
826}
827
828static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap)
829{
830 struct dvb_frontend *fe;
831 struct xc2028_config cfg = {
832 .i2c_adap = &adap->dev->i2c_adap,
833 .i2c_addr = 0x61,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300834 };
835 static struct xc2028_ctrl ctl = {
Michael Krufkyef80bfe2008-09-16 02:15:30 -0300836 .fname = XC2028_DEFAULT_FIRMWARE,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300837 .max_len = 64,
Robert Loweryd483b732008-07-30 19:43:11 -0300838 .demod = XC3028_FE_ZARLINK456,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300839 };
840
Michael Krufkyd7cba042008-09-12 13:31:45 -0300841 /* FIXME: generalize & move to common area */
Michael Krufky77eed212011-09-06 09:31:57 -0300842 adap->fe_adap[0].fe->callback = dvico_bluebird_xc2028_callback;
Michael Krufkyd7cba042008-09-12 13:31:45 -0300843
Michael Krufky77eed212011-09-06 09:31:57 -0300844 fe = dvb_attach(xc2028_attach, adap->fe_adap[0].fe, &cfg);
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300845 if (fe == NULL || fe->ops.tuner_ops.set_config == NULL)
846 return -EIO;
847
848 fe->ops.tuner_ops.set_config(fe, &ctl);
849
850 return 0;
851}
852
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300853static int cxusb_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
854{
Michael Krufky77eed212011-09-06 09:31:57 -0300855 dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe,
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300856 &adap->dev->i2c_adap, &aver_a868r_tuner);
857 return 0;
858}
859
Timothy Leedfbdce02008-08-09 13:36:51 -0300860static int cxusb_d680_dmb_tuner_attach(struct dvb_usb_adapter *adap)
861{
862 struct dvb_frontend *fe;
Michael Krufky77eed212011-09-06 09:31:57 -0300863 fe = dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe,
Timothy Leedfbdce02008-08-09 13:36:51 -0300864 &adap->dev->i2c_adap, &d680_dmb_tuner);
865 return (fe == NULL) ? -EIO : 0;
866}
867
David Wongb18bd1d2009-10-26 09:41:22 -0300868static int cxusb_mygica_d689_tuner_attach(struct dvb_usb_adapter *adap)
869{
870 struct dvb_frontend *fe;
Michael Krufky77eed212011-09-06 09:31:57 -0300871 fe = dvb_attach(max2165_attach, adap->fe_adap[0].fe,
David Wongb18bd1d2009-10-26 09:41:22 -0300872 &adap->dev->i2c_adap, &mygica_d689_max2165_cfg);
873 return (fe == NULL) ? -EIO : 0;
874}
875
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300876static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700877{
Patrick Boettchere2efeab2005-09-09 13:02:51 -0700878 u8 b;
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300879 if (usb_set_interface(adap->dev->udev, 0, 6) < 0)
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700880 err("set interface failed");
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700881
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300882 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, &b, 1);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700883
Michael Krufky310df362011-09-17 14:22:59 -0300884 adap->fe_adap[0].fe = dvb_attach(cx22702_attach, &cxusb_cx22702_config,
885 &adap->dev->i2c_adap);
886 if ((adap->fe_adap[0].fe) != NULL)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700887 return 0;
888
889 return -EIO;
890}
891
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300892static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
Michael Krufkyeffee032006-01-09 15:25:47 -0200893{
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300894 if (usb_set_interface(adap->dev->udev, 0, 7) < 0)
Michael Krufkyeffee032006-01-09 15:25:47 -0200895 err("set interface failed");
896
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300897 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
Michael Krufkyeffee032006-01-09 15:25:47 -0200898
Michael Krufky310df362011-09-17 14:22:59 -0300899 adap->fe_adap[0].fe = dvb_attach(lgdt330x_attach,
900 &cxusb_lgdt3303_config,
901 &adap->dev->i2c_adap);
902 if ((adap->fe_adap[0].fe) != NULL)
Michael Krufkyeffee032006-01-09 15:25:47 -0200903 return 0;
904
905 return -EIO;
906}
907
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300908static int cxusb_aver_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
909{
Michael Krufky77eed212011-09-06 09:31:57 -0300910 adap->fe_adap[0].fe = dvb_attach(lgdt330x_attach, &cxusb_aver_lgdt3303_config,
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300911 &adap->dev->i2c_adap);
Michael Krufky77eed212011-09-06 09:31:57 -0300912 if (adap->fe_adap[0].fe != NULL)
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300913 return 0;
914
915 return -EIO;
916}
917
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300918static int cxusb_mt352_frontend_attach(struct dvb_usb_adapter *adap)
Chris Pascoe0029ee12006-01-09 18:21:28 -0200919{
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300920 /* used in both lgz201 and th7579 */
921 if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
Chris Pascoe0029ee12006-01-09 18:21:28 -0200922 err("set interface failed");
923
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300924 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
Chris Pascoe0029ee12006-01-09 18:21:28 -0200925
Michael Krufky310df362011-09-17 14:22:59 -0300926 adap->fe_adap[0].fe = dvb_attach(mt352_attach, &cxusb_mt352_config,
927 &adap->dev->i2c_adap);
928 if ((adap->fe_adap[0].fe) != NULL)
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300929 return 0;
930
931 return -EIO;
932}
933
934static int cxusb_dee1601_frontend_attach(struct dvb_usb_adapter *adap)
935{
936 if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
937 err("set interface failed");
938
939 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
940
Michael Krufky310df362011-09-17 14:22:59 -0300941 adap->fe_adap[0].fe = dvb_attach(mt352_attach, &cxusb_dee1601_config,
942 &adap->dev->i2c_adap);
943 if ((adap->fe_adap[0].fe) != NULL)
944 return 0;
945
946 adap->fe_adap[0].fe = dvb_attach(zl10353_attach,
947 &cxusb_zl10353_dee1601_config,
948 &adap->dev->i2c_adap);
949 if ((adap->fe_adap[0].fe) != NULL)
Chris Pascoe0029ee12006-01-09 18:21:28 -0200950 return 0;
951
952 return -EIO;
953}
954
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300955static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap)
956{
957 u8 ircode[4];
958 int i;
959 struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
960 .buf = ircode, .len = 4 };
961
962 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
963 err("set interface failed");
964
965 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
966
967 /* reset the tuner and demodulator */
968 cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
969 cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
970 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
971
Michael Krufky310df362011-09-17 14:22:59 -0300972 adap->fe_adap[0].fe =
973 dvb_attach(zl10353_attach,
974 &cxusb_zl10353_xc3028_config_no_i2c_gate,
975 &adap->dev->i2c_adap);
976 if ((adap->fe_adap[0].fe) == NULL)
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300977 return -EIO;
978
979 /* try to determine if there is no IR decoder on the I2C bus */
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300980 for (i = 0; adap->dev->props.rc.legacy.rc_map_table != NULL && i < 5; i++) {
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300981 msleep(20);
982 if (cxusb_i2c_xfer(&adap->dev->i2c_adap, &msg, 1) != 1)
983 goto no_IR;
984 if (ircode[0] == 0 && ircode[1] == 0)
985 continue;
986 if (ircode[2] + ircode[3] != 0xff) {
987no_IR:
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300988 adap->dev->props.rc.legacy.rc_map_table = NULL;
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300989 info("No IR receiver detected on this device.");
990 break;
991 }
992 }
993
994 return 0;
995}
996
Anton Blanchard8d798982008-08-09 12:23:15 -0300997static struct dibx000_agc_config dib7070_agc_config = {
998 .band_caps = BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
999
1000 /*
1001 * P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5,
1002 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
1003 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0
1004 */
1005 .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) |
1006 (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
1007 .inv_gain = 600,
1008 .time_stabiliz = 10,
1009 .alpha_level = 0,
1010 .thlock = 118,
1011 .wbd_inv = 0,
1012 .wbd_ref = 3530,
1013 .wbd_sel = 1,
1014 .wbd_alpha = 5,
1015 .agc1_max = 65535,
1016 .agc1_min = 0,
1017 .agc2_max = 65535,
1018 .agc2_min = 0,
1019 .agc1_pt1 = 0,
1020 .agc1_pt2 = 40,
1021 .agc1_pt3 = 183,
1022 .agc1_slope1 = 206,
1023 .agc1_slope2 = 255,
1024 .agc2_pt1 = 72,
1025 .agc2_pt2 = 152,
1026 .agc2_slope1 = 88,
1027 .agc2_slope2 = 90,
1028 .alpha_mant = 17,
1029 .alpha_exp = 27,
1030 .beta_mant = 23,
1031 .beta_exp = 51,
1032 .perform_agc_softsplit = 0,
1033};
1034
1035static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
1036 .internal = 60000,
1037 .sampling = 15000,
1038 .pll_prediv = 1,
1039 .pll_ratio = 20,
1040 .pll_range = 3,
1041 .pll_reset = 1,
1042 .pll_bypass = 0,
1043 .enable_refdiv = 0,
1044 .bypclk_div = 0,
1045 .IO_CLK_en_core = 1,
1046 .ADClkSrc = 1,
1047 .modulo = 2,
1048 /* refsel, sel, freq_15k */
1049 .sad_cfg = (3 << 14) | (1 << 12) | (524 << 0),
1050 .ifreq = (0 << 25) | 0,
1051 .timf = 20452225,
1052 .xtal_hz = 12000000,
1053};
1054
1055static struct dib7000p_config cxusb_dualdig4_rev2_config = {
1056 .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK,
1057 .output_mpeg2_in_188_bytes = 1,
1058
1059 .agc_config_count = 1,
1060 .agc = &dib7070_agc_config,
1061 .bw = &dib7070_bw_config_12_mhz,
1062 .tuner_is_baseband = 1,
1063 .spur_protect = 1,
1064
1065 .gpio_dir = 0xfcef,
1066 .gpio_val = 0x0110,
1067
1068 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
1069
1070 .hostbus_diversity = 1,
1071};
1072
1073static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap)
1074{
1075 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
1076 err("set interface failed");
1077
1078 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
1079
1080 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
1081
Randy Dunlap30d81bb2010-02-08 20:30:44 -03001082 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
Prarit Bhargavaa49ba162010-05-12 19:30:02 -03001083 &cxusb_dualdig4_rev2_config) < 0) {
1084 printk(KERN_WARNING "Unable to enumerate dib7000p\n");
Randy Dunlap30d81bb2010-02-08 20:30:44 -03001085 return -ENODEV;
Prarit Bhargavaa49ba162010-05-12 19:30:02 -03001086 }
Anton Blanchard8d798982008-08-09 12:23:15 -03001087
Michael Krufky77eed212011-09-06 09:31:57 -03001088 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
Michael Krufkya2dc86b2008-08-09 13:06:26 -03001089 &cxusb_dualdig4_rev2_config);
Michael Krufky77eed212011-09-06 09:31:57 -03001090 if (adap->fe_adap[0].fe == NULL)
Anton Blanchard8d798982008-08-09 12:23:15 -03001091 return -EIO;
1092
1093 return 0;
1094}
1095
1096static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
1097{
1098 return dib7000p_set_gpio(fe, 8, 0, !onoff);
1099}
1100
1101static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
1102{
1103 return 0;
1104}
1105
1106static struct dib0070_config dib7070p_dib0070_config = {
1107 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1108 .reset = dib7070_tuner_reset,
1109 .sleep = dib7070_tuner_sleep,
1110 .clock_khz = 12000,
1111};
1112
1113struct dib0700_adapter_state {
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03001114 int (*set_param_save) (struct dvb_frontend *);
Anton Blanchard8d798982008-08-09 12:23:15 -03001115};
1116
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03001117static int dib7070_set_param_override(struct dvb_frontend *fe)
Anton Blanchard8d798982008-08-09 12:23:15 -03001118{
Mauro Carvalho Chehabafd2b382011-12-24 10:17:30 -03001119 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Anton Blanchard8d798982008-08-09 12:23:15 -03001120 struct dvb_usb_adapter *adap = fe->dvb->priv;
1121 struct dib0700_adapter_state *state = adap->priv;
1122
1123 u16 offset;
Mauro Carvalho Chehabafd2b382011-12-24 10:17:30 -03001124 u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
Anton Blanchard8d798982008-08-09 12:23:15 -03001125 switch (band) {
Michael Krufkya2dc86b2008-08-09 13:06:26 -03001126 case BAND_VHF: offset = 950; break;
1127 default:
1128 case BAND_UHF: offset = 550; break;
Anton Blanchard8d798982008-08-09 12:23:15 -03001129 }
1130
1131 dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
1132
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03001133 return state->set_param_save(fe);
Anton Blanchard8d798982008-08-09 12:23:15 -03001134}
1135
1136static int cxusb_dualdig4_rev2_tuner_attach(struct dvb_usb_adapter *adap)
1137{
1138 struct dib0700_adapter_state *st = adap->priv;
Michael Krufkya2dc86b2008-08-09 13:06:26 -03001139 struct i2c_adapter *tun_i2c =
Michael Krufky77eed212011-09-06 09:31:57 -03001140 dib7000p_get_i2c_master(adap->fe_adap[0].fe,
Michael Krufkya2dc86b2008-08-09 13:06:26 -03001141 DIBX000_I2C_INTERFACE_TUNER, 1);
Anton Blanchard8d798982008-08-09 12:23:15 -03001142
Michael Krufky77eed212011-09-06 09:31:57 -03001143 if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,
Anton Blanchard8d798982008-08-09 12:23:15 -03001144 &dib7070p_dib0070_config) == NULL)
1145 return -ENODEV;
1146
Michael Krufky77eed212011-09-06 09:31:57 -03001147 st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
1148 adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7070_set_param_override;
Anton Blanchard8d798982008-08-09 12:23:15 -03001149 return 0;
1150}
1151
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001152static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap)
1153{
1154 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
1155 err("set interface failed");
1156
1157 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
1158
1159 /* reset the tuner and demodulator */
1160 cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
1161 cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
1162 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
1163
Michael Krufky310df362011-09-17 14:22:59 -03001164 adap->fe_adap[0].fe = dvb_attach(zl10353_attach,
1165 &cxusb_zl10353_xc3028_config,
1166 &adap->dev->i2c_adap);
1167 if ((adap->fe_adap[0].fe) != NULL)
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001168 return 0;
1169
Michael Krufky310df362011-09-17 14:22:59 -03001170 adap->fe_adap[0].fe = dvb_attach(mt352_attach,
1171 &cxusb_mt352_xc3028_config,
1172 &adap->dev->i2c_adap);
1173 if ((adap->fe_adap[0].fe) != NULL)
Chris Pascoe702a6762007-11-20 03:34:11 -03001174 return 0;
1175
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001176 return -EIO;
1177}
1178
David T.L. Wong6bf1a992009-08-05 13:07:10 -03001179static struct lgs8gxx_config d680_lgs8gl5_cfg = {
1180 .prod = LGS8GXX_PROD_LGS8GL5,
Timothy Leedfbdce02008-08-09 13:36:51 -03001181 .demod_address = 0x19,
David T.L. Wong6bf1a992009-08-05 13:07:10 -03001182 .serial_ts = 0,
1183 .ts_clk_pol = 0,
1184 .ts_clk_gated = 1,
1185 .if_clk_freq = 30400, /* 30.4 MHz */
1186 .if_freq = 5725, /* 5.725 MHz */
1187 .if_neg_center = 0,
1188 .ext_adc = 0,
1189 .adc_signed = 0,
1190 .if_neg_edge = 0,
Timothy Leedfbdce02008-08-09 13:36:51 -03001191};
1192
1193static int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap)
1194{
1195 struct dvb_usb_device *d = adap->dev;
1196 int n;
1197
1198 /* Select required USB configuration */
1199 if (usb_set_interface(d->udev, 0, 0) < 0)
1200 err("set interface failed");
1201
1202 /* Unblock all USB pipes */
1203 usb_clear_halt(d->udev,
1204 usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1205 usb_clear_halt(d->udev,
1206 usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1207 usb_clear_halt(d->udev,
Michael Krufky77eed212011-09-06 09:31:57 -03001208 usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint));
Timothy Leedfbdce02008-08-09 13:36:51 -03001209
1210 /* Drain USB pipes to avoid hang after reboot */
1211 for (n = 0; n < 5; n++) {
1212 cxusb_d680_dmb_drain_message(d);
1213 cxusb_d680_dmb_drain_video(d);
1214 msleep(200);
1215 }
1216
1217 /* Reset the tuner */
1218 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) {
1219 err("clear tuner gpio failed");
1220 return -EIO;
1221 }
1222 msleep(100);
1223 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) {
1224 err("set tuner gpio failed");
1225 return -EIO;
1226 }
1227 msleep(100);
1228
1229 /* Attach frontend */
Michael Krufky77eed212011-09-06 09:31:57 -03001230 adap->fe_adap[0].fe = dvb_attach(lgs8gxx_attach, &d680_lgs8gl5_cfg, &d->i2c_adap);
1231 if (adap->fe_adap[0].fe == NULL)
Timothy Leedfbdce02008-08-09 13:36:51 -03001232 return -EIO;
1233
1234 return 0;
1235}
1236
David Wongb18bd1d2009-10-26 09:41:22 -03001237static struct atbm8830_config mygica_d689_atbm8830_cfg = {
1238 .prod = ATBM8830_PROD_8830,
1239 .demod_address = 0x40,
1240 .serial_ts = 0,
1241 .ts_sampling_edge = 1,
1242 .ts_clk_gated = 0,
1243 .osc_clk_freq = 30400, /* in kHz */
1244 .if_freq = 0, /* zero IF */
1245 .zif_swap_iq = 1,
David Wongc245c752009-11-28 08:36:31 -03001246 .agc_min = 0x2E,
1247 .agc_max = 0x90,
1248 .agc_hold_loop = 0,
David Wongb18bd1d2009-10-26 09:41:22 -03001249};
1250
1251static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap)
1252{
1253 struct dvb_usb_device *d = adap->dev;
David Wongb18bd1d2009-10-26 09:41:22 -03001254
1255 /* Select required USB configuration */
1256 if (usb_set_interface(d->udev, 0, 0) < 0)
1257 err("set interface failed");
1258
1259 /* Unblock all USB pipes */
1260 usb_clear_halt(d->udev,
1261 usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1262 usb_clear_halt(d->udev,
1263 usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1264 usb_clear_halt(d->udev,
Michael Krufky77eed212011-09-06 09:31:57 -03001265 usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint));
David Wongb18bd1d2009-10-26 09:41:22 -03001266
1267
1268 /* Reset the tuner */
1269 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) {
1270 err("clear tuner gpio failed");
1271 return -EIO;
1272 }
1273 msleep(100);
1274 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) {
1275 err("set tuner gpio failed");
1276 return -EIO;
1277 }
1278 msleep(100);
1279
1280 /* Attach frontend */
Michael Krufky77eed212011-09-06 09:31:57 -03001281 adap->fe_adap[0].fe = dvb_attach(atbm8830_attach, &mygica_d689_atbm8830_cfg,
David Wongb18bd1d2009-10-26 09:41:22 -03001282 &d->i2c_adap);
Michael Krufky77eed212011-09-06 09:31:57 -03001283 if (adap->fe_adap[0].fe == NULL)
David Wongb18bd1d2009-10-26 09:41:22 -03001284 return -EIO;
1285
1286 return 0;
1287}
1288
Patrick Boettcherf5373782006-01-09 18:21:38 -02001289/*
Chris Pascoe702a6762007-11-20 03:34:11 -03001290 * DViCO has shipped two devices with the same USB ID, but only one of them
1291 * needs a firmware download. Check the device class details to see if they
1292 * have non-default values to decide whether the device is actually cold or
1293 * not, and forget a match if it turns out we selected the wrong device.
1294 */
1295static int bluebird_fx2_identify_state(struct usb_device *udev,
1296 struct dvb_usb_device_properties *props,
1297 struct dvb_usb_device_description **desc,
1298 int *cold)
1299{
1300 int wascold = *cold;
1301
1302 *cold = udev->descriptor.bDeviceClass == 0xff &&
1303 udev->descriptor.bDeviceSubClass == 0xff &&
1304 udev->descriptor.bDeviceProtocol == 0xff;
1305
1306 if (*cold && !wascold)
1307 *desc = NULL;
1308
1309 return 0;
1310}
1311
1312/*
Patrick Boettcherf5373782006-01-09 18:21:38 -02001313 * DViCO bluebird firmware needs the "warm" product ID to be patched into the
1314 * firmware file before download.
1315 */
1316
Chris Pascoe702a6762007-11-20 03:34:11 -03001317static const int dvico_firmware_id_offsets[] = { 6638, 3204 };
Michael Krufkyf35db232006-12-05 14:53:39 -03001318static int bluebird_patch_dvico_firmware_download(struct usb_device *udev,
1319 const struct firmware *fw)
Patrick Boettcherf5373782006-01-09 18:21:38 -02001320{
Chris Pascoe702a6762007-11-20 03:34:11 -03001321 int pos;
Patrick Boettcherf5373782006-01-09 18:21:38 -02001322
Chris Pascoe702a6762007-11-20 03:34:11 -03001323 for (pos = 0; pos < ARRAY_SIZE(dvico_firmware_id_offsets); pos++) {
1324 int idoff = dvico_firmware_id_offsets[pos];
Patrick Boettcherf5373782006-01-09 18:21:38 -02001325
Chris Pascoe702a6762007-11-20 03:34:11 -03001326 if (fw->size < idoff + 4)
1327 continue;
Patrick Boettcherf5373782006-01-09 18:21:38 -02001328
Chris Pascoe702a6762007-11-20 03:34:11 -03001329 if (fw->data[idoff] == (USB_VID_DVICO & 0xff) &&
1330 fw->data[idoff + 1] == USB_VID_DVICO >> 8) {
David Woodhousee62f89f2008-05-24 00:12:42 +01001331 struct firmware new_fw;
1332 u8 *new_fw_data = vmalloc(fw->size);
1333 int ret;
1334
1335 if (!new_fw_data)
1336 return -ENOMEM;
1337
1338 memcpy(new_fw_data, fw->data, fw->size);
1339 new_fw.size = fw->size;
1340 new_fw.data = new_fw_data;
1341
1342 new_fw_data[idoff + 2] =
Chris Pascoe702a6762007-11-20 03:34:11 -03001343 le16_to_cpu(udev->descriptor.idProduct) + 1;
David Woodhousee62f89f2008-05-24 00:12:42 +01001344 new_fw_data[idoff + 3] =
Chris Pascoe702a6762007-11-20 03:34:11 -03001345 le16_to_cpu(udev->descriptor.idProduct) >> 8;
1346
David Woodhousee62f89f2008-05-24 00:12:42 +01001347 ret = usb_cypress_load_firmware(udev, &new_fw,
1348 CYPRESS_FX2);
1349 vfree(new_fw_data);
1350 return ret;
Chris Pascoe702a6762007-11-20 03:34:11 -03001351 }
Patrick Boettcherf5373782006-01-09 18:21:38 -02001352 }
1353
1354 return -EINVAL;
1355}
1356
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001357/* DVB USB Driver stuff */
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001358static struct dvb_usb_device_properties cxusb_medion_properties;
1359static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties;
1360static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties;
1361static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties;
1362static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties;
Chris Pascoeaeb012b2007-11-19 21:57:10 -03001363static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties;
Anton Blanchard8d798982008-08-09 12:23:15 -03001364static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties;
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001365static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties;
Chris Pascoe702a6762007-11-20 03:34:11 -03001366static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties;
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03001367static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
Timothy Leedfbdce02008-08-09 13:36:51 -03001368static struct dvb_usb_device_properties cxusb_d680_dmb_properties;
David Wongb18bd1d2009-10-26 09:41:22 -03001369static struct dvb_usb_device_properties cxusb_mygica_d689_properties;
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001370
1371static int cxusb_probe(struct usb_interface *intf,
Michael Krufkyf35db232006-12-05 14:53:39 -03001372 const struct usb_device_id *id)
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001373{
Janne Grunau78e92002008-04-09 19:13:13 -03001374 if (0 == dvb_usb_device_init(intf, &cxusb_medion_properties,
1375 THIS_MODULE, NULL, adapter_nr) ||
1376 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgh064f_properties,
1377 THIS_MODULE, NULL, adapter_nr) ||
1378 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dee1601_properties,
1379 THIS_MODULE, NULL, adapter_nr) ||
1380 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgz201_properties,
1381 THIS_MODULE, NULL, adapter_nr) ||
1382 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dtt7579_properties,
1383 THIS_MODULE, NULL, adapter_nr) ||
1384 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dualdig4_properties,
1385 THIS_MODULE, NULL, adapter_nr) ||
1386 0 == dvb_usb_device_init(intf, &cxusb_bluebird_nano2_properties,
1387 THIS_MODULE, NULL, adapter_nr) ||
1388 0 == dvb_usb_device_init(intf,
1389 &cxusb_bluebird_nano2_needsfirmware_properties,
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03001390 THIS_MODULE, NULL, adapter_nr) ||
1391 0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties,
1392 THIS_MODULE, NULL, adapter_nr) ||
Anton Blanchard8d798982008-08-09 12:23:15 -03001393 0 == dvb_usb_device_init(intf,
1394 &cxusb_bluebird_dualdig4_rev2_properties,
1395 THIS_MODULE, NULL, adapter_nr) ||
Timothy Leedfbdce02008-08-09 13:36:51 -03001396 0 == dvb_usb_device_init(intf, &cxusb_d680_dmb_properties,
1397 THIS_MODULE, NULL, adapter_nr) ||
David Wongb18bd1d2009-10-26 09:41:22 -03001398 0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties,
1399 THIS_MODULE, NULL, adapter_nr) ||
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03001400 0)
Michael Krufkyeffee032006-01-09 15:25:47 -02001401 return 0;
Michael Krufkyeffee032006-01-09 15:25:47 -02001402
1403 return -EINVAL;
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001404}
1405
1406static struct usb_device_id cxusb_table [] = {
Michael Krufkyf35db232006-12-05 14:53:39 -03001407 { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) },
1408 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) },
1409 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_WARM) },
1410 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_COLD) },
1411 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM) },
1412 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_COLD) },
1413 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_WARM) },
1414 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_COLD) },
1415 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_WARM) },
1416 { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD) },
1417 { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM) },
1418 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD) },
1419 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM) },
Chris Pascoeaeb012b2007-11-19 21:57:10 -03001420 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) },
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001421 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) },
Chris Pascoe702a6762007-11-20 03:34:11 -03001422 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) },
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03001423 { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) },
Anton Blanchard8d798982008-08-09 12:23:15 -03001424 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) },
Timothy Leedfbdce02008-08-09 13:36:51 -03001425 { USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) },
David Wongb18bd1d2009-10-26 09:41:22 -03001426 { USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) },
Michael Krufkyf35db232006-12-05 14:53:39 -03001427 {} /* Terminating entry */
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001428};
1429MODULE_DEVICE_TABLE (usb, cxusb_table);
1430
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001431static struct dvb_usb_device_properties cxusb_medion_properties = {
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001432 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1433
1434 .usb_ctrl = CYPRESS_FX2,
1435
1436 .size_of_priv = sizeof(struct cxusb_state),
1437
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001438 .num_adapters = 1,
1439 .adapter = {
1440 {
Michael Krufky77eed212011-09-06 09:31:57 -03001441 .num_frontends = 1,
1442 .fe = {{
Patrick Boettcher01451e72006-10-13 11:34:46 -03001443 .streaming_ctrl = cxusb_streaming_ctrl,
1444 .frontend_attach = cxusb_cx22702_frontend_attach,
1445 .tuner_attach = cxusb_fmd1216me_tuner_attach,
1446 /* parameter for the MPEG2-data transfer */
1447 .stream = {
1448 .type = USB_BULK,
1449 .count = 5,
1450 .endpoint = 0x02,
1451 .u = {
1452 .bulk = {
1453 .buffersize = 8192,
1454 }
1455 }
1456 },
Michael Krufky77eed212011-09-06 09:31:57 -03001457 }},
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001458 },
1459 },
1460 .power_ctrl = cxusb_power_ctrl,
1461
1462 .i2c_algo = &cxusb_i2c_algo,
1463
1464 .generic_bulk_ctrl_endpoint = 0x01,
1465
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001466 .num_device_descs = 1,
1467 .devices = {
1468 { "Medion MD95700 (MDUSBTV-HYBRID)",
1469 { NULL },
1470 { &cxusb_table[0], NULL },
1471 },
1472 }
1473};
1474
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001475static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = {
Michael Krufkyeffee032006-01-09 15:25:47 -02001476 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1477
Patrick Boettcherf5373782006-01-09 18:21:38 -02001478 .usb_ctrl = DEVICE_SPECIFIC,
1479 .firmware = "dvb-usb-bluebird-01.fw",
1480 .download_firmware = bluebird_patch_dvico_firmware_download,
Michael Krufky37bdfa02006-01-09 15:25:47 -02001481 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1482 use usb alt setting 7 for EP2 transfer (atsc) */
Michael Krufkyeffee032006-01-09 15:25:47 -02001483
1484 .size_of_priv = sizeof(struct cxusb_state),
1485
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001486 .num_adapters = 1,
1487 .adapter = {
1488 {
Michael Krufky77eed212011-09-06 09:31:57 -03001489 .num_frontends = 1,
1490 .fe = {{
Patrick Boettcher01451e72006-10-13 11:34:46 -03001491 .streaming_ctrl = cxusb_streaming_ctrl,
1492 .frontend_attach = cxusb_lgdt3303_frontend_attach,
Michael Krufkyf71a56c2006-10-13 21:55:57 -03001493 .tuner_attach = cxusb_lgh064f_tuner_attach,
Michael Krufkyeffee032006-01-09 15:25:47 -02001494
Patrick Boettcher01451e72006-10-13 11:34:46 -03001495 /* parameter for the MPEG2-data transfer */
1496 .stream = {
1497 .type = USB_BULK,
1498 .count = 5,
1499 .endpoint = 0x02,
1500 .u = {
1501 .bulk = {
1502 .buffersize = 8192,
1503 }
1504 }
1505 },
Michael Krufky77eed212011-09-06 09:31:57 -03001506 }},
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001507 },
1508 },
1509
1510 .power_ctrl = cxusb_bluebird_power_ctrl,
1511
Michael Krufkyeffee032006-01-09 15:25:47 -02001512 .i2c_algo = &cxusb_i2c_algo,
1513
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001514 .rc.legacy = {
1515 .rc_interval = 100,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03001516 .rc_map_table = rc_map_dvico_portable_table,
1517 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001518 .rc_query = cxusb_rc_query,
1519 },
Michael Krufkyc1501782006-03-26 05:43:36 -03001520
Michael Krufkyeffee032006-01-09 15:25:47 -02001521 .generic_bulk_ctrl_endpoint = 0x01,
Michael Krufkyeffee032006-01-09 15:25:47 -02001522
1523 .num_device_descs = 1,
1524 .devices = {
1525 { "DViCO FusionHDTV5 USB Gold",
1526 { &cxusb_table[1], NULL },
1527 { &cxusb_table[2], NULL },
1528 },
1529 }
1530};
1531
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001532static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = {
Chris Pascoe0029ee12006-01-09 18:21:28 -02001533 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1534
Patrick Boettcherf5373782006-01-09 18:21:38 -02001535 .usb_ctrl = DEVICE_SPECIFIC,
1536 .firmware = "dvb-usb-bluebird-01.fw",
1537 .download_firmware = bluebird_patch_dvico_firmware_download,
Chris Pascoe0029ee12006-01-09 18:21:28 -02001538 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1539 use usb alt setting 7 for EP2 transfer (atsc) */
1540
1541 .size_of_priv = sizeof(struct cxusb_state),
1542
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001543 .num_adapters = 1,
1544 .adapter = {
1545 {
Michael Krufky77eed212011-09-06 09:31:57 -03001546 .num_frontends = 1,
1547 .fe = {{
Patrick Boettcher01451e72006-10-13 11:34:46 -03001548 .streaming_ctrl = cxusb_streaming_ctrl,
1549 .frontend_attach = cxusb_dee1601_frontend_attach,
1550 .tuner_attach = cxusb_dee1601_tuner_attach,
1551 /* parameter for the MPEG2-data transfer */
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001552 .stream = {
1553 .type = USB_BULK,
Patrick Boettcher01451e72006-10-13 11:34:46 -03001554 .count = 5,
1555 .endpoint = 0x04,
1556 .u = {
1557 .bulk = {
1558 .buffersize = 8192,
1559 }
1560 }
1561 },
Michael Krufky77eed212011-09-06 09:31:57 -03001562 }},
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001563 },
1564 },
1565
1566 .power_ctrl = cxusb_bluebird_power_ctrl,
Chris Pascoe0029ee12006-01-09 18:21:28 -02001567
1568 .i2c_algo = &cxusb_i2c_algo,
1569
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001570 .rc.legacy = {
1571 .rc_interval = 150,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03001572 .rc_map_table = rc_map_dvico_mce_table,
1573 .rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001574 .rc_query = cxusb_rc_query,
1575 },
Chris Pascoe7c239702006-01-09 18:21:29 -02001576
Chris Pascoe0029ee12006-01-09 18:21:28 -02001577 .generic_bulk_ctrl_endpoint = 0x01,
Chris Pascoe0029ee12006-01-09 18:21:28 -02001578
Michael Krufky587c03d2006-09-28 02:16:01 -03001579 .num_device_descs = 3,
Chris Pascoe0029ee12006-01-09 18:21:28 -02001580 .devices = {
1581 { "DViCO FusionHDTV DVB-T Dual USB",
1582 { &cxusb_table[3], NULL },
1583 { &cxusb_table[4], NULL },
1584 },
Michael Krufkyac9ffb92006-01-11 23:21:00 -02001585 { "DigitalNow DVB-T Dual USB",
1586 { &cxusb_table[9], NULL },
1587 { &cxusb_table[10], NULL },
1588 },
Michael Krufky587c03d2006-09-28 02:16:01 -03001589 { "DViCO FusionHDTV DVB-T Dual Digital 2",
1590 { &cxusb_table[11], NULL },
1591 { &cxusb_table[12], NULL },
1592 },
Chris Pascoe0029ee12006-01-09 18:21:28 -02001593 }
1594};
1595
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001596static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = {
Michael Krufky6f447252006-01-11 19:40:33 -02001597 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1598
1599 .usb_ctrl = DEVICE_SPECIFIC,
1600 .firmware = "dvb-usb-bluebird-01.fw",
1601 .download_firmware = bluebird_patch_dvico_firmware_download,
1602 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1603 use usb alt setting 7 for EP2 transfer (atsc) */
1604
1605 .size_of_priv = sizeof(struct cxusb_state),
1606
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001607 .num_adapters = 2,
1608 .adapter = {
1609 {
Michael Krufky77eed212011-09-06 09:31:57 -03001610 .num_frontends = 1,
1611 .fe = {{
Patrick Boettcher01451e72006-10-13 11:34:46 -03001612 .streaming_ctrl = cxusb_streaming_ctrl,
1613 .frontend_attach = cxusb_mt352_frontend_attach,
1614 .tuner_attach = cxusb_lgz201_tuner_attach,
Michael Krufky6f447252006-01-11 19:40:33 -02001615
Patrick Boettcher01451e72006-10-13 11:34:46 -03001616 /* parameter for the MPEG2-data transfer */
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001617 .stream = {
1618 .type = USB_BULK,
Patrick Boettcher01451e72006-10-13 11:34:46 -03001619 .count = 5,
1620 .endpoint = 0x04,
1621 .u = {
1622 .bulk = {
1623 .buffersize = 8192,
1624 }
1625 }
1626 },
Michael Krufky77eed212011-09-06 09:31:57 -03001627 }},
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001628 },
1629 },
1630 .power_ctrl = cxusb_bluebird_power_ctrl,
1631
Michael Krufky6f447252006-01-11 19:40:33 -02001632 .i2c_algo = &cxusb_i2c_algo,
1633
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001634 .rc.legacy = {
1635 .rc_interval = 100,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03001636 .rc_map_table = rc_map_dvico_portable_table,
1637 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001638 .rc_query = cxusb_rc_query,
1639 },
Michael Krufkyc1501782006-03-26 05:43:36 -03001640
Michael Krufky6f447252006-01-11 19:40:33 -02001641 .generic_bulk_ctrl_endpoint = 0x01,
Michael Krufky6f447252006-01-11 19:40:33 -02001642 .num_device_descs = 1,
1643 .devices = {
1644 { "DViCO FusionHDTV DVB-T USB (LGZ201)",
1645 { &cxusb_table[5], NULL },
1646 { &cxusb_table[6], NULL },
1647 },
1648 }
1649};
1650
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001651static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = {
Michael Krufky6f447252006-01-11 19:40:33 -02001652 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1653
1654 .usb_ctrl = DEVICE_SPECIFIC,
1655 .firmware = "dvb-usb-bluebird-01.fw",
1656 .download_firmware = bluebird_patch_dvico_firmware_download,
1657 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1658 use usb alt setting 7 for EP2 transfer (atsc) */
1659
1660 .size_of_priv = sizeof(struct cxusb_state),
1661
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001662 .num_adapters = 1,
1663 .adapter = {
1664 {
Michael Krufky77eed212011-09-06 09:31:57 -03001665 .num_frontends = 1,
1666 .fe = {{
Patrick Boettcher01451e72006-10-13 11:34:46 -03001667 .streaming_ctrl = cxusb_streaming_ctrl,
1668 .frontend_attach = cxusb_mt352_frontend_attach,
1669 .tuner_attach = cxusb_dtt7579_tuner_attach,
Michael Krufky6f447252006-01-11 19:40:33 -02001670
Patrick Boettcher01451e72006-10-13 11:34:46 -03001671 /* parameter for the MPEG2-data transfer */
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001672 .stream = {
1673 .type = USB_BULK,
Patrick Boettcher01451e72006-10-13 11:34:46 -03001674 .count = 5,
1675 .endpoint = 0x04,
1676 .u = {
1677 .bulk = {
1678 .buffersize = 8192,
1679 }
1680 }
1681 },
Michael Krufky77eed212011-09-06 09:31:57 -03001682 }},
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001683 },
1684 },
1685 .power_ctrl = cxusb_bluebird_power_ctrl,
1686
Michael Krufky6f447252006-01-11 19:40:33 -02001687 .i2c_algo = &cxusb_i2c_algo,
1688
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001689 .rc.legacy = {
1690 .rc_interval = 100,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03001691 .rc_map_table = rc_map_dvico_portable_table,
1692 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001693 .rc_query = cxusb_rc_query,
1694 },
Michael Krufkyc1501782006-03-26 05:43:36 -03001695
Michael Krufky6f447252006-01-11 19:40:33 -02001696 .generic_bulk_ctrl_endpoint = 0x01,
Michael Krufky6f447252006-01-11 19:40:33 -02001697
1698 .num_device_descs = 1,
1699 .devices = {
1700 { "DViCO FusionHDTV DVB-T USB (TH7579)",
1701 { &cxusb_table[7], NULL },
1702 { &cxusb_table[8], NULL },
1703 },
1704 }
1705};
1706
Chris Pascoeaeb012b2007-11-19 21:57:10 -03001707static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = {
1708 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1709
1710 .usb_ctrl = CYPRESS_FX2,
1711
1712 .size_of_priv = sizeof(struct cxusb_state),
1713
1714 .num_adapters = 1,
1715 .adapter = {
1716 {
Michael Krufky77eed212011-09-06 09:31:57 -03001717 .num_frontends = 1,
1718 .fe = {{
Chris Pascoeaeb012b2007-11-19 21:57:10 -03001719 .streaming_ctrl = cxusb_streaming_ctrl,
1720 .frontend_attach = cxusb_dualdig4_frontend_attach,
1721 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1722 /* parameter for the MPEG2-data transfer */
1723 .stream = {
1724 .type = USB_BULK,
1725 .count = 5,
1726 .endpoint = 0x02,
1727 .u = {
1728 .bulk = {
1729 .buffersize = 8192,
1730 }
1731 }
1732 },
Michael Krufky77eed212011-09-06 09:31:57 -03001733 }},
Chris Pascoeaeb012b2007-11-19 21:57:10 -03001734 },
1735 },
1736
1737 .power_ctrl = cxusb_power_ctrl,
1738
1739 .i2c_algo = &cxusb_i2c_algo,
1740
1741 .generic_bulk_ctrl_endpoint = 0x01,
1742
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001743 .rc.legacy = {
1744 .rc_interval = 100,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03001745 .rc_map_table = rc_map_dvico_mce_table,
1746 .rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001747 .rc_query = cxusb_bluebird2_rc_query,
1748 },
Chris Pascoeaeb012b2007-11-19 21:57:10 -03001749
1750 .num_device_descs = 1,
1751 .devices = {
1752 { "DViCO FusionHDTV DVB-T Dual Digital 4",
1753 { NULL },
1754 { &cxusb_table[13], NULL },
1755 },
1756 }
1757};
1758
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001759static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = {
1760 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1761
1762 .usb_ctrl = CYPRESS_FX2,
Chris Pascoe702a6762007-11-20 03:34:11 -03001763 .identify_state = bluebird_fx2_identify_state,
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001764
1765 .size_of_priv = sizeof(struct cxusb_state),
1766
1767 .num_adapters = 1,
1768 .adapter = {
1769 {
Michael Krufky77eed212011-09-06 09:31:57 -03001770 .num_frontends = 1,
1771 .fe = {{
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001772 .streaming_ctrl = cxusb_streaming_ctrl,
1773 .frontend_attach = cxusb_nano2_frontend_attach,
1774 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1775 /* parameter for the MPEG2-data transfer */
1776 .stream = {
1777 .type = USB_BULK,
1778 .count = 5,
1779 .endpoint = 0x02,
1780 .u = {
1781 .bulk = {
1782 .buffersize = 8192,
1783 }
1784 }
1785 },
Michael Krufky77eed212011-09-06 09:31:57 -03001786 }},
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001787 },
1788 },
1789
1790 .power_ctrl = cxusb_nano2_power_ctrl,
1791
1792 .i2c_algo = &cxusb_i2c_algo,
1793
1794 .generic_bulk_ctrl_endpoint = 0x01,
1795
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001796 .rc.legacy = {
1797 .rc_interval = 100,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03001798 .rc_map_table = rc_map_dvico_portable_table,
1799 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001800 .rc_query = cxusb_bluebird2_rc_query,
1801 },
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001802
1803 .num_device_descs = 1,
1804 .devices = {
1805 { "DViCO FusionHDTV DVB-T NANO2",
1806 { NULL },
1807 { &cxusb_table[14], NULL },
1808 },
1809 }
1810};
1811
Chris Pascoe702a6762007-11-20 03:34:11 -03001812static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties = {
1813 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1814
1815 .usb_ctrl = DEVICE_SPECIFIC,
1816 .firmware = "dvb-usb-bluebird-02.fw",
1817 .download_firmware = bluebird_patch_dvico_firmware_download,
1818 .identify_state = bluebird_fx2_identify_state,
1819
1820 .size_of_priv = sizeof(struct cxusb_state),
1821
1822 .num_adapters = 1,
1823 .adapter = {
1824 {
Michael Krufky77eed212011-09-06 09:31:57 -03001825 .num_frontends = 1,
1826 .fe = {{
Chris Pascoe702a6762007-11-20 03:34:11 -03001827 .streaming_ctrl = cxusb_streaming_ctrl,
1828 .frontend_attach = cxusb_nano2_frontend_attach,
1829 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1830 /* parameter for the MPEG2-data transfer */
1831 .stream = {
1832 .type = USB_BULK,
1833 .count = 5,
1834 .endpoint = 0x02,
1835 .u = {
1836 .bulk = {
1837 .buffersize = 8192,
1838 }
1839 }
1840 },
Michael Krufky77eed212011-09-06 09:31:57 -03001841 }},
Chris Pascoe702a6762007-11-20 03:34:11 -03001842 },
1843 },
1844
1845 .power_ctrl = cxusb_nano2_power_ctrl,
1846
1847 .i2c_algo = &cxusb_i2c_algo,
1848
1849 .generic_bulk_ctrl_endpoint = 0x01,
1850
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001851 .rc.legacy = {
1852 .rc_interval = 100,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03001853 .rc_map_table = rc_map_dvico_portable_table,
1854 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001855 .rc_query = cxusb_rc_query,
1856 },
Chris Pascoe702a6762007-11-20 03:34:11 -03001857
1858 .num_device_descs = 1,
1859 .devices = {
1860 { "DViCO FusionHDTV DVB-T NANO2 w/o firmware",
1861 { &cxusb_table[14], NULL },
1862 { &cxusb_table[15], NULL },
1863 },
1864 }
1865};
1866
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03001867static struct dvb_usb_device_properties cxusb_aver_a868r_properties = {
1868 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1869
1870 .usb_ctrl = CYPRESS_FX2,
1871
1872 .size_of_priv = sizeof(struct cxusb_state),
1873
1874 .num_adapters = 1,
1875 .adapter = {
1876 {
Michael Krufky77eed212011-09-06 09:31:57 -03001877 .num_frontends = 1,
1878 .fe = {{
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03001879 .streaming_ctrl = cxusb_aver_streaming_ctrl,
1880 .frontend_attach = cxusb_aver_lgdt3303_frontend_attach,
1881 .tuner_attach = cxusb_mxl5003s_tuner_attach,
1882 /* parameter for the MPEG2-data transfer */
1883 .stream = {
1884 .type = USB_BULK,
1885 .count = 5,
1886 .endpoint = 0x04,
1887 .u = {
1888 .bulk = {
1889 .buffersize = 8192,
1890 }
1891 }
1892 },
Michael Krufky77eed212011-09-06 09:31:57 -03001893 }},
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03001894 },
1895 },
1896 .power_ctrl = cxusb_aver_power_ctrl,
1897
1898 .i2c_algo = &cxusb_i2c_algo,
1899
1900 .generic_bulk_ctrl_endpoint = 0x01,
1901
1902 .num_device_descs = 1,
1903 .devices = {
1904 { "AVerMedia AVerTVHD Volar (A868R)",
1905 { NULL },
1906 { &cxusb_table[16], NULL },
1907 },
1908 }
1909};
1910
Michael Krufkya2dc86b2008-08-09 13:06:26 -03001911static
1912struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = {
Anton Blanchard8d798982008-08-09 12:23:15 -03001913 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1914
1915 .usb_ctrl = CYPRESS_FX2,
1916
1917 .size_of_priv = sizeof(struct cxusb_state),
1918
1919 .num_adapters = 1,
1920 .adapter = {
1921 {
Michael Krufky77eed212011-09-06 09:31:57 -03001922 .size_of_priv = sizeof(struct dib0700_adapter_state),
1923 .num_frontends = 1,
1924 .fe = {{
Michael Krufkya2dc86b2008-08-09 13:06:26 -03001925 .streaming_ctrl = cxusb_streaming_ctrl,
1926 .frontend_attach = cxusb_dualdig4_rev2_frontend_attach,
1927 .tuner_attach = cxusb_dualdig4_rev2_tuner_attach,
Anton Blanchard8d798982008-08-09 12:23:15 -03001928 /* parameter for the MPEG2-data transfer */
1929 .stream = {
1930 .type = USB_BULK,
1931 .count = 7,
1932 .endpoint = 0x02,
1933 .u = {
1934 .bulk = {
1935 .buffersize = 4096,
1936 }
1937 }
1938 },
Michael Krufky77eed212011-09-06 09:31:57 -03001939 }},
Anton Blanchard8d798982008-08-09 12:23:15 -03001940 },
1941 },
1942
1943 .power_ctrl = cxusb_bluebird_power_ctrl,
1944
1945 .i2c_algo = &cxusb_i2c_algo,
1946
1947 .generic_bulk_ctrl_endpoint = 0x01,
1948
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001949 .rc.legacy = {
1950 .rc_interval = 100,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03001951 .rc_map_table = rc_map_dvico_mce_table,
1952 .rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001953 .rc_query = cxusb_rc_query,
1954 },
Anton Blanchard8d798982008-08-09 12:23:15 -03001955
1956 .num_device_descs = 1,
1957 .devices = {
1958 { "DViCO FusionHDTV DVB-T Dual Digital 4 (rev 2)",
1959 { NULL },
1960 { &cxusb_table[17], NULL },
1961 },
1962 }
1963};
1964
Timothy Leedfbdce02008-08-09 13:36:51 -03001965static struct dvb_usb_device_properties cxusb_d680_dmb_properties = {
1966 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1967
1968 .usb_ctrl = CYPRESS_FX2,
1969
1970 .size_of_priv = sizeof(struct cxusb_state),
1971
1972 .num_adapters = 1,
1973 .adapter = {
1974 {
Michael Krufky77eed212011-09-06 09:31:57 -03001975 .num_frontends = 1,
1976 .fe = {{
Timothy Leedfbdce02008-08-09 13:36:51 -03001977 .streaming_ctrl = cxusb_d680_dmb_streaming_ctrl,
1978 .frontend_attach = cxusb_d680_dmb_frontend_attach,
1979 .tuner_attach = cxusb_d680_dmb_tuner_attach,
1980
1981 /* parameter for the MPEG2-data transfer */
1982 .stream = {
1983 .type = USB_BULK,
1984 .count = 5,
1985 .endpoint = 0x02,
1986 .u = {
1987 .bulk = {
1988 .buffersize = 8192,
1989 }
1990 }
1991 },
Michael Krufky77eed212011-09-06 09:31:57 -03001992 }},
Timothy Leedfbdce02008-08-09 13:36:51 -03001993 },
1994 },
1995
1996 .power_ctrl = cxusb_d680_dmb_power_ctrl,
1997
1998 .i2c_algo = &cxusb_i2c_algo,
1999
2000 .generic_bulk_ctrl_endpoint = 0x01,
2001
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03002002 .rc.legacy = {
2003 .rc_interval = 100,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03002004 .rc_map_table = rc_map_d680_dmb_table,
2005 .rc_map_size = ARRAY_SIZE(rc_map_d680_dmb_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03002006 .rc_query = cxusb_d680_dmb_rc_query,
2007 },
Timothy Leedfbdce02008-08-09 13:36:51 -03002008
2009 .num_device_descs = 1,
2010 .devices = {
2011 {
2012 "Conexant DMB-TH Stick",
2013 { NULL },
2014 { &cxusb_table[18], NULL },
2015 },
2016 }
2017};
2018
David Wongb18bd1d2009-10-26 09:41:22 -03002019static struct dvb_usb_device_properties cxusb_mygica_d689_properties = {
2020 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
2021
2022 .usb_ctrl = CYPRESS_FX2,
2023
2024 .size_of_priv = sizeof(struct cxusb_state),
2025
2026 .num_adapters = 1,
2027 .adapter = {
2028 {
Michael Krufky77eed212011-09-06 09:31:57 -03002029 .num_frontends = 1,
2030 .fe = {{
David Wongb18bd1d2009-10-26 09:41:22 -03002031 .streaming_ctrl = cxusb_d680_dmb_streaming_ctrl,
2032 .frontend_attach = cxusb_mygica_d689_frontend_attach,
2033 .tuner_attach = cxusb_mygica_d689_tuner_attach,
2034
2035 /* parameter for the MPEG2-data transfer */
2036 .stream = {
2037 .type = USB_BULK,
2038 .count = 5,
2039 .endpoint = 0x02,
2040 .u = {
2041 .bulk = {
2042 .buffersize = 8192,
2043 }
2044 }
2045 },
Michael Krufky77eed212011-09-06 09:31:57 -03002046 }},
David Wongb18bd1d2009-10-26 09:41:22 -03002047 },
2048 },
2049
2050 .power_ctrl = cxusb_d680_dmb_power_ctrl,
2051
2052 .i2c_algo = &cxusb_i2c_algo,
2053
2054 .generic_bulk_ctrl_endpoint = 0x01,
2055
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03002056 .rc.legacy = {
2057 .rc_interval = 100,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03002058 .rc_map_table = rc_map_d680_dmb_table,
2059 .rc_map_size = ARRAY_SIZE(rc_map_d680_dmb_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03002060 .rc_query = cxusb_d680_dmb_rc_query,
2061 },
David Wongb18bd1d2009-10-26 09:41:22 -03002062
2063 .num_device_descs = 1,
2064 .devices = {
2065 {
2066 "Mygica D689 DMB-TH",
2067 { NULL },
2068 { &cxusb_table[19], NULL },
2069 },
2070 }
2071};
2072
Patrick Boettcher22c6d932005-07-07 17:58:10 -07002073static struct usb_driver cxusb_driver = {
Patrick Boettcher63b5c1c2005-07-07 17:58:30 -07002074 .name = "dvb_usb_cxusb",
Patrick Boettcher22c6d932005-07-07 17:58:10 -07002075 .probe = cxusb_probe,
Michael Krufkyf35db232006-12-05 14:53:39 -03002076 .disconnect = dvb_usb_device_exit,
Patrick Boettcher22c6d932005-07-07 17:58:10 -07002077 .id_table = cxusb_table,
2078};
2079
Greg Kroah-Hartmanecb3b2b2011-11-18 09:46:12 -08002080module_usb_driver(cxusb_driver);
Patrick Boettcher22c6d932005-07-07 17:58:10 -07002081
2082MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
Michael Krufky5b9ed282006-10-15 14:51:08 -03002083MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
Michael Krufkyf4efb4d2006-01-13 14:10:25 -02002084MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
Patrick Boettcher22c6d932005-07-07 17:58:10 -07002085MODULE_DESCRIPTION("Driver for Conexant USB2.0 hybrid reference design");
2086MODULE_VERSION("1.0-alpha");
2087MODULE_LICENSE("GPL");