aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/dvb-usb/dw2102.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/dvb-usb/dw2102.c')
-rw-r--r--drivers/media/dvb/dvb-usb/dw2102.c325
1 files changed, 293 insertions, 32 deletions
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c
index c65f273ff313..75de49c0d943 100644
--- a/drivers/media/dvb/dvb-usb/dw2102.c
+++ b/drivers/media/dvb/dvb-usb/dw2102.c
@@ -1,7 +1,7 @@
1/* DVB USB framework compliant Linux driver for the 1/* DVB USB framework compliant Linux driver for the
2* DVBWorld DVB-S 2101, 2102, DVB-S2 2104 Card 2* DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101,
3* 3* TeVii S600, S650 Cards
4* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) 4* Copyright (C) 2008,2009 Igor M. Liplianin (liplianin@me.by)
5* 5*
6* This program is free software; you can redistribute it and/or modify it 6* This program is free software; you can redistribute it and/or modify it
7* under the terms of the GNU General Public License as published by the 7* under the terms of the GNU General Public License as published by the
@@ -17,6 +17,7 @@
17#include "stb6000.h" 17#include "stb6000.h"
18#include "eds1547.h" 18#include "eds1547.h"
19#include "cx24116.h" 19#include "cx24116.h"
20#include "tda1002x.h"
20 21
21#ifndef USB_PID_DW2102 22#ifndef USB_PID_DW2102
22#define USB_PID_DW2102 0x2102 23#define USB_PID_DW2102 0x2102
@@ -26,10 +27,18 @@
26#define USB_PID_DW2104 0x2104 27#define USB_PID_DW2104 0x2104
27#endif 28#endif
28 29
30#ifndef USB_PID_DW3101
31#define USB_PID_DW3101 0x3101
32#endif
33
29#ifndef USB_PID_CINERGY_S 34#ifndef USB_PID_CINERGY_S
30#define USB_PID_CINERGY_S 0x0064 35#define USB_PID_CINERGY_S 0x0064
31#endif 36#endif
32 37
38#ifndef USB_PID_TEVII_S650
39#define USB_PID_TEVII_S650 0xd650
40#endif
41
33#define DW210X_READ_MSG 0 42#define DW210X_READ_MSG 0
34#define DW210X_WRITE_MSG 1 43#define DW210X_WRITE_MSG 1
35 44
@@ -40,18 +49,21 @@
40#define DW2102_VOLTAGE_CTRL (0x1800) 49#define DW2102_VOLTAGE_CTRL (0x1800)
41#define DW2102_RC_QUERY (0x1a00) 50#define DW2102_RC_QUERY (0x1a00)
42 51
43struct dw210x_state { 52struct dvb_usb_rc_keys_table {
44 u32 last_key_pressed; 53 struct dvb_usb_rc_key *rc_keys;
45}; 54 int rc_keys_size;
46struct dw210x_rc_keys {
47 u32 keycode;
48 u32 event;
49}; 55};
50 56
51/* debug */ 57/* debug */
52static int dvb_usb_dw2102_debug; 58static int dvb_usb_dw2102_debug;
53module_param_named(debug, dvb_usb_dw2102_debug, int, 0644); 59module_param_named(debug, dvb_usb_dw2102_debug, int, 0644);
54MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer (or-able))." DVB_USB_DEBUG_STATUS); 60MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))."
61 DVB_USB_DEBUG_STATUS);
62
63/* keymaps */
64static int ir_keymap;
65module_param_named(keymap, ir_keymap, int, 0644);
66MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ...");
55 67
56DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 68DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
57 69
@@ -79,7 +91,7 @@ static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value,
79static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], 91static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
80 int num) 92 int num)
81{ 93{
82struct dvb_usb_device *d = i2c_get_adapdata(adap); 94 struct dvb_usb_device *d = i2c_get_adapdata(adap);
83 int i = 0, ret = 0; 95 int i = 0, ret = 0;
84 u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0}; 96 u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0};
85 u16 value; 97 u16 value;
@@ -205,6 +217,7 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
205 mutex_unlock(&d->i2c_mutex); 217 mutex_unlock(&d->i2c_mutex);
206 return num; 218 return num;
207} 219}
220
208static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) 221static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
209{ 222{
210 struct dvb_usb_device *d = i2c_get_adapdata(adap); 223 struct dvb_usb_device *d = i2c_get_adapdata(adap);
@@ -219,7 +232,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
219 case 2: { 232 case 2: {
220 /* read */ 233 /* read */
221 /* first write first register number */ 234 /* first write first register number */
222 u8 ibuf [msg[1].len + 2], obuf[3]; 235 u8 ibuf[msg[1].len + 2], obuf[3];
223 obuf[0] = 0xd0; 236 obuf[0] = 0xd0;
224 obuf[1] = msg[0].len; 237 obuf[1] = msg[0].len;
225 obuf[2] = msg[0].buf[0]; 238 obuf[2] = msg[0].buf[0];
@@ -293,7 +306,7 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
293 case 2: { 306 case 2: {
294 /* read */ 307 /* read */
295 /* first write first register number */ 308 /* first write first register number */
296 u8 ibuf [msg[1].len + 2], obuf[3]; 309 u8 ibuf[msg[1].len + 2], obuf[3];
297 obuf[0] = 0xaa; 310 obuf[0] = 0xaa;
298 obuf[1] = msg[0].len; 311 obuf[1] = msg[0].len;
299 obuf[2] = msg[0].buf[0]; 312 obuf[2] = msg[0].buf[0];
@@ -360,6 +373,69 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
360 return num; 373 return num;
361} 374}
362 375
376static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
377 int num)
378{
379 struct dvb_usb_device *d = i2c_get_adapdata(adap);
380 int ret = 0, i;
381
382 if (!d)
383 return -ENODEV;
384 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
385 return -EAGAIN;
386
387 switch (num) {
388 case 2: {
389 /* read */
390 /* first write first register number */
391 u8 ibuf[msg[1].len + 2], obuf[3];
392 obuf[0] = msg[0].addr << 1;
393 obuf[1] = msg[0].len;
394 obuf[2] = msg[0].buf[0];
395 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
396 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
397 /* second read registers */
398 ret = dw210x_op_rw(d->udev, 0xc3, 0x19 , 0,
399 ibuf, msg[1].len + 2, DW210X_READ_MSG);
400 memcpy(msg[1].buf, ibuf + 2, msg[1].len);
401
402 break;
403 }
404 case 1:
405 switch (msg[0].addr) {
406 case 0x60:
407 case 0x0c: {
408 /* write to register */
409 u8 obuf[msg[0].len + 2];
410 obuf[0] = msg[0].addr << 1;
411 obuf[1] = msg[0].len;
412 memcpy(obuf + 2, msg[0].buf, msg[0].len);
413 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
414 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
415 break;
416 }
417 case(DW2102_RC_QUERY): {
418 u8 ibuf[2];
419 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
420 ibuf, 2, DW210X_READ_MSG);
421 memcpy(msg[0].buf, ibuf , 2);
422 break;
423 }
424 }
425
426 break;
427 }
428
429 for (i = 0; i < num; i++) {
430 deb_xfer("%02x:%02x: %s ", i, msg[i].addr,
431 msg[i].flags == 0 ? ">>>" : "<<<");
432 debug_dump(msg[i].buf, msg[i].len, deb_xfer);
433 }
434
435 mutex_unlock(&d->i2c_mutex);
436 return num;
437}
438
363static u32 dw210x_i2c_func(struct i2c_adapter *adapter) 439static u32 dw210x_i2c_func(struct i2c_adapter *adapter)
364{ 440{
365 return I2C_FUNC_I2C; 441 return I2C_FUNC_I2C;
@@ -385,6 +461,11 @@ static struct i2c_algorithm dw2104_i2c_algo = {
385 .functionality = dw210x_i2c_func, 461 .functionality = dw210x_i2c_func,
386}; 462};
387 463
464static struct i2c_algorithm dw3101_i2c_algo = {
465 .master_xfer = dw3101_i2c_transfer,
466 .functionality = dw210x_i2c_func,
467};
468
388static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) 469static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
389{ 470{
390 int i; 471 int i;
@@ -404,6 +485,7 @@ static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
404 debug_dump(eepromline, 16, deb_xfer); 485 debug_dump(eepromline, 16, deb_xfer);
405 } 486 }
406 } 487 }
488
407 memcpy(mac, eeprom + 8, 6); 489 memcpy(mac, eeprom + 8, 6);
408 return 0; 490 return 0;
409}; 491};
@@ -448,6 +530,11 @@ static struct si21xx_config serit_sp1511lhb_config = {
448 530
449}; 531};
450 532
533static struct tda10023_config dw3101_tda10023_config = {
534 .demod_address = 0x0c,
535 .invert = 1,
536};
537
451static int dw2104_frontend_attach(struct dvb_usb_adapter *d) 538static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
452{ 539{
453 if ((d->fe = dvb_attach(cx24116_attach, &dw2104_config, 540 if ((d->fe = dvb_attach(cx24116_attach, &dw2104_config,
@@ -460,6 +547,7 @@ static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
460} 547}
461 548
462static struct dvb_usb_device_properties dw2102_properties; 549static struct dvb_usb_device_properties dw2102_properties;
550static struct dvb_usb_device_properties dw2104_properties;
463 551
464static int dw2102_frontend_attach(struct dvb_usb_adapter *d) 552static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
465{ 553{
@@ -497,6 +585,17 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
497 return -EIO; 585 return -EIO;
498} 586}
499 587
588static int dw3101_frontend_attach(struct dvb_usb_adapter *d)
589{
590 d->fe = dvb_attach(tda10023_attach, &dw3101_tda10023_config,
591 &d->dev->i2c_adap, 0x48);
592 if (d->fe != NULL) {
593 info("Attached tda10023!\n");
594 return 0;
595 }
596 return -EIO;
597}
598
500static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) 599static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
501{ 600{
502 dvb_attach(dvb_pll_attach, adap->fe, 0x60, 601 dvb_attach(dvb_pll_attach, adap->fe, 0x60,
@@ -512,6 +611,14 @@ static int dw2102_earda_tuner_attach(struct dvb_usb_adapter *adap)
512 return 0; 611 return 0;
513} 612}
514 613
614static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
615{
616 dvb_attach(dvb_pll_attach, adap->fe, 0x60,
617 &adap->dev->i2c_adap, DVB_PLL_TUA6034);
618
619 return 0;
620}
621
515static struct dvb_usb_rc_key dw210x_rc_keys[] = { 622static struct dvb_usb_rc_key dw210x_rc_keys[] = {
516 { 0xf8, 0x0a, KEY_Q }, /*power*/ 623 { 0xf8, 0x0a, KEY_Q }, /*power*/
517 { 0xf8, 0x0c, KEY_M }, /*mute*/ 624 { 0xf8, 0x0c, KEY_M }, /*mute*/
@@ -544,44 +651,147 @@ static struct dvb_usb_rc_key dw210x_rc_keys[] = {
544 { 0xf8, 0x40, KEY_F }, /*full*/ 651 { 0xf8, 0x40, KEY_F }, /*full*/
545 { 0xf8, 0x1e, KEY_W }, /*tvmode*/ 652 { 0xf8, 0x1e, KEY_W }, /*tvmode*/
546 { 0xf8, 0x1b, KEY_B }, /*recall*/ 653 { 0xf8, 0x1b, KEY_B }, /*recall*/
654};
547 655
656static struct dvb_usb_rc_key tevii_rc_keys[] = {
657 { 0xf8, 0x0a, KEY_POWER },
658 { 0xf8, 0x0c, KEY_MUTE },
659 { 0xf8, 0x11, KEY_1 },
660 { 0xf8, 0x12, KEY_2 },
661 { 0xf8, 0x13, KEY_3 },
662 { 0xf8, 0x14, KEY_4 },
663 { 0xf8, 0x15, KEY_5 },
664 { 0xf8, 0x16, KEY_6 },
665 { 0xf8, 0x17, KEY_7 },
666 { 0xf8, 0x18, KEY_8 },
667 { 0xf8, 0x19, KEY_9 },
668 { 0xf8, 0x10, KEY_0 },
669 { 0xf8, 0x1c, KEY_MENU },
670 { 0xf8, 0x0f, KEY_VOLUMEDOWN },
671 { 0xf8, 0x1a, KEY_LAST },
672 { 0xf8, 0x0e, KEY_OPEN },
673 { 0xf8, 0x04, KEY_RECORD },
674 { 0xf8, 0x09, KEY_VOLUMEUP },
675 { 0xf8, 0x08, KEY_CHANNELUP },
676 { 0xf8, 0x07, KEY_PVR },
677 { 0xf8, 0x0b, KEY_TIME },
678 { 0xf8, 0x02, KEY_RIGHT },
679 { 0xf8, 0x03, KEY_LEFT },
680 { 0xf8, 0x00, KEY_UP },
681 { 0xf8, 0x1f, KEY_OK },
682 { 0xf8, 0x01, KEY_DOWN },
683 { 0xf8, 0x05, KEY_TUNER },
684 { 0xf8, 0x06, KEY_CHANNELDOWN },
685 { 0xf8, 0x40, KEY_PLAYPAUSE },
686 { 0xf8, 0x1e, KEY_REWIND },
687 { 0xf8, 0x1b, KEY_FAVORITES },
688 { 0xf8, 0x1d, KEY_BACK },
689 { 0xf8, 0x4d, KEY_FASTFORWARD },
690 { 0xf8, 0x44, KEY_EPG },
691 { 0xf8, 0x4c, KEY_INFO },
692 { 0xf8, 0x41, KEY_AB },
693 { 0xf8, 0x43, KEY_AUDIO },
694 { 0xf8, 0x45, KEY_SUBTITLE },
695 { 0xf8, 0x4a, KEY_LIST },
696 { 0xf8, 0x46, KEY_F1 },
697 { 0xf8, 0x47, KEY_F2 },
698 { 0xf8, 0x5e, KEY_F3 },
699 { 0xf8, 0x5c, KEY_F4 },
700 { 0xf8, 0x52, KEY_F5 },
701 { 0xf8, 0x5a, KEY_F6 },
702 { 0xf8, 0x56, KEY_MODE },
703 { 0xf8, 0x58, KEY_SWITCHVIDEOMODE },
548}; 704};
549 705
706static struct dvb_usb_rc_key tbs_rc_keys[] = {
707 { 0xf8, 0x84, KEY_POWER },
708 { 0xf8, 0x94, KEY_MUTE },
709 { 0xf8, 0x87, KEY_1 },
710 { 0xf8, 0x86, KEY_2 },
711 { 0xf8, 0x85, KEY_3 },
712 { 0xf8, 0x8b, KEY_4 },
713 { 0xf8, 0x8a, KEY_5 },
714 { 0xf8, 0x89, KEY_6 },
715 { 0xf8, 0x8f, KEY_7 },
716 { 0xf8, 0x8e, KEY_8 },
717 { 0xf8, 0x8d, KEY_9 },
718 { 0xf8, 0x92, KEY_0 },
719 { 0xf8, 0x96, KEY_CHANNELUP },
720 { 0xf8, 0x91, KEY_CHANNELDOWN },
721 { 0xf8, 0x93, KEY_VOLUMEUP },
722 { 0xf8, 0x8c, KEY_VOLUMEDOWN },
723 { 0xf8, 0x83, KEY_RECORD },
724 { 0xf8, 0x98, KEY_PAUSE },
725 { 0xf8, 0x99, KEY_OK },
726 { 0xf8, 0x9a, KEY_SHUFFLE },
727 { 0xf8, 0x81, KEY_UP },
728 { 0xf8, 0x90, KEY_LEFT },
729 { 0xf8, 0x82, KEY_RIGHT },
730 { 0xf8, 0x88, KEY_DOWN },
731 { 0xf8, 0x95, KEY_FAVORITES },
732 { 0xf8, 0x97, KEY_SUBTITLE },
733 { 0xf8, 0x9d, KEY_ZOOM },
734 { 0xf8, 0x9f, KEY_EXIT },
735 { 0xf8, 0x9e, KEY_MENU },
736 { 0xf8, 0x9c, KEY_EPG },
737 { 0xf8, 0x80, KEY_PREVIOUS },
738 { 0xf8, 0x9b, KEY_MODE }
739};
550 740
741static struct dvb_usb_rc_keys_table keys_tables[] = {
742 { dw210x_rc_keys, ARRAY_SIZE(dw210x_rc_keys) },
743 { tevii_rc_keys, ARRAY_SIZE(tevii_rc_keys) },
744 { tbs_rc_keys, ARRAY_SIZE(tbs_rc_keys) },
745};
551 746
552static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) 747static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
553{ 748{
554 struct dw210x_state *st = d->priv; 749 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
750 int keymap_size = d->props.rc_key_map_size;
555 u8 key[2]; 751 u8 key[2];
556 struct i2c_msg msg[] = { 752 struct i2c_msg msg = {
557 {.addr = DW2102_RC_QUERY, .flags = I2C_M_RD, .buf = key, 753 .addr = DW2102_RC_QUERY,
558 .len = 2}, 754 .flags = I2C_M_RD,
755 .buf = key,
756 .len = 2
559 }; 757 };
560 int i; 758 int i;
759 /* override keymap */
760 if ((ir_keymap > 0) && (ir_keymap <= ARRAY_SIZE(keys_tables))) {
761 keymap = keys_tables[ir_keymap - 1].rc_keys ;
762 keymap_size = keys_tables[ir_keymap - 1].rc_keys_size;
763 }
561 764
562 *state = REMOTE_NO_KEY_PRESSED; 765 *state = REMOTE_NO_KEY_PRESSED;
563 if (dw2102_i2c_transfer(&d->i2c_adap, msg, 1) == 1) { 766 if (dw2102_i2c_transfer(&d->i2c_adap, &msg, 1) == 1) {
564 for (i = 0; i < ARRAY_SIZE(dw210x_rc_keys); i++) { 767 for (i = 0; i < keymap_size ; i++) {
565 if (dw210x_rc_keys[i].data == msg[0].buf[0]) { 768 if (keymap[i].data == msg.buf[0]) {
566 *state = REMOTE_KEY_PRESSED; 769 *state = REMOTE_KEY_PRESSED;
567 *event = dw210x_rc_keys[i].event; 770 *event = keymap[i].event;
568 st->last_key_pressed =
569 dw210x_rc_keys[i].event;
570 break; 771 break;
571 } 772 }
572 st->last_key_pressed = 0; 773
573 } 774 }
775
776 if ((*state) == REMOTE_KEY_PRESSED)
777 deb_rc("%s: found rc key: %x, %x, event: %x\n",
778 __func__, key[0], key[1], (*event));
779 else if (key[0] != 0xff)
780 deb_rc("%s: unknown rc key: %x, %x\n",
781 __func__, key[0], key[1]);
782
574 } 783 }
575 /* info("key: %x %x\n",key[0],key[1]); */ 784
576 return 0; 785 return 0;
577} 786}
578 787
579static struct usb_device_id dw2102_table[] = { 788static struct usb_device_id dw2102_table[] = {
580 {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)}, 789 {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)},
581 {USB_DEVICE(USB_VID_CYPRESS, 0x2101)}, 790 {USB_DEVICE(USB_VID_CYPRESS, 0x2101)},
582 {USB_DEVICE(USB_VID_CYPRESS, 0x2104)}, 791 {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2104)},
583 {USB_DEVICE(0x9022, 0xd650)}, 792 {USB_DEVICE(0x9022, USB_PID_TEVII_S650)},
584 {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)}, 793 {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)},
794 {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)},
585 { } 795 { }
586}; 796};
587 797
@@ -642,11 +852,16 @@ static int dw2102_load_firmware(struct usb_device *dev,
642 } 852 }
643 /* init registers */ 853 /* init registers */
644 switch (dev->descriptor.idProduct) { 854 switch (dev->descriptor.idProduct) {
855 case USB_PID_TEVII_S650:
856 dw2104_properties.rc_key_map = tevii_rc_keys;
857 dw2104_properties.rc_key_map_size =
858 ARRAY_SIZE(tevii_rc_keys);
645 case USB_PID_DW2104: 859 case USB_PID_DW2104:
646 case 0xd650:
647 reset = 1; 860 reset = 1;
648 dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1, 861 dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1,
649 DW210X_WRITE_MSG); 862 DW210X_WRITE_MSG);
863 /* break omitted intentionally */
864 case USB_PID_DW3101:
650 reset = 0; 865 reset = 0;
651 dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0, 866 dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
652 DW210X_WRITE_MSG); 867 DW210X_WRITE_MSG);
@@ -690,6 +905,7 @@ static int dw2102_load_firmware(struct usb_device *dev,
690 DW210X_READ_MSG); 905 DW210X_READ_MSG);
691 break; 906 break;
692 } 907 }
908
693 msleep(100); 909 msleep(100);
694 kfree(p); 910 kfree(p);
695 } 911 }
@@ -700,7 +916,6 @@ static struct dvb_usb_device_properties dw2102_properties = {
700 .caps = DVB_USB_IS_AN_I2C_ADAPTER, 916 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
701 .usb_ctrl = DEVICE_SPECIFIC, 917 .usb_ctrl = DEVICE_SPECIFIC,
702 .firmware = "dvb-usb-dw2102.fw", 918 .firmware = "dvb-usb-dw2102.fw",
703 .size_of_priv = sizeof(struct dw210x_state),
704 .no_reconnect = 1, 919 .no_reconnect = 1,
705 920
706 .i2c_algo = &dw2102_serit_i2c_algo, 921 .i2c_algo = &dw2102_serit_i2c_algo,
@@ -714,7 +929,7 @@ static struct dvb_usb_device_properties dw2102_properties = {
714 .num_adapters = 1, 929 .num_adapters = 1,
715 .download_firmware = dw2102_load_firmware, 930 .download_firmware = dw2102_load_firmware,
716 .read_mac_address = dw210x_read_mac_address, 931 .read_mac_address = dw210x_read_mac_address,
717 .adapter = { 932 .adapter = {
718 { 933 {
719 .frontend_attach = dw2102_frontend_attach, 934 .frontend_attach = dw2102_frontend_attach,
720 .streaming_ctrl = NULL, 935 .streaming_ctrl = NULL,
@@ -752,7 +967,6 @@ static struct dvb_usb_device_properties dw2104_properties = {
752 .caps = DVB_USB_IS_AN_I2C_ADAPTER, 967 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
753 .usb_ctrl = DEVICE_SPECIFIC, 968 .usb_ctrl = DEVICE_SPECIFIC,
754 .firmware = "dvb-usb-dw2104.fw", 969 .firmware = "dvb-usb-dw2104.fw",
755 .size_of_priv = sizeof(struct dw210x_state),
756 .no_reconnect = 1, 970 .no_reconnect = 1,
757 971
758 .i2c_algo = &dw2104_i2c_algo, 972 .i2c_algo = &dw2104_i2c_algo,
@@ -796,12 +1010,57 @@ static struct dvb_usb_device_properties dw2104_properties = {
796 } 1010 }
797}; 1011};
798 1012
1013static struct dvb_usb_device_properties dw3101_properties = {
1014 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1015 .usb_ctrl = DEVICE_SPECIFIC,
1016 .firmware = "dvb-usb-dw3101.fw",
1017 .no_reconnect = 1,
1018
1019 .i2c_algo = &dw3101_i2c_algo,
1020 .rc_key_map = dw210x_rc_keys,
1021 .rc_key_map_size = ARRAY_SIZE(dw210x_rc_keys),
1022 .rc_interval = 150,
1023 .rc_query = dw2102_rc_query,
1024
1025 .generic_bulk_ctrl_endpoint = 0x81,
1026 /* parameter for the MPEG2-data transfer */
1027 .num_adapters = 1,
1028 .download_firmware = dw2102_load_firmware,
1029 .read_mac_address = dw210x_read_mac_address,
1030 .adapter = {
1031 {
1032 .frontend_attach = dw3101_frontend_attach,
1033 .streaming_ctrl = NULL,
1034 .tuner_attach = dw3101_tuner_attach,
1035 .stream = {
1036 .type = USB_BULK,
1037 .count = 8,
1038 .endpoint = 0x82,
1039 .u = {
1040 .bulk = {
1041 .buffersize = 4096,
1042 }
1043 }
1044 },
1045 }
1046 },
1047 .num_device_descs = 1,
1048 .devices = {
1049 { "DVBWorld DVB-C 3101 USB2.0",
1050 {&dw2102_table[5], NULL},
1051 {NULL},
1052 },
1053 }
1054};
1055
799static int dw2102_probe(struct usb_interface *intf, 1056static int dw2102_probe(struct usb_interface *intf,
800 const struct usb_device_id *id) 1057 const struct usb_device_id *id)
801{ 1058{
802 if (0 == dvb_usb_device_init(intf, &dw2102_properties, 1059 if (0 == dvb_usb_device_init(intf, &dw2102_properties,
803 THIS_MODULE, NULL, adapter_nr) || 1060 THIS_MODULE, NULL, adapter_nr) ||
804 0 == dvb_usb_device_init(intf, &dw2104_properties, 1061 0 == dvb_usb_device_init(intf, &dw2104_properties,
1062 THIS_MODULE, NULL, adapter_nr) ||
1063 0 == dvb_usb_device_init(intf, &dw3101_properties,
805 THIS_MODULE, NULL, adapter_nr)) { 1064 THIS_MODULE, NULL, adapter_nr)) {
806 return 0; 1065 return 0;
807 } 1066 }
@@ -833,6 +1092,8 @@ module_init(dw2102_module_init);
833module_exit(dw2102_module_exit); 1092module_exit(dw2102_module_exit);
834 1093
835MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); 1094MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
836MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104 USB2.0 device"); 1095MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104,"
1096 " DVB-C 3101 USB2.0,"
1097 " TeVii S600, S650 USB2.0 devices");
837MODULE_VERSION("0.1"); 1098MODULE_VERSION("0.1");
838MODULE_LICENSE("GPL"); 1099MODULE_LICENSE("GPL");