diff options
author | Antti Palosaari <crope@iki.fi> | 2010-10-22 17:45:18 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-10-23 09:11:28 -0400 |
commit | 74c8e3ad0e5296d65be091bdc0d3ae9f72f7e019 (patch) | |
tree | 2f818cce0a2b2655a425facf6aea6427ca2ca825 /drivers/media | |
parent | d8d627834b1f4dd21a63c2b524e9eb56173df57b (diff) |
[media] af9015: RC fixes and improvements
Read all remote controller registers at once to reduce USB remote polling traffic.
Use .rc_codes() to disable / enable remote polling instead of .rc_query().
Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/dvb/dvb-usb/af9015.c | 80 |
1 files changed, 33 insertions, 47 deletions
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index 759cbf81a4d3..f11743f3ffd8 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c | |||
@@ -207,12 +207,18 @@ static int af9015_write_reg(struct dvb_usb_device *d, u16 addr, u8 val) | |||
207 | return af9015_write_regs(d, addr, &val, 1); | 207 | return af9015_write_regs(d, addr, &val, 1); |
208 | } | 208 | } |
209 | 209 | ||
210 | static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val) | 210 | static int af9015_read_regs(struct dvb_usb_device *d, u16 addr, u8 *val, u8 len) |
211 | { | 211 | { |
212 | struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, 1, val}; | 212 | struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len, |
213 | val}; | ||
213 | return af9015_ctrl_msg(d, &req); | 214 | return af9015_ctrl_msg(d, &req); |
214 | } | 215 | } |
215 | 216 | ||
217 | static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val) | ||
218 | { | ||
219 | return af9015_read_regs(d, addr, val, 1); | ||
220 | } | ||
221 | |||
216 | static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, | 222 | static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, |
217 | u8 val) | 223 | u8 val) |
218 | { | 224 | { |
@@ -787,11 +793,14 @@ static void af9015_set_remote_config(struct usb_device *udev, | |||
787 | af9015_rc_setup_modparam); | 793 | af9015_rc_setup_modparam); |
788 | } | 794 | } |
789 | } | 795 | } |
796 | |||
797 | /* finally load "empty" just for leaving IR receiver enabled */ | ||
798 | if (!props->rc.core.rc_codes) | ||
799 | props->rc.core.rc_codes = RC_MAP_EMPTY; | ||
800 | |||
790 | return; | 801 | return; |
791 | } | 802 | } |
792 | 803 | ||
793 | static int af9015_rc_query(struct dvb_usb_device *d); | ||
794 | |||
795 | static int af9015_read_config(struct usb_device *udev) | 804 | static int af9015_read_config(struct usb_device *udev) |
796 | { | 805 | { |
797 | int ret; | 806 | int ret; |
@@ -815,12 +824,10 @@ static int af9015_read_config(struct usb_device *udev) | |||
815 | 824 | ||
816 | deb_info("%s: IR mode:%d\n", __func__, val); | 825 | deb_info("%s: IR mode:%d\n", __func__, val); |
817 | for (i = 0; i < af9015_properties_count; i++) { | 826 | for (i = 0; i < af9015_properties_count; i++) { |
818 | if (val == AF9015_IR_MODE_DISABLED) { | 827 | if (val == AF9015_IR_MODE_DISABLED) |
819 | af9015_properties[i].rc.core.rc_query = NULL; | 828 | af9015_properties[i].rc.core.rc_codes = NULL; |
820 | } else { | 829 | else |
821 | af9015_properties[i].rc.core.rc_query = af9015_rc_query; | ||
822 | af9015_set_remote_config(udev, &af9015_properties[i]); | 830 | af9015_set_remote_config(udev, &af9015_properties[i]); |
823 | } | ||
824 | } | 831 | } |
825 | 832 | ||
826 | /* TS mode - one or two receivers */ | 833 | /* TS mode - one or two receivers */ |
@@ -1005,67 +1012,43 @@ static int af9015_rc_query(struct dvb_usb_device *d) | |||
1005 | { | 1012 | { |
1006 | struct af9015_state *priv = d->priv; | 1013 | struct af9015_state *priv = d->priv; |
1007 | int ret; | 1014 | int ret; |
1008 | u8 repeat, keycode[4]; | 1015 | u8 buf[16]; |
1009 | 1016 | ||
1010 | /* read registers needed to detect remote controller code */ | 1017 | /* read registers needed to detect remote controller code */ |
1011 | /* TODO: Implement read multiple registers to reduce idle USB traffic. | 1018 | ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf)); |
1012 | Currently three reads are needed for one idle rc polling. */ | ||
1013 | ret = af9015_read_reg(d, 0x98df, &repeat); | ||
1014 | if (ret) | 1019 | if (ret) |
1015 | goto error; | 1020 | goto error; |
1016 | 1021 | ||
1017 | ret = af9015_read_reg(d, 0x98e7, &keycode[2]); | 1022 | if (buf[14] || buf[15]) { |
1018 | if (ret) | 1023 | deb_rc("%s: key pressed %02x %02x %02x %02x\n", __func__, |
1019 | goto error; | 1024 | buf[12], buf[13], buf[14], buf[15]); |
1020 | |||
1021 | ret = af9015_read_reg(d, 0x98e8, &keycode[3]); | ||
1022 | if (ret) | ||
1023 | goto error; | ||
1024 | |||
1025 | if (keycode[2] || keycode[3]) { | ||
1026 | /* read 1st address byte */ | ||
1027 | ret = af9015_read_reg(d, 0x98e5, &keycode[0]); | ||
1028 | if (ret) | ||
1029 | goto error; | ||
1030 | |||
1031 | /* read 2nd address byte */ | ||
1032 | ret = af9015_read_reg(d, 0x98e6, &keycode[1]); | ||
1033 | if (ret) | ||
1034 | goto error; | ||
1035 | |||
1036 | deb_rc("%s: key pressed ", __func__); | ||
1037 | debug_dump(keycode, sizeof(keycode), deb_rc); | ||
1038 | |||
1039 | /* clean data bytes from mem */ | ||
1040 | ret = af9015_write_reg(d, 0x98e7, 0); | ||
1041 | if (ret) | ||
1042 | goto error; | ||
1043 | 1025 | ||
1044 | ret = af9015_write_reg(d, 0x98e8, 0); | 1026 | /* clean IR code from mem */ |
1027 | ret = af9015_write_regs(d, 0x98e5, "\x00\x00\x00\x00", 4); | ||
1045 | if (ret) | 1028 | if (ret) |
1046 | goto error; | 1029 | goto error; |
1047 | 1030 | ||
1048 | if (keycode[2] == (u8) ~keycode[3]) { | 1031 | if (buf[14] == (u8) ~buf[15]) { |
1049 | if (keycode[0] == (u8) ~keycode[1]) { | 1032 | if (buf[12] == (u8) ~buf[13]) { |
1050 | /* NEC */ | 1033 | /* NEC */ |
1051 | priv->rc_keycode = keycode[0] << 8 | keycode[2]; | 1034 | priv->rc_keycode = buf[12] << 8 | buf[14]; |
1052 | } else { | 1035 | } else { |
1053 | /* NEC extended*/ | 1036 | /* NEC extended*/ |
1054 | priv->rc_keycode = keycode[0] << 16 | | 1037 | priv->rc_keycode = buf[12] << 16 | |
1055 | keycode[1] << 8 | keycode[2]; | 1038 | buf[13] << 8 | buf[14]; |
1056 | } | 1039 | } |
1057 | ir_keydown(d->rc_input_dev, priv->rc_keycode, 0); | 1040 | ir_keydown(d->rc_input_dev, priv->rc_keycode, 0); |
1058 | } else { | 1041 | } else { |
1059 | priv->rc_keycode = 0; /* clear just for sure */ | 1042 | priv->rc_keycode = 0; /* clear just for sure */ |
1060 | } | 1043 | } |
1061 | } else if (priv->rc_repeat != repeat) { | 1044 | } else if (priv->rc_repeat != buf[6] || buf[0]) { |
1062 | deb_rc("%s: key repeated\n", __func__); | 1045 | deb_rc("%s: key repeated\n", __func__); |
1063 | ir_keydown(d->rc_input_dev, priv->rc_keycode, 0); | 1046 | ir_keydown(d->rc_input_dev, priv->rc_keycode, 0); |
1064 | } else { | 1047 | } else { |
1065 | deb_rc("%s: no key press\n", __func__); | 1048 | deb_rc("%s: no key press\n", __func__); |
1066 | } | 1049 | } |
1067 | 1050 | ||
1068 | priv->rc_repeat = repeat; | 1051 | priv->rc_repeat = buf[6]; |
1069 | 1052 | ||
1070 | error: | 1053 | error: |
1071 | if (ret) | 1054 | if (ret) |
@@ -1358,6 +1341,7 @@ static struct dvb_usb_device_properties af9015_properties[] = { | |||
1358 | .rc.core = { | 1341 | .rc.core = { |
1359 | .protocol = IR_TYPE_NEC, | 1342 | .protocol = IR_TYPE_NEC, |
1360 | .module_name = "af9015", | 1343 | .module_name = "af9015", |
1344 | .rc_query = af9015_rc_query, | ||
1361 | .rc_interval = AF9015_RC_INTERVAL, | 1345 | .rc_interval = AF9015_RC_INTERVAL, |
1362 | .rc_props = { | 1346 | .rc_props = { |
1363 | .allowed_protos = IR_TYPE_NEC, | 1347 | .allowed_protos = IR_TYPE_NEC, |
@@ -1486,6 +1470,7 @@ static struct dvb_usb_device_properties af9015_properties[] = { | |||
1486 | .rc.core = { | 1470 | .rc.core = { |
1487 | .protocol = IR_TYPE_NEC, | 1471 | .protocol = IR_TYPE_NEC, |
1488 | .module_name = "af9015", | 1472 | .module_name = "af9015", |
1473 | .rc_query = af9015_rc_query, | ||
1489 | .rc_interval = AF9015_RC_INTERVAL, | 1474 | .rc_interval = AF9015_RC_INTERVAL, |
1490 | .rc_props = { | 1475 | .rc_props = { |
1491 | .allowed_protos = IR_TYPE_NEC, | 1476 | .allowed_protos = IR_TYPE_NEC, |
@@ -1599,6 +1584,7 @@ static struct dvb_usb_device_properties af9015_properties[] = { | |||
1599 | .rc.core = { | 1584 | .rc.core = { |
1600 | .protocol = IR_TYPE_NEC, | 1585 | .protocol = IR_TYPE_NEC, |
1601 | .module_name = "af9015", | 1586 | .module_name = "af9015", |
1587 | .rc_query = af9015_rc_query, | ||
1602 | .rc_interval = AF9015_RC_INTERVAL, | 1588 | .rc_interval = AF9015_RC_INTERVAL, |
1603 | .rc_props = { | 1589 | .rc_props = { |
1604 | .allowed_protos = IR_TYPE_NEC, | 1590 | .allowed_protos = IR_TYPE_NEC, |