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