blob: f379f7e1fcb07ab3617e47b6bf453b1c5a4d6722 [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"
Olli Salonen26c42b02014-07-13 10:52:22 -030045#include "si2168.h"
46#include "si2157.h"
Patrick Boettcher22c6d932005-07-07 17:58:10 -070047
Mauro Carvalho Chehab64f7ef82013-11-02 07:18:09 -030048/* Max transfer size done by I2C transfer functions */
Mauro Carvalho Chehabeb9da072014-06-30 11:56:33 -030049#define MAX_XFER_SIZE 80
Mauro Carvalho Chehab64f7ef82013-11-02 07:18:09 -030050
Patrick Boettcher22c6d932005-07-07 17:58:10 -070051/* debug */
Adrian Bunk53133af2007-11-05 14:07:06 -030052static int dvb_usb_cxusb_debug;
Michael Krufkyf35db232006-12-05 14:53:39 -030053module_param_named(debug, dvb_usb_cxusb_debug, int, 0644);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070054MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
Janne Grunau78e92002008-04-09 19:13:13 -030055
56DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
57
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -030058#define deb_info(args...) dprintk(dvb_usb_cxusb_debug, 0x03, args)
59#define deb_i2c(args...) dprintk(dvb_usb_cxusb_debug, 0x02, args)
Patrick Boettcher22c6d932005-07-07 17:58:10 -070060
61static int cxusb_ctrl_msg(struct dvb_usb_device *d,
Michael Krufkyf35db232006-12-05 14:53:39 -030062 u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
Patrick Boettcher22c6d932005-07-07 17:58:10 -070063{
64 int wo = (rbuf == NULL || rlen == 0); /* write-only */
Mauro Carvalho Chehab64f7ef82013-11-02 07:18:09 -030065 u8 sndbuf[MAX_XFER_SIZE];
66
67 if (1 + wlen > sizeof(sndbuf)) {
68 warn("i2c wr: len=%d is too big!\n",
69 wlen);
70 return -EOPNOTSUPP;
71 }
72
Michael Krufkyf35db232006-12-05 14:53:39 -030073 memset(sndbuf, 0, 1+wlen);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070074
75 sndbuf[0] = cmd;
Michael Krufkyf35db232006-12-05 14:53:39 -030076 memcpy(&sndbuf[1], wbuf, wlen);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070077 if (wo)
Chris Pascoeb17f1092007-11-19 02:42:44 -030078 return dvb_usb_generic_write(d, sndbuf, 1+wlen);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070079 else
Chris Pascoeb17f1092007-11-19 02:42:44 -030080 return dvb_usb_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen, 0);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070081}
82
Patrick Boettchere2efeab2005-09-09 13:02:51 -070083/* GPIO */
84static void cxusb_gpio_tuner(struct dvb_usb_device *d, int onoff)
Patrick Boettcher22c6d932005-07-07 17:58:10 -070085{
86 struct cxusb_state *st = d->priv;
Michael Krufkyf35db232006-12-05 14:53:39 -030087 u8 o[2], i;
Patrick Boettcher22c6d932005-07-07 17:58:10 -070088
Patrick Boettchere2efeab2005-09-09 13:02:51 -070089 if (st->gpio_write_state[GPIO_TUNER] == onoff)
Patrick Boettcher22c6d932005-07-07 17:58:10 -070090 return;
91
Patrick Boettchere2efeab2005-09-09 13:02:51 -070092 o[0] = GPIO_TUNER;
93 o[1] = onoff;
Michael Krufkyf35db232006-12-05 14:53:39 -030094 cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070095
96 if (i != 0x01)
Patrick Boettchere2efeab2005-09-09 13:02:51 -070097 deb_info("gpio_write failed.\n");
Patrick Boettcher22c6d932005-07-07 17:58:10 -070098
Patrick Boettchere2efeab2005-09-09 13:02:51 -070099 st->gpio_write_state[GPIO_TUNER] = onoff;
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700100}
101
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300102static int cxusb_bluebird_gpio_rw(struct dvb_usb_device *d, u8 changemask,
103 u8 newval)
104{
105 u8 o[2], gpio_state;
106 int rc;
107
108 o[0] = 0xff & ~changemask; /* mask of bits to keep */
109 o[1] = newval & changemask; /* new values for bits */
110
111 rc = cxusb_ctrl_msg(d, CMD_BLUEBIRD_GPIO_RW, o, 2, &gpio_state, 1);
112 if (rc < 0 || (gpio_state & changemask) != (newval & changemask))
113 deb_info("bluebird_gpio_write failed.\n");
114
115 return rc < 0 ? rc : gpio_state;
116}
117
118static void cxusb_bluebird_gpio_pulse(struct dvb_usb_device *d, u8 pin, int low)
119{
120 cxusb_bluebird_gpio_rw(d, pin, low ? 0 : pin);
121 msleep(5);
122 cxusb_bluebird_gpio_rw(d, pin, low ? pin : 0);
123}
124
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300125static void cxusb_nano2_led(struct dvb_usb_device *d, int onoff)
126{
127 cxusb_bluebird_gpio_rw(d, 0x40, onoff ? 0 : 0x40);
128}
129
Timothy Leedfbdce02008-08-09 13:36:51 -0300130static int cxusb_d680_dmb_gpio_tuner(struct dvb_usb_device *d,
131 u8 addr, int onoff)
132{
133 u8 o[2] = {addr, onoff};
134 u8 i;
135 int rc;
136
137 rc = cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
138
139 if (rc < 0)
140 return rc;
141 if (i == 0x01)
142 return 0;
143 else {
144 deb_info("gpio_write failed.\n");
145 return -EIO;
146 }
147}
148
Olli Salonen26c42b02014-07-13 10:52:22 -0300149static int cxusb_tt_ct2_4400_gpio_tuner(struct dvb_usb_device *d, int onoff)
150{
151 u8 o[2], i;
152 int rc;
153
154 o[0] = 0x83;
155 o[1] = onoff;
156 rc = cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
157
158 if (rc) {
159 deb_info("gpio_write failed.\n");
160 return -EIO;
161 }
162 return 0;
163}
164
Patrick Boettchere2efeab2005-09-09 13:02:51 -0700165/* I2C */
Michael Krufkyf35db232006-12-05 14:53:39 -0300166static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
167 int num)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700168{
169 struct dvb_usb_device *d = i2c_get_adapdata(adap);
Dan Carpenter1cdbcc52013-11-22 04:55:43 -0300170 int ret;
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700171 int i;
172
Ingo Molnar3593cab2006-02-07 06:49:14 -0200173 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700174 return -EAGAIN;
175
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700176 for (i = 0; i < num; i++) {
177
Michael Krufky5e805ef2006-03-23 00:01:34 -0300178 if (d->udev->descriptor.idVendor == USB_VID_MEDION)
179 switch (msg[i].addr) {
Michael Krufkyf35db232006-12-05 14:53:39 -0300180 case 0x63:
181 cxusb_gpio_tuner(d, 0);
182 break;
183 default:
184 cxusb_gpio_tuner(d, 1);
185 break;
Michael Krufky5e805ef2006-03-23 00:01:34 -0300186 }
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700187
Chris Pascoe272479d72007-11-19 03:01:22 -0300188 if (msg[i].flags & I2C_M_RD) {
189 /* read only */
Mauro Carvalho Chehab64f7ef82013-11-02 07:18:09 -0300190 u8 obuf[3], ibuf[MAX_XFER_SIZE];
191
192 if (1 + msg[i].len > sizeof(ibuf)) {
193 warn("i2c rd: len=%d is too big!\n",
194 msg[i].len);
Dan Carpenter1cdbcc52013-11-22 04:55:43 -0300195 ret = -EOPNOTSUPP;
196 goto unlock;
Mauro Carvalho Chehab64f7ef82013-11-02 07:18:09 -0300197 }
Chris Pascoe272479d72007-11-19 03:01:22 -0300198 obuf[0] = 0;
199 obuf[1] = msg[i].len;
200 obuf[2] = msg[i].addr;
201 if (cxusb_ctrl_msg(d, CMD_I2C_READ,
202 obuf, 3,
203 ibuf, 1+msg[i].len) < 0) {
204 warn("i2c read failed");
205 break;
206 }
207 memcpy(msg[i].buf, &ibuf[1], msg[i].len);
Chris Pascoea644e4a2007-11-19 03:05:09 -0300208 } else if (i+1 < num && (msg[i+1].flags & I2C_M_RD) &&
209 msg[i].addr == msg[i+1].addr) {
210 /* write to then read from same address */
Mauro Carvalho Chehab64f7ef82013-11-02 07:18:09 -0300211 u8 obuf[MAX_XFER_SIZE], ibuf[MAX_XFER_SIZE];
212
213 if (3 + msg[i].len > sizeof(obuf)) {
214 warn("i2c wr: len=%d is too big!\n",
215 msg[i].len);
Dan Carpenter1cdbcc52013-11-22 04:55:43 -0300216 ret = -EOPNOTSUPP;
217 goto unlock;
Mauro Carvalho Chehab64f7ef82013-11-02 07:18:09 -0300218 }
219 if (1 + msg[i + 1].len > sizeof(ibuf)) {
220 warn("i2c rd: len=%d is too big!\n",
221 msg[i + 1].len);
Dan Carpenter1cdbcc52013-11-22 04:55:43 -0300222 ret = -EOPNOTSUPP;
223 goto unlock;
Mauro Carvalho Chehab64f7ef82013-11-02 07:18:09 -0300224 }
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700225 obuf[0] = msg[i].len;
226 obuf[1] = msg[i+1].len;
227 obuf[2] = msg[i].addr;
Michael Krufkyf35db232006-12-05 14:53:39 -0300228 memcpy(&obuf[3], msg[i].buf, msg[i].len);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700229
230 if (cxusb_ctrl_msg(d, CMD_I2C_READ,
Michael Krufkyf35db232006-12-05 14:53:39 -0300231 obuf, 3+msg[i].len,
232 ibuf, 1+msg[i+1].len) < 0)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700233 break;
234
235 if (ibuf[0] != 0x08)
Michael Krufkyae62e3d2006-03-23 01:11:18 -0300236 deb_i2c("i2c read may have failed\n");
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700237
Michael Krufkyf35db232006-12-05 14:53:39 -0300238 memcpy(msg[i+1].buf, &ibuf[1], msg[i+1].len);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700239
240 i++;
Chris Pascoe272479d72007-11-19 03:01:22 -0300241 } else {
242 /* write only */
Mauro Carvalho Chehab64f7ef82013-11-02 07:18:09 -0300243 u8 obuf[MAX_XFER_SIZE], ibuf;
244
245 if (2 + msg[i].len > sizeof(obuf)) {
246 warn("i2c wr: len=%d is too big!\n",
247 msg[i].len);
Dan Carpenter1cdbcc52013-11-22 04:55:43 -0300248 ret = -EOPNOTSUPP;
249 goto unlock;
Mauro Carvalho Chehab64f7ef82013-11-02 07:18:09 -0300250 }
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700251 obuf[0] = msg[i].addr;
252 obuf[1] = msg[i].len;
Michael Krufkyf35db232006-12-05 14:53:39 -0300253 memcpy(&obuf[2], msg[i].buf, msg[i].len);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700254
Michael Krufkyf35db232006-12-05 14:53:39 -0300255 if (cxusb_ctrl_msg(d, CMD_I2C_WRITE, obuf,
256 2+msg[i].len, &ibuf,1) < 0)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700257 break;
258 if (ibuf != 0x08)
Michael Krufkyae62e3d2006-03-23 01:11:18 -0300259 deb_i2c("i2c write may have failed\n");
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700260 }
261 }
262
Dan Carpenter1cdbcc52013-11-22 04:55:43 -0300263 if (i == num)
264 ret = num;
265 else
266 ret = -EREMOTEIO;
267
268unlock:
Ingo Molnar3593cab2006-02-07 06:49:14 -0200269 mutex_unlock(&d->i2c_mutex);
Dan Carpenter1cdbcc52013-11-22 04:55:43 -0300270 return ret;
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700271}
272
273static u32 cxusb_i2c_func(struct i2c_adapter *adapter)
274{
275 return I2C_FUNC_I2C;
276}
277
278static struct i2c_algorithm cxusb_i2c_algo = {
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700279 .master_xfer = cxusb_i2c_xfer,
280 .functionality = cxusb_i2c_func,
281};
282
283static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff)
284{
Patrick Boettchere2efeab2005-09-09 13:02:51 -0700285 u8 b = 0;
286 if (onoff)
287 return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
288 else
289 return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700290}
291
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300292static int cxusb_aver_power_ctrl(struct dvb_usb_device *d, int onoff)
293{
294 int ret;
295 if (!onoff)
296 return cxusb_ctrl_msg(d, CMD_POWER_OFF, NULL, 0, NULL, 0);
297 if (d->state == DVB_USB_STATE_INIT &&
298 usb_set_interface(d->udev, 0, 0) < 0)
299 err("set interface failed");
Hans Verkuilc6eb8ea2008-09-03 17:11:54 -0300300 do {} while (!(ret = cxusb_ctrl_msg(d, CMD_POWER_ON, NULL, 0, NULL, 0)) &&
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300301 !(ret = cxusb_ctrl_msg(d, 0x15, NULL, 0, NULL, 0)) &&
302 !(ret = cxusb_ctrl_msg(d, 0x17, NULL, 0, NULL, 0)) && 0);
303 if (!ret) {
304 /* FIXME: We don't know why, but we need to configure the
305 * lgdt3303 with the register settings below on resume */
306 int i;
307 u8 buf, bufs[] = {
308 0x0e, 0x2, 0x00, 0x7f,
309 0x0e, 0x2, 0x02, 0xfe,
310 0x0e, 0x2, 0x02, 0x01,
311 0x0e, 0x2, 0x00, 0x03,
312 0x0e, 0x2, 0x0d, 0x40,
313 0x0e, 0x2, 0x0e, 0x87,
314 0x0e, 0x2, 0x0f, 0x8e,
315 0x0e, 0x2, 0x10, 0x01,
316 0x0e, 0x2, 0x14, 0xd7,
317 0x0e, 0x2, 0x47, 0x88,
318 };
319 msleep(20);
320 for (i = 0; i < sizeof(bufs)/sizeof(u8); i += 4/sizeof(u8)) {
321 ret = cxusb_ctrl_msg(d, CMD_I2C_WRITE,
322 bufs+i, 4, &buf, 1);
323 if (ret)
324 break;
325 if (buf != 0x8)
326 return -EREMOTEIO;
327 }
328 }
329 return ret;
330}
331
Michael Krufky5691c842006-04-19 20:40:01 -0300332static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff)
333{
334 u8 b = 0;
335 if (onoff)
336 return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
337 else
338 return 0;
339}
340
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300341static int cxusb_nano2_power_ctrl(struct dvb_usb_device *d, int onoff)
342{
343 int rc = 0;
344
345 rc = cxusb_power_ctrl(d, onoff);
346 if (!onoff)
347 cxusb_nano2_led(d, 0);
348
349 return rc;
350}
351
Timothy Leedfbdce02008-08-09 13:36:51 -0300352static int cxusb_d680_dmb_power_ctrl(struct dvb_usb_device *d, int onoff)
353{
354 int ret;
355 u8 b;
356 ret = cxusb_power_ctrl(d, onoff);
357 if (!onoff)
358 return ret;
359
360 msleep(128);
361 cxusb_ctrl_msg(d, CMD_DIGITAL, NULL, 0, &b, 1);
362 msleep(100);
363 return ret;
364}
365
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300366static int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700367{
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700368 u8 buf[2] = { 0x03, 0x00 };
369 if (onoff)
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300370 cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON, buf, 2, NULL, 0);
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700371 else
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300372 cxusb_ctrl_msg(adap->dev, CMD_STREAMING_OFF, NULL, 0, NULL, 0);
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700373
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700374 return 0;
375}
376
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300377static int cxusb_aver_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
378{
379 if (onoff)
380 cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_ON, NULL, 0, NULL, 0);
381 else
382 cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_OFF,
383 NULL, 0, NULL, 0);
384 return 0;
385}
386
Timothy Leedfbdce02008-08-09 13:36:51 -0300387static void cxusb_d680_dmb_drain_message(struct dvb_usb_device *d)
388{
389 int ep = d->props.generic_bulk_ctrl_endpoint;
390 const int timeout = 100;
391 const int junk_len = 32;
392 u8 *junk;
393 int rd_count;
394
395 /* Discard remaining data in video pipe */
396 junk = kmalloc(junk_len, GFP_KERNEL);
397 if (!junk)
398 return;
399 while (1) {
400 if (usb_bulk_msg(d->udev,
401 usb_rcvbulkpipe(d->udev, ep),
402 junk, junk_len, &rd_count, timeout) < 0)
403 break;
404 if (!rd_count)
405 break;
406 }
407 kfree(junk);
408}
409
410static void cxusb_d680_dmb_drain_video(struct dvb_usb_device *d)
411{
Michael Krufky77eed212011-09-06 09:31:57 -0300412 struct usb_data_stream_properties *p = &d->props.adapter[0].fe[0].stream;
Timothy Leedfbdce02008-08-09 13:36:51 -0300413 const int timeout = 100;
414 const int junk_len = p->u.bulk.buffersize;
415 u8 *junk;
416 int rd_count;
417
418 /* Discard remaining data in video pipe */
419 junk = kmalloc(junk_len, GFP_KERNEL);
420 if (!junk)
421 return;
422 while (1) {
423 if (usb_bulk_msg(d->udev,
424 usb_rcvbulkpipe(d->udev, p->endpoint),
425 junk, junk_len, &rd_count, timeout) < 0)
426 break;
427 if (!rd_count)
428 break;
429 }
430 kfree(junk);
431}
432
433static int cxusb_d680_dmb_streaming_ctrl(
434 struct dvb_usb_adapter *adap, int onoff)
435{
436 if (onoff) {
437 u8 buf[2] = { 0x03, 0x00 };
438 cxusb_d680_dmb_drain_video(adap->dev);
439 return cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON,
440 buf, sizeof(buf), NULL, 0);
441 } else {
442 int ret = cxusb_ctrl_msg(adap->dev,
443 CMD_STREAMING_OFF, NULL, 0, NULL, 0);
444 return ret;
445 }
446}
447
Chris Pascoe7c239702006-01-09 18:21:29 -0200448static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
449{
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300450 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
Michael Krufkya07e6092006-01-09 18:21:31 -0200451 u8 ircode[4];
Chris Pascoe7c239702006-01-09 18:21:29 -0200452 int i;
453
Michael Krufkya07e6092006-01-09 18:21:31 -0200454 cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4);
Chris Pascoe7c239702006-01-09 18:21:29 -0200455
456 *event = 0;
457 *state = REMOTE_NO_KEY_PRESSED;
458
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300459 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
Mauro Carvalho Chehab2e365882009-08-29 15:19:31 -0300460 if (rc5_custom(&keymap[i]) == ircode[2] &&
461 rc5_data(&keymap[i]) == ircode[3]) {
Mauro Carvalho Chehab34abf212010-07-31 11:24:57 -0300462 *event = keymap[i].keycode;
Chris Pascoe7c239702006-01-09 18:21:29 -0200463 *state = REMOTE_KEY_PRESSED;
464
465 return 0;
466 }
467 }
468
469 return 0;
470}
471
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300472static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event,
473 int *state)
474{
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300475 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300476 u8 ircode[4];
477 int i;
478 struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
479 .buf = ircode, .len = 4 };
480
481 *event = 0;
482 *state = REMOTE_NO_KEY_PRESSED;
483
484 if (cxusb_i2c_xfer(&d->i2c_adap, &msg, 1) != 1)
485 return 0;
486
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300487 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
Mauro Carvalho Chehab2e365882009-08-29 15:19:31 -0300488 if (rc5_custom(&keymap[i]) == ircode[1] &&
489 rc5_data(&keymap[i]) == ircode[2]) {
Mauro Carvalho Chehab34abf212010-07-31 11:24:57 -0300490 *event = keymap[i].keycode;
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300491 *state = REMOTE_KEY_PRESSED;
492
493 return 0;
494 }
495 }
496
497 return 0;
498}
499
Timothy Leedfbdce02008-08-09 13:36:51 -0300500static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
501 int *state)
502{
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300503 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
Timothy Leedfbdce02008-08-09 13:36:51 -0300504 u8 ircode[2];
505 int i;
506
507 *event = 0;
508 *state = REMOTE_NO_KEY_PRESSED;
509
510 if (cxusb_ctrl_msg(d, 0x10, NULL, 0, ircode, 2) < 0)
511 return 0;
512
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300513 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
Mauro Carvalho Chehab2e365882009-08-29 15:19:31 -0300514 if (rc5_custom(&keymap[i]) == ircode[0] &&
515 rc5_data(&keymap[i]) == ircode[1]) {
Mauro Carvalho Chehab34abf212010-07-31 11:24:57 -0300516 *event = keymap[i].keycode;
Timothy Leedfbdce02008-08-09 13:36:51 -0300517 *state = REMOTE_KEY_PRESSED;
518
519 return 0;
520 }
521 }
522
523 return 0;
524}
525
Olli Salonen26c42b02014-07-13 10:52:22 -0300526static int cxusb_tt_ct2_4400_rc_query(struct dvb_usb_device *d)
527{
528 u8 i[2];
529 int ret;
530 u32 cmd, keycode;
531 u8 rc5_cmd, rc5_addr, rc5_toggle;
532
533 ret = cxusb_ctrl_msg(d, 0x10, NULL, 0, i, 2);
534 if (ret)
535 return ret;
536
537 cmd = (i[0] << 8) | i[1];
538
539 if (cmd != 0xffff) {
540 rc5_cmd = cmd & 0x3F; /* bits 1-6 for command */
541 rc5_addr = (cmd & 0x07C0) >> 6; /* bits 7-11 for address */
542 rc5_toggle = (cmd & 0x0800) >> 11; /* bit 12 for toggle */
543 keycode = (rc5_addr << 8) | rc5_cmd;
544 rc_keydown(d->rc_dev, keycode, rc5_toggle);
545 }
546
547 return 0;
548}
549
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300550static struct rc_map_table rc_map_dvico_mce_table[] = {
Mauro Carvalho Chehab2e365882009-08-29 15:19:31 -0300551 { 0xfe02, KEY_TV },
552 { 0xfe0e, KEY_MP3 },
553 { 0xfe1a, KEY_DVD },
554 { 0xfe1e, KEY_FAVORITES },
555 { 0xfe16, KEY_SETUP },
556 { 0xfe46, KEY_POWER2 },
557 { 0xfe0a, KEY_EPG },
558 { 0xfe49, KEY_BACK },
559 { 0xfe4d, KEY_MENU },
560 { 0xfe51, KEY_UP },
561 { 0xfe5b, KEY_LEFT },
562 { 0xfe5f, KEY_RIGHT },
563 { 0xfe53, KEY_DOWN },
564 { 0xfe5e, KEY_OK },
565 { 0xfe59, KEY_INFO },
566 { 0xfe55, KEY_TAB },
567 { 0xfe0f, KEY_PREVIOUSSONG },/* Replay */
568 { 0xfe12, KEY_NEXTSONG }, /* Skip */
569 { 0xfe42, KEY_ENTER }, /* Windows/Start */
570 { 0xfe15, KEY_VOLUMEUP },
571 { 0xfe05, KEY_VOLUMEDOWN },
572 { 0xfe11, KEY_CHANNELUP },
573 { 0xfe09, KEY_CHANNELDOWN },
574 { 0xfe52, KEY_CAMERA },
575 { 0xfe5a, KEY_TUNER }, /* Live */
576 { 0xfe19, KEY_OPEN },
577 { 0xfe0b, KEY_1 },
578 { 0xfe17, KEY_2 },
579 { 0xfe1b, KEY_3 },
580 { 0xfe07, KEY_4 },
581 { 0xfe50, KEY_5 },
582 { 0xfe54, KEY_6 },
583 { 0xfe48, KEY_7 },
584 { 0xfe4c, KEY_8 },
585 { 0xfe58, KEY_9 },
586 { 0xfe13, KEY_ANGLE }, /* Aspect */
587 { 0xfe03, KEY_0 },
588 { 0xfe1f, KEY_ZOOM },
589 { 0xfe43, KEY_REWIND },
590 { 0xfe47, KEY_PLAYPAUSE },
591 { 0xfe4f, KEY_FASTFORWARD },
592 { 0xfe57, KEY_MUTE },
593 { 0xfe0d, KEY_STOP },
594 { 0xfe01, KEY_RECORD },
595 { 0xfe4e, KEY_POWER },
Michael Krufkya07e6092006-01-09 18:21:31 -0200596};
597
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300598static struct rc_map_table rc_map_dvico_portable_table[] = {
Mauro Carvalho Chehab2e365882009-08-29 15:19:31 -0300599 { 0xfc02, KEY_SETUP }, /* Profile */
600 { 0xfc43, KEY_POWER2 },
601 { 0xfc06, KEY_EPG },
602 { 0xfc5a, KEY_BACK },
603 { 0xfc05, KEY_MENU },
604 { 0xfc47, KEY_INFO },
605 { 0xfc01, KEY_TAB },
606 { 0xfc42, KEY_PREVIOUSSONG },/* Replay */
607 { 0xfc49, KEY_VOLUMEUP },
608 { 0xfc09, KEY_VOLUMEDOWN },
609 { 0xfc54, KEY_CHANNELUP },
610 { 0xfc0b, KEY_CHANNELDOWN },
611 { 0xfc16, KEY_CAMERA },
612 { 0xfc40, KEY_TUNER }, /* ATV/DTV */
613 { 0xfc45, KEY_OPEN },
614 { 0xfc19, KEY_1 },
615 { 0xfc18, KEY_2 },
616 { 0xfc1b, KEY_3 },
617 { 0xfc1a, KEY_4 },
618 { 0xfc58, KEY_5 },
619 { 0xfc59, KEY_6 },
620 { 0xfc15, KEY_7 },
621 { 0xfc14, KEY_8 },
622 { 0xfc17, KEY_9 },
623 { 0xfc44, KEY_ANGLE }, /* Aspect */
624 { 0xfc55, KEY_0 },
625 { 0xfc07, KEY_ZOOM },
626 { 0xfc0a, KEY_REWIND },
627 { 0xfc08, KEY_PLAYPAUSE },
628 { 0xfc4b, KEY_FASTFORWARD },
629 { 0xfc5b, KEY_MUTE },
630 { 0xfc04, KEY_STOP },
631 { 0xfc56, KEY_RECORD },
632 { 0xfc57, KEY_POWER },
633 { 0xfc41, KEY_UNKNOWN }, /* INPUT */
634 { 0xfc00, KEY_UNKNOWN }, /* HD */
Michael Krufkyc1501782006-03-26 05:43:36 -0300635};
636
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300637static struct rc_map_table rc_map_d680_dmb_table[] = {
Mauro Carvalho Chehab2e365882009-08-29 15:19:31 -0300638 { 0x0038, KEY_UNKNOWN }, /* TV/AV */
639 { 0x080c, KEY_ZOOM },
640 { 0x0800, KEY_0 },
641 { 0x0001, KEY_1 },
642 { 0x0802, KEY_2 },
643 { 0x0003, KEY_3 },
644 { 0x0804, KEY_4 },
645 { 0x0005, KEY_5 },
646 { 0x0806, KEY_6 },
647 { 0x0007, KEY_7 },
648 { 0x0808, KEY_8 },
649 { 0x0009, KEY_9 },
650 { 0x000a, KEY_MUTE },
651 { 0x0829, KEY_BACK },
652 { 0x0012, KEY_CHANNELUP },
653 { 0x0813, KEY_CHANNELDOWN },
654 { 0x002b, KEY_VOLUMEUP },
655 { 0x082c, KEY_VOLUMEDOWN },
656 { 0x0020, KEY_UP },
657 { 0x0821, KEY_DOWN },
658 { 0x0011, KEY_LEFT },
659 { 0x0810, KEY_RIGHT },
660 { 0x000d, KEY_OK },
661 { 0x081f, KEY_RECORD },
662 { 0x0017, KEY_PLAYPAUSE },
663 { 0x0816, KEY_PLAYPAUSE },
664 { 0x000b, KEY_STOP },
665 { 0x0827, KEY_FASTFORWARD },
666 { 0x0026, KEY_REWIND },
667 { 0x081e, KEY_UNKNOWN }, /* Time Shift */
668 { 0x000e, KEY_UNKNOWN }, /* Snapshot */
669 { 0x082d, KEY_UNKNOWN }, /* Mouse Cursor */
670 { 0x000f, KEY_UNKNOWN }, /* Minimize/Maximize */
671 { 0x0814, KEY_UNKNOWN }, /* Shuffle */
672 { 0x0025, KEY_POWER },
Timothy Leedfbdce02008-08-09 13:36:51 -0300673};
674
Chris Pascoe0029ee12006-01-09 18:21:28 -0200675static int cxusb_dee1601_demod_init(struct dvb_frontend* fe)
676{
Chris Pascoed9ed8812006-02-07 06:49:11 -0200677 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 };
Chris Pascoe0029ee12006-01-09 18:21:28 -0200678 static u8 reset [] = { RESET, 0x80 };
679 static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
680 static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 };
681 static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
682 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
683
684 mt352_write(fe, clock_config, sizeof(clock_config));
685 udelay(200);
686 mt352_write(fe, reset, sizeof(reset));
687 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
688
689 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
690 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
691 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
692
693 return 0;
694}
695
Michael Krufky6f447252006-01-11 19:40:33 -0200696static int cxusb_mt352_demod_init(struct dvb_frontend* fe)
697{ /* used in both lgz201 and th7579 */
Michael Krufkyfb51fd22006-02-07 06:49:12 -0200698 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x29 };
Michael Krufky6f447252006-01-11 19:40:33 -0200699 static u8 reset [] = { RESET, 0x80 };
700 static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
701 static u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 };
702 static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
703 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
704
705 mt352_write(fe, clock_config, sizeof(clock_config));
706 udelay(200);
707 mt352_write(fe, reset, sizeof(reset));
708 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
709
710 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
711 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
712 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
713 return 0;
714}
715
Adrian Bunk703cb2c2006-01-23 17:11:09 -0200716static struct cx22702_config cxusb_cx22702_config = {
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700717 .demod_address = 0x63,
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700718 .output_mode = CX22702_PARALLEL_OUTPUT,
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700719};
720
Michael Krufkyfddd6322006-02-27 00:08:17 -0300721static struct lgdt330x_config cxusb_lgdt3303_config = {
Michael Krufkyeffee032006-01-09 15:25:47 -0200722 .demod_address = 0x0e,
723 .demod_chip = LGDT3303,
Michael Krufkyeffee032006-01-09 15:25:47 -0200724};
725
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300726static struct lgdt330x_config cxusb_aver_lgdt3303_config = {
727 .demod_address = 0x0e,
728 .demod_chip = LGDT3303,
729 .clock_polarity_flip = 2,
730};
731
Adrian Bunk703cb2c2006-01-23 17:11:09 -0200732static struct mt352_config cxusb_dee1601_config = {
Chris Pascoe0029ee12006-01-09 18:21:28 -0200733 .demod_address = 0x0f,
734 .demod_init = cxusb_dee1601_demod_init,
Chris Pascoe0029ee12006-01-09 18:21:28 -0200735};
736
Michael Krufkyc9ce3942006-06-11 04:24:31 -0300737static struct zl10353_config cxusb_zl10353_dee1601_config = {
738 .demod_address = 0x0f,
Chris Pascoe8fb95782006-08-10 03:17:16 -0300739 .parallel_ts = 1,
Michael Krufkyc9ce3942006-06-11 04:24:31 -0300740};
741
Adrian Bunk6fe00b02006-04-19 20:49:28 -0300742static struct mt352_config cxusb_mt352_config = {
Michael Krufky6f447252006-01-11 19:40:33 -0200743 /* used in both lgz201 and th7579 */
744 .demod_address = 0x0f,
745 .demod_init = cxusb_mt352_demod_init,
Michael Krufky6f447252006-01-11 19:40:33 -0200746};
747
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300748static struct zl10353_config cxusb_zl10353_xc3028_config = {
749 .demod_address = 0x0f,
Chris Pascoea1dcd9d2007-11-20 08:17:54 -0300750 .if2 = 45600,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300751 .no_tuner = 1,
752 .parallel_ts = 1,
753};
754
Robert Lowery0bc35182009-11-08 00:00:11 -0300755static struct zl10353_config cxusb_zl10353_xc3028_config_no_i2c_gate = {
756 .demod_address = 0x0f,
757 .if2 = 45600,
758 .no_tuner = 1,
759 .parallel_ts = 1,
760 .disable_i2c_gate_ctrl = 1,
761};
762
Chris Pascoe702a6762007-11-20 03:34:11 -0300763static struct mt352_config cxusb_mt352_xc3028_config = {
764 .demod_address = 0x0f,
765 .if2 = 4560,
766 .no_tuner = 1,
767 .demod_init = cxusb_mt352_demod_init,
768};
769
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300770/* FIXME: needs tweaking */
771static struct mxl5005s_config aver_a868r_tuner = {
772 .i2c_address = 0x63,
773 .if_freq = 6000000UL,
774 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
775 .agc_mode = MXL_SINGLE_AGC,
776 .tracking_filter = MXL_TF_C,
777 .rssi_enable = MXL_RSSI_ENABLE,
778 .cap_select = MXL_CAP_SEL_ENABLE,
779 .div_out = MXL_DIV_OUT_4,
780 .clock_out = MXL_CLOCK_OUT_DISABLE,
781 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
782 .top = MXL5005S_TOP_25P2,
783 .mod_mode = MXL_DIGITAL_MODE,
784 .if_mode = MXL_ZERO_IF,
785 .AgcMasterByte = 0x00,
786};
787
Timothy Leedfbdce02008-08-09 13:36:51 -0300788/* FIXME: needs tweaking */
789static struct mxl5005s_config d680_dmb_tuner = {
790 .i2c_address = 0x63,
791 .if_freq = 36125000UL,
792 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
793 .agc_mode = MXL_SINGLE_AGC,
794 .tracking_filter = MXL_TF_C,
795 .rssi_enable = MXL_RSSI_ENABLE,
796 .cap_select = MXL_CAP_SEL_ENABLE,
797 .div_out = MXL_DIV_OUT_4,
798 .clock_out = MXL_CLOCK_OUT_DISABLE,
799 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
800 .top = MXL5005S_TOP_25P2,
801 .mod_mode = MXL_DIGITAL_MODE,
802 .if_mode = MXL_ZERO_IF,
803 .AgcMasterByte = 0x00,
804};
805
David Wongb18bd1d2009-10-26 09:41:22 -0300806static struct max2165_config mygica_d689_max2165_cfg = {
807 .i2c_address = 0x60,
808 .osc_clk = 20
809};
810
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700811/* Callbacks for DVB USB */
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300812static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700813{
Michael Krufky77eed212011-09-06 09:31:57 -0300814 dvb_attach(simple_tuner_attach, adap->fe_adap[0].fe,
Michael Krufkycb89cd32008-04-22 14:46:16 -0300815 &adap->dev->i2c_adap, 0x61,
816 TUNER_PHILIPS_FMD1216ME_MK3);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700817 return 0;
818}
819
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300820static int cxusb_dee1601_tuner_attach(struct dvb_usb_adapter *adap)
Chris Pascoe0029ee12006-01-09 18:21:28 -0200821{
Michael Krufky77eed212011-09-06 09:31:57 -0300822 dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61,
Michael Krufky47a99912007-06-12 16:10:51 -0300823 NULL, DVB_PLL_THOMSON_DTT7579);
Chris Pascoe0029ee12006-01-09 18:21:28 -0200824 return 0;
825}
826
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300827static int cxusb_lgz201_tuner_attach(struct dvb_usb_adapter *adap)
Michael Krufky6f447252006-01-11 19:40:33 -0200828{
Michael Krufky77eed212011-09-06 09:31:57 -0300829 dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61, NULL, DVB_PLL_LG_Z201);
Michael Krufky6f447252006-01-11 19:40:33 -0200830 return 0;
831}
832
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300833static int cxusb_dtt7579_tuner_attach(struct dvb_usb_adapter *adap)
Michael Krufky6f447252006-01-11 19:40:33 -0200834{
Michael Krufky77eed212011-09-06 09:31:57 -0300835 dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60,
Michael Krufky47a99912007-06-12 16:10:51 -0300836 NULL, DVB_PLL_THOMSON_DTT7579);
Patrick Boettcher332bed52006-05-14 04:49:00 -0300837 return 0;
838}
839
Michael Krufkyf71a56c2006-10-13 21:55:57 -0300840static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap)
Patrick Boettcher332bed52006-05-14 04:49:00 -0300841{
Michael Krufky77eed212011-09-06 09:31:57 -0300842 dvb_attach(simple_tuner_attach, adap->fe_adap[0].fe,
Michael Krufky827855d2008-04-22 14:46:16 -0300843 &adap->dev->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF);
Michael Krufky6f447252006-01-11 19:40:33 -0200844 return 0;
845}
846
Michael Krufkyd7cba042008-09-12 13:31:45 -0300847static int dvico_bluebird_xc2028_callback(void *ptr, int component,
848 int command, int arg)
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300849{
Robert Loweryd483b732008-07-30 19:43:11 -0300850 struct dvb_usb_adapter *adap = ptr;
851 struct dvb_usb_device *d = adap->dev;
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300852
853 switch (command) {
854 case XC2028_TUNER_RESET:
Harvey Harrison708bebd2008-04-08 23:20:00 -0300855 deb_info("%s: XC2028_TUNER_RESET %d\n", __func__, arg);
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300856 cxusb_bluebird_gpio_pulse(d, 0x01, 1);
857 break;
858 case XC2028_RESET_CLK:
Harvey Harrison708bebd2008-04-08 23:20:00 -0300859 deb_info("%s: XC2028_RESET_CLK %d\n", __func__, arg);
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300860 break;
861 default:
Harvey Harrison708bebd2008-04-08 23:20:00 -0300862 deb_info("%s: unknown command %d, arg %d\n", __func__,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300863 command, arg);
864 return -EINVAL;
865 }
866
867 return 0;
868}
869
870static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap)
871{
872 struct dvb_frontend *fe;
873 struct xc2028_config cfg = {
874 .i2c_adap = &adap->dev->i2c_adap,
875 .i2c_addr = 0x61,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300876 };
877 static struct xc2028_ctrl ctl = {
Michael Krufkyef80bfe2008-09-16 02:15:30 -0300878 .fname = XC2028_DEFAULT_FIRMWARE,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300879 .max_len = 64,
Robert Loweryd483b732008-07-30 19:43:11 -0300880 .demod = XC3028_FE_ZARLINK456,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300881 };
882
Michael Krufkyd7cba042008-09-12 13:31:45 -0300883 /* FIXME: generalize & move to common area */
Michael Krufky77eed212011-09-06 09:31:57 -0300884 adap->fe_adap[0].fe->callback = dvico_bluebird_xc2028_callback;
Michael Krufkyd7cba042008-09-12 13:31:45 -0300885
Michael Krufky77eed212011-09-06 09:31:57 -0300886 fe = dvb_attach(xc2028_attach, adap->fe_adap[0].fe, &cfg);
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300887 if (fe == NULL || fe->ops.tuner_ops.set_config == NULL)
888 return -EIO;
889
890 fe->ops.tuner_ops.set_config(fe, &ctl);
891
892 return 0;
893}
894
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300895static int cxusb_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
896{
Michael Krufky77eed212011-09-06 09:31:57 -0300897 dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe,
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300898 &adap->dev->i2c_adap, &aver_a868r_tuner);
899 return 0;
900}
901
Timothy Leedfbdce02008-08-09 13:36:51 -0300902static int cxusb_d680_dmb_tuner_attach(struct dvb_usb_adapter *adap)
903{
904 struct dvb_frontend *fe;
Michael Krufky77eed212011-09-06 09:31:57 -0300905 fe = dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe,
Timothy Leedfbdce02008-08-09 13:36:51 -0300906 &adap->dev->i2c_adap, &d680_dmb_tuner);
907 return (fe == NULL) ? -EIO : 0;
908}
909
David Wongb18bd1d2009-10-26 09:41:22 -0300910static int cxusb_mygica_d689_tuner_attach(struct dvb_usb_adapter *adap)
911{
912 struct dvb_frontend *fe;
Michael Krufky77eed212011-09-06 09:31:57 -0300913 fe = dvb_attach(max2165_attach, adap->fe_adap[0].fe,
David Wongb18bd1d2009-10-26 09:41:22 -0300914 &adap->dev->i2c_adap, &mygica_d689_max2165_cfg);
915 return (fe == NULL) ? -EIO : 0;
916}
917
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300918static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700919{
Patrick Boettchere2efeab2005-09-09 13:02:51 -0700920 u8 b;
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300921 if (usb_set_interface(adap->dev->udev, 0, 6) < 0)
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700922 err("set interface failed");
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700923
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300924 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, &b, 1);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700925
Michael Krufky310df362011-09-17 14:22:59 -0300926 adap->fe_adap[0].fe = dvb_attach(cx22702_attach, &cxusb_cx22702_config,
927 &adap->dev->i2c_adap);
928 if ((adap->fe_adap[0].fe) != NULL)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700929 return 0;
930
931 return -EIO;
932}
933
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300934static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
Michael Krufkyeffee032006-01-09 15:25:47 -0200935{
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300936 if (usb_set_interface(adap->dev->udev, 0, 7) < 0)
Michael Krufkyeffee032006-01-09 15:25:47 -0200937 err("set interface failed");
938
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300939 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
Michael Krufkyeffee032006-01-09 15:25:47 -0200940
Michael Krufky310df362011-09-17 14:22:59 -0300941 adap->fe_adap[0].fe = dvb_attach(lgdt330x_attach,
942 &cxusb_lgdt3303_config,
943 &adap->dev->i2c_adap);
944 if ((adap->fe_adap[0].fe) != NULL)
Michael Krufkyeffee032006-01-09 15:25:47 -0200945 return 0;
946
947 return -EIO;
948}
949
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300950static int cxusb_aver_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
951{
Michael Krufky77eed212011-09-06 09:31:57 -0300952 adap->fe_adap[0].fe = dvb_attach(lgdt330x_attach, &cxusb_aver_lgdt3303_config,
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300953 &adap->dev->i2c_adap);
Michael Krufky77eed212011-09-06 09:31:57 -0300954 if (adap->fe_adap[0].fe != NULL)
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300955 return 0;
956
957 return -EIO;
958}
959
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300960static int cxusb_mt352_frontend_attach(struct dvb_usb_adapter *adap)
Chris Pascoe0029ee12006-01-09 18:21:28 -0200961{
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300962 /* used in both lgz201 and th7579 */
963 if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
Chris Pascoe0029ee12006-01-09 18:21:28 -0200964 err("set interface failed");
965
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300966 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
Chris Pascoe0029ee12006-01-09 18:21:28 -0200967
Michael Krufky310df362011-09-17 14:22:59 -0300968 adap->fe_adap[0].fe = dvb_attach(mt352_attach, &cxusb_mt352_config,
969 &adap->dev->i2c_adap);
970 if ((adap->fe_adap[0].fe) != NULL)
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300971 return 0;
972
973 return -EIO;
974}
975
976static int cxusb_dee1601_frontend_attach(struct dvb_usb_adapter *adap)
977{
978 if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
979 err("set interface failed");
980
981 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
982
Michael Krufky310df362011-09-17 14:22:59 -0300983 adap->fe_adap[0].fe = dvb_attach(mt352_attach, &cxusb_dee1601_config,
984 &adap->dev->i2c_adap);
985 if ((adap->fe_adap[0].fe) != NULL)
986 return 0;
987
988 adap->fe_adap[0].fe = dvb_attach(zl10353_attach,
989 &cxusb_zl10353_dee1601_config,
990 &adap->dev->i2c_adap);
991 if ((adap->fe_adap[0].fe) != NULL)
Chris Pascoe0029ee12006-01-09 18:21:28 -0200992 return 0;
993
994 return -EIO;
995}
996
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300997static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap)
998{
999 u8 ircode[4];
1000 int i;
1001 struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
1002 .buf = ircode, .len = 4 };
1003
1004 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
1005 err("set interface failed");
1006
1007 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
1008
1009 /* reset the tuner and demodulator */
1010 cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
1011 cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
1012 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
1013
Michael Krufky310df362011-09-17 14:22:59 -03001014 adap->fe_adap[0].fe =
1015 dvb_attach(zl10353_attach,
1016 &cxusb_zl10353_xc3028_config_no_i2c_gate,
1017 &adap->dev->i2c_adap);
1018 if ((adap->fe_adap[0].fe) == NULL)
Chris Pascoeaeb012b2007-11-19 21:57:10 -03001019 return -EIO;
1020
1021 /* try to determine if there is no IR decoder on the I2C bus */
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03001022 for (i = 0; adap->dev->props.rc.legacy.rc_map_table != NULL && i < 5; i++) {
Chris Pascoeaeb012b2007-11-19 21:57:10 -03001023 msleep(20);
1024 if (cxusb_i2c_xfer(&adap->dev->i2c_adap, &msg, 1) != 1)
1025 goto no_IR;
1026 if (ircode[0] == 0 && ircode[1] == 0)
1027 continue;
1028 if (ircode[2] + ircode[3] != 0xff) {
1029no_IR:
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03001030 adap->dev->props.rc.legacy.rc_map_table = NULL;
Chris Pascoeaeb012b2007-11-19 21:57:10 -03001031 info("No IR receiver detected on this device.");
1032 break;
1033 }
1034 }
1035
1036 return 0;
1037}
1038
Anton Blanchard8d798982008-08-09 12:23:15 -03001039static struct dibx000_agc_config dib7070_agc_config = {
1040 .band_caps = BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
1041
1042 /*
1043 * P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5,
1044 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
1045 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0
1046 */
1047 .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) |
1048 (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
1049 .inv_gain = 600,
1050 .time_stabiliz = 10,
1051 .alpha_level = 0,
1052 .thlock = 118,
1053 .wbd_inv = 0,
1054 .wbd_ref = 3530,
1055 .wbd_sel = 1,
1056 .wbd_alpha = 5,
1057 .agc1_max = 65535,
1058 .agc1_min = 0,
1059 .agc2_max = 65535,
1060 .agc2_min = 0,
1061 .agc1_pt1 = 0,
1062 .agc1_pt2 = 40,
1063 .agc1_pt3 = 183,
1064 .agc1_slope1 = 206,
1065 .agc1_slope2 = 255,
1066 .agc2_pt1 = 72,
1067 .agc2_pt2 = 152,
1068 .agc2_slope1 = 88,
1069 .agc2_slope2 = 90,
1070 .alpha_mant = 17,
1071 .alpha_exp = 27,
1072 .beta_mant = 23,
1073 .beta_exp = 51,
1074 .perform_agc_softsplit = 0,
1075};
1076
1077static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
1078 .internal = 60000,
1079 .sampling = 15000,
1080 .pll_prediv = 1,
1081 .pll_ratio = 20,
1082 .pll_range = 3,
1083 .pll_reset = 1,
1084 .pll_bypass = 0,
1085 .enable_refdiv = 0,
1086 .bypclk_div = 0,
1087 .IO_CLK_en_core = 1,
1088 .ADClkSrc = 1,
1089 .modulo = 2,
1090 /* refsel, sel, freq_15k */
1091 .sad_cfg = (3 << 14) | (1 << 12) | (524 << 0),
1092 .ifreq = (0 << 25) | 0,
1093 .timf = 20452225,
1094 .xtal_hz = 12000000,
1095};
1096
1097static struct dib7000p_config cxusb_dualdig4_rev2_config = {
1098 .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK,
1099 .output_mpeg2_in_188_bytes = 1,
1100
1101 .agc_config_count = 1,
1102 .agc = &dib7070_agc_config,
1103 .bw = &dib7070_bw_config_12_mhz,
1104 .tuner_is_baseband = 1,
1105 .spur_protect = 1,
1106
1107 .gpio_dir = 0xfcef,
1108 .gpio_val = 0x0110,
1109
1110 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
1111
1112 .hostbus_diversity = 1,
1113};
1114
Mauro Carvalho Chehab8abe4a02014-05-29 09:20:15 -03001115struct dib0700_adapter_state {
1116 int (*set_param_save)(struct dvb_frontend *);
1117 struct dib7000p_ops dib7000p_ops;
1118};
1119
Anton Blanchard8d798982008-08-09 12:23:15 -03001120static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap)
1121{
Mauro Carvalho Chehab8abe4a02014-05-29 09:20:15 -03001122 struct dib0700_adapter_state *state = adap->priv;
1123
Anton Blanchard8d798982008-08-09 12:23:15 -03001124 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
1125 err("set interface failed");
1126
1127 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
1128
1129 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
1130
Mauro Carvalho Chehab8abe4a02014-05-29 09:20:15 -03001131 if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops))
1132 return -ENODEV;
1133
1134 if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
1135 &cxusb_dualdig4_rev2_config) < 0) {
Prarit Bhargavaa49ba162010-05-12 19:30:02 -03001136 printk(KERN_WARNING "Unable to enumerate dib7000p\n");
Randy Dunlap30d81bb2010-02-08 20:30:44 -03001137 return -ENODEV;
Prarit Bhargavaa49ba162010-05-12 19:30:02 -03001138 }
Anton Blanchard8d798982008-08-09 12:23:15 -03001139
Mauro Carvalho Chehab8abe4a02014-05-29 09:20:15 -03001140 adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80,
1141 &cxusb_dualdig4_rev2_config);
Michael Krufky77eed212011-09-06 09:31:57 -03001142 if (adap->fe_adap[0].fe == NULL)
Anton Blanchard8d798982008-08-09 12:23:15 -03001143 return -EIO;
1144
1145 return 0;
1146}
1147
1148static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
1149{
Mauro Carvalho Chehab8abe4a02014-05-29 09:20:15 -03001150 struct dvb_usb_adapter *adap = fe->dvb->priv;
1151 struct dib0700_adapter_state *state = adap->priv;
1152
1153 return state->dib7000p_ops.set_gpio(fe, 8, 0, !onoff);
Anton Blanchard8d798982008-08-09 12:23:15 -03001154}
1155
1156static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
1157{
1158 return 0;
1159}
1160
1161static struct dib0070_config dib7070p_dib0070_config = {
1162 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1163 .reset = dib7070_tuner_reset,
1164 .sleep = dib7070_tuner_sleep,
1165 .clock_khz = 12000,
1166};
1167
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03001168static int dib7070_set_param_override(struct dvb_frontend *fe)
Anton Blanchard8d798982008-08-09 12:23:15 -03001169{
Mauro Carvalho Chehabafd2b382011-12-24 10:17:30 -03001170 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Anton Blanchard8d798982008-08-09 12:23:15 -03001171 struct dvb_usb_adapter *adap = fe->dvb->priv;
1172 struct dib0700_adapter_state *state = adap->priv;
1173
1174 u16 offset;
Mauro Carvalho Chehabafd2b382011-12-24 10:17:30 -03001175 u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
Anton Blanchard8d798982008-08-09 12:23:15 -03001176 switch (band) {
Michael Krufkya2dc86b2008-08-09 13:06:26 -03001177 case BAND_VHF: offset = 950; break;
1178 default:
1179 case BAND_UHF: offset = 550; break;
Anton Blanchard8d798982008-08-09 12:23:15 -03001180 }
1181
Mauro Carvalho Chehab8abe4a02014-05-29 09:20:15 -03001182 state->dib7000p_ops.set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
Anton Blanchard8d798982008-08-09 12:23:15 -03001183
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03001184 return state->set_param_save(fe);
Anton Blanchard8d798982008-08-09 12:23:15 -03001185}
1186
1187static int cxusb_dualdig4_rev2_tuner_attach(struct dvb_usb_adapter *adap)
1188{
1189 struct dib0700_adapter_state *st = adap->priv;
Mauro Carvalho Chehab8abe4a02014-05-29 09:20:15 -03001190 struct i2c_adapter *tun_i2c;
1191
1192 /*
1193 * No need to call dvb7000p_attach here, as it was called
1194 * already, as frontend_attach method is called first, and
1195 * tuner_attach is only called on sucess.
1196 */
1197 tun_i2c = st->dib7000p_ops.get_i2c_master(adap->fe_adap[0].fe,
Michael Krufkya2dc86b2008-08-09 13:06:26 -03001198 DIBX000_I2C_INTERFACE_TUNER, 1);
Anton Blanchard8d798982008-08-09 12:23:15 -03001199
Michael Krufky77eed212011-09-06 09:31:57 -03001200 if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,
Anton Blanchard8d798982008-08-09 12:23:15 -03001201 &dib7070p_dib0070_config) == NULL)
1202 return -ENODEV;
1203
Michael Krufky77eed212011-09-06 09:31:57 -03001204 st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
1205 adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7070_set_param_override;
Anton Blanchard8d798982008-08-09 12:23:15 -03001206 return 0;
1207}
1208
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001209static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap)
1210{
1211 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
1212 err("set interface failed");
1213
1214 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
1215
1216 /* reset the tuner and demodulator */
1217 cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
1218 cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
1219 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
1220
Michael Krufky310df362011-09-17 14:22:59 -03001221 adap->fe_adap[0].fe = dvb_attach(zl10353_attach,
1222 &cxusb_zl10353_xc3028_config,
1223 &adap->dev->i2c_adap);
1224 if ((adap->fe_adap[0].fe) != NULL)
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001225 return 0;
1226
Michael Krufky310df362011-09-17 14:22:59 -03001227 adap->fe_adap[0].fe = dvb_attach(mt352_attach,
1228 &cxusb_mt352_xc3028_config,
1229 &adap->dev->i2c_adap);
1230 if ((adap->fe_adap[0].fe) != NULL)
Chris Pascoe702a6762007-11-20 03:34:11 -03001231 return 0;
1232
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001233 return -EIO;
1234}
1235
David T.L. Wong6bf1a992009-08-05 13:07:10 -03001236static struct lgs8gxx_config d680_lgs8gl5_cfg = {
1237 .prod = LGS8GXX_PROD_LGS8GL5,
Timothy Leedfbdce02008-08-09 13:36:51 -03001238 .demod_address = 0x19,
David T.L. Wong6bf1a992009-08-05 13:07:10 -03001239 .serial_ts = 0,
1240 .ts_clk_pol = 0,
1241 .ts_clk_gated = 1,
1242 .if_clk_freq = 30400, /* 30.4 MHz */
1243 .if_freq = 5725, /* 5.725 MHz */
1244 .if_neg_center = 0,
1245 .ext_adc = 0,
1246 .adc_signed = 0,
1247 .if_neg_edge = 0,
Timothy Leedfbdce02008-08-09 13:36:51 -03001248};
1249
1250static int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap)
1251{
1252 struct dvb_usb_device *d = adap->dev;
1253 int n;
1254
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));
Timothy Leedfbdce02008-08-09 13:36:51 -03001266
1267 /* Drain USB pipes to avoid hang after reboot */
1268 for (n = 0; n < 5; n++) {
1269 cxusb_d680_dmb_drain_message(d);
1270 cxusb_d680_dmb_drain_video(d);
1271 msleep(200);
1272 }
1273
1274 /* Reset the tuner */
1275 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) {
1276 err("clear tuner gpio failed");
1277 return -EIO;
1278 }
1279 msleep(100);
1280 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) {
1281 err("set tuner gpio failed");
1282 return -EIO;
1283 }
1284 msleep(100);
1285
1286 /* Attach frontend */
Michael Krufky77eed212011-09-06 09:31:57 -03001287 adap->fe_adap[0].fe = dvb_attach(lgs8gxx_attach, &d680_lgs8gl5_cfg, &d->i2c_adap);
1288 if (adap->fe_adap[0].fe == NULL)
Timothy Leedfbdce02008-08-09 13:36:51 -03001289 return -EIO;
1290
1291 return 0;
1292}
1293
David Wongb18bd1d2009-10-26 09:41:22 -03001294static struct atbm8830_config mygica_d689_atbm8830_cfg = {
1295 .prod = ATBM8830_PROD_8830,
1296 .demod_address = 0x40,
1297 .serial_ts = 0,
1298 .ts_sampling_edge = 1,
1299 .ts_clk_gated = 0,
1300 .osc_clk_freq = 30400, /* in kHz */
1301 .if_freq = 0, /* zero IF */
1302 .zif_swap_iq = 1,
David Wongc245c752009-11-28 08:36:31 -03001303 .agc_min = 0x2E,
1304 .agc_max = 0x90,
1305 .agc_hold_loop = 0,
David Wongb18bd1d2009-10-26 09:41:22 -03001306};
1307
1308static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap)
1309{
1310 struct dvb_usb_device *d = adap->dev;
David Wongb18bd1d2009-10-26 09:41:22 -03001311
1312 /* Select required USB configuration */
1313 if (usb_set_interface(d->udev, 0, 0) < 0)
1314 err("set interface failed");
1315
1316 /* Unblock all USB pipes */
1317 usb_clear_halt(d->udev,
1318 usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1319 usb_clear_halt(d->udev,
1320 usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1321 usb_clear_halt(d->udev,
Michael Krufky77eed212011-09-06 09:31:57 -03001322 usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint));
David Wongb18bd1d2009-10-26 09:41:22 -03001323
1324
1325 /* Reset the tuner */
1326 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) {
1327 err("clear tuner gpio failed");
1328 return -EIO;
1329 }
1330 msleep(100);
1331 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) {
1332 err("set tuner gpio failed");
1333 return -EIO;
1334 }
1335 msleep(100);
1336
1337 /* Attach frontend */
Michael Krufky77eed212011-09-06 09:31:57 -03001338 adap->fe_adap[0].fe = dvb_attach(atbm8830_attach, &mygica_d689_atbm8830_cfg,
David Wongb18bd1d2009-10-26 09:41:22 -03001339 &d->i2c_adap);
Michael Krufky77eed212011-09-06 09:31:57 -03001340 if (adap->fe_adap[0].fe == NULL)
David Wongb18bd1d2009-10-26 09:41:22 -03001341 return -EIO;
1342
1343 return 0;
1344}
1345
Olli Salonen26c42b02014-07-13 10:52:22 -03001346static int cxusb_tt_ct2_4400_attach(struct dvb_usb_adapter *adap)
1347{
1348 struct dvb_usb_device *d = adap->dev;
1349 struct cxusb_state *st = d->priv;
1350 struct i2c_adapter *adapter;
1351 struct i2c_client *client_demod;
1352 struct i2c_client *client_tuner;
1353 struct i2c_board_info info;
1354 struct si2168_config si2168_config;
1355 struct si2157_config si2157_config;
1356
1357 /* reset the tuner */
1358 if (cxusb_tt_ct2_4400_gpio_tuner(d, 0) < 0) {
1359 err("clear tuner gpio failed");
1360 return -EIO;
1361 }
1362 msleep(100);
1363 if (cxusb_tt_ct2_4400_gpio_tuner(d, 1) < 0) {
1364 err("set tuner gpio failed");
1365 return -EIO;
1366 }
1367 msleep(100);
1368
1369 /* attach frontend */
1370 si2168_config.i2c_adapter = &adapter;
1371 si2168_config.fe = &adap->fe_adap[0].fe;
1372 memset(&info, 0, sizeof(struct i2c_board_info));
1373 strlcpy(info.type, "si2168", I2C_NAME_SIZE);
1374 info.addr = 0x64;
1375 info.platform_data = &si2168_config;
1376 request_module(info.type);
1377 client_demod = i2c_new_device(&d->i2c_adap, &info);
1378 if (client_demod == NULL || client_demod->dev.driver == NULL)
1379 return -ENODEV;
1380
1381 if (!try_module_get(client_demod->dev.driver->owner)) {
1382 i2c_unregister_device(client_demod);
1383 return -ENODEV;
1384 }
1385
1386 st->i2c_client_demod = client_demod;
1387
1388 /* attach tuner */
Matthias Schwarzott9f7ca3d2014-07-15 16:34:34 -03001389 memset(&si2157_config, 0, sizeof(si2157_config));
Olli Salonen26c42b02014-07-13 10:52:22 -03001390 si2157_config.fe = adap->fe_adap[0].fe;
1391 memset(&info, 0, sizeof(struct i2c_board_info));
1392 strlcpy(info.type, "si2157", I2C_NAME_SIZE);
1393 info.addr = 0x60;
1394 info.platform_data = &si2157_config;
1395 request_module(info.type);
1396 client_tuner = i2c_new_device(adapter, &info);
1397 if (client_tuner == NULL || client_tuner->dev.driver == NULL) {
1398 module_put(client_demod->dev.driver->owner);
1399 i2c_unregister_device(client_demod);
1400 return -ENODEV;
1401 }
1402 if (!try_module_get(client_tuner->dev.driver->owner)) {
1403 i2c_unregister_device(client_tuner);
1404 module_put(client_demod->dev.driver->owner);
1405 i2c_unregister_device(client_demod);
1406 return -ENODEV;
1407 }
1408
1409 st->i2c_client_tuner = client_tuner;
1410
1411 return 0;
1412}
1413
Patrick Boettcherf5373782006-01-09 18:21:38 -02001414/*
Chris Pascoe702a6762007-11-20 03:34:11 -03001415 * DViCO has shipped two devices with the same USB ID, but only one of them
1416 * needs a firmware download. Check the device class details to see if they
1417 * have non-default values to decide whether the device is actually cold or
1418 * not, and forget a match if it turns out we selected the wrong device.
1419 */
1420static int bluebird_fx2_identify_state(struct usb_device *udev,
1421 struct dvb_usb_device_properties *props,
1422 struct dvb_usb_device_description **desc,
1423 int *cold)
1424{
1425 int wascold = *cold;
1426
1427 *cold = udev->descriptor.bDeviceClass == 0xff &&
1428 udev->descriptor.bDeviceSubClass == 0xff &&
1429 udev->descriptor.bDeviceProtocol == 0xff;
1430
1431 if (*cold && !wascold)
1432 *desc = NULL;
1433
1434 return 0;
1435}
1436
1437/*
Patrick Boettcherf5373782006-01-09 18:21:38 -02001438 * DViCO bluebird firmware needs the "warm" product ID to be patched into the
1439 * firmware file before download.
1440 */
1441
Chris Pascoe702a6762007-11-20 03:34:11 -03001442static const int dvico_firmware_id_offsets[] = { 6638, 3204 };
Michael Krufkyf35db232006-12-05 14:53:39 -03001443static int bluebird_patch_dvico_firmware_download(struct usb_device *udev,
1444 const struct firmware *fw)
Patrick Boettcherf5373782006-01-09 18:21:38 -02001445{
Chris Pascoe702a6762007-11-20 03:34:11 -03001446 int pos;
Patrick Boettcherf5373782006-01-09 18:21:38 -02001447
Chris Pascoe702a6762007-11-20 03:34:11 -03001448 for (pos = 0; pos < ARRAY_SIZE(dvico_firmware_id_offsets); pos++) {
1449 int idoff = dvico_firmware_id_offsets[pos];
Patrick Boettcherf5373782006-01-09 18:21:38 -02001450
Chris Pascoe702a6762007-11-20 03:34:11 -03001451 if (fw->size < idoff + 4)
1452 continue;
Patrick Boettcherf5373782006-01-09 18:21:38 -02001453
Chris Pascoe702a6762007-11-20 03:34:11 -03001454 if (fw->data[idoff] == (USB_VID_DVICO & 0xff) &&
1455 fw->data[idoff + 1] == USB_VID_DVICO >> 8) {
David Woodhousee62f89f2008-05-24 00:12:42 +01001456 struct firmware new_fw;
1457 u8 *new_fw_data = vmalloc(fw->size);
1458 int ret;
1459
1460 if (!new_fw_data)
1461 return -ENOMEM;
1462
1463 memcpy(new_fw_data, fw->data, fw->size);
1464 new_fw.size = fw->size;
1465 new_fw.data = new_fw_data;
1466
1467 new_fw_data[idoff + 2] =
Chris Pascoe702a6762007-11-20 03:34:11 -03001468 le16_to_cpu(udev->descriptor.idProduct) + 1;
David Woodhousee62f89f2008-05-24 00:12:42 +01001469 new_fw_data[idoff + 3] =
Chris Pascoe702a6762007-11-20 03:34:11 -03001470 le16_to_cpu(udev->descriptor.idProduct) >> 8;
1471
David Woodhousee62f89f2008-05-24 00:12:42 +01001472 ret = usb_cypress_load_firmware(udev, &new_fw,
1473 CYPRESS_FX2);
1474 vfree(new_fw_data);
1475 return ret;
Chris Pascoe702a6762007-11-20 03:34:11 -03001476 }
Patrick Boettcherf5373782006-01-09 18:21:38 -02001477 }
1478
1479 return -EINVAL;
1480}
1481
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001482/* DVB USB Driver stuff */
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001483static struct dvb_usb_device_properties cxusb_medion_properties;
1484static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties;
1485static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties;
1486static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties;
1487static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties;
Chris Pascoeaeb012b2007-11-19 21:57:10 -03001488static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties;
Anton Blanchard8d798982008-08-09 12:23:15 -03001489static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties;
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001490static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties;
Chris Pascoe702a6762007-11-20 03:34:11 -03001491static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties;
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03001492static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
Timothy Leedfbdce02008-08-09 13:36:51 -03001493static struct dvb_usb_device_properties cxusb_d680_dmb_properties;
David Wongb18bd1d2009-10-26 09:41:22 -03001494static struct dvb_usb_device_properties cxusb_mygica_d689_properties;
Olli Salonen26c42b02014-07-13 10:52:22 -03001495static struct dvb_usb_device_properties cxusb_tt_ct2_4400_properties;
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001496
1497static int cxusb_probe(struct usb_interface *intf,
Michael Krufkyf35db232006-12-05 14:53:39 -03001498 const struct usb_device_id *id)
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001499{
Janne Grunau78e92002008-04-09 19:13:13 -03001500 if (0 == dvb_usb_device_init(intf, &cxusb_medion_properties,
1501 THIS_MODULE, NULL, adapter_nr) ||
1502 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgh064f_properties,
1503 THIS_MODULE, NULL, adapter_nr) ||
1504 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dee1601_properties,
1505 THIS_MODULE, NULL, adapter_nr) ||
1506 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgz201_properties,
1507 THIS_MODULE, NULL, adapter_nr) ||
1508 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dtt7579_properties,
1509 THIS_MODULE, NULL, adapter_nr) ||
1510 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dualdig4_properties,
1511 THIS_MODULE, NULL, adapter_nr) ||
1512 0 == dvb_usb_device_init(intf, &cxusb_bluebird_nano2_properties,
1513 THIS_MODULE, NULL, adapter_nr) ||
1514 0 == dvb_usb_device_init(intf,
1515 &cxusb_bluebird_nano2_needsfirmware_properties,
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03001516 THIS_MODULE, NULL, adapter_nr) ||
1517 0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties,
1518 THIS_MODULE, NULL, adapter_nr) ||
Anton Blanchard8d798982008-08-09 12:23:15 -03001519 0 == dvb_usb_device_init(intf,
1520 &cxusb_bluebird_dualdig4_rev2_properties,
1521 THIS_MODULE, NULL, adapter_nr) ||
Timothy Leedfbdce02008-08-09 13:36:51 -03001522 0 == dvb_usb_device_init(intf, &cxusb_d680_dmb_properties,
1523 THIS_MODULE, NULL, adapter_nr) ||
David Wongb18bd1d2009-10-26 09:41:22 -03001524 0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties,
1525 THIS_MODULE, NULL, adapter_nr) ||
Olli Salonen26c42b02014-07-13 10:52:22 -03001526 0 == dvb_usb_device_init(intf, &cxusb_tt_ct2_4400_properties,
1527 THIS_MODULE, NULL, adapter_nr) ||
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03001528 0)
Michael Krufkyeffee032006-01-09 15:25:47 -02001529 return 0;
Michael Krufkyeffee032006-01-09 15:25:47 -02001530
1531 return -EINVAL;
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001532}
1533
Olli Salonen26c42b02014-07-13 10:52:22 -03001534static void cxusb_disconnect(struct usb_interface *intf)
1535{
1536 struct dvb_usb_device *d = usb_get_intfdata(intf);
1537 struct cxusb_state *st = d->priv;
1538 struct i2c_client *client;
1539
1540 /* remove I2C client for tuner */
1541 client = st->i2c_client_tuner;
1542 if (client) {
1543 module_put(client->dev.driver->owner);
1544 i2c_unregister_device(client);
1545 }
1546
1547 /* remove I2C client for demodulator */
1548 client = st->i2c_client_demod;
1549 if (client) {
1550 module_put(client->dev.driver->owner);
1551 i2c_unregister_device(client);
1552 }
1553
1554 dvb_usb_device_exit(intf);
1555}
1556
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001557static struct usb_device_id cxusb_table [] = {
Michael Krufkyf35db232006-12-05 14:53:39 -03001558 { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) },
1559 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) },
1560 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_WARM) },
1561 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_COLD) },
1562 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM) },
1563 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_COLD) },
1564 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_WARM) },
1565 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_COLD) },
1566 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_WARM) },
1567 { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD) },
1568 { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM) },
1569 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD) },
1570 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM) },
Chris Pascoeaeb012b2007-11-19 21:57:10 -03001571 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) },
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001572 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) },
Chris Pascoe702a6762007-11-20 03:34:11 -03001573 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) },
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03001574 { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) },
Anton Blanchard8d798982008-08-09 12:23:15 -03001575 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) },
Timothy Leedfbdce02008-08-09 13:36:51 -03001576 { USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) },
David Wongb18bd1d2009-10-26 09:41:22 -03001577 { USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) },
Olli Salonen26c42b02014-07-13 10:52:22 -03001578 { USB_DEVICE(USB_VID_TECHNOTREND, USB_PID_TECHNOTREND_TVSTICK_CT2_4400) },
Michael Krufkyf35db232006-12-05 14:53:39 -03001579 {} /* Terminating entry */
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001580};
1581MODULE_DEVICE_TABLE (usb, cxusb_table);
1582
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001583static struct dvb_usb_device_properties cxusb_medion_properties = {
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001584 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1585
1586 .usb_ctrl = CYPRESS_FX2,
1587
1588 .size_of_priv = sizeof(struct cxusb_state),
1589
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001590 .num_adapters = 1,
1591 .adapter = {
1592 {
Michael Krufky77eed212011-09-06 09:31:57 -03001593 .num_frontends = 1,
1594 .fe = {{
Patrick Boettcher01451e72006-10-13 11:34:46 -03001595 .streaming_ctrl = cxusb_streaming_ctrl,
1596 .frontend_attach = cxusb_cx22702_frontend_attach,
1597 .tuner_attach = cxusb_fmd1216me_tuner_attach,
1598 /* parameter for the MPEG2-data transfer */
1599 .stream = {
1600 .type = USB_BULK,
1601 .count = 5,
1602 .endpoint = 0x02,
1603 .u = {
1604 .bulk = {
1605 .buffersize = 8192,
1606 }
1607 }
1608 },
Michael Krufky77eed212011-09-06 09:31:57 -03001609 }},
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001610 },
1611 },
1612 .power_ctrl = cxusb_power_ctrl,
1613
1614 .i2c_algo = &cxusb_i2c_algo,
1615
1616 .generic_bulk_ctrl_endpoint = 0x01,
1617
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001618 .num_device_descs = 1,
1619 .devices = {
1620 { "Medion MD95700 (MDUSBTV-HYBRID)",
1621 { NULL },
1622 { &cxusb_table[0], NULL },
1623 },
1624 }
1625};
1626
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001627static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = {
Michael Krufkyeffee032006-01-09 15:25:47 -02001628 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1629
Patrick Boettcherf5373782006-01-09 18:21:38 -02001630 .usb_ctrl = DEVICE_SPECIFIC,
1631 .firmware = "dvb-usb-bluebird-01.fw",
1632 .download_firmware = bluebird_patch_dvico_firmware_download,
Michael Krufky37bdfa02006-01-09 15:25:47 -02001633 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1634 use usb alt setting 7 for EP2 transfer (atsc) */
Michael Krufkyeffee032006-01-09 15:25:47 -02001635
1636 .size_of_priv = sizeof(struct cxusb_state),
1637
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001638 .num_adapters = 1,
1639 .adapter = {
1640 {
Michael Krufky77eed212011-09-06 09:31:57 -03001641 .num_frontends = 1,
1642 .fe = {{
Patrick Boettcher01451e72006-10-13 11:34:46 -03001643 .streaming_ctrl = cxusb_streaming_ctrl,
1644 .frontend_attach = cxusb_lgdt3303_frontend_attach,
Michael Krufkyf71a56c2006-10-13 21:55:57 -03001645 .tuner_attach = cxusb_lgh064f_tuner_attach,
Michael Krufkyeffee032006-01-09 15:25:47 -02001646
Patrick Boettcher01451e72006-10-13 11:34:46 -03001647 /* parameter for the MPEG2-data transfer */
1648 .stream = {
1649 .type = USB_BULK,
1650 .count = 5,
1651 .endpoint = 0x02,
1652 .u = {
1653 .bulk = {
1654 .buffersize = 8192,
1655 }
1656 }
1657 },
Michael Krufky77eed212011-09-06 09:31:57 -03001658 }},
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001659 },
1660 },
1661
1662 .power_ctrl = cxusb_bluebird_power_ctrl,
1663
Michael Krufkyeffee032006-01-09 15:25:47 -02001664 .i2c_algo = &cxusb_i2c_algo,
1665
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001666 .rc.legacy = {
1667 .rc_interval = 100,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03001668 .rc_map_table = rc_map_dvico_portable_table,
1669 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001670 .rc_query = cxusb_rc_query,
1671 },
Michael Krufkyc1501782006-03-26 05:43:36 -03001672
Michael Krufkyeffee032006-01-09 15:25:47 -02001673 .generic_bulk_ctrl_endpoint = 0x01,
Michael Krufkyeffee032006-01-09 15:25:47 -02001674
1675 .num_device_descs = 1,
1676 .devices = {
1677 { "DViCO FusionHDTV5 USB Gold",
1678 { &cxusb_table[1], NULL },
1679 { &cxusb_table[2], NULL },
1680 },
1681 }
1682};
1683
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001684static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = {
Chris Pascoe0029ee12006-01-09 18:21:28 -02001685 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1686
Patrick Boettcherf5373782006-01-09 18:21:38 -02001687 .usb_ctrl = DEVICE_SPECIFIC,
1688 .firmware = "dvb-usb-bluebird-01.fw",
1689 .download_firmware = bluebird_patch_dvico_firmware_download,
Chris Pascoe0029ee12006-01-09 18:21:28 -02001690 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1691 use usb alt setting 7 for EP2 transfer (atsc) */
1692
1693 .size_of_priv = sizeof(struct cxusb_state),
1694
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001695 .num_adapters = 1,
1696 .adapter = {
1697 {
Michael Krufky77eed212011-09-06 09:31:57 -03001698 .num_frontends = 1,
1699 .fe = {{
Patrick Boettcher01451e72006-10-13 11:34:46 -03001700 .streaming_ctrl = cxusb_streaming_ctrl,
1701 .frontend_attach = cxusb_dee1601_frontend_attach,
1702 .tuner_attach = cxusb_dee1601_tuner_attach,
1703 /* parameter for the MPEG2-data transfer */
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001704 .stream = {
1705 .type = USB_BULK,
Patrick Boettcher01451e72006-10-13 11:34:46 -03001706 .count = 5,
1707 .endpoint = 0x04,
1708 .u = {
1709 .bulk = {
1710 .buffersize = 8192,
1711 }
1712 }
1713 },
Michael Krufky77eed212011-09-06 09:31:57 -03001714 }},
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001715 },
1716 },
1717
1718 .power_ctrl = cxusb_bluebird_power_ctrl,
Chris Pascoe0029ee12006-01-09 18:21:28 -02001719
1720 .i2c_algo = &cxusb_i2c_algo,
1721
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001722 .rc.legacy = {
1723 .rc_interval = 150,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03001724 .rc_map_table = rc_map_dvico_mce_table,
1725 .rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001726 .rc_query = cxusb_rc_query,
1727 },
Chris Pascoe7c239702006-01-09 18:21:29 -02001728
Chris Pascoe0029ee12006-01-09 18:21:28 -02001729 .generic_bulk_ctrl_endpoint = 0x01,
Chris Pascoe0029ee12006-01-09 18:21:28 -02001730
Michael Krufky587c03d2006-09-28 02:16:01 -03001731 .num_device_descs = 3,
Chris Pascoe0029ee12006-01-09 18:21:28 -02001732 .devices = {
1733 { "DViCO FusionHDTV DVB-T Dual USB",
1734 { &cxusb_table[3], NULL },
1735 { &cxusb_table[4], NULL },
1736 },
Michael Krufkyac9ffb92006-01-11 23:21:00 -02001737 { "DigitalNow DVB-T Dual USB",
1738 { &cxusb_table[9], NULL },
1739 { &cxusb_table[10], NULL },
1740 },
Michael Krufky587c03d2006-09-28 02:16:01 -03001741 { "DViCO FusionHDTV DVB-T Dual Digital 2",
1742 { &cxusb_table[11], NULL },
1743 { &cxusb_table[12], NULL },
1744 },
Chris Pascoe0029ee12006-01-09 18:21:28 -02001745 }
1746};
1747
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001748static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = {
Michael Krufky6f447252006-01-11 19:40:33 -02001749 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1750
1751 .usb_ctrl = DEVICE_SPECIFIC,
1752 .firmware = "dvb-usb-bluebird-01.fw",
1753 .download_firmware = bluebird_patch_dvico_firmware_download,
1754 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1755 use usb alt setting 7 for EP2 transfer (atsc) */
1756
1757 .size_of_priv = sizeof(struct cxusb_state),
1758
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001759 .num_adapters = 2,
1760 .adapter = {
1761 {
Michael Krufky77eed212011-09-06 09:31:57 -03001762 .num_frontends = 1,
1763 .fe = {{
Patrick Boettcher01451e72006-10-13 11:34:46 -03001764 .streaming_ctrl = cxusb_streaming_ctrl,
1765 .frontend_attach = cxusb_mt352_frontend_attach,
1766 .tuner_attach = cxusb_lgz201_tuner_attach,
Michael Krufky6f447252006-01-11 19:40:33 -02001767
Patrick Boettcher01451e72006-10-13 11:34:46 -03001768 /* parameter for the MPEG2-data transfer */
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001769 .stream = {
1770 .type = USB_BULK,
Patrick Boettcher01451e72006-10-13 11:34:46 -03001771 .count = 5,
1772 .endpoint = 0x04,
1773 .u = {
1774 .bulk = {
1775 .buffersize = 8192,
1776 }
1777 }
1778 },
Michael Krufky77eed212011-09-06 09:31:57 -03001779 }},
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001780 },
1781 },
1782 .power_ctrl = cxusb_bluebird_power_ctrl,
1783
Michael Krufky6f447252006-01-11 19:40:33 -02001784 .i2c_algo = &cxusb_i2c_algo,
1785
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001786 .rc.legacy = {
1787 .rc_interval = 100,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03001788 .rc_map_table = rc_map_dvico_portable_table,
1789 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001790 .rc_query = cxusb_rc_query,
1791 },
Michael Krufkyc1501782006-03-26 05:43:36 -03001792
Michael Krufky6f447252006-01-11 19:40:33 -02001793 .generic_bulk_ctrl_endpoint = 0x01,
Michael Krufky6f447252006-01-11 19:40:33 -02001794 .num_device_descs = 1,
1795 .devices = {
1796 { "DViCO FusionHDTV DVB-T USB (LGZ201)",
1797 { &cxusb_table[5], NULL },
1798 { &cxusb_table[6], NULL },
1799 },
1800 }
1801};
1802
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001803static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = {
Michael Krufky6f447252006-01-11 19:40:33 -02001804 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1805
1806 .usb_ctrl = DEVICE_SPECIFIC,
1807 .firmware = "dvb-usb-bluebird-01.fw",
1808 .download_firmware = bluebird_patch_dvico_firmware_download,
1809 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1810 use usb alt setting 7 for EP2 transfer (atsc) */
1811
1812 .size_of_priv = sizeof(struct cxusb_state),
1813
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001814 .num_adapters = 1,
1815 .adapter = {
1816 {
Michael Krufky77eed212011-09-06 09:31:57 -03001817 .num_frontends = 1,
1818 .fe = {{
Patrick Boettcher01451e72006-10-13 11:34:46 -03001819 .streaming_ctrl = cxusb_streaming_ctrl,
1820 .frontend_attach = cxusb_mt352_frontend_attach,
1821 .tuner_attach = cxusb_dtt7579_tuner_attach,
Michael Krufky6f447252006-01-11 19:40:33 -02001822
Patrick Boettcher01451e72006-10-13 11:34:46 -03001823 /* parameter for the MPEG2-data transfer */
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001824 .stream = {
1825 .type = USB_BULK,
Patrick Boettcher01451e72006-10-13 11:34:46 -03001826 .count = 5,
1827 .endpoint = 0x04,
1828 .u = {
1829 .bulk = {
1830 .buffersize = 8192,
1831 }
1832 }
1833 },
Michael Krufky77eed212011-09-06 09:31:57 -03001834 }},
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001835 },
1836 },
1837 .power_ctrl = cxusb_bluebird_power_ctrl,
1838
Michael Krufky6f447252006-01-11 19:40:33 -02001839 .i2c_algo = &cxusb_i2c_algo,
1840
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001841 .rc.legacy = {
1842 .rc_interval = 100,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03001843 .rc_map_table = rc_map_dvico_portable_table,
1844 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001845 .rc_query = cxusb_rc_query,
1846 },
Michael Krufkyc1501782006-03-26 05:43:36 -03001847
Michael Krufky6f447252006-01-11 19:40:33 -02001848 .generic_bulk_ctrl_endpoint = 0x01,
Michael Krufky6f447252006-01-11 19:40:33 -02001849
1850 .num_device_descs = 1,
1851 .devices = {
1852 { "DViCO FusionHDTV DVB-T USB (TH7579)",
1853 { &cxusb_table[7], NULL },
1854 { &cxusb_table[8], NULL },
1855 },
1856 }
1857};
1858
Chris Pascoeaeb012b2007-11-19 21:57:10 -03001859static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = {
1860 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1861
1862 .usb_ctrl = CYPRESS_FX2,
1863
1864 .size_of_priv = sizeof(struct cxusb_state),
1865
1866 .num_adapters = 1,
1867 .adapter = {
1868 {
Michael Krufky77eed212011-09-06 09:31:57 -03001869 .num_frontends = 1,
1870 .fe = {{
Chris Pascoeaeb012b2007-11-19 21:57:10 -03001871 .streaming_ctrl = cxusb_streaming_ctrl,
1872 .frontend_attach = cxusb_dualdig4_frontend_attach,
1873 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1874 /* parameter for the MPEG2-data transfer */
1875 .stream = {
1876 .type = USB_BULK,
1877 .count = 5,
1878 .endpoint = 0x02,
1879 .u = {
1880 .bulk = {
1881 .buffersize = 8192,
1882 }
1883 }
1884 },
Michael Krufky77eed212011-09-06 09:31:57 -03001885 }},
Chris Pascoeaeb012b2007-11-19 21:57:10 -03001886 },
1887 },
1888
1889 .power_ctrl = cxusb_power_ctrl,
1890
1891 .i2c_algo = &cxusb_i2c_algo,
1892
1893 .generic_bulk_ctrl_endpoint = 0x01,
1894
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001895 .rc.legacy = {
1896 .rc_interval = 100,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03001897 .rc_map_table = rc_map_dvico_mce_table,
1898 .rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001899 .rc_query = cxusb_bluebird2_rc_query,
1900 },
Chris Pascoeaeb012b2007-11-19 21:57:10 -03001901
1902 .num_device_descs = 1,
1903 .devices = {
1904 { "DViCO FusionHDTV DVB-T Dual Digital 4",
1905 { NULL },
1906 { &cxusb_table[13], NULL },
1907 },
1908 }
1909};
1910
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001911static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = {
1912 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1913
1914 .usb_ctrl = CYPRESS_FX2,
Chris Pascoe702a6762007-11-20 03:34:11 -03001915 .identify_state = bluebird_fx2_identify_state,
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001916
1917 .size_of_priv = sizeof(struct cxusb_state),
1918
1919 .num_adapters = 1,
1920 .adapter = {
1921 {
Michael Krufky77eed212011-09-06 09:31:57 -03001922 .num_frontends = 1,
1923 .fe = {{
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001924 .streaming_ctrl = cxusb_streaming_ctrl,
1925 .frontend_attach = cxusb_nano2_frontend_attach,
1926 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1927 /* parameter for the MPEG2-data transfer */
1928 .stream = {
1929 .type = USB_BULK,
1930 .count = 5,
1931 .endpoint = 0x02,
1932 .u = {
1933 .bulk = {
1934 .buffersize = 8192,
1935 }
1936 }
1937 },
Michael Krufky77eed212011-09-06 09:31:57 -03001938 }},
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001939 },
1940 },
1941
1942 .power_ctrl = cxusb_nano2_power_ctrl,
1943
1944 .i2c_algo = &cxusb_i2c_algo,
1945
1946 .generic_bulk_ctrl_endpoint = 0x01,
1947
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001948 .rc.legacy = {
1949 .rc_interval = 100,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03001950 .rc_map_table = rc_map_dvico_portable_table,
1951 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001952 .rc_query = cxusb_bluebird2_rc_query,
1953 },
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001954
1955 .num_device_descs = 1,
1956 .devices = {
1957 { "DViCO FusionHDTV DVB-T NANO2",
1958 { NULL },
1959 { &cxusb_table[14], NULL },
1960 },
1961 }
1962};
1963
Chris Pascoe702a6762007-11-20 03:34:11 -03001964static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties = {
1965 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1966
1967 .usb_ctrl = DEVICE_SPECIFIC,
1968 .firmware = "dvb-usb-bluebird-02.fw",
1969 .download_firmware = bluebird_patch_dvico_firmware_download,
1970 .identify_state = bluebird_fx2_identify_state,
1971
1972 .size_of_priv = sizeof(struct cxusb_state),
1973
1974 .num_adapters = 1,
1975 .adapter = {
1976 {
Michael Krufky77eed212011-09-06 09:31:57 -03001977 .num_frontends = 1,
1978 .fe = {{
Chris Pascoe702a6762007-11-20 03:34:11 -03001979 .streaming_ctrl = cxusb_streaming_ctrl,
1980 .frontend_attach = cxusb_nano2_frontend_attach,
1981 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1982 /* parameter for the MPEG2-data transfer */
1983 .stream = {
1984 .type = USB_BULK,
1985 .count = 5,
1986 .endpoint = 0x02,
1987 .u = {
1988 .bulk = {
1989 .buffersize = 8192,
1990 }
1991 }
1992 },
Michael Krufky77eed212011-09-06 09:31:57 -03001993 }},
Chris Pascoe702a6762007-11-20 03:34:11 -03001994 },
1995 },
1996
1997 .power_ctrl = cxusb_nano2_power_ctrl,
1998
1999 .i2c_algo = &cxusb_i2c_algo,
2000
2001 .generic_bulk_ctrl_endpoint = 0x01,
2002
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03002003 .rc.legacy = {
2004 .rc_interval = 100,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03002005 .rc_map_table = rc_map_dvico_portable_table,
2006 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03002007 .rc_query = cxusb_rc_query,
2008 },
Chris Pascoe702a6762007-11-20 03:34:11 -03002009
2010 .num_device_descs = 1,
2011 .devices = {
2012 { "DViCO FusionHDTV DVB-T NANO2 w/o firmware",
2013 { &cxusb_table[14], NULL },
2014 { &cxusb_table[15], NULL },
2015 },
2016 }
2017};
2018
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03002019static struct dvb_usb_device_properties cxusb_aver_a868r_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 = {{
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03002031 .streaming_ctrl = cxusb_aver_streaming_ctrl,
2032 .frontend_attach = cxusb_aver_lgdt3303_frontend_attach,
2033 .tuner_attach = cxusb_mxl5003s_tuner_attach,
2034 /* parameter for the MPEG2-data transfer */
2035 .stream = {
2036 .type = USB_BULK,
2037 .count = 5,
2038 .endpoint = 0x04,
2039 .u = {
2040 .bulk = {
2041 .buffersize = 8192,
2042 }
2043 }
2044 },
Michael Krufky77eed212011-09-06 09:31:57 -03002045 }},
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03002046 },
2047 },
2048 .power_ctrl = cxusb_aver_power_ctrl,
2049
2050 .i2c_algo = &cxusb_i2c_algo,
2051
2052 .generic_bulk_ctrl_endpoint = 0x01,
2053
2054 .num_device_descs = 1,
2055 .devices = {
2056 { "AVerMedia AVerTVHD Volar (A868R)",
2057 { NULL },
2058 { &cxusb_table[16], NULL },
2059 },
2060 }
2061};
2062
Michael Krufkya2dc86b2008-08-09 13:06:26 -03002063static
2064struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = {
Anton Blanchard8d798982008-08-09 12:23:15 -03002065 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
2066
2067 .usb_ctrl = CYPRESS_FX2,
2068
2069 .size_of_priv = sizeof(struct cxusb_state),
2070
2071 .num_adapters = 1,
2072 .adapter = {
2073 {
Michael Krufky77eed212011-09-06 09:31:57 -03002074 .size_of_priv = sizeof(struct dib0700_adapter_state),
2075 .num_frontends = 1,
2076 .fe = {{
Michael Krufkya2dc86b2008-08-09 13:06:26 -03002077 .streaming_ctrl = cxusb_streaming_ctrl,
2078 .frontend_attach = cxusb_dualdig4_rev2_frontend_attach,
2079 .tuner_attach = cxusb_dualdig4_rev2_tuner_attach,
Anton Blanchard8d798982008-08-09 12:23:15 -03002080 /* parameter for the MPEG2-data transfer */
2081 .stream = {
2082 .type = USB_BULK,
2083 .count = 7,
2084 .endpoint = 0x02,
2085 .u = {
2086 .bulk = {
2087 .buffersize = 4096,
2088 }
2089 }
2090 },
Michael Krufky77eed212011-09-06 09:31:57 -03002091 }},
Anton Blanchard8d798982008-08-09 12:23:15 -03002092 },
2093 },
2094
2095 .power_ctrl = cxusb_bluebird_power_ctrl,
2096
2097 .i2c_algo = &cxusb_i2c_algo,
2098
2099 .generic_bulk_ctrl_endpoint = 0x01,
2100
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03002101 .rc.legacy = {
2102 .rc_interval = 100,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03002103 .rc_map_table = rc_map_dvico_mce_table,
2104 .rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03002105 .rc_query = cxusb_rc_query,
2106 },
Anton Blanchard8d798982008-08-09 12:23:15 -03002107
2108 .num_device_descs = 1,
2109 .devices = {
2110 { "DViCO FusionHDTV DVB-T Dual Digital 4 (rev 2)",
2111 { NULL },
2112 { &cxusb_table[17], NULL },
2113 },
2114 }
2115};
2116
Timothy Leedfbdce02008-08-09 13:36:51 -03002117static struct dvb_usb_device_properties cxusb_d680_dmb_properties = {
2118 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
2119
2120 .usb_ctrl = CYPRESS_FX2,
2121
2122 .size_of_priv = sizeof(struct cxusb_state),
2123
2124 .num_adapters = 1,
2125 .adapter = {
2126 {
Michael Krufky77eed212011-09-06 09:31:57 -03002127 .num_frontends = 1,
2128 .fe = {{
Timothy Leedfbdce02008-08-09 13:36:51 -03002129 .streaming_ctrl = cxusb_d680_dmb_streaming_ctrl,
2130 .frontend_attach = cxusb_d680_dmb_frontend_attach,
2131 .tuner_attach = cxusb_d680_dmb_tuner_attach,
2132
2133 /* parameter for the MPEG2-data transfer */
2134 .stream = {
2135 .type = USB_BULK,
2136 .count = 5,
2137 .endpoint = 0x02,
2138 .u = {
2139 .bulk = {
2140 .buffersize = 8192,
2141 }
2142 }
2143 },
Michael Krufky77eed212011-09-06 09:31:57 -03002144 }},
Timothy Leedfbdce02008-08-09 13:36:51 -03002145 },
2146 },
2147
2148 .power_ctrl = cxusb_d680_dmb_power_ctrl,
2149
2150 .i2c_algo = &cxusb_i2c_algo,
2151
2152 .generic_bulk_ctrl_endpoint = 0x01,
2153
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03002154 .rc.legacy = {
2155 .rc_interval = 100,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03002156 .rc_map_table = rc_map_d680_dmb_table,
2157 .rc_map_size = ARRAY_SIZE(rc_map_d680_dmb_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03002158 .rc_query = cxusb_d680_dmb_rc_query,
2159 },
Timothy Leedfbdce02008-08-09 13:36:51 -03002160
2161 .num_device_descs = 1,
2162 .devices = {
2163 {
2164 "Conexant DMB-TH Stick",
2165 { NULL },
2166 { &cxusb_table[18], NULL },
2167 },
2168 }
2169};
2170
David Wongb18bd1d2009-10-26 09:41:22 -03002171static struct dvb_usb_device_properties cxusb_mygica_d689_properties = {
2172 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
2173
2174 .usb_ctrl = CYPRESS_FX2,
2175
2176 .size_of_priv = sizeof(struct cxusb_state),
2177
2178 .num_adapters = 1,
2179 .adapter = {
2180 {
Michael Krufky77eed212011-09-06 09:31:57 -03002181 .num_frontends = 1,
2182 .fe = {{
David Wongb18bd1d2009-10-26 09:41:22 -03002183 .streaming_ctrl = cxusb_d680_dmb_streaming_ctrl,
2184 .frontend_attach = cxusb_mygica_d689_frontend_attach,
2185 .tuner_attach = cxusb_mygica_d689_tuner_attach,
2186
2187 /* parameter for the MPEG2-data transfer */
2188 .stream = {
2189 .type = USB_BULK,
2190 .count = 5,
2191 .endpoint = 0x02,
2192 .u = {
2193 .bulk = {
2194 .buffersize = 8192,
2195 }
2196 }
2197 },
Michael Krufky77eed212011-09-06 09:31:57 -03002198 }},
David Wongb18bd1d2009-10-26 09:41:22 -03002199 },
2200 },
2201
2202 .power_ctrl = cxusb_d680_dmb_power_ctrl,
2203
2204 .i2c_algo = &cxusb_i2c_algo,
2205
2206 .generic_bulk_ctrl_endpoint = 0x01,
2207
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03002208 .rc.legacy = {
2209 .rc_interval = 100,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03002210 .rc_map_table = rc_map_d680_dmb_table,
2211 .rc_map_size = ARRAY_SIZE(rc_map_d680_dmb_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03002212 .rc_query = cxusb_d680_dmb_rc_query,
2213 },
David Wongb18bd1d2009-10-26 09:41:22 -03002214
2215 .num_device_descs = 1,
2216 .devices = {
2217 {
2218 "Mygica D689 DMB-TH",
2219 { NULL },
2220 { &cxusb_table[19], NULL },
2221 },
2222 }
2223};
2224
Olli Salonen26c42b02014-07-13 10:52:22 -03002225static struct dvb_usb_device_properties cxusb_tt_ct2_4400_properties = {
2226 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
2227
2228 .usb_ctrl = CYPRESS_FX2,
2229
2230 .size_of_priv = sizeof(struct cxusb_state),
2231
2232 .num_adapters = 1,
2233 .adapter = {
2234 {
2235 .num_frontends = 1,
2236 .fe = {{
2237 .streaming_ctrl = cxusb_streaming_ctrl,
2238 /* both frontend and tuner attached in the
2239 same function */
2240 .frontend_attach = cxusb_tt_ct2_4400_attach,
2241
2242 /* parameter for the MPEG2-data transfer */
2243 .stream = {
2244 .type = USB_BULK,
2245 .count = 8,
2246 .endpoint = 0x82,
2247 .u = {
2248 .bulk = {
2249 .buffersize = 4096,
2250 }
2251 }
2252 },
2253 } },
2254 },
2255 },
2256
2257 .i2c_algo = &cxusb_i2c_algo,
2258 .generic_bulk_ctrl_endpoint = 0x01,
2259 .generic_bulk_ctrl_endpoint_response = 0x81,
2260
2261 .rc.core = {
2262 .rc_codes = RC_MAP_TT_1500,
2263 .allowed_protos = RC_BIT_RC5,
2264 .rc_query = cxusb_tt_ct2_4400_rc_query,
2265 .rc_interval = 150,
2266 },
2267
2268 .num_device_descs = 1,
2269 .devices = {
2270 {
2271 "TechnoTrend TVStick CT2-4400",
2272 { NULL },
2273 { &cxusb_table[20], NULL },
2274 },
2275 }
2276};
2277
Patrick Boettcher22c6d932005-07-07 17:58:10 -07002278static struct usb_driver cxusb_driver = {
Patrick Boettcher63b5c1c2005-07-07 17:58:30 -07002279 .name = "dvb_usb_cxusb",
Patrick Boettcher22c6d932005-07-07 17:58:10 -07002280 .probe = cxusb_probe,
Olli Salonen26c42b02014-07-13 10:52:22 -03002281 .disconnect = cxusb_disconnect,
Patrick Boettcher22c6d932005-07-07 17:58:10 -07002282 .id_table = cxusb_table,
2283};
2284
Greg Kroah-Hartmanecb3b2b2011-11-18 09:46:12 -08002285module_usb_driver(cxusb_driver);
Patrick Boettcher22c6d932005-07-07 17:58:10 -07002286
2287MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
Michael Krufky5b9ed282006-10-15 14:51:08 -03002288MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
Michael Krufkyf4efb4d2006-01-13 14:10:25 -02002289MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
Patrick Boettcher22c6d932005-07-07 17:58:10 -07002290MODULE_DESCRIPTION("Driver for Conexant USB2.0 hybrid reference design");
2291MODULE_VERSION("1.0-alpha");
2292MODULE_LICENSE("GPL");