blob: 39772812269dc81845d85954d1c52f2f3cc429e0 [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 Boettcher99e44da2016-01-24 12:56:58 -020016 * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@posteo.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
48/* debug */
Adrian Bunk53133af2007-11-05 14:07:06 -030049static int dvb_usb_cxusb_debug;
Michael Krufkyf35db232006-12-05 14:53:39 -030050module_param_named(debug, dvb_usb_cxusb_debug, int, 0644);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070051MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
Janne Grunau78e92002008-04-09 19:13:13 -030052
53DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
54
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -030055#define deb_info(args...) dprintk(dvb_usb_cxusb_debug, 0x03, args)
56#define deb_i2c(args...) dprintk(dvb_usb_cxusb_debug, 0x02, args)
Patrick Boettcher22c6d932005-07-07 17:58:10 -070057
58static int cxusb_ctrl_msg(struct dvb_usb_device *d,
Michael Krufkyf35db232006-12-05 14:53:39 -030059 u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
Patrick Boettcher22c6d932005-07-07 17:58:10 -070060{
Mauro Carvalho Chehab17ce0392016-10-07 06:30:27 -030061 struct cxusb_state *st = d->priv;
62 int ret, wo;
Mauro Carvalho Chehab64f7ef82013-11-02 07:18:09 -030063
Mauro Carvalho Chehab17ce0392016-10-07 06:30:27 -030064 if (1 + wlen > MAX_XFER_SIZE) {
65 warn("i2c wr: len=%d is too big!\n", wlen);
Mauro Carvalho Chehab64f7ef82013-11-02 07:18:09 -030066 return -EOPNOTSUPP;
67 }
68
Mauro Carvalho Chehab17ce0392016-10-07 06:30:27 -030069 wo = (rbuf == NULL || rlen == 0); /* write-only */
Patrick Boettcher22c6d932005-07-07 17:58:10 -070070
Mauro Carvalho Chehab17ce0392016-10-07 06:30:27 -030071 mutex_lock(&st->data_mutex);
72 st->data[0] = cmd;
73 memcpy(&st->data[1], wbuf, wlen);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070074 if (wo)
Mauro Carvalho Chehab17ce0392016-10-07 06:30:27 -030075 ret = dvb_usb_generic_write(d, st->data, 1 + wlen);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070076 else
Mauro Carvalho Chehab17ce0392016-10-07 06:30:27 -030077 ret = dvb_usb_generic_rw(d, st->data, 1 + wlen,
78 rbuf, rlen, 0);
79
80 mutex_unlock(&st->data_mutex);
81 return ret;
Patrick Boettcher22c6d932005-07-07 17:58:10 -070082}
83
Patrick Boettchere2efeab2005-09-09 13:02:51 -070084/* GPIO */
85static void cxusb_gpio_tuner(struct dvb_usb_device *d, int onoff)
Patrick Boettcher22c6d932005-07-07 17:58:10 -070086{
87 struct cxusb_state *st = d->priv;
Michael Krufkyf35db232006-12-05 14:53:39 -030088 u8 o[2], i;
Patrick Boettcher22c6d932005-07-07 17:58:10 -070089
Patrick Boettchere2efeab2005-09-09 13:02:51 -070090 if (st->gpio_write_state[GPIO_TUNER] == onoff)
Patrick Boettcher22c6d932005-07-07 17:58:10 -070091 return;
92
Patrick Boettchere2efeab2005-09-09 13:02:51 -070093 o[0] = GPIO_TUNER;
94 o[1] = onoff;
Michael Krufkyf35db232006-12-05 14:53:39 -030095 cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
Patrick Boettcher22c6d932005-07-07 17:58:10 -070096
97 if (i != 0x01)
Patrick Boettchere2efeab2005-09-09 13:02:51 -070098 deb_info("gpio_write failed.\n");
Patrick Boettcher22c6d932005-07-07 17:58:10 -070099
Patrick Boettchere2efeab2005-09-09 13:02:51 -0700100 st->gpio_write_state[GPIO_TUNER] = onoff;
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700101}
102
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300103static int cxusb_bluebird_gpio_rw(struct dvb_usb_device *d, u8 changemask,
104 u8 newval)
105{
106 u8 o[2], gpio_state;
107 int rc;
108
109 o[0] = 0xff & ~changemask; /* mask of bits to keep */
110 o[1] = newval & changemask; /* new values for bits */
111
112 rc = cxusb_ctrl_msg(d, CMD_BLUEBIRD_GPIO_RW, o, 2, &gpio_state, 1);
113 if (rc < 0 || (gpio_state & changemask) != (newval & changemask))
114 deb_info("bluebird_gpio_write failed.\n");
115
116 return rc < 0 ? rc : gpio_state;
117}
118
119static void cxusb_bluebird_gpio_pulse(struct dvb_usb_device *d, u8 pin, int low)
120{
121 cxusb_bluebird_gpio_rw(d, pin, low ? 0 : pin);
122 msleep(5);
123 cxusb_bluebird_gpio_rw(d, pin, low ? pin : 0);
124}
125
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300126static void cxusb_nano2_led(struct dvb_usb_device *d, int onoff)
127{
128 cxusb_bluebird_gpio_rw(d, 0x40, onoff ? 0 : 0x40);
129}
130
Timothy Leedfbdce02008-08-09 13:36:51 -0300131static int cxusb_d680_dmb_gpio_tuner(struct dvb_usb_device *d,
132 u8 addr, int onoff)
133{
134 u8 o[2] = {addr, onoff};
135 u8 i;
136 int rc;
137
138 rc = cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
139
140 if (rc < 0)
141 return rc;
142 if (i == 0x01)
143 return 0;
144 else {
145 deb_info("gpio_write failed.\n");
146 return -EIO;
147 }
148}
149
Patrick Boettchere2efeab2005-09-09 13:02:51 -0700150/* I2C */
Michael Krufkyf35db232006-12-05 14:53:39 -0300151static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
152 int num)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700153{
154 struct dvb_usb_device *d = i2c_get_adapdata(adap);
Dan Carpenter1cdbcc52013-11-22 04:55:43 -0300155 int ret;
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700156 int i;
157
Ingo Molnar3593cab2006-02-07 06:49:14 -0200158 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700159 return -EAGAIN;
160
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700161 for (i = 0; i < num; i++) {
162
Hans Verkuil41150cb2014-08-21 11:55:00 -0300163 if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_MEDION)
Michael Krufky5e805ef2006-03-23 00:01:34 -0300164 switch (msg[i].addr) {
Michael Krufkyf35db232006-12-05 14:53:39 -0300165 case 0x63:
166 cxusb_gpio_tuner(d, 0);
167 break;
168 default:
169 cxusb_gpio_tuner(d, 1);
170 break;
Michael Krufky5e805ef2006-03-23 00:01:34 -0300171 }
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700172
Chris Pascoe272479d72007-11-19 03:01:22 -0300173 if (msg[i].flags & I2C_M_RD) {
174 /* read only */
Mauro Carvalho Chehab64f7ef82013-11-02 07:18:09 -0300175 u8 obuf[3], ibuf[MAX_XFER_SIZE];
176
177 if (1 + msg[i].len > sizeof(ibuf)) {
178 warn("i2c rd: len=%d is too big!\n",
179 msg[i].len);
Dan Carpenter1cdbcc52013-11-22 04:55:43 -0300180 ret = -EOPNOTSUPP;
181 goto unlock;
Mauro Carvalho Chehab64f7ef82013-11-02 07:18:09 -0300182 }
Chris Pascoe272479d72007-11-19 03:01:22 -0300183 obuf[0] = 0;
184 obuf[1] = msg[i].len;
185 obuf[2] = msg[i].addr;
186 if (cxusb_ctrl_msg(d, CMD_I2C_READ,
187 obuf, 3,
188 ibuf, 1+msg[i].len) < 0) {
189 warn("i2c read failed");
190 break;
191 }
192 memcpy(msg[i].buf, &ibuf[1], msg[i].len);
Chris Pascoea644e4a2007-11-19 03:05:09 -0300193 } else if (i+1 < num && (msg[i+1].flags & I2C_M_RD) &&
194 msg[i].addr == msg[i+1].addr) {
195 /* write to then read from same address */
Mauro Carvalho Chehab64f7ef82013-11-02 07:18:09 -0300196 u8 obuf[MAX_XFER_SIZE], ibuf[MAX_XFER_SIZE];
197
198 if (3 + msg[i].len > sizeof(obuf)) {
199 warn("i2c wr: len=%d is too big!\n",
200 msg[i].len);
Dan Carpenter1cdbcc52013-11-22 04:55:43 -0300201 ret = -EOPNOTSUPP;
202 goto unlock;
Mauro Carvalho Chehab64f7ef82013-11-02 07:18:09 -0300203 }
204 if (1 + msg[i + 1].len > sizeof(ibuf)) {
205 warn("i2c rd: len=%d is too big!\n",
206 msg[i + 1].len);
Dan Carpenter1cdbcc52013-11-22 04:55:43 -0300207 ret = -EOPNOTSUPP;
208 goto unlock;
Mauro Carvalho Chehab64f7ef82013-11-02 07:18:09 -0300209 }
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700210 obuf[0] = msg[i].len;
211 obuf[1] = msg[i+1].len;
212 obuf[2] = msg[i].addr;
Michael Krufkyf35db232006-12-05 14:53:39 -0300213 memcpy(&obuf[3], msg[i].buf, msg[i].len);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700214
215 if (cxusb_ctrl_msg(d, CMD_I2C_READ,
Michael Krufkyf35db232006-12-05 14:53:39 -0300216 obuf, 3+msg[i].len,
217 ibuf, 1+msg[i+1].len) < 0)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700218 break;
219
220 if (ibuf[0] != 0x08)
Michael Krufkyae62e3d2006-03-23 01:11:18 -0300221 deb_i2c("i2c read may have failed\n");
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700222
Michael Krufkyf35db232006-12-05 14:53:39 -0300223 memcpy(msg[i+1].buf, &ibuf[1], msg[i+1].len);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700224
225 i++;
Chris Pascoe272479d72007-11-19 03:01:22 -0300226 } else {
227 /* write only */
Mauro Carvalho Chehab64f7ef82013-11-02 07:18:09 -0300228 u8 obuf[MAX_XFER_SIZE], ibuf;
229
230 if (2 + msg[i].len > sizeof(obuf)) {
231 warn("i2c wr: len=%d is too big!\n",
232 msg[i].len);
Dan Carpenter1cdbcc52013-11-22 04:55:43 -0300233 ret = -EOPNOTSUPP;
234 goto unlock;
Mauro Carvalho Chehab64f7ef82013-11-02 07:18:09 -0300235 }
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700236 obuf[0] = msg[i].addr;
237 obuf[1] = msg[i].len;
Michael Krufkyf35db232006-12-05 14:53:39 -0300238 memcpy(&obuf[2], msg[i].buf, msg[i].len);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700239
Michael Krufkyf35db232006-12-05 14:53:39 -0300240 if (cxusb_ctrl_msg(d, CMD_I2C_WRITE, obuf,
241 2+msg[i].len, &ibuf,1) < 0)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700242 break;
243 if (ibuf != 0x08)
Michael Krufkyae62e3d2006-03-23 01:11:18 -0300244 deb_i2c("i2c write may have failed\n");
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700245 }
246 }
247
Dan Carpenter1cdbcc52013-11-22 04:55:43 -0300248 if (i == num)
249 ret = num;
250 else
251 ret = -EREMOTEIO;
252
253unlock:
Ingo Molnar3593cab2006-02-07 06:49:14 -0200254 mutex_unlock(&d->i2c_mutex);
Dan Carpenter1cdbcc52013-11-22 04:55:43 -0300255 return ret;
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700256}
257
258static u32 cxusb_i2c_func(struct i2c_adapter *adapter)
259{
260 return I2C_FUNC_I2C;
261}
262
263static struct i2c_algorithm cxusb_i2c_algo = {
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700264 .master_xfer = cxusb_i2c_xfer,
265 .functionality = cxusb_i2c_func,
266};
267
268static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff)
269{
Patrick Boettchere2efeab2005-09-09 13:02:51 -0700270 u8 b = 0;
271 if (onoff)
272 return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
273 else
274 return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700275}
276
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300277static int cxusb_aver_power_ctrl(struct dvb_usb_device *d, int onoff)
278{
279 int ret;
280 if (!onoff)
281 return cxusb_ctrl_msg(d, CMD_POWER_OFF, NULL, 0, NULL, 0);
282 if (d->state == DVB_USB_STATE_INIT &&
283 usb_set_interface(d->udev, 0, 0) < 0)
284 err("set interface failed");
Hans Verkuilc6eb8ea2008-09-03 17:11:54 -0300285 do {} while (!(ret = cxusb_ctrl_msg(d, CMD_POWER_ON, NULL, 0, NULL, 0)) &&
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300286 !(ret = cxusb_ctrl_msg(d, 0x15, NULL, 0, NULL, 0)) &&
287 !(ret = cxusb_ctrl_msg(d, 0x17, NULL, 0, NULL, 0)) && 0);
288 if (!ret) {
289 /* FIXME: We don't know why, but we need to configure the
290 * lgdt3303 with the register settings below on resume */
291 int i;
292 u8 buf, bufs[] = {
293 0x0e, 0x2, 0x00, 0x7f,
294 0x0e, 0x2, 0x02, 0xfe,
295 0x0e, 0x2, 0x02, 0x01,
296 0x0e, 0x2, 0x00, 0x03,
297 0x0e, 0x2, 0x0d, 0x40,
298 0x0e, 0x2, 0x0e, 0x87,
299 0x0e, 0x2, 0x0f, 0x8e,
300 0x0e, 0x2, 0x10, 0x01,
301 0x0e, 0x2, 0x14, 0xd7,
302 0x0e, 0x2, 0x47, 0x88,
303 };
304 msleep(20);
305 for (i = 0; i < sizeof(bufs)/sizeof(u8); i += 4/sizeof(u8)) {
306 ret = cxusb_ctrl_msg(d, CMD_I2C_WRITE,
307 bufs+i, 4, &buf, 1);
308 if (ret)
309 break;
310 if (buf != 0x8)
311 return -EREMOTEIO;
312 }
313 }
314 return ret;
315}
316
Michael Krufky5691c842006-04-19 20:40:01 -0300317static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff)
318{
319 u8 b = 0;
320 if (onoff)
321 return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
322 else
323 return 0;
324}
325
Chris Pascoe5ccaf902007-11-20 01:53:31 -0300326static int cxusb_nano2_power_ctrl(struct dvb_usb_device *d, int onoff)
327{
328 int rc = 0;
329
330 rc = cxusb_power_ctrl(d, onoff);
331 if (!onoff)
332 cxusb_nano2_led(d, 0);
333
334 return rc;
335}
336
Timothy Leedfbdce02008-08-09 13:36:51 -0300337static int cxusb_d680_dmb_power_ctrl(struct dvb_usb_device *d, int onoff)
338{
339 int ret;
340 u8 b;
341 ret = cxusb_power_ctrl(d, onoff);
342 if (!onoff)
343 return ret;
344
345 msleep(128);
346 cxusb_ctrl_msg(d, CMD_DIGITAL, NULL, 0, &b, 1);
347 msleep(100);
348 return ret;
349}
350
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300351static int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700352{
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700353 u8 buf[2] = { 0x03, 0x00 };
354 if (onoff)
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300355 cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON, buf, 2, NULL, 0);
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700356 else
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300357 cxusb_ctrl_msg(adap->dev, CMD_STREAMING_OFF, NULL, 0, NULL, 0);
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700358
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700359 return 0;
360}
361
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300362static int cxusb_aver_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
363{
364 if (onoff)
365 cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_ON, NULL, 0, NULL, 0);
366 else
367 cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_OFF,
368 NULL, 0, NULL, 0);
369 return 0;
370}
371
Timothy Leedfbdce02008-08-09 13:36:51 -0300372static void cxusb_d680_dmb_drain_message(struct dvb_usb_device *d)
373{
374 int ep = d->props.generic_bulk_ctrl_endpoint;
375 const int timeout = 100;
376 const int junk_len = 32;
377 u8 *junk;
378 int rd_count;
379
380 /* Discard remaining data in video pipe */
381 junk = kmalloc(junk_len, GFP_KERNEL);
382 if (!junk)
383 return;
384 while (1) {
385 if (usb_bulk_msg(d->udev,
386 usb_rcvbulkpipe(d->udev, ep),
387 junk, junk_len, &rd_count, timeout) < 0)
388 break;
389 if (!rd_count)
390 break;
391 }
392 kfree(junk);
393}
394
395static void cxusb_d680_dmb_drain_video(struct dvb_usb_device *d)
396{
Michael Krufky77eed212011-09-06 09:31:57 -0300397 struct usb_data_stream_properties *p = &d->props.adapter[0].fe[0].stream;
Timothy Leedfbdce02008-08-09 13:36:51 -0300398 const int timeout = 100;
399 const int junk_len = p->u.bulk.buffersize;
400 u8 *junk;
401 int rd_count;
402
403 /* Discard remaining data in video pipe */
404 junk = kmalloc(junk_len, GFP_KERNEL);
405 if (!junk)
406 return;
407 while (1) {
408 if (usb_bulk_msg(d->udev,
409 usb_rcvbulkpipe(d->udev, p->endpoint),
410 junk, junk_len, &rd_count, timeout) < 0)
411 break;
412 if (!rd_count)
413 break;
414 }
415 kfree(junk);
416}
417
418static int cxusb_d680_dmb_streaming_ctrl(
419 struct dvb_usb_adapter *adap, int onoff)
420{
421 if (onoff) {
422 u8 buf[2] = { 0x03, 0x00 };
423 cxusb_d680_dmb_drain_video(adap->dev);
424 return cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON,
425 buf, sizeof(buf), NULL, 0);
426 } else {
427 int ret = cxusb_ctrl_msg(adap->dev,
428 CMD_STREAMING_OFF, NULL, 0, NULL, 0);
429 return ret;
430 }
431}
432
Chris Pascoe7c239702006-01-09 18:21:29 -0200433static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
434{
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300435 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
Michael Krufkya07e6092006-01-09 18:21:31 -0200436 u8 ircode[4];
Chris Pascoe7c239702006-01-09 18:21:29 -0200437 int i;
438
Michael Krufkya07e6092006-01-09 18:21:31 -0200439 cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4);
Chris Pascoe7c239702006-01-09 18:21:29 -0200440
441 *event = 0;
442 *state = REMOTE_NO_KEY_PRESSED;
443
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300444 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
Mauro Carvalho Chehab2e365882009-08-29 15:19:31 -0300445 if (rc5_custom(&keymap[i]) == ircode[2] &&
446 rc5_data(&keymap[i]) == ircode[3]) {
Mauro Carvalho Chehab34abf212010-07-31 11:24:57 -0300447 *event = keymap[i].keycode;
Chris Pascoe7c239702006-01-09 18:21:29 -0200448 *state = REMOTE_KEY_PRESSED;
449
450 return 0;
451 }
452 }
453
454 return 0;
455}
456
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300457static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event,
458 int *state)
459{
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300460 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300461 u8 ircode[4];
462 int i;
463 struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
464 .buf = ircode, .len = 4 };
465
466 *event = 0;
467 *state = REMOTE_NO_KEY_PRESSED;
468
469 if (cxusb_i2c_xfer(&d->i2c_adap, &msg, 1) != 1)
470 return 0;
471
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300472 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
Mauro Carvalho Chehab2e365882009-08-29 15:19:31 -0300473 if (rc5_custom(&keymap[i]) == ircode[1] &&
474 rc5_data(&keymap[i]) == ircode[2]) {
Mauro Carvalho Chehab34abf212010-07-31 11:24:57 -0300475 *event = keymap[i].keycode;
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300476 *state = REMOTE_KEY_PRESSED;
477
478 return 0;
479 }
480 }
481
482 return 0;
483}
484
Timothy Leedfbdce02008-08-09 13:36:51 -0300485static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
486 int *state)
487{
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300488 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
Timothy Leedfbdce02008-08-09 13:36:51 -0300489 u8 ircode[2];
490 int i;
491
492 *event = 0;
493 *state = REMOTE_NO_KEY_PRESSED;
494
495 if (cxusb_ctrl_msg(d, 0x10, NULL, 0, ircode, 2) < 0)
496 return 0;
497
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300498 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
Mauro Carvalho Chehab2e365882009-08-29 15:19:31 -0300499 if (rc5_custom(&keymap[i]) == ircode[0] &&
500 rc5_data(&keymap[i]) == ircode[1]) {
Mauro Carvalho Chehab34abf212010-07-31 11:24:57 -0300501 *event = keymap[i].keycode;
Timothy Leedfbdce02008-08-09 13:36:51 -0300502 *state = REMOTE_KEY_PRESSED;
503
504 return 0;
505 }
506 }
507
508 return 0;
509}
510
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300511static struct rc_map_table rc_map_dvico_mce_table[] = {
Mauro Carvalho Chehab2e365882009-08-29 15:19:31 -0300512 { 0xfe02, KEY_TV },
513 { 0xfe0e, KEY_MP3 },
514 { 0xfe1a, KEY_DVD },
515 { 0xfe1e, KEY_FAVORITES },
516 { 0xfe16, KEY_SETUP },
517 { 0xfe46, KEY_POWER2 },
518 { 0xfe0a, KEY_EPG },
519 { 0xfe49, KEY_BACK },
520 { 0xfe4d, KEY_MENU },
521 { 0xfe51, KEY_UP },
522 { 0xfe5b, KEY_LEFT },
523 { 0xfe5f, KEY_RIGHT },
524 { 0xfe53, KEY_DOWN },
525 { 0xfe5e, KEY_OK },
526 { 0xfe59, KEY_INFO },
527 { 0xfe55, KEY_TAB },
528 { 0xfe0f, KEY_PREVIOUSSONG },/* Replay */
529 { 0xfe12, KEY_NEXTSONG }, /* Skip */
530 { 0xfe42, KEY_ENTER }, /* Windows/Start */
531 { 0xfe15, KEY_VOLUMEUP },
532 { 0xfe05, KEY_VOLUMEDOWN },
533 { 0xfe11, KEY_CHANNELUP },
534 { 0xfe09, KEY_CHANNELDOWN },
535 { 0xfe52, KEY_CAMERA },
536 { 0xfe5a, KEY_TUNER }, /* Live */
537 { 0xfe19, KEY_OPEN },
538 { 0xfe0b, KEY_1 },
539 { 0xfe17, KEY_2 },
540 { 0xfe1b, KEY_3 },
541 { 0xfe07, KEY_4 },
542 { 0xfe50, KEY_5 },
543 { 0xfe54, KEY_6 },
544 { 0xfe48, KEY_7 },
545 { 0xfe4c, KEY_8 },
546 { 0xfe58, KEY_9 },
547 { 0xfe13, KEY_ANGLE }, /* Aspect */
548 { 0xfe03, KEY_0 },
549 { 0xfe1f, KEY_ZOOM },
550 { 0xfe43, KEY_REWIND },
551 { 0xfe47, KEY_PLAYPAUSE },
552 { 0xfe4f, KEY_FASTFORWARD },
553 { 0xfe57, KEY_MUTE },
554 { 0xfe0d, KEY_STOP },
555 { 0xfe01, KEY_RECORD },
556 { 0xfe4e, KEY_POWER },
Michael Krufkya07e6092006-01-09 18:21:31 -0200557};
558
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300559static struct rc_map_table rc_map_dvico_portable_table[] = {
Mauro Carvalho Chehab2e365882009-08-29 15:19:31 -0300560 { 0xfc02, KEY_SETUP }, /* Profile */
561 { 0xfc43, KEY_POWER2 },
562 { 0xfc06, KEY_EPG },
563 { 0xfc5a, KEY_BACK },
564 { 0xfc05, KEY_MENU },
565 { 0xfc47, KEY_INFO },
566 { 0xfc01, KEY_TAB },
567 { 0xfc42, KEY_PREVIOUSSONG },/* Replay */
568 { 0xfc49, KEY_VOLUMEUP },
569 { 0xfc09, KEY_VOLUMEDOWN },
570 { 0xfc54, KEY_CHANNELUP },
571 { 0xfc0b, KEY_CHANNELDOWN },
572 { 0xfc16, KEY_CAMERA },
573 { 0xfc40, KEY_TUNER }, /* ATV/DTV */
574 { 0xfc45, KEY_OPEN },
575 { 0xfc19, KEY_1 },
576 { 0xfc18, KEY_2 },
577 { 0xfc1b, KEY_3 },
578 { 0xfc1a, KEY_4 },
579 { 0xfc58, KEY_5 },
580 { 0xfc59, KEY_6 },
581 { 0xfc15, KEY_7 },
582 { 0xfc14, KEY_8 },
583 { 0xfc17, KEY_9 },
584 { 0xfc44, KEY_ANGLE }, /* Aspect */
585 { 0xfc55, KEY_0 },
586 { 0xfc07, KEY_ZOOM },
587 { 0xfc0a, KEY_REWIND },
588 { 0xfc08, KEY_PLAYPAUSE },
589 { 0xfc4b, KEY_FASTFORWARD },
590 { 0xfc5b, KEY_MUTE },
591 { 0xfc04, KEY_STOP },
592 { 0xfc56, KEY_RECORD },
593 { 0xfc57, KEY_POWER },
594 { 0xfc41, KEY_UNKNOWN }, /* INPUT */
595 { 0xfc00, KEY_UNKNOWN }, /* HD */
Michael Krufkyc1501782006-03-26 05:43:36 -0300596};
597
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300598static struct rc_map_table rc_map_d680_dmb_table[] = {
Mauro Carvalho Chehab2e365882009-08-29 15:19:31 -0300599 { 0x0038, KEY_UNKNOWN }, /* TV/AV */
600 { 0x080c, KEY_ZOOM },
601 { 0x0800, KEY_0 },
602 { 0x0001, KEY_1 },
603 { 0x0802, KEY_2 },
604 { 0x0003, KEY_3 },
605 { 0x0804, KEY_4 },
606 { 0x0005, KEY_5 },
607 { 0x0806, KEY_6 },
608 { 0x0007, KEY_7 },
609 { 0x0808, KEY_8 },
610 { 0x0009, KEY_9 },
611 { 0x000a, KEY_MUTE },
612 { 0x0829, KEY_BACK },
613 { 0x0012, KEY_CHANNELUP },
614 { 0x0813, KEY_CHANNELDOWN },
615 { 0x002b, KEY_VOLUMEUP },
616 { 0x082c, KEY_VOLUMEDOWN },
617 { 0x0020, KEY_UP },
618 { 0x0821, KEY_DOWN },
619 { 0x0011, KEY_LEFT },
620 { 0x0810, KEY_RIGHT },
621 { 0x000d, KEY_OK },
622 { 0x081f, KEY_RECORD },
623 { 0x0017, KEY_PLAYPAUSE },
624 { 0x0816, KEY_PLAYPAUSE },
625 { 0x000b, KEY_STOP },
626 { 0x0827, KEY_FASTFORWARD },
627 { 0x0026, KEY_REWIND },
628 { 0x081e, KEY_UNKNOWN }, /* Time Shift */
629 { 0x000e, KEY_UNKNOWN }, /* Snapshot */
630 { 0x082d, KEY_UNKNOWN }, /* Mouse Cursor */
631 { 0x000f, KEY_UNKNOWN }, /* Minimize/Maximize */
632 { 0x0814, KEY_UNKNOWN }, /* Shuffle */
633 { 0x0025, KEY_POWER },
Timothy Leedfbdce02008-08-09 13:36:51 -0300634};
635
Chris Pascoe0029ee12006-01-09 18:21:28 -0200636static int cxusb_dee1601_demod_init(struct dvb_frontend* fe)
637{
Chris Pascoed9ed8812006-02-07 06:49:11 -0200638 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 };
Chris Pascoe0029ee12006-01-09 18:21:28 -0200639 static u8 reset [] = { RESET, 0x80 };
640 static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
641 static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 };
642 static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
643 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
644
645 mt352_write(fe, clock_config, sizeof(clock_config));
646 udelay(200);
647 mt352_write(fe, reset, sizeof(reset));
648 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
649
650 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
651 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
652 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
653
654 return 0;
655}
656
Michael Krufky6f447252006-01-11 19:40:33 -0200657static int cxusb_mt352_demod_init(struct dvb_frontend* fe)
658{ /* used in both lgz201 and th7579 */
Michael Krufkyfb51fd22006-02-07 06:49:12 -0200659 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x29 };
Michael Krufky6f447252006-01-11 19:40:33 -0200660 static u8 reset [] = { RESET, 0x80 };
661 static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
662 static u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 };
663 static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
664 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
665
666 mt352_write(fe, clock_config, sizeof(clock_config));
667 udelay(200);
668 mt352_write(fe, reset, sizeof(reset));
669 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
670
671 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
672 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
673 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
674 return 0;
675}
676
Adrian Bunk703cb2c2006-01-23 17:11:09 -0200677static struct cx22702_config cxusb_cx22702_config = {
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700678 .demod_address = 0x63,
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700679 .output_mode = CX22702_PARALLEL_OUTPUT,
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700680};
681
Michael Krufkyfddd6322006-02-27 00:08:17 -0300682static struct lgdt330x_config cxusb_lgdt3303_config = {
Michael Krufkyeffee032006-01-09 15:25:47 -0200683 .demod_address = 0x0e,
684 .demod_chip = LGDT3303,
Michael Krufkyeffee032006-01-09 15:25:47 -0200685};
686
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300687static struct lgdt330x_config cxusb_aver_lgdt3303_config = {
688 .demod_address = 0x0e,
689 .demod_chip = LGDT3303,
690 .clock_polarity_flip = 2,
691};
692
Adrian Bunk703cb2c2006-01-23 17:11:09 -0200693static struct mt352_config cxusb_dee1601_config = {
Chris Pascoe0029ee12006-01-09 18:21:28 -0200694 .demod_address = 0x0f,
695 .demod_init = cxusb_dee1601_demod_init,
Chris Pascoe0029ee12006-01-09 18:21:28 -0200696};
697
Michael Krufkyc9ce3942006-06-11 04:24:31 -0300698static struct zl10353_config cxusb_zl10353_dee1601_config = {
699 .demod_address = 0x0f,
Chris Pascoe8fb95782006-08-10 03:17:16 -0300700 .parallel_ts = 1,
Michael Krufkyc9ce3942006-06-11 04:24:31 -0300701};
702
Adrian Bunk6fe00b02006-04-19 20:49:28 -0300703static struct mt352_config cxusb_mt352_config = {
Michael Krufky6f447252006-01-11 19:40:33 -0200704 /* used in both lgz201 and th7579 */
705 .demod_address = 0x0f,
706 .demod_init = cxusb_mt352_demod_init,
Michael Krufky6f447252006-01-11 19:40:33 -0200707};
708
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300709static struct zl10353_config cxusb_zl10353_xc3028_config = {
710 .demod_address = 0x0f,
Chris Pascoea1dcd9d2007-11-20 08:17:54 -0300711 .if2 = 45600,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300712 .no_tuner = 1,
713 .parallel_ts = 1,
714};
715
Robert Lowery0bc35182009-11-08 00:00:11 -0300716static struct zl10353_config cxusb_zl10353_xc3028_config_no_i2c_gate = {
717 .demod_address = 0x0f,
718 .if2 = 45600,
719 .no_tuner = 1,
720 .parallel_ts = 1,
721 .disable_i2c_gate_ctrl = 1,
722};
723
Chris Pascoe702a6762007-11-20 03:34:11 -0300724static struct mt352_config cxusb_mt352_xc3028_config = {
725 .demod_address = 0x0f,
726 .if2 = 4560,
727 .no_tuner = 1,
728 .demod_init = cxusb_mt352_demod_init,
729};
730
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300731/* FIXME: needs tweaking */
732static struct mxl5005s_config aver_a868r_tuner = {
733 .i2c_address = 0x63,
734 .if_freq = 6000000UL,
735 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
736 .agc_mode = MXL_SINGLE_AGC,
737 .tracking_filter = MXL_TF_C,
738 .rssi_enable = MXL_RSSI_ENABLE,
739 .cap_select = MXL_CAP_SEL_ENABLE,
740 .div_out = MXL_DIV_OUT_4,
741 .clock_out = MXL_CLOCK_OUT_DISABLE,
742 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
743 .top = MXL5005S_TOP_25P2,
744 .mod_mode = MXL_DIGITAL_MODE,
745 .if_mode = MXL_ZERO_IF,
746 .AgcMasterByte = 0x00,
747};
748
Timothy Leedfbdce02008-08-09 13:36:51 -0300749/* FIXME: needs tweaking */
750static struct mxl5005s_config d680_dmb_tuner = {
751 .i2c_address = 0x63,
752 .if_freq = 36125000UL,
753 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
754 .agc_mode = MXL_SINGLE_AGC,
755 .tracking_filter = MXL_TF_C,
756 .rssi_enable = MXL_RSSI_ENABLE,
757 .cap_select = MXL_CAP_SEL_ENABLE,
758 .div_out = MXL_DIV_OUT_4,
759 .clock_out = MXL_CLOCK_OUT_DISABLE,
760 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
761 .top = MXL5005S_TOP_25P2,
762 .mod_mode = MXL_DIGITAL_MODE,
763 .if_mode = MXL_ZERO_IF,
764 .AgcMasterByte = 0x00,
765};
766
David Wongb18bd1d2009-10-26 09:41:22 -0300767static struct max2165_config mygica_d689_max2165_cfg = {
768 .i2c_address = 0x60,
769 .osc_clk = 20
770};
771
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700772/* Callbacks for DVB USB */
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300773static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700774{
Michael Krufky77eed212011-09-06 09:31:57 -0300775 dvb_attach(simple_tuner_attach, adap->fe_adap[0].fe,
Michael Krufkycb89cd32008-04-22 14:46:16 -0300776 &adap->dev->i2c_adap, 0x61,
777 TUNER_PHILIPS_FMD1216ME_MK3);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700778 return 0;
779}
780
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300781static int cxusb_dee1601_tuner_attach(struct dvb_usb_adapter *adap)
Chris Pascoe0029ee12006-01-09 18:21:28 -0200782{
Michael Krufky77eed212011-09-06 09:31:57 -0300783 dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61,
Michael Krufky47a99912007-06-12 16:10:51 -0300784 NULL, DVB_PLL_THOMSON_DTT7579);
Chris Pascoe0029ee12006-01-09 18:21:28 -0200785 return 0;
786}
787
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300788static int cxusb_lgz201_tuner_attach(struct dvb_usb_adapter *adap)
Michael Krufky6f447252006-01-11 19:40:33 -0200789{
Michael Krufky77eed212011-09-06 09:31:57 -0300790 dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61, NULL, DVB_PLL_LG_Z201);
Michael Krufky6f447252006-01-11 19:40:33 -0200791 return 0;
792}
793
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300794static int cxusb_dtt7579_tuner_attach(struct dvb_usb_adapter *adap)
Michael Krufky6f447252006-01-11 19:40:33 -0200795{
Michael Krufky77eed212011-09-06 09:31:57 -0300796 dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60,
Michael Krufky47a99912007-06-12 16:10:51 -0300797 NULL, DVB_PLL_THOMSON_DTT7579);
Patrick Boettcher332bed52006-05-14 04:49:00 -0300798 return 0;
799}
800
Michael Krufkyf71a56c2006-10-13 21:55:57 -0300801static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap)
Patrick Boettcher332bed52006-05-14 04:49:00 -0300802{
Michael Krufky77eed212011-09-06 09:31:57 -0300803 dvb_attach(simple_tuner_attach, adap->fe_adap[0].fe,
Michael Krufky827855d2008-04-22 14:46:16 -0300804 &adap->dev->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF);
Michael Krufky6f447252006-01-11 19:40:33 -0200805 return 0;
806}
807
Michael Krufkyd7cba042008-09-12 13:31:45 -0300808static int dvico_bluebird_xc2028_callback(void *ptr, int component,
809 int command, int arg)
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300810{
Robert Loweryd483b732008-07-30 19:43:11 -0300811 struct dvb_usb_adapter *adap = ptr;
812 struct dvb_usb_device *d = adap->dev;
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300813
814 switch (command) {
815 case XC2028_TUNER_RESET:
Harvey Harrison708bebd2008-04-08 23:20:00 -0300816 deb_info("%s: XC2028_TUNER_RESET %d\n", __func__, arg);
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300817 cxusb_bluebird_gpio_pulse(d, 0x01, 1);
818 break;
819 case XC2028_RESET_CLK:
Harvey Harrison708bebd2008-04-08 23:20:00 -0300820 deb_info("%s: XC2028_RESET_CLK %d\n", __func__, arg);
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300821 break;
822 default:
Harvey Harrison708bebd2008-04-08 23:20:00 -0300823 deb_info("%s: unknown command %d, arg %d\n", __func__,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300824 command, arg);
825 return -EINVAL;
826 }
827
828 return 0;
829}
830
831static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap)
832{
833 struct dvb_frontend *fe;
834 struct xc2028_config cfg = {
835 .i2c_adap = &adap->dev->i2c_adap,
836 .i2c_addr = 0x61,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300837 };
838 static struct xc2028_ctrl ctl = {
Michael Krufkyef80bfe2008-09-16 02:15:30 -0300839 .fname = XC2028_DEFAULT_FIRMWARE,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300840 .max_len = 64,
Robert Loweryd483b732008-07-30 19:43:11 -0300841 .demod = XC3028_FE_ZARLINK456,
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300842 };
843
Michael Krufkyd7cba042008-09-12 13:31:45 -0300844 /* FIXME: generalize & move to common area */
Michael Krufky77eed212011-09-06 09:31:57 -0300845 adap->fe_adap[0].fe->callback = dvico_bluebird_xc2028_callback;
Michael Krufkyd7cba042008-09-12 13:31:45 -0300846
Michael Krufky77eed212011-09-06 09:31:57 -0300847 fe = dvb_attach(xc2028_attach, adap->fe_adap[0].fe, &cfg);
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300848 if (fe == NULL || fe->ops.tuner_ops.set_config == NULL)
849 return -EIO;
850
851 fe->ops.tuner_ops.set_config(fe, &ctl);
852
853 return 0;
854}
855
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300856static int cxusb_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
857{
Michael Krufky77eed212011-09-06 09:31:57 -0300858 dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe,
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300859 &adap->dev->i2c_adap, &aver_a868r_tuner);
860 return 0;
861}
862
Timothy Leedfbdce02008-08-09 13:36:51 -0300863static int cxusb_d680_dmb_tuner_attach(struct dvb_usb_adapter *adap)
864{
865 struct dvb_frontend *fe;
Michael Krufky77eed212011-09-06 09:31:57 -0300866 fe = dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe,
Timothy Leedfbdce02008-08-09 13:36:51 -0300867 &adap->dev->i2c_adap, &d680_dmb_tuner);
868 return (fe == NULL) ? -EIO : 0;
869}
870
David Wongb18bd1d2009-10-26 09:41:22 -0300871static int cxusb_mygica_d689_tuner_attach(struct dvb_usb_adapter *adap)
872{
873 struct dvb_frontend *fe;
Michael Krufky77eed212011-09-06 09:31:57 -0300874 fe = dvb_attach(max2165_attach, adap->fe_adap[0].fe,
David Wongb18bd1d2009-10-26 09:41:22 -0300875 &adap->dev->i2c_adap, &mygica_d689_max2165_cfg);
876 return (fe == NULL) ? -EIO : 0;
877}
878
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300879static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700880{
Patrick Boettchere2efeab2005-09-09 13:02:51 -0700881 u8 b;
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300882 if (usb_set_interface(adap->dev->udev, 0, 6) < 0)
Patrick Boettcher8257e8a2005-07-07 17:58:15 -0700883 err("set interface failed");
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700884
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300885 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, &b, 1);
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700886
Michael Krufky310df362011-09-17 14:22:59 -0300887 adap->fe_adap[0].fe = dvb_attach(cx22702_attach, &cxusb_cx22702_config,
888 &adap->dev->i2c_adap);
889 if ((adap->fe_adap[0].fe) != NULL)
Patrick Boettcher22c6d932005-07-07 17:58:10 -0700890 return 0;
891
892 return -EIO;
893}
894
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300895static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
Michael Krufkyeffee032006-01-09 15:25:47 -0200896{
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300897 if (usb_set_interface(adap->dev->udev, 0, 7) < 0)
Michael Krufkyeffee032006-01-09 15:25:47 -0200898 err("set interface failed");
899
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300900 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
Michael Krufkyeffee032006-01-09 15:25:47 -0200901
Michael Krufky310df362011-09-17 14:22:59 -0300902 adap->fe_adap[0].fe = dvb_attach(lgdt330x_attach,
903 &cxusb_lgdt3303_config,
904 &adap->dev->i2c_adap);
905 if ((adap->fe_adap[0].fe) != NULL)
Michael Krufkyeffee032006-01-09 15:25:47 -0200906 return 0;
907
908 return -EIO;
909}
910
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300911static int cxusb_aver_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
912{
Michael Krufky77eed212011-09-06 09:31:57 -0300913 adap->fe_adap[0].fe = dvb_attach(lgdt330x_attach, &cxusb_aver_lgdt3303_config,
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300914 &adap->dev->i2c_adap);
Michael Krufky77eed212011-09-06 09:31:57 -0300915 if (adap->fe_adap[0].fe != NULL)
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -0300916 return 0;
917
918 return -EIO;
919}
920
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300921static int cxusb_mt352_frontend_attach(struct dvb_usb_adapter *adap)
Chris Pascoe0029ee12006-01-09 18:21:28 -0200922{
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300923 /* used in both lgz201 and th7579 */
924 if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
Chris Pascoe0029ee12006-01-09 18:21:28 -0200925 err("set interface failed");
926
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300927 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
Chris Pascoe0029ee12006-01-09 18:21:28 -0200928
Michael Krufky310df362011-09-17 14:22:59 -0300929 adap->fe_adap[0].fe = dvb_attach(mt352_attach, &cxusb_mt352_config,
930 &adap->dev->i2c_adap);
931 if ((adap->fe_adap[0].fe) != NULL)
Patrick Boettcher4d43e132006-09-30 06:53:48 -0300932 return 0;
933
934 return -EIO;
935}
936
937static int cxusb_dee1601_frontend_attach(struct dvb_usb_adapter *adap)
938{
939 if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
940 err("set interface failed");
941
942 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
943
Michael Krufky310df362011-09-17 14:22:59 -0300944 adap->fe_adap[0].fe = dvb_attach(mt352_attach, &cxusb_dee1601_config,
945 &adap->dev->i2c_adap);
946 if ((adap->fe_adap[0].fe) != NULL)
947 return 0;
948
949 adap->fe_adap[0].fe = dvb_attach(zl10353_attach,
950 &cxusb_zl10353_dee1601_config,
951 &adap->dev->i2c_adap);
952 if ((adap->fe_adap[0].fe) != NULL)
Chris Pascoe0029ee12006-01-09 18:21:28 -0200953 return 0;
954
955 return -EIO;
956}
957
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300958static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap)
959{
960 u8 ircode[4];
961 int i;
962 struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
963 .buf = ircode, .len = 4 };
964
965 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
966 err("set interface failed");
967
968 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
969
970 /* reset the tuner and demodulator */
971 cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
972 cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
973 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
974
Michael Krufky310df362011-09-17 14:22:59 -0300975 adap->fe_adap[0].fe =
976 dvb_attach(zl10353_attach,
977 &cxusb_zl10353_xc3028_config_no_i2c_gate,
978 &adap->dev->i2c_adap);
979 if ((adap->fe_adap[0].fe) == NULL)
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300980 return -EIO;
981
982 /* try to determine if there is no IR decoder on the I2C bus */
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300983 for (i = 0; adap->dev->props.rc.legacy.rc_map_table != NULL && i < 5; i++) {
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300984 msleep(20);
985 if (cxusb_i2c_xfer(&adap->dev->i2c_adap, &msg, 1) != 1)
986 goto no_IR;
987 if (ircode[0] == 0 && ircode[1] == 0)
988 continue;
989 if (ircode[2] + ircode[3] != 0xff) {
990no_IR:
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -0300991 adap->dev->props.rc.legacy.rc_map_table = NULL;
Chris Pascoeaeb012b2007-11-19 21:57:10 -0300992 info("No IR receiver detected on this device.");
993 break;
994 }
995 }
996
997 return 0;
998}
999
Anton Blanchard8d798982008-08-09 12:23:15 -03001000static struct dibx000_agc_config dib7070_agc_config = {
1001 .band_caps = BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
1002
1003 /*
1004 * P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5,
1005 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
1006 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0
1007 */
1008 .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) |
1009 (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
1010 .inv_gain = 600,
1011 .time_stabiliz = 10,
1012 .alpha_level = 0,
1013 .thlock = 118,
1014 .wbd_inv = 0,
1015 .wbd_ref = 3530,
1016 .wbd_sel = 1,
1017 .wbd_alpha = 5,
1018 .agc1_max = 65535,
1019 .agc1_min = 0,
1020 .agc2_max = 65535,
1021 .agc2_min = 0,
1022 .agc1_pt1 = 0,
1023 .agc1_pt2 = 40,
1024 .agc1_pt3 = 183,
1025 .agc1_slope1 = 206,
1026 .agc1_slope2 = 255,
1027 .agc2_pt1 = 72,
1028 .agc2_pt2 = 152,
1029 .agc2_slope1 = 88,
1030 .agc2_slope2 = 90,
1031 .alpha_mant = 17,
1032 .alpha_exp = 27,
1033 .beta_mant = 23,
1034 .beta_exp = 51,
1035 .perform_agc_softsplit = 0,
1036};
1037
1038static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
1039 .internal = 60000,
1040 .sampling = 15000,
1041 .pll_prediv = 1,
1042 .pll_ratio = 20,
1043 .pll_range = 3,
1044 .pll_reset = 1,
1045 .pll_bypass = 0,
1046 .enable_refdiv = 0,
1047 .bypclk_div = 0,
1048 .IO_CLK_en_core = 1,
1049 .ADClkSrc = 1,
1050 .modulo = 2,
1051 /* refsel, sel, freq_15k */
1052 .sad_cfg = (3 << 14) | (1 << 12) | (524 << 0),
1053 .ifreq = (0 << 25) | 0,
1054 .timf = 20452225,
1055 .xtal_hz = 12000000,
1056};
1057
1058static struct dib7000p_config cxusb_dualdig4_rev2_config = {
1059 .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK,
1060 .output_mpeg2_in_188_bytes = 1,
1061
1062 .agc_config_count = 1,
1063 .agc = &dib7070_agc_config,
1064 .bw = &dib7070_bw_config_12_mhz,
1065 .tuner_is_baseband = 1,
1066 .spur_protect = 1,
1067
1068 .gpio_dir = 0xfcef,
1069 .gpio_val = 0x0110,
1070
1071 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
1072
1073 .hostbus_diversity = 1,
1074};
1075
Mauro Carvalho Chehab8abe4a02014-05-29 09:20:15 -03001076struct dib0700_adapter_state {
1077 int (*set_param_save)(struct dvb_frontend *);
1078 struct dib7000p_ops dib7000p_ops;
1079};
1080
Anton Blanchard8d798982008-08-09 12:23:15 -03001081static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap)
1082{
Mauro Carvalho Chehab8abe4a02014-05-29 09:20:15 -03001083 struct dib0700_adapter_state *state = adap->priv;
1084
Anton Blanchard8d798982008-08-09 12:23:15 -03001085 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
1086 err("set interface failed");
1087
1088 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
1089
1090 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
1091
Mauro Carvalho Chehab8abe4a02014-05-29 09:20:15 -03001092 if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops))
1093 return -ENODEV;
1094
1095 if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
1096 &cxusb_dualdig4_rev2_config) < 0) {
Prarit Bhargavaa49ba162010-05-12 19:30:02 -03001097 printk(KERN_WARNING "Unable to enumerate dib7000p\n");
Randy Dunlap30d81bb2010-02-08 20:30:44 -03001098 return -ENODEV;
Prarit Bhargavaa49ba162010-05-12 19:30:02 -03001099 }
Anton Blanchard8d798982008-08-09 12:23:15 -03001100
Mauro Carvalho Chehab8abe4a02014-05-29 09:20:15 -03001101 adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80,
1102 &cxusb_dualdig4_rev2_config);
Michael Krufky77eed212011-09-06 09:31:57 -03001103 if (adap->fe_adap[0].fe == NULL)
Anton Blanchard8d798982008-08-09 12:23:15 -03001104 return -EIO;
1105
1106 return 0;
1107}
1108
1109static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
1110{
Mauro Carvalho Chehab8abe4a02014-05-29 09:20:15 -03001111 struct dvb_usb_adapter *adap = fe->dvb->priv;
1112 struct dib0700_adapter_state *state = adap->priv;
1113
1114 return state->dib7000p_ops.set_gpio(fe, 8, 0, !onoff);
Anton Blanchard8d798982008-08-09 12:23:15 -03001115}
1116
1117static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
1118{
1119 return 0;
1120}
1121
1122static struct dib0070_config dib7070p_dib0070_config = {
1123 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1124 .reset = dib7070_tuner_reset,
1125 .sleep = dib7070_tuner_sleep,
1126 .clock_khz = 12000,
1127};
1128
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03001129static int dib7070_set_param_override(struct dvb_frontend *fe)
Anton Blanchard8d798982008-08-09 12:23:15 -03001130{
Mauro Carvalho Chehabafd2b382011-12-24 10:17:30 -03001131 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Anton Blanchard8d798982008-08-09 12:23:15 -03001132 struct dvb_usb_adapter *adap = fe->dvb->priv;
1133 struct dib0700_adapter_state *state = adap->priv;
1134
1135 u16 offset;
Mauro Carvalho Chehabafd2b382011-12-24 10:17:30 -03001136 u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
Anton Blanchard8d798982008-08-09 12:23:15 -03001137 switch (band) {
Michael Krufkya2dc86b2008-08-09 13:06:26 -03001138 case BAND_VHF: offset = 950; break;
1139 default:
1140 case BAND_UHF: offset = 550; break;
Anton Blanchard8d798982008-08-09 12:23:15 -03001141 }
1142
Mauro Carvalho Chehab8abe4a02014-05-29 09:20:15 -03001143 state->dib7000p_ops.set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
Anton Blanchard8d798982008-08-09 12:23:15 -03001144
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03001145 return state->set_param_save(fe);
Anton Blanchard8d798982008-08-09 12:23:15 -03001146}
1147
1148static int cxusb_dualdig4_rev2_tuner_attach(struct dvb_usb_adapter *adap)
1149{
1150 struct dib0700_adapter_state *st = adap->priv;
Mauro Carvalho Chehab8abe4a02014-05-29 09:20:15 -03001151 struct i2c_adapter *tun_i2c;
1152
1153 /*
1154 * No need to call dvb7000p_attach here, as it was called
1155 * already, as frontend_attach method is called first, and
1156 * tuner_attach is only called on sucess.
1157 */
1158 tun_i2c = st->dib7000p_ops.get_i2c_master(adap->fe_adap[0].fe,
Michael Krufkya2dc86b2008-08-09 13:06:26 -03001159 DIBX000_I2C_INTERFACE_TUNER, 1);
Anton Blanchard8d798982008-08-09 12:23:15 -03001160
Michael Krufky77eed212011-09-06 09:31:57 -03001161 if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,
Anton Blanchard8d798982008-08-09 12:23:15 -03001162 &dib7070p_dib0070_config) == NULL)
1163 return -ENODEV;
1164
Michael Krufky77eed212011-09-06 09:31:57 -03001165 st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
1166 adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7070_set_param_override;
Anton Blanchard8d798982008-08-09 12:23:15 -03001167 return 0;
1168}
1169
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001170static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap)
1171{
1172 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
1173 err("set interface failed");
1174
1175 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
1176
1177 /* reset the tuner and demodulator */
1178 cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
1179 cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
1180 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
1181
Michael Krufky310df362011-09-17 14:22:59 -03001182 adap->fe_adap[0].fe = dvb_attach(zl10353_attach,
1183 &cxusb_zl10353_xc3028_config,
1184 &adap->dev->i2c_adap);
1185 if ((adap->fe_adap[0].fe) != NULL)
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001186 return 0;
1187
Michael Krufky310df362011-09-17 14:22:59 -03001188 adap->fe_adap[0].fe = dvb_attach(mt352_attach,
1189 &cxusb_mt352_xc3028_config,
1190 &adap->dev->i2c_adap);
1191 if ((adap->fe_adap[0].fe) != NULL)
Chris Pascoe702a6762007-11-20 03:34:11 -03001192 return 0;
1193
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001194 return -EIO;
1195}
1196
David T.L. Wong6bf1a992009-08-05 13:07:10 -03001197static struct lgs8gxx_config d680_lgs8gl5_cfg = {
1198 .prod = LGS8GXX_PROD_LGS8GL5,
Timothy Leedfbdce02008-08-09 13:36:51 -03001199 .demod_address = 0x19,
David T.L. Wong6bf1a992009-08-05 13:07:10 -03001200 .serial_ts = 0,
1201 .ts_clk_pol = 0,
1202 .ts_clk_gated = 1,
1203 .if_clk_freq = 30400, /* 30.4 MHz */
1204 .if_freq = 5725, /* 5.725 MHz */
1205 .if_neg_center = 0,
1206 .ext_adc = 0,
1207 .adc_signed = 0,
1208 .if_neg_edge = 0,
Timothy Leedfbdce02008-08-09 13:36:51 -03001209};
1210
1211static int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap)
1212{
1213 struct dvb_usb_device *d = adap->dev;
1214 int n;
1215
1216 /* Select required USB configuration */
1217 if (usb_set_interface(d->udev, 0, 0) < 0)
1218 err("set interface failed");
1219
1220 /* Unblock all USB pipes */
1221 usb_clear_halt(d->udev,
1222 usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1223 usb_clear_halt(d->udev,
1224 usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1225 usb_clear_halt(d->udev,
Michael Krufky77eed212011-09-06 09:31:57 -03001226 usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint));
Timothy Leedfbdce02008-08-09 13:36:51 -03001227
1228 /* Drain USB pipes to avoid hang after reboot */
1229 for (n = 0; n < 5; n++) {
1230 cxusb_d680_dmb_drain_message(d);
1231 cxusb_d680_dmb_drain_video(d);
1232 msleep(200);
1233 }
1234
1235 /* Reset the tuner */
1236 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) {
1237 err("clear tuner gpio failed");
1238 return -EIO;
1239 }
1240 msleep(100);
1241 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) {
1242 err("set tuner gpio failed");
1243 return -EIO;
1244 }
1245 msleep(100);
1246
1247 /* Attach frontend */
Michael Krufky77eed212011-09-06 09:31:57 -03001248 adap->fe_adap[0].fe = dvb_attach(lgs8gxx_attach, &d680_lgs8gl5_cfg, &d->i2c_adap);
1249 if (adap->fe_adap[0].fe == NULL)
Timothy Leedfbdce02008-08-09 13:36:51 -03001250 return -EIO;
1251
1252 return 0;
1253}
1254
David Wongb18bd1d2009-10-26 09:41:22 -03001255static struct atbm8830_config mygica_d689_atbm8830_cfg = {
1256 .prod = ATBM8830_PROD_8830,
1257 .demod_address = 0x40,
1258 .serial_ts = 0,
1259 .ts_sampling_edge = 1,
1260 .ts_clk_gated = 0,
1261 .osc_clk_freq = 30400, /* in kHz */
1262 .if_freq = 0, /* zero IF */
1263 .zif_swap_iq = 1,
David Wongc245c752009-11-28 08:36:31 -03001264 .agc_min = 0x2E,
1265 .agc_max = 0x90,
1266 .agc_hold_loop = 0,
David Wongb18bd1d2009-10-26 09:41:22 -03001267};
1268
1269static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap)
1270{
1271 struct dvb_usb_device *d = adap->dev;
David Wongb18bd1d2009-10-26 09:41:22 -03001272
1273 /* Select required USB configuration */
1274 if (usb_set_interface(d->udev, 0, 0) < 0)
1275 err("set interface failed");
1276
1277 /* Unblock all USB pipes */
1278 usb_clear_halt(d->udev,
1279 usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1280 usb_clear_halt(d->udev,
1281 usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1282 usb_clear_halt(d->udev,
Michael Krufky77eed212011-09-06 09:31:57 -03001283 usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint));
David Wongb18bd1d2009-10-26 09:41:22 -03001284
1285
1286 /* Reset the tuner */
1287 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) {
1288 err("clear tuner gpio failed");
1289 return -EIO;
1290 }
1291 msleep(100);
1292 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) {
1293 err("set tuner gpio failed");
1294 return -EIO;
1295 }
1296 msleep(100);
1297
1298 /* Attach frontend */
Michael Krufky77eed212011-09-06 09:31:57 -03001299 adap->fe_adap[0].fe = dvb_attach(atbm8830_attach, &mygica_d689_atbm8830_cfg,
David Wongb18bd1d2009-10-26 09:41:22 -03001300 &d->i2c_adap);
Michael Krufky77eed212011-09-06 09:31:57 -03001301 if (adap->fe_adap[0].fe == NULL)
David Wongb18bd1d2009-10-26 09:41:22 -03001302 return -EIO;
1303
1304 return 0;
1305}
1306
CrazyCata0f629b2014-11-14 18:24:28 -03001307static int cxusb_mygica_t230_frontend_attach(struct dvb_usb_adapter *adap)
1308{
1309 struct dvb_usb_device *d = adap->dev;
1310 struct cxusb_state *st = d->priv;
1311 struct i2c_adapter *adapter;
1312 struct i2c_client *client_demod;
1313 struct i2c_client *client_tuner;
1314 struct i2c_board_info info;
1315 struct si2168_config si2168_config;
1316 struct si2157_config si2157_config;
1317
1318 /* Select required USB configuration */
1319 if (usb_set_interface(d->udev, 0, 0) < 0)
1320 err("set interface failed");
1321
1322 /* Unblock all USB pipes */
1323 usb_clear_halt(d->udev,
1324 usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1325 usb_clear_halt(d->udev,
1326 usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1327 usb_clear_halt(d->udev,
1328 usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint));
1329
1330 /* attach frontend */
1331 si2168_config.i2c_adapter = &adapter;
1332 si2168_config.fe = &adap->fe_adap[0].fe;
1333 si2168_config.ts_mode = SI2168_TS_PARALLEL;
1334 si2168_config.ts_clock_inv = 1;
1335 memset(&info, 0, sizeof(struct i2c_board_info));
1336 strlcpy(info.type, "si2168", I2C_NAME_SIZE);
1337 info.addr = 0x64;
1338 info.platform_data = &si2168_config;
1339 request_module(info.type);
1340 client_demod = i2c_new_device(&d->i2c_adap, &info);
1341 if (client_demod == NULL || client_demod->dev.driver == NULL)
1342 return -ENODEV;
1343
1344 if (!try_module_get(client_demod->dev.driver->owner)) {
1345 i2c_unregister_device(client_demod);
1346 return -ENODEV;
1347 }
1348
1349 st->i2c_client_demod = client_demod;
1350
1351 /* attach tuner */
1352 memset(&si2157_config, 0, sizeof(si2157_config));
1353 si2157_config.fe = adap->fe_adap[0].fe;
Olli Salonenee3c3e42015-05-05 13:54:17 -03001354 si2157_config.if_port = 1;
CrazyCata0f629b2014-11-14 18:24:28 -03001355 memset(&info, 0, sizeof(struct i2c_board_info));
1356 strlcpy(info.type, "si2157", I2C_NAME_SIZE);
1357 info.addr = 0x60;
1358 info.platform_data = &si2157_config;
1359 request_module(info.type);
1360 client_tuner = i2c_new_device(adapter, &info);
1361 if (client_tuner == NULL || client_tuner->dev.driver == NULL) {
1362 module_put(client_demod->dev.driver->owner);
1363 i2c_unregister_device(client_demod);
1364 return -ENODEV;
1365 }
1366 if (!try_module_get(client_tuner->dev.driver->owner)) {
1367 i2c_unregister_device(client_tuner);
1368 module_put(client_demod->dev.driver->owner);
1369 i2c_unregister_device(client_demod);
1370 return -ENODEV;
1371 }
1372
1373 st->i2c_client_tuner = client_tuner;
1374
1375 return 0;
1376}
1377
Patrick Boettcherf5373782006-01-09 18:21:38 -02001378/*
Chris Pascoe702a6762007-11-20 03:34:11 -03001379 * DViCO has shipped two devices with the same USB ID, but only one of them
1380 * needs a firmware download. Check the device class details to see if they
1381 * have non-default values to decide whether the device is actually cold or
1382 * not, and forget a match if it turns out we selected the wrong device.
1383 */
1384static int bluebird_fx2_identify_state(struct usb_device *udev,
1385 struct dvb_usb_device_properties *props,
1386 struct dvb_usb_device_description **desc,
1387 int *cold)
1388{
1389 int wascold = *cold;
1390
1391 *cold = udev->descriptor.bDeviceClass == 0xff &&
1392 udev->descriptor.bDeviceSubClass == 0xff &&
1393 udev->descriptor.bDeviceProtocol == 0xff;
1394
1395 if (*cold && !wascold)
1396 *desc = NULL;
1397
1398 return 0;
1399}
1400
1401/*
Patrick Boettcherf5373782006-01-09 18:21:38 -02001402 * DViCO bluebird firmware needs the "warm" product ID to be patched into the
1403 * firmware file before download.
1404 */
1405
Chris Pascoe702a6762007-11-20 03:34:11 -03001406static const int dvico_firmware_id_offsets[] = { 6638, 3204 };
Michael Krufkyf35db232006-12-05 14:53:39 -03001407static int bluebird_patch_dvico_firmware_download(struct usb_device *udev,
1408 const struct firmware *fw)
Patrick Boettcherf5373782006-01-09 18:21:38 -02001409{
Chris Pascoe702a6762007-11-20 03:34:11 -03001410 int pos;
Patrick Boettcherf5373782006-01-09 18:21:38 -02001411
Chris Pascoe702a6762007-11-20 03:34:11 -03001412 for (pos = 0; pos < ARRAY_SIZE(dvico_firmware_id_offsets); pos++) {
1413 int idoff = dvico_firmware_id_offsets[pos];
Patrick Boettcherf5373782006-01-09 18:21:38 -02001414
Chris Pascoe702a6762007-11-20 03:34:11 -03001415 if (fw->size < idoff + 4)
1416 continue;
Patrick Boettcherf5373782006-01-09 18:21:38 -02001417
Chris Pascoe702a6762007-11-20 03:34:11 -03001418 if (fw->data[idoff] == (USB_VID_DVICO & 0xff) &&
1419 fw->data[idoff + 1] == USB_VID_DVICO >> 8) {
David Woodhousee62f89f2008-05-24 00:12:42 +01001420 struct firmware new_fw;
1421 u8 *new_fw_data = vmalloc(fw->size);
1422 int ret;
1423
1424 if (!new_fw_data)
1425 return -ENOMEM;
1426
1427 memcpy(new_fw_data, fw->data, fw->size);
1428 new_fw.size = fw->size;
1429 new_fw.data = new_fw_data;
1430
1431 new_fw_data[idoff + 2] =
Chris Pascoe702a6762007-11-20 03:34:11 -03001432 le16_to_cpu(udev->descriptor.idProduct) + 1;
David Woodhousee62f89f2008-05-24 00:12:42 +01001433 new_fw_data[idoff + 3] =
Chris Pascoe702a6762007-11-20 03:34:11 -03001434 le16_to_cpu(udev->descriptor.idProduct) >> 8;
1435
David Woodhousee62f89f2008-05-24 00:12:42 +01001436 ret = usb_cypress_load_firmware(udev, &new_fw,
1437 CYPRESS_FX2);
1438 vfree(new_fw_data);
1439 return ret;
Chris Pascoe702a6762007-11-20 03:34:11 -03001440 }
Patrick Boettcherf5373782006-01-09 18:21:38 -02001441 }
1442
1443 return -EINVAL;
1444}
1445
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001446/* DVB USB Driver stuff */
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001447static struct dvb_usb_device_properties cxusb_medion_properties;
1448static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties;
1449static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties;
1450static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties;
1451static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties;
Chris Pascoeaeb012b2007-11-19 21:57:10 -03001452static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties;
Anton Blanchard8d798982008-08-09 12:23:15 -03001453static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties;
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001454static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties;
Chris Pascoe702a6762007-11-20 03:34:11 -03001455static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties;
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03001456static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
Timothy Leedfbdce02008-08-09 13:36:51 -03001457static struct dvb_usb_device_properties cxusb_d680_dmb_properties;
David Wongb18bd1d2009-10-26 09:41:22 -03001458static struct dvb_usb_device_properties cxusb_mygica_d689_properties;
CrazyCata0f629b2014-11-14 18:24:28 -03001459static struct dvb_usb_device_properties cxusb_mygica_t230_properties;
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001460
1461static int cxusb_probe(struct usb_interface *intf,
Michael Krufkyf35db232006-12-05 14:53:39 -03001462 const struct usb_device_id *id)
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001463{
Mauro Carvalho Chehab17ce0392016-10-07 06:30:27 -03001464 struct dvb_usb_device *d;
1465 struct cxusb_state *st;
1466
Janne Grunau78e92002008-04-09 19:13:13 -03001467 if (0 == dvb_usb_device_init(intf, &cxusb_medion_properties,
Mauro Carvalho Chehab17ce0392016-10-07 06:30:27 -03001468 THIS_MODULE, &d, adapter_nr) ||
Janne Grunau78e92002008-04-09 19:13:13 -03001469 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgh064f_properties,
Mauro Carvalho Chehab17ce0392016-10-07 06:30:27 -03001470 THIS_MODULE, &d, adapter_nr) ||
Janne Grunau78e92002008-04-09 19:13:13 -03001471 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dee1601_properties,
Mauro Carvalho Chehab17ce0392016-10-07 06:30:27 -03001472 THIS_MODULE, &d, adapter_nr) ||
Janne Grunau78e92002008-04-09 19:13:13 -03001473 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgz201_properties,
Mauro Carvalho Chehab17ce0392016-10-07 06:30:27 -03001474 THIS_MODULE, &d, adapter_nr) ||
Janne Grunau78e92002008-04-09 19:13:13 -03001475 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dtt7579_properties,
Mauro Carvalho Chehab17ce0392016-10-07 06:30:27 -03001476 THIS_MODULE, &d, adapter_nr) ||
Janne Grunau78e92002008-04-09 19:13:13 -03001477 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dualdig4_properties,
Mauro Carvalho Chehab17ce0392016-10-07 06:30:27 -03001478 THIS_MODULE, &d, adapter_nr) ||
Janne Grunau78e92002008-04-09 19:13:13 -03001479 0 == dvb_usb_device_init(intf, &cxusb_bluebird_nano2_properties,
Mauro Carvalho Chehab17ce0392016-10-07 06:30:27 -03001480 THIS_MODULE, &d, adapter_nr) ||
Janne Grunau78e92002008-04-09 19:13:13 -03001481 0 == dvb_usb_device_init(intf,
1482 &cxusb_bluebird_nano2_needsfirmware_properties,
Mauro Carvalho Chehab17ce0392016-10-07 06:30:27 -03001483 THIS_MODULE, &d, adapter_nr) ||
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03001484 0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties,
Mauro Carvalho Chehab17ce0392016-10-07 06:30:27 -03001485 THIS_MODULE, &d, adapter_nr) ||
Anton Blanchard8d798982008-08-09 12:23:15 -03001486 0 == dvb_usb_device_init(intf,
1487 &cxusb_bluebird_dualdig4_rev2_properties,
Mauro Carvalho Chehab17ce0392016-10-07 06:30:27 -03001488 THIS_MODULE, &d, adapter_nr) ||
Timothy Leedfbdce02008-08-09 13:36:51 -03001489 0 == dvb_usb_device_init(intf, &cxusb_d680_dmb_properties,
Mauro Carvalho Chehab17ce0392016-10-07 06:30:27 -03001490 THIS_MODULE, &d, adapter_nr) ||
David Wongb18bd1d2009-10-26 09:41:22 -03001491 0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties,
Mauro Carvalho Chehab17ce0392016-10-07 06:30:27 -03001492 THIS_MODULE, &d, adapter_nr) ||
CrazyCata0f629b2014-11-14 18:24:28 -03001493 0 == dvb_usb_device_init(intf, &cxusb_mygica_t230_properties,
Mauro Carvalho Chehab17ce0392016-10-07 06:30:27 -03001494 THIS_MODULE, &d, adapter_nr) ||
1495 0) {
1496 st = d->priv;
1497 mutex_init(&st->data_mutex);
1498
Michael Krufkyeffee032006-01-09 15:25:47 -02001499 return 0;
Mauro Carvalho Chehab17ce0392016-10-07 06:30:27 -03001500 }
Michael Krufkyeffee032006-01-09 15:25:47 -02001501
1502 return -EINVAL;
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001503}
1504
Olli Salonen26c42b02014-07-13 10:52:22 -03001505static void cxusb_disconnect(struct usb_interface *intf)
1506{
1507 struct dvb_usb_device *d = usb_get_intfdata(intf);
1508 struct cxusb_state *st = d->priv;
1509 struct i2c_client *client;
1510
1511 /* remove I2C client for tuner */
1512 client = st->i2c_client_tuner;
1513 if (client) {
1514 module_put(client->dev.driver->owner);
1515 i2c_unregister_device(client);
1516 }
1517
1518 /* remove I2C client for demodulator */
1519 client = st->i2c_client_demod;
1520 if (client) {
1521 module_put(client->dev.driver->owner);
1522 i2c_unregister_device(client);
1523 }
1524
1525 dvb_usb_device_exit(intf);
1526}
1527
David Howells974e08d2015-02-17 11:30:34 -03001528enum cxusb_table_index {
1529 MEDION_MD95700,
1530 DVICO_BLUEBIRD_LG064F_COLD,
1531 DVICO_BLUEBIRD_LG064F_WARM,
1532 DVICO_BLUEBIRD_DUAL_1_COLD,
1533 DVICO_BLUEBIRD_DUAL_1_WARM,
1534 DVICO_BLUEBIRD_LGZ201_COLD,
1535 DVICO_BLUEBIRD_LGZ201_WARM,
1536 DVICO_BLUEBIRD_TH7579_COLD,
1537 DVICO_BLUEBIRD_TH7579_WARM,
1538 DIGITALNOW_BLUEBIRD_DUAL_1_COLD,
1539 DIGITALNOW_BLUEBIRD_DUAL_1_WARM,
1540 DVICO_BLUEBIRD_DUAL_2_COLD,
1541 DVICO_BLUEBIRD_DUAL_2_WARM,
1542 DVICO_BLUEBIRD_DUAL_4,
1543 DVICO_BLUEBIRD_DVB_T_NANO_2,
1544 DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM,
1545 AVERMEDIA_VOLAR_A868R,
1546 DVICO_BLUEBIRD_DUAL_4_REV_2,
1547 CONEXANT_D680_DMB,
1548 MYGICA_D689,
1549 MYGICA_T230,
1550 NR__cxusb_table_index
1551};
1552
1553static struct usb_device_id cxusb_table[NR__cxusb_table_index + 1] = {
1554 [MEDION_MD95700] = {
1555 USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700)
1556 },
1557 [DVICO_BLUEBIRD_LG064F_COLD] = {
1558 USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD)
1559 },
1560 [DVICO_BLUEBIRD_LG064F_WARM] = {
1561 USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_WARM)
1562 },
1563 [DVICO_BLUEBIRD_DUAL_1_COLD] = {
1564 USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_COLD)
1565 },
1566 [DVICO_BLUEBIRD_DUAL_1_WARM] = {
1567 USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM)
1568 },
1569 [DVICO_BLUEBIRD_LGZ201_COLD] = {
1570 USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_COLD)
1571 },
1572 [DVICO_BLUEBIRD_LGZ201_WARM] = {
1573 USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_WARM)
1574 },
1575 [DVICO_BLUEBIRD_TH7579_COLD] = {
1576 USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_COLD)
1577 },
1578 [DVICO_BLUEBIRD_TH7579_WARM] = {
1579 USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_WARM)
1580 },
1581 [DIGITALNOW_BLUEBIRD_DUAL_1_COLD] = {
1582 USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD)
1583 },
1584 [DIGITALNOW_BLUEBIRD_DUAL_1_WARM] = {
1585 USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM)
1586 },
1587 [DVICO_BLUEBIRD_DUAL_2_COLD] = {
1588 USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD)
1589 },
1590 [DVICO_BLUEBIRD_DUAL_2_WARM] = {
1591 USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM)
1592 },
1593 [DVICO_BLUEBIRD_DUAL_4] = {
1594 USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4)
1595 },
1596 [DVICO_BLUEBIRD_DVB_T_NANO_2] = {
1597 USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2)
1598 },
1599 [DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM] = {
1600 USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM)
1601 },
1602 [AVERMEDIA_VOLAR_A868R] = {
1603 USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R)
1604 },
1605 [DVICO_BLUEBIRD_DUAL_4_REV_2] = {
1606 USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2)
1607 },
1608 [CONEXANT_D680_DMB] = {
1609 USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB)
1610 },
1611 [MYGICA_D689] = {
1612 USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689)
1613 },
1614 [MYGICA_T230] = {
1615 USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230)
1616 },
Michael Krufkyf35db232006-12-05 14:53:39 -03001617 {} /* Terminating entry */
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001618};
1619MODULE_DEVICE_TABLE (usb, cxusb_table);
1620
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001621static struct dvb_usb_device_properties cxusb_medion_properties = {
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001622 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1623
1624 .usb_ctrl = CYPRESS_FX2,
1625
1626 .size_of_priv = sizeof(struct cxusb_state),
1627
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001628 .num_adapters = 1,
1629 .adapter = {
1630 {
Michael Krufky77eed212011-09-06 09:31:57 -03001631 .num_frontends = 1,
1632 .fe = {{
Patrick Boettcher01451e72006-10-13 11:34:46 -03001633 .streaming_ctrl = cxusb_streaming_ctrl,
1634 .frontend_attach = cxusb_cx22702_frontend_attach,
1635 .tuner_attach = cxusb_fmd1216me_tuner_attach,
1636 /* parameter for the MPEG2-data transfer */
1637 .stream = {
1638 .type = USB_BULK,
1639 .count = 5,
1640 .endpoint = 0x02,
1641 .u = {
1642 .bulk = {
1643 .buffersize = 8192,
1644 }
1645 }
1646 },
Michael Krufky77eed212011-09-06 09:31:57 -03001647 }},
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001648 },
1649 },
1650 .power_ctrl = cxusb_power_ctrl,
1651
1652 .i2c_algo = &cxusb_i2c_algo,
1653
1654 .generic_bulk_ctrl_endpoint = 0x01,
1655
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001656 .num_device_descs = 1,
1657 .devices = {
1658 { "Medion MD95700 (MDUSBTV-HYBRID)",
1659 { NULL },
David Howells974e08d2015-02-17 11:30:34 -03001660 { &cxusb_table[MEDION_MD95700], NULL },
Patrick Boettcher22c6d932005-07-07 17:58:10 -07001661 },
1662 }
1663};
1664
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001665static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = {
Michael Krufkyeffee032006-01-09 15:25:47 -02001666 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1667
Patrick Boettcherf5373782006-01-09 18:21:38 -02001668 .usb_ctrl = DEVICE_SPECIFIC,
1669 .firmware = "dvb-usb-bluebird-01.fw",
1670 .download_firmware = bluebird_patch_dvico_firmware_download,
Michael Krufky37bdfa02006-01-09 15:25:47 -02001671 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1672 use usb alt setting 7 for EP2 transfer (atsc) */
Michael Krufkyeffee032006-01-09 15:25:47 -02001673
1674 .size_of_priv = sizeof(struct cxusb_state),
1675
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001676 .num_adapters = 1,
1677 .adapter = {
1678 {
Michael Krufky77eed212011-09-06 09:31:57 -03001679 .num_frontends = 1,
1680 .fe = {{
Patrick Boettcher01451e72006-10-13 11:34:46 -03001681 .streaming_ctrl = cxusb_streaming_ctrl,
1682 .frontend_attach = cxusb_lgdt3303_frontend_attach,
Michael Krufkyf71a56c2006-10-13 21:55:57 -03001683 .tuner_attach = cxusb_lgh064f_tuner_attach,
Michael Krufkyeffee032006-01-09 15:25:47 -02001684
Patrick Boettcher01451e72006-10-13 11:34:46 -03001685 /* parameter for the MPEG2-data transfer */
1686 .stream = {
1687 .type = USB_BULK,
1688 .count = 5,
1689 .endpoint = 0x02,
1690 .u = {
1691 .bulk = {
1692 .buffersize = 8192,
1693 }
1694 }
1695 },
Michael Krufky77eed212011-09-06 09:31:57 -03001696 }},
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001697 },
1698 },
1699
1700 .power_ctrl = cxusb_bluebird_power_ctrl,
1701
Michael Krufkyeffee032006-01-09 15:25:47 -02001702 .i2c_algo = &cxusb_i2c_algo,
1703
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001704 .rc.legacy = {
1705 .rc_interval = 100,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03001706 .rc_map_table = rc_map_dvico_portable_table,
1707 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001708 .rc_query = cxusb_rc_query,
1709 },
Michael Krufkyc1501782006-03-26 05:43:36 -03001710
Michael Krufkyeffee032006-01-09 15:25:47 -02001711 .generic_bulk_ctrl_endpoint = 0x01,
Michael Krufkyeffee032006-01-09 15:25:47 -02001712
1713 .num_device_descs = 1,
1714 .devices = {
1715 { "DViCO FusionHDTV5 USB Gold",
David Howells974e08d2015-02-17 11:30:34 -03001716 { &cxusb_table[DVICO_BLUEBIRD_LG064F_COLD], NULL },
1717 { &cxusb_table[DVICO_BLUEBIRD_LG064F_WARM], NULL },
Michael Krufkyeffee032006-01-09 15:25:47 -02001718 },
1719 }
1720};
1721
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001722static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = {
Chris Pascoe0029ee12006-01-09 18:21:28 -02001723 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1724
Patrick Boettcherf5373782006-01-09 18:21:38 -02001725 .usb_ctrl = DEVICE_SPECIFIC,
1726 .firmware = "dvb-usb-bluebird-01.fw",
1727 .download_firmware = bluebird_patch_dvico_firmware_download,
Chris Pascoe0029ee12006-01-09 18:21:28 -02001728 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1729 use usb alt setting 7 for EP2 transfer (atsc) */
1730
1731 .size_of_priv = sizeof(struct cxusb_state),
1732
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001733 .num_adapters = 1,
1734 .adapter = {
1735 {
Michael Krufky77eed212011-09-06 09:31:57 -03001736 .num_frontends = 1,
1737 .fe = {{
Patrick Boettcher01451e72006-10-13 11:34:46 -03001738 .streaming_ctrl = cxusb_streaming_ctrl,
1739 .frontend_attach = cxusb_dee1601_frontend_attach,
1740 .tuner_attach = cxusb_dee1601_tuner_attach,
1741 /* parameter for the MPEG2-data transfer */
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001742 .stream = {
1743 .type = USB_BULK,
Patrick Boettcher01451e72006-10-13 11:34:46 -03001744 .count = 5,
1745 .endpoint = 0x04,
1746 .u = {
1747 .bulk = {
1748 .buffersize = 8192,
1749 }
1750 }
1751 },
Michael Krufky77eed212011-09-06 09:31:57 -03001752 }},
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001753 },
1754 },
1755
1756 .power_ctrl = cxusb_bluebird_power_ctrl,
Chris Pascoe0029ee12006-01-09 18:21:28 -02001757
1758 .i2c_algo = &cxusb_i2c_algo,
1759
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001760 .rc.legacy = {
1761 .rc_interval = 150,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03001762 .rc_map_table = rc_map_dvico_mce_table,
1763 .rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001764 .rc_query = cxusb_rc_query,
1765 },
Chris Pascoe7c239702006-01-09 18:21:29 -02001766
Chris Pascoe0029ee12006-01-09 18:21:28 -02001767 .generic_bulk_ctrl_endpoint = 0x01,
Chris Pascoe0029ee12006-01-09 18:21:28 -02001768
Michael Krufky587c03d2006-09-28 02:16:01 -03001769 .num_device_descs = 3,
Chris Pascoe0029ee12006-01-09 18:21:28 -02001770 .devices = {
1771 { "DViCO FusionHDTV DVB-T Dual USB",
David Howells974e08d2015-02-17 11:30:34 -03001772 { &cxusb_table[DVICO_BLUEBIRD_DUAL_1_COLD], NULL },
1773 { &cxusb_table[DVICO_BLUEBIRD_DUAL_1_WARM], NULL },
Chris Pascoe0029ee12006-01-09 18:21:28 -02001774 },
Michael Krufkyac9ffb92006-01-11 23:21:00 -02001775 { "DigitalNow DVB-T Dual USB",
David Howells974e08d2015-02-17 11:30:34 -03001776 { &cxusb_table[DIGITALNOW_BLUEBIRD_DUAL_1_COLD], NULL },
1777 { &cxusb_table[DIGITALNOW_BLUEBIRD_DUAL_1_WARM], NULL },
Michael Krufkyac9ffb92006-01-11 23:21:00 -02001778 },
Michael Krufky587c03d2006-09-28 02:16:01 -03001779 { "DViCO FusionHDTV DVB-T Dual Digital 2",
David Howells974e08d2015-02-17 11:30:34 -03001780 { &cxusb_table[DVICO_BLUEBIRD_DUAL_2_COLD], NULL },
1781 { &cxusb_table[DVICO_BLUEBIRD_DUAL_2_WARM], NULL },
Michael Krufky587c03d2006-09-28 02:16:01 -03001782 },
Chris Pascoe0029ee12006-01-09 18:21:28 -02001783 }
1784};
1785
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001786static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = {
Michael Krufky6f447252006-01-11 19:40:33 -02001787 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1788
1789 .usb_ctrl = DEVICE_SPECIFIC,
1790 .firmware = "dvb-usb-bluebird-01.fw",
1791 .download_firmware = bluebird_patch_dvico_firmware_download,
1792 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1793 use usb alt setting 7 for EP2 transfer (atsc) */
1794
1795 .size_of_priv = sizeof(struct cxusb_state),
1796
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001797 .num_adapters = 2,
1798 .adapter = {
1799 {
Michael Krufky77eed212011-09-06 09:31:57 -03001800 .num_frontends = 1,
1801 .fe = {{
Patrick Boettcher01451e72006-10-13 11:34:46 -03001802 .streaming_ctrl = cxusb_streaming_ctrl,
1803 .frontend_attach = cxusb_mt352_frontend_attach,
1804 .tuner_attach = cxusb_lgz201_tuner_attach,
Michael Krufky6f447252006-01-11 19:40:33 -02001805
Patrick Boettcher01451e72006-10-13 11:34:46 -03001806 /* parameter for the MPEG2-data transfer */
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001807 .stream = {
1808 .type = USB_BULK,
Patrick Boettcher01451e72006-10-13 11:34:46 -03001809 .count = 5,
1810 .endpoint = 0x04,
1811 .u = {
1812 .bulk = {
1813 .buffersize = 8192,
1814 }
1815 }
1816 },
Michael Krufky77eed212011-09-06 09:31:57 -03001817 }},
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001818 },
1819 },
1820 .power_ctrl = cxusb_bluebird_power_ctrl,
1821
Michael Krufky6f447252006-01-11 19:40:33 -02001822 .i2c_algo = &cxusb_i2c_algo,
1823
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001824 .rc.legacy = {
1825 .rc_interval = 100,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03001826 .rc_map_table = rc_map_dvico_portable_table,
1827 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001828 .rc_query = cxusb_rc_query,
1829 },
Michael Krufkyc1501782006-03-26 05:43:36 -03001830
Michael Krufky6f447252006-01-11 19:40:33 -02001831 .generic_bulk_ctrl_endpoint = 0x01,
Michael Krufky6f447252006-01-11 19:40:33 -02001832 .num_device_descs = 1,
1833 .devices = {
1834 { "DViCO FusionHDTV DVB-T USB (LGZ201)",
David Howells974e08d2015-02-17 11:30:34 -03001835 { &cxusb_table[DVICO_BLUEBIRD_LGZ201_COLD], NULL },
1836 { &cxusb_table[DVICO_BLUEBIRD_LGZ201_WARM], NULL },
Michael Krufky6f447252006-01-11 19:40:33 -02001837 },
1838 }
1839};
1840
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001841static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = {
Michael Krufky6f447252006-01-11 19:40:33 -02001842 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1843
1844 .usb_ctrl = DEVICE_SPECIFIC,
1845 .firmware = "dvb-usb-bluebird-01.fw",
1846 .download_firmware = bluebird_patch_dvico_firmware_download,
1847 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1848 use usb alt setting 7 for EP2 transfer (atsc) */
1849
1850 .size_of_priv = sizeof(struct cxusb_state),
1851
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001852 .num_adapters = 1,
1853 .adapter = {
1854 {
Michael Krufky77eed212011-09-06 09:31:57 -03001855 .num_frontends = 1,
1856 .fe = {{
Patrick Boettcher01451e72006-10-13 11:34:46 -03001857 .streaming_ctrl = cxusb_streaming_ctrl,
1858 .frontend_attach = cxusb_mt352_frontend_attach,
1859 .tuner_attach = cxusb_dtt7579_tuner_attach,
Michael Krufky6f447252006-01-11 19:40:33 -02001860
Patrick Boettcher01451e72006-10-13 11:34:46 -03001861 /* parameter for the MPEG2-data transfer */
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001862 .stream = {
1863 .type = USB_BULK,
Patrick Boettcher01451e72006-10-13 11:34:46 -03001864 .count = 5,
1865 .endpoint = 0x04,
1866 .u = {
1867 .bulk = {
1868 .buffersize = 8192,
1869 }
1870 }
1871 },
Michael Krufky77eed212011-09-06 09:31:57 -03001872 }},
Patrick Boettcher4d43e132006-09-30 06:53:48 -03001873 },
1874 },
1875 .power_ctrl = cxusb_bluebird_power_ctrl,
1876
Michael Krufky6f447252006-01-11 19:40:33 -02001877 .i2c_algo = &cxusb_i2c_algo,
1878
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001879 .rc.legacy = {
1880 .rc_interval = 100,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03001881 .rc_map_table = rc_map_dvico_portable_table,
1882 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001883 .rc_query = cxusb_rc_query,
1884 },
Michael Krufkyc1501782006-03-26 05:43:36 -03001885
Michael Krufky6f447252006-01-11 19:40:33 -02001886 .generic_bulk_ctrl_endpoint = 0x01,
Michael Krufky6f447252006-01-11 19:40:33 -02001887
1888 .num_device_descs = 1,
1889 .devices = {
1890 { "DViCO FusionHDTV DVB-T USB (TH7579)",
David Howells974e08d2015-02-17 11:30:34 -03001891 { &cxusb_table[DVICO_BLUEBIRD_TH7579_COLD], NULL },
1892 { &cxusb_table[DVICO_BLUEBIRD_TH7579_WARM], NULL },
Michael Krufky6f447252006-01-11 19:40:33 -02001893 },
1894 }
1895};
1896
Chris Pascoeaeb012b2007-11-19 21:57:10 -03001897static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = {
1898 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1899
1900 .usb_ctrl = CYPRESS_FX2,
1901
1902 .size_of_priv = sizeof(struct cxusb_state),
1903
1904 .num_adapters = 1,
1905 .adapter = {
1906 {
Michael Krufky77eed212011-09-06 09:31:57 -03001907 .num_frontends = 1,
1908 .fe = {{
Chris Pascoeaeb012b2007-11-19 21:57:10 -03001909 .streaming_ctrl = cxusb_streaming_ctrl,
1910 .frontend_attach = cxusb_dualdig4_frontend_attach,
1911 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1912 /* parameter for the MPEG2-data transfer */
1913 .stream = {
1914 .type = USB_BULK,
1915 .count = 5,
1916 .endpoint = 0x02,
1917 .u = {
1918 .bulk = {
1919 .buffersize = 8192,
1920 }
1921 }
1922 },
Michael Krufky77eed212011-09-06 09:31:57 -03001923 }},
Chris Pascoeaeb012b2007-11-19 21:57:10 -03001924 },
1925 },
1926
1927 .power_ctrl = cxusb_power_ctrl,
1928
1929 .i2c_algo = &cxusb_i2c_algo,
1930
1931 .generic_bulk_ctrl_endpoint = 0x01,
1932
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001933 .rc.legacy = {
1934 .rc_interval = 100,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03001935 .rc_map_table = rc_map_dvico_mce_table,
1936 .rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001937 .rc_query = cxusb_bluebird2_rc_query,
1938 },
Chris Pascoeaeb012b2007-11-19 21:57:10 -03001939
1940 .num_device_descs = 1,
1941 .devices = {
1942 { "DViCO FusionHDTV DVB-T Dual Digital 4",
1943 { NULL },
David Howells974e08d2015-02-17 11:30:34 -03001944 { &cxusb_table[DVICO_BLUEBIRD_DUAL_4], NULL },
Chris Pascoeaeb012b2007-11-19 21:57:10 -03001945 },
1946 }
1947};
1948
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001949static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = {
1950 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1951
1952 .usb_ctrl = CYPRESS_FX2,
Chris Pascoe702a6762007-11-20 03:34:11 -03001953 .identify_state = bluebird_fx2_identify_state,
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001954
1955 .size_of_priv = sizeof(struct cxusb_state),
1956
1957 .num_adapters = 1,
1958 .adapter = {
1959 {
Michael Krufky77eed212011-09-06 09:31:57 -03001960 .num_frontends = 1,
1961 .fe = {{
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001962 .streaming_ctrl = cxusb_streaming_ctrl,
1963 .frontend_attach = cxusb_nano2_frontend_attach,
1964 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1965 /* parameter for the MPEG2-data transfer */
1966 .stream = {
1967 .type = USB_BULK,
1968 .count = 5,
1969 .endpoint = 0x02,
1970 .u = {
1971 .bulk = {
1972 .buffersize = 8192,
1973 }
1974 }
1975 },
Michael Krufky77eed212011-09-06 09:31:57 -03001976 }},
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001977 },
1978 },
1979
1980 .power_ctrl = cxusb_nano2_power_ctrl,
1981
1982 .i2c_algo = &cxusb_i2c_algo,
1983
1984 .generic_bulk_ctrl_endpoint = 0x01,
1985
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001986 .rc.legacy = {
1987 .rc_interval = 100,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03001988 .rc_map_table = rc_map_dvico_portable_table,
1989 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001990 .rc_query = cxusb_bluebird2_rc_query,
1991 },
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001992
1993 .num_device_descs = 1,
1994 .devices = {
1995 { "DViCO FusionHDTV DVB-T NANO2",
1996 { NULL },
David Howells974e08d2015-02-17 11:30:34 -03001997 { &cxusb_table[DVICO_BLUEBIRD_DVB_T_NANO_2], NULL },
Chris Pascoe5ccaf902007-11-20 01:53:31 -03001998 },
1999 }
2000};
2001
Chris Pascoe702a6762007-11-20 03:34:11 -03002002static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties = {
2003 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
2004
2005 .usb_ctrl = DEVICE_SPECIFIC,
2006 .firmware = "dvb-usb-bluebird-02.fw",
2007 .download_firmware = bluebird_patch_dvico_firmware_download,
2008 .identify_state = bluebird_fx2_identify_state,
2009
2010 .size_of_priv = sizeof(struct cxusb_state),
2011
2012 .num_adapters = 1,
2013 .adapter = {
2014 {
Michael Krufky77eed212011-09-06 09:31:57 -03002015 .num_frontends = 1,
2016 .fe = {{
Chris Pascoe702a6762007-11-20 03:34:11 -03002017 .streaming_ctrl = cxusb_streaming_ctrl,
2018 .frontend_attach = cxusb_nano2_frontend_attach,
2019 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
2020 /* parameter for the MPEG2-data transfer */
2021 .stream = {
2022 .type = USB_BULK,
2023 .count = 5,
2024 .endpoint = 0x02,
2025 .u = {
2026 .bulk = {
2027 .buffersize = 8192,
2028 }
2029 }
2030 },
Michael Krufky77eed212011-09-06 09:31:57 -03002031 }},
Chris Pascoe702a6762007-11-20 03:34:11 -03002032 },
2033 },
2034
2035 .power_ctrl = cxusb_nano2_power_ctrl,
2036
2037 .i2c_algo = &cxusb_i2c_algo,
2038
2039 .generic_bulk_ctrl_endpoint = 0x01,
2040
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03002041 .rc.legacy = {
2042 .rc_interval = 100,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03002043 .rc_map_table = rc_map_dvico_portable_table,
2044 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03002045 .rc_query = cxusb_rc_query,
2046 },
Chris Pascoe702a6762007-11-20 03:34:11 -03002047
2048 .num_device_descs = 1,
2049 .devices = {
2050 { "DViCO FusionHDTV DVB-T NANO2 w/o firmware",
David Howells974e08d2015-02-17 11:30:34 -03002051 { &cxusb_table[DVICO_BLUEBIRD_DVB_T_NANO_2], NULL },
2052 { &cxusb_table[DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM], NULL },
Chris Pascoe702a6762007-11-20 03:34:11 -03002053 },
2054 }
2055};
2056
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03002057static struct dvb_usb_device_properties cxusb_aver_a868r_properties = {
2058 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
2059
2060 .usb_ctrl = CYPRESS_FX2,
2061
2062 .size_of_priv = sizeof(struct cxusb_state),
2063
2064 .num_adapters = 1,
2065 .adapter = {
2066 {
Michael Krufky77eed212011-09-06 09:31:57 -03002067 .num_frontends = 1,
2068 .fe = {{
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03002069 .streaming_ctrl = cxusb_aver_streaming_ctrl,
2070 .frontend_attach = cxusb_aver_lgdt3303_frontend_attach,
2071 .tuner_attach = cxusb_mxl5003s_tuner_attach,
2072 /* parameter for the MPEG2-data transfer */
2073 .stream = {
2074 .type = USB_BULK,
2075 .count = 5,
2076 .endpoint = 0x04,
2077 .u = {
2078 .bulk = {
2079 .buffersize = 8192,
2080 }
2081 }
2082 },
Michael Krufky77eed212011-09-06 09:31:57 -03002083 }},
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03002084 },
2085 },
2086 .power_ctrl = cxusb_aver_power_ctrl,
2087
2088 .i2c_algo = &cxusb_i2c_algo,
2089
2090 .generic_bulk_ctrl_endpoint = 0x01,
2091
2092 .num_device_descs = 1,
2093 .devices = {
2094 { "AVerMedia AVerTVHD Volar (A868R)",
2095 { NULL },
David Howells974e08d2015-02-17 11:30:34 -03002096 { &cxusb_table[AVERMEDIA_VOLAR_A868R], NULL },
Daniel Gimpelevichf5376ad2008-06-28 05:01:30 -03002097 },
2098 }
2099};
2100
Michael Krufkya2dc86b2008-08-09 13:06:26 -03002101static
2102struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = {
Anton Blanchard8d798982008-08-09 12:23:15 -03002103 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
2104
2105 .usb_ctrl = CYPRESS_FX2,
2106
2107 .size_of_priv = sizeof(struct cxusb_state),
2108
2109 .num_adapters = 1,
2110 .adapter = {
2111 {
Michael Krufky77eed212011-09-06 09:31:57 -03002112 .size_of_priv = sizeof(struct dib0700_adapter_state),
2113 .num_frontends = 1,
2114 .fe = {{
Michael Krufkya2dc86b2008-08-09 13:06:26 -03002115 .streaming_ctrl = cxusb_streaming_ctrl,
2116 .frontend_attach = cxusb_dualdig4_rev2_frontend_attach,
2117 .tuner_attach = cxusb_dualdig4_rev2_tuner_attach,
Anton Blanchard8d798982008-08-09 12:23:15 -03002118 /* parameter for the MPEG2-data transfer */
2119 .stream = {
2120 .type = USB_BULK,
2121 .count = 7,
2122 .endpoint = 0x02,
2123 .u = {
2124 .bulk = {
2125 .buffersize = 4096,
2126 }
2127 }
2128 },
Michael Krufky77eed212011-09-06 09:31:57 -03002129 }},
Anton Blanchard8d798982008-08-09 12:23:15 -03002130 },
2131 },
2132
2133 .power_ctrl = cxusb_bluebird_power_ctrl,
2134
2135 .i2c_algo = &cxusb_i2c_algo,
2136
2137 .generic_bulk_ctrl_endpoint = 0x01,
2138
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03002139 .rc.legacy = {
2140 .rc_interval = 100,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03002141 .rc_map_table = rc_map_dvico_mce_table,
2142 .rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03002143 .rc_query = cxusb_rc_query,
2144 },
Anton Blanchard8d798982008-08-09 12:23:15 -03002145
2146 .num_device_descs = 1,
2147 .devices = {
2148 { "DViCO FusionHDTV DVB-T Dual Digital 4 (rev 2)",
2149 { NULL },
David Howells974e08d2015-02-17 11:30:34 -03002150 { &cxusb_table[DVICO_BLUEBIRD_DUAL_4_REV_2], NULL },
Anton Blanchard8d798982008-08-09 12:23:15 -03002151 },
2152 }
2153};
2154
Timothy Leedfbdce02008-08-09 13:36:51 -03002155static struct dvb_usb_device_properties cxusb_d680_dmb_properties = {
2156 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
2157
2158 .usb_ctrl = CYPRESS_FX2,
2159
2160 .size_of_priv = sizeof(struct cxusb_state),
2161
2162 .num_adapters = 1,
2163 .adapter = {
2164 {
Michael Krufky77eed212011-09-06 09:31:57 -03002165 .num_frontends = 1,
2166 .fe = {{
Timothy Leedfbdce02008-08-09 13:36:51 -03002167 .streaming_ctrl = cxusb_d680_dmb_streaming_ctrl,
2168 .frontend_attach = cxusb_d680_dmb_frontend_attach,
2169 .tuner_attach = cxusb_d680_dmb_tuner_attach,
2170
2171 /* parameter for the MPEG2-data transfer */
2172 .stream = {
2173 .type = USB_BULK,
2174 .count = 5,
2175 .endpoint = 0x02,
2176 .u = {
2177 .bulk = {
2178 .buffersize = 8192,
2179 }
2180 }
2181 },
Michael Krufky77eed212011-09-06 09:31:57 -03002182 }},
Timothy Leedfbdce02008-08-09 13:36:51 -03002183 },
2184 },
2185
2186 .power_ctrl = cxusb_d680_dmb_power_ctrl,
2187
2188 .i2c_algo = &cxusb_i2c_algo,
2189
2190 .generic_bulk_ctrl_endpoint = 0x01,
2191
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03002192 .rc.legacy = {
2193 .rc_interval = 100,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03002194 .rc_map_table = rc_map_d680_dmb_table,
2195 .rc_map_size = ARRAY_SIZE(rc_map_d680_dmb_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03002196 .rc_query = cxusb_d680_dmb_rc_query,
2197 },
Timothy Leedfbdce02008-08-09 13:36:51 -03002198
2199 .num_device_descs = 1,
2200 .devices = {
2201 {
2202 "Conexant DMB-TH Stick",
2203 { NULL },
David Howells974e08d2015-02-17 11:30:34 -03002204 { &cxusb_table[CONEXANT_D680_DMB], NULL },
Timothy Leedfbdce02008-08-09 13:36:51 -03002205 },
2206 }
2207};
2208
David Wongb18bd1d2009-10-26 09:41:22 -03002209static struct dvb_usb_device_properties cxusb_mygica_d689_properties = {
2210 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
2211
2212 .usb_ctrl = CYPRESS_FX2,
2213
2214 .size_of_priv = sizeof(struct cxusb_state),
2215
2216 .num_adapters = 1,
2217 .adapter = {
2218 {
Michael Krufky77eed212011-09-06 09:31:57 -03002219 .num_frontends = 1,
2220 .fe = {{
David Wongb18bd1d2009-10-26 09:41:22 -03002221 .streaming_ctrl = cxusb_d680_dmb_streaming_ctrl,
2222 .frontend_attach = cxusb_mygica_d689_frontend_attach,
2223 .tuner_attach = cxusb_mygica_d689_tuner_attach,
2224
2225 /* parameter for the MPEG2-data transfer */
2226 .stream = {
2227 .type = USB_BULK,
2228 .count = 5,
2229 .endpoint = 0x02,
2230 .u = {
2231 .bulk = {
2232 .buffersize = 8192,
2233 }
2234 }
2235 },
Michael Krufky77eed212011-09-06 09:31:57 -03002236 }},
David Wongb18bd1d2009-10-26 09:41:22 -03002237 },
2238 },
2239
2240 .power_ctrl = cxusb_d680_dmb_power_ctrl,
2241
2242 .i2c_algo = &cxusb_i2c_algo,
2243
2244 .generic_bulk_ctrl_endpoint = 0x01,
2245
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03002246 .rc.legacy = {
2247 .rc_interval = 100,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03002248 .rc_map_table = rc_map_d680_dmb_table,
2249 .rc_map_size = ARRAY_SIZE(rc_map_d680_dmb_table),
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03002250 .rc_query = cxusb_d680_dmb_rc_query,
2251 },
David Wongb18bd1d2009-10-26 09:41:22 -03002252
2253 .num_device_descs = 1,
2254 .devices = {
2255 {
2256 "Mygica D689 DMB-TH",
2257 { NULL },
David Howells974e08d2015-02-17 11:30:34 -03002258 { &cxusb_table[MYGICA_D689], NULL },
David Wongb18bd1d2009-10-26 09:41:22 -03002259 },
2260 }
2261};
2262
CrazyCata0f629b2014-11-14 18:24:28 -03002263static struct dvb_usb_device_properties cxusb_mygica_t230_properties = {
2264 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
2265
2266 .usb_ctrl = CYPRESS_FX2,
2267
2268 .size_of_priv = sizeof(struct cxusb_state),
2269
2270 .num_adapters = 1,
2271 .adapter = {
2272 {
2273 .num_frontends = 1,
2274 .fe = {{
2275 .streaming_ctrl = cxusb_streaming_ctrl,
2276 .frontend_attach = cxusb_mygica_t230_frontend_attach,
2277
2278 /* parameter for the MPEG2-data transfer */
2279 .stream = {
2280 .type = USB_BULK,
2281 .count = 5,
2282 .endpoint = 0x02,
2283 .u = {
2284 .bulk = {
2285 .buffersize = 8192,
2286 }
2287 }
2288 },
2289 } },
2290 },
2291 },
2292
2293 .power_ctrl = cxusb_d680_dmb_power_ctrl,
2294
2295 .i2c_algo = &cxusb_i2c_algo,
2296
2297 .generic_bulk_ctrl_endpoint = 0x01,
2298
2299 .rc.legacy = {
2300 .rc_interval = 100,
2301 .rc_map_table = rc_map_d680_dmb_table,
2302 .rc_map_size = ARRAY_SIZE(rc_map_d680_dmb_table),
2303 .rc_query = cxusb_d680_dmb_rc_query,
2304 },
2305
2306 .num_device_descs = 1,
2307 .devices = {
2308 {
2309 "Mygica T230 DVB-T/T2/C",
2310 { NULL },
David Howells974e08d2015-02-17 11:30:34 -03002311 { &cxusb_table[MYGICA_T230], NULL },
CrazyCata0f629b2014-11-14 18:24:28 -03002312 },
2313 }
2314};
2315
Patrick Boettcher22c6d932005-07-07 17:58:10 -07002316static struct usb_driver cxusb_driver = {
Patrick Boettcher63b5c1c2005-07-07 17:58:30 -07002317 .name = "dvb_usb_cxusb",
Patrick Boettcher22c6d932005-07-07 17:58:10 -07002318 .probe = cxusb_probe,
Olli Salonen26c42b02014-07-13 10:52:22 -03002319 .disconnect = cxusb_disconnect,
Patrick Boettcher22c6d932005-07-07 17:58:10 -07002320 .id_table = cxusb_table,
2321};
2322
Greg Kroah-Hartmanecb3b2b2011-11-18 09:46:12 -08002323module_usb_driver(cxusb_driver);
Patrick Boettcher22c6d932005-07-07 17:58:10 -07002324
Patrick Boettcher99e44da2016-01-24 12:56:58 -02002325MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
Michael Krufky5b9ed282006-10-15 14:51:08 -03002326MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
Michael Krufkyf4efb4d2006-01-13 14:10:25 -02002327MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
Patrick Boettcher22c6d932005-07-07 17:58:10 -07002328MODULE_DESCRIPTION("Driver for Conexant USB2.0 hybrid reference design");
2329MODULE_VERSION("1.0-alpha");
2330MODULE_LICENSE("GPL");