[media] af9035: add remote control support
authorHans-Frieder Vogt <hfvogt@gmx.net>
Sat, 21 Apr 2012 21:23:16 +0000 (18:23 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Mon, 14 May 2012 16:19:12 +0000 (13:19 -0300)
Signed-off-by: Hans-Frieder Vogt <hfvogt@gmx.net>
Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/dvb/dvb-usb/af9035.c
drivers/media/dvb/dvb-usb/af9035.h

index a68ae53..fc9e68c 100644 (file)
@@ -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 = {
                        {
index eece4ed..27a484b 100644 (file)
@@ -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