diff options
Diffstat (limited to 'drivers/media/dvb/dvb-usb/dw2102.c')
-rw-r--r-- | drivers/media/dvb/dvb-usb/dw2102.c | 325 |
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 | ||
43 | struct dw210x_state { | 52 | struct dvb_usb_rc_keys_table { |
44 | u32 last_key_pressed; | 53 | struct dvb_usb_rc_key *rc_keys; |
45 | }; | 54 | int rc_keys_size; |
46 | struct dw210x_rc_keys { | ||
47 | u32 keycode; | ||
48 | u32 event; | ||
49 | }; | 55 | }; |
50 | 56 | ||
51 | /* debug */ | 57 | /* debug */ |
52 | static int dvb_usb_dw2102_debug; | 58 | static int dvb_usb_dw2102_debug; |
53 | module_param_named(debug, dvb_usb_dw2102_debug, int, 0644); | 59 | module_param_named(debug, dvb_usb_dw2102_debug, int, 0644); |
54 | MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer (or-able))." DVB_USB_DEBUG_STATUS); | 60 | MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))." |
61 | DVB_USB_DEBUG_STATUS); | ||
62 | |||
63 | /* keymaps */ | ||
64 | static int ir_keymap; | ||
65 | module_param_named(keymap, ir_keymap, int, 0644); | ||
66 | MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ..."); | ||
55 | 67 | ||
56 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | 68 | DVB_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, | |||
79 | static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], | 91 | static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], |
80 | int num) | 92 | int num) |
81 | { | 93 | { |
82 | struct 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 | |||
208 | static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) | 221 | static 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 | ||
376 | static 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 | |||
363 | static u32 dw210x_i2c_func(struct i2c_adapter *adapter) | 439 | static 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 | ||
464 | static struct i2c_algorithm dw3101_i2c_algo = { | ||
465 | .master_xfer = dw3101_i2c_transfer, | ||
466 | .functionality = dw210x_i2c_func, | ||
467 | }; | ||
468 | |||
388 | static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) | 469 | static 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 | ||
533 | static struct tda10023_config dw3101_tda10023_config = { | ||
534 | .demod_address = 0x0c, | ||
535 | .invert = 1, | ||
536 | }; | ||
537 | |||
451 | static int dw2104_frontend_attach(struct dvb_usb_adapter *d) | 538 | static 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 | ||
462 | static struct dvb_usb_device_properties dw2102_properties; | 549 | static struct dvb_usb_device_properties dw2102_properties; |
550 | static struct dvb_usb_device_properties dw2104_properties; | ||
463 | 551 | ||
464 | static int dw2102_frontend_attach(struct dvb_usb_adapter *d) | 552 | static 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 | ||
588 | static 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 | |||
500 | static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) | 599 | static 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 | ||
614 | static 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 | |||
515 | static struct dvb_usb_rc_key dw210x_rc_keys[] = { | 622 | static 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 | ||
656 | static 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 | ||
706 | static 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 | ||
741 | static 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 | ||
552 | static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | 747 | static 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 | ||
579 | static struct usb_device_id dw2102_table[] = { | 788 | static 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 | ||
1013 | static 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 | |||
799 | static int dw2102_probe(struct usb_interface *intf, | 1056 | static 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); | |||
833 | module_exit(dw2102_module_exit); | 1092 | module_exit(dw2102_module_exit); |
834 | 1093 | ||
835 | MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); | 1094 | MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); |
836 | MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104 USB2.0 device"); | 1095 | MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104," |
1096 | " DVB-C 3101 USB2.0," | ||
1097 | " TeVii S600, S650 USB2.0 devices"); | ||
837 | MODULE_VERSION("0.1"); | 1098 | MODULE_VERSION("0.1"); |
838 | MODULE_LICENSE("GPL"); | 1099 | MODULE_LICENSE("GPL"); |