diff options
author | Ian Armstrong <ian@iarmst.demon.co.uk> | 2011-03-18 18:23:05 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-03-22 03:54:52 -0400 |
commit | c1e13971b19324305b35fafc080b527465214d3c (patch) | |
tree | 15abefc08f1b5f04deb640e00edfe3e23d82a94f /drivers/media/dvb | |
parent | ce5b2acce60405b938d1f1f994024cde4e2cdd7e (diff) |
[media] af9015: enhance RC
Patch from Ian Armstrong.
I've encountered a couple of problems with the current af9015 driver as
supplied with the 2.6.37 kernel, that the attached patch appears to fix. (I've
generated this patch against the current v4l-dvb git).
Some key-presses are lost. A key-press is only generated upon 'valid' data
(buf[14] == (u8) ~buf[15]), but the buffer is wiped before this check.
Sometimes the 15th byte has not been set at the time of read, so the data
isn't valid & ignored. On the next poll the 15th byte has been set, but the
rest of the data was wiped previously, so the data is still invalid & the key
is lost.
Weird repeat error, where an old key press is sometimes repeated in error. ie.
button sequence '1 (pause) 2 (pause) 3 (pause) 4' generates output like '1
(pause) 2 (pause) 23 (pause) 4'. The current driver zeroes the data for the
key pushed, but sometimes this data is already zero but with other bytes set
suggesting a repeat code. This results in the last key being incorrectly
repeated.
This patch attempts to reduce the risk of a missed key-press & also stop the
random repeat of an old key-press when a new key is pressed.
Signed-off-by: Ian Armstrong <ian@iarmst.demon.co.uk>
Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb')
-rw-r--r-- | drivers/media/dvb/dvb-usb/af9015.c | 39 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/af9015.h | 1 |
2 files changed, 29 insertions, 11 deletions
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index 8671ca362c81..6457d042b1a0 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c | |||
@@ -479,6 +479,9 @@ static int af9015_init_endpoint(struct dvb_usb_device *d) | |||
479 | ret = af9015_set_reg_bit(d, 0xd50b, 0); | 479 | ret = af9015_set_reg_bit(d, 0xd50b, 0); |
480 | else | 480 | else |
481 | ret = af9015_clear_reg_bit(d, 0xd50b, 0); | 481 | ret = af9015_clear_reg_bit(d, 0xd50b, 0); |
482 | if (ret) | ||
483 | goto error; | ||
484 | ret = af9015_write_reg(d, 0x98e9, 0xff); | ||
482 | error: | 485 | error: |
483 | if (ret) | 486 | if (ret) |
484 | err("endpoint init failed:%d", ret); | 487 | err("endpoint init failed:%d", ret); |
@@ -1016,22 +1019,35 @@ static int af9015_rc_query(struct dvb_usb_device *d) | |||
1016 | { | 1019 | { |
1017 | struct af9015_state *priv = d->priv; | 1020 | struct af9015_state *priv = d->priv; |
1018 | int ret; | 1021 | int ret; |
1019 | u8 buf[16]; | 1022 | u8 buf[17]; |
1020 | 1023 | ||
1021 | /* read registers needed to detect remote controller code */ | 1024 | /* read registers needed to detect remote controller code */ |
1022 | ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf)); | 1025 | ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf)); |
1023 | if (ret) | 1026 | if (ret) |
1024 | goto error; | 1027 | goto error; |
1025 | 1028 | ||
1026 | if (buf[14] || buf[15]) { | 1029 | /* If any of these are non-zero, assume invalid data */ |
1030 | if (buf[1] || buf[2] || buf[3]) | ||
1031 | return ret; | ||
1032 | |||
1033 | /* Check for repeat of previous code */ | ||
1034 | if ((priv->rc_repeat != buf[6] || buf[0]) && | ||
1035 | !memcmp(&buf[12], priv->rc_last, 4)) { | ||
1036 | deb_rc("%s: key repeated\n", __func__); | ||
1037 | rc_keydown(d->rc_dev, priv->rc_keycode, 0); | ||
1038 | priv->rc_repeat = buf[6]; | ||
1039 | return ret; | ||
1040 | } | ||
1041 | |||
1042 | /* Only process key if canary killed */ | ||
1043 | if (buf[16] != 0xff && buf[0] != 0x01) { | ||
1044 | /* Reset the canary */ | ||
1045 | af9015_write_reg(d, 0x98e9, 0xff); | ||
1027 | deb_rc("%s: key pressed %02x %02x %02x %02x\n", __func__, | 1046 | deb_rc("%s: key pressed %02x %02x %02x %02x\n", __func__, |
1028 | buf[12], buf[13], buf[14], buf[15]); | 1047 | buf[12], buf[13], buf[14], buf[15]); |
1029 | 1048 | ||
1030 | /* clean IR code from mem */ | 1049 | /* Remember this key */ |
1031 | ret = af9015_write_regs(d, 0x98e5, "\x00\x00\x00\x00", 4); | 1050 | memcpy(priv->rc_last, &buf[12], 4); |
1032 | if (ret) | ||
1033 | goto error; | ||
1034 | |||
1035 | if (buf[14] == (u8) ~buf[15]) { | 1051 | if (buf[14] == (u8) ~buf[15]) { |
1036 | if (buf[12] == (u8) ~buf[13]) { | 1052 | if (buf[12] == (u8) ~buf[13]) { |
1037 | /* NEC */ | 1053 | /* NEC */ |
@@ -1041,15 +1057,16 @@ static int af9015_rc_query(struct dvb_usb_device *d) | |||
1041 | priv->rc_keycode = buf[12] << 16 | | 1057 | priv->rc_keycode = buf[12] << 16 | |
1042 | buf[13] << 8 | buf[14]; | 1058 | buf[13] << 8 | buf[14]; |
1043 | } | 1059 | } |
1044 | rc_keydown(d->rc_dev, priv->rc_keycode, 0); | ||
1045 | } else { | 1060 | } else { |
1046 | priv->rc_keycode = 0; /* clear just for sure */ | 1061 | priv->rc_keycode = buf[12] << 24 | buf[13] << 16 | |
1062 | buf[14] << 8 | buf[15]; | ||
1047 | } | 1063 | } |
1048 | } else if (priv->rc_repeat != buf[6] || buf[0]) { | ||
1049 | deb_rc("%s: key repeated\n", __func__); | ||
1050 | rc_keydown(d->rc_dev, priv->rc_keycode, 0); | 1064 | rc_keydown(d->rc_dev, priv->rc_keycode, 0); |
1051 | } else { | 1065 | } else { |
1052 | deb_rc("%s: no key press\n", __func__); | 1066 | deb_rc("%s: no key press\n", __func__); |
1067 | /* Invalidate last keypress */ | ||
1068 | /* Not really needed, but helps with debug */ | ||
1069 | priv->rc_last[2] = priv->rc_last[3]; | ||
1053 | } | 1070 | } |
1054 | 1071 | ||
1055 | priv->rc_repeat = buf[6]; | 1072 | priv->rc_repeat = buf[6]; |
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h index f20cfa6ed690..beb3004f00ba 100644 --- a/drivers/media/dvb/dvb-usb/af9015.h +++ b/drivers/media/dvb/dvb-usb/af9015.h | |||
@@ -102,6 +102,7 @@ struct af9015_state { | |||
102 | struct i2c_adapter i2c_adap; /* I2C adapter for 2nd FE */ | 102 | struct i2c_adapter i2c_adap; /* I2C adapter for 2nd FE */ |
103 | u8 rc_repeat; | 103 | u8 rc_repeat; |
104 | u32 rc_keycode; | 104 | u32 rc_keycode; |
105 | u8 rc_last[4]; | ||
105 | }; | 106 | }; |
106 | 107 | ||
107 | struct af9015_config { | 108 | struct af9015_config { |