diff options
Diffstat (limited to 'drivers/media/dvb/dvb-usb/dw2102.c')
-rw-r--r-- | drivers/media/dvb/dvb-usb/dw2102.c | 126 |
1 files changed, 110 insertions, 16 deletions
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index dee9399f8597..06a0aa1ae2cb 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c | |||
@@ -40,12 +40,9 @@ | |||
40 | #define DW2102_VOLTAGE_CTRL (0x1800) | 40 | #define DW2102_VOLTAGE_CTRL (0x1800) |
41 | #define DW2102_RC_QUERY (0x1a00) | 41 | #define DW2102_RC_QUERY (0x1a00) |
42 | 42 | ||
43 | struct dw210x_state { | 43 | struct dvb_usb_rc_keys_table { |
44 | u32 last_key_pressed; | 44 | struct dvb_usb_rc_key *rc_keys; |
45 | }; | 45 | int rc_keys_size; |
46 | struct dw210x_rc_keys { | ||
47 | u32 keycode; | ||
48 | u32 event; | ||
49 | }; | 46 | }; |
50 | 47 | ||
51 | /* debug */ | 48 | /* debug */ |
@@ -54,6 +51,10 @@ module_param_named(debug, dvb_usb_dw2102_debug, int, 0644); | |||
54 | MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))." | 51 | MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))." |
55 | DVB_USB_DEBUG_STATUS); | 52 | DVB_USB_DEBUG_STATUS); |
56 | 53 | ||
54 | /* keymaps */ | ||
55 | static int ir_keymap; | ||
56 | module_param_named(keymap, ir_keymap, int, 0644); | ||
57 | MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ..."); | ||
57 | 58 | ||
58 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | 59 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
59 | 60 | ||
@@ -462,6 +463,7 @@ static int dw2104_frontend_attach(struct dvb_usb_adapter *d) | |||
462 | } | 463 | } |
463 | 464 | ||
464 | static struct dvb_usb_device_properties dw2102_properties; | 465 | static struct dvb_usb_device_properties dw2102_properties; |
466 | static struct dvb_usb_device_properties dw2104_properties; | ||
465 | 467 | ||
466 | static int dw2102_frontend_attach(struct dvb_usb_adapter *d) | 468 | static int dw2102_frontend_attach(struct dvb_usb_adapter *d) |
467 | { | 469 | { |
@@ -546,14 +548,103 @@ static struct dvb_usb_rc_key dw210x_rc_keys[] = { | |||
546 | { 0xf8, 0x40, KEY_F }, /*full*/ | 548 | { 0xf8, 0x40, KEY_F }, /*full*/ |
547 | { 0xf8, 0x1e, KEY_W }, /*tvmode*/ | 549 | { 0xf8, 0x1e, KEY_W }, /*tvmode*/ |
548 | { 0xf8, 0x1b, KEY_B }, /*recall*/ | 550 | { 0xf8, 0x1b, KEY_B }, /*recall*/ |
551 | }; | ||
549 | 552 | ||
553 | static struct dvb_usb_rc_key tevii_rc_keys[] = { | ||
554 | { 0xf8, 0x0a, KEY_POWER }, | ||
555 | { 0xf8, 0x0c, KEY_MUTE }, | ||
556 | { 0xf8, 0x11, KEY_1 }, | ||
557 | { 0xf8, 0x12, KEY_2 }, | ||
558 | { 0xf8, 0x13, KEY_3 }, | ||
559 | { 0xf8, 0x14, KEY_4 }, | ||
560 | { 0xf8, 0x15, KEY_5 }, | ||
561 | { 0xf8, 0x16, KEY_6 }, | ||
562 | { 0xf8, 0x17, KEY_7 }, | ||
563 | { 0xf8, 0x18, KEY_8 }, | ||
564 | { 0xf8, 0x19, KEY_9 }, | ||
565 | { 0xf8, 0x10, KEY_0 }, | ||
566 | { 0xf8, 0x1c, KEY_MENU }, | ||
567 | { 0xf8, 0x0f, KEY_VOLUMEDOWN }, | ||
568 | { 0xf8, 0x1a, KEY_LAST }, | ||
569 | { 0xf8, 0x0e, KEY_OPEN }, | ||
570 | { 0xf8, 0x04, KEY_RECORD }, | ||
571 | { 0xf8, 0x09, KEY_VOLUMEUP }, | ||
572 | { 0xf8, 0x08, KEY_CHANNELUP }, | ||
573 | { 0xf8, 0x07, KEY_PVR }, | ||
574 | { 0xf8, 0x0b, KEY_TIME }, | ||
575 | { 0xf8, 0x02, KEY_RIGHT }, | ||
576 | { 0xf8, 0x03, KEY_LEFT }, | ||
577 | { 0xf8, 0x00, KEY_UP }, | ||
578 | { 0xf8, 0x1f, KEY_OK }, | ||
579 | { 0xf8, 0x01, KEY_DOWN }, | ||
580 | { 0xf8, 0x05, KEY_TUNER }, | ||
581 | { 0xf8, 0x06, KEY_CHANNELDOWN }, | ||
582 | { 0xf8, 0x40, KEY_PLAYPAUSE }, | ||
583 | { 0xf8, 0x1e, KEY_REWIND }, | ||
584 | { 0xf8, 0x1b, KEY_FAVORITES }, | ||
585 | { 0xf8, 0x1d, KEY_BACK }, | ||
586 | { 0xf8, 0x4d, KEY_FASTFORWARD }, | ||
587 | { 0xf8, 0x44, KEY_EPG }, | ||
588 | { 0xf8, 0x4c, KEY_INFO }, | ||
589 | { 0xf8, 0x41, KEY_AB }, | ||
590 | { 0xf8, 0x43, KEY_AUDIO }, | ||
591 | { 0xf8, 0x45, KEY_SUBTITLE }, | ||
592 | { 0xf8, 0x4a, KEY_LIST }, | ||
593 | { 0xf8, 0x46, KEY_F1 }, | ||
594 | { 0xf8, 0x47, KEY_F2 }, | ||
595 | { 0xf8, 0x5e, KEY_F3 }, | ||
596 | { 0xf8, 0x5c, KEY_F4 }, | ||
597 | { 0xf8, 0x52, KEY_F5 }, | ||
598 | { 0xf8, 0x5a, KEY_F6 }, | ||
599 | { 0xf8, 0x56, KEY_MODE }, | ||
600 | { 0xf8, 0x58, KEY_SWITCHVIDEOMODE }, | ||
550 | }; | 601 | }; |
551 | 602 | ||
603 | static struct dvb_usb_rc_key tbs_rc_keys[] = { | ||
604 | { 0xf8, 0x84, KEY_POWER }, | ||
605 | { 0xf8, 0x94, KEY_MUTE }, | ||
606 | { 0xf8, 0x87, KEY_1 }, | ||
607 | { 0xf8, 0x86, KEY_2 }, | ||
608 | { 0xf8, 0x85, KEY_3 }, | ||
609 | { 0xf8, 0x8b, KEY_4 }, | ||
610 | { 0xf8, 0x8a, KEY_5 }, | ||
611 | { 0xf8, 0x89, KEY_6 }, | ||
612 | { 0xf8, 0x8f, KEY_7 }, | ||
613 | { 0xf8, 0x8e, KEY_8 }, | ||
614 | { 0xf8, 0x8d, KEY_9 }, | ||
615 | { 0xf8, 0x92, KEY_0 }, | ||
616 | { 0xf8, 0x96, KEY_CHANNELUP }, | ||
617 | { 0xf8, 0x91, KEY_CHANNELDOWN }, | ||
618 | { 0xf8, 0x93, KEY_VOLUMEUP }, | ||
619 | { 0xf8, 0x8c, KEY_VOLUMEDOWN }, | ||
620 | { 0xf8, 0x83, KEY_RECORD }, | ||
621 | { 0xf8, 0x98, KEY_PAUSE }, | ||
622 | { 0xf8, 0x99, KEY_OK }, | ||
623 | { 0xf8, 0x9a, KEY_SHUFFLE }, | ||
624 | { 0xf8, 0x81, KEY_UP }, | ||
625 | { 0xf8, 0x90, KEY_LEFT }, | ||
626 | { 0xf8, 0x82, KEY_RIGHT }, | ||
627 | { 0xf8, 0x88, KEY_DOWN }, | ||
628 | { 0xf8, 0x95, KEY_FAVORITES }, | ||
629 | { 0xf8, 0x97, KEY_SUBTITLE }, | ||
630 | { 0xf8, 0x9d, KEY_ZOOM }, | ||
631 | { 0xf8, 0x9f, KEY_EXIT }, | ||
632 | { 0xf8, 0x9e, KEY_MENU }, | ||
633 | { 0xf8, 0x9c, KEY_EPG }, | ||
634 | { 0xf8, 0x80, KEY_PREVIOUS }, | ||
635 | { 0xf8, 0x9b, KEY_MODE } | ||
636 | }; | ||
552 | 637 | ||
638 | static struct dvb_usb_rc_keys_table keys_tables[] = { | ||
639 | { dw210x_rc_keys, ARRAY_SIZE(dw210x_rc_keys) }, | ||
640 | { tevii_rc_keys, ARRAY_SIZE(tevii_rc_keys) }, | ||
641 | { tbs_rc_keys, ARRAY_SIZE(tbs_rc_keys) }, | ||
642 | }; | ||
553 | 643 | ||
554 | static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | 644 | static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) |
555 | { | 645 | { |
556 | struct dw210x_state *st = d->priv; | 646 | struct dvb_usb_rc_key *keymap = d->props.rc_key_map; |
647 | int keymap_size = d->props.rc_key_map_size; | ||
557 | u8 key[2]; | 648 | u8 key[2]; |
558 | struct i2c_msg msg = { | 649 | struct i2c_msg msg = { |
559 | .addr = DW2102_RC_QUERY, | 650 | .addr = DW2102_RC_QUERY, |
@@ -562,19 +653,21 @@ static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | |||
562 | .len = 2 | 653 | .len = 2 |
563 | }; | 654 | }; |
564 | int i; | 655 | int i; |
656 | /* override keymap */ | ||
657 | if ((ir_keymap > 0) && (ir_keymap <= ARRAY_SIZE(keys_tables))) { | ||
658 | keymap = keys_tables[ir_keymap - 1].rc_keys ; | ||
659 | keymap_size = keys_tables[ir_keymap - 1].rc_keys_size; | ||
660 | } | ||
565 | 661 | ||
566 | *state = REMOTE_NO_KEY_PRESSED; | 662 | *state = REMOTE_NO_KEY_PRESSED; |
567 | if (dw2102_i2c_transfer(&d->i2c_adap, &msg, 1) == 1) { | 663 | if (dw2102_i2c_transfer(&d->i2c_adap, &msg, 1) == 1) { |
568 | for (i = 0; i < ARRAY_SIZE(dw210x_rc_keys); i++) { | 664 | for (i = 0; i < keymap_size ; i++) { |
569 | if (dw210x_rc_keys[i].data == msg.buf[0]) { | 665 | if (keymap[i].data == msg.buf[0]) { |
570 | *state = REMOTE_KEY_PRESSED; | 666 | *state = REMOTE_KEY_PRESSED; |
571 | *event = dw210x_rc_keys[i].event; | 667 | *event = keymap[i].event; |
572 | st->last_key_pressed = | ||
573 | dw210x_rc_keys[i].event; | ||
574 | break; | 668 | break; |
575 | } | 669 | } |
576 | 670 | ||
577 | st->last_key_pressed = 0; | ||
578 | } | 671 | } |
579 | 672 | ||
580 | if ((*state) == REMOTE_KEY_PRESSED) | 673 | if ((*state) == REMOTE_KEY_PRESSED) |
@@ -655,8 +748,11 @@ static int dw2102_load_firmware(struct usb_device *dev, | |||
655 | } | 748 | } |
656 | /* init registers */ | 749 | /* init registers */ |
657 | switch (dev->descriptor.idProduct) { | 750 | switch (dev->descriptor.idProduct) { |
658 | case USB_PID_DW2104: | ||
659 | case 0xd650: | 751 | case 0xd650: |
752 | dw2104_properties.rc_key_map = tevii_rc_keys; | ||
753 | dw2104_properties.rc_key_map_size = | ||
754 | ARRAY_SIZE(tevii_rc_keys); | ||
755 | case USB_PID_DW2104: | ||
660 | reset = 1; | 756 | reset = 1; |
661 | dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1, | 757 | dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1, |
662 | DW210X_WRITE_MSG); | 758 | DW210X_WRITE_MSG); |
@@ -713,7 +809,6 @@ static struct dvb_usb_device_properties dw2102_properties = { | |||
713 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | 809 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
714 | .usb_ctrl = DEVICE_SPECIFIC, | 810 | .usb_ctrl = DEVICE_SPECIFIC, |
715 | .firmware = "dvb-usb-dw2102.fw", | 811 | .firmware = "dvb-usb-dw2102.fw", |
716 | .size_of_priv = sizeof(struct dw210x_state), | ||
717 | .no_reconnect = 1, | 812 | .no_reconnect = 1, |
718 | 813 | ||
719 | .i2c_algo = &dw2102_serit_i2c_algo, | 814 | .i2c_algo = &dw2102_serit_i2c_algo, |
@@ -765,7 +860,6 @@ static struct dvb_usb_device_properties dw2104_properties = { | |||
765 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | 860 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
766 | .usb_ctrl = DEVICE_SPECIFIC, | 861 | .usb_ctrl = DEVICE_SPECIFIC, |
767 | .firmware = "dvb-usb-dw2104.fw", | 862 | .firmware = "dvb-usb-dw2104.fw", |
768 | .size_of_priv = sizeof(struct dw210x_state), | ||
769 | .no_reconnect = 1, | 863 | .no_reconnect = 1, |
770 | 864 | ||
771 | .i2c_algo = &dw2104_i2c_algo, | 865 | .i2c_algo = &dw2104_i2c_algo, |