Commit | Line | Data |
---|---|---|
a10e763b | 1 | // SPDX-License-Identifier: GPL-2.0-only |
22c6d93a PB |
2 | /* DVB USB compliant linux driver for Conexant USB reference design. |
3 | * | |
4 | * The Conexant reference design I saw on their website was only for analogue | |
5 | * capturing (using the cx25842). The box I took to write this driver (reverse | |
6 | * engineered) is the one labeled Medion MD95700. In addition to the cx25842 | |
7 | * for analogue capturing it also has a cx22702 DVB-T demodulator on the main | |
8 | * board. Besides it has a atiremote (X10) and a USB2.0 hub onboard. | |
9 | * | |
10 | * Maybe it is a little bit premature to call this driver cxusb, but I assume | |
11 | * the USB protocol is identical or at least inherited from the reference | |
12 | * design, so it can be reused for the "analogue-only" device (if it will | |
13 | * appear at all). | |
14 | * | |
81481e9e | 15 | * TODO: Use the cx25840-driver for the analogue part |
22c6d93a | 16 | * |
99e44da7 | 17 | * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@posteo.de) |
5b9ed286 | 18 | * Copyright (C) 2006 Michael Krufky (mkrufky@linuxtv.org) |
aeb012bb | 19 | * Copyright (C) 2006, 2007 Chris Pascoe (c.pascoe@itee.uq.edu.au) |
22c6d93a | 20 | * |
670d7adb | 21 | * see Documentation/media/dvb-drivers/dvb-usb.rst for more information |
22c6d93a | 22 | */ |
827855d3 | 23 | #include <media/tuner.h> |
e62f89f2 | 24 | #include <linux/vmalloc.h> |
5a0e3ad6 | 25 | #include <linux/slab.h> |
e40d14a8 | 26 | #include <linux/kernel.h> |
827855d3 | 27 | |
22c6d93a PB |
28 | #include "cxusb.h" |
29 | ||
30 | #include "cx22702.h" | |
effee033 | 31 | #include "lgdt330x.h" |
0029ee14 CP |
32 | #include "mt352.h" |
33 | #include "mt352_priv.h" | |
c9ce3940 | 34 | #include "zl10353.h" |
aeb012bb | 35 | #include "tuner-xc2028.h" |
827855d3 | 36 | #include "tuner-simple.h" |
f5376ada | 37 | #include "mxl5005s.h" |
b18bd1d8 | 38 | #include "max2165.h" |
8d798988 AB |
39 | #include "dib7000p.h" |
40 | #include "dib0070.h" | |
6bf1a997 | 41 | #include "lgs8gxx.h" |
b18bd1d8 | 42 | #include "atbm8830.h" |
26c42b0d OS |
43 | #include "si2168.h" |
44 | #include "si2157.h" | |
22c6d93a PB |
45 | |
46 | /* debug */ | |
53133afb | 47 | static int dvb_usb_cxusb_debug; |
f35db23c | 48 | module_param_named(debug, dvb_usb_cxusb_debug, int, 0644); |
22c6d93a | 49 | MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); |
78e92006 JG |
50 | |
51 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | |
52 | ||
f5376ada DG |
53 | #define deb_info(args...) dprintk(dvb_usb_cxusb_debug, 0x03, args) |
54 | #define deb_i2c(args...) dprintk(dvb_usb_cxusb_debug, 0x02, args) | |
22c6d93a PB |
55 | |
56 | static int cxusb_ctrl_msg(struct dvb_usb_device *d, | |
cee32edb | 57 | u8 cmd, const u8 *wbuf, int wlen, u8 *rbuf, int rlen) |
22c6d93a | 58 | { |
17ce039b | 59 | struct cxusb_state *st = d->priv; |
3f190e3a | 60 | int ret; |
64f7ef8a | 61 | |
17ce039b MCC |
62 | if (1 + wlen > MAX_XFER_SIZE) { |
63 | warn("i2c wr: len=%d is too big!\n", wlen); | |
64f7ef8a MCC |
64 | return -EOPNOTSUPP; |
65 | } | |
66 | ||
3f190e3a SB |
67 | if (rlen > MAX_XFER_SIZE) { |
68 | warn("i2c rd: len=%d is too big!\n", rlen); | |
69 | return -EOPNOTSUPP; | |
70 | } | |
22c6d93a | 71 | |
7724325a | 72 | mutex_lock(&d->data_mutex); |
17ce039b MCC |
73 | st->data[0] = cmd; |
74 | memcpy(&st->data[1], wbuf, wlen); | |
3f190e3a SB |
75 | ret = dvb_usb_generic_rw(d, st->data, 1 + wlen, st->data, rlen, 0); |
76 | if (!ret && rbuf && rlen) | |
77 | memcpy(rbuf, st->data, rlen); | |
17ce039b | 78 | |
7724325a | 79 | mutex_unlock(&d->data_mutex); |
17ce039b | 80 | return ret; |
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; | |
cee32edb CIK |
291 | u8 buf; |
292 | static const u8 bufs[] = { | |
f5376ada DG |
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); | |
e40d14a8 | 305 | for (i = 0; i < ARRAY_SIZE(bufs); i += 4 / sizeof(u8)) { |
f5376ada DG |
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 | ||
5691c847 MK |
317 | static 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 | ||
5ccaf905 CP |
326 | static 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 | ||
dfbdce04 TL |
337 | static 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 | ||
4d43e13f | 351 | static int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) |
22c6d93a | 352 | { |
8257e8a4 PB |
353 | u8 buf[2] = { 0x03, 0x00 }; |
354 | if (onoff) | |
4d43e13f | 355 | cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON, buf, 2, NULL, 0); |
8257e8a4 | 356 | else |
4d43e13f | 357 | cxusb_ctrl_msg(adap->dev, CMD_STREAMING_OFF, NULL, 0, NULL, 0); |
8257e8a4 | 358 | |
22c6d93a PB |
359 | return 0; |
360 | } | |
361 | ||
f5376ada DG |
362 | static 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 | ||
5fa88151 C |
372 | static int cxusb_read_status(struct dvb_frontend *fe, |
373 | enum fe_status *status) | |
374 | { | |
375 | struct dvb_usb_adapter *adap = (struct dvb_usb_adapter *)fe->dvb->priv; | |
376 | struct cxusb_state *state = (struct cxusb_state *)adap->dev->priv; | |
377 | int ret; | |
378 | ||
379 | ret = state->fe_read_status(fe, status); | |
380 | ||
381 | /* it need resync slave fifo when signal change from unlock to lock.*/ | |
382 | if ((*status & FE_HAS_LOCK) && (!state->last_lock)) { | |
383 | mutex_lock(&state->stream_mutex); | |
384 | cxusb_streaming_ctrl(adap, 1); | |
385 | mutex_unlock(&state->stream_mutex); | |
386 | } | |
387 | ||
388 | state->last_lock = (*status & FE_HAS_LOCK) ? 1 : 0; | |
389 | return ret; | |
390 | } | |
391 | ||
dfbdce04 TL |
392 | static void cxusb_d680_dmb_drain_message(struct dvb_usb_device *d) |
393 | { | |
394 | int ep = d->props.generic_bulk_ctrl_endpoint; | |
395 | const int timeout = 100; | |
396 | const int junk_len = 32; | |
397 | u8 *junk; | |
398 | int rd_count; | |
399 | ||
400 | /* Discard remaining data in video pipe */ | |
401 | junk = kmalloc(junk_len, GFP_KERNEL); | |
402 | if (!junk) | |
403 | return; | |
404 | while (1) { | |
405 | if (usb_bulk_msg(d->udev, | |
406 | usb_rcvbulkpipe(d->udev, ep), | |
407 | junk, junk_len, &rd_count, timeout) < 0) | |
408 | break; | |
409 | if (!rd_count) | |
410 | break; | |
411 | } | |
412 | kfree(junk); | |
413 | } | |
414 | ||
415 | static void cxusb_d680_dmb_drain_video(struct dvb_usb_device *d) | |
416 | { | |
77eed219 | 417 | struct usb_data_stream_properties *p = &d->props.adapter[0].fe[0].stream; |
dfbdce04 TL |
418 | const int timeout = 100; |
419 | const int junk_len = p->u.bulk.buffersize; | |
420 | u8 *junk; | |
421 | int rd_count; | |
422 | ||
423 | /* Discard remaining data in video pipe */ | |
424 | junk = kmalloc(junk_len, GFP_KERNEL); | |
425 | if (!junk) | |
426 | return; | |
427 | while (1) { | |
428 | if (usb_bulk_msg(d->udev, | |
429 | usb_rcvbulkpipe(d->udev, p->endpoint), | |
430 | junk, junk_len, &rd_count, timeout) < 0) | |
431 | break; | |
432 | if (!rd_count) | |
433 | break; | |
434 | } | |
435 | kfree(junk); | |
436 | } | |
437 | ||
438 | static int cxusb_d680_dmb_streaming_ctrl( | |
439 | struct dvb_usb_adapter *adap, int onoff) | |
440 | { | |
441 | if (onoff) { | |
442 | u8 buf[2] = { 0x03, 0x00 }; | |
443 | cxusb_d680_dmb_drain_video(adap->dev); | |
444 | return cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON, | |
445 | buf, sizeof(buf), NULL, 0); | |
446 | } else { | |
447 | int ret = cxusb_ctrl_msg(adap->dev, | |
448 | CMD_STREAMING_OFF, NULL, 0, NULL, 0); | |
449 | return ret; | |
450 | } | |
451 | } | |
452 | ||
517b5007 | 453 | static int cxusb_rc_query(struct dvb_usb_device *d) |
7c239703 | 454 | { |
a07e6096 | 455 | u8 ircode[4]; |
7c239703 | 456 | |
a07e6096 | 457 | cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4); |
7c239703 | 458 | |
517b5007 | 459 | if (ircode[2] || ircode[3]) |
6d741bfe | 460 | rc_keydown(d->rc_dev, RC_PROTO_NEC, |
207c957d | 461 | RC_SCANCODE_NEC(~ircode[2] & 0xff, ircode[3]), 0); |
7c239703 CP |
462 | return 0; |
463 | } | |
464 | ||
517b5007 | 465 | static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d) |
aeb012bb | 466 | { |
aeb012bb | 467 | u8 ircode[4]; |
aeb012bb CP |
468 | struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD, |
469 | .buf = ircode, .len = 4 }; | |
470 | ||
aeb012bb CP |
471 | if (cxusb_i2c_xfer(&d->i2c_adap, &msg, 1) != 1) |
472 | return 0; | |
473 | ||
517b5007 | 474 | if (ircode[1] || ircode[2]) |
6d741bfe | 475 | rc_keydown(d->rc_dev, RC_PROTO_NEC, |
207c957d | 476 | RC_SCANCODE_NEC(~ircode[1] & 0xff, ircode[2]), 0); |
aeb012bb CP |
477 | return 0; |
478 | } | |
479 | ||
517b5007 | 480 | static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d) |
dfbdce04 | 481 | { |
dfbdce04 | 482 | u8 ircode[2]; |
dfbdce04 TL |
483 | |
484 | if (cxusb_ctrl_msg(d, 0x10, NULL, 0, ircode, 2) < 0) | |
485 | return 0; | |
486 | ||
517b5007 | 487 | if (ircode[0] || ircode[1]) |
6d741bfe | 488 | rc_keydown(d->rc_dev, RC_PROTO_UNKNOWN, |
517b5007 | 489 | RC_SCANCODE_RC5(ircode[0], ircode[1]), 0); |
dfbdce04 TL |
490 | return 0; |
491 | } | |
492 | ||
0029ee14 CP |
493 | static int cxusb_dee1601_demod_init(struct dvb_frontend* fe) |
494 | { | |
d9ed881c | 495 | static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 }; |
0029ee14 CP |
496 | static u8 reset [] = { RESET, 0x80 }; |
497 | static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; | |
498 | static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 }; | |
499 | static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 }; | |
500 | static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; | |
501 | ||
502 | mt352_write(fe, clock_config, sizeof(clock_config)); | |
503 | udelay(200); | |
504 | mt352_write(fe, reset, sizeof(reset)); | |
505 | mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); | |
506 | ||
507 | mt352_write(fe, agc_cfg, sizeof(agc_cfg)); | |
508 | mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg)); | |
509 | mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); | |
510 | ||
511 | return 0; | |
512 | } | |
513 | ||
6f447259 MK |
514 | static int cxusb_mt352_demod_init(struct dvb_frontend* fe) |
515 | { /* used in both lgz201 and th7579 */ | |
fb51fd2d | 516 | static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x29 }; |
6f447259 MK |
517 | static u8 reset [] = { RESET, 0x80 }; |
518 | static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; | |
519 | static u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 }; | |
520 | static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 }; | |
521 | static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; | |
522 | ||
523 | mt352_write(fe, clock_config, sizeof(clock_config)); | |
524 | udelay(200); | |
525 | mt352_write(fe, reset, sizeof(reset)); | |
526 | mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); | |
527 | ||
528 | mt352_write(fe, agc_cfg, sizeof(agc_cfg)); | |
529 | mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg)); | |
530 | mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); | |
531 | return 0; | |
532 | } | |
533 | ||
703cb2cb | 534 | static struct cx22702_config cxusb_cx22702_config = { |
22c6d93a | 535 | .demod_address = 0x63, |
8257e8a4 | 536 | .output_mode = CX22702_PARALLEL_OUTPUT, |
22c6d93a PB |
537 | }; |
538 | ||
fddd632a | 539 | static struct lgdt330x_config cxusb_lgdt3303_config = { |
effee033 | 540 | .demod_chip = LGDT3303, |
effee033 MK |
541 | }; |
542 | ||
f5376ada | 543 | static struct lgdt330x_config cxusb_aver_lgdt3303_config = { |
f5376ada DG |
544 | .demod_chip = LGDT3303, |
545 | .clock_polarity_flip = 2, | |
546 | }; | |
547 | ||
703cb2cb | 548 | static struct mt352_config cxusb_dee1601_config = { |
0029ee14 CP |
549 | .demod_address = 0x0f, |
550 | .demod_init = cxusb_dee1601_demod_init, | |
0029ee14 CP |
551 | }; |
552 | ||
c9ce3940 MK |
553 | static struct zl10353_config cxusb_zl10353_dee1601_config = { |
554 | .demod_address = 0x0f, | |
8fb95784 | 555 | .parallel_ts = 1, |
c9ce3940 MK |
556 | }; |
557 | ||
6fe00b0e | 558 | static struct mt352_config cxusb_mt352_config = { |
6f447259 MK |
559 | /* used in both lgz201 and th7579 */ |
560 | .demod_address = 0x0f, | |
561 | .demod_init = cxusb_mt352_demod_init, | |
6f447259 MK |
562 | }; |
563 | ||
aeb012bb CP |
564 | static struct zl10353_config cxusb_zl10353_xc3028_config = { |
565 | .demod_address = 0x0f, | |
a1dcd9de | 566 | .if2 = 45600, |
aeb012bb CP |
567 | .no_tuner = 1, |
568 | .parallel_ts = 1, | |
569 | }; | |
570 | ||
0bc35180 RL |
571 | static struct zl10353_config cxusb_zl10353_xc3028_config_no_i2c_gate = { |
572 | .demod_address = 0x0f, | |
573 | .if2 = 45600, | |
574 | .no_tuner = 1, | |
575 | .parallel_ts = 1, | |
576 | .disable_i2c_gate_ctrl = 1, | |
577 | }; | |
578 | ||
702a6762 CP |
579 | static struct mt352_config cxusb_mt352_xc3028_config = { |
580 | .demod_address = 0x0f, | |
581 | .if2 = 4560, | |
582 | .no_tuner = 1, | |
583 | .demod_init = cxusb_mt352_demod_init, | |
584 | }; | |
585 | ||
f5376ada DG |
586 | /* FIXME: needs tweaking */ |
587 | static struct mxl5005s_config aver_a868r_tuner = { | |
588 | .i2c_address = 0x63, | |
589 | .if_freq = 6000000UL, | |
590 | .xtal_freq = CRYSTAL_FREQ_16000000HZ, | |
591 | .agc_mode = MXL_SINGLE_AGC, | |
592 | .tracking_filter = MXL_TF_C, | |
593 | .rssi_enable = MXL_RSSI_ENABLE, | |
594 | .cap_select = MXL_CAP_SEL_ENABLE, | |
595 | .div_out = MXL_DIV_OUT_4, | |
596 | .clock_out = MXL_CLOCK_OUT_DISABLE, | |
597 | .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM, | |
598 | .top = MXL5005S_TOP_25P2, | |
599 | .mod_mode = MXL_DIGITAL_MODE, | |
600 | .if_mode = MXL_ZERO_IF, | |
601 | .AgcMasterByte = 0x00, | |
602 | }; | |
603 | ||
dfbdce04 TL |
604 | /* FIXME: needs tweaking */ |
605 | static struct mxl5005s_config d680_dmb_tuner = { | |
606 | .i2c_address = 0x63, | |
607 | .if_freq = 36125000UL, | |
608 | .xtal_freq = CRYSTAL_FREQ_16000000HZ, | |
609 | .agc_mode = MXL_SINGLE_AGC, | |
610 | .tracking_filter = MXL_TF_C, | |
611 | .rssi_enable = MXL_RSSI_ENABLE, | |
612 | .cap_select = MXL_CAP_SEL_ENABLE, | |
613 | .div_out = MXL_DIV_OUT_4, | |
614 | .clock_out = MXL_CLOCK_OUT_DISABLE, | |
615 | .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM, | |
616 | .top = MXL5005S_TOP_25P2, | |
617 | .mod_mode = MXL_DIGITAL_MODE, | |
618 | .if_mode = MXL_ZERO_IF, | |
619 | .AgcMasterByte = 0x00, | |
620 | }; | |
621 | ||
b18bd1d8 DW |
622 | static struct max2165_config mygica_d689_max2165_cfg = { |
623 | .i2c_address = 0x60, | |
624 | .osc_clk = 20 | |
625 | }; | |
626 | ||
22c6d93a | 627 | /* Callbacks for DVB USB */ |
4d43e13f | 628 | static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap) |
22c6d93a | 629 | { |
77eed219 | 630 | dvb_attach(simple_tuner_attach, adap->fe_adap[0].fe, |
cb89cd33 MK |
631 | &adap->dev->i2c_adap, 0x61, |
632 | TUNER_PHILIPS_FMD1216ME_MK3); | |
22c6d93a PB |
633 | return 0; |
634 | } | |
635 | ||
4d43e13f | 636 | static int cxusb_dee1601_tuner_attach(struct dvb_usb_adapter *adap) |
0029ee14 | 637 | { |
77eed219 | 638 | dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61, |
47a9991e | 639 | NULL, DVB_PLL_THOMSON_DTT7579); |
0029ee14 CP |
640 | return 0; |
641 | } | |
642 | ||
4d43e13f | 643 | static int cxusb_lgz201_tuner_attach(struct dvb_usb_adapter *adap) |
6f447259 | 644 | { |
77eed219 | 645 | dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61, NULL, DVB_PLL_LG_Z201); |
6f447259 MK |
646 | return 0; |
647 | } | |
648 | ||
4d43e13f | 649 | static int cxusb_dtt7579_tuner_attach(struct dvb_usb_adapter *adap) |
6f447259 | 650 | { |
77eed219 | 651 | dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, |
47a9991e | 652 | NULL, DVB_PLL_THOMSON_DTT7579); |
332bed5f PB |
653 | return 0; |
654 | } | |
655 | ||
f71a56c1 | 656 | static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap) |
332bed5f | 657 | { |
77eed219 | 658 | dvb_attach(simple_tuner_attach, adap->fe_adap[0].fe, |
827855d3 | 659 | &adap->dev->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF); |
6f447259 MK |
660 | return 0; |
661 | } | |
662 | ||
d7cba043 MK |
663 | static int dvico_bluebird_xc2028_callback(void *ptr, int component, |
664 | int command, int arg) | |
aeb012bb | 665 | { |
d483b730 RL |
666 | struct dvb_usb_adapter *adap = ptr; |
667 | struct dvb_usb_device *d = adap->dev; | |
aeb012bb CP |
668 | |
669 | switch (command) { | |
670 | case XC2028_TUNER_RESET: | |
708bebdd | 671 | deb_info("%s: XC2028_TUNER_RESET %d\n", __func__, arg); |
aeb012bb CP |
672 | cxusb_bluebird_gpio_pulse(d, 0x01, 1); |
673 | break; | |
674 | case XC2028_RESET_CLK: | |
708bebdd | 675 | deb_info("%s: XC2028_RESET_CLK %d\n", __func__, arg); |
aeb012bb | 676 | break; |
9893b905 MCC |
677 | case XC2028_I2C_FLUSH: |
678 | break; | |
aeb012bb | 679 | default: |
708bebdd | 680 | deb_info("%s: unknown command %d, arg %d\n", __func__, |
aeb012bb CP |
681 | command, arg); |
682 | return -EINVAL; | |
683 | } | |
684 | ||
685 | return 0; | |
686 | } | |
687 | ||
688 | static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap) | |
689 | { | |
690 | struct dvb_frontend *fe; | |
691 | struct xc2028_config cfg = { | |
692 | .i2c_adap = &adap->dev->i2c_adap, | |
693 | .i2c_addr = 0x61, | |
aeb012bb CP |
694 | }; |
695 | static struct xc2028_ctrl ctl = { | |
ef80bfeb | 696 | .fname = XC2028_DEFAULT_FIRMWARE, |
aeb012bb | 697 | .max_len = 64, |
d483b730 | 698 | .demod = XC3028_FE_ZARLINK456, |
aeb012bb CP |
699 | }; |
700 | ||
d7cba043 | 701 | /* FIXME: generalize & move to common area */ |
77eed219 | 702 | adap->fe_adap[0].fe->callback = dvico_bluebird_xc2028_callback; |
d7cba043 | 703 | |
77eed219 | 704 | fe = dvb_attach(xc2028_attach, adap->fe_adap[0].fe, &cfg); |
aeb012bb CP |
705 | if (fe == NULL || fe->ops.tuner_ops.set_config == NULL) |
706 | return -EIO; | |
707 | ||
708 | fe->ops.tuner_ops.set_config(fe, &ctl); | |
709 | ||
710 | return 0; | |
711 | } | |
712 | ||
f5376ada DG |
713 | static int cxusb_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap) |
714 | { | |
77eed219 | 715 | dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe, |
f5376ada DG |
716 | &adap->dev->i2c_adap, &aver_a868r_tuner); |
717 | return 0; | |
718 | } | |
719 | ||
dfbdce04 TL |
720 | static int cxusb_d680_dmb_tuner_attach(struct dvb_usb_adapter *adap) |
721 | { | |
722 | struct dvb_frontend *fe; | |
77eed219 | 723 | fe = dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe, |
dfbdce04 TL |
724 | &adap->dev->i2c_adap, &d680_dmb_tuner); |
725 | return (fe == NULL) ? -EIO : 0; | |
726 | } | |
727 | ||
b18bd1d8 DW |
728 | static int cxusb_mygica_d689_tuner_attach(struct dvb_usb_adapter *adap) |
729 | { | |
730 | struct dvb_frontend *fe; | |
77eed219 | 731 | fe = dvb_attach(max2165_attach, adap->fe_adap[0].fe, |
b18bd1d8 DW |
732 | &adap->dev->i2c_adap, &mygica_d689_max2165_cfg); |
733 | return (fe == NULL) ? -EIO : 0; | |
734 | } | |
735 | ||
4d43e13f | 736 | static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap) |
22c6d93a | 737 | { |
e2efeab2 | 738 | u8 b; |
4d43e13f | 739 | if (usb_set_interface(adap->dev->udev, 0, 6) < 0) |
8257e8a4 | 740 | err("set interface failed"); |
22c6d93a | 741 | |
4d43e13f | 742 | cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, &b, 1); |
22c6d93a | 743 | |
310df366 MK |
744 | adap->fe_adap[0].fe = dvb_attach(cx22702_attach, &cxusb_cx22702_config, |
745 | &adap->dev->i2c_adap); | |
746 | if ((adap->fe_adap[0].fe) != NULL) | |
22c6d93a PB |
747 | return 0; |
748 | ||
749 | return -EIO; | |
750 | } | |
751 | ||
4d43e13f | 752 | static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap) |
effee033 | 753 | { |
4d43e13f | 754 | if (usb_set_interface(adap->dev->udev, 0, 7) < 0) |
effee033 MK |
755 | err("set interface failed"); |
756 | ||
4d43e13f | 757 | cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0); |
effee033 | 758 | |
310df366 MK |
759 | adap->fe_adap[0].fe = dvb_attach(lgdt330x_attach, |
760 | &cxusb_lgdt3303_config, | |
23ba635d | 761 | 0x0e, |
310df366 MK |
762 | &adap->dev->i2c_adap); |
763 | if ((adap->fe_adap[0].fe) != NULL) | |
effee033 MK |
764 | return 0; |
765 | ||
766 | return -EIO; | |
767 | } | |
768 | ||
f5376ada DG |
769 | static int cxusb_aver_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap) |
770 | { | |
23ba635d MCC |
771 | adap->fe_adap[0].fe = dvb_attach(lgdt330x_attach, |
772 | &cxusb_aver_lgdt3303_config, | |
773 | 0x0e, | |
774 | &adap->dev->i2c_adap); | |
77eed219 | 775 | if (adap->fe_adap[0].fe != NULL) |
f5376ada DG |
776 | return 0; |
777 | ||
778 | return -EIO; | |
779 | } | |
780 | ||
4d43e13f PB |
781 | static int cxusb_mt352_frontend_attach(struct dvb_usb_adapter *adap) |
782 | { | |
783 | /* used in both lgz201 and th7579 */ | |
784 | if (usb_set_interface(adap->dev->udev, 0, 0) < 0) | |
6f447259 MK |
785 | err("set interface failed"); |
786 | ||
4d43e13f | 787 | cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0); |
6f447259 | 788 | |
310df366 MK |
789 | adap->fe_adap[0].fe = dvb_attach(mt352_attach, &cxusb_mt352_config, |
790 | &adap->dev->i2c_adap); | |
791 | if ((adap->fe_adap[0].fe) != NULL) | |
6f447259 MK |
792 | return 0; |
793 | ||
794 | return -EIO; | |
795 | } | |
796 | ||
4d43e13f | 797 | static int cxusb_dee1601_frontend_attach(struct dvb_usb_adapter *adap) |
0029ee14 | 798 | { |
4d43e13f | 799 | if (usb_set_interface(adap->dev->udev, 0, 0) < 0) |
0029ee14 CP |
800 | err("set interface failed"); |
801 | ||
4d43e13f | 802 | cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0); |
0029ee14 | 803 | |
310df366 MK |
804 | adap->fe_adap[0].fe = dvb_attach(mt352_attach, &cxusb_dee1601_config, |
805 | &adap->dev->i2c_adap); | |
806 | if ((adap->fe_adap[0].fe) != NULL) | |
807 | return 0; | |
808 | ||
809 | adap->fe_adap[0].fe = dvb_attach(zl10353_attach, | |
810 | &cxusb_zl10353_dee1601_config, | |
811 | &adap->dev->i2c_adap); | |
812 | if ((adap->fe_adap[0].fe) != NULL) | |
0029ee14 CP |
813 | return 0; |
814 | ||
815 | return -EIO; | |
816 | } | |
817 | ||
aeb012bb CP |
818 | static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap) |
819 | { | |
820 | u8 ircode[4]; | |
821 | int i; | |
822 | struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD, | |
823 | .buf = ircode, .len = 4 }; | |
824 | ||
825 | if (usb_set_interface(adap->dev->udev, 0, 1) < 0) | |
826 | err("set interface failed"); | |
827 | ||
828 | cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0); | |
829 | ||
830 | /* reset the tuner and demodulator */ | |
831 | cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0); | |
832 | cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1); | |
833 | cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1); | |
834 | ||
310df366 MK |
835 | adap->fe_adap[0].fe = |
836 | dvb_attach(zl10353_attach, | |
837 | &cxusb_zl10353_xc3028_config_no_i2c_gate, | |
838 | &adap->dev->i2c_adap); | |
839 | if ((adap->fe_adap[0].fe) == NULL) | |
aeb012bb CP |
840 | return -EIO; |
841 | ||
842 | /* try to determine if there is no IR decoder on the I2C bus */ | |
517b5007 | 843 | for (i = 0; adap->dev->props.rc.core.rc_codes && i < 5; i++) { |
aeb012bb CP |
844 | msleep(20); |
845 | if (cxusb_i2c_xfer(&adap->dev->i2c_adap, &msg, 1) != 1) | |
846 | goto no_IR; | |
847 | if (ircode[0] == 0 && ircode[1] == 0) | |
848 | continue; | |
849 | if (ircode[2] + ircode[3] != 0xff) { | |
850 | no_IR: | |
517b5007 | 851 | adap->dev->props.rc.core.rc_codes = NULL; |
aeb012bb CP |
852 | info("No IR receiver detected on this device."); |
853 | break; | |
854 | } | |
855 | } | |
856 | ||
857 | return 0; | |
858 | } | |
859 | ||
8d798988 AB |
860 | static struct dibx000_agc_config dib7070_agc_config = { |
861 | .band_caps = BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, | |
862 | ||
863 | /* | |
864 | * P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, | |
865 | * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, | |
866 | * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 | |
867 | */ | |
868 | .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | | |
869 | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), | |
870 | .inv_gain = 600, | |
871 | .time_stabiliz = 10, | |
872 | .alpha_level = 0, | |
873 | .thlock = 118, | |
874 | .wbd_inv = 0, | |
875 | .wbd_ref = 3530, | |
876 | .wbd_sel = 1, | |
877 | .wbd_alpha = 5, | |
878 | .agc1_max = 65535, | |
879 | .agc1_min = 0, | |
880 | .agc2_max = 65535, | |
881 | .agc2_min = 0, | |
882 | .agc1_pt1 = 0, | |
883 | .agc1_pt2 = 40, | |
884 | .agc1_pt3 = 183, | |
885 | .agc1_slope1 = 206, | |
886 | .agc1_slope2 = 255, | |
887 | .agc2_pt1 = 72, | |
888 | .agc2_pt2 = 152, | |
889 | .agc2_slope1 = 88, | |
890 | .agc2_slope2 = 90, | |
891 | .alpha_mant = 17, | |
892 | .alpha_exp = 27, | |
893 | .beta_mant = 23, | |
894 | .beta_exp = 51, | |
895 | .perform_agc_softsplit = 0, | |
896 | }; | |
897 | ||
898 | static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = { | |
899 | .internal = 60000, | |
900 | .sampling = 15000, | |
901 | .pll_prediv = 1, | |
902 | .pll_ratio = 20, | |
903 | .pll_range = 3, | |
904 | .pll_reset = 1, | |
905 | .pll_bypass = 0, | |
906 | .enable_refdiv = 0, | |
907 | .bypclk_div = 0, | |
908 | .IO_CLK_en_core = 1, | |
909 | .ADClkSrc = 1, | |
910 | .modulo = 2, | |
911 | /* refsel, sel, freq_15k */ | |
912 | .sad_cfg = (3 << 14) | (1 << 12) | (524 << 0), | |
913 | .ifreq = (0 << 25) | 0, | |
914 | .timf = 20452225, | |
915 | .xtal_hz = 12000000, | |
916 | }; | |
917 | ||
918 | static struct dib7000p_config cxusb_dualdig4_rev2_config = { | |
919 | .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK, | |
920 | .output_mpeg2_in_188_bytes = 1, | |
921 | ||
922 | .agc_config_count = 1, | |
923 | .agc = &dib7070_agc_config, | |
924 | .bw = &dib7070_bw_config_12_mhz, | |
925 | .tuner_is_baseband = 1, | |
926 | .spur_protect = 1, | |
927 | ||
928 | .gpio_dir = 0xfcef, | |
929 | .gpio_val = 0x0110, | |
930 | ||
931 | .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, | |
932 | ||
933 | .hostbus_diversity = 1, | |
934 | }; | |
935 | ||
8abe4a0a MCC |
936 | struct dib0700_adapter_state { |
937 | int (*set_param_save)(struct dvb_frontend *); | |
938 | struct dib7000p_ops dib7000p_ops; | |
939 | }; | |
940 | ||
8d798988 AB |
941 | static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap) |
942 | { | |
8abe4a0a MCC |
943 | struct dib0700_adapter_state *state = adap->priv; |
944 | ||
8d798988 AB |
945 | if (usb_set_interface(adap->dev->udev, 0, 1) < 0) |
946 | err("set interface failed"); | |
947 | ||
948 | cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0); | |
949 | ||
950 | cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1); | |
951 | ||
8abe4a0a MCC |
952 | if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops)) |
953 | return -ENODEV; | |
954 | ||
955 | if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18, | |
956 | &cxusb_dualdig4_rev2_config) < 0) { | |
a49ba167 | 957 | printk(KERN_WARNING "Unable to enumerate dib7000p\n"); |
30d81bb0 | 958 | return -ENODEV; |
a49ba167 | 959 | } |
8d798988 | 960 | |
8abe4a0a MCC |
961 | adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80, |
962 | &cxusb_dualdig4_rev2_config); | |
77eed219 | 963 | if (adap->fe_adap[0].fe == NULL) |
8d798988 AB |
964 | return -EIO; |
965 | ||
966 | return 0; | |
967 | } | |
968 | ||
969 | static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff) | |
970 | { | |
8abe4a0a MCC |
971 | struct dvb_usb_adapter *adap = fe->dvb->priv; |
972 | struct dib0700_adapter_state *state = adap->priv; | |
973 | ||
974 | return state->dib7000p_ops.set_gpio(fe, 8, 0, !onoff); | |
8d798988 AB |
975 | } |
976 | ||
977 | static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff) | |
978 | { | |
979 | return 0; | |
980 | } | |
981 | ||
982 | static struct dib0070_config dib7070p_dib0070_config = { | |
983 | .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS, | |
984 | .reset = dib7070_tuner_reset, | |
985 | .sleep = dib7070_tuner_sleep, | |
986 | .clock_khz = 12000, | |
987 | }; | |
988 | ||
14d24d14 | 989 | static int dib7070_set_param_override(struct dvb_frontend *fe) |
8d798988 | 990 | { |
afd2b38a | 991 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; |
8d798988 AB |
992 | struct dvb_usb_adapter *adap = fe->dvb->priv; |
993 | struct dib0700_adapter_state *state = adap->priv; | |
994 | ||
995 | u16 offset; | |
afd2b38a | 996 | u8 band = BAND_OF_FREQUENCY(p->frequency/1000); |
8d798988 | 997 | switch (band) { |
a2dc86b6 MK |
998 | case BAND_VHF: offset = 950; break; |
999 | default: | |
1000 | case BAND_UHF: offset = 550; break; | |
8d798988 AB |
1001 | } |
1002 | ||
8abe4a0a | 1003 | state->dib7000p_ops.set_wbd_ref(fe, offset + dib0070_wbd_offset(fe)); |
8d798988 | 1004 | |
14d24d14 | 1005 | return state->set_param_save(fe); |
8d798988 AB |
1006 | } |
1007 | ||
1008 | static int cxusb_dualdig4_rev2_tuner_attach(struct dvb_usb_adapter *adap) | |
1009 | { | |
1010 | struct dib0700_adapter_state *st = adap->priv; | |
8abe4a0a MCC |
1011 | struct i2c_adapter *tun_i2c; |
1012 | ||
1013 | /* | |
1014 | * No need to call dvb7000p_attach here, as it was called | |
1015 | * already, as frontend_attach method is called first, and | |
3e4d8f48 | 1016 | * tuner_attach is only called on success. |
8abe4a0a MCC |
1017 | */ |
1018 | tun_i2c = st->dib7000p_ops.get_i2c_master(adap->fe_adap[0].fe, | |
a2dc86b6 | 1019 | DIBX000_I2C_INTERFACE_TUNER, 1); |
8d798988 | 1020 | |
77eed219 | 1021 | if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, |
8d798988 AB |
1022 | &dib7070p_dib0070_config) == NULL) |
1023 | return -ENODEV; | |
1024 | ||
77eed219 MK |
1025 | st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; |
1026 | adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7070_set_param_override; | |
8d798988 AB |
1027 | return 0; |
1028 | } | |
1029 | ||
5ccaf905 CP |
1030 | static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap) |
1031 | { | |
1032 | if (usb_set_interface(adap->dev->udev, 0, 1) < 0) | |
1033 | err("set interface failed"); | |
1034 | ||
1035 | cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0); | |
1036 | ||
1037 | /* reset the tuner and demodulator */ | |
1038 | cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0); | |
1039 | cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1); | |
1040 | cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1); | |
1041 | ||
310df366 MK |
1042 | adap->fe_adap[0].fe = dvb_attach(zl10353_attach, |
1043 | &cxusb_zl10353_xc3028_config, | |
1044 | &adap->dev->i2c_adap); | |
1045 | if ((adap->fe_adap[0].fe) != NULL) | |
5ccaf905 CP |
1046 | return 0; |
1047 | ||
310df366 MK |
1048 | adap->fe_adap[0].fe = dvb_attach(mt352_attach, |
1049 | &cxusb_mt352_xc3028_config, | |
1050 | &adap->dev->i2c_adap); | |
1051 | if ((adap->fe_adap[0].fe) != NULL) | |
702a6762 CP |
1052 | return 0; |
1053 | ||
5ccaf905 CP |
1054 | return -EIO; |
1055 | } | |
1056 | ||
6bf1a997 DW |
1057 | static struct lgs8gxx_config d680_lgs8gl5_cfg = { |
1058 | .prod = LGS8GXX_PROD_LGS8GL5, | |
dfbdce04 | 1059 | .demod_address = 0x19, |
6bf1a997 DW |
1060 | .serial_ts = 0, |
1061 | .ts_clk_pol = 0, | |
1062 | .ts_clk_gated = 1, | |
1063 | .if_clk_freq = 30400, /* 30.4 MHz */ | |
1064 | .if_freq = 5725, /* 5.725 MHz */ | |
1065 | .if_neg_center = 0, | |
1066 | .ext_adc = 0, | |
1067 | .adc_signed = 0, | |
1068 | .if_neg_edge = 0, | |
dfbdce04 TL |
1069 | }; |
1070 | ||
1071 | static int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap) | |
1072 | { | |
1073 | struct dvb_usb_device *d = adap->dev; | |
1074 | int n; | |
1075 | ||
1076 | /* Select required USB configuration */ | |
1077 | if (usb_set_interface(d->udev, 0, 0) < 0) | |
1078 | err("set interface failed"); | |
1079 | ||
1080 | /* Unblock all USB pipes */ | |
1081 | usb_clear_halt(d->udev, | |
1082 | usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); | |
1083 | usb_clear_halt(d->udev, | |
1084 | usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); | |
1085 | usb_clear_halt(d->udev, | |
77eed219 | 1086 | usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint)); |
dfbdce04 TL |
1087 | |
1088 | /* Drain USB pipes to avoid hang after reboot */ | |
1089 | for (n = 0; n < 5; n++) { | |
1090 | cxusb_d680_dmb_drain_message(d); | |
1091 | cxusb_d680_dmb_drain_video(d); | |
1092 | msleep(200); | |
1093 | } | |
1094 | ||
1095 | /* Reset the tuner */ | |
1096 | if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) { | |
1097 | err("clear tuner gpio failed"); | |
1098 | return -EIO; | |
1099 | } | |
1100 | msleep(100); | |
1101 | if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) { | |
1102 | err("set tuner gpio failed"); | |
1103 | return -EIO; | |
1104 | } | |
1105 | msleep(100); | |
1106 | ||
1107 | /* Attach frontend */ | |
77eed219 MK |
1108 | adap->fe_adap[0].fe = dvb_attach(lgs8gxx_attach, &d680_lgs8gl5_cfg, &d->i2c_adap); |
1109 | if (adap->fe_adap[0].fe == NULL) | |
dfbdce04 TL |
1110 | return -EIO; |
1111 | ||
1112 | return 0; | |
1113 | } | |
1114 | ||
b18bd1d8 DW |
1115 | static struct atbm8830_config mygica_d689_atbm8830_cfg = { |
1116 | .prod = ATBM8830_PROD_8830, | |
1117 | .demod_address = 0x40, | |
1118 | .serial_ts = 0, | |
1119 | .ts_sampling_edge = 1, | |
1120 | .ts_clk_gated = 0, | |
1121 | .osc_clk_freq = 30400, /* in kHz */ | |
1122 | .if_freq = 0, /* zero IF */ | |
1123 | .zif_swap_iq = 1, | |
c245c75c DW |
1124 | .agc_min = 0x2E, |
1125 | .agc_max = 0x90, | |
1126 | .agc_hold_loop = 0, | |
b18bd1d8 DW |
1127 | }; |
1128 | ||
1129 | static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap) | |
1130 | { | |
1131 | struct dvb_usb_device *d = adap->dev; | |
b18bd1d8 DW |
1132 | |
1133 | /* Select required USB configuration */ | |
1134 | if (usb_set_interface(d->udev, 0, 0) < 0) | |
1135 | err("set interface failed"); | |
1136 | ||
1137 | /* Unblock all USB pipes */ | |
1138 | usb_clear_halt(d->udev, | |
1139 | usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); | |
1140 | usb_clear_halt(d->udev, | |
1141 | usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); | |
1142 | usb_clear_halt(d->udev, | |
77eed219 | 1143 | usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint)); |
b18bd1d8 DW |
1144 | |
1145 | ||
1146 | /* Reset the tuner */ | |
1147 | if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) { | |
1148 | err("clear tuner gpio failed"); | |
1149 | return -EIO; | |
1150 | } | |
1151 | msleep(100); | |
1152 | if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) { | |
1153 | err("set tuner gpio failed"); | |
1154 | return -EIO; | |
1155 | } | |
1156 | msleep(100); | |
1157 | ||
1158 | /* Attach frontend */ | |
77eed219 | 1159 | adap->fe_adap[0].fe = dvb_attach(atbm8830_attach, &mygica_d689_atbm8830_cfg, |
b18bd1d8 | 1160 | &d->i2c_adap); |
77eed219 | 1161 | if (adap->fe_adap[0].fe == NULL) |
b18bd1d8 DW |
1162 | return -EIO; |
1163 | ||
1164 | return 0; | |
1165 | } | |
1166 | ||
a0f629b9 C |
1167 | static int cxusb_mygica_t230_frontend_attach(struct dvb_usb_adapter *adap) |
1168 | { | |
1169 | struct dvb_usb_device *d = adap->dev; | |
1170 | struct cxusb_state *st = d->priv; | |
1171 | struct i2c_adapter *adapter; | |
1172 | struct i2c_client *client_demod; | |
1173 | struct i2c_client *client_tuner; | |
1174 | struct i2c_board_info info; | |
1175 | struct si2168_config si2168_config; | |
1176 | struct si2157_config si2157_config; | |
1177 | ||
1178 | /* Select required USB configuration */ | |
1179 | if (usb_set_interface(d->udev, 0, 0) < 0) | |
1180 | err("set interface failed"); | |
1181 | ||
1182 | /* Unblock all USB pipes */ | |
1183 | usb_clear_halt(d->udev, | |
1184 | usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); | |
1185 | usb_clear_halt(d->udev, | |
1186 | usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); | |
1187 | usb_clear_halt(d->udev, | |
1188 | usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint)); | |
1189 | ||
1190 | /* attach frontend */ | |
1191 | si2168_config.i2c_adapter = &adapter; | |
1192 | si2168_config.fe = &adap->fe_adap[0].fe; | |
1193 | si2168_config.ts_mode = SI2168_TS_PARALLEL; | |
1194 | si2168_config.ts_clock_inv = 1; | |
1195 | memset(&info, 0, sizeof(struct i2c_board_info)); | |
c0decac1 | 1196 | strscpy(info.type, "si2168", I2C_NAME_SIZE); |
a0f629b9 C |
1197 | info.addr = 0x64; |
1198 | info.platform_data = &si2168_config; | |
1199 | request_module(info.type); | |
1200 | client_demod = i2c_new_device(&d->i2c_adap, &info); | |
1201 | if (client_demod == NULL || client_demod->dev.driver == NULL) | |
1202 | return -ENODEV; | |
1203 | ||
1204 | if (!try_module_get(client_demod->dev.driver->owner)) { | |
1205 | i2c_unregister_device(client_demod); | |
1206 | return -ENODEV; | |
1207 | } | |
1208 | ||
1209 | st->i2c_client_demod = client_demod; | |
1210 | ||
1211 | /* attach tuner */ | |
1212 | memset(&si2157_config, 0, sizeof(si2157_config)); | |
1213 | si2157_config.fe = adap->fe_adap[0].fe; | |
ee3c3e46 | 1214 | si2157_config.if_port = 1; |
a0f629b9 | 1215 | memset(&info, 0, sizeof(struct i2c_board_info)); |
c0decac1 | 1216 | strscpy(info.type, "si2157", I2C_NAME_SIZE); |
a0f629b9 C |
1217 | info.addr = 0x60; |
1218 | info.platform_data = &si2157_config; | |
1219 | request_module(info.type); | |
1220 | client_tuner = i2c_new_device(adapter, &info); | |
1221 | if (client_tuner == NULL || client_tuner->dev.driver == NULL) { | |
1222 | module_put(client_demod->dev.driver->owner); | |
1223 | i2c_unregister_device(client_demod); | |
1224 | return -ENODEV; | |
1225 | } | |
1226 | if (!try_module_get(client_tuner->dev.driver->owner)) { | |
1227 | i2c_unregister_device(client_tuner); | |
1228 | module_put(client_demod->dev.driver->owner); | |
1229 | i2c_unregister_device(client_demod); | |
1230 | return -ENODEV; | |
1231 | } | |
1232 | ||
1233 | st->i2c_client_tuner = client_tuner; | |
1234 | ||
5fa88151 C |
1235 | /* hook fe: need to resync the slave fifo when signal locks. */ |
1236 | mutex_init(&st->stream_mutex); | |
1237 | st->last_lock = 0; | |
1238 | st->fe_read_status = adap->fe_adap[0].fe->ops.read_status; | |
1239 | adap->fe_adap[0].fe->ops.read_status = cxusb_read_status; | |
1240 | ||
a0f629b9 C |
1241 | return 0; |
1242 | } | |
1243 | ||
702a6762 CP |
1244 | /* |
1245 | * DViCO has shipped two devices with the same USB ID, but only one of them | |
1246 | * needs a firmware download. Check the device class details to see if they | |
1247 | * have non-default values to decide whether the device is actually cold or | |
1248 | * not, and forget a match if it turns out we selected the wrong device. | |
1249 | */ | |
1250 | static int bluebird_fx2_identify_state(struct usb_device *udev, | |
1251 | struct dvb_usb_device_properties *props, | |
1252 | struct dvb_usb_device_description **desc, | |
1253 | int *cold) | |
1254 | { | |
1255 | int wascold = *cold; | |
1256 | ||
1257 | *cold = udev->descriptor.bDeviceClass == 0xff && | |
1258 | udev->descriptor.bDeviceSubClass == 0xff && | |
1259 | udev->descriptor.bDeviceProtocol == 0xff; | |
1260 | ||
1261 | if (*cold && !wascold) | |
1262 | *desc = NULL; | |
1263 | ||
1264 | return 0; | |
1265 | } | |
1266 | ||
f5373788 PB |
1267 | /* |
1268 | * DViCO bluebird firmware needs the "warm" product ID to be patched into the | |
1269 | * firmware file before download. | |
1270 | */ | |
1271 | ||
702a6762 | 1272 | static const int dvico_firmware_id_offsets[] = { 6638, 3204 }; |
f35db23c MK |
1273 | static int bluebird_patch_dvico_firmware_download(struct usb_device *udev, |
1274 | const struct firmware *fw) | |
f5373788 | 1275 | { |
702a6762 CP |
1276 | int pos; |
1277 | ||
1278 | for (pos = 0; pos < ARRAY_SIZE(dvico_firmware_id_offsets); pos++) { | |
1279 | int idoff = dvico_firmware_id_offsets[pos]; | |
f5373788 | 1280 | |
702a6762 CP |
1281 | if (fw->size < idoff + 4) |
1282 | continue; | |
f5373788 | 1283 | |
702a6762 CP |
1284 | if (fw->data[idoff] == (USB_VID_DVICO & 0xff) && |
1285 | fw->data[idoff + 1] == USB_VID_DVICO >> 8) { | |
e62f89f2 DW |
1286 | struct firmware new_fw; |
1287 | u8 *new_fw_data = vmalloc(fw->size); | |
1288 | int ret; | |
1289 | ||
1290 | if (!new_fw_data) | |
1291 | return -ENOMEM; | |
1292 | ||
1293 | memcpy(new_fw_data, fw->data, fw->size); | |
1294 | new_fw.size = fw->size; | |
1295 | new_fw.data = new_fw_data; | |
1296 | ||
1297 | new_fw_data[idoff + 2] = | |
702a6762 | 1298 | le16_to_cpu(udev->descriptor.idProduct) + 1; |
e62f89f2 | 1299 | new_fw_data[idoff + 3] = |
702a6762 | 1300 | le16_to_cpu(udev->descriptor.idProduct) >> 8; |
f5373788 | 1301 | |
e62f89f2 DW |
1302 | ret = usb_cypress_load_firmware(udev, &new_fw, |
1303 | CYPRESS_FX2); | |
1304 | vfree(new_fw_data); | |
1305 | return ret; | |
702a6762 | 1306 | } |
f5373788 PB |
1307 | } |
1308 | ||
1309 | return -EINVAL; | |
1310 | } | |
1311 | ||
22c6d93a | 1312 | /* DVB USB Driver stuff */ |
4d43e13f PB |
1313 | static struct dvb_usb_device_properties cxusb_medion_properties; |
1314 | static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties; | |
1315 | static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties; | |
1316 | static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties; | |
1317 | static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties; | |
aeb012bb | 1318 | static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties; |
8d798988 | 1319 | static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties; |
5ccaf905 | 1320 | static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties; |
702a6762 | 1321 | static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties; |
f5376ada | 1322 | static struct dvb_usb_device_properties cxusb_aver_a868r_properties; |
dfbdce04 | 1323 | static struct dvb_usb_device_properties cxusb_d680_dmb_properties; |
b18bd1d8 | 1324 | static struct dvb_usb_device_properties cxusb_mygica_d689_properties; |
a0f629b9 | 1325 | static struct dvb_usb_device_properties cxusb_mygica_t230_properties; |
22c6d93a PB |
1326 | |
1327 | static int cxusb_probe(struct usb_interface *intf, | |
f35db23c | 1328 | const struct usb_device_id *id) |
22c6d93a | 1329 | { |
78e92006 | 1330 | if (0 == dvb_usb_device_init(intf, &cxusb_medion_properties, |
7724325a | 1331 | THIS_MODULE, NULL, adapter_nr) || |
78e92006 | 1332 | 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgh064f_properties, |
7724325a | 1333 | THIS_MODULE, NULL, adapter_nr) || |
78e92006 | 1334 | 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dee1601_properties, |
7724325a | 1335 | THIS_MODULE, NULL, adapter_nr) || |
78e92006 | 1336 | 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgz201_properties, |
7724325a | 1337 | THIS_MODULE, NULL, adapter_nr) || |
78e92006 | 1338 | 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dtt7579_properties, |
7724325a | 1339 | THIS_MODULE, NULL, adapter_nr) || |
78e92006 | 1340 | 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dualdig4_properties, |
7724325a | 1341 | THIS_MODULE, NULL, adapter_nr) || |
78e92006 | 1342 | 0 == dvb_usb_device_init(intf, &cxusb_bluebird_nano2_properties, |
7724325a | 1343 | THIS_MODULE, NULL, adapter_nr) || |
78e92006 JG |
1344 | 0 == dvb_usb_device_init(intf, |
1345 | &cxusb_bluebird_nano2_needsfirmware_properties, | |
7724325a | 1346 | THIS_MODULE, NULL, adapter_nr) || |
f5376ada | 1347 | 0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties, |
7724325a | 1348 | THIS_MODULE, NULL, adapter_nr) || |
8d798988 AB |
1349 | 0 == dvb_usb_device_init(intf, |
1350 | &cxusb_bluebird_dualdig4_rev2_properties, | |
7724325a | 1351 | THIS_MODULE, NULL, adapter_nr) || |
dfbdce04 | 1352 | 0 == dvb_usb_device_init(intf, &cxusb_d680_dmb_properties, |
7724325a | 1353 | THIS_MODULE, NULL, adapter_nr) || |
b18bd1d8 | 1354 | 0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties, |
7724325a | 1355 | THIS_MODULE, NULL, adapter_nr) || |
a0f629b9 | 1356 | 0 == dvb_usb_device_init(intf, &cxusb_mygica_t230_properties, |
7724325a MCC |
1357 | THIS_MODULE, NULL, adapter_nr) || |
1358 | 0) | |
effee033 | 1359 | return 0; |
effee033 MK |
1360 | |
1361 | return -EINVAL; | |
22c6d93a PB |
1362 | } |
1363 | ||
26c42b0d OS |
1364 | static void cxusb_disconnect(struct usb_interface *intf) |
1365 | { | |
1366 | struct dvb_usb_device *d = usb_get_intfdata(intf); | |
1367 | struct cxusb_state *st = d->priv; | |
1368 | struct i2c_client *client; | |
1369 | ||
1370 | /* remove I2C client for tuner */ | |
1371 | client = st->i2c_client_tuner; | |
1372 | if (client) { | |
1373 | module_put(client->dev.driver->owner); | |
1374 | i2c_unregister_device(client); | |
1375 | } | |
1376 | ||
1377 | /* remove I2C client for demodulator */ | |
1378 | client = st->i2c_client_demod; | |
1379 | if (client) { | |
1380 | module_put(client->dev.driver->owner); | |
1381 | i2c_unregister_device(client); | |
1382 | } | |
1383 | ||
1384 | dvb_usb_device_exit(intf); | |
1385 | } | |
1386 | ||
974e08d8 DH |
1387 | enum cxusb_table_index { |
1388 | MEDION_MD95700, | |
1389 | DVICO_BLUEBIRD_LG064F_COLD, | |
1390 | DVICO_BLUEBIRD_LG064F_WARM, | |
1391 | DVICO_BLUEBIRD_DUAL_1_COLD, | |
1392 | DVICO_BLUEBIRD_DUAL_1_WARM, | |
1393 | DVICO_BLUEBIRD_LGZ201_COLD, | |
1394 | DVICO_BLUEBIRD_LGZ201_WARM, | |
1395 | DVICO_BLUEBIRD_TH7579_COLD, | |
1396 | DVICO_BLUEBIRD_TH7579_WARM, | |
1397 | DIGITALNOW_BLUEBIRD_DUAL_1_COLD, | |
1398 | DIGITALNOW_BLUEBIRD_DUAL_1_WARM, | |
1399 | DVICO_BLUEBIRD_DUAL_2_COLD, | |
1400 | DVICO_BLUEBIRD_DUAL_2_WARM, | |
1401 | DVICO_BLUEBIRD_DUAL_4, | |
1402 | DVICO_BLUEBIRD_DVB_T_NANO_2, | |
1403 | DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM, | |
1404 | AVERMEDIA_VOLAR_A868R, | |
1405 | DVICO_BLUEBIRD_DUAL_4_REV_2, | |
1406 | CONEXANT_D680_DMB, | |
1407 | MYGICA_D689, | |
1408 | MYGICA_T230, | |
1409 | NR__cxusb_table_index | |
1410 | }; | |
1411 | ||
1412 | static struct usb_device_id cxusb_table[NR__cxusb_table_index + 1] = { | |
1413 | [MEDION_MD95700] = { | |
1414 | USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) | |
1415 | }, | |
1416 | [DVICO_BLUEBIRD_LG064F_COLD] = { | |
1417 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) | |
1418 | }, | |
1419 | [DVICO_BLUEBIRD_LG064F_WARM] = { | |
1420 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_WARM) | |
1421 | }, | |
1422 | [DVICO_BLUEBIRD_DUAL_1_COLD] = { | |
1423 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_COLD) | |
1424 | }, | |
1425 | [DVICO_BLUEBIRD_DUAL_1_WARM] = { | |
1426 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM) | |
1427 | }, | |
1428 | [DVICO_BLUEBIRD_LGZ201_COLD] = { | |
1429 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_COLD) | |
1430 | }, | |
1431 | [DVICO_BLUEBIRD_LGZ201_WARM] = { | |
1432 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_WARM) | |
1433 | }, | |
1434 | [DVICO_BLUEBIRD_TH7579_COLD] = { | |
1435 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_COLD) | |
1436 | }, | |
1437 | [DVICO_BLUEBIRD_TH7579_WARM] = { | |
1438 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_WARM) | |
1439 | }, | |
1440 | [DIGITALNOW_BLUEBIRD_DUAL_1_COLD] = { | |
1441 | USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD) | |
1442 | }, | |
1443 | [DIGITALNOW_BLUEBIRD_DUAL_1_WARM] = { | |
1444 | USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM) | |
1445 | }, | |
1446 | [DVICO_BLUEBIRD_DUAL_2_COLD] = { | |
1447 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD) | |
1448 | }, | |
1449 | [DVICO_BLUEBIRD_DUAL_2_WARM] = { | |
1450 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM) | |
1451 | }, | |
1452 | [DVICO_BLUEBIRD_DUAL_4] = { | |
1453 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) | |
1454 | }, | |
1455 | [DVICO_BLUEBIRD_DVB_T_NANO_2] = { | |
1456 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) | |
1457 | }, | |
1458 | [DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM] = { | |
1459 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) | |
1460 | }, | |
1461 | [AVERMEDIA_VOLAR_A868R] = { | |
1462 | USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) | |
1463 | }, | |
1464 | [DVICO_BLUEBIRD_DUAL_4_REV_2] = { | |
1465 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) | |
1466 | }, | |
1467 | [CONEXANT_D680_DMB] = { | |
1468 | USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) | |
1469 | }, | |
1470 | [MYGICA_D689] = { | |
1471 | USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) | |
1472 | }, | |
1473 | [MYGICA_T230] = { | |
1474 | USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230) | |
1475 | }, | |
f35db23c | 1476 | {} /* Terminating entry */ |
22c6d93a PB |
1477 | }; |
1478 | MODULE_DEVICE_TABLE (usb, cxusb_table); | |
1479 | ||
4d43e13f | 1480 | static struct dvb_usb_device_properties cxusb_medion_properties = { |
22c6d93a PB |
1481 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
1482 | ||
1483 | .usb_ctrl = CYPRESS_FX2, | |
1484 | ||
1485 | .size_of_priv = sizeof(struct cxusb_state), | |
1486 | ||
4d43e13f PB |
1487 | .num_adapters = 1, |
1488 | .adapter = { | |
1489 | { | |
77eed219 MK |
1490 | .num_frontends = 1, |
1491 | .fe = {{ | |
01451e72 PB |
1492 | .streaming_ctrl = cxusb_streaming_ctrl, |
1493 | .frontend_attach = cxusb_cx22702_frontend_attach, | |
1494 | .tuner_attach = cxusb_fmd1216me_tuner_attach, | |
1495 | /* parameter for the MPEG2-data transfer */ | |
1496 | .stream = { | |
1497 | .type = USB_BULK, | |
1498 | .count = 5, | |
1499 | .endpoint = 0x02, | |
1500 | .u = { | |
1501 | .bulk = { | |
1502 | .buffersize = 8192, | |
1503 | } | |
1504 | } | |
1505 | }, | |
77eed219 | 1506 | }}, |
4d43e13f PB |
1507 | }, |
1508 | }, | |
1509 | .power_ctrl = cxusb_power_ctrl, | |
1510 | ||
1511 | .i2c_algo = &cxusb_i2c_algo, | |
1512 | ||
1513 | .generic_bulk_ctrl_endpoint = 0x01, | |
1514 | ||
22c6d93a PB |
1515 | .num_device_descs = 1, |
1516 | .devices = { | |
1517 | { "Medion MD95700 (MDUSBTV-HYBRID)", | |
1518 | { NULL }, | |
974e08d8 | 1519 | { &cxusb_table[MEDION_MD95700], NULL }, |
22c6d93a PB |
1520 | }, |
1521 | } | |
1522 | }; | |
1523 | ||
4d43e13f | 1524 | static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = { |
effee033 MK |
1525 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
1526 | ||
f5373788 PB |
1527 | .usb_ctrl = DEVICE_SPECIFIC, |
1528 | .firmware = "dvb-usb-bluebird-01.fw", | |
1529 | .download_firmware = bluebird_patch_dvico_firmware_download, | |
37bdfa06 MK |
1530 | /* use usb alt setting 0 for EP4 transfer (dvb-t), |
1531 | use usb alt setting 7 for EP2 transfer (atsc) */ | |
effee033 MK |
1532 | |
1533 | .size_of_priv = sizeof(struct cxusb_state), | |
1534 | ||
4d43e13f PB |
1535 | .num_adapters = 1, |
1536 | .adapter = { | |
1537 | { | |
77eed219 MK |
1538 | .num_frontends = 1, |
1539 | .fe = {{ | |
01451e72 PB |
1540 | .streaming_ctrl = cxusb_streaming_ctrl, |
1541 | .frontend_attach = cxusb_lgdt3303_frontend_attach, | |
f71a56c1 | 1542 | .tuner_attach = cxusb_lgh064f_tuner_attach, |
01451e72 PB |
1543 | |
1544 | /* parameter for the MPEG2-data transfer */ | |
1545 | .stream = { | |
1546 | .type = USB_BULK, | |
1547 | .count = 5, | |
1548 | .endpoint = 0x02, | |
1549 | .u = { | |
1550 | .bulk = { | |
1551 | .buffersize = 8192, | |
1552 | } | |
1553 | } | |
1554 | }, | |
77eed219 | 1555 | }}, |
4d43e13f PB |
1556 | }, |
1557 | }, | |
1558 | ||
1559 | .power_ctrl = cxusb_bluebird_power_ctrl, | |
1560 | ||
1561 | .i2c_algo = &cxusb_i2c_algo, | |
1562 | ||
517b5007 SY |
1563 | .rc.core = { |
1564 | .rc_interval = 100, | |
1565 | .rc_codes = RC_MAP_DVICO_PORTABLE, | |
1566 | .module_name = KBUILD_MODNAME, | |
1567 | .rc_query = cxusb_rc_query, | |
6d741bfe | 1568 | .allowed_protos = RC_PROTO_BIT_NEC, |
f72a27b8 | 1569 | }, |
4d43e13f PB |
1570 | |
1571 | .generic_bulk_ctrl_endpoint = 0x01, | |
effee033 MK |
1572 | |
1573 | .num_device_descs = 1, | |
1574 | .devices = { | |
1575 | { "DViCO FusionHDTV5 USB Gold", | |
974e08d8 DH |
1576 | { &cxusb_table[DVICO_BLUEBIRD_LG064F_COLD], NULL }, |
1577 | { &cxusb_table[DVICO_BLUEBIRD_LG064F_WARM], NULL }, | |
effee033 MK |
1578 | }, |
1579 | } | |
1580 | }; | |
1581 | ||
4d43e13f | 1582 | static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = { |
0029ee14 CP |
1583 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
1584 | ||
f5373788 PB |
1585 | .usb_ctrl = DEVICE_SPECIFIC, |
1586 | .firmware = "dvb-usb-bluebird-01.fw", | |
1587 | .download_firmware = bluebird_patch_dvico_firmware_download, | |
0029ee14 CP |
1588 | /* use usb alt setting 0 for EP4 transfer (dvb-t), |
1589 | use usb alt setting 7 for EP2 transfer (atsc) */ | |
1590 | ||
1591 | .size_of_priv = sizeof(struct cxusb_state), | |
1592 | ||
4d43e13f PB |
1593 | .num_adapters = 1, |
1594 | .adapter = { | |
1595 | { | |
77eed219 MK |
1596 | .num_frontends = 1, |
1597 | .fe = {{ | |
01451e72 PB |
1598 | .streaming_ctrl = cxusb_streaming_ctrl, |
1599 | .frontend_attach = cxusb_dee1601_frontend_attach, | |
1600 | .tuner_attach = cxusb_dee1601_tuner_attach, | |
1601 | /* parameter for the MPEG2-data transfer */ | |
4d43e13f PB |
1602 | .stream = { |
1603 | .type = USB_BULK, | |
01451e72 PB |
1604 | .count = 5, |
1605 | .endpoint = 0x04, | |
1606 | .u = { | |
1607 | .bulk = { | |
1608 | .buffersize = 8192, | |
1609 | } | |
1610 | } | |
1611 | }, | |
77eed219 | 1612 | }}, |
4d43e13f PB |
1613 | }, |
1614 | }, | |
1615 | ||
1616 | .power_ctrl = cxusb_bluebird_power_ctrl, | |
1617 | ||
1618 | .i2c_algo = &cxusb_i2c_algo, | |
1619 | ||
517b5007 SY |
1620 | .rc.core = { |
1621 | .rc_interval = 100, | |
1622 | .rc_codes = RC_MAP_DVICO_MCE, | |
1623 | .module_name = KBUILD_MODNAME, | |
1624 | .rc_query = cxusb_rc_query, | |
6d741bfe | 1625 | .allowed_protos = RC_PROTO_BIT_NEC, |
f72a27b8 | 1626 | }, |
4d43e13f PB |
1627 | |
1628 | .generic_bulk_ctrl_endpoint = 0x01, | |
0029ee14 | 1629 | |
587c03d1 | 1630 | .num_device_descs = 3, |
0029ee14 CP |
1631 | .devices = { |
1632 | { "DViCO FusionHDTV DVB-T Dual USB", | |
974e08d8 DH |
1633 | { &cxusb_table[DVICO_BLUEBIRD_DUAL_1_COLD], NULL }, |
1634 | { &cxusb_table[DVICO_BLUEBIRD_DUAL_1_WARM], NULL }, | |
0029ee14 | 1635 | }, |
ac9ffb90 | 1636 | { "DigitalNow DVB-T Dual USB", |
974e08d8 DH |
1637 | { &cxusb_table[DIGITALNOW_BLUEBIRD_DUAL_1_COLD], NULL }, |
1638 | { &cxusb_table[DIGITALNOW_BLUEBIRD_DUAL_1_WARM], NULL }, | |
ac9ffb90 | 1639 | }, |
587c03d1 | 1640 | { "DViCO FusionHDTV DVB-T Dual Digital 2", |
974e08d8 DH |
1641 | { &cxusb_table[DVICO_BLUEBIRD_DUAL_2_COLD], NULL }, |
1642 | { &cxusb_table[DVICO_BLUEBIRD_DUAL_2_WARM], NULL }, | |
587c03d1 | 1643 | }, |
0029ee14 CP |
1644 | } |
1645 | }; | |
1646 | ||
4d43e13f | 1647 | static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = { |
6f447259 MK |
1648 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
1649 | ||
1650 | .usb_ctrl = DEVICE_SPECIFIC, | |
1651 | .firmware = "dvb-usb-bluebird-01.fw", | |
1652 | .download_firmware = bluebird_patch_dvico_firmware_download, | |
1653 | /* use usb alt setting 0 for EP4 transfer (dvb-t), | |
1654 | use usb alt setting 7 for EP2 transfer (atsc) */ | |
1655 | ||
1656 | .size_of_priv = sizeof(struct cxusb_state), | |
1657 | ||
4d43e13f PB |
1658 | .num_adapters = 2, |
1659 | .adapter = { | |
1660 | { | |
77eed219 MK |
1661 | .num_frontends = 1, |
1662 | .fe = {{ | |
01451e72 PB |
1663 | .streaming_ctrl = cxusb_streaming_ctrl, |
1664 | .frontend_attach = cxusb_mt352_frontend_attach, | |
1665 | .tuner_attach = cxusb_lgz201_tuner_attach, | |
6f447259 | 1666 | |
01451e72 | 1667 | /* parameter for the MPEG2-data transfer */ |
4d43e13f PB |
1668 | .stream = { |
1669 | .type = USB_BULK, | |
01451e72 PB |
1670 | .count = 5, |
1671 | .endpoint = 0x04, | |
1672 | .u = { | |
1673 | .bulk = { | |
1674 | .buffersize = 8192, | |
1675 | } | |
1676 | } | |
1677 | }, | |
77eed219 | 1678 | }}, |
4d43e13f PB |
1679 | }, |
1680 | }, | |
1681 | .power_ctrl = cxusb_bluebird_power_ctrl, | |
1682 | ||
1683 | .i2c_algo = &cxusb_i2c_algo, | |
6f447259 | 1684 | |
517b5007 SY |
1685 | .rc.core = { |
1686 | .rc_interval = 100, | |
1687 | .rc_codes = RC_MAP_DVICO_PORTABLE, | |
1688 | .module_name = KBUILD_MODNAME, | |
1689 | .rc_query = cxusb_rc_query, | |
6d741bfe | 1690 | .allowed_protos = RC_PROTO_BIT_NEC, |
f72a27b8 | 1691 | }, |
4d43e13f PB |
1692 | |
1693 | .generic_bulk_ctrl_endpoint = 0x01, | |
6f447259 MK |
1694 | .num_device_descs = 1, |
1695 | .devices = { | |
1696 | { "DViCO FusionHDTV DVB-T USB (LGZ201)", | |
974e08d8 DH |
1697 | { &cxusb_table[DVICO_BLUEBIRD_LGZ201_COLD], NULL }, |
1698 | { &cxusb_table[DVICO_BLUEBIRD_LGZ201_WARM], NULL }, | |
6f447259 MK |
1699 | }, |
1700 | } | |
1701 | }; | |
1702 | ||
4d43e13f | 1703 | static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = { |
6f447259 MK |
1704 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
1705 | ||
1706 | .usb_ctrl = DEVICE_SPECIFIC, | |
1707 | .firmware = "dvb-usb-bluebird-01.fw", | |
1708 | .download_firmware = bluebird_patch_dvico_firmware_download, | |
1709 | /* use usb alt setting 0 for EP4 transfer (dvb-t), | |
1710 | use usb alt setting 7 for EP2 transfer (atsc) */ | |
1711 | ||
1712 | .size_of_priv = sizeof(struct cxusb_state), | |
1713 | ||
4d43e13f PB |
1714 | .num_adapters = 1, |
1715 | .adapter = { | |
1716 | { | |
77eed219 MK |
1717 | .num_frontends = 1, |
1718 | .fe = {{ | |
01451e72 PB |
1719 | .streaming_ctrl = cxusb_streaming_ctrl, |
1720 | .frontend_attach = cxusb_mt352_frontend_attach, | |
1721 | .tuner_attach = cxusb_dtt7579_tuner_attach, | |
6f447259 | 1722 | |
01451e72 | 1723 | /* parameter for the MPEG2-data transfer */ |
4d43e13f PB |
1724 | .stream = { |
1725 | .type = USB_BULK, | |
01451e72 PB |
1726 | .count = 5, |
1727 | .endpoint = 0x04, | |
1728 | .u = { | |
1729 | .bulk = { | |
1730 | .buffersize = 8192, | |
1731 | } | |
1732 | } | |
1733 | }, | |
77eed219 | 1734 | }}, |
4d43e13f PB |
1735 | }, |
1736 | }, | |
1737 | .power_ctrl = cxusb_bluebird_power_ctrl, | |
1738 | ||
1739 | .i2c_algo = &cxusb_i2c_algo, | |
1740 | ||
517b5007 SY |
1741 | .rc.core = { |
1742 | .rc_interval = 100, | |
1743 | .rc_codes = RC_MAP_DVICO_PORTABLE, | |
1744 | .module_name = KBUILD_MODNAME, | |
1745 | .rc_query = cxusb_rc_query, | |
6d741bfe | 1746 | .allowed_protos = RC_PROTO_BIT_NEC, |
f72a27b8 | 1747 | }, |
4d43e13f PB |
1748 | |
1749 | .generic_bulk_ctrl_endpoint = 0x01, | |
6f447259 MK |
1750 | |
1751 | .num_device_descs = 1, | |
1752 | .devices = { | |
1753 | { "DViCO FusionHDTV DVB-T USB (TH7579)", | |
974e08d8 DH |
1754 | { &cxusb_table[DVICO_BLUEBIRD_TH7579_COLD], NULL }, |
1755 | { &cxusb_table[DVICO_BLUEBIRD_TH7579_WARM], NULL }, | |
6f447259 MK |
1756 | }, |
1757 | } | |
1758 | }; | |
1759 | ||
aeb012bb CP |
1760 | static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = { |
1761 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | |
1762 | ||
1763 | .usb_ctrl = CYPRESS_FX2, | |
1764 | ||
1765 | .size_of_priv = sizeof(struct cxusb_state), | |
1766 | ||
1767 | .num_adapters = 1, | |
1768 | .adapter = { | |
1769 | { | |
77eed219 MK |
1770 | .num_frontends = 1, |
1771 | .fe = {{ | |
aeb012bb CP |
1772 | .streaming_ctrl = cxusb_streaming_ctrl, |
1773 | .frontend_attach = cxusb_dualdig4_frontend_attach, | |
1774 | .tuner_attach = cxusb_dvico_xc3028_tuner_attach, | |
1775 | /* parameter for the MPEG2-data transfer */ | |
1776 | .stream = { | |
1777 | .type = USB_BULK, | |
1778 | .count = 5, | |
1779 | .endpoint = 0x02, | |
1780 | .u = { | |
1781 | .bulk = { | |
1782 | .buffersize = 8192, | |
1783 | } | |
1784 | } | |
1785 | }, | |
77eed219 | 1786 | }}, |
aeb012bb CP |
1787 | }, |
1788 | }, | |
1789 | ||
1790 | .power_ctrl = cxusb_power_ctrl, | |
1791 | ||
1792 | .i2c_algo = &cxusb_i2c_algo, | |
1793 | ||
1794 | .generic_bulk_ctrl_endpoint = 0x01, | |
1795 | ||
517b5007 SY |
1796 | .rc.core = { |
1797 | .rc_interval = 100, | |
1798 | .rc_codes = RC_MAP_DVICO_MCE, | |
1799 | .module_name = KBUILD_MODNAME, | |
1800 | .rc_query = cxusb_bluebird2_rc_query, | |
6d741bfe | 1801 | .allowed_protos = RC_PROTO_BIT_NEC, |
f72a27b8 | 1802 | }, |
aeb012bb CP |
1803 | |
1804 | .num_device_descs = 1, | |
1805 | .devices = { | |
1806 | { "DViCO FusionHDTV DVB-T Dual Digital 4", | |
1807 | { NULL }, | |
974e08d8 | 1808 | { &cxusb_table[DVICO_BLUEBIRD_DUAL_4], NULL }, |
aeb012bb CP |
1809 | }, |
1810 | } | |
1811 | }; | |
1812 | ||
5ccaf905 CP |
1813 | static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = { |
1814 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | |
1815 | ||
1816 | .usb_ctrl = CYPRESS_FX2, | |
702a6762 | 1817 | .identify_state = bluebird_fx2_identify_state, |
5ccaf905 CP |
1818 | |
1819 | .size_of_priv = sizeof(struct cxusb_state), | |
1820 | ||
1821 | .num_adapters = 1, | |
1822 | .adapter = { | |
1823 | { | |
77eed219 MK |
1824 | .num_frontends = 1, |
1825 | .fe = {{ | |
5ccaf905 CP |
1826 | .streaming_ctrl = cxusb_streaming_ctrl, |
1827 | .frontend_attach = cxusb_nano2_frontend_attach, | |
1828 | .tuner_attach = cxusb_dvico_xc3028_tuner_attach, | |
1829 | /* parameter for the MPEG2-data transfer */ | |
1830 | .stream = { | |
1831 | .type = USB_BULK, | |
1832 | .count = 5, | |
1833 | .endpoint = 0x02, | |
1834 | .u = { | |
1835 | .bulk = { | |
1836 | .buffersize = 8192, | |
1837 | } | |
1838 | } | |
1839 | }, | |
77eed219 | 1840 | }}, |
5ccaf905 CP |
1841 | }, |
1842 | }, | |
1843 | ||
1844 | .power_ctrl = cxusb_nano2_power_ctrl, | |
1845 | ||
1846 | .i2c_algo = &cxusb_i2c_algo, | |
1847 | ||
1848 | .generic_bulk_ctrl_endpoint = 0x01, | |
1849 | ||
517b5007 SY |
1850 | .rc.core = { |
1851 | .rc_interval = 100, | |
1852 | .rc_codes = RC_MAP_DVICO_PORTABLE, | |
1853 | .module_name = KBUILD_MODNAME, | |
1854 | .rc_query = cxusb_bluebird2_rc_query, | |
6d741bfe | 1855 | .allowed_protos = RC_PROTO_BIT_NEC, |
f72a27b8 | 1856 | }, |
5ccaf905 CP |
1857 | |
1858 | .num_device_descs = 1, | |
1859 | .devices = { | |
1860 | { "DViCO FusionHDTV DVB-T NANO2", | |
1861 | { NULL }, | |
974e08d8 | 1862 | { &cxusb_table[DVICO_BLUEBIRD_DVB_T_NANO_2], NULL }, |
5ccaf905 CP |
1863 | }, |
1864 | } | |
1865 | }; | |
1866 | ||
702a6762 CP |
1867 | static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties = { |
1868 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | |
1869 | ||
1870 | .usb_ctrl = DEVICE_SPECIFIC, | |
1871 | .firmware = "dvb-usb-bluebird-02.fw", | |
1872 | .download_firmware = bluebird_patch_dvico_firmware_download, | |
1873 | .identify_state = bluebird_fx2_identify_state, | |
1874 | ||
1875 | .size_of_priv = sizeof(struct cxusb_state), | |
1876 | ||
1877 | .num_adapters = 1, | |
1878 | .adapter = { | |
1879 | { | |
77eed219 MK |
1880 | .num_frontends = 1, |
1881 | .fe = {{ | |
702a6762 CP |
1882 | .streaming_ctrl = cxusb_streaming_ctrl, |
1883 | .frontend_attach = cxusb_nano2_frontend_attach, | |
1884 | .tuner_attach = cxusb_dvico_xc3028_tuner_attach, | |
1885 | /* parameter for the MPEG2-data transfer */ | |
1886 | .stream = { | |
1887 | .type = USB_BULK, | |
1888 | .count = 5, | |
1889 | .endpoint = 0x02, | |
1890 | .u = { | |
1891 | .bulk = { | |
1892 | .buffersize = 8192, | |
1893 | } | |
1894 | } | |
1895 | }, | |
77eed219 | 1896 | }}, |
702a6762 CP |
1897 | }, |
1898 | }, | |
1899 | ||
1900 | .power_ctrl = cxusb_nano2_power_ctrl, | |
1901 | ||
1902 | .i2c_algo = &cxusb_i2c_algo, | |
1903 | ||
1904 | .generic_bulk_ctrl_endpoint = 0x01, | |
1905 | ||
517b5007 SY |
1906 | .rc.core = { |
1907 | .rc_interval = 100, | |
1908 | .rc_codes = RC_MAP_DVICO_PORTABLE, | |
1909 | .module_name = KBUILD_MODNAME, | |
1910 | .rc_query = cxusb_rc_query, | |
6d741bfe | 1911 | .allowed_protos = RC_PROTO_BIT_NEC, |
f72a27b8 | 1912 | }, |
702a6762 CP |
1913 | |
1914 | .num_device_descs = 1, | |
1915 | .devices = { | |
1916 | { "DViCO FusionHDTV DVB-T NANO2 w/o firmware", | |
974e08d8 DH |
1917 | { &cxusb_table[DVICO_BLUEBIRD_DVB_T_NANO_2], NULL }, |
1918 | { &cxusb_table[DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM], NULL }, | |
702a6762 CP |
1919 | }, |
1920 | } | |
1921 | }; | |
1922 | ||
f5376ada DG |
1923 | static struct dvb_usb_device_properties cxusb_aver_a868r_properties = { |
1924 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | |
1925 | ||
1926 | .usb_ctrl = CYPRESS_FX2, | |
1927 | ||
1928 | .size_of_priv = sizeof(struct cxusb_state), | |
1929 | ||
1930 | .num_adapters = 1, | |
1931 | .adapter = { | |
1932 | { | |
77eed219 MK |
1933 | .num_frontends = 1, |
1934 | .fe = {{ | |
f5376ada DG |
1935 | .streaming_ctrl = cxusb_aver_streaming_ctrl, |
1936 | .frontend_attach = cxusb_aver_lgdt3303_frontend_attach, | |
1937 | .tuner_attach = cxusb_mxl5003s_tuner_attach, | |
1938 | /* parameter for the MPEG2-data transfer */ | |
1939 | .stream = { | |
1940 | .type = USB_BULK, | |
1941 | .count = 5, | |
1942 | .endpoint = 0x04, | |
1943 | .u = { | |
1944 | .bulk = { | |
1945 | .buffersize = 8192, | |
1946 | } | |
1947 | } | |
1948 | }, | |
77eed219 | 1949 | }}, |
f5376ada DG |
1950 | }, |
1951 | }, | |
1952 | .power_ctrl = cxusb_aver_power_ctrl, | |
1953 | ||
1954 | .i2c_algo = &cxusb_i2c_algo, | |
1955 | ||
1956 | .generic_bulk_ctrl_endpoint = 0x01, | |
1957 | ||
1958 | .num_device_descs = 1, | |
1959 | .devices = { | |
1960 | { "AVerMedia AVerTVHD Volar (A868R)", | |
1961 | { NULL }, | |
974e08d8 | 1962 | { &cxusb_table[AVERMEDIA_VOLAR_A868R], NULL }, |
f5376ada DG |
1963 | }, |
1964 | } | |
1965 | }; | |
1966 | ||
a2dc86b6 MK |
1967 | static |
1968 | struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = { | |
8d798988 AB |
1969 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
1970 | ||
1971 | .usb_ctrl = CYPRESS_FX2, | |
1972 | ||
1973 | .size_of_priv = sizeof(struct cxusb_state), | |
1974 | ||
1975 | .num_adapters = 1, | |
1976 | .adapter = { | |
1977 | { | |
77eed219 MK |
1978 | .size_of_priv = sizeof(struct dib0700_adapter_state), |
1979 | .num_frontends = 1, | |
1980 | .fe = {{ | |
a2dc86b6 MK |
1981 | .streaming_ctrl = cxusb_streaming_ctrl, |
1982 | .frontend_attach = cxusb_dualdig4_rev2_frontend_attach, | |
1983 | .tuner_attach = cxusb_dualdig4_rev2_tuner_attach, | |
8d798988 AB |
1984 | /* parameter for the MPEG2-data transfer */ |
1985 | .stream = { | |
1986 | .type = USB_BULK, | |
1987 | .count = 7, | |
1988 | .endpoint = 0x02, | |
1989 | .u = { | |
1990 | .bulk = { | |
1991 | .buffersize = 4096, | |
1992 | } | |
1993 | } | |
1994 | }, | |
77eed219 | 1995 | }}, |
8d798988 AB |
1996 | }, |
1997 | }, | |
1998 | ||
1999 | .power_ctrl = cxusb_bluebird_power_ctrl, | |
2000 | ||
2001 | .i2c_algo = &cxusb_i2c_algo, | |
2002 | ||
2003 | .generic_bulk_ctrl_endpoint = 0x01, | |
2004 | ||
517b5007 SY |
2005 | .rc.core = { |
2006 | .rc_interval = 100, | |
2007 | .rc_codes = RC_MAP_DVICO_MCE, | |
2008 | .module_name = KBUILD_MODNAME, | |
2009 | .rc_query = cxusb_rc_query, | |
6d741bfe | 2010 | .allowed_protos = RC_PROTO_BIT_NEC, |
f72a27b8 | 2011 | }, |
8d798988 AB |
2012 | |
2013 | .num_device_descs = 1, | |
2014 | .devices = { | |
2015 | { "DViCO FusionHDTV DVB-T Dual Digital 4 (rev 2)", | |
2016 | { NULL }, | |
974e08d8 | 2017 | { &cxusb_table[DVICO_BLUEBIRD_DUAL_4_REV_2], NULL }, |
8d798988 AB |
2018 | }, |
2019 | } | |
2020 | }; | |
2021 | ||
dfbdce04 TL |
2022 | static struct dvb_usb_device_properties cxusb_d680_dmb_properties = { |
2023 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | |
2024 | ||
2025 | .usb_ctrl = CYPRESS_FX2, | |
2026 | ||
2027 | .size_of_priv = sizeof(struct cxusb_state), | |
2028 | ||
2029 | .num_adapters = 1, | |
2030 | .adapter = { | |
2031 | { | |
77eed219 MK |
2032 | .num_frontends = 1, |
2033 | .fe = {{ | |
dfbdce04 TL |
2034 | .streaming_ctrl = cxusb_d680_dmb_streaming_ctrl, |
2035 | .frontend_attach = cxusb_d680_dmb_frontend_attach, | |
2036 | .tuner_attach = cxusb_d680_dmb_tuner_attach, | |
2037 | ||
2038 | /* parameter for the MPEG2-data transfer */ | |
2039 | .stream = { | |
2040 | .type = USB_BULK, | |
2041 | .count = 5, | |
2042 | .endpoint = 0x02, | |
2043 | .u = { | |
2044 | .bulk = { | |
2045 | .buffersize = 8192, | |
2046 | } | |
2047 | } | |
2048 | }, | |
77eed219 | 2049 | }}, |
dfbdce04 TL |
2050 | }, |
2051 | }, | |
2052 | ||
2053 | .power_ctrl = cxusb_d680_dmb_power_ctrl, | |
2054 | ||
2055 | .i2c_algo = &cxusb_i2c_algo, | |
2056 | ||
2057 | .generic_bulk_ctrl_endpoint = 0x01, | |
2058 | ||
517b5007 SY |
2059 | .rc.core = { |
2060 | .rc_interval = 100, | |
1bbab525 | 2061 | .rc_codes = RC_MAP_TOTAL_MEDIA_IN_HAND_02, |
517b5007 SY |
2062 | .module_name = KBUILD_MODNAME, |
2063 | .rc_query = cxusb_d680_dmb_rc_query, | |
6d741bfe | 2064 | .allowed_protos = RC_PROTO_BIT_UNKNOWN, |
f72a27b8 | 2065 | }, |
dfbdce04 TL |
2066 | |
2067 | .num_device_descs = 1, | |
2068 | .devices = { | |
2069 | { | |
2070 | "Conexant DMB-TH Stick", | |
2071 | { NULL }, | |
974e08d8 | 2072 | { &cxusb_table[CONEXANT_D680_DMB], NULL }, |
dfbdce04 TL |
2073 | }, |
2074 | } | |
2075 | }; | |
2076 | ||
b18bd1d8 DW |
2077 | static struct dvb_usb_device_properties cxusb_mygica_d689_properties = { |
2078 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | |
2079 | ||
2080 | .usb_ctrl = CYPRESS_FX2, | |
2081 | ||
2082 | .size_of_priv = sizeof(struct cxusb_state), | |
2083 | ||
2084 | .num_adapters = 1, | |
2085 | .adapter = { | |
2086 | { | |
77eed219 MK |
2087 | .num_frontends = 1, |
2088 | .fe = {{ | |
b18bd1d8 DW |
2089 | .streaming_ctrl = cxusb_d680_dmb_streaming_ctrl, |
2090 | .frontend_attach = cxusb_mygica_d689_frontend_attach, | |
2091 | .tuner_attach = cxusb_mygica_d689_tuner_attach, | |
2092 | ||
2093 | /* parameter for the MPEG2-data transfer */ | |
2094 | .stream = { | |
2095 | .type = USB_BULK, | |
2096 | .count = 5, | |
2097 | .endpoint = 0x02, | |
2098 | .u = { | |
2099 | .bulk = { | |
2100 | .buffersize = 8192, | |
2101 | } | |
2102 | } | |
2103 | }, | |
77eed219 | 2104 | }}, |
b18bd1d8 DW |
2105 | }, |
2106 | }, | |
2107 | ||
2108 | .power_ctrl = cxusb_d680_dmb_power_ctrl, | |
2109 | ||
2110 | .i2c_algo = &cxusb_i2c_algo, | |
2111 | ||
2112 | .generic_bulk_ctrl_endpoint = 0x01, | |
2113 | ||
517b5007 SY |
2114 | .rc.core = { |
2115 | .rc_interval = 100, | |
2116 | .rc_codes = RC_MAP_D680_DMB, | |
2117 | .module_name = KBUILD_MODNAME, | |
2118 | .rc_query = cxusb_d680_dmb_rc_query, | |
6d741bfe | 2119 | .allowed_protos = RC_PROTO_BIT_UNKNOWN, |
f72a27b8 | 2120 | }, |
b18bd1d8 DW |
2121 | |
2122 | .num_device_descs = 1, | |
2123 | .devices = { | |
2124 | { | |
2125 | "Mygica D689 DMB-TH", | |
2126 | { NULL }, | |
974e08d8 | 2127 | { &cxusb_table[MYGICA_D689], NULL }, |
b18bd1d8 DW |
2128 | }, |
2129 | } | |
2130 | }; | |
2131 | ||
a0f629b9 C |
2132 | static struct dvb_usb_device_properties cxusb_mygica_t230_properties = { |
2133 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | |
2134 | ||
2135 | .usb_ctrl = CYPRESS_FX2, | |
2136 | ||
2137 | .size_of_priv = sizeof(struct cxusb_state), | |
2138 | ||
2139 | .num_adapters = 1, | |
2140 | .adapter = { | |
2141 | { | |
2142 | .num_frontends = 1, | |
2143 | .fe = {{ | |
2144 | .streaming_ctrl = cxusb_streaming_ctrl, | |
2145 | .frontend_attach = cxusb_mygica_t230_frontend_attach, | |
2146 | ||
2147 | /* parameter for the MPEG2-data transfer */ | |
2148 | .stream = { | |
2149 | .type = USB_BULK, | |
2150 | .count = 5, | |
2151 | .endpoint = 0x02, | |
2152 | .u = { | |
2153 | .bulk = { | |
2154 | .buffersize = 8192, | |
2155 | } | |
2156 | } | |
2157 | }, | |
2158 | } }, | |
2159 | }, | |
2160 | }, | |
2161 | ||
2162 | .power_ctrl = cxusb_d680_dmb_power_ctrl, | |
2163 | ||
2164 | .i2c_algo = &cxusb_i2c_algo, | |
2165 | ||
2166 | .generic_bulk_ctrl_endpoint = 0x01, | |
2167 | ||
517b5007 SY |
2168 | .rc.core = { |
2169 | .rc_interval = 100, | |
c20ffbfe | 2170 | .rc_codes = RC_MAP_D680_DMB, |
517b5007 SY |
2171 | .module_name = KBUILD_MODNAME, |
2172 | .rc_query = cxusb_d680_dmb_rc_query, | |
6d741bfe | 2173 | .allowed_protos = RC_PROTO_BIT_UNKNOWN, |
a0f629b9 C |
2174 | }, |
2175 | ||
2176 | .num_device_descs = 1, | |
2177 | .devices = { | |
2178 | { | |
2179 | "Mygica T230 DVB-T/T2/C", | |
2180 | { NULL }, | |
974e08d8 | 2181 | { &cxusb_table[MYGICA_T230], NULL }, |
a0f629b9 C |
2182 | }, |
2183 | } | |
2184 | }; | |
2185 | ||
22c6d93a | 2186 | static struct usb_driver cxusb_driver = { |
63b5c1c4 | 2187 | .name = "dvb_usb_cxusb", |
22c6d93a | 2188 | .probe = cxusb_probe, |
26c42b0d | 2189 | .disconnect = cxusb_disconnect, |
22c6d93a PB |
2190 | .id_table = cxusb_table, |
2191 | }; | |
2192 | ||
ecb3b2b3 | 2193 | module_usb_driver(cxusb_driver); |
22c6d93a | 2194 | |
99e44da7 | 2195 | MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>"); |
5b9ed286 | 2196 | MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>"); |
f4efb4db | 2197 | MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); |
22c6d93a PB |
2198 | MODULE_DESCRIPTION("Driver for Conexant USB2.0 hybrid reference design"); |
2199 | MODULE_VERSION("1.0-alpha"); | |
2200 | MODULE_LICENSE("GPL"); |