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