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