aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorIgor M. Liplianin <liplianin@me.by>2009-11-27 12:37:35 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-12-16 06:27:46 -0500
commit141cc35e2d2941fcf4cfc78a75c75f7fc083d25f (patch)
tree9ba16cc8247eb5dea0c52d92d9834a0e5b9c8063 /drivers/media
parent21508b9ad4bb1db788b5307ab2070f1c2602caf2 (diff)
V4L/DVB (13678): Add support for yet another DvbWorld, TeVii and Prof USB devices
Patch to support DvbWorld DW2104 device modifications with STV0903 and DS3000 demods as well as TeVii S660 and Prof 1100 Also replace some magic numbers with meaningfull variables. Signed-off-by: Igor M. Liplianin <liplianin@me.by> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig8
-rw-r--r--drivers/media/dvb/dvb-usb/dw2102.c456
2 files changed, 315 insertions, 149 deletions
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 2dee1bf73577..1b249897c9fb 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -265,9 +265,13 @@ config DVB_USB_DW2102
265 select DVB_TDA10021 if !DVB_FE_CUSTOMISE 265 select DVB_TDA10021 if !DVB_FE_CUSTOMISE
266 select DVB_MT312 if !DVB_FE_CUSTOMISE 266 select DVB_MT312 if !DVB_FE_CUSTOMISE
267 select DVB_ZL10039 if !DVB_FE_CUSTOMISE 267 select DVB_ZL10039 if !DVB_FE_CUSTOMISE
268 select DVB_DS3000 if !DVB_FE_CUSTOMISE
269 select DVB_STB6100 if !DVB_FE_CUSTOMISE
270 select DVB_STV6110 if !DVB_FE_CUSTOMISE
271 select DVB_STV0900 if !DVB_FE_CUSTOMISE
268 help 272 help
269 Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers 273 Say Y here to support the DvbWorld, TeVii, Prof DVB-S/S2 USB2.0
270 and the TeVii S650, S630. 274 receivers.
271 275
272config DVB_USB_CINERGY_T2 276config DVB_USB_CINERGY_T2
273 tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver" 277 tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver"
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c
index 5bb9479d154e..64132c0cf80d 100644
--- a/drivers/media/dvb/dvb-usb/dw2102.c
+++ b/drivers/media/dvb/dvb-usb/dw2102.c
@@ -20,6 +20,11 @@
20#include "tda1002x.h" 20#include "tda1002x.h"
21#include "mt312.h" 21#include "mt312.h"
22#include "zl10039.h" 22#include "zl10039.h"
23#include "ds3000.h"
24#include "stv0900.h"
25#include "stv6110.h"
26#include "stb6100.h"
27#include "stb6100_proc.h"
23 28
24#ifndef USB_PID_DW2102 29#ifndef USB_PID_DW2102
25#define USB_PID_DW2102 0x2102 30#define USB_PID_DW2102 0x2102
@@ -37,12 +42,20 @@
37#define USB_PID_CINERGY_S 0x0064 42#define USB_PID_CINERGY_S 0x0064
38#endif 43#endif
39 44
45#ifndef USB_PID_TEVII_S630
46#define USB_PID_TEVII_S630 0xd630
47#endif
48
40#ifndef USB_PID_TEVII_S650 49#ifndef USB_PID_TEVII_S650
41#define USB_PID_TEVII_S650 0xd650 50#define USB_PID_TEVII_S650 0xd650
42#endif 51#endif
43 52
44#ifndef USB_PID_TEVII_S630 53#ifndef USB_PID_TEVII_S660
45#define USB_PID_TEVII_S630 0xd630 54#define USB_PID_TEVII_S660 0xd660
55#endif
56
57#ifndef USB_PID_PROF_1100
58#define USB_PID_PROF_1100 0xb012
46#endif 59#endif
47 60
48#define DW210X_READ_MSG 0 61#define DW210X_READ_MSG 0
@@ -55,6 +68,10 @@
55#define DW2102_VOLTAGE_CTRL (0x1800) 68#define DW2102_VOLTAGE_CTRL (0x1800)
56#define DW2102_RC_QUERY (0x1a00) 69#define DW2102_RC_QUERY (0x1a00)
57 70
71#define err_str "did not find the firmware file. (%s) " \
72 "Please see linux/Documentation/dvb/ for more details " \
73 "on firmware-problems."
74
58struct dvb_usb_rc_keys_table { 75struct dvb_usb_rc_keys_table {
59 struct dvb_usb_rc_key *rc_keys; 76 struct dvb_usb_rc_key *rc_keys;
60 int rc_keys_size; 77 int rc_keys_size;
@@ -71,6 +88,12 @@ static int ir_keymap;
71module_param_named(keymap, ir_keymap, int, 0644); 88module_param_named(keymap, ir_keymap, int, 0644);
72MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ..."); 89MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ...");
73 90
91/* demod probe */
92static int demod_probe = 1;
93module_param_named(demod, demod_probe, int, 0644);
94MODULE_PARM_DESC(demod, "demod to probe (1=cx24116 2=stv0903+stv6110 "
95 "4=stv0903+stb6100(or-able)).");
96
74DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 97DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
75 98
76static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value, 99static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value,
@@ -183,7 +206,7 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
183 switch (num) { 206 switch (num) {
184 case 2: 207 case 2:
185 /* read si2109 register by number */ 208 /* read si2109 register by number */
186 buf6[0] = 0xd0; 209 buf6[0] = msg[0].addr << 1;
187 buf6[1] = msg[0].len; 210 buf6[1] = msg[0].len;
188 buf6[2] = msg[0].buf[0]; 211 buf6[2] = msg[0].buf[0];
189 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, 212 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
@@ -198,7 +221,7 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
198 switch (msg[0].addr) { 221 switch (msg[0].addr) {
199 case 0x68: 222 case 0x68:
200 /* write to si2109 register */ 223 /* write to si2109 register */
201 buf6[0] = 0xd0; 224 buf6[0] = msg[0].addr << 1;
202 buf6[1] = msg[0].len; 225 buf6[1] = msg[0].len;
203 memcpy(buf6 + 2, msg[0].buf, msg[0].len); 226 memcpy(buf6 + 2, msg[0].buf, msg[0].len);
204 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6, 227 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6,
@@ -239,7 +262,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
239 /* read */ 262 /* read */
240 /* first write first register number */ 263 /* first write first register number */
241 u8 ibuf[msg[1].len + 2], obuf[3]; 264 u8 ibuf[msg[1].len + 2], obuf[3];
242 obuf[0] = 0xd0; 265 obuf[0] = msg[0].addr << 1;
243 obuf[1] = msg[0].len; 266 obuf[1] = msg[0].len;
244 obuf[2] = msg[0].buf[0]; 267 obuf[2] = msg[0].buf[0];
245 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, 268 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
@@ -256,7 +279,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
256 case 0x68: { 279 case 0x68: {
257 /* write to register */ 280 /* write to register */
258 u8 obuf[msg[0].len + 2]; 281 u8 obuf[msg[0].len + 2];
259 obuf[0] = 0xd0; 282 obuf[0] = msg[0].addr << 1;
260 obuf[1] = msg[0].len; 283 obuf[1] = msg[0].len;
261 memcpy(obuf + 2, msg[0].buf, msg[0].len); 284 memcpy(obuf + 2, msg[0].buf, msg[0].len);
262 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, 285 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
@@ -266,7 +289,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
266 case 0x61: { 289 case 0x61: {
267 /* write to tuner */ 290 /* write to tuner */
268 u8 obuf[msg[0].len + 2]; 291 u8 obuf[msg[0].len + 2];
269 obuf[0] = 0xc2; 292 obuf[0] = msg[0].addr << 1;
270 obuf[1] = msg[0].len; 293 obuf[1] = msg[0].len;
271 memcpy(obuf + 2, msg[0].buf, msg[0].len); 294 memcpy(obuf + 2, msg[0].buf, msg[0].len);
272 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, 295 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
@@ -301,78 +324,78 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
301{ 324{
302 struct dvb_usb_device *d = i2c_get_adapdata(adap); 325 struct dvb_usb_device *d = i2c_get_adapdata(adap);
303 int ret = 0; 326 int ret = 0;
304 int len, i; 327 int len, i, j;
305 328
306 if (!d) 329 if (!d)
307 return -ENODEV; 330 return -ENODEV;
308 if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 331 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
309 return -EAGAIN; 332 return -EAGAIN;
310 333
311 switch (num) { 334 for (j = 0; j < num; j++) {
312 case 2: { 335 switch (msg[j].addr) {
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): { 336 case(DW2102_RC_QUERY): {
359 u8 ibuf[2]; 337 u8 ibuf[2];
360 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, 338 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
361 ibuf, 2, DW210X_READ_MSG); 339 ibuf, 2, DW210X_READ_MSG);
362 memcpy(msg[0].buf, ibuf , 2); 340 memcpy(msg[j].buf, ibuf , 2);
363 break; 341 break;
364 } 342 }
365 case(DW2102_VOLTAGE_CTRL): { 343 case(DW2102_VOLTAGE_CTRL): {
366 u8 obuf[2]; 344 u8 obuf[2];
367 obuf[0] = 0x30; 345 obuf[0] = 0x30;
368 obuf[1] = msg[0].buf[0]; 346 obuf[1] = msg[j].buf[0];
369 ret = dw210x_op_rw(d->udev, 0xb2, 0, 0, 347 ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
370 obuf, 2, DW210X_WRITE_MSG); 348 obuf, 2, DW210X_WRITE_MSG);
371 break; 349 break;
372 } 350 }
351 /*case 0x55: cx24116
352 case 0x6a: stv0903
353 case 0x68: ds3000, stv0903
354 case 0x60: ts2020, stv6110, stb6100 */
355 default: {
356 if (msg[j].flags == I2C_M_RD) {
357 /* read registers */
358 u8 ibuf[msg[j].len + 2];
359 ret = dw210x_op_rw(d->udev, 0xc3,
360 (msg[j].addr << 1) + 1, 0,
361 ibuf, msg[j].len + 2,
362 DW210X_READ_MSG);
363 memcpy(msg[j].buf, ibuf + 2, msg[j].len);
364 mdelay(10);
365 } else if (((msg[j].buf[0] == 0xb0) &&
366 (msg[j].addr == 0x68)) ||
367 ((msg[j].buf[0] == 0xf7) &&
368 (msg[j].addr == 0x55))) {
369 /* write firmware */
370 u8 obuf[19];
371 obuf[0] = msg[j].addr << 1;
372 obuf[1] = (msg[j].len > 15 ? 17 : msg[j].len);
373 obuf[2] = msg[j].buf[0];
374 len = msg[j].len - 1;
375 i = 1;
376 do {
377 memcpy(obuf + 3, msg[j].buf + i,
378 (len > 16 ? 16 : len));
379 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
380 obuf, (len > 16 ? 16 : len) + 3,
381 DW210X_WRITE_MSG);
382 i += 16;
383 len -= 16;
384 } while (len > 0);
385 } else {
386 /* write registers */
387 u8 obuf[msg[j].len + 2];
388 obuf[0] = msg[j].addr << 1;
389 obuf[1] = msg[j].len;
390 memcpy(obuf + 2, msg[j].buf, msg[j].len);
391 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
392 obuf, msg[j].len + 2,
393 DW210X_WRITE_MSG);
394 }
395 break;
396 }
373 } 397 }
374 398
375 break;
376 } 399 }
377 400
378 mutex_unlock(&d->i2c_mutex); 401 mutex_unlock(&d->i2c_mutex);
@@ -442,63 +465,85 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
442 return num; 465 return num;
443} 466}
444 467
445static int s630_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], 468static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
446 int num) 469 int num)
447{ 470{
448 struct dvb_usb_device *d = i2c_get_adapdata(adap); 471 struct dvb_usb_device *d = i2c_get_adapdata(adap);
449 int ret = 0; 472 int ret = 0;
473 int len, i, j;
450 474
451 if (!d) 475 if (!d)
452 return -ENODEV; 476 return -ENODEV;
453 if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 477 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
454 return -EAGAIN; 478 return -EAGAIN;
455 479
456 switch (num) { 480 for (j = 0; j < num; j++) {
457 case 2: { /* read */ 481 switch (msg[j].addr) {
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): { 482 case (DW2102_RC_QUERY): {
485 u8 ibuf[4]; 483 u8 ibuf[4];
486 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, 484 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
487 ibuf, 4, DW210X_READ_MSG); 485 ibuf, 4, DW210X_READ_MSG);
488 msg[0].buf[0] = ibuf[3]; 486 memcpy(msg[j].buf, ibuf + 1, 2);
489 break; 487 break;
490 } 488 }
491 case (DW2102_VOLTAGE_CTRL): { 489 case (DW2102_VOLTAGE_CTRL): {
492 u8 obuf[2]; 490 u8 obuf[2];
493 obuf[0] = 0x03; 491 obuf[0] = 3;
494 obuf[1] = msg[0].buf[0]; 492 obuf[1] = msg[j].buf[0];
495 ret = dw210x_op_rw(d->udev, 0x8a, 0, 0, 493 ret = dw210x_op_rw(d->udev, 0x8a, 0, 0,
496 obuf, 2, DW210X_WRITE_MSG); 494 obuf, 2, DW210X_WRITE_MSG);
497 break; 495 break;
498 } 496 }
497 /*case 0x55: cx24116
498 case 0x6a: stv0903
499 case 0x68: ds3000, stv0903
500 case 0x60: ts2020, stv6110, stb6100
501 case 0xa0: eeprom */
502 default: {
503 if (msg[j].flags == I2C_M_RD) {
504 /* read registers */
505 u8 ibuf[msg[j].len];
506 ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
507 ibuf, msg[j].len,
508 DW210X_READ_MSG);
509 memcpy(msg[j].buf, ibuf, msg[j].len);
510 break;
511 } else if ((msg[j].buf[0] == 0xb0) &&
512 (msg[j].addr == 0x68)) {
513 /* write firmware */
514 u8 obuf[19];
515 obuf[0] = (msg[j].len > 16 ?
516 18 : msg[j].len + 1);
517 obuf[1] = msg[j].addr << 1;
518 obuf[2] = msg[j].buf[0];
519 len = msg[j].len - 1;
520 i = 1;
521 do {
522 memcpy(obuf + 3, msg[j].buf + i,
523 (len > 16 ? 16 : len));
524 ret = dw210x_op_rw(d->udev, 0x80, 0, 0,
525 obuf, (len > 16 ? 16 : len) + 3,
526 DW210X_WRITE_MSG);
527 i += 16;
528 len -= 16;
529 } while (len > 0);
530 } else {
531 /* write registers */
532 u8 obuf[msg[j].len + 2];
533 obuf[0] = msg[j].len + 1;
534 obuf[1] = (msg[j].addr << 1);
535 memcpy(obuf + 2, msg[j].buf, msg[j].len);
536 ret = dw210x_op_rw(d->udev,
537 (num > 1 ? 0x90 : 0x80), 0, 0,
538 obuf, msg[j].len + 2,
539 DW210X_WRITE_MSG);
540 break;
541 }
542 break;
543 }
499 } 544 }
500 545
501 break; 546 msleep(3);
502 } 547 }
503 548
504 mutex_unlock(&d->i2c_mutex); 549 mutex_unlock(&d->i2c_mutex);
@@ -535,8 +580,8 @@ static struct i2c_algorithm dw3101_i2c_algo = {
535 .functionality = dw210x_i2c_func, 580 .functionality = dw210x_i2c_func,
536}; 581};
537 582
538static struct i2c_algorithm s630_i2c_algo = { 583static struct i2c_algorithm s6x0_i2c_algo = {
539 .master_xfer = s630_i2c_transfer, 584 .master_xfer = s6x0_i2c_transfer,
540 .functionality = dw210x_i2c_func, 585 .functionality = dw210x_i2c_func,
541}; 586};
542 587
@@ -564,25 +609,34 @@ static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
564 return 0; 609 return 0;
565}; 610};
566 611
567static int s630_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) 612static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
568{ 613{
569 int i, ret; 614 int i, ret;
570 u8 buf[3], eeprom[256], eepromline[16]; 615 u8 ibuf[] = { 0 }, obuf[] = { 0 };
616 u8 eeprom[256], eepromline[16];
617 struct i2c_msg msg[] = {
618 {
619 .addr = 0xa0 >> 1,
620 .flags = 0,
621 .buf = obuf,
622 .len = 1,
623 }, {
624 .addr = 0xa0 >> 1,
625 .flags = I2C_M_RD,
626 .buf = ibuf,
627 .len = 1,
628 }
629 };
571 630
572 for (i = 0; i < 256; i++) { 631 for (i = 0; i < 256; i++) {
573 buf[0] = 1; 632 obuf[0] = i;
574 buf[1] = 0xa0; 633 ret = s6x0_i2c_transfer(&d->i2c_adap, msg, 2);
575 buf[2] = i; 634 if (ret != 2) {
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."); 635 err("read eeprom failed.");
582 return -1; 636 return -1;
583 } else { 637 } else {
584 eepromline[i % 16] = buf[0]; 638 eepromline[i % 16] = ibuf[0];
585 eeprom[i] = buf[0]; 639 eeprom[i] = ibuf[0];
586 } 640 }
587 641
588 if ((i % 16) == 15) { 642 if ((i % 16) == 15) {
@@ -644,19 +698,104 @@ static struct mt312_config zl313_config = {
644 .demod_address = 0x0e, 698 .demod_address = 0x0e,
645}; 699};
646 700
701static struct ds3000_config dw2104_ds3000_config = {
702 .demod_address = 0x68,
703};
704
705static struct stv0900_config dw2104a_stv0900_config = {
706 .demod_address = 0x6a,
707 .demod_mode = 0,
708 .xtal = 27000000,
709 .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
710 .diseqc_mode = 2,/* 2/3 PWM */
711 .tun1_maddress = 0,/* 0x60 */
712 .tun1_adc = 0,/* 2 Vpp */
713 .path1_mode = 3,
714};
715
716static struct stb6100_config dw2104a_stb6100_config = {
717 .tuner_address = 0x60,
718 .refclock = 27000000,
719};
720
721static struct stv0900_config dw2104_stv0900_config = {
722 .demod_address = 0x68,
723 .demod_mode = 0,
724 .xtal = 8000000,
725 .clkmode = 3,
726 .diseqc_mode = 2,
727 .tun1_maddress = 0,
728 .tun1_adc = 1,/* 1 Vpp */
729 .path1_mode = 3,
730};
731
732static struct stv6110_config dw2104_stv6110_config = {
733 .i2c_address = 0x60,
734 .mclk = 16000000,
735 .clk_div = 1,
736};
737
647static int dw2104_frontend_attach(struct dvb_usb_adapter *d) 738static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
648{ 739{
649 if ((d->fe = dvb_attach(cx24116_attach, &dw2104_config, 740 struct dvb_tuner_ops *tuner_ops = NULL;
650 &d->dev->i2c_adap)) != NULL) { 741
742 if (demod_probe & 4) {
743 d->fe = dvb_attach(stv0900_attach, &dw2104a_stv0900_config,
744 &d->dev->i2c_adap, 0);
745 if (d->fe != NULL) {
746 if (dvb_attach(stb6100_attach, d->fe,
747 &dw2104a_stb6100_config,
748 &d->dev->i2c_adap)) {
749 tuner_ops = &d->fe->ops.tuner_ops;
750 tuner_ops->set_frequency = stb6100_set_freq;
751 tuner_ops->get_frequency = stb6100_get_freq;
752 tuner_ops->set_bandwidth = stb6100_set_bandw;
753 tuner_ops->get_bandwidth = stb6100_get_bandw;
754 d->fe->ops.set_voltage = dw210x_set_voltage;
755 info("Attached STV0900+STB6100!\n");
756 return 0;
757 }
758 }
759 }
760
761 if (demod_probe & 2) {
762 d->fe = dvb_attach(stv0900_attach, &dw2104_stv0900_config,
763 &d->dev->i2c_adap, 0);
764 if (d->fe != NULL) {
765 if (dvb_attach(stv6110_attach, d->fe,
766 &dw2104_stv6110_config,
767 &d->dev->i2c_adap)) {
768 d->fe->ops.set_voltage = dw210x_set_voltage;
769 info("Attached STV0900+STV6110A!\n");
770 return 0;
771 }
772 }
773 }
774
775 if (demod_probe & 1) {
776 d->fe = dvb_attach(cx24116_attach, &dw2104_config,
777 &d->dev->i2c_adap);
778 if (d->fe != NULL) {
779 d->fe->ops.set_voltage = dw210x_set_voltage;
780 info("Attached cx24116!\n");
781 return 0;
782 }
783 }
784
785 d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
786 &d->dev->i2c_adap);
787 if (d->fe != NULL) {
651 d->fe->ops.set_voltage = dw210x_set_voltage; 788 d->fe->ops.set_voltage = dw210x_set_voltage;
652 info("Attached cx24116!\n"); 789 info("Attached DS3000!\n");
653 return 0; 790 return 0;
654 } 791 }
792
655 return -EIO; 793 return -EIO;
656} 794}
657 795
658static struct dvb_usb_device_properties dw2102_properties; 796static struct dvb_usb_device_properties dw2102_properties;
659static struct dvb_usb_device_properties dw2104_properties; 797static struct dvb_usb_device_properties dw2104_properties;
798static struct dvb_usb_device_properties s6x0_properties;
660 799
661static int dw2102_frontend_attach(struct dvb_usb_adapter *d) 800static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
662{ 801{
@@ -670,14 +809,17 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
670 return 0; 809 return 0;
671 } 810 }
672 } 811 }
812
673 if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) { 813 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, 814 d->fe = dvb_attach(stv0288_attach, &earda_config,
676 &d->dev->i2c_adap); 815 &d->dev->i2c_adap);
677 if (d->fe != NULL) { 816 if (d->fe != NULL) {
678 d->fe->ops.set_voltage = dw210x_set_voltage; 817 if (dvb_attach(stb6000_attach, d->fe, 0x61,
679 info("Attached stv0288!\n"); 818 &d->dev->i2c_adap)) {
680 return 0; 819 d->fe->ops.set_voltage = dw210x_set_voltage;
820 info("Attached stv0288!\n");
821 return 0;
822 }
681 } 823 }
682 } 824 }
683 825
@@ -705,15 +847,38 @@ static int dw3101_frontend_attach(struct dvb_usb_adapter *d)
705 return -EIO; 847 return -EIO;
706} 848}
707 849
708static int s630_frontend_attach(struct dvb_usb_adapter *d) 850static int s6x0_frontend_attach(struct dvb_usb_adapter *d)
709{ 851{
710 d->fe = dvb_attach(mt312_attach, &zl313_config, 852 d->fe = dvb_attach(mt312_attach, &zl313_config,
711 &d->dev->i2c_adap); 853 &d->dev->i2c_adap);
854 if (d->fe != NULL) {
855 if (dvb_attach(zl10039_attach, d->fe, 0x60,
856 &d->dev->i2c_adap)) {
857 d->fe->ops.set_voltage = dw210x_set_voltage;
858 info("Attached zl100313+zl10039!\n");
859 return 0;
860 }
861 }
862
863 d->fe = dvb_attach(stv0288_attach, &earda_config,
864 &d->dev->i2c_adap);
865 if (d->fe != NULL) {
866 if (dvb_attach(stb6000_attach, d->fe, 0x61,
867 &d->dev->i2c_adap)) {
868 d->fe->ops.set_voltage = dw210x_set_voltage;
869 info("Attached stv0288+stb6000!\n");
870 return 0;
871 }
872 }
873
874 d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
875 &d->dev->i2c_adap);
712 if (d->fe != NULL) { 876 if (d->fe != NULL) {
713 d->fe->ops.set_voltage = dw210x_set_voltage; 877 d->fe->ops.set_voltage = dw210x_set_voltage;
714 info("Attached zl10313!\n"); 878 info("Attached ds3000+ds2020!\n");
715 return 0; 879 return 0;
716 } 880 }
881
717 return -EIO; 882 return -EIO;
718} 883}
719 884
@@ -724,14 +889,6 @@ static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
724 return 0; 889 return 0;
725} 890}
726 891
727static 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
735static int dw3101_tuner_attach(struct dvb_usb_adapter *adap) 892static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
736{ 893{
737 dvb_attach(dvb_pll_attach, adap->fe, 0x60, 894 dvb_attach(dvb_pll_attach, adap->fe, 0x60,
@@ -740,14 +897,6 @@ static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
740 return 0; 897 return 0;
741} 898}
742 899
743static 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
751static struct dvb_usb_rc_key dw210x_rc_keys[] = { 900static struct dvb_usb_rc_key dw210x_rc_keys[] = {
752 { 0xf80a, KEY_Q }, /*power*/ 901 { 0xf80a, KEY_Q }, /*power*/
753 { 0xf80c, KEY_M }, /*mute*/ 902 { 0xf80c, KEY_M }, /*mute*/
@@ -922,6 +1071,8 @@ static struct usb_device_id dw2102_table[] = {
922 {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)}, 1071 {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)},
923 {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)}, 1072 {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)},
924 {USB_DEVICE(0x9022, USB_PID_TEVII_S630)}, 1073 {USB_DEVICE(0x9022, USB_PID_TEVII_S630)},
1074 {USB_DEVICE(0x3011, USB_PID_PROF_1100)},
1075 {USB_DEVICE(0x9022, USB_PID_TEVII_S660)},
925 { } 1076 { }
926}; 1077};
927 1078
@@ -935,15 +1086,13 @@ static int dw2102_load_firmware(struct usb_device *dev,
935 u8 reset; 1086 u8 reset;
936 u8 reset16[] = {0, 0, 0, 0, 0, 0, 0}; 1087 u8 reset16[] = {0, 0, 0, 0, 0, 0, 0};
937 const struct firmware *fw; 1088 const struct firmware *fw;
938 const char *filename = "dvb-usb-dw2101.fw"; 1089 const char *fw_2101 = "dvb-usb-dw2101.fw";
939 1090
940 switch (dev->descriptor.idProduct) { 1091 switch (dev->descriptor.idProduct) {
941 case 0x2101: 1092 case 0x2101:
942 ret = request_firmware(&fw, filename, &dev->dev); 1093 ret = request_firmware(&fw, fw_2101, &dev->dev);
943 if (ret != 0) { 1094 if (ret != 0) {
944 err("did not find the firmware file. (%s) " 1095 err(err_str, fw_2101);
945 "Please see linux/Documentation/dvb/ for more details "
946 "on firmware-problems.", filename);
947 return ret; 1096 return ret;
948 } 1097 }
949 break; 1098 break;
@@ -983,6 +1132,11 @@ static int dw2102_load_firmware(struct usb_device *dev,
983 } 1132 }
984 /* init registers */ 1133 /* init registers */
985 switch (dev->descriptor.idProduct) { 1134 switch (dev->descriptor.idProduct) {
1135 case USB_PID_PROF_1100:
1136 s6x0_properties.rc_key_map = tbs_rc_keys;
1137 s6x0_properties.rc_key_map_size =
1138 ARRAY_SIZE(tbs_rc_keys);
1139 break;
986 case USB_PID_TEVII_S650: 1140 case USB_PID_TEVII_S650:
987 dw2104_properties.rc_key_map = tevii_rc_keys; 1141 dw2104_properties.rc_key_map = tevii_rc_keys;
988 dw2104_properties.rc_key_map_size = 1142 dw2104_properties.rc_key_map_size =
@@ -1021,7 +1175,6 @@ static int dw2102_load_firmware(struct usb_device *dev,
1021 DW210X_READ_MSG); 1175 DW210X_READ_MSG);
1022 if (reset16[2] == 0x11) { 1176 if (reset16[2] == 0x11) {
1023 dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo; 1177 dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo;
1024 dw2102_properties.adapter->tuner_attach = &dw2102_earda_tuner_attach;
1025 break; 1178 break;
1026 } 1179 }
1027 } 1180 }
@@ -1184,13 +1337,13 @@ static struct dvb_usb_device_properties dw3101_properties = {
1184 } 1337 }
1185}; 1338};
1186 1339
1187static struct dvb_usb_device_properties s630_properties = { 1340static struct dvb_usb_device_properties s6x0_properties = {
1188 .caps = DVB_USB_IS_AN_I2C_ADAPTER, 1341 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1189 .usb_ctrl = DEVICE_SPECIFIC, 1342 .usb_ctrl = DEVICE_SPECIFIC,
1190 .firmware = "dvb-usb-s630.fw", 1343 .firmware = "dvb-usb-s630.fw",
1191 .no_reconnect = 1, 1344 .no_reconnect = 1,
1192 1345
1193 .i2c_algo = &s630_i2c_algo, 1346 .i2c_algo = &s6x0_i2c_algo,
1194 .rc_key_map = tevii_rc_keys, 1347 .rc_key_map = tevii_rc_keys,
1195 .rc_key_map_size = ARRAY_SIZE(tevii_rc_keys), 1348 .rc_key_map_size = ARRAY_SIZE(tevii_rc_keys),
1196 .rc_interval = 150, 1349 .rc_interval = 150,
@@ -1199,12 +1352,12 @@ static struct dvb_usb_device_properties s630_properties = {
1199 .generic_bulk_ctrl_endpoint = 0x81, 1352 .generic_bulk_ctrl_endpoint = 0x81,
1200 .num_adapters = 1, 1353 .num_adapters = 1,
1201 .download_firmware = dw2102_load_firmware, 1354 .download_firmware = dw2102_load_firmware,
1202 .read_mac_address = s630_read_mac_address, 1355 .read_mac_address = s6x0_read_mac_address,
1203 .adapter = { 1356 .adapter = {
1204 { 1357 {
1205 .frontend_attach = s630_frontend_attach, 1358 .frontend_attach = s6x0_frontend_attach,
1206 .streaming_ctrl = NULL, 1359 .streaming_ctrl = NULL,
1207 .tuner_attach = s630_zl10039_tuner_attach, 1360 .tuner_attach = NULL,
1208 .stream = { 1361 .stream = {
1209 .type = USB_BULK, 1362 .type = USB_BULK,
1210 .count = 8, 1363 .count = 8,
@@ -1217,12 +1370,20 @@ static struct dvb_usb_device_properties s630_properties = {
1217 }, 1370 },
1218 } 1371 }
1219 }, 1372 },
1220 .num_device_descs = 1, 1373 .num_device_descs = 3,
1221 .devices = { 1374 .devices = {
1222 {"TeVii S630 USB", 1375 {"TeVii S630 USB",
1223 {&dw2102_table[6], NULL}, 1376 {&dw2102_table[6], NULL},
1224 {NULL}, 1377 {NULL},
1225 }, 1378 },
1379 {"Prof 1100 USB ",
1380 {&dw2102_table[7], NULL},
1381 {NULL},
1382 },
1383 {"TeVii S660 USB",
1384 {&dw2102_table[8], NULL},
1385 {NULL},
1386 },
1226 } 1387 }
1227}; 1388};
1228 1389
@@ -1235,10 +1396,10 @@ static int dw2102_probe(struct usb_interface *intf,
1235 THIS_MODULE, NULL, adapter_nr) || 1396 THIS_MODULE, NULL, adapter_nr) ||
1236 0 == dvb_usb_device_init(intf, &dw3101_properties, 1397 0 == dvb_usb_device_init(intf, &dw3101_properties,
1237 THIS_MODULE, NULL, adapter_nr) || 1398 THIS_MODULE, NULL, adapter_nr) ||
1238 0 == dvb_usb_device_init(intf, &s630_properties, 1399 0 == dvb_usb_device_init(intf, &s6x0_properties,
1239 THIS_MODULE, NULL, adapter_nr)) { 1400 THIS_MODULE, NULL, adapter_nr))
1240 return 0; 1401 return 0;
1241 } 1402
1242 return -ENODEV; 1403 return -ENODEV;
1243} 1404}
1244 1405
@@ -1269,6 +1430,7 @@ module_exit(dw2102_module_exit);
1269MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); 1430MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
1270MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104," 1431MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104,"
1271 " DVB-C 3101 USB2.0," 1432 " DVB-C 3101 USB2.0,"
1272 " TeVii S600, S630, S650 USB2.0 devices"); 1433 " TeVii S600, S630, S650, S660 USB2.0,"
1434 " Prof 1100 USB2.0 devices");
1273MODULE_VERSION("0.1"); 1435MODULE_VERSION("0.1");
1274MODULE_LICENSE("GPL"); 1436MODULE_LICENSE("GPL");