Commit | Line | Data |
---|---|---|
22c6d93a PB |
1 | /* 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 | * | |
81481e9e | 14 | * TODO: Use the cx25840-driver for the analogue part |
22c6d93a | 15 | * |
22c6d93a | 16 | * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de) |
5b9ed286 | 17 | * Copyright (C) 2006 Michael Krufky (mkrufky@linuxtv.org) |
aeb012bb | 18 | * Copyright (C) 2006, 2007 Chris Pascoe (c.pascoe@itee.uq.edu.au) |
22c6d93a | 19 | * |
f35db23c MK |
20 | * 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. | |
22c6d93a PB |
23 | * |
24 | * see Documentation/dvb/README.dvb-usb for more information | |
25 | */ | |
827855d3 | 26 | #include <media/tuner.h> |
e62f89f2 | 27 | #include <linux/vmalloc.h> |
5a0e3ad6 | 28 | #include <linux/slab.h> |
827855d3 | 29 | |
22c6d93a PB |
30 | #include "cxusb.h" |
31 | ||
32 | #include "cx22702.h" | |
effee033 | 33 | #include "lgdt330x.h" |
0029ee14 CP |
34 | #include "mt352.h" |
35 | #include "mt352_priv.h" | |
c9ce3940 | 36 | #include "zl10353.h" |
aeb012bb | 37 | #include "tuner-xc2028.h" |
827855d3 | 38 | #include "tuner-simple.h" |
f5376ada | 39 | #include "mxl5005s.h" |
b18bd1d8 | 40 | #include "max2165.h" |
8d798988 AB |
41 | #include "dib7000p.h" |
42 | #include "dib0070.h" | |
6bf1a997 | 43 | #include "lgs8gxx.h" |
b18bd1d8 | 44 | #include "atbm8830.h" |
26c42b0d OS |
45 | #include "si2168.h" |
46 | #include "si2157.h" | |
22c6d93a | 47 | |
64f7ef8a | 48 | /* Max transfer size done by I2C transfer functions */ |
eb9da073 | 49 | #define MAX_XFER_SIZE 80 |
64f7ef8a | 50 | |
22c6d93a | 51 | /* debug */ |
53133afb | 52 | static int dvb_usb_cxusb_debug; |
f35db23c | 53 | module_param_named(debug, dvb_usb_cxusb_debug, int, 0644); |
22c6d93a | 54 | MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); |
78e92006 JG |
55 | |
56 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | |
57 | ||
f5376ada DG |
58 | #define deb_info(args...) dprintk(dvb_usb_cxusb_debug, 0x03, args) |
59 | #define deb_i2c(args...) dprintk(dvb_usb_cxusb_debug, 0x02, args) | |
22c6d93a PB |
60 | |
61 | static int cxusb_ctrl_msg(struct dvb_usb_device *d, | |
f35db23c | 62 | u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen) |
22c6d93a PB |
63 | { |
64 | int wo = (rbuf == NULL || rlen == 0); /* write-only */ | |
64f7ef8a MCC |
65 | u8 sndbuf[MAX_XFER_SIZE]; |
66 | ||
67 | if (1 + wlen > sizeof(sndbuf)) { | |
68 | warn("i2c wr: len=%d is too big!\n", | |
69 | wlen); | |
70 | return -EOPNOTSUPP; | |
71 | } | |
72 | ||
f35db23c | 73 | memset(sndbuf, 0, 1+wlen); |
22c6d93a PB |
74 | |
75 | sndbuf[0] = cmd; | |
f35db23c | 76 | memcpy(&sndbuf[1], wbuf, wlen); |
22c6d93a | 77 | if (wo) |
b17f109d | 78 | return dvb_usb_generic_write(d, sndbuf, 1+wlen); |
22c6d93a | 79 | else |
b17f109d | 80 | return dvb_usb_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen, 0); |
22c6d93a PB |
81 | } |
82 | ||
e2efeab2 PB |
83 | /* GPIO */ |
84 | static void cxusb_gpio_tuner(struct dvb_usb_device *d, int onoff) | |
22c6d93a PB |
85 | { |
86 | struct cxusb_state *st = d->priv; | |
f35db23c | 87 | u8 o[2], i; |
22c6d93a | 88 | |
e2efeab2 | 89 | if (st->gpio_write_state[GPIO_TUNER] == onoff) |
22c6d93a PB |
90 | return; |
91 | ||
e2efeab2 PB |
92 | o[0] = GPIO_TUNER; |
93 | o[1] = onoff; | |
f35db23c | 94 | cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1); |
22c6d93a PB |
95 | |
96 | if (i != 0x01) | |
e2efeab2 | 97 | deb_info("gpio_write failed.\n"); |
22c6d93a | 98 | |
e2efeab2 | 99 | st->gpio_write_state[GPIO_TUNER] = onoff; |
22c6d93a PB |
100 | } |
101 | ||
aeb012bb CP |
102 | static int cxusb_bluebird_gpio_rw(struct dvb_usb_device *d, u8 changemask, |
103 | u8 newval) | |
104 | { | |
105 | u8 o[2], gpio_state; | |
106 | int rc; | |
107 | ||
108 | o[0] = 0xff & ~changemask; /* mask of bits to keep */ | |
109 | o[1] = newval & changemask; /* new values for bits */ | |
110 | ||
111 | rc = cxusb_ctrl_msg(d, CMD_BLUEBIRD_GPIO_RW, o, 2, &gpio_state, 1); | |
112 | if (rc < 0 || (gpio_state & changemask) != (newval & changemask)) | |
113 | deb_info("bluebird_gpio_write failed.\n"); | |
114 | ||
115 | return rc < 0 ? rc : gpio_state; | |
116 | } | |
117 | ||
118 | static void cxusb_bluebird_gpio_pulse(struct dvb_usb_device *d, u8 pin, int low) | |
119 | { | |
120 | cxusb_bluebird_gpio_rw(d, pin, low ? 0 : pin); | |
121 | msleep(5); | |
122 | cxusb_bluebird_gpio_rw(d, pin, low ? pin : 0); | |
123 | } | |
124 | ||
5ccaf905 CP |
125 | static void cxusb_nano2_led(struct dvb_usb_device *d, int onoff) |
126 | { | |
127 | cxusb_bluebird_gpio_rw(d, 0x40, onoff ? 0 : 0x40); | |
128 | } | |
129 | ||
dfbdce04 TL |
130 | static int cxusb_d680_dmb_gpio_tuner(struct dvb_usb_device *d, |
131 | u8 addr, int onoff) | |
132 | { | |
133 | u8 o[2] = {addr, onoff}; | |
134 | u8 i; | |
135 | int rc; | |
136 | ||
137 | rc = cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1); | |
138 | ||
139 | if (rc < 0) | |
140 | return rc; | |
141 | if (i == 0x01) | |
142 | return 0; | |
143 | else { | |
144 | deb_info("gpio_write failed.\n"); | |
145 | return -EIO; | |
146 | } | |
147 | } | |
148 | ||
e2efeab2 | 149 | /* I2C */ |
f35db23c MK |
150 | static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], |
151 | int num) | |
22c6d93a PB |
152 | { |
153 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | |
1cdbcc5d | 154 | int ret; |
22c6d93a PB |
155 | int i; |
156 | ||
3593cab5 | 157 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) |
22c6d93a PB |
158 | return -EAGAIN; |
159 | ||
22c6d93a PB |
160 | for (i = 0; i < num; i++) { |
161 | ||
41150cb9 | 162 | if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_MEDION) |
5e805eff | 163 | switch (msg[i].addr) { |
f35db23c MK |
164 | case 0x63: |
165 | cxusb_gpio_tuner(d, 0); | |
166 | break; | |
167 | default: | |
168 | cxusb_gpio_tuner(d, 1); | |
169 | break; | |
5e805eff | 170 | } |
22c6d93a | 171 | |
272479d7 CP |
172 | if (msg[i].flags & I2C_M_RD) { |
173 | /* read only */ | |
64f7ef8a MCC |
174 | u8 obuf[3], ibuf[MAX_XFER_SIZE]; |
175 | ||
176 | if (1 + msg[i].len > sizeof(ibuf)) { | |
177 | warn("i2c rd: len=%d is too big!\n", | |
178 | msg[i].len); | |
1cdbcc5d DC |
179 | ret = -EOPNOTSUPP; |
180 | goto unlock; | |
64f7ef8a | 181 | } |
272479d7 CP |
182 | obuf[0] = 0; |
183 | obuf[1] = msg[i].len; | |
184 | obuf[2] = msg[i].addr; | |
185 | if (cxusb_ctrl_msg(d, CMD_I2C_READ, | |
186 | obuf, 3, | |
187 | ibuf, 1+msg[i].len) < 0) { | |
188 | warn("i2c read failed"); | |
189 | break; | |
190 | } | |
191 | memcpy(msg[i].buf, &ibuf[1], msg[i].len); | |
a644e4a3 CP |
192 | } else if (i+1 < num && (msg[i+1].flags & I2C_M_RD) && |
193 | msg[i].addr == msg[i+1].addr) { | |
194 | /* write to then read from same address */ | |
64f7ef8a MCC |
195 | u8 obuf[MAX_XFER_SIZE], ibuf[MAX_XFER_SIZE]; |
196 | ||
197 | if (3 + msg[i].len > sizeof(obuf)) { | |
198 | warn("i2c wr: len=%d is too big!\n", | |
199 | msg[i].len); | |
1cdbcc5d DC |
200 | ret = -EOPNOTSUPP; |
201 | goto unlock; | |
64f7ef8a MCC |
202 | } |
203 | if (1 + msg[i + 1].len > sizeof(ibuf)) { | |
204 | warn("i2c rd: len=%d is too big!\n", | |
205 | msg[i + 1].len); | |
1cdbcc5d DC |
206 | ret = -EOPNOTSUPP; |
207 | goto unlock; | |
64f7ef8a | 208 | } |
22c6d93a PB |
209 | obuf[0] = msg[i].len; |
210 | obuf[1] = msg[i+1].len; | |
211 | obuf[2] = msg[i].addr; | |
f35db23c | 212 | memcpy(&obuf[3], msg[i].buf, msg[i].len); |
22c6d93a PB |
213 | |
214 | if (cxusb_ctrl_msg(d, CMD_I2C_READ, | |
f35db23c MK |
215 | obuf, 3+msg[i].len, |
216 | ibuf, 1+msg[i+1].len) < 0) | |
22c6d93a PB |
217 | break; |
218 | ||
219 | if (ibuf[0] != 0x08) | |
ae62e3d4 | 220 | deb_i2c("i2c read may have failed\n"); |
22c6d93a | 221 | |
f35db23c | 222 | memcpy(msg[i+1].buf, &ibuf[1], msg[i+1].len); |
22c6d93a PB |
223 | |
224 | i++; | |
272479d7 CP |
225 | } else { |
226 | /* write only */ | |
64f7ef8a MCC |
227 | u8 obuf[MAX_XFER_SIZE], ibuf; |
228 | ||
229 | if (2 + msg[i].len > sizeof(obuf)) { | |
230 | warn("i2c wr: len=%d is too big!\n", | |
231 | msg[i].len); | |
1cdbcc5d DC |
232 | ret = -EOPNOTSUPP; |
233 | goto unlock; | |
64f7ef8a | 234 | } |
22c6d93a PB |
235 | obuf[0] = msg[i].addr; |
236 | obuf[1] = msg[i].len; | |
f35db23c | 237 | memcpy(&obuf[2], msg[i].buf, msg[i].len); |
22c6d93a | 238 | |
f35db23c MK |
239 | if (cxusb_ctrl_msg(d, CMD_I2C_WRITE, obuf, |
240 | 2+msg[i].len, &ibuf,1) < 0) | |
22c6d93a PB |
241 | break; |
242 | if (ibuf != 0x08) | |
ae62e3d4 | 243 | deb_i2c("i2c write may have failed\n"); |
22c6d93a PB |
244 | } |
245 | } | |
246 | ||
1cdbcc5d DC |
247 | if (i == num) |
248 | ret = num; | |
249 | else | |
250 | ret = -EREMOTEIO; | |
251 | ||
252 | unlock: | |
3593cab5 | 253 | mutex_unlock(&d->i2c_mutex); |
1cdbcc5d | 254 | return ret; |
22c6d93a PB |
255 | } |
256 | ||
257 | static u32 cxusb_i2c_func(struct i2c_adapter *adapter) | |
258 | { | |
259 | return I2C_FUNC_I2C; | |
260 | } | |
261 | ||
262 | static struct i2c_algorithm cxusb_i2c_algo = { | |
22c6d93a PB |
263 | .master_xfer = cxusb_i2c_xfer, |
264 | .functionality = cxusb_i2c_func, | |
265 | }; | |
266 | ||
267 | static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff) | |
268 | { | |
e2efeab2 PB |
269 | u8 b = 0; |
270 | if (onoff) | |
271 | return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0); | |
272 | else | |
273 | return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0); | |
22c6d93a PB |
274 | } |
275 | ||
f5376ada DG |
276 | static int cxusb_aver_power_ctrl(struct dvb_usb_device *d, int onoff) |
277 | { | |
278 | int ret; | |
279 | if (!onoff) | |
280 | return cxusb_ctrl_msg(d, CMD_POWER_OFF, NULL, 0, NULL, 0); | |
281 | if (d->state == DVB_USB_STATE_INIT && | |
282 | usb_set_interface(d->udev, 0, 0) < 0) | |
283 | err("set interface failed"); | |
c6eb8eaf | 284 | do {} while (!(ret = cxusb_ctrl_msg(d, CMD_POWER_ON, NULL, 0, NULL, 0)) && |
f5376ada DG |
285 | !(ret = cxusb_ctrl_msg(d, 0x15, NULL, 0, NULL, 0)) && |
286 | !(ret = cxusb_ctrl_msg(d, 0x17, NULL, 0, NULL, 0)) && 0); | |
287 | if (!ret) { | |
288 | /* FIXME: We don't know why, but we need to configure the | |
289 | * lgdt3303 with the register settings below on resume */ | |
290 | int i; | |
291 | u8 buf, bufs[] = { | |
292 | 0x0e, 0x2, 0x00, 0x7f, | |
293 | 0x0e, 0x2, 0x02, 0xfe, | |
294 | 0x0e, 0x2, 0x02, 0x01, | |
295 | 0x0e, 0x2, 0x00, 0x03, | |
296 | 0x0e, 0x2, 0x0d, 0x40, | |
297 | 0x0e, 0x2, 0x0e, 0x87, | |
298 | 0x0e, 0x2, 0x0f, 0x8e, | |
299 | 0x0e, 0x2, 0x10, 0x01, | |
300 | 0x0e, 0x2, 0x14, 0xd7, | |
301 | 0x0e, 0x2, 0x47, 0x88, | |
302 | }; | |
303 | msleep(20); | |
304 | for (i = 0; i < sizeof(bufs)/sizeof(u8); i += 4/sizeof(u8)) { | |
305 | ret = cxusb_ctrl_msg(d, CMD_I2C_WRITE, | |
306 | bufs+i, 4, &buf, 1); | |
307 | if (ret) | |
308 | break; | |
309 | if (buf != 0x8) | |
310 | return -EREMOTEIO; | |
311 | } | |
312 | } | |
313 | return ret; | |
314 | } | |
315 | ||
5691c847 MK |
316 | static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff) |
317 | { | |
318 | u8 b = 0; | |
319 | if (onoff) | |
320 | return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0); | |
321 | else | |
322 | return 0; | |
323 | } | |
324 | ||
5ccaf905 CP |
325 | static int cxusb_nano2_power_ctrl(struct dvb_usb_device *d, int onoff) |
326 | { | |
327 | int rc = 0; | |
328 | ||
329 | rc = cxusb_power_ctrl(d, onoff); | |
330 | if (!onoff) | |
331 | cxusb_nano2_led(d, 0); | |
332 | ||
333 | return rc; | |
334 | } | |
335 | ||
dfbdce04 TL |
336 | static int cxusb_d680_dmb_power_ctrl(struct dvb_usb_device *d, int onoff) |
337 | { | |
338 | int ret; | |
339 | u8 b; | |
340 | ret = cxusb_power_ctrl(d, onoff); | |
341 | if (!onoff) | |
342 | return ret; | |
343 | ||
344 | msleep(128); | |
345 | cxusb_ctrl_msg(d, CMD_DIGITAL, NULL, 0, &b, 1); | |
346 | msleep(100); | |
347 | return ret; | |
348 | } | |
349 | ||
4d43e13f | 350 | static int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) |
22c6d93a | 351 | { |
8257e8a4 PB |
352 | u8 buf[2] = { 0x03, 0x00 }; |
353 | if (onoff) | |
4d43e13f | 354 | cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON, buf, 2, NULL, 0); |
8257e8a4 | 355 | else |
4d43e13f | 356 | cxusb_ctrl_msg(adap->dev, CMD_STREAMING_OFF, NULL, 0, NULL, 0); |
8257e8a4 | 357 | |
22c6d93a PB |
358 | return 0; |
359 | } | |
360 | ||
f5376ada DG |
361 | static int cxusb_aver_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) |
362 | { | |
363 | if (onoff) | |
364 | cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_ON, NULL, 0, NULL, 0); | |
365 | else | |
366 | cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_OFF, | |
367 | NULL, 0, NULL, 0); | |
368 | return 0; | |
369 | } | |
370 | ||
dfbdce04 TL |
371 | static void cxusb_d680_dmb_drain_message(struct dvb_usb_device *d) |
372 | { | |
373 | int ep = d->props.generic_bulk_ctrl_endpoint; | |
374 | const int timeout = 100; | |
375 | const int junk_len = 32; | |
376 | u8 *junk; | |
377 | int rd_count; | |
378 | ||
379 | /* Discard remaining data in video pipe */ | |
380 | junk = kmalloc(junk_len, GFP_KERNEL); | |
381 | if (!junk) | |
382 | return; | |
383 | while (1) { | |
384 | if (usb_bulk_msg(d->udev, | |
385 | usb_rcvbulkpipe(d->udev, ep), | |
386 | junk, junk_len, &rd_count, timeout) < 0) | |
387 | break; | |
388 | if (!rd_count) | |
389 | break; | |
390 | } | |
391 | kfree(junk); | |
392 | } | |
393 | ||
394 | static void cxusb_d680_dmb_drain_video(struct dvb_usb_device *d) | |
395 | { | |
77eed219 | 396 | struct usb_data_stream_properties *p = &d->props.adapter[0].fe[0].stream; |
dfbdce04 TL |
397 | const int timeout = 100; |
398 | const int junk_len = p->u.bulk.buffersize; | |
399 | u8 *junk; | |
400 | int rd_count; | |
401 | ||
402 | /* Discard remaining data in video pipe */ | |
403 | junk = kmalloc(junk_len, GFP_KERNEL); | |
404 | if (!junk) | |
405 | return; | |
406 | while (1) { | |
407 | if (usb_bulk_msg(d->udev, | |
408 | usb_rcvbulkpipe(d->udev, p->endpoint), | |
409 | junk, junk_len, &rd_count, timeout) < 0) | |
410 | break; | |
411 | if (!rd_count) | |
412 | break; | |
413 | } | |
414 | kfree(junk); | |
415 | } | |
416 | ||
417 | static int cxusb_d680_dmb_streaming_ctrl( | |
418 | struct dvb_usb_adapter *adap, int onoff) | |
419 | { | |
420 | if (onoff) { | |
421 | u8 buf[2] = { 0x03, 0x00 }; | |
422 | cxusb_d680_dmb_drain_video(adap->dev); | |
423 | return cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON, | |
424 | buf, sizeof(buf), NULL, 0); | |
425 | } else { | |
426 | int ret = cxusb_ctrl_msg(adap->dev, | |
427 | CMD_STREAMING_OFF, NULL, 0, NULL, 0); | |
428 | return ret; | |
429 | } | |
430 | } | |
431 | ||
7c239703 CP |
432 | static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state) |
433 | { | |
2f4f58d6 | 434 | struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table; |
a07e6096 | 435 | u8 ircode[4]; |
7c239703 CP |
436 | int i; |
437 | ||
a07e6096 | 438 | cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4); |
7c239703 CP |
439 | |
440 | *event = 0; | |
441 | *state = REMOTE_NO_KEY_PRESSED; | |
442 | ||
2f4f58d6 | 443 | for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) { |
2e365883 MCC |
444 | if (rc5_custom(&keymap[i]) == ircode[2] && |
445 | rc5_data(&keymap[i]) == ircode[3]) { | |
34abf219 | 446 | *event = keymap[i].keycode; |
7c239703 CP |
447 | *state = REMOTE_KEY_PRESSED; |
448 | ||
449 | return 0; | |
450 | } | |
451 | } | |
452 | ||
453 | return 0; | |
454 | } | |
455 | ||
aeb012bb CP |
456 | static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event, |
457 | int *state) | |
458 | { | |
2f4f58d6 | 459 | struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table; |
aeb012bb CP |
460 | u8 ircode[4]; |
461 | int i; | |
462 | struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD, | |
463 | .buf = ircode, .len = 4 }; | |
464 | ||
465 | *event = 0; | |
466 | *state = REMOTE_NO_KEY_PRESSED; | |
467 | ||
468 | if (cxusb_i2c_xfer(&d->i2c_adap, &msg, 1) != 1) | |
469 | return 0; | |
470 | ||
2f4f58d6 | 471 | for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) { |
2e365883 MCC |
472 | if (rc5_custom(&keymap[i]) == ircode[1] && |
473 | rc5_data(&keymap[i]) == ircode[2]) { | |
34abf219 | 474 | *event = keymap[i].keycode; |
aeb012bb CP |
475 | *state = REMOTE_KEY_PRESSED; |
476 | ||
477 | return 0; | |
478 | } | |
479 | } | |
480 | ||
481 | return 0; | |
482 | } | |
483 | ||
dfbdce04 TL |
484 | static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event, |
485 | int *state) | |
486 | { | |
2f4f58d6 | 487 | struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table; |
dfbdce04 TL |
488 | u8 ircode[2]; |
489 | int i; | |
490 | ||
491 | *event = 0; | |
492 | *state = REMOTE_NO_KEY_PRESSED; | |
493 | ||
494 | if (cxusb_ctrl_msg(d, 0x10, NULL, 0, ircode, 2) < 0) | |
495 | return 0; | |
496 | ||
2f4f58d6 | 497 | for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) { |
2e365883 MCC |
498 | if (rc5_custom(&keymap[i]) == ircode[0] && |
499 | rc5_data(&keymap[i]) == ircode[1]) { | |
34abf219 | 500 | *event = keymap[i].keycode; |
dfbdce04 TL |
501 | *state = REMOTE_KEY_PRESSED; |
502 | ||
503 | return 0; | |
504 | } | |
505 | } | |
506 | ||
507 | return 0; | |
508 | } | |
509 | ||
2f4f58d6 | 510 | static struct rc_map_table rc_map_dvico_mce_table[] = { |
2e365883 MCC |
511 | { 0xfe02, KEY_TV }, |
512 | { 0xfe0e, KEY_MP3 }, | |
513 | { 0xfe1a, KEY_DVD }, | |
514 | { 0xfe1e, KEY_FAVORITES }, | |
515 | { 0xfe16, KEY_SETUP }, | |
516 | { 0xfe46, KEY_POWER2 }, | |
517 | { 0xfe0a, KEY_EPG }, | |
518 | { 0xfe49, KEY_BACK }, | |
519 | { 0xfe4d, KEY_MENU }, | |
520 | { 0xfe51, KEY_UP }, | |
521 | { 0xfe5b, KEY_LEFT }, | |
522 | { 0xfe5f, KEY_RIGHT }, | |
523 | { 0xfe53, KEY_DOWN }, | |
524 | { 0xfe5e, KEY_OK }, | |
525 | { 0xfe59, KEY_INFO }, | |
526 | { 0xfe55, KEY_TAB }, | |
527 | { 0xfe0f, KEY_PREVIOUSSONG },/* Replay */ | |
528 | { 0xfe12, KEY_NEXTSONG }, /* Skip */ | |
529 | { 0xfe42, KEY_ENTER }, /* Windows/Start */ | |
530 | { 0xfe15, KEY_VOLUMEUP }, | |
531 | { 0xfe05, KEY_VOLUMEDOWN }, | |
532 | { 0xfe11, KEY_CHANNELUP }, | |
533 | { 0xfe09, KEY_CHANNELDOWN }, | |
534 | { 0xfe52, KEY_CAMERA }, | |
535 | { 0xfe5a, KEY_TUNER }, /* Live */ | |
536 | { 0xfe19, KEY_OPEN }, | |
537 | { 0xfe0b, KEY_1 }, | |
538 | { 0xfe17, KEY_2 }, | |
539 | { 0xfe1b, KEY_3 }, | |
540 | { 0xfe07, KEY_4 }, | |
541 | { 0xfe50, KEY_5 }, | |
542 | { 0xfe54, KEY_6 }, | |
543 | { 0xfe48, KEY_7 }, | |
544 | { 0xfe4c, KEY_8 }, | |
545 | { 0xfe58, KEY_9 }, | |
546 | { 0xfe13, KEY_ANGLE }, /* Aspect */ | |
547 | { 0xfe03, KEY_0 }, | |
548 | { 0xfe1f, KEY_ZOOM }, | |
549 | { 0xfe43, KEY_REWIND }, | |
550 | { 0xfe47, KEY_PLAYPAUSE }, | |
551 | { 0xfe4f, KEY_FASTFORWARD }, | |
552 | { 0xfe57, KEY_MUTE }, | |
553 | { 0xfe0d, KEY_STOP }, | |
554 | { 0xfe01, KEY_RECORD }, | |
555 | { 0xfe4e, KEY_POWER }, | |
a07e6096 MK |
556 | }; |
557 | ||
2f4f58d6 | 558 | static struct rc_map_table rc_map_dvico_portable_table[] = { |
2e365883 MCC |
559 | { 0xfc02, KEY_SETUP }, /* Profile */ |
560 | { 0xfc43, KEY_POWER2 }, | |
561 | { 0xfc06, KEY_EPG }, | |
562 | { 0xfc5a, KEY_BACK }, | |
563 | { 0xfc05, KEY_MENU }, | |
564 | { 0xfc47, KEY_INFO }, | |
565 | { 0xfc01, KEY_TAB }, | |
566 | { 0xfc42, KEY_PREVIOUSSONG },/* Replay */ | |
567 | { 0xfc49, KEY_VOLUMEUP }, | |
568 | { 0xfc09, KEY_VOLUMEDOWN }, | |
569 | { 0xfc54, KEY_CHANNELUP }, | |
570 | { 0xfc0b, KEY_CHANNELDOWN }, | |
571 | { 0xfc16, KEY_CAMERA }, | |
572 | { 0xfc40, KEY_TUNER }, /* ATV/DTV */ | |
573 | { 0xfc45, KEY_OPEN }, | |
574 | { 0xfc19, KEY_1 }, | |
575 | { 0xfc18, KEY_2 }, | |
576 | { 0xfc1b, KEY_3 }, | |
577 | { 0xfc1a, KEY_4 }, | |
578 | { 0xfc58, KEY_5 }, | |
579 | { 0xfc59, KEY_6 }, | |
580 | { 0xfc15, KEY_7 }, | |
581 | { 0xfc14, KEY_8 }, | |
582 | { 0xfc17, KEY_9 }, | |
583 | { 0xfc44, KEY_ANGLE }, /* Aspect */ | |
584 | { 0xfc55, KEY_0 }, | |
585 | { 0xfc07, KEY_ZOOM }, | |
586 | { 0xfc0a, KEY_REWIND }, | |
587 | { 0xfc08, KEY_PLAYPAUSE }, | |
588 | { 0xfc4b, KEY_FASTFORWARD }, | |
589 | { 0xfc5b, KEY_MUTE }, | |
590 | { 0xfc04, KEY_STOP }, | |
591 | { 0xfc56, KEY_RECORD }, | |
592 | { 0xfc57, KEY_POWER }, | |
593 | { 0xfc41, KEY_UNKNOWN }, /* INPUT */ | |
594 | { 0xfc00, KEY_UNKNOWN }, /* HD */ | |
c150178b MK |
595 | }; |
596 | ||
2f4f58d6 | 597 | static struct rc_map_table rc_map_d680_dmb_table[] = { |
2e365883 MCC |
598 | { 0x0038, KEY_UNKNOWN }, /* TV/AV */ |
599 | { 0x080c, KEY_ZOOM }, | |
600 | { 0x0800, KEY_0 }, | |
601 | { 0x0001, KEY_1 }, | |
602 | { 0x0802, KEY_2 }, | |
603 | { 0x0003, KEY_3 }, | |
604 | { 0x0804, KEY_4 }, | |
605 | { 0x0005, KEY_5 }, | |
606 | { 0x0806, KEY_6 }, | |
607 | { 0x0007, KEY_7 }, | |
608 | { 0x0808, KEY_8 }, | |
609 | { 0x0009, KEY_9 }, | |
610 | { 0x000a, KEY_MUTE }, | |
611 | { 0x0829, KEY_BACK }, | |
612 | { 0x0012, KEY_CHANNELUP }, | |
613 | { 0x0813, KEY_CHANNELDOWN }, | |
614 | { 0x002b, KEY_VOLUMEUP }, | |
615 | { 0x082c, KEY_VOLUMEDOWN }, | |
616 | { 0x0020, KEY_UP }, | |
617 | { 0x0821, KEY_DOWN }, | |
618 | { 0x0011, KEY_LEFT }, | |
619 | { 0x0810, KEY_RIGHT }, | |
620 | { 0x000d, KEY_OK }, | |
621 | { 0x081f, KEY_RECORD }, | |
622 | { 0x0017, KEY_PLAYPAUSE }, | |
623 | { 0x0816, KEY_PLAYPAUSE }, | |
624 | { 0x000b, KEY_STOP }, | |
625 | { 0x0827, KEY_FASTFORWARD }, | |
626 | { 0x0026, KEY_REWIND }, | |
627 | { 0x081e, KEY_UNKNOWN }, /* Time Shift */ | |
628 | { 0x000e, KEY_UNKNOWN }, /* Snapshot */ | |
629 | { 0x082d, KEY_UNKNOWN }, /* Mouse Cursor */ | |
630 | { 0x000f, KEY_UNKNOWN }, /* Minimize/Maximize */ | |
631 | { 0x0814, KEY_UNKNOWN }, /* Shuffle */ | |
632 | { 0x0025, KEY_POWER }, | |
dfbdce04 TL |
633 | }; |
634 | ||
0029ee14 CP |
635 | static int cxusb_dee1601_demod_init(struct dvb_frontend* fe) |
636 | { | |
d9ed881c | 637 | static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 }; |
0029ee14 CP |
638 | static u8 reset [] = { RESET, 0x80 }; |
639 | static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; | |
640 | static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 }; | |
641 | static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 }; | |
642 | static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; | |
643 | ||
644 | mt352_write(fe, clock_config, sizeof(clock_config)); | |
645 | udelay(200); | |
646 | mt352_write(fe, reset, sizeof(reset)); | |
647 | mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); | |
648 | ||
649 | mt352_write(fe, agc_cfg, sizeof(agc_cfg)); | |
650 | mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg)); | |
651 | mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); | |
652 | ||
653 | return 0; | |
654 | } | |
655 | ||
6f447259 MK |
656 | static int cxusb_mt352_demod_init(struct dvb_frontend* fe) |
657 | { /* used in both lgz201 and th7579 */ | |
fb51fd2d | 658 | static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x29 }; |
6f447259 MK |
659 | static u8 reset [] = { RESET, 0x80 }; |
660 | static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; | |
661 | static u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 }; | |
662 | static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 }; | |
663 | static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; | |
664 | ||
665 | mt352_write(fe, clock_config, sizeof(clock_config)); | |
666 | udelay(200); | |
667 | mt352_write(fe, reset, sizeof(reset)); | |
668 | mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); | |
669 | ||
670 | mt352_write(fe, agc_cfg, sizeof(agc_cfg)); | |
671 | mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg)); | |
672 | mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); | |
673 | return 0; | |
674 | } | |
675 | ||
703cb2cb | 676 | static struct cx22702_config cxusb_cx22702_config = { |
22c6d93a | 677 | .demod_address = 0x63, |
8257e8a4 | 678 | .output_mode = CX22702_PARALLEL_OUTPUT, |
22c6d93a PB |
679 | }; |
680 | ||
fddd632a | 681 | static struct lgdt330x_config cxusb_lgdt3303_config = { |
effee033 MK |
682 | .demod_address = 0x0e, |
683 | .demod_chip = LGDT3303, | |
effee033 MK |
684 | }; |
685 | ||
f5376ada DG |
686 | static struct lgdt330x_config cxusb_aver_lgdt3303_config = { |
687 | .demod_address = 0x0e, | |
688 | .demod_chip = LGDT3303, | |
689 | .clock_polarity_flip = 2, | |
690 | }; | |
691 | ||
703cb2cb | 692 | static struct mt352_config cxusb_dee1601_config = { |
0029ee14 CP |
693 | .demod_address = 0x0f, |
694 | .demod_init = cxusb_dee1601_demod_init, | |
0029ee14 CP |
695 | }; |
696 | ||
c9ce3940 MK |
697 | static struct zl10353_config cxusb_zl10353_dee1601_config = { |
698 | .demod_address = 0x0f, | |
8fb95784 | 699 | .parallel_ts = 1, |
c9ce3940 MK |
700 | }; |
701 | ||
6fe00b0e | 702 | static struct mt352_config cxusb_mt352_config = { |
6f447259 MK |
703 | /* used in both lgz201 and th7579 */ |
704 | .demod_address = 0x0f, | |
705 | .demod_init = cxusb_mt352_demod_init, | |
6f447259 MK |
706 | }; |
707 | ||
aeb012bb CP |
708 | static struct zl10353_config cxusb_zl10353_xc3028_config = { |
709 | .demod_address = 0x0f, | |
a1dcd9de | 710 | .if2 = 45600, |
aeb012bb CP |
711 | .no_tuner = 1, |
712 | .parallel_ts = 1, | |
713 | }; | |
714 | ||
0bc35180 RL |
715 | static struct zl10353_config cxusb_zl10353_xc3028_config_no_i2c_gate = { |
716 | .demod_address = 0x0f, | |
717 | .if2 = 45600, | |
718 | .no_tuner = 1, | |
719 | .parallel_ts = 1, | |
720 | .disable_i2c_gate_ctrl = 1, | |
721 | }; | |
722 | ||
702a6762 CP |
723 | static struct mt352_config cxusb_mt352_xc3028_config = { |
724 | .demod_address = 0x0f, | |
725 | .if2 = 4560, | |
726 | .no_tuner = 1, | |
727 | .demod_init = cxusb_mt352_demod_init, | |
728 | }; | |
729 | ||
f5376ada DG |
730 | /* FIXME: needs tweaking */ |
731 | static struct mxl5005s_config aver_a868r_tuner = { | |
732 | .i2c_address = 0x63, | |
733 | .if_freq = 6000000UL, | |
734 | .xtal_freq = CRYSTAL_FREQ_16000000HZ, | |
735 | .agc_mode = MXL_SINGLE_AGC, | |
736 | .tracking_filter = MXL_TF_C, | |
737 | .rssi_enable = MXL_RSSI_ENABLE, | |
738 | .cap_select = MXL_CAP_SEL_ENABLE, | |
739 | .div_out = MXL_DIV_OUT_4, | |
740 | .clock_out = MXL_CLOCK_OUT_DISABLE, | |
741 | .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM, | |
742 | .top = MXL5005S_TOP_25P2, | |
743 | .mod_mode = MXL_DIGITAL_MODE, | |
744 | .if_mode = MXL_ZERO_IF, | |
745 | .AgcMasterByte = 0x00, | |
746 | }; | |
747 | ||
dfbdce04 TL |
748 | /* FIXME: needs tweaking */ |
749 | static struct mxl5005s_config d680_dmb_tuner = { | |
750 | .i2c_address = 0x63, | |
751 | .if_freq = 36125000UL, | |
752 | .xtal_freq = CRYSTAL_FREQ_16000000HZ, | |
753 | .agc_mode = MXL_SINGLE_AGC, | |
754 | .tracking_filter = MXL_TF_C, | |
755 | .rssi_enable = MXL_RSSI_ENABLE, | |
756 | .cap_select = MXL_CAP_SEL_ENABLE, | |
757 | .div_out = MXL_DIV_OUT_4, | |
758 | .clock_out = MXL_CLOCK_OUT_DISABLE, | |
759 | .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM, | |
760 | .top = MXL5005S_TOP_25P2, | |
761 | .mod_mode = MXL_DIGITAL_MODE, | |
762 | .if_mode = MXL_ZERO_IF, | |
763 | .AgcMasterByte = 0x00, | |
764 | }; | |
765 | ||
b18bd1d8 DW |
766 | static struct max2165_config mygica_d689_max2165_cfg = { |
767 | .i2c_address = 0x60, | |
768 | .osc_clk = 20 | |
769 | }; | |
770 | ||
22c6d93a | 771 | /* Callbacks for DVB USB */ |
4d43e13f | 772 | static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap) |
22c6d93a | 773 | { |
77eed219 | 774 | dvb_attach(simple_tuner_attach, adap->fe_adap[0].fe, |
cb89cd33 MK |
775 | &adap->dev->i2c_adap, 0x61, |
776 | TUNER_PHILIPS_FMD1216ME_MK3); | |
22c6d93a PB |
777 | return 0; |
778 | } | |
779 | ||
4d43e13f | 780 | static int cxusb_dee1601_tuner_attach(struct dvb_usb_adapter *adap) |
0029ee14 | 781 | { |
77eed219 | 782 | dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61, |
47a9991e | 783 | NULL, DVB_PLL_THOMSON_DTT7579); |
0029ee14 CP |
784 | return 0; |
785 | } | |
786 | ||
4d43e13f | 787 | static int cxusb_lgz201_tuner_attach(struct dvb_usb_adapter *adap) |
6f447259 | 788 | { |
77eed219 | 789 | dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61, NULL, DVB_PLL_LG_Z201); |
6f447259 MK |
790 | return 0; |
791 | } | |
792 | ||
4d43e13f | 793 | static int cxusb_dtt7579_tuner_attach(struct dvb_usb_adapter *adap) |
6f447259 | 794 | { |
77eed219 | 795 | dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, |
47a9991e | 796 | NULL, DVB_PLL_THOMSON_DTT7579); |
332bed5f PB |
797 | return 0; |
798 | } | |
799 | ||
f71a56c1 | 800 | static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap) |
332bed5f | 801 | { |
77eed219 | 802 | dvb_attach(simple_tuner_attach, adap->fe_adap[0].fe, |
827855d3 | 803 | &adap->dev->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF); |
6f447259 MK |
804 | return 0; |
805 | } | |
806 | ||
d7cba043 MK |
807 | static int dvico_bluebird_xc2028_callback(void *ptr, int component, |
808 | int command, int arg) | |
aeb012bb | 809 | { |
d483b730 RL |
810 | struct dvb_usb_adapter *adap = ptr; |
811 | struct dvb_usb_device *d = adap->dev; | |
aeb012bb CP |
812 | |
813 | switch (command) { | |
814 | case XC2028_TUNER_RESET: | |
708bebdd | 815 | deb_info("%s: XC2028_TUNER_RESET %d\n", __func__, arg); |
aeb012bb CP |
816 | cxusb_bluebird_gpio_pulse(d, 0x01, 1); |
817 | break; | |
818 | case XC2028_RESET_CLK: | |
708bebdd | 819 | deb_info("%s: XC2028_RESET_CLK %d\n", __func__, arg); |
aeb012bb CP |
820 | break; |
821 | default: | |
708bebdd | 822 | deb_info("%s: unknown command %d, arg %d\n", __func__, |
aeb012bb CP |
823 | command, arg); |
824 | return -EINVAL; | |
825 | } | |
826 | ||
827 | return 0; | |
828 | } | |
829 | ||
830 | static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap) | |
831 | { | |
832 | struct dvb_frontend *fe; | |
833 | struct xc2028_config cfg = { | |
834 | .i2c_adap = &adap->dev->i2c_adap, | |
835 | .i2c_addr = 0x61, | |
aeb012bb CP |
836 | }; |
837 | static struct xc2028_ctrl ctl = { | |
ef80bfeb | 838 | .fname = XC2028_DEFAULT_FIRMWARE, |
aeb012bb | 839 | .max_len = 64, |
d483b730 | 840 | .demod = XC3028_FE_ZARLINK456, |
aeb012bb CP |
841 | }; |
842 | ||
d7cba043 | 843 | /* FIXME: generalize & move to common area */ |
77eed219 | 844 | adap->fe_adap[0].fe->callback = dvico_bluebird_xc2028_callback; |
d7cba043 | 845 | |
77eed219 | 846 | fe = dvb_attach(xc2028_attach, adap->fe_adap[0].fe, &cfg); |
aeb012bb CP |
847 | if (fe == NULL || fe->ops.tuner_ops.set_config == NULL) |
848 | return -EIO; | |
849 | ||
850 | fe->ops.tuner_ops.set_config(fe, &ctl); | |
851 | ||
852 | return 0; | |
853 | } | |
854 | ||
f5376ada DG |
855 | static int cxusb_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap) |
856 | { | |
77eed219 | 857 | dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe, |
f5376ada DG |
858 | &adap->dev->i2c_adap, &aver_a868r_tuner); |
859 | return 0; | |
860 | } | |
861 | ||
dfbdce04 TL |
862 | static int cxusb_d680_dmb_tuner_attach(struct dvb_usb_adapter *adap) |
863 | { | |
864 | struct dvb_frontend *fe; | |
77eed219 | 865 | fe = dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe, |
dfbdce04 TL |
866 | &adap->dev->i2c_adap, &d680_dmb_tuner); |
867 | return (fe == NULL) ? -EIO : 0; | |
868 | } | |
869 | ||
b18bd1d8 DW |
870 | static int cxusb_mygica_d689_tuner_attach(struct dvb_usb_adapter *adap) |
871 | { | |
872 | struct dvb_frontend *fe; | |
77eed219 | 873 | fe = dvb_attach(max2165_attach, adap->fe_adap[0].fe, |
b18bd1d8 DW |
874 | &adap->dev->i2c_adap, &mygica_d689_max2165_cfg); |
875 | return (fe == NULL) ? -EIO : 0; | |
876 | } | |
877 | ||
4d43e13f | 878 | static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap) |
22c6d93a | 879 | { |
e2efeab2 | 880 | u8 b; |
4d43e13f | 881 | if (usb_set_interface(adap->dev->udev, 0, 6) < 0) |
8257e8a4 | 882 | err("set interface failed"); |
22c6d93a | 883 | |
4d43e13f | 884 | cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, &b, 1); |
22c6d93a | 885 | |
310df366 MK |
886 | adap->fe_adap[0].fe = dvb_attach(cx22702_attach, &cxusb_cx22702_config, |
887 | &adap->dev->i2c_adap); | |
888 | if ((adap->fe_adap[0].fe) != NULL) | |
22c6d93a PB |
889 | return 0; |
890 | ||
891 | return -EIO; | |
892 | } | |
893 | ||
4d43e13f | 894 | static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap) |
effee033 | 895 | { |
4d43e13f | 896 | if (usb_set_interface(adap->dev->udev, 0, 7) < 0) |
effee033 MK |
897 | err("set interface failed"); |
898 | ||
4d43e13f | 899 | cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0); |
effee033 | 900 | |
310df366 MK |
901 | adap->fe_adap[0].fe = dvb_attach(lgdt330x_attach, |
902 | &cxusb_lgdt3303_config, | |
903 | &adap->dev->i2c_adap); | |
904 | if ((adap->fe_adap[0].fe) != NULL) | |
effee033 MK |
905 | return 0; |
906 | ||
907 | return -EIO; | |
908 | } | |
909 | ||
f5376ada DG |
910 | static int cxusb_aver_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap) |
911 | { | |
77eed219 | 912 | adap->fe_adap[0].fe = dvb_attach(lgdt330x_attach, &cxusb_aver_lgdt3303_config, |
f5376ada | 913 | &adap->dev->i2c_adap); |
77eed219 | 914 | if (adap->fe_adap[0].fe != NULL) |
f5376ada DG |
915 | return 0; |
916 | ||
917 | return -EIO; | |
918 | } | |
919 | ||
4d43e13f PB |
920 | static int cxusb_mt352_frontend_attach(struct dvb_usb_adapter *adap) |
921 | { | |
922 | /* used in both lgz201 and th7579 */ | |
923 | if (usb_set_interface(adap->dev->udev, 0, 0) < 0) | |
6f447259 MK |
924 | err("set interface failed"); |
925 | ||
4d43e13f | 926 | cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0); |
6f447259 | 927 | |
310df366 MK |
928 | adap->fe_adap[0].fe = dvb_attach(mt352_attach, &cxusb_mt352_config, |
929 | &adap->dev->i2c_adap); | |
930 | if ((adap->fe_adap[0].fe) != NULL) | |
6f447259 MK |
931 | return 0; |
932 | ||
933 | return -EIO; | |
934 | } | |
935 | ||
4d43e13f | 936 | static int cxusb_dee1601_frontend_attach(struct dvb_usb_adapter *adap) |
0029ee14 | 937 | { |
4d43e13f | 938 | if (usb_set_interface(adap->dev->udev, 0, 0) < 0) |
0029ee14 CP |
939 | err("set interface failed"); |
940 | ||
4d43e13f | 941 | cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0); |
0029ee14 | 942 | |
310df366 MK |
943 | adap->fe_adap[0].fe = dvb_attach(mt352_attach, &cxusb_dee1601_config, |
944 | &adap->dev->i2c_adap); | |
945 | if ((adap->fe_adap[0].fe) != NULL) | |
946 | return 0; | |
947 | ||
948 | adap->fe_adap[0].fe = dvb_attach(zl10353_attach, | |
949 | &cxusb_zl10353_dee1601_config, | |
950 | &adap->dev->i2c_adap); | |
951 | if ((adap->fe_adap[0].fe) != NULL) | |
0029ee14 CP |
952 | return 0; |
953 | ||
954 | return -EIO; | |
955 | } | |
956 | ||
aeb012bb CP |
957 | static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap) |
958 | { | |
959 | u8 ircode[4]; | |
960 | int i; | |
961 | struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD, | |
962 | .buf = ircode, .len = 4 }; | |
963 | ||
964 | if (usb_set_interface(adap->dev->udev, 0, 1) < 0) | |
965 | err("set interface failed"); | |
966 | ||
967 | cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0); | |
968 | ||
969 | /* reset the tuner and demodulator */ | |
970 | cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0); | |
971 | cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1); | |
972 | cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1); | |
973 | ||
310df366 MK |
974 | adap->fe_adap[0].fe = |
975 | dvb_attach(zl10353_attach, | |
976 | &cxusb_zl10353_xc3028_config_no_i2c_gate, | |
977 | &adap->dev->i2c_adap); | |
978 | if ((adap->fe_adap[0].fe) == NULL) | |
aeb012bb CP |
979 | return -EIO; |
980 | ||
981 | /* try to determine if there is no IR decoder on the I2C bus */ | |
2f4f58d6 | 982 | for (i = 0; adap->dev->props.rc.legacy.rc_map_table != NULL && i < 5; i++) { |
aeb012bb CP |
983 | msleep(20); |
984 | if (cxusb_i2c_xfer(&adap->dev->i2c_adap, &msg, 1) != 1) | |
985 | goto no_IR; | |
986 | if (ircode[0] == 0 && ircode[1] == 0) | |
987 | continue; | |
988 | if (ircode[2] + ircode[3] != 0xff) { | |
989 | no_IR: | |
2f4f58d6 | 990 | adap->dev->props.rc.legacy.rc_map_table = NULL; |
aeb012bb CP |
991 | info("No IR receiver detected on this device."); |
992 | break; | |
993 | } | |
994 | } | |
995 | ||
996 | return 0; | |
997 | } | |
998 | ||
8d798988 AB |
999 | static struct dibx000_agc_config dib7070_agc_config = { |
1000 | .band_caps = BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, | |
1001 | ||
1002 | /* | |
1003 | * P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, | |
1004 | * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, | |
1005 | * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 | |
1006 | */ | |
1007 | .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | | |
1008 | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), | |
1009 | .inv_gain = 600, | |
1010 | .time_stabiliz = 10, | |
1011 | .alpha_level = 0, | |
1012 | .thlock = 118, | |
1013 | .wbd_inv = 0, | |
1014 | .wbd_ref = 3530, | |
1015 | .wbd_sel = 1, | |
1016 | .wbd_alpha = 5, | |
1017 | .agc1_max = 65535, | |
1018 | .agc1_min = 0, | |
1019 | .agc2_max = 65535, | |
1020 | .agc2_min = 0, | |
1021 | .agc1_pt1 = 0, | |
1022 | .agc1_pt2 = 40, | |
1023 | .agc1_pt3 = 183, | |
1024 | .agc1_slope1 = 206, | |
1025 | .agc1_slope2 = 255, | |
1026 | .agc2_pt1 = 72, | |
1027 | .agc2_pt2 = 152, | |
1028 | .agc2_slope1 = 88, | |
1029 | .agc2_slope2 = 90, | |
1030 | .alpha_mant = 17, | |
1031 | .alpha_exp = 27, | |
1032 | .beta_mant = 23, | |
1033 | .beta_exp = 51, | |
1034 | .perform_agc_softsplit = 0, | |
1035 | }; | |
1036 | ||
1037 | static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = { | |
1038 | .internal = 60000, | |
1039 | .sampling = 15000, | |
1040 | .pll_prediv = 1, | |
1041 | .pll_ratio = 20, | |
1042 | .pll_range = 3, | |
1043 | .pll_reset = 1, | |
1044 | .pll_bypass = 0, | |
1045 | .enable_refdiv = 0, | |
1046 | .bypclk_div = 0, | |
1047 | .IO_CLK_en_core = 1, | |
1048 | .ADClkSrc = 1, | |
1049 | .modulo = 2, | |
1050 | /* refsel, sel, freq_15k */ | |
1051 | .sad_cfg = (3 << 14) | (1 << 12) | (524 << 0), | |
1052 | .ifreq = (0 << 25) | 0, | |
1053 | .timf = 20452225, | |
1054 | .xtal_hz = 12000000, | |
1055 | }; | |
1056 | ||
1057 | static struct dib7000p_config cxusb_dualdig4_rev2_config = { | |
1058 | .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK, | |
1059 | .output_mpeg2_in_188_bytes = 1, | |
1060 | ||
1061 | .agc_config_count = 1, | |
1062 | .agc = &dib7070_agc_config, | |
1063 | .bw = &dib7070_bw_config_12_mhz, | |
1064 | .tuner_is_baseband = 1, | |
1065 | .spur_protect = 1, | |
1066 | ||
1067 | .gpio_dir = 0xfcef, | |
1068 | .gpio_val = 0x0110, | |
1069 | ||
1070 | .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, | |
1071 | ||
1072 | .hostbus_diversity = 1, | |
1073 | }; | |
1074 | ||
8abe4a0a MCC |
1075 | struct dib0700_adapter_state { |
1076 | int (*set_param_save)(struct dvb_frontend *); | |
1077 | struct dib7000p_ops dib7000p_ops; | |
1078 | }; | |
1079 | ||
8d798988 AB |
1080 | static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap) |
1081 | { | |
8abe4a0a MCC |
1082 | struct dib0700_adapter_state *state = adap->priv; |
1083 | ||
8d798988 AB |
1084 | if (usb_set_interface(adap->dev->udev, 0, 1) < 0) |
1085 | err("set interface failed"); | |
1086 | ||
1087 | cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0); | |
1088 | ||
1089 | cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1); | |
1090 | ||
8abe4a0a MCC |
1091 | if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) |
1092 | return -ENODEV; | |
1093 | ||
1094 | if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18, | |
1095 | &cxusb_dualdig4_rev2_config) < 0) { | |
a49ba167 | 1096 | printk(KERN_WARNING "Unable to enumerate dib7000p\n"); |
30d81bb0 | 1097 | return -ENODEV; |
a49ba167 | 1098 | } |
8d798988 | 1099 | |
8abe4a0a MCC |
1100 | adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80, |
1101 | &cxusb_dualdig4_rev2_config); | |
77eed219 | 1102 | if (adap->fe_adap[0].fe == NULL) |
8d798988 AB |
1103 | return -EIO; |
1104 | ||
1105 | return 0; | |
1106 | } | |
1107 | ||
1108 | static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff) | |
1109 | { | |
8abe4a0a MCC |
1110 | struct dvb_usb_adapter *adap = fe->dvb->priv; |
1111 | struct dib0700_adapter_state *state = adap->priv; | |
1112 | ||
1113 | return state->dib7000p_ops.set_gpio(fe, 8, 0, !onoff); | |
8d798988 AB |
1114 | } |
1115 | ||
1116 | static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff) | |
1117 | { | |
1118 | return 0; | |
1119 | } | |
1120 | ||
1121 | static struct dib0070_config dib7070p_dib0070_config = { | |
1122 | .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS, | |
1123 | .reset = dib7070_tuner_reset, | |
1124 | .sleep = dib7070_tuner_sleep, | |
1125 | .clock_khz = 12000, | |
1126 | }; | |
1127 | ||
14d24d14 | 1128 | static int dib7070_set_param_override(struct dvb_frontend *fe) |
8d798988 | 1129 | { |
afd2b38a | 1130 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; |
8d798988 AB |
1131 | struct dvb_usb_adapter *adap = fe->dvb->priv; |
1132 | struct dib0700_adapter_state *state = adap->priv; | |
1133 | ||
1134 | u16 offset; | |
afd2b38a | 1135 | u8 band = BAND_OF_FREQUENCY(p->frequency/1000); |
8d798988 | 1136 | switch (band) { |
a2dc86b6 MK |
1137 | case BAND_VHF: offset = 950; break; |
1138 | default: | |
1139 | case BAND_UHF: offset = 550; break; | |
8d798988 AB |
1140 | } |
1141 | ||
8abe4a0a | 1142 | state->dib7000p_ops.set_wbd_ref(fe, offset + dib0070_wbd_offset(fe)); |
8d798988 | 1143 | |
14d24d14 | 1144 | return state->set_param_save(fe); |
8d798988 AB |
1145 | } |
1146 | ||
1147 | static int cxusb_dualdig4_rev2_tuner_attach(struct dvb_usb_adapter *adap) | |
1148 | { | |
1149 | struct dib0700_adapter_state *st = adap->priv; | |
8abe4a0a MCC |
1150 | struct i2c_adapter *tun_i2c; |
1151 | ||
1152 | /* | |
1153 | * No need to call dvb7000p_attach here, as it was called | |
1154 | * already, as frontend_attach method is called first, and | |
1155 | * tuner_attach is only called on sucess. | |
1156 | */ | |
1157 | tun_i2c = st->dib7000p_ops.get_i2c_master(adap->fe_adap[0].fe, | |
a2dc86b6 | 1158 | DIBX000_I2C_INTERFACE_TUNER, 1); |
8d798988 | 1159 | |
77eed219 | 1160 | if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, |
8d798988 AB |
1161 | &dib7070p_dib0070_config) == NULL) |
1162 | return -ENODEV; | |
1163 | ||
77eed219 MK |
1164 | st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; |
1165 | adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7070_set_param_override; | |
8d798988 AB |
1166 | return 0; |
1167 | } | |
1168 | ||
5ccaf905 CP |
1169 | static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap) |
1170 | { | |
1171 | if (usb_set_interface(adap->dev->udev, 0, 1) < 0) | |
1172 | err("set interface failed"); | |
1173 | ||
1174 | cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0); | |
1175 | ||
1176 | /* reset the tuner and demodulator */ | |
1177 | cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0); | |
1178 | cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1); | |
1179 | cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1); | |
1180 | ||
310df366 MK |
1181 | adap->fe_adap[0].fe = dvb_attach(zl10353_attach, |
1182 | &cxusb_zl10353_xc3028_config, | |
1183 | &adap->dev->i2c_adap); | |
1184 | if ((adap->fe_adap[0].fe) != NULL) | |
5ccaf905 CP |
1185 | return 0; |
1186 | ||
310df366 MK |
1187 | adap->fe_adap[0].fe = dvb_attach(mt352_attach, |
1188 | &cxusb_mt352_xc3028_config, | |
1189 | &adap->dev->i2c_adap); | |
1190 | if ((adap->fe_adap[0].fe) != NULL) | |
702a6762 CP |
1191 | return 0; |
1192 | ||
5ccaf905 CP |
1193 | return -EIO; |
1194 | } | |
1195 | ||
6bf1a997 DW |
1196 | static struct lgs8gxx_config d680_lgs8gl5_cfg = { |
1197 | .prod = LGS8GXX_PROD_LGS8GL5, | |
dfbdce04 | 1198 | .demod_address = 0x19, |
6bf1a997 DW |
1199 | .serial_ts = 0, |
1200 | .ts_clk_pol = 0, | |
1201 | .ts_clk_gated = 1, | |
1202 | .if_clk_freq = 30400, /* 30.4 MHz */ | |
1203 | .if_freq = 5725, /* 5.725 MHz */ | |
1204 | .if_neg_center = 0, | |
1205 | .ext_adc = 0, | |
1206 | .adc_signed = 0, | |
1207 | .if_neg_edge = 0, | |
dfbdce04 TL |
1208 | }; |
1209 | ||
1210 | static int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap) | |
1211 | { | |
1212 | struct dvb_usb_device *d = adap->dev; | |
1213 | int n; | |
1214 | ||
1215 | /* Select required USB configuration */ | |
1216 | if (usb_set_interface(d->udev, 0, 0) < 0) | |
1217 | err("set interface failed"); | |
1218 | ||
1219 | /* Unblock all USB pipes */ | |
1220 | usb_clear_halt(d->udev, | |
1221 | usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); | |
1222 | usb_clear_halt(d->udev, | |
1223 | usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); | |
1224 | usb_clear_halt(d->udev, | |
77eed219 | 1225 | usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint)); |
dfbdce04 TL |
1226 | |
1227 | /* Drain USB pipes to avoid hang after reboot */ | |
1228 | for (n = 0; n < 5; n++) { | |
1229 | cxusb_d680_dmb_drain_message(d); | |
1230 | cxusb_d680_dmb_drain_video(d); | |
1231 | msleep(200); | |
1232 | } | |
1233 | ||
1234 | /* Reset the tuner */ | |
1235 | if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) { | |
1236 | err("clear tuner gpio failed"); | |
1237 | return -EIO; | |
1238 | } | |
1239 | msleep(100); | |
1240 | if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) { | |
1241 | err("set tuner gpio failed"); | |
1242 | return -EIO; | |
1243 | } | |
1244 | msleep(100); | |
1245 | ||
1246 | /* Attach frontend */ | |
77eed219 MK |
1247 | adap->fe_adap[0].fe = dvb_attach(lgs8gxx_attach, &d680_lgs8gl5_cfg, &d->i2c_adap); |
1248 | if (adap->fe_adap[0].fe == NULL) | |
dfbdce04 TL |
1249 | return -EIO; |
1250 | ||
1251 | return 0; | |
1252 | } | |
1253 | ||
b18bd1d8 DW |
1254 | static struct atbm8830_config mygica_d689_atbm8830_cfg = { |
1255 | .prod = ATBM8830_PROD_8830, | |
1256 | .demod_address = 0x40, | |
1257 | .serial_ts = 0, | |
1258 | .ts_sampling_edge = 1, | |
1259 | .ts_clk_gated = 0, | |
1260 | .osc_clk_freq = 30400, /* in kHz */ | |
1261 | .if_freq = 0, /* zero IF */ | |
1262 | .zif_swap_iq = 1, | |
c245c75c DW |
1263 | .agc_min = 0x2E, |
1264 | .agc_max = 0x90, | |
1265 | .agc_hold_loop = 0, | |
b18bd1d8 DW |
1266 | }; |
1267 | ||
1268 | static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap) | |
1269 | { | |
1270 | struct dvb_usb_device *d = adap->dev; | |
b18bd1d8 DW |
1271 | |
1272 | /* Select required USB configuration */ | |
1273 | if (usb_set_interface(d->udev, 0, 0) < 0) | |
1274 | err("set interface failed"); | |
1275 | ||
1276 | /* Unblock all USB pipes */ | |
1277 | usb_clear_halt(d->udev, | |
1278 | usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); | |
1279 | usb_clear_halt(d->udev, | |
1280 | usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); | |
1281 | usb_clear_halt(d->udev, | |
77eed219 | 1282 | usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint)); |
b18bd1d8 DW |
1283 | |
1284 | ||
1285 | /* Reset the tuner */ | |
1286 | if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) { | |
1287 | err("clear tuner gpio failed"); | |
1288 | return -EIO; | |
1289 | } | |
1290 | msleep(100); | |
1291 | if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) { | |
1292 | err("set tuner gpio failed"); | |
1293 | return -EIO; | |
1294 | } | |
1295 | msleep(100); | |
1296 | ||
1297 | /* Attach frontend */ | |
77eed219 | 1298 | adap->fe_adap[0].fe = dvb_attach(atbm8830_attach, &mygica_d689_atbm8830_cfg, |
b18bd1d8 | 1299 | &d->i2c_adap); |
77eed219 | 1300 | if (adap->fe_adap[0].fe == NULL) |
b18bd1d8 DW |
1301 | return -EIO; |
1302 | ||
1303 | return 0; | |
1304 | } | |
1305 | ||
a0f629b9 C |
1306 | static int cxusb_mygica_t230_frontend_attach(struct dvb_usb_adapter *adap) |
1307 | { | |
1308 | struct dvb_usb_device *d = adap->dev; | |
1309 | struct cxusb_state *st = d->priv; | |
1310 | struct i2c_adapter *adapter; | |
1311 | struct i2c_client *client_demod; | |
1312 | struct i2c_client *client_tuner; | |
1313 | struct i2c_board_info info; | |
1314 | struct si2168_config si2168_config; | |
1315 | struct si2157_config si2157_config; | |
1316 | ||
1317 | /* Select required USB configuration */ | |
1318 | if (usb_set_interface(d->udev, 0, 0) < 0) | |
1319 | err("set interface failed"); | |
1320 | ||
1321 | /* Unblock all USB pipes */ | |
1322 | usb_clear_halt(d->udev, | |
1323 | usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); | |
1324 | usb_clear_halt(d->udev, | |
1325 | usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); | |
1326 | usb_clear_halt(d->udev, | |
1327 | usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint)); | |
1328 | ||
1329 | /* attach frontend */ | |
1330 | si2168_config.i2c_adapter = &adapter; | |
1331 | si2168_config.fe = &adap->fe_adap[0].fe; | |
1332 | si2168_config.ts_mode = SI2168_TS_PARALLEL; | |
1333 | si2168_config.ts_clock_inv = 1; | |
1334 | memset(&info, 0, sizeof(struct i2c_board_info)); | |
1335 | strlcpy(info.type, "si2168", I2C_NAME_SIZE); | |
1336 | info.addr = 0x64; | |
1337 | info.platform_data = &si2168_config; | |
1338 | request_module(info.type); | |
1339 | client_demod = i2c_new_device(&d->i2c_adap, &info); | |
1340 | if (client_demod == NULL || client_demod->dev.driver == NULL) | |
1341 | return -ENODEV; | |
1342 | ||
1343 | if (!try_module_get(client_demod->dev.driver->owner)) { | |
1344 | i2c_unregister_device(client_demod); | |
1345 | return -ENODEV; | |
1346 | } | |
1347 | ||
1348 | st->i2c_client_demod = client_demod; | |
1349 | ||
1350 | /* attach tuner */ | |
1351 | memset(&si2157_config, 0, sizeof(si2157_config)); | |
1352 | si2157_config.fe = adap->fe_adap[0].fe; | |
ee3c3e46 | 1353 | si2157_config.if_port = 1; |
a0f629b9 C |
1354 | memset(&info, 0, sizeof(struct i2c_board_info)); |
1355 | strlcpy(info.type, "si2157", I2C_NAME_SIZE); | |
1356 | info.addr = 0x60; | |
1357 | info.platform_data = &si2157_config; | |
1358 | request_module(info.type); | |
1359 | client_tuner = i2c_new_device(adapter, &info); | |
1360 | if (client_tuner == NULL || client_tuner->dev.driver == NULL) { | |
1361 | module_put(client_demod->dev.driver->owner); | |
1362 | i2c_unregister_device(client_demod); | |
1363 | return -ENODEV; | |
1364 | } | |
1365 | if (!try_module_get(client_tuner->dev.driver->owner)) { | |
1366 | i2c_unregister_device(client_tuner); | |
1367 | module_put(client_demod->dev.driver->owner); | |
1368 | i2c_unregister_device(client_demod); | |
1369 | return -ENODEV; | |
1370 | } | |
1371 | ||
1372 | st->i2c_client_tuner = client_tuner; | |
1373 | ||
1374 | return 0; | |
1375 | } | |
1376 | ||
702a6762 CP |
1377 | /* |
1378 | * DViCO has shipped two devices with the same USB ID, but only one of them | |
1379 | * needs a firmware download. Check the device class details to see if they | |
1380 | * have non-default values to decide whether the device is actually cold or | |
1381 | * not, and forget a match if it turns out we selected the wrong device. | |
1382 | */ | |
1383 | static int bluebird_fx2_identify_state(struct usb_device *udev, | |
1384 | struct dvb_usb_device_properties *props, | |
1385 | struct dvb_usb_device_description **desc, | |
1386 | int *cold) | |
1387 | { | |
1388 | int wascold = *cold; | |
1389 | ||
1390 | *cold = udev->descriptor.bDeviceClass == 0xff && | |
1391 | udev->descriptor.bDeviceSubClass == 0xff && | |
1392 | udev->descriptor.bDeviceProtocol == 0xff; | |
1393 | ||
1394 | if (*cold && !wascold) | |
1395 | *desc = NULL; | |
1396 | ||
1397 | return 0; | |
1398 | } | |
1399 | ||
f5373788 PB |
1400 | /* |
1401 | * DViCO bluebird firmware needs the "warm" product ID to be patched into the | |
1402 | * firmware file before download. | |
1403 | */ | |
1404 | ||
702a6762 | 1405 | static const int dvico_firmware_id_offsets[] = { 6638, 3204 }; |
f35db23c MK |
1406 | static int bluebird_patch_dvico_firmware_download(struct usb_device *udev, |
1407 | const struct firmware *fw) | |
f5373788 | 1408 | { |
702a6762 CP |
1409 | int pos; |
1410 | ||
1411 | for (pos = 0; pos < ARRAY_SIZE(dvico_firmware_id_offsets); pos++) { | |
1412 | int idoff = dvico_firmware_id_offsets[pos]; | |
f5373788 | 1413 | |
702a6762 CP |
1414 | if (fw->size < idoff + 4) |
1415 | continue; | |
f5373788 | 1416 | |
702a6762 CP |
1417 | if (fw->data[idoff] == (USB_VID_DVICO & 0xff) && |
1418 | fw->data[idoff + 1] == USB_VID_DVICO >> 8) { | |
e62f89f2 DW |
1419 | struct firmware new_fw; |
1420 | u8 *new_fw_data = vmalloc(fw->size); | |
1421 | int ret; | |
1422 | ||
1423 | if (!new_fw_data) | |
1424 | return -ENOMEM; | |
1425 | ||
1426 | memcpy(new_fw_data, fw->data, fw->size); | |
1427 | new_fw.size = fw->size; | |
1428 | new_fw.data = new_fw_data; | |
1429 | ||
1430 | new_fw_data[idoff + 2] = | |
702a6762 | 1431 | le16_to_cpu(udev->descriptor.idProduct) + 1; |
e62f89f2 | 1432 | new_fw_data[idoff + 3] = |
702a6762 | 1433 | le16_to_cpu(udev->descriptor.idProduct) >> 8; |
f5373788 | 1434 | |
e62f89f2 DW |
1435 | ret = usb_cypress_load_firmware(udev, &new_fw, |
1436 | CYPRESS_FX2); | |
1437 | vfree(new_fw_data); | |
1438 | return ret; | |
702a6762 | 1439 | } |
f5373788 PB |
1440 | } |
1441 | ||
1442 | return -EINVAL; | |
1443 | } | |
1444 | ||
22c6d93a | 1445 | /* DVB USB Driver stuff */ |
4d43e13f PB |
1446 | static struct dvb_usb_device_properties cxusb_medion_properties; |
1447 | static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties; | |
1448 | static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties; | |
1449 | static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties; | |
1450 | static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties; | |
aeb012bb | 1451 | static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties; |
8d798988 | 1452 | static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties; |
5ccaf905 | 1453 | static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties; |
702a6762 | 1454 | static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties; |
f5376ada | 1455 | static struct dvb_usb_device_properties cxusb_aver_a868r_properties; |
dfbdce04 | 1456 | static struct dvb_usb_device_properties cxusb_d680_dmb_properties; |
b18bd1d8 | 1457 | static struct dvb_usb_device_properties cxusb_mygica_d689_properties; |
a0f629b9 | 1458 | static struct dvb_usb_device_properties cxusb_mygica_t230_properties; |
22c6d93a PB |
1459 | |
1460 | static int cxusb_probe(struct usb_interface *intf, | |
f35db23c | 1461 | const struct usb_device_id *id) |
22c6d93a | 1462 | { |
78e92006 JG |
1463 | if (0 == dvb_usb_device_init(intf, &cxusb_medion_properties, |
1464 | THIS_MODULE, NULL, adapter_nr) || | |
1465 | 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgh064f_properties, | |
1466 | THIS_MODULE, NULL, adapter_nr) || | |
1467 | 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dee1601_properties, | |
1468 | THIS_MODULE, NULL, adapter_nr) || | |
1469 | 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgz201_properties, | |
1470 | THIS_MODULE, NULL, adapter_nr) || | |
1471 | 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dtt7579_properties, | |
1472 | THIS_MODULE, NULL, adapter_nr) || | |
1473 | 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dualdig4_properties, | |
1474 | THIS_MODULE, NULL, adapter_nr) || | |
1475 | 0 == dvb_usb_device_init(intf, &cxusb_bluebird_nano2_properties, | |
1476 | THIS_MODULE, NULL, adapter_nr) || | |
1477 | 0 == dvb_usb_device_init(intf, | |
1478 | &cxusb_bluebird_nano2_needsfirmware_properties, | |
f5376ada DG |
1479 | THIS_MODULE, NULL, adapter_nr) || |
1480 | 0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties, | |
1481 | THIS_MODULE, NULL, adapter_nr) || | |
8d798988 AB |
1482 | 0 == dvb_usb_device_init(intf, |
1483 | &cxusb_bluebird_dualdig4_rev2_properties, | |
1484 | THIS_MODULE, NULL, adapter_nr) || | |
dfbdce04 TL |
1485 | 0 == dvb_usb_device_init(intf, &cxusb_d680_dmb_properties, |
1486 | THIS_MODULE, NULL, adapter_nr) || | |
b18bd1d8 DW |
1487 | 0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties, |
1488 | THIS_MODULE, NULL, adapter_nr) || | |
a0f629b9 C |
1489 | 0 == dvb_usb_device_init(intf, &cxusb_mygica_t230_properties, |
1490 | THIS_MODULE, NULL, adapter_nr) || | |
f5376ada | 1491 | 0) |
effee033 | 1492 | return 0; |
effee033 MK |
1493 | |
1494 | return -EINVAL; | |
22c6d93a PB |
1495 | } |
1496 | ||
26c42b0d OS |
1497 | static void cxusb_disconnect(struct usb_interface *intf) |
1498 | { | |
1499 | struct dvb_usb_device *d = usb_get_intfdata(intf); | |
1500 | struct cxusb_state *st = d->priv; | |
1501 | struct i2c_client *client; | |
1502 | ||
1503 | /* remove I2C client for tuner */ | |
1504 | client = st->i2c_client_tuner; | |
1505 | if (client) { | |
1506 | module_put(client->dev.driver->owner); | |
1507 | i2c_unregister_device(client); | |
1508 | } | |
1509 | ||
1510 | /* remove I2C client for demodulator */ | |
1511 | client = st->i2c_client_demod; | |
1512 | if (client) { | |
1513 | module_put(client->dev.driver->owner); | |
1514 | i2c_unregister_device(client); | |
1515 | } | |
1516 | ||
1517 | dvb_usb_device_exit(intf); | |
1518 | } | |
1519 | ||
974e08d8 DH |
1520 | enum cxusb_table_index { |
1521 | MEDION_MD95700, | |
1522 | DVICO_BLUEBIRD_LG064F_COLD, | |
1523 | DVICO_BLUEBIRD_LG064F_WARM, | |
1524 | DVICO_BLUEBIRD_DUAL_1_COLD, | |
1525 | DVICO_BLUEBIRD_DUAL_1_WARM, | |
1526 | DVICO_BLUEBIRD_LGZ201_COLD, | |
1527 | DVICO_BLUEBIRD_LGZ201_WARM, | |
1528 | DVICO_BLUEBIRD_TH7579_COLD, | |
1529 | DVICO_BLUEBIRD_TH7579_WARM, | |
1530 | DIGITALNOW_BLUEBIRD_DUAL_1_COLD, | |
1531 | DIGITALNOW_BLUEBIRD_DUAL_1_WARM, | |
1532 | DVICO_BLUEBIRD_DUAL_2_COLD, | |
1533 | DVICO_BLUEBIRD_DUAL_2_WARM, | |
1534 | DVICO_BLUEBIRD_DUAL_4, | |
1535 | DVICO_BLUEBIRD_DVB_T_NANO_2, | |
1536 | DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM, | |
1537 | AVERMEDIA_VOLAR_A868R, | |
1538 | DVICO_BLUEBIRD_DUAL_4_REV_2, | |
1539 | CONEXANT_D680_DMB, | |
1540 | MYGICA_D689, | |
1541 | MYGICA_T230, | |
1542 | NR__cxusb_table_index | |
1543 | }; | |
1544 | ||
1545 | static struct usb_device_id cxusb_table[NR__cxusb_table_index + 1] = { | |
1546 | [MEDION_MD95700] = { | |
1547 | USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) | |
1548 | }, | |
1549 | [DVICO_BLUEBIRD_LG064F_COLD] = { | |
1550 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) | |
1551 | }, | |
1552 | [DVICO_BLUEBIRD_LG064F_WARM] = { | |
1553 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_WARM) | |
1554 | }, | |
1555 | [DVICO_BLUEBIRD_DUAL_1_COLD] = { | |
1556 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_COLD) | |
1557 | }, | |
1558 | [DVICO_BLUEBIRD_DUAL_1_WARM] = { | |
1559 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM) | |
1560 | }, | |
1561 | [DVICO_BLUEBIRD_LGZ201_COLD] = { | |
1562 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_COLD) | |
1563 | }, | |
1564 | [DVICO_BLUEBIRD_LGZ201_WARM] = { | |
1565 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_WARM) | |
1566 | }, | |
1567 | [DVICO_BLUEBIRD_TH7579_COLD] = { | |
1568 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_COLD) | |
1569 | }, | |
1570 | [DVICO_BLUEBIRD_TH7579_WARM] = { | |
1571 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_WARM) | |
1572 | }, | |
1573 | [DIGITALNOW_BLUEBIRD_DUAL_1_COLD] = { | |
1574 | USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD) | |
1575 | }, | |
1576 | [DIGITALNOW_BLUEBIRD_DUAL_1_WARM] = { | |
1577 | USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM) | |
1578 | }, | |
1579 | [DVICO_BLUEBIRD_DUAL_2_COLD] = { | |
1580 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD) | |
1581 | }, | |
1582 | [DVICO_BLUEBIRD_DUAL_2_WARM] = { | |
1583 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM) | |
1584 | }, | |
1585 | [DVICO_BLUEBIRD_DUAL_4] = { | |
1586 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) | |
1587 | }, | |
1588 | [DVICO_BLUEBIRD_DVB_T_NANO_2] = { | |
1589 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) | |
1590 | }, | |
1591 | [DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM] = { | |
1592 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) | |
1593 | }, | |
1594 | [AVERMEDIA_VOLAR_A868R] = { | |
1595 | USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) | |
1596 | }, | |
1597 | [DVICO_BLUEBIRD_DUAL_4_REV_2] = { | |
1598 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) | |
1599 | }, | |
1600 | [CONEXANT_D680_DMB] = { | |
1601 | USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) | |
1602 | }, | |
1603 | [MYGICA_D689] = { | |
1604 | USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) | |
1605 | }, | |
1606 | [MYGICA_T230] = { | |
1607 | USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230) | |
1608 | }, | |
f35db23c | 1609 | {} /* Terminating entry */ |
22c6d93a PB |
1610 | }; |
1611 | MODULE_DEVICE_TABLE (usb, cxusb_table); | |
1612 | ||
4d43e13f | 1613 | static struct dvb_usb_device_properties cxusb_medion_properties = { |
22c6d93a PB |
1614 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
1615 | ||
1616 | .usb_ctrl = CYPRESS_FX2, | |
1617 | ||
1618 | .size_of_priv = sizeof(struct cxusb_state), | |
1619 | ||
4d43e13f PB |
1620 | .num_adapters = 1, |
1621 | .adapter = { | |
1622 | { | |
77eed219 MK |
1623 | .num_frontends = 1, |
1624 | .fe = {{ | |
01451e72 PB |
1625 | .streaming_ctrl = cxusb_streaming_ctrl, |
1626 | .frontend_attach = cxusb_cx22702_frontend_attach, | |
1627 | .tuner_attach = cxusb_fmd1216me_tuner_attach, | |
1628 | /* parameter for the MPEG2-data transfer */ | |
1629 | .stream = { | |
1630 | .type = USB_BULK, | |
1631 | .count = 5, | |
1632 | .endpoint = 0x02, | |
1633 | .u = { | |
1634 | .bulk = { | |
1635 | .buffersize = 8192, | |
1636 | } | |
1637 | } | |
1638 | }, | |
77eed219 | 1639 | }}, |
4d43e13f PB |
1640 | }, |
1641 | }, | |
1642 | .power_ctrl = cxusb_power_ctrl, | |
1643 | ||
1644 | .i2c_algo = &cxusb_i2c_algo, | |
1645 | ||
1646 | .generic_bulk_ctrl_endpoint = 0x01, | |
1647 | ||
22c6d93a PB |
1648 | .num_device_descs = 1, |
1649 | .devices = { | |
1650 | { "Medion MD95700 (MDUSBTV-HYBRID)", | |
1651 | { NULL }, | |
974e08d8 | 1652 | { &cxusb_table[MEDION_MD95700], NULL }, |
22c6d93a PB |
1653 | }, |
1654 | } | |
1655 | }; | |
1656 | ||
4d43e13f | 1657 | static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = { |
effee033 MK |
1658 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
1659 | ||
f5373788 PB |
1660 | .usb_ctrl = DEVICE_SPECIFIC, |
1661 | .firmware = "dvb-usb-bluebird-01.fw", | |
1662 | .download_firmware = bluebird_patch_dvico_firmware_download, | |
37bdfa06 MK |
1663 | /* use usb alt setting 0 for EP4 transfer (dvb-t), |
1664 | use usb alt setting 7 for EP2 transfer (atsc) */ | |
effee033 MK |
1665 | |
1666 | .size_of_priv = sizeof(struct cxusb_state), | |
1667 | ||
4d43e13f PB |
1668 | .num_adapters = 1, |
1669 | .adapter = { | |
1670 | { | |
77eed219 MK |
1671 | .num_frontends = 1, |
1672 | .fe = {{ | |
01451e72 PB |
1673 | .streaming_ctrl = cxusb_streaming_ctrl, |
1674 | .frontend_attach = cxusb_lgdt3303_frontend_attach, | |
f71a56c1 | 1675 | .tuner_attach = cxusb_lgh064f_tuner_attach, |
01451e72 PB |
1676 | |
1677 | /* parameter for the MPEG2-data transfer */ | |
1678 | .stream = { | |
1679 | .type = USB_BULK, | |
1680 | .count = 5, | |
1681 | .endpoint = 0x02, | |
1682 | .u = { | |
1683 | .bulk = { | |
1684 | .buffersize = 8192, | |
1685 | } | |
1686 | } | |
1687 | }, | |
77eed219 | 1688 | }}, |
4d43e13f PB |
1689 | }, |
1690 | }, | |
1691 | ||
1692 | .power_ctrl = cxusb_bluebird_power_ctrl, | |
1693 | ||
1694 | .i2c_algo = &cxusb_i2c_algo, | |
1695 | ||
f72a27b8 MCC |
1696 | .rc.legacy = { |
1697 | .rc_interval = 100, | |
2f4f58d6 MCC |
1698 | .rc_map_table = rc_map_dvico_portable_table, |
1699 | .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table), | |
f72a27b8 MCC |
1700 | .rc_query = cxusb_rc_query, |
1701 | }, | |
4d43e13f PB |
1702 | |
1703 | .generic_bulk_ctrl_endpoint = 0x01, | |
effee033 MK |
1704 | |
1705 | .num_device_descs = 1, | |
1706 | .devices = { | |
1707 | { "DViCO FusionHDTV5 USB Gold", | |
974e08d8 DH |
1708 | { &cxusb_table[DVICO_BLUEBIRD_LG064F_COLD], NULL }, |
1709 | { &cxusb_table[DVICO_BLUEBIRD_LG064F_WARM], NULL }, | |
effee033 MK |
1710 | }, |
1711 | } | |
1712 | }; | |
1713 | ||
4d43e13f | 1714 | static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = { |
0029ee14 CP |
1715 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
1716 | ||
f5373788 PB |
1717 | .usb_ctrl = DEVICE_SPECIFIC, |
1718 | .firmware = "dvb-usb-bluebird-01.fw", | |
1719 | .download_firmware = bluebird_patch_dvico_firmware_download, | |
0029ee14 CP |
1720 | /* use usb alt setting 0 for EP4 transfer (dvb-t), |
1721 | use usb alt setting 7 for EP2 transfer (atsc) */ | |
1722 | ||
1723 | .size_of_priv = sizeof(struct cxusb_state), | |
1724 | ||
4d43e13f PB |
1725 | .num_adapters = 1, |
1726 | .adapter = { | |
1727 | { | |
77eed219 MK |
1728 | .num_frontends = 1, |
1729 | .fe = {{ | |
01451e72 PB |
1730 | .streaming_ctrl = cxusb_streaming_ctrl, |
1731 | .frontend_attach = cxusb_dee1601_frontend_attach, | |
1732 | .tuner_attach = cxusb_dee1601_tuner_attach, | |
1733 | /* parameter for the MPEG2-data transfer */ | |
4d43e13f PB |
1734 | .stream = { |
1735 | .type = USB_BULK, | |
01451e72 PB |
1736 | .count = 5, |
1737 | .endpoint = 0x04, | |
1738 | .u = { | |
1739 | .bulk = { | |
1740 | .buffersize = 8192, | |
1741 | } | |
1742 | } | |
1743 | }, | |
77eed219 | 1744 | }}, |
4d43e13f PB |
1745 | }, |
1746 | }, | |
1747 | ||
1748 | .power_ctrl = cxusb_bluebird_power_ctrl, | |
1749 | ||
1750 | .i2c_algo = &cxusb_i2c_algo, | |
1751 | ||
f72a27b8 MCC |
1752 | .rc.legacy = { |
1753 | .rc_interval = 150, | |
2f4f58d6 MCC |
1754 | .rc_map_table = rc_map_dvico_mce_table, |
1755 | .rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table), | |
f72a27b8 MCC |
1756 | .rc_query = cxusb_rc_query, |
1757 | }, | |
4d43e13f PB |
1758 | |
1759 | .generic_bulk_ctrl_endpoint = 0x01, | |
0029ee14 | 1760 | |
587c03d1 | 1761 | .num_device_descs = 3, |
0029ee14 CP |
1762 | .devices = { |
1763 | { "DViCO FusionHDTV DVB-T Dual USB", | |
974e08d8 DH |
1764 | { &cxusb_table[DVICO_BLUEBIRD_DUAL_1_COLD], NULL }, |
1765 | { &cxusb_table[DVICO_BLUEBIRD_DUAL_1_WARM], NULL }, | |
0029ee14 | 1766 | }, |
ac9ffb90 | 1767 | { "DigitalNow DVB-T Dual USB", |
974e08d8 DH |
1768 | { &cxusb_table[DIGITALNOW_BLUEBIRD_DUAL_1_COLD], NULL }, |
1769 | { &cxusb_table[DIGITALNOW_BLUEBIRD_DUAL_1_WARM], NULL }, | |
ac9ffb90 | 1770 | }, |
587c03d1 | 1771 | { "DViCO FusionHDTV DVB-T Dual Digital 2", |
974e08d8 DH |
1772 | { &cxusb_table[DVICO_BLUEBIRD_DUAL_2_COLD], NULL }, |
1773 | { &cxusb_table[DVICO_BLUEBIRD_DUAL_2_WARM], NULL }, | |
587c03d1 | 1774 | }, |
0029ee14 CP |
1775 | } |
1776 | }; | |
1777 | ||
4d43e13f | 1778 | static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = { |
6f447259 MK |
1779 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
1780 | ||
1781 | .usb_ctrl = DEVICE_SPECIFIC, | |
1782 | .firmware = "dvb-usb-bluebird-01.fw", | |
1783 | .download_firmware = bluebird_patch_dvico_firmware_download, | |
1784 | /* use usb alt setting 0 for EP4 transfer (dvb-t), | |
1785 | use usb alt setting 7 for EP2 transfer (atsc) */ | |
1786 | ||
1787 | .size_of_priv = sizeof(struct cxusb_state), | |
1788 | ||
4d43e13f PB |
1789 | .num_adapters = 2, |
1790 | .adapter = { | |
1791 | { | |
77eed219 MK |
1792 | .num_frontends = 1, |
1793 | .fe = {{ | |
01451e72 PB |
1794 | .streaming_ctrl = cxusb_streaming_ctrl, |
1795 | .frontend_attach = cxusb_mt352_frontend_attach, | |
1796 | .tuner_attach = cxusb_lgz201_tuner_attach, | |
6f447259 | 1797 | |
01451e72 | 1798 | /* parameter for the MPEG2-data transfer */ |
4d43e13f PB |
1799 | .stream = { |
1800 | .type = USB_BULK, | |
01451e72 PB |
1801 | .count = 5, |
1802 | .endpoint = 0x04, | |
1803 | .u = { | |
1804 | .bulk = { | |
1805 | .buffersize = 8192, | |
1806 | } | |
1807 | } | |
1808 | }, | |
77eed219 | 1809 | }}, |
4d43e13f PB |
1810 | }, |
1811 | }, | |
1812 | .power_ctrl = cxusb_bluebird_power_ctrl, | |
1813 | ||
1814 | .i2c_algo = &cxusb_i2c_algo, | |
6f447259 | 1815 | |
f72a27b8 MCC |
1816 | .rc.legacy = { |
1817 | .rc_interval = 100, | |
2f4f58d6 MCC |
1818 | .rc_map_table = rc_map_dvico_portable_table, |
1819 | .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table), | |
f72a27b8 MCC |
1820 | .rc_query = cxusb_rc_query, |
1821 | }, | |
4d43e13f PB |
1822 | |
1823 | .generic_bulk_ctrl_endpoint = 0x01, | |
6f447259 MK |
1824 | .num_device_descs = 1, |
1825 | .devices = { | |
1826 | { "DViCO FusionHDTV DVB-T USB (LGZ201)", | |
974e08d8 DH |
1827 | { &cxusb_table[DVICO_BLUEBIRD_LGZ201_COLD], NULL }, |
1828 | { &cxusb_table[DVICO_BLUEBIRD_LGZ201_WARM], NULL }, | |
6f447259 MK |
1829 | }, |
1830 | } | |
1831 | }; | |
1832 | ||
4d43e13f | 1833 | static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = { |
6f447259 MK |
1834 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
1835 | ||
1836 | .usb_ctrl = DEVICE_SPECIFIC, | |
1837 | .firmware = "dvb-usb-bluebird-01.fw", | |
1838 | .download_firmware = bluebird_patch_dvico_firmware_download, | |
1839 | /* use usb alt setting 0 for EP4 transfer (dvb-t), | |
1840 | use usb alt setting 7 for EP2 transfer (atsc) */ | |
1841 | ||
1842 | .size_of_priv = sizeof(struct cxusb_state), | |
1843 | ||
4d43e13f PB |
1844 | .num_adapters = 1, |
1845 | .adapter = { | |
1846 | { | |
77eed219 MK |
1847 | .num_frontends = 1, |
1848 | .fe = {{ | |
01451e72 PB |
1849 | .streaming_ctrl = cxusb_streaming_ctrl, |
1850 | .frontend_attach = cxusb_mt352_frontend_attach, | |
1851 | .tuner_attach = cxusb_dtt7579_tuner_attach, | |
6f447259 | 1852 | |
01451e72 | 1853 | /* parameter for the MPEG2-data transfer */ |
4d43e13f PB |
1854 | .stream = { |
1855 | .type = USB_BULK, | |
01451e72 PB |
1856 | .count = 5, |
1857 | .endpoint = 0x04, | |
1858 | .u = { | |
1859 | .bulk = { | |
1860 | .buffersize = 8192, | |
1861 | } | |
1862 | } | |
1863 | }, | |
77eed219 | 1864 | }}, |
4d43e13f PB |
1865 | }, |
1866 | }, | |
1867 | .power_ctrl = cxusb_bluebird_power_ctrl, | |
1868 | ||
1869 | .i2c_algo = &cxusb_i2c_algo, | |
1870 | ||
f72a27b8 MCC |
1871 | .rc.legacy = { |
1872 | .rc_interval = 100, | |
2f4f58d6 MCC |
1873 | .rc_map_table = rc_map_dvico_portable_table, |
1874 | .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table), | |
f72a27b8 MCC |
1875 | .rc_query = cxusb_rc_query, |
1876 | }, | |
4d43e13f PB |
1877 | |
1878 | .generic_bulk_ctrl_endpoint = 0x01, | |
6f447259 MK |
1879 | |
1880 | .num_device_descs = 1, | |
1881 | .devices = { | |
1882 | { "DViCO FusionHDTV DVB-T USB (TH7579)", | |
974e08d8 DH |
1883 | { &cxusb_table[DVICO_BLUEBIRD_TH7579_COLD], NULL }, |
1884 | { &cxusb_table[DVICO_BLUEBIRD_TH7579_WARM], NULL }, | |
6f447259 MK |
1885 | }, |
1886 | } | |
1887 | }; | |
1888 | ||
aeb012bb CP |
1889 | static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = { |
1890 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | |
1891 | ||
1892 | .usb_ctrl = CYPRESS_FX2, | |
1893 | ||
1894 | .size_of_priv = sizeof(struct cxusb_state), | |
1895 | ||
1896 | .num_adapters = 1, | |
1897 | .adapter = { | |
1898 | { | |
77eed219 MK |
1899 | .num_frontends = 1, |
1900 | .fe = {{ | |
aeb012bb CP |
1901 | .streaming_ctrl = cxusb_streaming_ctrl, |
1902 | .frontend_attach = cxusb_dualdig4_frontend_attach, | |
1903 | .tuner_attach = cxusb_dvico_xc3028_tuner_attach, | |
1904 | /* parameter for the MPEG2-data transfer */ | |
1905 | .stream = { | |
1906 | .type = USB_BULK, | |
1907 | .count = 5, | |
1908 | .endpoint = 0x02, | |
1909 | .u = { | |
1910 | .bulk = { | |
1911 | .buffersize = 8192, | |
1912 | } | |
1913 | } | |
1914 | }, | |
77eed219 | 1915 | }}, |
aeb012bb CP |
1916 | }, |
1917 | }, | |
1918 | ||
1919 | .power_ctrl = cxusb_power_ctrl, | |
1920 | ||
1921 | .i2c_algo = &cxusb_i2c_algo, | |
1922 | ||
1923 | .generic_bulk_ctrl_endpoint = 0x01, | |
1924 | ||
f72a27b8 MCC |
1925 | .rc.legacy = { |
1926 | .rc_interval = 100, | |
2f4f58d6 MCC |
1927 | .rc_map_table = rc_map_dvico_mce_table, |
1928 | .rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table), | |
f72a27b8 MCC |
1929 | .rc_query = cxusb_bluebird2_rc_query, |
1930 | }, | |
aeb012bb CP |
1931 | |
1932 | .num_device_descs = 1, | |
1933 | .devices = { | |
1934 | { "DViCO FusionHDTV DVB-T Dual Digital 4", | |
1935 | { NULL }, | |
974e08d8 | 1936 | { &cxusb_table[DVICO_BLUEBIRD_DUAL_4], NULL }, |
aeb012bb CP |
1937 | }, |
1938 | } | |
1939 | }; | |
1940 | ||
5ccaf905 CP |
1941 | static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = { |
1942 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | |
1943 | ||
1944 | .usb_ctrl = CYPRESS_FX2, | |
702a6762 | 1945 | .identify_state = bluebird_fx2_identify_state, |
5ccaf905 CP |
1946 | |
1947 | .size_of_priv = sizeof(struct cxusb_state), | |
1948 | ||
1949 | .num_adapters = 1, | |
1950 | .adapter = { | |
1951 | { | |
77eed219 MK |
1952 | .num_frontends = 1, |
1953 | .fe = {{ | |
5ccaf905 CP |
1954 | .streaming_ctrl = cxusb_streaming_ctrl, |
1955 | .frontend_attach = cxusb_nano2_frontend_attach, | |
1956 | .tuner_attach = cxusb_dvico_xc3028_tuner_attach, | |
1957 | /* parameter for the MPEG2-data transfer */ | |
1958 | .stream = { | |
1959 | .type = USB_BULK, | |
1960 | .count = 5, | |
1961 | .endpoint = 0x02, | |
1962 | .u = { | |
1963 | .bulk = { | |
1964 | .buffersize = 8192, | |
1965 | } | |
1966 | } | |
1967 | }, | |
77eed219 | 1968 | }}, |
5ccaf905 CP |
1969 | }, |
1970 | }, | |
1971 | ||
1972 | .power_ctrl = cxusb_nano2_power_ctrl, | |
1973 | ||
1974 | .i2c_algo = &cxusb_i2c_algo, | |
1975 | ||
1976 | .generic_bulk_ctrl_endpoint = 0x01, | |
1977 | ||
f72a27b8 MCC |
1978 | .rc.legacy = { |
1979 | .rc_interval = 100, | |
2f4f58d6 MCC |
1980 | .rc_map_table = rc_map_dvico_portable_table, |
1981 | .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table), | |
f72a27b8 MCC |
1982 | .rc_query = cxusb_bluebird2_rc_query, |
1983 | }, | |
5ccaf905 CP |
1984 | |
1985 | .num_device_descs = 1, | |
1986 | .devices = { | |
1987 | { "DViCO FusionHDTV DVB-T NANO2", | |
1988 | { NULL }, | |
974e08d8 | 1989 | { &cxusb_table[DVICO_BLUEBIRD_DVB_T_NANO_2], NULL }, |
5ccaf905 CP |
1990 | }, |
1991 | } | |
1992 | }; | |
1993 | ||
702a6762 CP |
1994 | static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties = { |
1995 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | |
1996 | ||
1997 | .usb_ctrl = DEVICE_SPECIFIC, | |
1998 | .firmware = "dvb-usb-bluebird-02.fw", | |
1999 | .download_firmware = bluebird_patch_dvico_firmware_download, | |
2000 | .identify_state = bluebird_fx2_identify_state, | |
2001 | ||
2002 | .size_of_priv = sizeof(struct cxusb_state), | |
2003 | ||
2004 | .num_adapters = 1, | |
2005 | .adapter = { | |
2006 | { | |
77eed219 MK |
2007 | .num_frontends = 1, |
2008 | .fe = {{ | |
702a6762 CP |
2009 | .streaming_ctrl = cxusb_streaming_ctrl, |
2010 | .frontend_attach = cxusb_nano2_frontend_attach, | |
2011 | .tuner_attach = cxusb_dvico_xc3028_tuner_attach, | |
2012 | /* parameter for the MPEG2-data transfer */ | |
2013 | .stream = { | |
2014 | .type = USB_BULK, | |
2015 | .count = 5, | |
2016 | .endpoint = 0x02, | |
2017 | .u = { | |
2018 | .bulk = { | |
2019 | .buffersize = 8192, | |
2020 | } | |
2021 | } | |
2022 | }, | |
77eed219 | 2023 | }}, |
702a6762 CP |
2024 | }, |
2025 | }, | |
2026 | ||
2027 | .power_ctrl = cxusb_nano2_power_ctrl, | |
2028 | ||
2029 | .i2c_algo = &cxusb_i2c_algo, | |
2030 | ||
2031 | .generic_bulk_ctrl_endpoint = 0x01, | |
2032 | ||
f72a27b8 MCC |
2033 | .rc.legacy = { |
2034 | .rc_interval = 100, | |
2f4f58d6 MCC |
2035 | .rc_map_table = rc_map_dvico_portable_table, |
2036 | .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table), | |
f72a27b8 MCC |
2037 | .rc_query = cxusb_rc_query, |
2038 | }, | |
702a6762 CP |
2039 | |
2040 | .num_device_descs = 1, | |
2041 | .devices = { | |
2042 | { "DViCO FusionHDTV DVB-T NANO2 w/o firmware", | |
974e08d8 DH |
2043 | { &cxusb_table[DVICO_BLUEBIRD_DVB_T_NANO_2], NULL }, |
2044 | { &cxusb_table[DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM], NULL }, | |
702a6762 CP |
2045 | }, |
2046 | } | |
2047 | }; | |
2048 | ||
f5376ada DG |
2049 | static struct dvb_usb_device_properties cxusb_aver_a868r_properties = { |
2050 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | |
2051 | ||
2052 | .usb_ctrl = CYPRESS_FX2, | |
2053 | ||
2054 | .size_of_priv = sizeof(struct cxusb_state), | |
2055 | ||
2056 | .num_adapters = 1, | |
2057 | .adapter = { | |
2058 | { | |
77eed219 MK |
2059 | .num_frontends = 1, |
2060 | .fe = {{ | |
f5376ada DG |
2061 | .streaming_ctrl = cxusb_aver_streaming_ctrl, |
2062 | .frontend_attach = cxusb_aver_lgdt3303_frontend_attach, | |
2063 | .tuner_attach = cxusb_mxl5003s_tuner_attach, | |
2064 | /* parameter for the MPEG2-data transfer */ | |
2065 | .stream = { | |
2066 | .type = USB_BULK, | |
2067 | .count = 5, | |
2068 | .endpoint = 0x04, | |
2069 | .u = { | |
2070 | .bulk = { | |
2071 | .buffersize = 8192, | |
2072 | } | |
2073 | } | |
2074 | }, | |
77eed219 | 2075 | }}, |
f5376ada DG |
2076 | }, |
2077 | }, | |
2078 | .power_ctrl = cxusb_aver_power_ctrl, | |
2079 | ||
2080 | .i2c_algo = &cxusb_i2c_algo, | |
2081 | ||
2082 | .generic_bulk_ctrl_endpoint = 0x01, | |
2083 | ||
2084 | .num_device_descs = 1, | |
2085 | .devices = { | |
2086 | { "AVerMedia AVerTVHD Volar (A868R)", | |
2087 | { NULL }, | |
974e08d8 | 2088 | { &cxusb_table[AVERMEDIA_VOLAR_A868R], NULL }, |
f5376ada DG |
2089 | }, |
2090 | } | |
2091 | }; | |
2092 | ||
a2dc86b6 MK |
2093 | static |
2094 | struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = { | |
8d798988 AB |
2095 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
2096 | ||
2097 | .usb_ctrl = CYPRESS_FX2, | |
2098 | ||
2099 | .size_of_priv = sizeof(struct cxusb_state), | |
2100 | ||
2101 | .num_adapters = 1, | |
2102 | .adapter = { | |
2103 | { | |
77eed219 MK |
2104 | .size_of_priv = sizeof(struct dib0700_adapter_state), |
2105 | .num_frontends = 1, | |
2106 | .fe = {{ | |
a2dc86b6 MK |
2107 | .streaming_ctrl = cxusb_streaming_ctrl, |
2108 | .frontend_attach = cxusb_dualdig4_rev2_frontend_attach, | |
2109 | .tuner_attach = cxusb_dualdig4_rev2_tuner_attach, | |
8d798988 AB |
2110 | /* parameter for the MPEG2-data transfer */ |
2111 | .stream = { | |
2112 | .type = USB_BULK, | |
2113 | .count = 7, | |
2114 | .endpoint = 0x02, | |
2115 | .u = { | |
2116 | .bulk = { | |
2117 | .buffersize = 4096, | |
2118 | } | |
2119 | } | |
2120 | }, | |
77eed219 | 2121 | }}, |
8d798988 AB |
2122 | }, |
2123 | }, | |
2124 | ||
2125 | .power_ctrl = cxusb_bluebird_power_ctrl, | |
2126 | ||
2127 | .i2c_algo = &cxusb_i2c_algo, | |
2128 | ||
2129 | .generic_bulk_ctrl_endpoint = 0x01, | |
2130 | ||
f72a27b8 MCC |
2131 | .rc.legacy = { |
2132 | .rc_interval = 100, | |
2f4f58d6 MCC |
2133 | .rc_map_table = rc_map_dvico_mce_table, |
2134 | .rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table), | |
f72a27b8 MCC |
2135 | .rc_query = cxusb_rc_query, |
2136 | }, | |
8d798988 AB |
2137 | |
2138 | .num_device_descs = 1, | |
2139 | .devices = { | |
2140 | { "DViCO FusionHDTV DVB-T Dual Digital 4 (rev 2)", | |
2141 | { NULL }, | |
974e08d8 | 2142 | { &cxusb_table[DVICO_BLUEBIRD_DUAL_4_REV_2], NULL }, |
8d798988 AB |
2143 | }, |
2144 | } | |
2145 | }; | |
2146 | ||
dfbdce04 TL |
2147 | static struct dvb_usb_device_properties cxusb_d680_dmb_properties = { |
2148 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | |
2149 | ||
2150 | .usb_ctrl = CYPRESS_FX2, | |
2151 | ||
2152 | .size_of_priv = sizeof(struct cxusb_state), | |
2153 | ||
2154 | .num_adapters = 1, | |
2155 | .adapter = { | |
2156 | { | |
77eed219 MK |
2157 | .num_frontends = 1, |
2158 | .fe = {{ | |
dfbdce04 TL |
2159 | .streaming_ctrl = cxusb_d680_dmb_streaming_ctrl, |
2160 | .frontend_attach = cxusb_d680_dmb_frontend_attach, | |
2161 | .tuner_attach = cxusb_d680_dmb_tuner_attach, | |
2162 | ||
2163 | /* parameter for the MPEG2-data transfer */ | |
2164 | .stream = { | |
2165 | .type = USB_BULK, | |
2166 | .count = 5, | |
2167 | .endpoint = 0x02, | |
2168 | .u = { | |
2169 | .bulk = { | |
2170 | .buffersize = 8192, | |
2171 | } | |
2172 | } | |
2173 | }, | |
77eed219 | 2174 | }}, |
dfbdce04 TL |
2175 | }, |
2176 | }, | |
2177 | ||
2178 | .power_ctrl = cxusb_d680_dmb_power_ctrl, | |
2179 | ||
2180 | .i2c_algo = &cxusb_i2c_algo, | |
2181 | ||
2182 | .generic_bulk_ctrl_endpoint = 0x01, | |
2183 | ||
f72a27b8 MCC |
2184 | .rc.legacy = { |
2185 | .rc_interval = 100, | |
2f4f58d6 MCC |
2186 | .rc_map_table = rc_map_d680_dmb_table, |
2187 | .rc_map_size = ARRAY_SIZE(rc_map_d680_dmb_table), | |
f72a27b8 MCC |
2188 | .rc_query = cxusb_d680_dmb_rc_query, |
2189 | }, | |
dfbdce04 TL |
2190 | |
2191 | .num_device_descs = 1, | |
2192 | .devices = { | |
2193 | { | |
2194 | "Conexant DMB-TH Stick", | |
2195 | { NULL }, | |
974e08d8 | 2196 | { &cxusb_table[CONEXANT_D680_DMB], NULL }, |
dfbdce04 TL |
2197 | }, |
2198 | } | |
2199 | }; | |
2200 | ||
b18bd1d8 DW |
2201 | static struct dvb_usb_device_properties cxusb_mygica_d689_properties = { |
2202 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | |
2203 | ||
2204 | .usb_ctrl = CYPRESS_FX2, | |
2205 | ||
2206 | .size_of_priv = sizeof(struct cxusb_state), | |
2207 | ||
2208 | .num_adapters = 1, | |
2209 | .adapter = { | |
2210 | { | |
77eed219 MK |
2211 | .num_frontends = 1, |
2212 | .fe = {{ | |
b18bd1d8 DW |
2213 | .streaming_ctrl = cxusb_d680_dmb_streaming_ctrl, |
2214 | .frontend_attach = cxusb_mygica_d689_frontend_attach, | |
2215 | .tuner_attach = cxusb_mygica_d689_tuner_attach, | |
2216 | ||
2217 | /* parameter for the MPEG2-data transfer */ | |
2218 | .stream = { | |
2219 | .type = USB_BULK, | |
2220 | .count = 5, | |
2221 | .endpoint = 0x02, | |
2222 | .u = { | |
2223 | .bulk = { | |
2224 | .buffersize = 8192, | |
2225 | } | |
2226 | } | |
2227 | }, | |
77eed219 | 2228 | }}, |
b18bd1d8 DW |
2229 | }, |
2230 | }, | |
2231 | ||
2232 | .power_ctrl = cxusb_d680_dmb_power_ctrl, | |
2233 | ||
2234 | .i2c_algo = &cxusb_i2c_algo, | |
2235 | ||
2236 | .generic_bulk_ctrl_endpoint = 0x01, | |
2237 | ||
f72a27b8 MCC |
2238 | .rc.legacy = { |
2239 | .rc_interval = 100, | |
2f4f58d6 MCC |
2240 | .rc_map_table = rc_map_d680_dmb_table, |
2241 | .rc_map_size = ARRAY_SIZE(rc_map_d680_dmb_table), | |
f72a27b8 MCC |
2242 | .rc_query = cxusb_d680_dmb_rc_query, |
2243 | }, | |
b18bd1d8 DW |
2244 | |
2245 | .num_device_descs = 1, | |
2246 | .devices = { | |
2247 | { | |
2248 | "Mygica D689 DMB-TH", | |
2249 | { NULL }, | |
974e08d8 | 2250 | { &cxusb_table[MYGICA_D689], NULL }, |
b18bd1d8 DW |
2251 | }, |
2252 | } | |
2253 | }; | |
2254 | ||
a0f629b9 C |
2255 | static struct dvb_usb_device_properties cxusb_mygica_t230_properties = { |
2256 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | |
2257 | ||
2258 | .usb_ctrl = CYPRESS_FX2, | |
2259 | ||
2260 | .size_of_priv = sizeof(struct cxusb_state), | |
2261 | ||
2262 | .num_adapters = 1, | |
2263 | .adapter = { | |
2264 | { | |
2265 | .num_frontends = 1, | |
2266 | .fe = {{ | |
2267 | .streaming_ctrl = cxusb_streaming_ctrl, | |
2268 | .frontend_attach = cxusb_mygica_t230_frontend_attach, | |
2269 | ||
2270 | /* parameter for the MPEG2-data transfer */ | |
2271 | .stream = { | |
2272 | .type = USB_BULK, | |
2273 | .count = 5, | |
2274 | .endpoint = 0x02, | |
2275 | .u = { | |
2276 | .bulk = { | |
2277 | .buffersize = 8192, | |
2278 | } | |
2279 | } | |
2280 | }, | |
2281 | } }, | |
2282 | }, | |
2283 | }, | |
2284 | ||
2285 | .power_ctrl = cxusb_d680_dmb_power_ctrl, | |
2286 | ||
2287 | .i2c_algo = &cxusb_i2c_algo, | |
2288 | ||
2289 | .generic_bulk_ctrl_endpoint = 0x01, | |
2290 | ||
2291 | .rc.legacy = { | |
2292 | .rc_interval = 100, | |
2293 | .rc_map_table = rc_map_d680_dmb_table, | |
2294 | .rc_map_size = ARRAY_SIZE(rc_map_d680_dmb_table), | |
2295 | .rc_query = cxusb_d680_dmb_rc_query, | |
2296 | }, | |
2297 | ||
2298 | .num_device_descs = 1, | |
2299 | .devices = { | |
2300 | { | |
2301 | "Mygica T230 DVB-T/T2/C", | |
2302 | { NULL }, | |
974e08d8 | 2303 | { &cxusb_table[MYGICA_T230], NULL }, |
a0f629b9 C |
2304 | }, |
2305 | } | |
2306 | }; | |
2307 | ||
22c6d93a | 2308 | static struct usb_driver cxusb_driver = { |
63b5c1c4 | 2309 | .name = "dvb_usb_cxusb", |
22c6d93a | 2310 | .probe = cxusb_probe, |
26c42b0d | 2311 | .disconnect = cxusb_disconnect, |
22c6d93a PB |
2312 | .id_table = cxusb_table, |
2313 | }; | |
2314 | ||
ecb3b2b3 | 2315 | module_usb_driver(cxusb_driver); |
22c6d93a PB |
2316 | |
2317 | MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); | |
5b9ed286 | 2318 | MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>"); |
f4efb4db | 2319 | MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); |
22c6d93a PB |
2320 | MODULE_DESCRIPTION("Driver for Conexant USB2.0 hybrid reference design"); |
2321 | MODULE_VERSION("1.0-alpha"); | |
2322 | MODULE_LICENSE("GPL"); |