aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb
diff options
context:
space:
mode:
authorIan Armstrong <ian@iarmst.demon.co.uk>2011-03-18 18:23:05 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-03-22 03:54:52 -0400
commitc1e13971b19324305b35fafc080b527465214d3c (patch)
tree15abefc08f1b5f04deb640e00edfe3e23d82a94f /drivers/media/dvb
parentce5b2acce60405b938d1f1f994024cde4e2cdd7e (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.c39
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.h1
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);
482error: 485error:
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
107struct af9015_config { 108struct af9015_config {