Merge branch 'locking-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[deliverable/linux.git] / drivers / media / usb / dvb-usb / dw2102.c
CommitLineData
fe03d5ee 1/* DVB USB framework compliant Linux driver for the
2f30fb49 2 * DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101,
6ede20f9 3 * TeVii S421, S480, S482, S600, S630, S632, S650, S660, S662,
2f30fb49 4 * Prof 1100, 7500,
27254c36 5 * Geniatech SU3000, T220,
6ede20f9
OS
6 * TechnoTrend S2-4600,
7 * Terratec Cinergy S2 cards
955d00ac 8 * Copyright (C) 2008-2012 Igor M. Liplianin (liplianin@me.by)
2f30fb49
IL
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation, version 2.
13 *
14 * see Documentation/dvb/README.dvb-usb for more information
15 */
7fd4828f 16#include "dw2102.h"
21b007b9 17#include "si21xx.h"
7fd4828f
IL
18#include "stv0299.h"
19#include "z0194a.h"
8a4949b7
IL
20#include "stv0288.h"
21#include "stb6000.h"
22#include "eds1547.h"
fe03d5ee 23#include "cx24116.h"
1dac77c9 24#include "tda1002x.h"
d0a1ddad
IL
25#include "mt312.h"
26#include "zl10039.h"
73f0af44 27#include "ts2020.h"
141cc35e
IL
28#include "ds3000.h"
29#include "stv0900.h"
30#include "stv6110.h"
31#include "stb6100.h"
32#include "stb6100_proc.h"
955d00ac 33#include "m88rs2000.h"
51d882ed
EP
34#include "tda18271.h"
35#include "cxd2820r.h"
27254c36 36#include "m88ds3103.h"
7fd4828f 37
0065a79a
MCC
38/* Max transfer size done by I2C transfer functions */
39#define MAX_XFER_SIZE 64
40
7fd4828f
IL
41#ifndef USB_PID_DW2102
42#define USB_PID_DW2102 0x2102
43#endif
44
fe03d5ee
IL
45#ifndef USB_PID_DW2104
46#define USB_PID_DW2104 0x2104
47#endif
48
1dac77c9
IL
49#ifndef USB_PID_DW3101
50#define USB_PID_DW3101 0x3101
51#endif
52
4cc0edff
IL
53#ifndef USB_PID_CINERGY_S
54#define USB_PID_CINERGY_S 0x0064
55#endif
56
141cc35e
IL
57#ifndef USB_PID_TEVII_S630
58#define USB_PID_TEVII_S630 0xd630
59#endif
60
1dac77c9
IL
61#ifndef USB_PID_TEVII_S650
62#define USB_PID_TEVII_S650 0xd650
63#endif
64
141cc35e
IL
65#ifndef USB_PID_TEVII_S660
66#define USB_PID_TEVII_S660 0xd660
67#endif
68
6ede20f9
OS
69#ifndef USB_PID_TEVII_S662
70#define USB_PID_TEVII_S662 0xd662
71#endif
72
e8f5055a
IL
73#ifndef USB_PID_TEVII_S480_1
74#define USB_PID_TEVII_S480_1 0xd481
75#endif
76
77#ifndef USB_PID_TEVII_S480_2
78#define USB_PID_TEVII_S480_2 0xd482
79#endif
80
141cc35e
IL
81#ifndef USB_PID_PROF_1100
82#define USB_PID_PROF_1100 0xb012
d0a1ddad
IL
83#endif
84
955d00ac
IL
85#ifndef USB_PID_TEVII_S421
86#define USB_PID_TEVII_S421 0xd421
87#endif
88
89#ifndef USB_PID_TEVII_S632
90#define USB_PID_TEVII_S632 0xd632
91#endif
92
f08e9f0d
AP
93#ifndef USB_PID_GOTVIEW_SAT_HD
94#define USB_PID_GOTVIEW_SAT_HD 0x5456
95#endif
96
21b007b9
IL
97#define DW210X_READ_MSG 0
98#define DW210X_WRITE_MSG 1
7fd4828f
IL
99
100#define REG_1F_SYMBOLRATE_BYTE0 0x1f
101#define REG_20_SYMBOLRATE_BYTE1 0x20
102#define REG_21_SYMBOLRATE_BYTE2 0x21
fe03d5ee 103/* on my own*/
7fd4828f 104#define DW2102_VOLTAGE_CTRL (0x1800)
d2ffc447 105#define SU3000_STREAM_CTRL (0x1900)
7fd4828f 106#define DW2102_RC_QUERY (0x1a00)
fa8bae10 107#define DW2102_LED_CTRL (0x1b00)
7fd4828f 108
6823627b
RC
109#define DW2101_FIRMWARE "dvb-usb-dw2101.fw"
110#define DW2102_FIRMWARE "dvb-usb-dw2102.fw"
111#define DW2104_FIRMWARE "dvb-usb-dw2104.fw"
112#define DW3101_FIRMWARE "dvb-usb-dw3101.fw"
113#define S630_FIRMWARE "dvb-usb-s630.fw"
114#define S660_FIRMWARE "dvb-usb-s660.fw"
115#define P1100_FIRMWARE "dvb-usb-p1100.fw"
116#define P7500_FIRMWARE "dvb-usb-p7500.fw"
117
141cc35e
IL
118#define err_str "did not find the firmware file. (%s) " \
119 "Please see linux/Documentation/dvb/ for more details " \
120 "on firmware-problems."
121
2c4ffe27 122struct dw2102_state {
d2ffc447 123 u8 initialized;
356484ca 124 u8 last_lock;
f3c6abca 125 struct i2c_client *i2c_client_demod;
70769b24 126 struct i2c_client *i2c_client_tuner;
356484ca
OS
127
128 /* fe hook functions*/
0df289a2 129 int (*old_set_voltage)(struct dvb_frontend *f, enum fe_sec_voltage v);
356484ca 130 int (*fe_read_status)(struct dvb_frontend *fe,
0df289a2 131 enum fe_status *status);
52c506e0
IL
132};
133
fe03d5ee
IL
134/* debug */
135static int dvb_usb_dw2102_debug;
136module_param_named(debug, dvb_usb_dw2102_debug, int, 0644);
8a8dad71
IL
137MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))."
138 DVB_USB_DEBUG_STATUS);
139
141cc35e
IL
140/* demod probe */
141static int demod_probe = 1;
142module_param_named(demod, demod_probe, int, 0644);
143MODULE_PARM_DESC(demod, "demod to probe (1=cx24116 2=stv0903+stv6110 "
144 "4=stv0903+stb6100(or-able)).");
145
7fd4828f
IL
146DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
147
21b007b9 148static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value,
fe03d5ee 149 u16 index, u8 * data, u16 len, int flags)
7fd4828f
IL
150{
151 int ret;
b47b8501 152 u8 *u8buf;
21b007b9 153 unsigned int pipe = (flags == DW210X_READ_MSG) ?
fe03d5ee 154 usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0);
21b007b9 155 u8 request_type = (flags == DW210X_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
7fd4828f 156
b47b8501
FM
157 u8buf = kmalloc(len, GFP_KERNEL);
158 if (!u8buf)
159 return -ENOMEM;
160
161
21b007b9 162 if (flags == DW210X_WRITE_MSG)
7fd4828f 163 memcpy(u8buf, data, len);
fe03d5ee
IL
164 ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR,
165 value, index , u8buf, len, 2000);
7fd4828f 166
21b007b9 167 if (flags == DW210X_READ_MSG)
7fd4828f 168 memcpy(data, u8buf, len);
b47b8501
FM
169
170 kfree(u8buf);
7fd4828f
IL
171 return ret;
172}
173
174/* I2C */
7fd4828f
IL
175static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
176 int num)
177{
1dac77c9 178 struct dvb_usb_device *d = i2c_get_adapdata(adap);
d51dbecc 179 int i = 0;
7fd4828f 180 u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0};
7fd4828f
IL
181 u16 value;
182
183 if (!d)
184 return -ENODEV;
185 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
186 return -EAGAIN;
187
188 switch (num) {
189 case 2:
190 /* read stv0299 register */
7fd4828f
IL
191 value = msg[0].buf[0];/* register */
192 for (i = 0; i < msg[1].len; i++) {
d51dbecc 193 dw210x_op_rw(d->udev, 0xb5, value + i, 0,
21b007b9 194 buf6, 2, DW210X_READ_MSG);
7fd4828f 195 msg[1].buf[i] = buf6[0];
7fd4828f
IL
196 }
197 break;
198 case 1:
199 switch (msg[0].addr) {
200 case 0x68:
201 /* write to stv0299 register */
202 buf6[0] = 0x2a;
203 buf6[1] = msg[0].buf[0];
204 buf6[2] = msg[0].buf[1];
d51dbecc 205 dw210x_op_rw(d->udev, 0xb2, 0, 0,
21b007b9 206 buf6, 3, DW210X_WRITE_MSG);
7fd4828f
IL
207 break;
208 case 0x60:
209 if (msg[0].flags == 0) {
210 /* write to tuner pll */
211 buf6[0] = 0x2c;
212 buf6[1] = 5;
213 buf6[2] = 0xc0;
214 buf6[3] = msg[0].buf[0];
215 buf6[4] = msg[0].buf[1];
216 buf6[5] = msg[0].buf[2];
217 buf6[6] = msg[0].buf[3];
d51dbecc 218 dw210x_op_rw(d->udev, 0xb2, 0, 0,
21b007b9 219 buf6, 7, DW210X_WRITE_MSG);
7fd4828f 220 } else {
fe03d5ee 221 /* read from tuner */
d51dbecc 222 dw210x_op_rw(d->udev, 0xb5, 0, 0,
21b007b9 223 buf6, 1, DW210X_READ_MSG);
7fd4828f
IL
224 msg[0].buf[0] = buf6[0];
225 }
226 break;
227 case (DW2102_RC_QUERY):
d51dbecc 228 dw210x_op_rw(d->udev, 0xb8, 0, 0,
21b007b9 229 buf6, 2, DW210X_READ_MSG);
7fd4828f
IL
230 msg[0].buf[0] = buf6[0];
231 msg[0].buf[1] = buf6[1];
232 break;
233 case (DW2102_VOLTAGE_CTRL):
234 buf6[0] = 0x30;
235 buf6[1] = msg[0].buf[0];
d51dbecc 236 dw210x_op_rw(d->udev, 0xb2, 0, 0,
21b007b9 237 buf6, 2, DW210X_WRITE_MSG);
7fd4828f
IL
238 break;
239 }
240
241 break;
242 }
243
244 mutex_unlock(&d->i2c_mutex);
245 return num;
246}
247
21b007b9
IL
248static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
249 struct i2c_msg msg[], int num)
250{
251 struct dvb_usb_device *d = i2c_get_adapdata(adap);
21b007b9
IL
252 u8 buf6[] = {0, 0, 0, 0, 0, 0, 0};
253
254 if (!d)
255 return -ENODEV;
256 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
257 return -EAGAIN;
258
259 switch (num) {
260 case 2:
261 /* read si2109 register by number */
141cc35e 262 buf6[0] = msg[0].addr << 1;
21b007b9
IL
263 buf6[1] = msg[0].len;
264 buf6[2] = msg[0].buf[0];
d51dbecc 265 dw210x_op_rw(d->udev, 0xc2, 0, 0,
21b007b9
IL
266 buf6, msg[0].len + 2, DW210X_WRITE_MSG);
267 /* read si2109 register */
d51dbecc 268 dw210x_op_rw(d->udev, 0xc3, 0xd0, 0,
21b007b9
IL
269 buf6, msg[1].len + 2, DW210X_READ_MSG);
270 memcpy(msg[1].buf, buf6 + 2, msg[1].len);
271
272 break;
273 case 1:
274 switch (msg[0].addr) {
275 case 0x68:
276 /* write to si2109 register */
141cc35e 277 buf6[0] = msg[0].addr << 1;
21b007b9
IL
278 buf6[1] = msg[0].len;
279 memcpy(buf6 + 2, msg[0].buf, msg[0].len);
d51dbecc 280 dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6,
21b007b9
IL
281 msg[0].len + 2, DW210X_WRITE_MSG);
282 break;
283 case(DW2102_RC_QUERY):
d51dbecc 284 dw210x_op_rw(d->udev, 0xb8, 0, 0,
21b007b9
IL
285 buf6, 2, DW210X_READ_MSG);
286 msg[0].buf[0] = buf6[0];
287 msg[0].buf[1] = buf6[1];
288 break;
289 case(DW2102_VOLTAGE_CTRL):
290 buf6[0] = 0x30;
291 buf6[1] = msg[0].buf[0];
d51dbecc 292 dw210x_op_rw(d->udev, 0xb2, 0, 0,
21b007b9
IL
293 buf6, 2, DW210X_WRITE_MSG);
294 break;
295 }
296 break;
297 }
298
299 mutex_unlock(&d->i2c_mutex);
300 return num;
301}
1dac77c9 302
8a4949b7
IL
303static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
304{
305 struct dvb_usb_device *d = i2c_get_adapdata(adap);
324ed533 306 int ret;
8a4949b7
IL
307
308 if (!d)
309 return -ENODEV;
310 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
311 return -EAGAIN;
312
313 switch (num) {
314 case 2: {
315 /* read */
316 /* first write first register number */
0065a79a
MCC
317 u8 ibuf[MAX_XFER_SIZE], obuf[3];
318
319 if (2 + msg[1].len > sizeof(ibuf)) {
320 warn("i2c rd: len=%d is too big!\n",
321 msg[1].len);
324ed533
DC
322 ret = -EOPNOTSUPP;
323 goto unlock;
0065a79a
MCC
324 }
325
141cc35e 326 obuf[0] = msg[0].addr << 1;
8a4949b7
IL
327 obuf[1] = msg[0].len;
328 obuf[2] = msg[0].buf[0];
d51dbecc 329 dw210x_op_rw(d->udev, 0xc2, 0, 0,
8a4949b7
IL
330 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
331 /* second read registers */
d51dbecc 332 dw210x_op_rw(d->udev, 0xc3, 0xd1 , 0,
8a4949b7
IL
333 ibuf, msg[1].len + 2, DW210X_READ_MSG);
334 memcpy(msg[1].buf, ibuf + 2, msg[1].len);
335
336 break;
337 }
338 case 1:
339 switch (msg[0].addr) {
340 case 0x68: {
341 /* write to register */
0065a79a
MCC
342 u8 obuf[MAX_XFER_SIZE];
343
344 if (2 + msg[0].len > sizeof(obuf)) {
345 warn("i2c wr: len=%d is too big!\n",
346 msg[1].len);
324ed533
DC
347 ret = -EOPNOTSUPP;
348 goto unlock;
0065a79a
MCC
349 }
350
141cc35e 351 obuf[0] = msg[0].addr << 1;
8a4949b7
IL
352 obuf[1] = msg[0].len;
353 memcpy(obuf + 2, msg[0].buf, msg[0].len);
d51dbecc 354 dw210x_op_rw(d->udev, 0xc2, 0, 0,
8a4949b7
IL
355 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
356 break;
357 }
358 case 0x61: {
359 /* write to tuner */
0065a79a
MCC
360 u8 obuf[MAX_XFER_SIZE];
361
362 if (2 + msg[0].len > sizeof(obuf)) {
363 warn("i2c wr: len=%d is too big!\n",
364 msg[1].len);
324ed533
DC
365 ret = -EOPNOTSUPP;
366 goto unlock;
0065a79a
MCC
367 }
368
141cc35e 369 obuf[0] = msg[0].addr << 1;
8a4949b7
IL
370 obuf[1] = msg[0].len;
371 memcpy(obuf + 2, msg[0].buf, msg[0].len);
d51dbecc 372 dw210x_op_rw(d->udev, 0xc2, 0, 0,
8a4949b7
IL
373 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
374 break;
375 }
376 case(DW2102_RC_QUERY): {
377 u8 ibuf[2];
d51dbecc 378 dw210x_op_rw(d->udev, 0xb8, 0, 0,
8a4949b7
IL
379 ibuf, 2, DW210X_READ_MSG);
380 memcpy(msg[0].buf, ibuf , 2);
381 break;
382 }
383 case(DW2102_VOLTAGE_CTRL): {
384 u8 obuf[2];
385 obuf[0] = 0x30;
386 obuf[1] = msg[0].buf[0];
d51dbecc 387 dw210x_op_rw(d->udev, 0xb2, 0, 0,
8a4949b7
IL
388 obuf, 2, DW210X_WRITE_MSG);
389 break;
390 }
391 }
392
393 break;
394 }
324ed533 395 ret = num;
8a4949b7 396
324ed533 397unlock:
8a4949b7 398 mutex_unlock(&d->i2c_mutex);
324ed533 399 return ret;
8a4949b7 400}
21b007b9 401
fe03d5ee
IL
402static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
403{
404 struct dvb_usb_device *d = i2c_get_adapdata(adap);
324ed533 405 int len, i, j, ret;
fe03d5ee
IL
406
407 if (!d)
408 return -ENODEV;
409 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
410 return -EAGAIN;
411
141cc35e
IL
412 for (j = 0; j < num; j++) {
413 switch (msg[j].addr) {
fe03d5ee
IL
414 case(DW2102_RC_QUERY): {
415 u8 ibuf[2];
d51dbecc 416 dw210x_op_rw(d->udev, 0xb8, 0, 0,
21b007b9 417 ibuf, 2, DW210X_READ_MSG);
141cc35e 418 memcpy(msg[j].buf, ibuf , 2);
fe03d5ee
IL
419 break;
420 }
421 case(DW2102_VOLTAGE_CTRL): {
422 u8 obuf[2];
423 obuf[0] = 0x30;
141cc35e 424 obuf[1] = msg[j].buf[0];
d51dbecc 425 dw210x_op_rw(d->udev, 0xb2, 0, 0,
21b007b9 426 obuf, 2, DW210X_WRITE_MSG);
fe03d5ee
IL
427 break;
428 }
141cc35e
IL
429 /*case 0x55: cx24116
430 case 0x6a: stv0903
431 case 0x68: ds3000, stv0903
432 case 0x60: ts2020, stv6110, stb6100 */
433 default: {
434 if (msg[j].flags == I2C_M_RD) {
435 /* read registers */
0065a79a
MCC
436 u8 ibuf[MAX_XFER_SIZE];
437
438 if (2 + msg[j].len > sizeof(ibuf)) {
439 warn("i2c rd: len=%d is too big!\n",
440 msg[j].len);
324ed533
DC
441 ret = -EOPNOTSUPP;
442 goto unlock;
0065a79a
MCC
443 }
444
d51dbecc 445 dw210x_op_rw(d->udev, 0xc3,
141cc35e
IL
446 (msg[j].addr << 1) + 1, 0,
447 ibuf, msg[j].len + 2,
448 DW210X_READ_MSG);
449 memcpy(msg[j].buf, ibuf + 2, msg[j].len);
48902bc7 450 mdelay(10);
141cc35e
IL
451 } else if (((msg[j].buf[0] == 0xb0) &&
452 (msg[j].addr == 0x68)) ||
453 ((msg[j].buf[0] == 0xf7) &&
454 (msg[j].addr == 0x55))) {
455 /* write firmware */
456 u8 obuf[19];
457 obuf[0] = msg[j].addr << 1;
458 obuf[1] = (msg[j].len > 15 ? 17 : msg[j].len);
459 obuf[2] = msg[j].buf[0];
460 len = msg[j].len - 1;
461 i = 1;
462 do {
463 memcpy(obuf + 3, msg[j].buf + i,
464 (len > 16 ? 16 : len));
d51dbecc 465 dw210x_op_rw(d->udev, 0xc2, 0, 0,
141cc35e
IL
466 obuf, (len > 16 ? 16 : len) + 3,
467 DW210X_WRITE_MSG);
468 i += 16;
469 len -= 16;
470 } while (len > 0);
471 } else {
472 /* write registers */
0065a79a
MCC
473 u8 obuf[MAX_XFER_SIZE];
474
475 if (2 + msg[j].len > sizeof(obuf)) {
476 warn("i2c wr: len=%d is too big!\n",
477 msg[j].len);
324ed533
DC
478 ret = -EOPNOTSUPP;
479 goto unlock;
0065a79a
MCC
480 }
481
141cc35e
IL
482 obuf[0] = msg[j].addr << 1;
483 obuf[1] = msg[j].len;
484 memcpy(obuf + 2, msg[j].buf, msg[j].len);
d51dbecc 485 dw210x_op_rw(d->udev, 0xc2, 0, 0,
141cc35e
IL
486 obuf, msg[j].len + 2,
487 DW210X_WRITE_MSG);
488 }
489 break;
490 }
fe03d5ee
IL
491 }
492
fe03d5ee 493 }
324ed533 494 ret = num;
fe03d5ee 495
324ed533 496unlock:
fe03d5ee 497 mutex_unlock(&d->i2c_mutex);
324ed533 498 return ret;
fe03d5ee
IL
499}
500
1dac77c9
IL
501static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
502 int num)
503{
504 struct dvb_usb_device *d = i2c_get_adapdata(adap);
324ed533 505 int ret;
d51dbecc 506 int i;
1dac77c9
IL
507
508 if (!d)
509 return -ENODEV;
510 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
511 return -EAGAIN;
512
513 switch (num) {
514 case 2: {
515 /* read */
516 /* first write first register number */
0065a79a
MCC
517 u8 ibuf[MAX_XFER_SIZE], obuf[3];
518
519 if (2 + msg[1].len > sizeof(ibuf)) {
520 warn("i2c rd: len=%d is too big!\n",
521 msg[1].len);
324ed533
DC
522 ret = -EOPNOTSUPP;
523 goto unlock;
0065a79a 524 }
1dac77c9
IL
525 obuf[0] = msg[0].addr << 1;
526 obuf[1] = msg[0].len;
527 obuf[2] = msg[0].buf[0];
d51dbecc 528 dw210x_op_rw(d->udev, 0xc2, 0, 0,
1dac77c9
IL
529 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
530 /* second read registers */
d51dbecc 531 dw210x_op_rw(d->udev, 0xc3, 0x19 , 0,
1dac77c9
IL
532 ibuf, msg[1].len + 2, DW210X_READ_MSG);
533 memcpy(msg[1].buf, ibuf + 2, msg[1].len);
534
535 break;
536 }
537 case 1:
538 switch (msg[0].addr) {
539 case 0x60:
540 case 0x0c: {
541 /* write to register */
0065a79a
MCC
542 u8 obuf[MAX_XFER_SIZE];
543
544 if (2 + msg[0].len > sizeof(obuf)) {
545 warn("i2c wr: len=%d is too big!\n",
546 msg[0].len);
324ed533
DC
547 ret = -EOPNOTSUPP;
548 goto unlock;
0065a79a 549 }
1dac77c9
IL
550 obuf[0] = msg[0].addr << 1;
551 obuf[1] = msg[0].len;
552 memcpy(obuf + 2, msg[0].buf, msg[0].len);
d51dbecc 553 dw210x_op_rw(d->udev, 0xc2, 0, 0,
1dac77c9
IL
554 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
555 break;
556 }
557 case(DW2102_RC_QUERY): {
558 u8 ibuf[2];
d51dbecc 559 dw210x_op_rw(d->udev, 0xb8, 0, 0,
1dac77c9
IL
560 ibuf, 2, DW210X_READ_MSG);
561 memcpy(msg[0].buf, ibuf , 2);
562 break;
563 }
564 }
565
566 break;
567 }
568
569 for (i = 0; i < num; i++) {
570 deb_xfer("%02x:%02x: %s ", i, msg[i].addr,
571 msg[i].flags == 0 ? ">>>" : "<<<");
572 debug_dump(msg[i].buf, msg[i].len, deb_xfer);
573 }
324ed533 574 ret = num;
1dac77c9 575
324ed533 576unlock:
1dac77c9 577 mutex_unlock(&d->i2c_mutex);
324ed533 578 return ret;
1dac77c9
IL
579}
580
141cc35e 581static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
d0a1ddad
IL
582 int num)
583{
584 struct dvb_usb_device *d = i2c_get_adapdata(adap);
21ead03b 585 struct usb_device *udev;
324ed533 586 int len, i, j, ret;
d0a1ddad
IL
587
588 if (!d)
589 return -ENODEV;
21ead03b 590 udev = d->udev;
d0a1ddad
IL
591 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
592 return -EAGAIN;
593
141cc35e
IL
594 for (j = 0; j < num; j++) {
595 switch (msg[j].addr) {
d0a1ddad 596 case (DW2102_RC_QUERY): {
5a530cbe 597 u8 ibuf[5];
d51dbecc 598 dw210x_op_rw(d->udev, 0xb8, 0, 0,
5a530cbe
IL
599 ibuf, 5, DW210X_READ_MSG);
600 memcpy(msg[j].buf, ibuf + 3, 2);
d0a1ddad
IL
601 break;
602 }
603 case (DW2102_VOLTAGE_CTRL): {
604 u8 obuf[2];
cd79d33e
IL
605
606 obuf[0] = 1;
607 obuf[1] = msg[j].buf[1];/* off-on */
d51dbecc 608 dw210x_op_rw(d->udev, 0x8a, 0, 0,
cd79d33e 609 obuf, 2, DW210X_WRITE_MSG);
141cc35e 610 obuf[0] = 3;
cd79d33e 611 obuf[1] = msg[j].buf[0];/* 13v-18v */
d51dbecc 612 dw210x_op_rw(d->udev, 0x8a, 0, 0,
d0a1ddad
IL
613 obuf, 2, DW210X_WRITE_MSG);
614 break;
615 }
fa8bae10
IL
616 case (DW2102_LED_CTRL): {
617 u8 obuf[2];
618
619 obuf[0] = 5;
620 obuf[1] = msg[j].buf[0];
d51dbecc 621 dw210x_op_rw(d->udev, 0x8a, 0, 0,
fa8bae10
IL
622 obuf, 2, DW210X_WRITE_MSG);
623 break;
624 }
141cc35e
IL
625 /*case 0x55: cx24116
626 case 0x6a: stv0903
955d00ac 627 case 0x68: ds3000, stv0903, rs2000
141cc35e
IL
628 case 0x60: ts2020, stv6110, stb6100
629 case 0xa0: eeprom */
630 default: {
631 if (msg[j].flags == I2C_M_RD) {
632 /* read registers */
0065a79a
MCC
633 u8 ibuf[MAX_XFER_SIZE];
634
635 if (msg[j].len > sizeof(ibuf)) {
636 warn("i2c rd: len=%d is too big!\n",
637 msg[j].len);
324ed533
DC
638 ret = -EOPNOTSUPP;
639 goto unlock;
0065a79a
MCC
640 }
641
d51dbecc 642 dw210x_op_rw(d->udev, 0x91, 0, 0,
141cc35e
IL
643 ibuf, msg[j].len,
644 DW210X_READ_MSG);
645 memcpy(msg[j].buf, ibuf, msg[j].len);
646 break;
647 } else if ((msg[j].buf[0] == 0xb0) &&
648 (msg[j].addr == 0x68)) {
649 /* write firmware */
650 u8 obuf[19];
651 obuf[0] = (msg[j].len > 16 ?
652 18 : msg[j].len + 1);
653 obuf[1] = msg[j].addr << 1;
654 obuf[2] = msg[j].buf[0];
655 len = msg[j].len - 1;
656 i = 1;
657 do {
658 memcpy(obuf + 3, msg[j].buf + i,
659 (len > 16 ? 16 : len));
d51dbecc 660 dw210x_op_rw(d->udev, 0x80, 0, 0,
141cc35e
IL
661 obuf, (len > 16 ? 16 : len) + 3,
662 DW210X_WRITE_MSG);
663 i += 16;
664 len -= 16;
665 } while (len > 0);
a84adf40 666 } else if (j < (num - 1)) {
cd79d33e 667 /* write register addr before read */
0065a79a
MCC
668 u8 obuf[MAX_XFER_SIZE];
669
670 if (2 + msg[j].len > sizeof(obuf)) {
671 warn("i2c wr: len=%d is too big!\n",
672 msg[j].len);
324ed533
DC
673 ret = -EOPNOTSUPP;
674 goto unlock;
0065a79a
MCC
675 }
676
cd79d33e
IL
677 obuf[0] = msg[j + 1].len;
678 obuf[1] = (msg[j].addr << 1);
679 memcpy(obuf + 2, msg[j].buf, msg[j].len);
d51dbecc 680 dw210x_op_rw(d->udev,
1ad5d064 681 le16_to_cpu(udev->descriptor.idProduct) ==
a84adf40 682 0x7500 ? 0x92 : 0x90, 0, 0,
cd79d33e
IL
683 obuf, msg[j].len + 2,
684 DW210X_WRITE_MSG);
685 break;
141cc35e
IL
686 } else {
687 /* write registers */
0065a79a
MCC
688 u8 obuf[MAX_XFER_SIZE];
689
690 if (2 + msg[j].len > sizeof(obuf)) {
691 warn("i2c wr: len=%d is too big!\n",
692 msg[j].len);
324ed533
DC
693 ret = -EOPNOTSUPP;
694 goto unlock;
0065a79a 695 }
141cc35e
IL
696 obuf[0] = msg[j].len + 1;
697 obuf[1] = (msg[j].addr << 1);
698 memcpy(obuf + 2, msg[j].buf, msg[j].len);
d51dbecc 699 dw210x_op_rw(d->udev, 0x80, 0, 0,
141cc35e
IL
700 obuf, msg[j].len + 2,
701 DW210X_WRITE_MSG);
702 break;
703 }
704 break;
705 }
d0a1ddad 706 }
d0a1ddad 707 }
324ed533 708 ret = num;
d0a1ddad 709
324ed533 710unlock:
d0a1ddad 711 mutex_unlock(&d->i2c_mutex);
324ed533 712 return ret;
d0a1ddad
IL
713}
714
d2ffc447
IL
715static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
716 int num)
717{
718 struct dvb_usb_device *d = i2c_get_adapdata(adap);
719 u8 obuf[0x40], ibuf[0x40];
720
721 if (!d)
722 return -ENODEV;
723 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
724 return -EAGAIN;
725
726 switch (num) {
727 case 1:
728 switch (msg[0].addr) {
729 case SU3000_STREAM_CTRL:
730 obuf[0] = msg[0].buf[0] + 0x36;
731 obuf[1] = 3;
732 obuf[2] = 0;
733 if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 0, 0) < 0)
734 err("i2c transfer failed.");
735 break;
736 case DW2102_RC_QUERY:
737 obuf[0] = 0x10;
738 if (dvb_usb_generic_rw(d, obuf, 1, ibuf, 2, 0) < 0)
739 err("i2c transfer failed.");
740 msg[0].buf[1] = ibuf[0];
741 msg[0].buf[0] = ibuf[1];
742 break;
743 default:
744 /* always i2c write*/
745 obuf[0] = 0x08;
746 obuf[1] = msg[0].addr;
747 obuf[2] = msg[0].len;
748
749 memcpy(&obuf[3], msg[0].buf, msg[0].len);
750
751 if (dvb_usb_generic_rw(d, obuf, msg[0].len + 3,
752 ibuf, 1, 0) < 0)
753 err("i2c transfer failed.");
754
755 }
756 break;
757 case 2:
758 /* always i2c read */
759 obuf[0] = 0x09;
760 obuf[1] = msg[0].len;
761 obuf[2] = msg[1].len;
762 obuf[3] = msg[0].addr;
763 memcpy(&obuf[4], msg[0].buf, msg[0].len);
764
765 if (dvb_usb_generic_rw(d, obuf, msg[0].len + 4,
766 ibuf, msg[1].len + 1, 0) < 0)
767 err("i2c transfer failed.");
768
769 memcpy(msg[1].buf, &ibuf[1], msg[1].len);
770 break;
771 default:
772 warn("more than 2 i2c messages at a time is not handled yet.");
773 break;
774 }
775 mutex_unlock(&d->i2c_mutex);
776 return num;
777}
778
21b007b9 779static u32 dw210x_i2c_func(struct i2c_adapter *adapter)
7fd4828f
IL
780{
781 return I2C_FUNC_I2C;
782}
783
784static struct i2c_algorithm dw2102_i2c_algo = {
785 .master_xfer = dw2102_i2c_transfer,
21b007b9
IL
786 .functionality = dw210x_i2c_func,
787};
788
789static struct i2c_algorithm dw2102_serit_i2c_algo = {
790 .master_xfer = dw2102_serit_i2c_transfer,
791 .functionality = dw210x_i2c_func,
7fd4828f
IL
792};
793
8a4949b7
IL
794static struct i2c_algorithm dw2102_earda_i2c_algo = {
795 .master_xfer = dw2102_earda_i2c_transfer,
796 .functionality = dw210x_i2c_func,
797};
798
fe03d5ee
IL
799static struct i2c_algorithm dw2104_i2c_algo = {
800 .master_xfer = dw2104_i2c_transfer,
21b007b9 801 .functionality = dw210x_i2c_func,
fe03d5ee
IL
802};
803
1dac77c9
IL
804static struct i2c_algorithm dw3101_i2c_algo = {
805 .master_xfer = dw3101_i2c_transfer,
806 .functionality = dw210x_i2c_func,
807};
808
141cc35e
IL
809static struct i2c_algorithm s6x0_i2c_algo = {
810 .master_xfer = s6x0_i2c_transfer,
d0a1ddad
IL
811 .functionality = dw210x_i2c_func,
812};
813
d2ffc447
IL
814static struct i2c_algorithm su3000_i2c_algo = {
815 .master_xfer = su3000_i2c_transfer,
816 .functionality = dw210x_i2c_func,
817};
818
21b007b9 819static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
fe03d5ee
IL
820{
821 int i;
822 u8 ibuf[] = {0, 0};
823 u8 eeprom[256], eepromline[16];
824
825 for (i = 0; i < 256; i++) {
21b007b9 826 if (dw210x_op_rw(d->udev, 0xb6, 0xa0 , i, ibuf, 2, DW210X_READ_MSG) < 0) {
fe03d5ee
IL
827 err("read eeprom failed.");
828 return -1;
829 } else {
830 eepromline[i%16] = ibuf[0];
831 eeprom[i] = ibuf[0];
832 }
833 if ((i % 16) == 15) {
834 deb_xfer("%02x: ", i - 15);
835 debug_dump(eepromline, 16, deb_xfer);
836 }
837 }
1dac77c9 838
fe03d5ee
IL
839 memcpy(mac, eeprom + 8, 6);
840 return 0;
841};
842
141cc35e 843static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
d0a1ddad
IL
844{
845 int i, ret;
141cc35e
IL
846 u8 ibuf[] = { 0 }, obuf[] = { 0 };
847 u8 eeprom[256], eepromline[16];
848 struct i2c_msg msg[] = {
849 {
850 .addr = 0xa0 >> 1,
851 .flags = 0,
852 .buf = obuf,
853 .len = 1,
854 }, {
855 .addr = 0xa0 >> 1,
856 .flags = I2C_M_RD,
857 .buf = ibuf,
858 .len = 1,
859 }
860 };
d0a1ddad
IL
861
862 for (i = 0; i < 256; i++) {
141cc35e
IL
863 obuf[0] = i;
864 ret = s6x0_i2c_transfer(&d->i2c_adap, msg, 2);
865 if (ret != 2) {
d0a1ddad
IL
866 err("read eeprom failed.");
867 return -1;
868 } else {
141cc35e
IL
869 eepromline[i % 16] = ibuf[0];
870 eeprom[i] = ibuf[0];
d0a1ddad
IL
871 }
872
873 if ((i % 16) == 15) {
874 deb_xfer("%02x: ", i - 15);
875 debug_dump(eepromline, 16, deb_xfer);
876 }
877 }
878
879 memcpy(mac, eeprom + 16, 6);
880 return 0;
881};
882
d2ffc447
IL
883static int su3000_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
884{
885 static u8 command_start[] = {0x00};
886 static u8 command_stop[] = {0x01};
887 struct i2c_msg msg = {
888 .addr = SU3000_STREAM_CTRL,
889 .flags = 0,
890 .buf = onoff ? command_start : command_stop,
891 .len = 1
892 };
893
894 i2c_transfer(&adap->dev->i2c_adap, &msg, 1);
895
896 return 0;
897}
898
899static int su3000_power_ctrl(struct dvb_usb_device *d, int i)
900{
2c4ffe27 901 struct dw2102_state *state = (struct dw2102_state *)d->priv;
d2ffc447
IL
902 u8 obuf[] = {0xde, 0};
903
904 info("%s: %d, initialized %d\n", __func__, i, state->initialized);
905
906 if (i && !state->initialized) {
907 state->initialized = 1;
908 /* reset board */
909 dvb_usb_generic_rw(d, obuf, 2, NULL, 0, 0);
910 }
911
912 return 0;
913}
914
915static int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
916{
917 int i;
918 u8 obuf[] = { 0x1f, 0xf0 };
919 u8 ibuf[] = { 0 };
920 struct i2c_msg msg[] = {
921 {
922 .addr = 0x51,
923 .flags = 0,
924 .buf = obuf,
925 .len = 2,
926 }, {
927 .addr = 0x51,
928 .flags = I2C_M_RD,
929 .buf = ibuf,
930 .len = 1,
931
932 }
933 };
934
935 for (i = 0; i < 6; i++) {
936 obuf[1] = 0xf0 + i;
937 if (i2c_transfer(&d->i2c_adap, msg, 2) != 2)
938 break;
939 else
940 mac[i] = ibuf[0];
d2ffc447
IL
941 }
942
943 return 0;
944}
945
946static int su3000_identify_state(struct usb_device *udev,
947 struct dvb_usb_device_properties *props,
948 struct dvb_usb_device_description **desc,
949 int *cold)
950{
951 info("%s\n", __func__);
952
953 *cold = 0;
954 return 0;
955}
956
0df289a2
MCC
957static int dw210x_set_voltage(struct dvb_frontend *fe,
958 enum fe_sec_voltage voltage)
7fd4828f 959{
cd79d33e
IL
960 static u8 command_13v[] = {0x00, 0x01};
961 static u8 command_18v[] = {0x01, 0x01};
962 static u8 command_off[] = {0x00, 0x00};
963 struct i2c_msg msg = {
964 .addr = DW2102_VOLTAGE_CTRL,
965 .flags = 0,
966 .buf = command_off,
967 .len = 2,
7fd4828f
IL
968 };
969
970 struct dvb_usb_adapter *udev_adap =
971 (struct dvb_usb_adapter *)(fe->dvb->priv);
972 if (voltage == SEC_VOLTAGE_18)
cd79d33e
IL
973 msg.buf = command_18v;
974 else if (voltage == SEC_VOLTAGE_13)
975 msg.buf = command_13v;
976
977 i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1);
978
7fd4828f
IL
979 return 0;
980}
981
0df289a2
MCC
982static int s660_set_voltage(struct dvb_frontend *fe,
983 enum fe_sec_voltage voltage)
52c506e0
IL
984{
985 struct dvb_usb_adapter *d =
986 (struct dvb_usb_adapter *)(fe->dvb->priv);
2c4ffe27 987 struct dw2102_state *st = (struct dw2102_state *)d->dev->priv;
52c506e0
IL
988
989 dw210x_set_voltage(fe, voltage);
990 if (st->old_set_voltage)
991 st->old_set_voltage(fe, voltage);
992
993 return 0;
994}
995
fa8bae10
IL
996static void dw210x_led_ctrl(struct dvb_frontend *fe, int offon)
997{
998 static u8 led_off[] = { 0 };
999 static u8 led_on[] = { 1 };
1000 struct i2c_msg msg = {
1001 .addr = DW2102_LED_CTRL,
1002 .flags = 0,
1003 .buf = led_off,
1004 .len = 1
1005 };
1006 struct dvb_usb_adapter *udev_adap =
1007 (struct dvb_usb_adapter *)(fe->dvb->priv);
1008
1009 if (offon)
1010 msg.buf = led_on;
1011 i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1);
1012}
1013
0df289a2
MCC
1014static int tt_s2_4600_read_status(struct dvb_frontend *fe,
1015 enum fe_status *status)
356484ca
OS
1016{
1017 struct dvb_usb_adapter *d =
1018 (struct dvb_usb_adapter *)(fe->dvb->priv);
1019 struct dw2102_state *st = (struct dw2102_state *)d->dev->priv;
1020 int ret;
1021
1022 ret = st->fe_read_status(fe, status);
1023
1024 /* resync slave fifo when signal change from unlock to lock */
1025 if ((*status & FE_HAS_LOCK) && (!st->last_lock))
1026 su3000_streaming_ctrl(d, 1);
1027
1028 st->last_lock = (*status & FE_HAS_LOCK) ? 1 : 0;
1029 return ret;
1030}
1031
d4305c68
IL
1032static struct stv0299_config sharp_z0194a_config = {
1033 .demod_address = 0x68,
1034 .inittab = sharp_z0194a_inittab,
1035 .mclk = 88000000UL,
1036 .invert = 1,
1037 .skip_reinit = 0,
1038 .lock_output = STV0299_LOCKOUTPUT_1,
1039 .volt13_op0_op1 = STV0299_VOLT13_OP1,
1040 .min_delay_ms = 100,
1041 .set_symbol_rate = sharp_z0194a_set_symbol_rate,
1042};
1043
fe03d5ee
IL
1044static struct cx24116_config dw2104_config = {
1045 .demod_address = 0x55,
cc8c4f3a 1046 .mpg_clk_pos_pol = 0x01,
fe03d5ee
IL
1047};
1048
21b007b9
IL
1049static struct si21xx_config serit_sp1511lhb_config = {
1050 .demod_address = 0x68,
1051 .min_delay_ms = 100,
1052
1053};
1054
1dac77c9
IL
1055static struct tda10023_config dw3101_tda10023_config = {
1056 .demod_address = 0x0c,
1057 .invert = 1,
1058};
1059
d0a1ddad
IL
1060static struct mt312_config zl313_config = {
1061 .demod_address = 0x0e,
1062};
1063
141cc35e
IL
1064static struct ds3000_config dw2104_ds3000_config = {
1065 .demod_address = 0x68,
1066};
1067
03a67279 1068static struct ts2020_config dw2104_ts2020_config = {
73f0af44 1069 .tuner_address = 0x60,
b858c331 1070 .clk_out_div = 1,
03a67279 1071 .frequency_div = 1060000,
73f0af44
KD
1072};
1073
43385c8a
IL
1074static struct ds3000_config s660_ds3000_config = {
1075 .demod_address = 0x68,
b858c331 1076 .ci_mode = 1,
43385c8a
IL
1077 .set_lock_led = dw210x_led_ctrl,
1078};
1079
03a67279
JH
1080static struct ts2020_config s660_ts2020_config = {
1081 .tuner_address = 0x60,
1082 .clk_out_div = 1,
1083 .frequency_div = 1146000,
1084};
1085
141cc35e
IL
1086static struct stv0900_config dw2104a_stv0900_config = {
1087 .demod_address = 0x6a,
1088 .demod_mode = 0,
1089 .xtal = 27000000,
1090 .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
1091 .diseqc_mode = 2,/* 2/3 PWM */
1092 .tun1_maddress = 0,/* 0x60 */
1093 .tun1_adc = 0,/* 2 Vpp */
1094 .path1_mode = 3,
1095};
1096
1097static struct stb6100_config dw2104a_stb6100_config = {
1098 .tuner_address = 0x60,
1099 .refclock = 27000000,
1100};
1101
1102static struct stv0900_config dw2104_stv0900_config = {
1103 .demod_address = 0x68,
1104 .demod_mode = 0,
1105 .xtal = 8000000,
1106 .clkmode = 3,
1107 .diseqc_mode = 2,
1108 .tun1_maddress = 0,
1109 .tun1_adc = 1,/* 1 Vpp */
1110 .path1_mode = 3,
1111};
1112
1113static struct stv6110_config dw2104_stv6110_config = {
1114 .i2c_address = 0x60,
1115 .mclk = 16000000,
1116 .clk_div = 1,
1117};
1118
cd79d33e
IL
1119static struct stv0900_config prof_7500_stv0900_config = {
1120 .demod_address = 0x6a,
1121 .demod_mode = 0,
1122 .xtal = 27000000,
1123 .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
1124 .diseqc_mode = 2,/* 2/3 PWM */
1125 .tun1_maddress = 0,/* 0x60 */
1126 .tun1_adc = 0,/* 2 Vpp */
1127 .path1_mode = 3,
1128 .tun1_type = 3,
fa8bae10 1129 .set_lock_led = dw210x_led_ctrl,
cd79d33e
IL
1130};
1131
d2ffc447
IL
1132static struct ds3000_config su3000_ds3000_config = {
1133 .demod_address = 0x68,
1134 .ci_mode = 1,
b858c331 1135 .set_lock_led = dw210x_led_ctrl,
73f0af44
KD
1136};
1137
51d882ed
EP
1138static struct cxd2820r_config cxd2820r_config = {
1139 .i2c_address = 0x6c, /* (0xd8 >> 1) */
1140 .ts_mode = 0x38,
7b71ef7e 1141 .ts_clock_inv = 1,
51d882ed
EP
1142};
1143
1144static struct tda18271_config tda18271_config = {
1145 .output_opt = TDA18271_OUTPUT_LT_OFF,
1146 .gate = TDA18271_GATE_DIGITAL,
1147};
1148
955d00ac
IL
1149static u8 m88rs2000_inittab[] = {
1150 DEMOD_WRITE, 0x9a, 0x30,
1151 DEMOD_WRITE, 0x00, 0x01,
1152 WRITE_DELAY, 0x19, 0x00,
1153 DEMOD_WRITE, 0x00, 0x00,
1154 DEMOD_WRITE, 0x9a, 0xb0,
1155 DEMOD_WRITE, 0x81, 0xc1,
955d00ac
IL
1156 DEMOD_WRITE, 0x81, 0x81,
1157 DEMOD_WRITE, 0x86, 0xc6,
1158 DEMOD_WRITE, 0x9a, 0x30,
1159 DEMOD_WRITE, 0xf0, 0x80,
1160 DEMOD_WRITE, 0xf1, 0xbf,
1161 DEMOD_WRITE, 0xb0, 0x45,
1162 DEMOD_WRITE, 0xb2, 0x01,
1163 DEMOD_WRITE, 0x9a, 0xb0,
1164 0xff, 0xaa, 0xff
1165};
1166
1167static struct m88rs2000_config s421_m88rs2000_config = {
1168 .demod_addr = 0x68,
955d00ac
IL
1169 .inittab = m88rs2000_inittab,
1170};
1171
fe03d5ee
IL
1172static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
1173{
141cc35e
IL
1174 struct dvb_tuner_ops *tuner_ops = NULL;
1175
1176 if (demod_probe & 4) {
77eed219 1177 d->fe_adap[0].fe = dvb_attach(stv0900_attach, &dw2104a_stv0900_config,
141cc35e 1178 &d->dev->i2c_adap, 0);
77eed219
MK
1179 if (d->fe_adap[0].fe != NULL) {
1180 if (dvb_attach(stb6100_attach, d->fe_adap[0].fe,
141cc35e
IL
1181 &dw2104a_stb6100_config,
1182 &d->dev->i2c_adap)) {
77eed219 1183 tuner_ops = &d->fe_adap[0].fe->ops.tuner_ops;
141cc35e
IL
1184 tuner_ops->set_frequency = stb6100_set_freq;
1185 tuner_ops->get_frequency = stb6100_get_freq;
1186 tuner_ops->set_bandwidth = stb6100_set_bandw;
1187 tuner_ops->get_bandwidth = stb6100_get_bandw;
77eed219 1188 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
141cc35e
IL
1189 info("Attached STV0900+STB6100!\n");
1190 return 0;
1191 }
1192 }
1193 }
1194
1195 if (demod_probe & 2) {
77eed219 1196 d->fe_adap[0].fe = dvb_attach(stv0900_attach, &dw2104_stv0900_config,
141cc35e 1197 &d->dev->i2c_adap, 0);
77eed219
MK
1198 if (d->fe_adap[0].fe != NULL) {
1199 if (dvb_attach(stv6110_attach, d->fe_adap[0].fe,
141cc35e
IL
1200 &dw2104_stv6110_config,
1201 &d->dev->i2c_adap)) {
77eed219 1202 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
141cc35e
IL
1203 info("Attached STV0900+STV6110A!\n");
1204 return 0;
1205 }
1206 }
1207 }
1208
1209 if (demod_probe & 1) {
77eed219 1210 d->fe_adap[0].fe = dvb_attach(cx24116_attach, &dw2104_config,
141cc35e 1211 &d->dev->i2c_adap);
77eed219
MK
1212 if (d->fe_adap[0].fe != NULL) {
1213 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
141cc35e
IL
1214 info("Attached cx24116!\n");
1215 return 0;
1216 }
1217 }
1218
77eed219 1219 d->fe_adap[0].fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
141cc35e 1220 &d->dev->i2c_adap);
77eed219 1221 if (d->fe_adap[0].fe != NULL) {
73f0af44
KD
1222 dvb_attach(ts2020_attach, d->fe_adap[0].fe,
1223 &dw2104_ts2020_config, &d->dev->i2c_adap);
77eed219 1224 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
141cc35e 1225 info("Attached DS3000!\n");
fe03d5ee
IL
1226 return 0;
1227 }
141cc35e 1228
fe03d5ee
IL
1229 return -EIO;
1230}
1231
21b007b9 1232static struct dvb_usb_device_properties dw2102_properties;
b42e1d71 1233static struct dvb_usb_device_properties dw2104_properties;
141cc35e 1234static struct dvb_usb_device_properties s6x0_properties;
21b007b9 1235
7fd4828f
IL
1236static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
1237{
21b007b9
IL
1238 if (dw2102_properties.i2c_algo == &dw2102_serit_i2c_algo) {
1239 /*dw2102_properties.adapter->tuner_attach = NULL;*/
77eed219 1240 d->fe_adap[0].fe = dvb_attach(si21xx_attach, &serit_sp1511lhb_config,
21b007b9 1241 &d->dev->i2c_adap);
77eed219
MK
1242 if (d->fe_adap[0].fe != NULL) {
1243 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
21b007b9
IL
1244 info("Attached si21xx!\n");
1245 return 0;
1246 }
1247 }
141cc35e 1248
8a4949b7 1249 if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) {
77eed219 1250 d->fe_adap[0].fe = dvb_attach(stv0288_attach, &earda_config,
8a4949b7 1251 &d->dev->i2c_adap);
77eed219
MK
1252 if (d->fe_adap[0].fe != NULL) {
1253 if (dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61,
141cc35e 1254 &d->dev->i2c_adap)) {
77eed219 1255 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
141cc35e
IL
1256 info("Attached stv0288!\n");
1257 return 0;
1258 }
8a4949b7
IL
1259 }
1260 }
1261
21b007b9
IL
1262 if (dw2102_properties.i2c_algo == &dw2102_i2c_algo) {
1263 /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/
77eed219 1264 d->fe_adap[0].fe = dvb_attach(stv0299_attach, &sharp_z0194a_config,
21b007b9 1265 &d->dev->i2c_adap);
77eed219
MK
1266 if (d->fe_adap[0].fe != NULL) {
1267 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
21b007b9
IL
1268 info("Attached stv0299!\n");
1269 return 0;
1270 }
7fd4828f
IL
1271 }
1272 return -EIO;
1273}
1274
1dac77c9
IL
1275static int dw3101_frontend_attach(struct dvb_usb_adapter *d)
1276{
77eed219 1277 d->fe_adap[0].fe = dvb_attach(tda10023_attach, &dw3101_tda10023_config,
1dac77c9 1278 &d->dev->i2c_adap, 0x48);
77eed219 1279 if (d->fe_adap[0].fe != NULL) {
1dac77c9
IL
1280 info("Attached tda10023!\n");
1281 return 0;
1282 }
1283 return -EIO;
1284}
1285
195288da 1286static int zl100313_frontend_attach(struct dvb_usb_adapter *d)
d0a1ddad 1287{
77eed219 1288 d->fe_adap[0].fe = dvb_attach(mt312_attach, &zl313_config,
141cc35e 1289 &d->dev->i2c_adap);
77eed219
MK
1290 if (d->fe_adap[0].fe != NULL) {
1291 if (dvb_attach(zl10039_attach, d->fe_adap[0].fe, 0x60,
141cc35e 1292 &d->dev->i2c_adap)) {
77eed219 1293 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
141cc35e
IL
1294 info("Attached zl100313+zl10039!\n");
1295 return 0;
1296 }
1297 }
1298
195288da
IL
1299 return -EIO;
1300}
1301
1302static int stv0288_frontend_attach(struct dvb_usb_adapter *d)
1303{
fd5466d1
IL
1304 u8 obuf[] = {7, 1};
1305
77eed219 1306 d->fe_adap[0].fe = dvb_attach(stv0288_attach, &earda_config,
141cc35e 1307 &d->dev->i2c_adap);
141cc35e 1308
77eed219 1309 if (d->fe_adap[0].fe == NULL)
fd5466d1
IL
1310 return -EIO;
1311
77eed219 1312 if (NULL == dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61, &d->dev->i2c_adap))
fd5466d1
IL
1313 return -EIO;
1314
77eed219 1315 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
fd5466d1
IL
1316
1317 dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
1318
1319 info("Attached stv0288+stb6000!\n");
1320
1321 return 0;
1322
195288da
IL
1323}
1324
1325static int ds3000_frontend_attach(struct dvb_usb_adapter *d)
1326{
2c4ffe27 1327 struct dw2102_state *st = d->dev->priv;
5a530cbe 1328 u8 obuf[] = {7, 1};
52c506e0 1329
43385c8a 1330 d->fe_adap[0].fe = dvb_attach(ds3000_attach, &s660_ds3000_config,
141cc35e 1331 &d->dev->i2c_adap);
141cc35e 1332
77eed219 1333 if (d->fe_adap[0].fe == NULL)
52c506e0
IL
1334 return -EIO;
1335
03a67279 1336 dvb_attach(ts2020_attach, d->fe_adap[0].fe, &s660_ts2020_config,
73f0af44
KD
1337 &d->dev->i2c_adap);
1338
77eed219
MK
1339 st->old_set_voltage = d->fe_adap[0].fe->ops.set_voltage;
1340 d->fe_adap[0].fe->ops.set_voltage = s660_set_voltage;
5a530cbe
IL
1341
1342 dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
1343
03a67279 1344 info("Attached ds3000+ts2020!\n");
52c506e0
IL
1345
1346 return 0;
d0a1ddad
IL
1347}
1348
cd79d33e
IL
1349static int prof_7500_frontend_attach(struct dvb_usb_adapter *d)
1350{
4e59df8f
IL
1351 u8 obuf[] = {7, 1};
1352
77eed219 1353 d->fe_adap[0].fe = dvb_attach(stv0900_attach, &prof_7500_stv0900_config,
cd79d33e 1354 &d->dev->i2c_adap, 0);
77eed219 1355 if (d->fe_adap[0].fe == NULL)
cd79d33e 1356 return -EIO;
4e59df8f 1357
77eed219 1358 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
cd79d33e 1359
4e59df8f
IL
1360 dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
1361
cd79d33e
IL
1362 info("Attached STV0900+STB6100A!\n");
1363
1364 return 0;
1365}
1366
d2ffc447
IL
1367static int su3000_frontend_attach(struct dvb_usb_adapter *d)
1368{
1369 u8 obuf[3] = { 0xe, 0x80, 0 };
1370 u8 ibuf[] = { 0 };
1371
1372 if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1373 err("command 0x0e transfer failed.");
1374
b858c331
IL
1375 obuf[0] = 0xe;
1376 obuf[1] = 0x02;
1377 obuf[2] = 1;
1378
1379 if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1380 err("command 0x0e transfer failed.");
1381 msleep(300);
1382
d2ffc447
IL
1383 obuf[0] = 0xe;
1384 obuf[1] = 0x83;
1385 obuf[2] = 0;
1386
1387 if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1388 err("command 0x0e transfer failed.");
1389
1390 obuf[0] = 0xe;
1391 obuf[1] = 0x83;
1392 obuf[2] = 1;
1393
1394 if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1395 err("command 0x0e transfer failed.");
1396
1397 obuf[0] = 0x51;
1398
1399 if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
1400 err("command 0x51 transfer failed.");
1401
77eed219 1402 d->fe_adap[0].fe = dvb_attach(ds3000_attach, &su3000_ds3000_config,
d2ffc447 1403 &d->dev->i2c_adap);
77eed219 1404 if (d->fe_adap[0].fe == NULL)
d2ffc447
IL
1405 return -EIO;
1406
b858c331
IL
1407 if (dvb_attach(ts2020_attach, d->fe_adap[0].fe,
1408 &dw2104_ts2020_config,
1409 &d->dev->i2c_adap)) {
1410 info("Attached DS3000/TS2020!\n");
1411 return 0;
1412 }
d2ffc447 1413
b858c331
IL
1414 info("Failed to attach DS3000/TS2020!\n");
1415 return -EIO;
d2ffc447
IL
1416}
1417
51d882ed
EP
1418static int t220_frontend_attach(struct dvb_usb_adapter *d)
1419{
7b71ef7e 1420 u8 obuf[3] = { 0xe, 0x87, 0 };
51d882ed
EP
1421 u8 ibuf[] = { 0 };
1422
1423 if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1424 err("command 0x0e transfer failed.");
1425
1426 obuf[0] = 0xe;
7b71ef7e
C
1427 obuf[1] = 0x86;
1428 obuf[2] = 1;
1429
1430 if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1431 err("command 0x0e transfer failed.");
1432
1433 obuf[0] = 0xe;
1434 obuf[1] = 0x80;
51d882ed
EP
1435 obuf[2] = 0;
1436
1437 if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1438 err("command 0x0e transfer failed.");
1439
7b71ef7e 1440 msleep(50);
51d882ed
EP
1441
1442 obuf[0] = 0xe;
1443 obuf[1] = 0x80;
1444 obuf[2] = 1;
1445
1446 if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1447 err("command 0x0e transfer failed.");
1448
1449 obuf[0] = 0x51;
1450
1451 if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
1452 err("command 0x51 transfer failed.");
1453
1454 d->fe_adap[0].fe = dvb_attach(cxd2820r_attach, &cxd2820r_config,
1455 &d->dev->i2c_adap, NULL);
1456 if (d->fe_adap[0].fe != NULL) {
1457 if (dvb_attach(tda18271_attach, d->fe_adap[0].fe, 0x60,
1458 &d->dev->i2c_adap, &tda18271_config)) {
1459 info("Attached TDA18271HD/CXD2820R!\n");
1460 return 0;
1461 }
1462 }
1463
1464 info("Failed to attach TDA18271HD/CXD2820R!\n");
1465 return -EIO;
1466}
1467
955d00ac
IL
1468static int m88rs2000_frontend_attach(struct dvb_usb_adapter *d)
1469{
1470 u8 obuf[] = { 0x51 };
1471 u8 ibuf[] = { 0 };
1472
1473 if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
1474 err("command 0x51 transfer failed.");
1475
1476 d->fe_adap[0].fe = dvb_attach(m88rs2000_attach, &s421_m88rs2000_config,
1477 &d->dev->i2c_adap);
b858c331 1478
955d00ac
IL
1479 if (d->fe_adap[0].fe == NULL)
1480 return -EIO;
1481
b858c331
IL
1482 if (dvb_attach(ts2020_attach, d->fe_adap[0].fe,
1483 &dw2104_ts2020_config,
1484 &d->dev->i2c_adap)) {
1485 info("Attached RS2000/TS2020!\n");
1486 return 0;
1487 }
955d00ac 1488
b858c331
IL
1489 info("Failed to attach RS2000/TS2020!\n");
1490 return -EIO;
955d00ac
IL
1491}
1492
27254c36
OS
1493static int tt_s2_4600_frontend_attach(struct dvb_usb_adapter *adap)
1494{
1495 struct dvb_usb_device *d = adap->dev;
1496 struct dw2102_state *state = d->priv;
1497 u8 obuf[3] = { 0xe, 0x80, 0 };
1498 u8 ibuf[] = { 0 };
1499 struct i2c_adapter *i2c_adapter;
1500 struct i2c_client *client;
f3c6abca
OS
1501 struct i2c_board_info board_info;
1502 struct m88ds3103_platform_data m88ds3103_pdata = {};
0fecb6c0 1503 struct ts2020_config ts2020_config = {};
27254c36
OS
1504
1505 if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 1, 0) < 0)
1506 err("command 0x0e transfer failed.");
1507
1508 obuf[0] = 0xe;
1509 obuf[1] = 0x02;
1510 obuf[2] = 1;
1511
1512 if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 1, 0) < 0)
1513 err("command 0x0e transfer failed.");
1514 msleep(300);
1515
1516 obuf[0] = 0xe;
1517 obuf[1] = 0x83;
1518 obuf[2] = 0;
1519
1520 if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 1, 0) < 0)
1521 err("command 0x0e transfer failed.");
1522
1523 obuf[0] = 0xe;
1524 obuf[1] = 0x83;
1525 obuf[2] = 1;
1526
1527 if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 1, 0) < 0)
1528 err("command 0x0e transfer failed.");
1529
1530 obuf[0] = 0x51;
1531
1532 if (dvb_usb_generic_rw(d, obuf, 1, ibuf, 1, 0) < 0)
1533 err("command 0x51 transfer failed.");
1534
f3c6abca
OS
1535 /* attach demod */
1536 m88ds3103_pdata.clk = 27000000;
1537 m88ds3103_pdata.i2c_wr_max = 33;
1538 m88ds3103_pdata.ts_mode = M88DS3103_TS_CI;
1539 m88ds3103_pdata.ts_clk = 16000;
1540 m88ds3103_pdata.ts_clk_pol = 0;
1541 m88ds3103_pdata.spec_inv = 0;
1542 m88ds3103_pdata.agc = 0x99;
1543 m88ds3103_pdata.agc_inv = 0;
1544 m88ds3103_pdata.clk_out = M88DS3103_CLOCK_OUT_ENABLED;
1545 m88ds3103_pdata.envelope_mode = 0;
1546 m88ds3103_pdata.lnb_hv_pol = 1;
1547 m88ds3103_pdata.lnb_en_pol = 0;
1548 memset(&board_info, 0, sizeof(board_info));
1549 strlcpy(board_info.type, "m88ds3103", I2C_NAME_SIZE);
1550 board_info.addr = 0x68;
1551 board_info.platform_data = &m88ds3103_pdata;
1552 request_module("m88ds3103");
1553 client = i2c_new_device(&d->i2c_adap, &board_info);
1554 if (client == NULL || client->dev.driver == NULL)
27254c36 1555 return -ENODEV;
f3c6abca
OS
1556 if (!try_module_get(client->dev.driver->owner)) {
1557 i2c_unregister_device(client);
1558 return -ENODEV;
1559 }
1560 adap->fe_adap[0].fe = m88ds3103_pdata.get_dvb_frontend(client);
1561 i2c_adapter = m88ds3103_pdata.get_i2c_adapter(client);
1562
1563 state->i2c_client_demod = client;
27254c36
OS
1564
1565 /* attach tuner */
0fecb6c0 1566 ts2020_config.fe = adap->fe_adap[0].fe;
f3c6abca
OS
1567 memset(&board_info, 0, sizeof(board_info));
1568 strlcpy(board_info.type, "ts2022", I2C_NAME_SIZE);
1569 board_info.addr = 0x60;
1570 board_info.platform_data = &ts2020_config;
0fecb6c0 1571 request_module("ts2020");
f3c6abca 1572 client = i2c_new_device(i2c_adapter, &board_info);
27254c36
OS
1573
1574 if (client == NULL || client->dev.driver == NULL) {
1575 dvb_frontend_detach(adap->fe_adap[0].fe);
1576 return -ENODEV;
1577 }
1578
1579 if (!try_module_get(client->dev.driver->owner)) {
1580 i2c_unregister_device(client);
1581 dvb_frontend_detach(adap->fe_adap[0].fe);
1582 return -ENODEV;
1583 }
1584
1585 /* delegate signal strength measurement to tuner */
1586 adap->fe_adap[0].fe->ops.read_signal_strength =
1587 adap->fe_adap[0].fe->ops.tuner_ops.get_rf_strength;
1588
1589 state->i2c_client_tuner = client;
1590
356484ca
OS
1591 /* hook fe: need to resync the slave fifo when signal locks */
1592 state->fe_read_status = adap->fe_adap[0].fe->ops.read_status;
1593 adap->fe_adap[0].fe->ops.read_status = tt_s2_4600_read_status;
1594
1595 state->last_lock = 0;
1596
27254c36
OS
1597 return 0;
1598}
1599
7fd4828f
IL
1600static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
1601{
77eed219 1602 dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60,
7fd4828f
IL
1603 &adap->dev->i2c_adap, DVB_PLL_OPERA1);
1604 return 0;
1605}
1606
1dac77c9
IL
1607static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
1608{
77eed219 1609 dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60,
1dac77c9
IL
1610 &adap->dev->i2c_adap, DVB_PLL_TUA6034);
1611
1612 return 0;
1613}
1614
a49de26a
EP
1615static int dw2102_rc_query(struct dvb_usb_device *d)
1616{
1617 u8 key[2];
1618 struct i2c_msg msg = {
1619 .addr = DW2102_RC_QUERY,
1620 .flags = I2C_M_RD,
1621 .buf = key,
1622 .len = 2
1623 };
7fd4828f 1624
a49de26a
EP
1625 if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
1626 if (msg.buf[0] != 0xff) {
1627 deb_rc("%s: rc code: %x, %x\n",
1628 __func__, key[0], key[1]);
120703f9 1629 rc_keydown(d->rc_dev, RC_TYPE_UNKNOWN, key[0], 0);
a49de26a
EP
1630 }
1631 }
d2ffc447 1632
a49de26a
EP
1633 return 0;
1634}
7fd4828f 1635
a49de26a 1636static int prof_rc_query(struct dvb_usb_device *d)
7fd4828f 1637{
7fd4828f 1638 u8 key[2];
8a8dad71
IL
1639 struct i2c_msg msg = {
1640 .addr = DW2102_RC_QUERY,
1641 .flags = I2C_M_RD,
1642 .buf = key,
1643 .len = 2
7fd4828f 1644 };
8a8dad71 1645
a49de26a
EP
1646 if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
1647 if (msg.buf[0] != 0xff) {
1648 deb_rc("%s: rc code: %x, %x\n",
1649 __func__, key[0], key[1]);
120703f9 1650 rc_keydown(d->rc_dev, RC_TYPE_UNKNOWN, key[0]^0xff, 0);
7fd4828f 1651 }
a49de26a 1652 }
8a8dad71 1653
a49de26a
EP
1654 return 0;
1655}
1656
1657static int su3000_rc_query(struct dvb_usb_device *d)
1658{
1659 u8 key[2];
1660 struct i2c_msg msg = {
1661 .addr = DW2102_RC_QUERY,
1662 .flags = I2C_M_RD,
1663 .buf = key,
1664 .len = 2
1665 };
8a8dad71 1666
a49de26a
EP
1667 if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
1668 if (msg.buf[0] != 0xff) {
1669 deb_rc("%s: rc code: %x, %x\n",
1670 __func__, key[0], key[1]);
120703f9
DH
1671 rc_keydown(d->rc_dev, RC_TYPE_RC5,
1672 RC_SCANCODE_RC5(key[1], key[0]), 0);
a49de26a 1673 }
7fd4828f 1674 }
8a8dad71 1675
7fd4828f
IL
1676 return 0;
1677}
1678
27351b13
JN
1679enum dw2102_table_entry {
1680 CYPRESS_DW2102,
1681 CYPRESS_DW2101,
1682 CYPRESS_DW2104,
1683 TEVII_S650,
1684 TERRATEC_CINERGY_S,
1685 CYPRESS_DW3101,
1686 TEVII_S630,
1687 PROF_1100,
1688 TEVII_S660,
1689 PROF_7500,
1690 GENIATECH_SU3000,
1691 TERRATEC_CINERGY_S2,
1692 TEVII_S480_1,
1693 TEVII_S480_2,
1694 X3M_SPC1400HD,
955d00ac
IL
1695 TEVII_S421,
1696 TEVII_S632,
44122dd6 1697 TERRATEC_CINERGY_S2_R2,
f08e9f0d 1698 GOTVIEW_SAT_HD,
51d882ed 1699 GENIATECH_T220,
27254c36 1700 TECHNOTREND_S2_4600,
44767fc4
OS
1701 TEVII_S482_1,
1702 TEVII_S482_2,
93b66420 1703 TERRATEC_CINERGY_S2_BOX,
6ede20f9 1704 TEVII_S662
27351b13
JN
1705};
1706
7fd4828f 1707static struct usb_device_id dw2102_table[] = {
27351b13
JN
1708 [CYPRESS_DW2102] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)},
1709 [CYPRESS_DW2101] = {USB_DEVICE(USB_VID_CYPRESS, 0x2101)},
1710 [CYPRESS_DW2104] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2104)},
1711 [TEVII_S650] = {USB_DEVICE(0x9022, USB_PID_TEVII_S650)},
1712 [TERRATEC_CINERGY_S] = {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)},
1713 [CYPRESS_DW3101] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)},
1714 [TEVII_S630] = {USB_DEVICE(0x9022, USB_PID_TEVII_S630)},
1715 [PROF_1100] = {USB_DEVICE(0x3011, USB_PID_PROF_1100)},
1716 [TEVII_S660] = {USB_DEVICE(0x9022, USB_PID_TEVII_S660)},
1717 [PROF_7500] = {USB_DEVICE(0x3034, 0x7500)},
1718 [GENIATECH_SU3000] = {USB_DEVICE(0x1f4d, 0x3000)},
a561d768 1719 [TERRATEC_CINERGY_S2] = {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_S2_R1)},
27351b13
JN
1720 [TEVII_S480_1] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_1)},
1721 [TEVII_S480_2] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)},
1722 [X3M_SPC1400HD] = {USB_DEVICE(0x1f4d, 0x3100)},
955d00ac
IL
1723 [TEVII_S421] = {USB_DEVICE(0x9022, USB_PID_TEVII_S421)},
1724 [TEVII_S632] = {USB_DEVICE(0x9022, USB_PID_TEVII_S632)},
a561d768 1725 [TERRATEC_CINERGY_S2_R2] = {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_S2_R2)},
f08e9f0d 1726 [GOTVIEW_SAT_HD] = {USB_DEVICE(0x1FE1, USB_PID_GOTVIEW_SAT_HD)},
51d882ed 1727 [GENIATECH_T220] = {USB_DEVICE(0x1f4d, 0xD220)},
27254c36
OS
1728 [TECHNOTREND_S2_4600] = {USB_DEVICE(USB_VID_TECHNOTREND,
1729 USB_PID_TECHNOTREND_CONNECT_S2_4600)},
44767fc4
OS
1730 [TEVII_S482_1] = {USB_DEVICE(0x9022, 0xd483)},
1731 [TEVII_S482_2] = {USB_DEVICE(0x9022, 0xd484)},
93b66420 1732 [TERRATEC_CINERGY_S2_BOX] = {USB_DEVICE(USB_VID_TERRATEC, 0x0105)},
6ede20f9 1733 [TEVII_S662] = {USB_DEVICE(0x9022, USB_PID_TEVII_S662)},
7fd4828f
IL
1734 { }
1735};
1736
1737MODULE_DEVICE_TABLE(usb, dw2102_table);
1738
1739static int dw2102_load_firmware(struct usb_device *dev,
1740 const struct firmware *frmwr)
1741{
1742 u8 *b, *p;
1743 int ret = 0, i;
1744 u8 reset;
8a4949b7 1745 u8 reset16[] = {0, 0, 0, 0, 0, 0, 0};
7fd4828f 1746 const struct firmware *fw;
d0a1ddad 1747
1ad5d064 1748 switch (le16_to_cpu(dev->descriptor.idProduct)) {
7fd4828f 1749 case 0x2101:
6823627b 1750 ret = request_firmware(&fw, DW2101_FIRMWARE, &dev->dev);
7fd4828f 1751 if (ret != 0) {
6823627b 1752 err(err_str, DW2101_FIRMWARE);
7fd4828f
IL
1753 return ret;
1754 }
1755 break;
fe03d5ee 1756 default:
7fd4828f
IL
1757 fw = frmwr;
1758 break;
1759 }
fe03d5ee 1760 info("start downloading DW210X firmware");
7fd4828f
IL
1761 p = kmalloc(fw->size, GFP_KERNEL);
1762 reset = 1;
1763 /*stop the CPU*/
21b007b9
IL
1764 dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, DW210X_WRITE_MSG);
1765 dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, DW210X_WRITE_MSG);
7fd4828f
IL
1766
1767 if (p != NULL) {
1768 memcpy(p, fw->data, fw->size);
1769 for (i = 0; i < fw->size; i += 0x40) {
1770 b = (u8 *) p + i;
21b007b9
IL
1771 if (dw210x_op_rw(dev, 0xa0, i, 0, b , 0x40,
1772 DW210X_WRITE_MSG) != 0x40) {
7fd4828f
IL
1773 err("error while transferring firmware");
1774 ret = -EINVAL;
1775 break;
1776 }
1777 }
1778 /* restart the CPU */
1779 reset = 0;
21b007b9
IL
1780 if (ret || dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1,
1781 DW210X_WRITE_MSG) != 1) {
7fd4828f
IL
1782 err("could not restart the USB controller CPU.");
1783 ret = -EINVAL;
1784 }
21b007b9
IL
1785 if (ret || dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1,
1786 DW210X_WRITE_MSG) != 1) {
7fd4828f
IL
1787 err("could not restart the USB controller CPU.");
1788 ret = -EINVAL;
1789 }
1790 /* init registers */
1ad5d064 1791 switch (le16_to_cpu(dev->descriptor.idProduct)) {
1dac77c9 1792 case USB_PID_TEVII_S650:
a49de26a 1793 dw2104_properties.rc.core.rc_codes = RC_MAP_TEVII_NEC;
b42e1d71 1794 case USB_PID_DW2104:
fe03d5ee 1795 reset = 1;
21b007b9
IL
1796 dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1,
1797 DW210X_WRITE_MSG);
1dac77c9
IL
1798 /* break omitted intentionally */
1799 case USB_PID_DW3101:
fe03d5ee 1800 reset = 0;
21b007b9
IL
1801 dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
1802 DW210X_WRITE_MSG);
fe03d5ee 1803 break;
4cc0edff 1804 case USB_PID_CINERGY_S:
7fd4828f 1805 case USB_PID_DW2102:
21b007b9
IL
1806 dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
1807 DW210X_WRITE_MSG);
1808 dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
1809 DW210X_READ_MSG);
1810 /* check STV0299 frontend */
1811 dw210x_op_rw(dev, 0xb5, 0, 0, &reset16[0], 2,
1812 DW210X_READ_MSG);
ea023df5 1813 if ((reset16[0] == 0xa1) || (reset16[0] == 0x80)) {
21b007b9 1814 dw2102_properties.i2c_algo = &dw2102_i2c_algo;
77eed219 1815 dw2102_properties.adapter->fe[0].tuner_attach = &dw2102_tuner_attach;
8a4949b7
IL
1816 break;
1817 } else {
1818 /* check STV0288 frontend */
1819 reset16[0] = 0xd0;
1820 reset16[1] = 1;
1821 reset16[2] = 0;
1822 dw210x_op_rw(dev, 0xc2, 0, 0, &reset16[0], 3,
1823 DW210X_WRITE_MSG);
1824 dw210x_op_rw(dev, 0xc3, 0xd1, 0, &reset16[0], 3,
1825 DW210X_READ_MSG);
1826 if (reset16[2] == 0x11) {
1827 dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo;
8a4949b7
IL
1828 break;
1829 }
1830 }
7fd4828f 1831 case 0x2101:
21b007b9
IL
1832 dw210x_op_rw(dev, 0xbc, 0x0030, 0, &reset16[0], 2,
1833 DW210X_READ_MSG);
1834 dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
1835 DW210X_READ_MSG);
1836 dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
1837 DW210X_READ_MSG);
1838 dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
1839 DW210X_READ_MSG);
7fd4828f
IL
1840 break;
1841 }
1dac77c9 1842
fe03d5ee 1843 msleep(100);
7fd4828f
IL
1844 kfree(p);
1845 }
1846 return ret;
1847}
1848
1849static struct dvb_usb_device_properties dw2102_properties = {
1850 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1851 .usb_ctrl = DEVICE_SPECIFIC,
6823627b 1852 .firmware = DW2102_FIRMWARE,
7fd4828f
IL
1853 .no_reconnect = 1,
1854
21b007b9 1855 .i2c_algo = &dw2102_serit_i2c_algo,
f72a27b8 1856
a49de26a 1857 .rc.core = {
f72a27b8 1858 .rc_interval = 150,
a49de26a
EP
1859 .rc_codes = RC_MAP_DM1105_NEC,
1860 .module_name = "dw2102",
1861 .allowed_protos = RC_BIT_NEC,
f72a27b8
MCC
1862 .rc_query = dw2102_rc_query,
1863 },
7fd4828f
IL
1864
1865 .generic_bulk_ctrl_endpoint = 0x81,
1866 /* parameter for the MPEG2-data transfer */
1867 .num_adapters = 1,
1868 .download_firmware = dw2102_load_firmware,
21b007b9 1869 .read_mac_address = dw210x_read_mac_address,
1dac77c9 1870 .adapter = {
7fd4828f 1871 {
77eed219
MK
1872 .num_frontends = 1,
1873 .fe = {{
7fd4828f 1874 .frontend_attach = dw2102_frontend_attach,
7fd4828f
IL
1875 .stream = {
1876 .type = USB_BULK,
1877 .count = 8,
1878 .endpoint = 0x82,
1879 .u = {
1880 .bulk = {
1881 .buffersize = 4096,
1882 }
1883 }
1884 },
77eed219 1885 }},
7fd4828f
IL
1886 }
1887 },
4cc0edff 1888 .num_device_descs = 3,
7fd4828f
IL
1889 .devices = {
1890 {"DVBWorld DVB-S 2102 USB2.0",
27351b13 1891 {&dw2102_table[CYPRESS_DW2102], NULL},
7fd4828f
IL
1892 {NULL},
1893 },
1894 {"DVBWorld DVB-S 2101 USB2.0",
27351b13 1895 {&dw2102_table[CYPRESS_DW2101], NULL},
7fd4828f 1896 {NULL},
4cc0edff
IL
1897 },
1898 {"TerraTec Cinergy S USB",
27351b13 1899 {&dw2102_table[TERRATEC_CINERGY_S], NULL},
4cc0edff 1900 {NULL},
7fd4828f
IL
1901 },
1902 }
1903};
1904
fe03d5ee
IL
1905static struct dvb_usb_device_properties dw2104_properties = {
1906 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1907 .usb_ctrl = DEVICE_SPECIFIC,
6823627b 1908 .firmware = DW2104_FIRMWARE,
fe03d5ee
IL
1909 .no_reconnect = 1,
1910
1911 .i2c_algo = &dw2104_i2c_algo,
a49de26a 1912 .rc.core = {
f72a27b8 1913 .rc_interval = 150,
a49de26a
EP
1914 .rc_codes = RC_MAP_DM1105_NEC,
1915 .module_name = "dw2102",
1916 .allowed_protos = RC_BIT_NEC,
f72a27b8
MCC
1917 .rc_query = dw2102_rc_query,
1918 },
fe03d5ee
IL
1919
1920 .generic_bulk_ctrl_endpoint = 0x81,
1921 /* parameter for the MPEG2-data transfer */
1922 .num_adapters = 1,
1923 .download_firmware = dw2102_load_firmware,
21b007b9 1924 .read_mac_address = dw210x_read_mac_address,
fe03d5ee
IL
1925 .adapter = {
1926 {
77eed219
MK
1927 .num_frontends = 1,
1928 .fe = {{
fe03d5ee 1929 .frontend_attach = dw2104_frontend_attach,
fe03d5ee
IL
1930 .stream = {
1931 .type = USB_BULK,
1932 .count = 8,
1933 .endpoint = 0x82,
1934 .u = {
1935 .bulk = {
1936 .buffersize = 4096,
1937 }
1938 }
1939 },
77eed219 1940 }},
fe03d5ee
IL
1941 }
1942 },
1943 .num_device_descs = 2,
1944 .devices = {
1945 { "DVBWorld DW2104 USB2.0",
27351b13 1946 {&dw2102_table[CYPRESS_DW2104], NULL},
fe03d5ee
IL
1947 {NULL},
1948 },
1949 { "TeVii S650 USB2.0",
27351b13 1950 {&dw2102_table[TEVII_S650], NULL},
fe03d5ee
IL
1951 {NULL},
1952 },
1953 }
1954};
1955
1dac77c9
IL
1956static struct dvb_usb_device_properties dw3101_properties = {
1957 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1958 .usb_ctrl = DEVICE_SPECIFIC,
6823627b 1959 .firmware = DW3101_FIRMWARE,
1dac77c9
IL
1960 .no_reconnect = 1,
1961
1962 .i2c_algo = &dw3101_i2c_algo,
a49de26a 1963 .rc.core = {
f72a27b8 1964 .rc_interval = 150,
a49de26a
EP
1965 .rc_codes = RC_MAP_DM1105_NEC,
1966 .module_name = "dw2102",
1967 .allowed_protos = RC_BIT_NEC,
f72a27b8
MCC
1968 .rc_query = dw2102_rc_query,
1969 },
1dac77c9
IL
1970
1971 .generic_bulk_ctrl_endpoint = 0x81,
1972 /* parameter for the MPEG2-data transfer */
1973 .num_adapters = 1,
1974 .download_firmware = dw2102_load_firmware,
1975 .read_mac_address = dw210x_read_mac_address,
1976 .adapter = {
1977 {
77eed219
MK
1978 .num_frontends = 1,
1979 .fe = {{
1dac77c9 1980 .frontend_attach = dw3101_frontend_attach,
1dac77c9
IL
1981 .tuner_attach = dw3101_tuner_attach,
1982 .stream = {
1983 .type = USB_BULK,
1984 .count = 8,
1985 .endpoint = 0x82,
1986 .u = {
1987 .bulk = {
1988 .buffersize = 4096,
1989 }
1990 }
1991 },
77eed219 1992 }},
1dac77c9
IL
1993 }
1994 },
1995 .num_device_descs = 1,
1996 .devices = {
1997 { "DVBWorld DVB-C 3101 USB2.0",
27351b13 1998 {&dw2102_table[CYPRESS_DW3101], NULL},
1dac77c9
IL
1999 {NULL},
2000 },
2001 }
2002};
2003
141cc35e 2004static struct dvb_usb_device_properties s6x0_properties = {
d0a1ddad
IL
2005 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
2006 .usb_ctrl = DEVICE_SPECIFIC,
2c4ffe27 2007 .size_of_priv = sizeof(struct dw2102_state),
6823627b 2008 .firmware = S630_FIRMWARE,
d0a1ddad
IL
2009 .no_reconnect = 1,
2010
141cc35e 2011 .i2c_algo = &s6x0_i2c_algo,
a49de26a 2012 .rc.core = {
f72a27b8 2013 .rc_interval = 150,
a49de26a
EP
2014 .rc_codes = RC_MAP_TEVII_NEC,
2015 .module_name = "dw2102",
2016 .allowed_protos = RC_BIT_NEC,
f72a27b8
MCC
2017 .rc_query = dw2102_rc_query,
2018 },
d0a1ddad
IL
2019
2020 .generic_bulk_ctrl_endpoint = 0x81,
2021 .num_adapters = 1,
2022 .download_firmware = dw2102_load_firmware,
141cc35e 2023 .read_mac_address = s6x0_read_mac_address,
d0a1ddad
IL
2024 .adapter = {
2025 {
77eed219
MK
2026 .num_frontends = 1,
2027 .fe = {{
195288da 2028 .frontend_attach = zl100313_frontend_attach,
d0a1ddad
IL
2029 .stream = {
2030 .type = USB_BULK,
2031 .count = 8,
2032 .endpoint = 0x82,
2033 .u = {
2034 .bulk = {
2035 .buffersize = 4096,
2036 }
2037 }
2038 },
77eed219 2039 }},
d0a1ddad
IL
2040 }
2041 },
195288da 2042 .num_device_descs = 1,
d0a1ddad
IL
2043 .devices = {
2044 {"TeVii S630 USB",
27351b13 2045 {&dw2102_table[TEVII_S630], NULL},
d0a1ddad
IL
2046 {NULL},
2047 },
2048 }
2049};
2050
1ad5d064 2051static struct dvb_usb_device_properties *p1100;
195288da
IL
2052static struct dvb_usb_device_description d1100 = {
2053 "Prof 1100 USB ",
27351b13 2054 {&dw2102_table[PROF_1100], NULL},
195288da
IL
2055 {NULL},
2056};
2057
1ad5d064 2058static struct dvb_usb_device_properties *s660;
195288da
IL
2059static struct dvb_usb_device_description d660 = {
2060 "TeVii S660 USB",
27351b13 2061 {&dw2102_table[TEVII_S660], NULL},
195288da
IL
2062 {NULL},
2063};
2064
e8f5055a
IL
2065static struct dvb_usb_device_description d480_1 = {
2066 "TeVii S480.1 USB",
27351b13 2067 {&dw2102_table[TEVII_S480_1], NULL},
e8f5055a
IL
2068 {NULL},
2069};
2070
2071static struct dvb_usb_device_description d480_2 = {
2072 "TeVii S480.2 USB",
27351b13 2073 {&dw2102_table[TEVII_S480_2], NULL},
e8f5055a
IL
2074 {NULL},
2075};
2076
1ad5d064 2077static struct dvb_usb_device_properties *p7500;
cd79d33e
IL
2078static struct dvb_usb_device_description d7500 = {
2079 "Prof 7500 USB DVB-S2",
27351b13 2080 {&dw2102_table[PROF_7500], NULL},
cd79d33e
IL
2081 {NULL},
2082};
2083
1ad5d064 2084static struct dvb_usb_device_properties *s421;
955d00ac
IL
2085static struct dvb_usb_device_description d421 = {
2086 "TeVii S421 PCI",
2087 {&dw2102_table[TEVII_S421], NULL},
2088 {NULL},
2089};
2090
2091static struct dvb_usb_device_description d632 = {
2092 "TeVii S632 USB",
2093 {&dw2102_table[TEVII_S632], NULL},
2094 {NULL},
2095};
2096
d2ffc447
IL
2097static struct dvb_usb_device_properties su3000_properties = {
2098 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
2099 .usb_ctrl = DEVICE_SPECIFIC,
2c4ffe27 2100 .size_of_priv = sizeof(struct dw2102_state),
d2ffc447
IL
2101 .power_ctrl = su3000_power_ctrl,
2102 .num_adapters = 1,
2103 .identify_state = su3000_identify_state,
2104 .i2c_algo = &su3000_i2c_algo,
2105
a49de26a 2106 .rc.core = {
d2ffc447 2107 .rc_interval = 150,
a49de26a
EP
2108 .rc_codes = RC_MAP_SU3000,
2109 .module_name = "dw2102",
2110 .allowed_protos = RC_BIT_RC5,
2111 .rc_query = su3000_rc_query,
d2ffc447
IL
2112 },
2113
2114 .read_mac_address = su3000_read_mac_address,
2115
2116 .generic_bulk_ctrl_endpoint = 0x01,
2117
2118 .adapter = {
2119 {
77eed219
MK
2120 .num_frontends = 1,
2121 .fe = {{
d2ffc447
IL
2122 .streaming_ctrl = su3000_streaming_ctrl,
2123 .frontend_attach = su3000_frontend_attach,
2124 .stream = {
2125 .type = USB_BULK,
2126 .count = 8,
2127 .endpoint = 0x82,
2128 .u = {
2129 .bulk = {
2130 .buffersize = 4096,
2131 }
2132 }
2133 }
77eed219 2134 }},
d2ffc447
IL
2135 }
2136 },
f08e9f0d 2137 .num_device_descs = 5,
d2ffc447
IL
2138 .devices = {
2139 { "SU3000HD DVB-S USB2.0",
27351b13 2140 { &dw2102_table[GENIATECH_SU3000], NULL },
d2ffc447
IL
2141 { NULL },
2142 },
2adc591f 2143 { "Terratec Cinergy S2 USB HD",
27351b13 2144 { &dw2102_table[TERRATEC_CINERGY_S2], NULL },
2adc591f
IL
2145 { NULL },
2146 },
5265ea54 2147 { "X3M TV SPC1400HD PCI",
27351b13 2148 { &dw2102_table[X3M_SPC1400HD], NULL },
5265ea54
IL
2149 { NULL },
2150 },
44122dd6
IL
2151 { "Terratec Cinergy S2 USB HD Rev.2",
2152 { &dw2102_table[TERRATEC_CINERGY_S2_R2], NULL },
2153 { NULL },
2154 },
f08e9f0d
AP
2155 { "GOTVIEW Satellite HD",
2156 { &dw2102_table[GOTVIEW_SAT_HD], NULL },
2157 { NULL },
2158 },
d2ffc447
IL
2159 }
2160};
2161
51d882ed
EP
2162static struct dvb_usb_device_properties t220_properties = {
2163 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
2164 .usb_ctrl = DEVICE_SPECIFIC,
2c4ffe27 2165 .size_of_priv = sizeof(struct dw2102_state),
51d882ed
EP
2166 .power_ctrl = su3000_power_ctrl,
2167 .num_adapters = 1,
2168 .identify_state = su3000_identify_state,
2169 .i2c_algo = &su3000_i2c_algo,
2170
a49de26a 2171 .rc.core = {
51d882ed 2172 .rc_interval = 150,
a49de26a
EP
2173 .rc_codes = RC_MAP_SU3000,
2174 .module_name = "dw2102",
2175 .allowed_protos = RC_BIT_RC5,
2176 .rc_query = su3000_rc_query,
51d882ed
EP
2177 },
2178
2179 .read_mac_address = su3000_read_mac_address,
2180
2181 .generic_bulk_ctrl_endpoint = 0x01,
2182
2183 .adapter = {
2184 {
2185 .num_frontends = 1,
2186 .fe = { {
2187 .streaming_ctrl = su3000_streaming_ctrl,
2188 .frontend_attach = t220_frontend_attach,
2189 .stream = {
2190 .type = USB_BULK,
2191 .count = 8,
2192 .endpoint = 0x82,
2193 .u = {
2194 .bulk = {
2195 .buffersize = 4096,
2196 }
2197 }
2198 }
2199 } },
2200 }
2201 },
2202 .num_device_descs = 1,
2203 .devices = {
2204 { "Geniatech T220 DVB-T/T2 USB2.0",
2205 { &dw2102_table[GENIATECH_T220], NULL },
2206 { NULL },
2207 },
2208 }
2209};
2210
27254c36
OS
2211static struct dvb_usb_device_properties tt_s2_4600_properties = {
2212 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
2213 .usb_ctrl = DEVICE_SPECIFIC,
2214 .size_of_priv = sizeof(struct dw2102_state),
2215 .power_ctrl = su3000_power_ctrl,
2216 .num_adapters = 1,
2217 .identify_state = su3000_identify_state,
2218 .i2c_algo = &su3000_i2c_algo,
2219
2220 .rc.core = {
2221 .rc_interval = 250,
2222 .rc_codes = RC_MAP_TT_1500,
2223 .module_name = "dw2102",
2224 .allowed_protos = RC_BIT_RC5,
2225 .rc_query = su3000_rc_query,
2226 },
2227
2228 .read_mac_address = su3000_read_mac_address,
2229
2230 .generic_bulk_ctrl_endpoint = 0x01,
2231
2232 .adapter = {
2233 {
2234 .num_frontends = 1,
2235 .fe = {{
2236 .streaming_ctrl = su3000_streaming_ctrl,
2237 .frontend_attach = tt_s2_4600_frontend_attach,
2238 .stream = {
2239 .type = USB_BULK,
2240 .count = 8,
2241 .endpoint = 0x82,
2242 .u = {
2243 .bulk = {
2244 .buffersize = 4096,
2245 }
2246 }
2247 }
2248 } },
2249 }
2250 },
6ede20f9 2251 .num_device_descs = 5,
27254c36
OS
2252 .devices = {
2253 { "TechnoTrend TT-connect S2-4600",
2254 { &dw2102_table[TECHNOTREND_S2_4600], NULL },
2255 { NULL },
2256 },
44767fc4
OS
2257 { "TeVii S482 (tuner 1)",
2258 { &dw2102_table[TEVII_S482_1], NULL },
2259 { NULL },
2260 },
2261 { "TeVii S482 (tuner 2)",
2262 { &dw2102_table[TEVII_S482_2], NULL },
2263 { NULL },
2264 },
93b66420
PZ
2265 { "Terratec Cinergy S2 USB BOX",
2266 { &dw2102_table[TERRATEC_CINERGY_S2_BOX], NULL },
2267 { NULL },
2268 },
6ede20f9
OS
2269 { "TeVii S662",
2270 { &dw2102_table[TEVII_S662], NULL },
2271 { NULL },
2272 },
27254c36
OS
2273 }
2274};
2275
7fd4828f
IL
2276static int dw2102_probe(struct usb_interface *intf,
2277 const struct usb_device_id *id)
2278{
68dd9dd4
TM
2279 p1100 = kmemdup(&s6x0_properties,
2280 sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
195288da
IL
2281 if (!p1100)
2282 return -ENOMEM;
2283 /* copy default structure */
195288da 2284 /* fill only different fields */
6823627b 2285 p1100->firmware = P1100_FIRMWARE;
195288da 2286 p1100->devices[0] = d1100;
a49de26a
EP
2287 p1100->rc.core.rc_query = prof_rc_query;
2288 p1100->rc.core.rc_codes = RC_MAP_TBS_NEC;
77eed219 2289 p1100->adapter->fe[0].frontend_attach = stv0288_frontend_attach;
195288da 2290
68dd9dd4
TM
2291 s660 = kmemdup(&s6x0_properties,
2292 sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
195288da
IL
2293 if (!s660) {
2294 kfree(p1100);
2295 return -ENOMEM;
2296 }
6823627b 2297 s660->firmware = S660_FIRMWARE;
e8f5055a 2298 s660->num_device_descs = 3;
195288da 2299 s660->devices[0] = d660;
e8f5055a
IL
2300 s660->devices[1] = d480_1;
2301 s660->devices[2] = d480_2;
77eed219 2302 s660->adapter->fe[0].frontend_attach = ds3000_frontend_attach;
cd79d33e 2303
68dd9dd4
TM
2304 p7500 = kmemdup(&s6x0_properties,
2305 sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
195288da
IL
2306 if (!p7500) {
2307 kfree(p1100);
2308 kfree(s660);
cd79d33e 2309 return -ENOMEM;
195288da 2310 }
6823627b 2311 p7500->firmware = P7500_FIRMWARE;
cd79d33e 2312 p7500->devices[0] = d7500;
a49de26a
EP
2313 p7500->rc.core.rc_query = prof_rc_query;
2314 p7500->rc.core.rc_codes = RC_MAP_TBS_NEC;
77eed219 2315 p7500->adapter->fe[0].frontend_attach = prof_7500_frontend_attach;
cd79d33e 2316
955d00ac
IL
2317
2318 s421 = kmemdup(&su3000_properties,
2319 sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
2320 if (!s421) {
2321 kfree(p1100);
2322 kfree(s660);
2323 kfree(p7500);
2324 return -ENOMEM;
2325 }
2326 s421->num_device_descs = 2;
2327 s421->devices[0] = d421;
2328 s421->devices[1] = d632;
2329 s421->adapter->fe[0].frontend_attach = m88rs2000_frontend_attach;
2330
fe03d5ee
IL
2331 if (0 == dvb_usb_device_init(intf, &dw2102_properties,
2332 THIS_MODULE, NULL, adapter_nr) ||
2333 0 == dvb_usb_device_init(intf, &dw2104_properties,
1dac77c9
IL
2334 THIS_MODULE, NULL, adapter_nr) ||
2335 0 == dvb_usb_device_init(intf, &dw3101_properties,
d0a1ddad 2336 THIS_MODULE, NULL, adapter_nr) ||
141cc35e 2337 0 == dvb_usb_device_init(intf, &s6x0_properties,
cd79d33e 2338 THIS_MODULE, NULL, adapter_nr) ||
195288da
IL
2339 0 == dvb_usb_device_init(intf, p1100,
2340 THIS_MODULE, NULL, adapter_nr) ||
2341 0 == dvb_usb_device_init(intf, s660,
2342 THIS_MODULE, NULL, adapter_nr) ||
cd79d33e 2343 0 == dvb_usb_device_init(intf, p7500,
d2ffc447 2344 THIS_MODULE, NULL, adapter_nr) ||
955d00ac
IL
2345 0 == dvb_usb_device_init(intf, s421,
2346 THIS_MODULE, NULL, adapter_nr) ||
d2ffc447 2347 0 == dvb_usb_device_init(intf, &su3000_properties,
51d882ed
EP
2348 THIS_MODULE, NULL, adapter_nr) ||
2349 0 == dvb_usb_device_init(intf, &t220_properties,
27254c36
OS
2350 THIS_MODULE, NULL, adapter_nr) ||
2351 0 == dvb_usb_device_init(intf, &tt_s2_4600_properties,
51d882ed 2352 THIS_MODULE, NULL, adapter_nr))
fe03d5ee 2353 return 0;
141cc35e 2354
fe03d5ee 2355 return -ENODEV;
7fd4828f
IL
2356}
2357
70769b24
OS
2358static void dw2102_disconnect(struct usb_interface *intf)
2359{
2360 struct dvb_usb_device *d = usb_get_intfdata(intf);
2361 struct dw2102_state *st = (struct dw2102_state *)d->priv;
2362 struct i2c_client *client;
2363
2364 /* remove I2C client for tuner */
2365 client = st->i2c_client_tuner;
2366 if (client) {
2367 module_put(client->dev.driver->owner);
2368 i2c_unregister_device(client);
2369 }
2370
f3c6abca
OS
2371 /* remove I2C client for demodulator */
2372 client = st->i2c_client_demod;
2373 if (client) {
2374 module_put(client->dev.driver->owner);
2375 i2c_unregister_device(client);
2376 }
2377
70769b24
OS
2378 dvb_usb_device_exit(intf);
2379}
2380
7fd4828f
IL
2381static struct usb_driver dw2102_driver = {
2382 .name = "dw2102",
2383 .probe = dw2102_probe,
70769b24 2384 .disconnect = dw2102_disconnect,
7fd4828f
IL
2385 .id_table = dw2102_table,
2386};
2387
ecb3b2b3 2388module_usb_driver(dw2102_driver);
7fd4828f
IL
2389
2390MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
1dac77c9 2391MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104,"
955d00ac 2392 " DVB-C 3101 USB2.0,"
6ede20f9
OS
2393 " TeVii S421, S480, S482, S600, S630, S632, S650,"
2394 " TeVii S660, S662, Prof 1100, 7500 USB2.0,"
27254c36 2395 " Geniatech SU3000, T220,"
6ede20f9 2396 " TechnoTrend S2-4600, Terratec Cinergy S2 devices");
7fd4828f
IL
2397MODULE_VERSION("0.1");
2398MODULE_LICENSE("GPL");
6823627b
RC
2399MODULE_FIRMWARE(DW2101_FIRMWARE);
2400MODULE_FIRMWARE(DW2102_FIRMWARE);
2401MODULE_FIRMWARE(DW2104_FIRMWARE);
2402MODULE_FIRMWARE(DW3101_FIRMWARE);
2403MODULE_FIRMWARE(S630_FIRMWARE);
2404MODULE_FIRMWARE(S660_FIRMWARE);
2405MODULE_FIRMWARE(P1100_FIRMWARE);
2406MODULE_FIRMWARE(P7500_FIRMWARE);
This page took 0.744282 seconds and 5 git commands to generate.