aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorAntti Palosaari <crope@iki.fi>2010-10-22 17:45:18 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-10-23 09:11:28 -0400
commit74c8e3ad0e5296d65be091bdc0d3ae9f72f7e019 (patch)
tree2f818cce0a2b2655a425facf6aea6427ca2ca825 /drivers/media
parentd8d627834b1f4dd21a63c2b524e9eb56173df57b (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.c80
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
210static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val) 210static 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
217static 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
216static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, 222static 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
793static int af9015_rc_query(struct dvb_usb_device *d);
794
795static int af9015_read_config(struct usb_device *udev) 804static 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
1070error: 1053error:
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,