diff options
-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 { |