Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dw2102.c
Go to the documentation of this file.
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 ([email protected])
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 
90 };
91 
92 struct su3000_state {
94 };
95 
96 struct s6x0_state {
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))."
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 
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);
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,
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,
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,
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,
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,
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,
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,
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 = {
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,
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 = {
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 = {
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 
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)},
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,
1535  /* break omitted intentionally */
1536  case USB_PID_DW3101:
1537  reset = 0;
1538  dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
1540  break;
1541  case USB_PID_CINERGY_S:
1542  case USB_PID_DW2102:
1543  dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
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,
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 
1785 static struct dvb_usb_device_description d1100 = {
1786  "Prof 1100 USB ",
1787  {&dw2102_table[PROF_1100], NULL},
1788  {NULL},
1789 };
1790 
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 
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) [email protected]");
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");