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