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 | |
| 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>
| -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, |
