From 3234bd2f193936da6180a7dc6699a75191bc44d1 Mon Sep 17 00:00:00 2001 From: Hans-Frieder Vogt Date: Sat, 21 Apr 2012 18:23:16 -0300 Subject: [PATCH] [media] af9035: add remote control support Signed-off-by: Hans-Frieder Vogt Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/af9035.c | 65 ++++++++++++++++++++++++++++++++++++++ drivers/media/dvb/dvb-usb/af9035.h | 1 + 2 files changed, 66 insertions(+) diff --git a/drivers/media/dvb/dvb-usb/af9035.c b/drivers/media/dvb/dvb-usb/af9035.c index a68ae53..fc9e68c 100644 --- a/drivers/media/dvb/dvb-usb/af9035.c +++ b/drivers/media/dvb/dvb-usb/af9035.c @@ -313,6 +313,37 @@ static struct i2c_algorithm af9035_i2c_algo = { .functionality = af9035_i2c_functionality, }; +#define AF9035_POLL 250 +static int af9035_rc_query(struct dvb_usb_device *d) +{ + unsigned int key; + unsigned char b[4]; + int ret; + struct usb_req req = { CMD_IR_GET, 0, 0, NULL, 4, b }; + + ret = af9035_ctrl_msg(d->udev, &req); + if (ret < 0) + goto err; + + if ((b[2] + b[3]) == 0xff) { + if ((b[0] + b[1]) == 0xff) { + /* NEC */ + key = b[0] << 8 | b[2]; + } else { + /* ext. NEC */ + key = b[0] << 16 | b[1] << 8 | b[2]; + } + } else { + key = b[0] << 24 | b[1] << 16 | b[2] << 8 | b[3]; + } + + rc_keydown(d->rc_dev, key, 0); + +err: + /* ignore errors */ + return 0; +} + static int af9035_init(struct dvb_usb_device *d) { int ret, i; @@ -627,6 +658,32 @@ static int af9035_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) for (i = 0; i < af9035_properties[0].num_adapters; i++) af9035_af9033_config[i].clock = clock_lut[tmp]; + ret = af9035_rd_reg(d, EEPROM_IR_MODE, &tmp); + if (ret < 0) + goto err; + pr_debug("%s: ir_mode=%02x\n", __func__, tmp); + + /* don't activate rc if in HID mode or if not available */ + if (tmp == 5) { + ret = af9035_rd_reg(d, EEPROM_IR_TYPE, &tmp); + if (ret < 0) + goto err; + pr_debug("%s: ir_type=%02x\n", __func__, tmp); + + switch (tmp) { + case 0: /* NEC */ + default: + d->props.rc.core.protocol = RC_TYPE_NEC; + d->props.rc.core.allowed_protos = RC_TYPE_NEC; + break; + case 1: /* RC6 */ + d->props.rc.core.protocol = RC_TYPE_RC6; + d->props.rc.core.allowed_protos = RC_TYPE_RC6; + break; + } + d->props.rc.core.rc_query = af9035_rc_query; + } + return 0; err: @@ -1003,6 +1060,14 @@ static struct dvb_usb_device_properties af9035_properties[] = { .i2c_algo = &af9035_i2c_algo, + .rc.core = { + .protocol = RC_TYPE_UNKNOWN, + .module_name = "af9035", + .rc_query = NULL, + .rc_interval = AF9035_POLL, + .allowed_protos = RC_TYPE_UNKNOWN, + .rc_codes = RC_MAP_EMPTY, + }, .num_device_descs = 5, .devices = { { diff --git a/drivers/media/dvb/dvb-usb/af9035.h b/drivers/media/dvb/dvb-usb/af9035.h index eece4ed..27a484b 100644 --- a/drivers/media/dvb/dvb-usb/af9035.h +++ b/drivers/media/dvb/dvb-usb/af9035.h @@ -96,6 +96,7 @@ u32 clock_lut_it9135[] = { #define CMD_MEM_WR 0x01 #define CMD_I2C_RD 0x02 #define CMD_I2C_WR 0x03 +#define CMD_IR_GET 0x18 #define CMD_FW_DL 0x21 #define CMD_FW_QUERYINFO 0x22 #define CMD_FW_BOOT 0x23 -- 2.7.4