aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
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");