Commit 74c8e3ad authored by Antti Palosaari's avatar Antti Palosaari Committed by Mauro Carvalho Chehab

[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: default avatarAntti Palosaari <crope@iki.fi>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent d8d62783
...@@ -207,12 +207,18 @@ static int af9015_write_reg(struct dvb_usb_device *d, u16 addr, u8 val) ...@@ -207,12 +207,18 @@ static int af9015_write_reg(struct dvb_usb_device *d, u16 addr, u8 val)
return af9015_write_regs(d, addr, &val, 1); return af9015_write_regs(d, addr, &val, 1);
} }
static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val) static int af9015_read_regs(struct dvb_usb_device *d, u16 addr, u8 *val, u8 len)
{ {
struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, 1, val}; struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len,
val};
return af9015_ctrl_msg(d, &req); return af9015_ctrl_msg(d, &req);
} }
static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val)
{
return af9015_read_regs(d, addr, val, 1);
}
static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
u8 val) u8 val)
{ {
...@@ -787,11 +793,14 @@ static void af9015_set_remote_config(struct usb_device *udev, ...@@ -787,11 +793,14 @@ static void af9015_set_remote_config(struct usb_device *udev,
af9015_rc_setup_modparam); af9015_rc_setup_modparam);
} }
} }
/* finally load "empty" just for leaving IR receiver enabled */
if (!props->rc.core.rc_codes)
props->rc.core.rc_codes = RC_MAP_EMPTY;
return; return;
} }
static int af9015_rc_query(struct dvb_usb_device *d);
static int af9015_read_config(struct usb_device *udev) static int af9015_read_config(struct usb_device *udev)
{ {
int ret; int ret;
...@@ -815,12 +824,10 @@ static int af9015_read_config(struct usb_device *udev) ...@@ -815,12 +824,10 @@ static int af9015_read_config(struct usb_device *udev)
deb_info("%s: IR mode:%d\n", __func__, val); deb_info("%s: IR mode:%d\n", __func__, val);
for (i = 0; i < af9015_properties_count; i++) { for (i = 0; i < af9015_properties_count; i++) {
if (val == AF9015_IR_MODE_DISABLED) { if (val == AF9015_IR_MODE_DISABLED)
af9015_properties[i].rc.core.rc_query = NULL; af9015_properties[i].rc.core.rc_codes = NULL;
} else { else
af9015_properties[i].rc.core.rc_query = af9015_rc_query;
af9015_set_remote_config(udev, &af9015_properties[i]); af9015_set_remote_config(udev, &af9015_properties[i]);
}
} }
/* TS mode - one or two receivers */ /* TS mode - one or two receivers */
...@@ -1005,67 +1012,43 @@ static int af9015_rc_query(struct dvb_usb_device *d) ...@@ -1005,67 +1012,43 @@ static int af9015_rc_query(struct dvb_usb_device *d)
{ {
struct af9015_state *priv = d->priv; struct af9015_state *priv = d->priv;
int ret; int ret;
u8 repeat, keycode[4]; u8 buf[16];
/* read registers needed to detect remote controller code */ /* read registers needed to detect remote controller code */
/* TODO: Implement read multiple registers to reduce idle USB traffic. ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf));
Currently three reads are needed for one idle rc polling. */
ret = af9015_read_reg(d, 0x98df, &repeat);
if (ret) if (ret)
goto error; goto error;
ret = af9015_read_reg(d, 0x98e7, &keycode[2]); if (buf[14] || buf[15]) {
if (ret) deb_rc("%s: key pressed %02x %02x %02x %02x\n", __func__,
goto error; buf[12], buf[13], buf[14], buf[15]);
ret = af9015_read_reg(d, 0x98e8, &keycode[3]);
if (ret)
goto error;
if (keycode[2] || keycode[3]) {
/* read 1st address byte */
ret = af9015_read_reg(d, 0x98e5, &keycode[0]);
if (ret)
goto error;
/* read 2nd address byte */
ret = af9015_read_reg(d, 0x98e6, &keycode[1]);
if (ret)
goto error;
deb_rc("%s: key pressed ", __func__);
debug_dump(keycode, sizeof(keycode), deb_rc);
/* clean data bytes from mem */
ret = af9015_write_reg(d, 0x98e7, 0);
if (ret)
goto error;
ret = af9015_write_reg(d, 0x98e8, 0); /* clean IR code from mem */
ret = af9015_write_regs(d, 0x98e5, "\x00\x00\x00\x00", 4);
if (ret) if (ret)
goto error; goto error;
if (keycode[2] == (u8) ~keycode[3]) { if (buf[14] == (u8) ~buf[15]) {
if (keycode[0] == (u8) ~keycode[1]) { if (buf[12] == (u8) ~buf[13]) {
/* NEC */ /* NEC */
priv->rc_keycode = keycode[0] << 8 | keycode[2]; priv->rc_keycode = buf[12] << 8 | buf[14];
} else { } else {
/* NEC extended*/ /* NEC extended*/
priv->rc_keycode = keycode[0] << 16 | priv->rc_keycode = buf[12] << 16 |
keycode[1] << 8 | keycode[2]; buf[13] << 8 | buf[14];
} }
ir_keydown(d->rc_input_dev, priv->rc_keycode, 0); ir_keydown(d->rc_input_dev, priv->rc_keycode, 0);
} else { } else {
priv->rc_keycode = 0; /* clear just for sure */ priv->rc_keycode = 0; /* clear just for sure */
} }
} else if (priv->rc_repeat != repeat) { } else if (priv->rc_repeat != buf[6] || buf[0]) {
deb_rc("%s: key repeated\n", __func__); deb_rc("%s: key repeated\n", __func__);
ir_keydown(d->rc_input_dev, priv->rc_keycode, 0); ir_keydown(d->rc_input_dev, priv->rc_keycode, 0);
} else { } else {
deb_rc("%s: no key press\n", __func__); deb_rc("%s: no key press\n", __func__);
} }
priv->rc_repeat = repeat; priv->rc_repeat = buf[6];
error: error:
if (ret) if (ret)
...@@ -1358,6 +1341,7 @@ static struct dvb_usb_device_properties af9015_properties[] = { ...@@ -1358,6 +1341,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.rc.core = { .rc.core = {
.protocol = IR_TYPE_NEC, .protocol = IR_TYPE_NEC,
.module_name = "af9015", .module_name = "af9015",
.rc_query = af9015_rc_query,
.rc_interval = AF9015_RC_INTERVAL, .rc_interval = AF9015_RC_INTERVAL,
.rc_props = { .rc_props = {
.allowed_protos = IR_TYPE_NEC, .allowed_protos = IR_TYPE_NEC,
...@@ -1486,6 +1470,7 @@ static struct dvb_usb_device_properties af9015_properties[] = { ...@@ -1486,6 +1470,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.rc.core = { .rc.core = {
.protocol = IR_TYPE_NEC, .protocol = IR_TYPE_NEC,
.module_name = "af9015", .module_name = "af9015",
.rc_query = af9015_rc_query,
.rc_interval = AF9015_RC_INTERVAL, .rc_interval = AF9015_RC_INTERVAL,
.rc_props = { .rc_props = {
.allowed_protos = IR_TYPE_NEC, .allowed_protos = IR_TYPE_NEC,
...@@ -1599,6 +1584,7 @@ static struct dvb_usb_device_properties af9015_properties[] = { ...@@ -1599,6 +1584,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.rc.core = { .rc.core = {
.protocol = IR_TYPE_NEC, .protocol = IR_TYPE_NEC,
.module_name = "af9015", .module_name = "af9015",
.rc_query = af9015_rc_query,
.rc_interval = AF9015_RC_INTERVAL, .rc_interval = AF9015_RC_INTERVAL,
.rc_props = { .rc_props = {
.allowed_protos = IR_TYPE_NEC, .allowed_protos = IR_TYPE_NEC,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment