• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/drivers/media/dvb/dvb-usb/
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,
4*	Prof 1100, 7500 Cards
5* Copyright (C) 2008,2009 Igor M. Liplianin (liplianin@me.by)
6*
7*	This program is free software; you can redistribute it and/or modify it
8*	under the terms of the GNU General Public License as published by the
9*	Free Software Foundation, version 2.
10*
11* see Documentation/dvb/README.dvb-usb for more information
12*/
13#include "dw2102.h"
14#include "si21xx.h"
15#include "stv0299.h"
16#include "z0194a.h"
17#include "stv0288.h"
18#include "stb6000.h"
19#include "eds1547.h"
20#include "cx24116.h"
21#include "tda1002x.h"
22#include "mt312.h"
23#include "zl10039.h"
24#include "ds3000.h"
25#include "stv0900.h"
26#include "stv6110.h"
27#include "stb6100.h"
28#include "stb6100_proc.h"
29
30#ifndef USB_PID_DW2102
31#define USB_PID_DW2102 0x2102
32#endif
33
34#ifndef USB_PID_DW2104
35#define USB_PID_DW2104 0x2104
36#endif
37
38#ifndef USB_PID_DW3101
39#define USB_PID_DW3101 0x3101
40#endif
41
42#ifndef USB_PID_CINERGY_S
43#define USB_PID_CINERGY_S 0x0064
44#endif
45
46#ifndef USB_PID_TEVII_S630
47#define USB_PID_TEVII_S630 0xd630
48#endif
49
50#ifndef USB_PID_TEVII_S650
51#define USB_PID_TEVII_S650 0xd650
52#endif
53
54#ifndef USB_PID_TEVII_S660
55#define USB_PID_TEVII_S660 0xd660
56#endif
57
58#ifndef USB_PID_PROF_1100
59#define USB_PID_PROF_1100 0xb012
60#endif
61
62#define DW210X_READ_MSG 0
63#define DW210X_WRITE_MSG 1
64
65#define REG_1F_SYMBOLRATE_BYTE0 0x1f
66#define REG_20_SYMBOLRATE_BYTE1 0x20
67#define REG_21_SYMBOLRATE_BYTE2 0x21
68/* on my own*/
69#define DW2102_VOLTAGE_CTRL (0x1800)
70#define DW2102_RC_QUERY (0x1a00)
71
72#define	err_str "did not find the firmware file. (%s) " \
73		"Please see linux/Documentation/dvb/ for more details " \
74		"on firmware-problems."
75
76struct ir_codes_dvb_usb_table_table {
77	struct ir_scancode *rc_keys;
78	int rc_keys_size;
79};
80
81/* debug */
82static int dvb_usb_dw2102_debug;
83module_param_named(debug, dvb_usb_dw2102_debug, int, 0644);
84MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))."
85						DVB_USB_DEBUG_STATUS);
86
87/* keymaps */
88static int ir_keymap;
89module_param_named(keymap, ir_keymap, int, 0644);
90MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs  ...");
91
92/* demod probe */
93static int demod_probe = 1;
94module_param_named(demod, demod_probe, int, 0644);
95MODULE_PARM_DESC(demod, "demod to probe (1=cx24116 2=stv0903+stv6110 "
96			"4=stv0903+stb6100(or-able)).");
97
98DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
99
100static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value,
101			u16 index, u8 * data, u16 len, int flags)
102{
103	int ret;
104	u8 u8buf[len];
105
106	unsigned int pipe = (flags == DW210X_READ_MSG) ?
107				usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0);
108	u8 request_type = (flags == DW210X_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
109
110	if (flags == DW210X_WRITE_MSG)
111		memcpy(u8buf, data, len);
112	ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR,
113				value, index , u8buf, len, 2000);
114
115	if (flags == DW210X_READ_MSG)
116		memcpy(data, u8buf, len);
117	return ret;
118}
119
120/* I2C */
121static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
122		int num)
123{
124	struct dvb_usb_device *d = i2c_get_adapdata(adap);
125	int i = 0, ret = 0;
126	u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0};
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 */
137		value = msg[0].buf[0];/* register */
138		for (i = 0; i < msg[1].len; i++) {
139			value = value + i;
140			ret = dw210x_op_rw(d->udev, 0xb5, value, 0,
141					buf6, 2, DW210X_READ_MSG);
142			msg[1].buf[i] = buf6[0];
143		}
144		break;
145	case 1:
146		switch (msg[0].addr) {
147		case 0x68:
148			/* write to stv0299 register */
149			buf6[0] = 0x2a;
150			buf6[1] = msg[0].buf[0];
151			buf6[2] = msg[0].buf[1];
152			ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
153					buf6, 3, DW210X_WRITE_MSG);
154			break;
155		case 0x60:
156			if (msg[0].flags == 0) {
157			/* write to tuner pll */
158				buf6[0] = 0x2c;
159				buf6[1] = 5;
160				buf6[2] = 0xc0;
161				buf6[3] = msg[0].buf[0];
162				buf6[4] = msg[0].buf[1];
163				buf6[5] = msg[0].buf[2];
164				buf6[6] = msg[0].buf[3];
165				ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
166						buf6, 7, DW210X_WRITE_MSG);
167			} else {
168			/* read from tuner */
169				ret = dw210x_op_rw(d->udev, 0xb5, 0, 0,
170						buf6, 1, DW210X_READ_MSG);
171				msg[0].buf[0] = buf6[0];
172			}
173			break;
174		case (DW2102_RC_QUERY):
175			ret  = dw210x_op_rw(d->udev, 0xb8, 0, 0,
176					buf6, 2, DW210X_READ_MSG);
177			msg[0].buf[0] = buf6[0];
178			msg[0].buf[1] = buf6[1];
179			break;
180		case (DW2102_VOLTAGE_CTRL):
181			buf6[0] = 0x30;
182			buf6[1] = msg[0].buf[0];
183			ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
184					buf6, 2, DW210X_WRITE_MSG);
185			break;
186		}
187
188		break;
189	}
190
191	mutex_unlock(&d->i2c_mutex);
192	return num;
193}
194
195static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
196						struct i2c_msg msg[], int num)
197{
198	struct dvb_usb_device *d = i2c_get_adapdata(adap);
199	int ret = 0;
200	u8 buf6[] = {0, 0, 0, 0, 0, 0, 0};
201
202	if (!d)
203		return -ENODEV;
204	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
205		return -EAGAIN;
206
207	switch (num) {
208	case 2:
209		/* read si2109 register by number */
210		buf6[0] = msg[0].addr << 1;
211		buf6[1] = msg[0].len;
212		buf6[2] = msg[0].buf[0];
213		ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
214				buf6, msg[0].len + 2, DW210X_WRITE_MSG);
215		/* read si2109 register */
216		ret = dw210x_op_rw(d->udev, 0xc3, 0xd0, 0,
217				buf6, msg[1].len + 2, DW210X_READ_MSG);
218		memcpy(msg[1].buf, buf6 + 2, msg[1].len);
219
220		break;
221	case 1:
222		switch (msg[0].addr) {
223		case 0x68:
224			/* write to si2109 register */
225			buf6[0] = msg[0].addr << 1;
226			buf6[1] = msg[0].len;
227			memcpy(buf6 + 2, msg[0].buf, msg[0].len);
228			ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6,
229					msg[0].len + 2, DW210X_WRITE_MSG);
230			break;
231		case(DW2102_RC_QUERY):
232			ret  = dw210x_op_rw(d->udev, 0xb8, 0, 0,
233					buf6, 2, DW210X_READ_MSG);
234			msg[0].buf[0] = buf6[0];
235			msg[0].buf[1] = buf6[1];
236			break;
237		case(DW2102_VOLTAGE_CTRL):
238			buf6[0] = 0x30;
239			buf6[1] = msg[0].buf[0];
240			ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
241					buf6, 2, DW210X_WRITE_MSG);
242			break;
243		}
244		break;
245	}
246
247	mutex_unlock(&d->i2c_mutex);
248	return num;
249}
250
251static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
252{
253	struct dvb_usb_device *d = i2c_get_adapdata(adap);
254	int ret = 0;
255
256	if (!d)
257		return -ENODEV;
258	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
259		return -EAGAIN;
260
261	switch (num) {
262	case 2: {
263		/* read */
264		/* first write first register number */
265		u8 ibuf[msg[1].len + 2], obuf[3];
266		obuf[0] = msg[0].addr << 1;
267		obuf[1] = msg[0].len;
268		obuf[2] = msg[0].buf[0];
269		ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
270				obuf, msg[0].len + 2, DW210X_WRITE_MSG);
271		/* second read registers */
272		ret = dw210x_op_rw(d->udev, 0xc3, 0xd1 , 0,
273				ibuf, msg[1].len + 2, DW210X_READ_MSG);
274		memcpy(msg[1].buf, ibuf + 2, msg[1].len);
275
276		break;
277	}
278	case 1:
279		switch (msg[0].addr) {
280		case 0x68: {
281			/* write to register */
282			u8 obuf[msg[0].len + 2];
283			obuf[0] = msg[0].addr << 1;
284			obuf[1] = msg[0].len;
285			memcpy(obuf + 2, msg[0].buf, msg[0].len);
286			ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
287					obuf, msg[0].len + 2, DW210X_WRITE_MSG);
288			break;
289		}
290		case 0x61: {
291			/* write to tuner */
292			u8 obuf[msg[0].len + 2];
293			obuf[0] = msg[0].addr << 1;
294			obuf[1] = msg[0].len;
295			memcpy(obuf + 2, msg[0].buf, msg[0].len);
296			ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
297					obuf, msg[0].len + 2, DW210X_WRITE_MSG);
298			break;
299		}
300		case(DW2102_RC_QUERY): {
301			u8 ibuf[2];
302			ret  = dw210x_op_rw(d->udev, 0xb8, 0, 0,
303					ibuf, 2, DW210X_READ_MSG);
304			memcpy(msg[0].buf, ibuf , 2);
305			break;
306		}
307		case(DW2102_VOLTAGE_CTRL): {
308			u8 obuf[2];
309			obuf[0] = 0x30;
310			obuf[1] = msg[0].buf[0];
311			ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
312					obuf, 2, DW210X_WRITE_MSG);
313			break;
314		}
315		}
316
317		break;
318	}
319
320	mutex_unlock(&d->i2c_mutex);
321	return num;
322}
323
324static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
325{
326	struct dvb_usb_device *d = i2c_get_adapdata(adap);
327	int ret = 0;
328	int len, i, j;
329
330	if (!d)
331		return -ENODEV;
332	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
333		return -EAGAIN;
334
335	for (j = 0; j < num; j++) {
336		switch (msg[j].addr) {
337		case(DW2102_RC_QUERY): {
338			u8 ibuf[2];
339			ret  = dw210x_op_rw(d->udev, 0xb8, 0, 0,
340					ibuf, 2, DW210X_READ_MSG);
341			memcpy(msg[j].buf, ibuf , 2);
342			break;
343		}
344		case(DW2102_VOLTAGE_CTRL): {
345			u8 obuf[2];
346			obuf[0] = 0x30;
347			obuf[1] = msg[j].buf[0];
348			ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
349					obuf, 2, DW210X_WRITE_MSG);
350			break;
351		}
352		/*case 0x55: cx24116
353		case 0x6a: stv0903
354		case 0x68: ds3000, stv0903
355		case 0x60: ts2020, stv6110, stb6100 */
356		default: {
357			if (msg[j].flags == I2C_M_RD) {
358				/* read registers */
359				u8  ibuf[msg[j].len + 2];
360				ret = dw210x_op_rw(d->udev, 0xc3,
361						(msg[j].addr << 1) + 1, 0,
362						ibuf, msg[j].len + 2,
363						DW210X_READ_MSG);
364				memcpy(msg[j].buf, ibuf + 2, msg[j].len);
365			mdelay(10);
366			} else if (((msg[j].buf[0] == 0xb0) &&
367						(msg[j].addr == 0x68)) ||
368						((msg[j].buf[0] == 0xf7) &&
369						(msg[j].addr == 0x55))) {
370				/* write firmware */
371				u8 obuf[19];
372				obuf[0] = msg[j].addr << 1;
373				obuf[1] = (msg[j].len > 15 ? 17 : msg[j].len);
374				obuf[2] = msg[j].buf[0];
375				len = msg[j].len - 1;
376				i = 1;
377				do {
378					memcpy(obuf + 3, msg[j].buf + i,
379							(len > 16 ? 16 : len));
380					ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
381						obuf, (len > 16 ? 16 : len) + 3,
382						DW210X_WRITE_MSG);
383					i += 16;
384					len -= 16;
385				} while (len > 0);
386			} else {
387				/* write registers */
388				u8 obuf[msg[j].len + 2];
389				obuf[0] = msg[j].addr << 1;
390				obuf[1] = msg[j].len;
391				memcpy(obuf + 2, msg[j].buf, msg[j].len);
392				ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
393						obuf, msg[j].len + 2,
394						DW210X_WRITE_MSG);
395			}
396			break;
397		}
398		}
399
400	}
401
402	mutex_unlock(&d->i2c_mutex);
403	return num;
404}
405
406static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
407								int num)
408{
409	struct dvb_usb_device *d = i2c_get_adapdata(adap);
410	int ret = 0, i;
411
412	if (!d)
413		return -ENODEV;
414	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
415		return -EAGAIN;
416
417	switch (num) {
418	case 2: {
419		/* read */
420		/* first write first register number */
421		u8 ibuf[msg[1].len + 2], obuf[3];
422		obuf[0] = msg[0].addr << 1;
423		obuf[1] = msg[0].len;
424		obuf[2] = msg[0].buf[0];
425		ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
426				obuf, msg[0].len + 2, DW210X_WRITE_MSG);
427		/* second read registers */
428		ret = dw210x_op_rw(d->udev, 0xc3, 0x19 , 0,
429				ibuf, msg[1].len + 2, DW210X_READ_MSG);
430		memcpy(msg[1].buf, ibuf + 2, msg[1].len);
431
432		break;
433	}
434	case 1:
435		switch (msg[0].addr) {
436		case 0x60:
437		case 0x0c: {
438			/* write to register */
439			u8 obuf[msg[0].len + 2];
440			obuf[0] = msg[0].addr << 1;
441			obuf[1] = msg[0].len;
442			memcpy(obuf + 2, msg[0].buf, msg[0].len);
443			ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
444					obuf, msg[0].len + 2, DW210X_WRITE_MSG);
445			break;
446		}
447		case(DW2102_RC_QUERY): {
448			u8 ibuf[2];
449			ret  = dw210x_op_rw(d->udev, 0xb8, 0, 0,
450					ibuf, 2, DW210X_READ_MSG);
451			memcpy(msg[0].buf, ibuf , 2);
452			break;
453		}
454		}
455
456		break;
457	}
458
459	for (i = 0; i < num; i++) {
460		deb_xfer("%02x:%02x: %s ", i, msg[i].addr,
461				msg[i].flags == 0 ? ">>>" : "<<<");
462		debug_dump(msg[i].buf, msg[i].len, deb_xfer);
463	}
464
465	mutex_unlock(&d->i2c_mutex);
466	return num;
467}
468
469static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
470								int num)
471{
472	struct dvb_usb_device *d = i2c_get_adapdata(adap);
473	struct usb_device *udev;
474	int ret = 0;
475	int len, i, j;
476
477	if (!d)
478		return -ENODEV;
479	udev = d->udev;
480	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
481		return -EAGAIN;
482
483	for (j = 0; j < num; j++) {
484		switch (msg[j].addr) {
485		case (DW2102_RC_QUERY): {
486			u8 ibuf[4];
487			ret  = dw210x_op_rw(d->udev, 0xb8, 0, 0,
488					ibuf, 4, DW210X_READ_MSG);
489			memcpy(msg[j].buf, ibuf + 1, 2);
490			break;
491		}
492		case (DW2102_VOLTAGE_CTRL): {
493			u8 obuf[2];
494
495			obuf[0] = 1;
496			obuf[1] = msg[j].buf[1];/* off-on */
497			ret = dw210x_op_rw(d->udev, 0x8a, 0, 0,
498					obuf, 2, DW210X_WRITE_MSG);
499			obuf[0] = 3;
500			obuf[1] = msg[j].buf[0];/* 13v-18v */
501			ret = dw210x_op_rw(d->udev, 0x8a, 0, 0,
502					obuf, 2, DW210X_WRITE_MSG);
503			break;
504		}
505		/*case 0x55: cx24116
506		case 0x6a: stv0903
507		case 0x68: ds3000, stv0903
508		case 0x60: ts2020, stv6110, stb6100
509		case 0xa0: eeprom */
510		default: {
511			if (msg[j].flags == I2C_M_RD) {
512				/* read registers */
513				u8 ibuf[msg[j].len];
514				ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
515						ibuf, msg[j].len,
516						DW210X_READ_MSG);
517				memcpy(msg[j].buf, ibuf, msg[j].len);
518				break;
519			} else if ((msg[j].buf[0] == 0xb0) &&
520						(msg[j].addr == 0x68)) {
521				/* write firmware */
522				u8 obuf[19];
523				obuf[0] = (msg[j].len > 16 ?
524						18 : msg[j].len + 1);
525				obuf[1] = msg[j].addr << 1;
526				obuf[2] = msg[j].buf[0];
527				len = msg[j].len - 1;
528				i = 1;
529				do {
530					memcpy(obuf + 3, msg[j].buf + i,
531							(len > 16 ? 16 : len));
532					ret = dw210x_op_rw(d->udev, 0x80, 0, 0,
533						obuf, (len > 16 ? 16 : len) + 3,
534						DW210X_WRITE_MSG);
535					i += 16;
536					len -= 16;
537				} while (len > 0);
538			} else if ((udev->descriptor.idProduct == 0x7500)
539					&& (j < (num - 1))) {
540				/* write register addr before read */
541				u8 obuf[msg[j].len + 2];
542				obuf[0] = msg[j + 1].len;
543				obuf[1] = (msg[j].addr << 1);
544				memcpy(obuf + 2, msg[j].buf, msg[j].len);
545				ret = dw210x_op_rw(d->udev, 0x92, 0, 0,
546						obuf, msg[j].len + 2,
547						DW210X_WRITE_MSG);
548				break;
549			} else {
550				/* write registers */
551				u8 obuf[msg[j].len + 2];
552				obuf[0] = msg[j].len + 1;
553				obuf[1] = (msg[j].addr << 1);
554				memcpy(obuf + 2, msg[j].buf, msg[j].len);
555				ret = dw210x_op_rw(d->udev,
556						(num > 1 ? 0x90 : 0x80), 0, 0,
557						obuf, msg[j].len + 2,
558						DW210X_WRITE_MSG);
559				break;
560			}
561			break;
562		}
563		}
564
565		msleep(3);
566	}
567
568	mutex_unlock(&d->i2c_mutex);
569	return num;
570}
571
572static u32 dw210x_i2c_func(struct i2c_adapter *adapter)
573{
574	return I2C_FUNC_I2C;
575}
576
577static struct i2c_algorithm dw2102_i2c_algo = {
578	.master_xfer = dw2102_i2c_transfer,
579	.functionality = dw210x_i2c_func,
580};
581
582static struct i2c_algorithm dw2102_serit_i2c_algo = {
583	.master_xfer = dw2102_serit_i2c_transfer,
584	.functionality = dw210x_i2c_func,
585};
586
587static struct i2c_algorithm dw2102_earda_i2c_algo = {
588	.master_xfer = dw2102_earda_i2c_transfer,
589	.functionality = dw210x_i2c_func,
590};
591
592static struct i2c_algorithm dw2104_i2c_algo = {
593	.master_xfer = dw2104_i2c_transfer,
594	.functionality = dw210x_i2c_func,
595};
596
597static struct i2c_algorithm dw3101_i2c_algo = {
598	.master_xfer = dw3101_i2c_transfer,
599	.functionality = dw210x_i2c_func,
600};
601
602static struct i2c_algorithm s6x0_i2c_algo = {
603	.master_xfer = s6x0_i2c_transfer,
604	.functionality = dw210x_i2c_func,
605};
606
607static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
608{
609	int i;
610	u8 ibuf[] = {0, 0};
611	u8 eeprom[256], eepromline[16];
612
613	for (i = 0; i < 256; i++) {
614		if (dw210x_op_rw(d->udev, 0xb6, 0xa0 , i, ibuf, 2, DW210X_READ_MSG) < 0) {
615			err("read eeprom failed.");
616			return -1;
617		} else {
618			eepromline[i%16] = ibuf[0];
619			eeprom[i] = ibuf[0];
620		}
621		if ((i % 16) == 15) {
622			deb_xfer("%02x: ", i - 15);
623			debug_dump(eepromline, 16, deb_xfer);
624		}
625	}
626
627	memcpy(mac, eeprom + 8, 6);
628	return 0;
629};
630
631static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
632{
633	int i, ret;
634	u8 ibuf[] = { 0 }, obuf[] = { 0 };
635	u8 eeprom[256], eepromline[16];
636	struct i2c_msg msg[] = {
637		{
638			.addr = 0xa0 >> 1,
639			.flags = 0,
640			.buf = obuf,
641			.len = 1,
642		}, {
643			.addr = 0xa0 >> 1,
644			.flags = I2C_M_RD,
645			.buf = ibuf,
646			.len = 1,
647		}
648	};
649
650	for (i = 0; i < 256; i++) {
651		obuf[0] = i;
652		ret = s6x0_i2c_transfer(&d->i2c_adap, msg, 2);
653		if (ret != 2) {
654			err("read eeprom failed.");
655			return -1;
656		} else {
657			eepromline[i % 16] = ibuf[0];
658			eeprom[i] = ibuf[0];
659		}
660
661		if ((i % 16) == 15) {
662			deb_xfer("%02x: ", i - 15);
663			debug_dump(eepromline, 16, deb_xfer);
664		}
665	}
666
667	memcpy(mac, eeprom + 16, 6);
668	return 0;
669};
670
671static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
672{
673	static u8 command_13v[] = {0x00, 0x01};
674	static u8 command_18v[] = {0x01, 0x01};
675	static u8 command_off[] = {0x00, 0x00};
676	struct i2c_msg msg = {
677		.addr = DW2102_VOLTAGE_CTRL,
678		.flags = 0,
679		.buf = command_off,
680		.len = 2,
681	};
682
683	struct dvb_usb_adapter *udev_adap =
684		(struct dvb_usb_adapter *)(fe->dvb->priv);
685	if (voltage == SEC_VOLTAGE_18)
686		msg.buf = command_18v;
687	else if (voltage == SEC_VOLTAGE_13)
688		msg.buf = command_13v;
689
690	i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1);
691
692	return 0;
693}
694
695static struct stv0299_config sharp_z0194a_config = {
696	.demod_address = 0x68,
697	.inittab = sharp_z0194a_inittab,
698	.mclk = 88000000UL,
699	.invert = 1,
700	.skip_reinit = 0,
701	.lock_output = STV0299_LOCKOUTPUT_1,
702	.volt13_op0_op1 = STV0299_VOLT13_OP1,
703	.min_delay_ms = 100,
704	.set_symbol_rate = sharp_z0194a_set_symbol_rate,
705};
706
707static struct cx24116_config dw2104_config = {
708	.demod_address = 0x55,
709	.mpg_clk_pos_pol = 0x01,
710};
711
712static struct si21xx_config serit_sp1511lhb_config = {
713	.demod_address = 0x68,
714	.min_delay_ms = 100,
715
716};
717
718static struct tda10023_config dw3101_tda10023_config = {
719	.demod_address = 0x0c,
720	.invert = 1,
721};
722
723static struct mt312_config zl313_config = {
724	.demod_address = 0x0e,
725};
726
727static struct ds3000_config dw2104_ds3000_config = {
728	.demod_address = 0x68,
729};
730
731static struct stv0900_config dw2104a_stv0900_config = {
732	.demod_address = 0x6a,
733	.demod_mode = 0,
734	.xtal = 27000000,
735	.clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
736	.diseqc_mode = 2,/* 2/3 PWM */
737	.tun1_maddress = 0,/* 0x60 */
738	.tun1_adc = 0,/* 2 Vpp */
739	.path1_mode = 3,
740};
741
742static struct stb6100_config dw2104a_stb6100_config = {
743	.tuner_address = 0x60,
744	.refclock = 27000000,
745};
746
747static struct stv0900_config dw2104_stv0900_config = {
748	.demod_address = 0x68,
749	.demod_mode = 0,
750	.xtal = 8000000,
751	.clkmode = 3,
752	.diseqc_mode = 2,
753	.tun1_maddress = 0,
754	.tun1_adc = 1,/* 1 Vpp */
755	.path1_mode = 3,
756};
757
758static struct stv6110_config dw2104_stv6110_config = {
759	.i2c_address = 0x60,
760	.mclk = 16000000,
761	.clk_div = 1,
762};
763
764static struct stv0900_config prof_7500_stv0900_config = {
765	.demod_address = 0x6a,
766	.demod_mode = 0,
767	.xtal = 27000000,
768	.clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
769	.diseqc_mode = 2,/* 2/3 PWM */
770	.tun1_maddress = 0,/* 0x60 */
771	.tun1_adc = 0,/* 2 Vpp */
772	.path1_mode = 3,
773	.tun1_type = 3,
774};
775
776static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
777{
778	struct dvb_tuner_ops *tuner_ops = NULL;
779
780	if (demod_probe & 4) {
781		d->fe = dvb_attach(stv0900_attach, &dw2104a_stv0900_config,
782				&d->dev->i2c_adap, 0);
783		if (d->fe != NULL) {
784			if (dvb_attach(stb6100_attach, d->fe,
785					&dw2104a_stb6100_config,
786					&d->dev->i2c_adap)) {
787				tuner_ops = &d->fe->ops.tuner_ops;
788				tuner_ops->set_frequency = stb6100_set_freq;
789				tuner_ops->get_frequency = stb6100_get_freq;
790				tuner_ops->set_bandwidth = stb6100_set_bandw;
791				tuner_ops->get_bandwidth = stb6100_get_bandw;
792				d->fe->ops.set_voltage = dw210x_set_voltage;
793				info("Attached STV0900+STB6100!\n");
794				return 0;
795			}
796		}
797	}
798
799	if (demod_probe & 2) {
800		d->fe = dvb_attach(stv0900_attach, &dw2104_stv0900_config,
801				&d->dev->i2c_adap, 0);
802		if (d->fe != NULL) {
803			if (dvb_attach(stv6110_attach, d->fe,
804					&dw2104_stv6110_config,
805					&d->dev->i2c_adap)) {
806				d->fe->ops.set_voltage = dw210x_set_voltage;
807				info("Attached STV0900+STV6110A!\n");
808				return 0;
809			}
810		}
811	}
812
813	if (demod_probe & 1) {
814		d->fe = dvb_attach(cx24116_attach, &dw2104_config,
815				&d->dev->i2c_adap);
816		if (d->fe != NULL) {
817			d->fe->ops.set_voltage = dw210x_set_voltage;
818			info("Attached cx24116!\n");
819			return 0;
820		}
821	}
822
823	d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
824			&d->dev->i2c_adap);
825	if (d->fe != NULL) {
826		d->fe->ops.set_voltage = dw210x_set_voltage;
827		info("Attached DS3000!\n");
828		return 0;
829	}
830
831	return -EIO;
832}
833
834static struct dvb_usb_device_properties dw2102_properties;
835static struct dvb_usb_device_properties dw2104_properties;
836static struct dvb_usb_device_properties s6x0_properties;
837
838static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
839{
840	if (dw2102_properties.i2c_algo == &dw2102_serit_i2c_algo) {
841		/*dw2102_properties.adapter->tuner_attach = NULL;*/
842		d->fe = dvb_attach(si21xx_attach, &serit_sp1511lhb_config,
843					&d->dev->i2c_adap);
844		if (d->fe != NULL) {
845			d->fe->ops.set_voltage = dw210x_set_voltage;
846			info("Attached si21xx!\n");
847			return 0;
848		}
849	}
850
851	if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) {
852		d->fe = dvb_attach(stv0288_attach, &earda_config,
853					&d->dev->i2c_adap);
854		if (d->fe != NULL) {
855			if (dvb_attach(stb6000_attach, d->fe, 0x61,
856					&d->dev->i2c_adap)) {
857				d->fe->ops.set_voltage = dw210x_set_voltage;
858				info("Attached stv0288!\n");
859				return 0;
860			}
861		}
862	}
863
864	if (dw2102_properties.i2c_algo == &dw2102_i2c_algo) {
865		/*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/
866		d->fe = dvb_attach(stv0299_attach, &sharp_z0194a_config,
867					&d->dev->i2c_adap);
868		if (d->fe != NULL) {
869			d->fe->ops.set_voltage = dw210x_set_voltage;
870			info("Attached stv0299!\n");
871			return 0;
872		}
873	}
874	return -EIO;
875}
876
877static int dw3101_frontend_attach(struct dvb_usb_adapter *d)
878{
879	d->fe = dvb_attach(tda10023_attach, &dw3101_tda10023_config,
880				&d->dev->i2c_adap, 0x48);
881	if (d->fe != NULL) {
882		info("Attached tda10023!\n");
883		return 0;
884	}
885	return -EIO;
886}
887
888static int s6x0_frontend_attach(struct dvb_usb_adapter *d)
889{
890	d->fe = dvb_attach(mt312_attach, &zl313_config,
891			&d->dev->i2c_adap);
892	if (d->fe != NULL) {
893		if (dvb_attach(zl10039_attach, d->fe, 0x60,
894				&d->dev->i2c_adap)) {
895			d->fe->ops.set_voltage = dw210x_set_voltage;
896			info("Attached zl100313+zl10039!\n");
897			return 0;
898		}
899	}
900
901	d->fe = dvb_attach(stv0288_attach, &earda_config,
902			&d->dev->i2c_adap);
903	if (d->fe != NULL) {
904		if (dvb_attach(stb6000_attach, d->fe, 0x61,
905				&d->dev->i2c_adap)) {
906			d->fe->ops.set_voltage = dw210x_set_voltage;
907			info("Attached stv0288+stb6000!\n");
908			return 0;
909		}
910	}
911
912	d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
913			&d->dev->i2c_adap);
914	if (d->fe != NULL) {
915		d->fe->ops.set_voltage = dw210x_set_voltage;
916		info("Attached ds3000+ds2020!\n");
917		return 0;
918	}
919
920	return -EIO;
921}
922
923static int prof_7500_frontend_attach(struct dvb_usb_adapter *d)
924{
925	d->fe = dvb_attach(stv0900_attach, &prof_7500_stv0900_config,
926					&d->dev->i2c_adap, 0);
927	if (d->fe == NULL)
928		return -EIO;
929	d->fe->ops.set_voltage = dw210x_set_voltage;
930
931	info("Attached STV0900+STB6100A!\n");
932
933	return 0;
934}
935
936static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
937{
938	dvb_attach(dvb_pll_attach, adap->fe, 0x60,
939		&adap->dev->i2c_adap, DVB_PLL_OPERA1);
940	return 0;
941}
942
943static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
944{
945	dvb_attach(dvb_pll_attach, adap->fe, 0x60,
946		&adap->dev->i2c_adap, DVB_PLL_TUA6034);
947
948	return 0;
949}
950
951static struct ir_scancode ir_codes_dw210x_table[] = {
952	{ 0xf80a, KEY_Q },		/*power*/
953	{ 0xf80c, KEY_M },		/*mute*/
954	{ 0xf811, KEY_1 },
955	{ 0xf812, KEY_2 },
956	{ 0xf813, KEY_3 },
957	{ 0xf814, KEY_4 },
958	{ 0xf815, KEY_5 },
959	{ 0xf816, KEY_6 },
960	{ 0xf817, KEY_7 },
961	{ 0xf818, KEY_8 },
962	{ 0xf819, KEY_9 },
963	{ 0xf810, KEY_0 },
964	{ 0xf81c, KEY_PAGEUP },	/*ch+*/
965	{ 0xf80f, KEY_PAGEDOWN },	/*ch-*/
966	{ 0xf81a, KEY_O },		/*vol+*/
967	{ 0xf80e, KEY_Z },		/*vol-*/
968	{ 0xf804, KEY_R },		/*rec*/
969	{ 0xf809, KEY_D },		/*fav*/
970	{ 0xf808, KEY_BACKSPACE },	/*rewind*/
971	{ 0xf807, KEY_A },		/*fast*/
972	{ 0xf80b, KEY_P },		/*pause*/
973	{ 0xf802, KEY_ESC },	/*cancel*/
974	{ 0xf803, KEY_G },		/*tab*/
975	{ 0xf800, KEY_UP },		/*up*/
976	{ 0xf81f, KEY_ENTER },	/*ok*/
977	{ 0xf801, KEY_DOWN },	/*down*/
978	{ 0xf805, KEY_C },		/*cap*/
979	{ 0xf806, KEY_S },		/*stop*/
980	{ 0xf840, KEY_F },		/*full*/
981	{ 0xf81e, KEY_W },		/*tvmode*/
982	{ 0xf81b, KEY_B },		/*recall*/
983};
984
985static struct ir_scancode ir_codes_tevii_table[] = {
986	{ 0xf80a, KEY_POWER },
987	{ 0xf80c, KEY_MUTE },
988	{ 0xf811, KEY_1 },
989	{ 0xf812, KEY_2 },
990	{ 0xf813, KEY_3 },
991	{ 0xf814, KEY_4 },
992	{ 0xf815, KEY_5 },
993	{ 0xf816, KEY_6 },
994	{ 0xf817, KEY_7 },
995	{ 0xf818, KEY_8 },
996	{ 0xf819, KEY_9 },
997	{ 0xf810, KEY_0 },
998	{ 0xf81c, KEY_MENU },
999	{ 0xf80f, KEY_VOLUMEDOWN },
1000	{ 0xf81a, KEY_LAST },
1001	{ 0xf80e, KEY_OPEN },
1002	{ 0xf804, KEY_RECORD },
1003	{ 0xf809, KEY_VOLUMEUP },
1004	{ 0xf808, KEY_CHANNELUP },
1005	{ 0xf807, KEY_PVR },
1006	{ 0xf80b, KEY_TIME },
1007	{ 0xf802, KEY_RIGHT },
1008	{ 0xf803, KEY_LEFT },
1009	{ 0xf800, KEY_UP },
1010	{ 0xf81f, KEY_OK },
1011	{ 0xf801, KEY_DOWN },
1012	{ 0xf805, KEY_TUNER },
1013	{ 0xf806, KEY_CHANNELDOWN },
1014	{ 0xf840, KEY_PLAYPAUSE },
1015	{ 0xf81e, KEY_REWIND },
1016	{ 0xf81b, KEY_FAVORITES },
1017	{ 0xf81d, KEY_BACK },
1018	{ 0xf84d, KEY_FASTFORWARD },
1019	{ 0xf844, KEY_EPG },
1020	{ 0xf84c, KEY_INFO },
1021	{ 0xf841, KEY_AB },
1022	{ 0xf843, KEY_AUDIO },
1023	{ 0xf845, KEY_SUBTITLE },
1024	{ 0xf84a, KEY_LIST },
1025	{ 0xf846, KEY_F1 },
1026	{ 0xf847, KEY_F2 },
1027	{ 0xf85e, KEY_F3 },
1028	{ 0xf85c, KEY_F4 },
1029	{ 0xf852, KEY_F5 },
1030	{ 0xf85a, KEY_F6 },
1031	{ 0xf856, KEY_MODE },
1032	{ 0xf858, KEY_SWITCHVIDEOMODE },
1033};
1034
1035static struct ir_scancode ir_codes_tbs_table[] = {
1036	{ 0xf884, KEY_POWER },
1037	{ 0xf894, KEY_MUTE },
1038	{ 0xf887, KEY_1 },
1039	{ 0xf886, KEY_2 },
1040	{ 0xf885, KEY_3 },
1041	{ 0xf88b, KEY_4 },
1042	{ 0xf88a, KEY_5 },
1043	{ 0xf889, KEY_6 },
1044	{ 0xf88f, KEY_7 },
1045	{ 0xf88e, KEY_8 },
1046	{ 0xf88d, KEY_9 },
1047	{ 0xf892, KEY_0 },
1048	{ 0xf896, KEY_CHANNELUP },
1049	{ 0xf891, KEY_CHANNELDOWN },
1050	{ 0xf893, KEY_VOLUMEUP },
1051	{ 0xf88c, KEY_VOLUMEDOWN },
1052	{ 0xf883, KEY_RECORD },
1053	{ 0xf898, KEY_PAUSE  },
1054	{ 0xf899, KEY_OK },
1055	{ 0xf89a, KEY_SHUFFLE },
1056	{ 0xf881, KEY_UP },
1057	{ 0xf890, KEY_LEFT },
1058	{ 0xf882, KEY_RIGHT },
1059	{ 0xf888, KEY_DOWN },
1060	{ 0xf895, KEY_FAVORITES },
1061	{ 0xf897, KEY_SUBTITLE },
1062	{ 0xf89d, KEY_ZOOM },
1063	{ 0xf89f, KEY_EXIT },
1064	{ 0xf89e, KEY_MENU },
1065	{ 0xf89c, KEY_EPG },
1066	{ 0xf880, KEY_PREVIOUS },
1067	{ 0xf89b, KEY_MODE }
1068};
1069
1070static struct ir_codes_dvb_usb_table_table keys_tables[] = {
1071	{ ir_codes_dw210x_table, ARRAY_SIZE(ir_codes_dw210x_table) },
1072	{ ir_codes_tevii_table, ARRAY_SIZE(ir_codes_tevii_table) },
1073	{ ir_codes_tbs_table, ARRAY_SIZE(ir_codes_tbs_table) },
1074};
1075
1076static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
1077{
1078	struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map;
1079	int keymap_size = d->props.rc.legacy.rc_key_map_size;
1080	u8 key[2];
1081	struct i2c_msg msg = {
1082		.addr = DW2102_RC_QUERY,
1083		.flags = I2C_M_RD,
1084		.buf = key,
1085		.len = 2
1086	};
1087	int i;
1088	/* override keymap */
1089	if ((ir_keymap > 0) && (ir_keymap <= ARRAY_SIZE(keys_tables))) {
1090		keymap = keys_tables[ir_keymap - 1].rc_keys ;
1091		keymap_size = keys_tables[ir_keymap - 1].rc_keys_size;
1092	}
1093
1094	*state = REMOTE_NO_KEY_PRESSED;
1095	if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
1096		for (i = 0; i < keymap_size ; i++) {
1097			if (rc5_data(&keymap[i]) == msg.buf[0]) {
1098				*state = REMOTE_KEY_PRESSED;
1099				*event = keymap[i].keycode;
1100				break;
1101			}
1102
1103		}
1104
1105		if ((*state) == REMOTE_KEY_PRESSED)
1106			deb_rc("%s: found rc key: %x, %x, event: %x\n",
1107					__func__, key[0], key[1], (*event));
1108		else if (key[0] != 0xff)
1109			deb_rc("%s: unknown rc key: %x, %x\n",
1110					__func__, key[0], key[1]);
1111
1112	}
1113
1114	return 0;
1115}
1116
1117static struct usb_device_id dw2102_table[] = {
1118	{USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)},
1119	{USB_DEVICE(USB_VID_CYPRESS, 0x2101)},
1120	{USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2104)},
1121	{USB_DEVICE(0x9022, USB_PID_TEVII_S650)},
1122	{USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)},
1123	{USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)},
1124	{USB_DEVICE(0x9022, USB_PID_TEVII_S630)},
1125	{USB_DEVICE(0x3011, USB_PID_PROF_1100)},
1126	{USB_DEVICE(0x9022, USB_PID_TEVII_S660)},
1127	{USB_DEVICE(0x3034, 0x7500)},
1128	{ }
1129};
1130
1131MODULE_DEVICE_TABLE(usb, dw2102_table);
1132
1133static int dw2102_load_firmware(struct usb_device *dev,
1134			const struct firmware *frmwr)
1135{
1136	u8 *b, *p;
1137	int ret = 0, i;
1138	u8 reset;
1139	u8 reset16[] = {0, 0, 0, 0, 0, 0, 0};
1140	const struct firmware *fw;
1141	const char *fw_2101 = "dvb-usb-dw2101.fw";
1142
1143	switch (dev->descriptor.idProduct) {
1144	case 0x2101:
1145		ret = request_firmware(&fw, fw_2101, &dev->dev);
1146		if (ret != 0) {
1147			err(err_str, fw_2101);
1148			return ret;
1149		}
1150		break;
1151	default:
1152		fw = frmwr;
1153		break;
1154	}
1155	info("start downloading DW210X firmware");
1156	p = kmalloc(fw->size, GFP_KERNEL);
1157	reset = 1;
1158	/*stop the CPU*/
1159	dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, DW210X_WRITE_MSG);
1160	dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, DW210X_WRITE_MSG);
1161
1162	if (p != NULL) {
1163		memcpy(p, fw->data, fw->size);
1164		for (i = 0; i < fw->size; i += 0x40) {
1165			b = (u8 *) p + i;
1166			if (dw210x_op_rw(dev, 0xa0, i, 0, b , 0x40,
1167					DW210X_WRITE_MSG) != 0x40) {
1168				err("error while transferring firmware");
1169				ret = -EINVAL;
1170				break;
1171			}
1172		}
1173		/* restart the CPU */
1174		reset = 0;
1175		if (ret || dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1,
1176					DW210X_WRITE_MSG) != 1) {
1177			err("could not restart the USB controller CPU.");
1178			ret = -EINVAL;
1179		}
1180		if (ret || dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1,
1181					DW210X_WRITE_MSG) != 1) {
1182			err("could not restart the USB controller CPU.");
1183			ret = -EINVAL;
1184		}
1185		/* init registers */
1186		switch (dev->descriptor.idProduct) {
1187		case USB_PID_PROF_1100:
1188			s6x0_properties.rc.legacy.rc_key_map = ir_codes_tbs_table;
1189			s6x0_properties.rc.legacy.rc_key_map_size =
1190					ARRAY_SIZE(ir_codes_tbs_table);
1191			break;
1192		case USB_PID_TEVII_S650:
1193			dw2104_properties.rc.legacy.rc_key_map = ir_codes_tevii_table;
1194			dw2104_properties.rc.legacy.rc_key_map_size =
1195					ARRAY_SIZE(ir_codes_tevii_table);
1196		case USB_PID_DW2104:
1197			reset = 1;
1198			dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1,
1199					DW210X_WRITE_MSG);
1200			/* break omitted intentionally */
1201		case USB_PID_DW3101:
1202			reset = 0;
1203			dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
1204					DW210X_WRITE_MSG);
1205			break;
1206		case USB_PID_CINERGY_S:
1207		case USB_PID_DW2102:
1208			dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
1209					DW210X_WRITE_MSG);
1210			dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
1211					DW210X_READ_MSG);
1212			/* check STV0299 frontend  */
1213			dw210x_op_rw(dev, 0xb5, 0, 0, &reset16[0], 2,
1214					DW210X_READ_MSG);
1215			if ((reset16[0] == 0xa1) || (reset16[0] == 0x80)) {
1216				dw2102_properties.i2c_algo = &dw2102_i2c_algo;
1217				dw2102_properties.adapter->tuner_attach = &dw2102_tuner_attach;
1218				break;
1219			} else {
1220				/* check STV0288 frontend  */
1221				reset16[0] = 0xd0;
1222				reset16[1] = 1;
1223				reset16[2] = 0;
1224				dw210x_op_rw(dev, 0xc2, 0, 0, &reset16[0], 3,
1225						DW210X_WRITE_MSG);
1226				dw210x_op_rw(dev, 0xc3, 0xd1, 0, &reset16[0], 3,
1227						DW210X_READ_MSG);
1228				if (reset16[2] == 0x11) {
1229					dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo;
1230					break;
1231				}
1232			}
1233		case 0x2101:
1234			dw210x_op_rw(dev, 0xbc, 0x0030, 0, &reset16[0], 2,
1235					DW210X_READ_MSG);
1236			dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
1237					DW210X_READ_MSG);
1238			dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
1239					DW210X_READ_MSG);
1240			dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
1241					DW210X_READ_MSG);
1242			break;
1243		}
1244
1245		msleep(100);
1246		kfree(p);
1247	}
1248	return ret;
1249}
1250
1251static struct dvb_usb_device_properties dw2102_properties = {
1252	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
1253	.usb_ctrl = DEVICE_SPECIFIC,
1254	.firmware = "dvb-usb-dw2102.fw",
1255	.no_reconnect = 1,
1256
1257	.i2c_algo = &dw2102_serit_i2c_algo,
1258
1259	.rc.legacy = {
1260		.rc_key_map = ir_codes_dw210x_table,
1261		.rc_key_map_size = ARRAY_SIZE(ir_codes_dw210x_table),
1262		.rc_interval = 150,
1263		.rc_query = dw2102_rc_query,
1264	},
1265
1266	.generic_bulk_ctrl_endpoint = 0x81,
1267	/* parameter for the MPEG2-data transfer */
1268	.num_adapters = 1,
1269	.download_firmware = dw2102_load_firmware,
1270	.read_mac_address = dw210x_read_mac_address,
1271	.adapter = {
1272		{
1273			.frontend_attach = dw2102_frontend_attach,
1274			.streaming_ctrl = NULL,
1275			.tuner_attach = NULL,
1276			.stream = {
1277				.type = USB_BULK,
1278				.count = 8,
1279				.endpoint = 0x82,
1280				.u = {
1281					.bulk = {
1282						.buffersize = 4096,
1283					}
1284				}
1285			},
1286		}
1287	},
1288	.num_device_descs = 3,
1289	.devices = {
1290		{"DVBWorld DVB-S 2102 USB2.0",
1291			{&dw2102_table[0], NULL},
1292			{NULL},
1293		},
1294		{"DVBWorld DVB-S 2101 USB2.0",
1295			{&dw2102_table[1], NULL},
1296			{NULL},
1297		},
1298		{"TerraTec Cinergy S USB",
1299			{&dw2102_table[4], NULL},
1300			{NULL},
1301		},
1302	}
1303};
1304
1305static struct dvb_usb_device_properties dw2104_properties = {
1306	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
1307	.usb_ctrl = DEVICE_SPECIFIC,
1308	.firmware = "dvb-usb-dw2104.fw",
1309	.no_reconnect = 1,
1310
1311	.i2c_algo = &dw2104_i2c_algo,
1312	.rc.legacy = {
1313		.rc_key_map = ir_codes_dw210x_table,
1314		.rc_key_map_size = ARRAY_SIZE(ir_codes_dw210x_table),
1315		.rc_interval = 150,
1316		.rc_query = dw2102_rc_query,
1317	},
1318
1319	.generic_bulk_ctrl_endpoint = 0x81,
1320	/* parameter for the MPEG2-data transfer */
1321	.num_adapters = 1,
1322	.download_firmware = dw2102_load_firmware,
1323	.read_mac_address = dw210x_read_mac_address,
1324	.adapter = {
1325		{
1326			.frontend_attach = dw2104_frontend_attach,
1327			.streaming_ctrl = NULL,
1328			/*.tuner_attach = dw2104_tuner_attach,*/
1329			.stream = {
1330				.type = USB_BULK,
1331				.count = 8,
1332				.endpoint = 0x82,
1333				.u = {
1334					.bulk = {
1335						.buffersize = 4096,
1336					}
1337				}
1338			},
1339		}
1340	},
1341	.num_device_descs = 2,
1342	.devices = {
1343		{ "DVBWorld DW2104 USB2.0",
1344			{&dw2102_table[2], NULL},
1345			{NULL},
1346		},
1347		{ "TeVii S650 USB2.0",
1348			{&dw2102_table[3], NULL},
1349			{NULL},
1350		},
1351	}
1352};
1353
1354static struct dvb_usb_device_properties dw3101_properties = {
1355	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
1356	.usb_ctrl = DEVICE_SPECIFIC,
1357	.firmware = "dvb-usb-dw3101.fw",
1358	.no_reconnect = 1,
1359
1360	.i2c_algo = &dw3101_i2c_algo,
1361	.rc.legacy = {
1362		.rc_key_map = ir_codes_dw210x_table,
1363		.rc_key_map_size = ARRAY_SIZE(ir_codes_dw210x_table),
1364		.rc_interval = 150,
1365		.rc_query = dw2102_rc_query,
1366	},
1367
1368	.generic_bulk_ctrl_endpoint = 0x81,
1369	/* parameter for the MPEG2-data transfer */
1370	.num_adapters = 1,
1371	.download_firmware = dw2102_load_firmware,
1372	.read_mac_address = dw210x_read_mac_address,
1373	.adapter = {
1374		{
1375			.frontend_attach = dw3101_frontend_attach,
1376			.streaming_ctrl = NULL,
1377			.tuner_attach = dw3101_tuner_attach,
1378			.stream = {
1379				.type = USB_BULK,
1380				.count = 8,
1381				.endpoint = 0x82,
1382				.u = {
1383					.bulk = {
1384						.buffersize = 4096,
1385					}
1386				}
1387			},
1388		}
1389	},
1390	.num_device_descs = 1,
1391	.devices = {
1392		{ "DVBWorld DVB-C 3101 USB2.0",
1393			{&dw2102_table[5], NULL},
1394			{NULL},
1395		},
1396	}
1397};
1398
1399static struct dvb_usb_device_properties s6x0_properties = {
1400	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
1401	.usb_ctrl = DEVICE_SPECIFIC,
1402	.firmware = "dvb-usb-s630.fw",
1403	.no_reconnect = 1,
1404
1405	.i2c_algo = &s6x0_i2c_algo,
1406	.rc.legacy = {
1407		.rc_key_map = ir_codes_tevii_table,
1408		.rc_key_map_size = ARRAY_SIZE(ir_codes_tevii_table),
1409		.rc_interval = 150,
1410		.rc_query = dw2102_rc_query,
1411	},
1412
1413	.generic_bulk_ctrl_endpoint = 0x81,
1414	.num_adapters = 1,
1415	.download_firmware = dw2102_load_firmware,
1416	.read_mac_address = s6x0_read_mac_address,
1417	.adapter = {
1418		{
1419			.frontend_attach = s6x0_frontend_attach,
1420			.streaming_ctrl = NULL,
1421			.tuner_attach = NULL,
1422			.stream = {
1423				.type = USB_BULK,
1424				.count = 8,
1425				.endpoint = 0x82,
1426				.u = {
1427					.bulk = {
1428						.buffersize = 4096,
1429					}
1430				}
1431			},
1432		}
1433	},
1434	.num_device_descs = 3,
1435	.devices = {
1436		{"TeVii S630 USB",
1437			{&dw2102_table[6], NULL},
1438			{NULL},
1439		},
1440		{"Prof 1100 USB ",
1441			{&dw2102_table[7], NULL},
1442			{NULL},
1443		},
1444		{"TeVii S660 USB",
1445			{&dw2102_table[8], NULL},
1446			{NULL},
1447		},
1448	}
1449};
1450
1451struct dvb_usb_device_properties *p7500;
1452static struct dvb_usb_device_description d7500 = {
1453	"Prof 7500 USB DVB-S2",
1454	{&dw2102_table[9], NULL},
1455	{NULL},
1456};
1457
1458static int dw2102_probe(struct usb_interface *intf,
1459		const struct usb_device_id *id)
1460{
1461
1462	p7500 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
1463	if (!p7500)
1464		return -ENOMEM;
1465	/* copy default structure */
1466	memcpy(p7500, &s6x0_properties,
1467			sizeof(struct dvb_usb_device_properties));
1468	/* fill only different fields */
1469	p7500->firmware = "dvb-usb-p7500.fw";
1470	p7500->devices[0] = d7500;
1471	p7500->rc.legacy.rc_key_map = ir_codes_tbs_table;
1472	p7500->rc.legacy.rc_key_map_size = ARRAY_SIZE(ir_codes_tbs_table);
1473	p7500->adapter->frontend_attach = prof_7500_frontend_attach;
1474
1475	if (0 == dvb_usb_device_init(intf, &dw2102_properties,
1476			THIS_MODULE, NULL, adapter_nr) ||
1477	    0 == dvb_usb_device_init(intf, &dw2104_properties,
1478			THIS_MODULE, NULL, adapter_nr) ||
1479	    0 == dvb_usb_device_init(intf, &dw3101_properties,
1480			THIS_MODULE, NULL, adapter_nr) ||
1481	    0 == dvb_usb_device_init(intf, &s6x0_properties,
1482			THIS_MODULE, NULL, adapter_nr) ||
1483	    0 == dvb_usb_device_init(intf, p7500,
1484			THIS_MODULE, NULL, adapter_nr))
1485		return 0;
1486
1487	return -ENODEV;
1488}
1489
1490static struct usb_driver dw2102_driver = {
1491	.name = "dw2102",
1492	.probe = dw2102_probe,
1493	.disconnect = dvb_usb_device_exit,
1494	.id_table = dw2102_table,
1495};
1496
1497static int __init dw2102_module_init(void)
1498{
1499	int ret =  usb_register(&dw2102_driver);
1500	if (ret)
1501		err("usb_register failed. Error number %d", ret);
1502
1503	return ret;
1504}
1505
1506static void __exit dw2102_module_exit(void)
1507{
1508	usb_deregister(&dw2102_driver);
1509}
1510
1511module_init(dw2102_module_init);
1512module_exit(dw2102_module_exit);
1513
1514MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
1515MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104,"
1516				" DVB-C 3101 USB2.0,"
1517				" TeVii S600, S630, S650, S660 USB2.0,"
1518				" Prof 1100, 7500 USB2.0 devices");
1519MODULE_VERSION("0.1");
1520MODULE_LICENSE("GPL");
1521