Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 // handle au0828 IR remotes via linux kernel input layer.
0003 //
0004 // Copyright (c) 2014 Mauro Carvalho Chehab <mchehab@samsung.com>
0005 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
0006 //
0007 // Based on em28xx-input.c.
0008 
0009 #include "au0828.h"
0010 
0011 #include <linux/module.h>
0012 #include <linux/init.h>
0013 #include <linux/delay.h>
0014 #include <linux/interrupt.h>
0015 #include <linux/usb.h>
0016 #include <linux/slab.h>
0017 #include <media/rc-core.h>
0018 
0019 static int disable_ir;
0020 module_param(disable_ir,        int, 0444);
0021 MODULE_PARM_DESC(disable_ir, "disable infrared remote support");
0022 
0023 struct au0828_rc {
0024     struct au0828_dev *dev;
0025     struct rc_dev *rc;
0026     char name[32];
0027     char phys[32];
0028 
0029     /* poll decoder */
0030     int polling;
0031     struct delayed_work work;
0032 
0033     /* i2c slave address of external device (if used) */
0034     u16 i2c_dev_addr;
0035 
0036     int  (*get_key_i2c)(struct au0828_rc *ir);
0037 };
0038 
0039 /*
0040  * AU8522 has a builtin IR receiver. Add functions to get IR from it
0041  */
0042 
0043 static int au8522_rc_write(struct au0828_rc *ir, u16 reg, u8 data)
0044 {
0045     int rc;
0046     char buf[] = { (reg >> 8) | 0x80, reg & 0xff, data };
0047     struct i2c_msg msg = { .addr = ir->i2c_dev_addr, .flags = 0,
0048                    .buf = buf, .len = sizeof(buf) };
0049 
0050     rc = i2c_transfer(ir->dev->i2c_client.adapter, &msg, 1);
0051 
0052     if (rc < 0)
0053         return rc;
0054 
0055     return (rc == 1) ? 0 : -EIO;
0056 }
0057 
0058 static int au8522_rc_read(struct au0828_rc *ir, u16 reg, int val,
0059                  char *buf, int size)
0060 {
0061     int rc;
0062     char obuf[3];
0063     struct i2c_msg msg[2] = { { .addr = ir->i2c_dev_addr, .flags = 0,
0064                     .buf = obuf, .len = 2 },
0065                   { .addr = ir->i2c_dev_addr, .flags = I2C_M_RD,
0066                     .buf = buf, .len = size } };
0067 
0068     obuf[0] = 0x40 | reg >> 8;
0069     obuf[1] = reg & 0xff;
0070     if (val >= 0) {
0071         obuf[2] = val;
0072         msg[0].len++;
0073     }
0074 
0075     rc = i2c_transfer(ir->dev->i2c_client.adapter, msg, 2);
0076 
0077     if (rc < 0)
0078         return rc;
0079 
0080     return (rc == 2) ? 0 : -EIO;
0081 }
0082 
0083 static int au8522_rc_andor(struct au0828_rc *ir, u16 reg, u8 mask, u8 value)
0084 {
0085     int rc;
0086     char buf, oldbuf;
0087 
0088     rc = au8522_rc_read(ir, reg, -1, &buf, 1);
0089     if (rc < 0)
0090         return rc;
0091 
0092     oldbuf = buf;
0093     buf = (buf & ~mask) | (value & mask);
0094 
0095     /* Nothing to do, just return */
0096     if (buf == oldbuf)
0097         return 0;
0098 
0099     return au8522_rc_write(ir, reg, buf);
0100 }
0101 
0102 #define au8522_rc_set(ir, reg, bit) au8522_rc_andor(ir, (reg), (bit), (bit))
0103 #define au8522_rc_clear(ir, reg, bit) au8522_rc_andor(ir, (reg), (bit), 0)
0104 
0105 /* Remote Controller time units */
0106 
0107 #define AU8522_UNIT     200 /* us */
0108 #define NEC_START_SPACE     (4500 / AU8522_UNIT)
0109 #define NEC_START_PULSE     (563 * 16)
0110 #define RC5_START_SPACE     (4 * AU8522_UNIT)
0111 #define RC5_START_PULSE     889
0112 
0113 static int au0828_get_key_au8522(struct au0828_rc *ir)
0114 {
0115     unsigned char buf[40];
0116     struct ir_raw_event rawir = {};
0117     int i, j, rc;
0118     int prv_bit, bit, width;
0119     bool first = true;
0120 
0121     /* do nothing if device is disconnected */
0122     if (test_bit(DEV_DISCONNECTED, &ir->dev->dev_state))
0123         return 0;
0124 
0125     /* Check IR int */
0126     rc = au8522_rc_read(ir, 0xe1, -1, buf, 1);
0127     if (rc < 0 || !(buf[0] & (1 << 4))) {
0128         /* Be sure that IR is enabled */
0129         au8522_rc_set(ir, 0xe0, 1 << 4);
0130         return 0;
0131     }
0132 
0133     /* Something arrived. Get the data */
0134     rc = au8522_rc_read(ir, 0xe3, 0x11, buf, sizeof(buf));
0135 
0136 
0137     if (rc < 0)
0138         return rc;
0139 
0140     /* Disable IR */
0141     au8522_rc_clear(ir, 0xe0, 1 << 4);
0142 
0143     /* Enable IR */
0144     au8522_rc_set(ir, 0xe0, 1 << 4);
0145 
0146     dprintk(16, "RC data received: %*ph\n", 40, buf);
0147 
0148     prv_bit = (buf[0] >> 7) & 0x01;
0149     width = 0;
0150     for (i = 0; i < sizeof(buf); i++) {
0151         for (j = 7; j >= 0; j--) {
0152             bit = (buf[i] >> j) & 0x01;
0153             if (bit == prv_bit) {
0154                 width++;
0155                 continue;
0156             }
0157 
0158             /*
0159              * Fix an au8522 bug: the first pulse event
0160              * is lost. So, we need to fake it, based on the
0161              * protocol. That means that not all raw decoders
0162              * will work, as we need to add a hack for each
0163              * protocol, based on the first space.
0164              * So, we only support RC5 and NEC.
0165              */
0166 
0167             if (first) {
0168                 first = false;
0169 
0170                 rawir.pulse = true;
0171                 if (width > NEC_START_SPACE - 2 &&
0172                     width < NEC_START_SPACE + 2) {
0173                     /* NEC protocol */
0174                     rawir.duration = NEC_START_PULSE;
0175                     dprintk(16, "Storing NEC start %s with duration %d",
0176                         rawir.pulse ? "pulse" : "space",
0177                         rawir.duration);
0178                 } else {
0179                     /* RC5 protocol */
0180                     rawir.duration = RC5_START_PULSE;
0181                     dprintk(16, "Storing RC5 start %s with duration %d",
0182                         rawir.pulse ? "pulse" : "space",
0183                         rawir.duration);
0184                 }
0185                 ir_raw_event_store(ir->rc, &rawir);
0186             }
0187 
0188             rawir.pulse = prv_bit ? false : true;
0189             rawir.duration = AU8522_UNIT * width;
0190             dprintk(16, "Storing %s with duration %d",
0191                 rawir.pulse ? "pulse" : "space",
0192                 rawir.duration);
0193             ir_raw_event_store(ir->rc, &rawir);
0194 
0195             width = 1;
0196             prv_bit = bit;
0197         }
0198     }
0199 
0200     rawir.pulse = prv_bit ? false : true;
0201     rawir.duration = AU8522_UNIT * width;
0202     dprintk(16, "Storing end %s with duration %d",
0203         rawir.pulse ? "pulse" : "space",
0204         rawir.duration);
0205     ir_raw_event_store(ir->rc, &rawir);
0206 
0207     ir_raw_event_handle(ir->rc);
0208 
0209     return 1;
0210 }
0211 
0212 /*
0213  * Generic IR code
0214  */
0215 
0216 static void au0828_rc_work(struct work_struct *work)
0217 {
0218     struct au0828_rc *ir = container_of(work, struct au0828_rc, work.work);
0219     int rc;
0220 
0221     rc = ir->get_key_i2c(ir);
0222     if (rc < 0)
0223         pr_info("Error while getting RC scancode\n");
0224 
0225     schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
0226 }
0227 
0228 static int au0828_rc_start(struct rc_dev *rc)
0229 {
0230     struct au0828_rc *ir = rc->priv;
0231 
0232     INIT_DELAYED_WORK(&ir->work, au0828_rc_work);
0233 
0234     /* Enable IR */
0235     au8522_rc_set(ir, 0xe0, 1 << 4);
0236 
0237     schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
0238 
0239     return 0;
0240 }
0241 
0242 static void au0828_rc_stop(struct rc_dev *rc)
0243 {
0244     struct au0828_rc *ir = rc->priv;
0245 
0246     cancel_delayed_work_sync(&ir->work);
0247 
0248     /* do nothing if device is disconnected */
0249     if (!test_bit(DEV_DISCONNECTED, &ir->dev->dev_state)) {
0250         /* Disable IR */
0251         au8522_rc_clear(ir, 0xe0, 1 << 4);
0252     }
0253 }
0254 
0255 static int au0828_probe_i2c_ir(struct au0828_dev *dev)
0256 {
0257     int i = 0;
0258     static const unsigned short addr_list[] = {
0259          0x47, I2C_CLIENT_END
0260     };
0261 
0262     while (addr_list[i] != I2C_CLIENT_END) {
0263         if (i2c_probe_func_quick_read(dev->i2c_client.adapter,
0264                           addr_list[i]) == 1)
0265             return addr_list[i];
0266         i++;
0267     }
0268 
0269     return -ENODEV;
0270 }
0271 
0272 int au0828_rc_register(struct au0828_dev *dev)
0273 {
0274     struct au0828_rc *ir;
0275     struct rc_dev *rc;
0276     int err = -ENOMEM;
0277     u16 i2c_rc_dev_addr = 0;
0278 
0279     if (!dev->board.has_ir_i2c || disable_ir)
0280         return 0;
0281 
0282     i2c_rc_dev_addr = au0828_probe_i2c_ir(dev);
0283     if (!i2c_rc_dev_addr)
0284         return -ENODEV;
0285 
0286     ir = kzalloc(sizeof(*ir), GFP_KERNEL);
0287     rc = rc_allocate_device(RC_DRIVER_IR_RAW);
0288     if (!ir || !rc)
0289         goto error;
0290 
0291     /* record handles to ourself */
0292     ir->dev = dev;
0293     dev->ir = ir;
0294     ir->rc = rc;
0295 
0296     rc->priv = ir;
0297     rc->open = au0828_rc_start;
0298     rc->close = au0828_rc_stop;
0299 
0300     if (dev->board.has_ir_i2c) {    /* external i2c device */
0301         switch (dev->boardnr) {
0302         case AU0828_BOARD_HAUPPAUGE_HVR950Q:
0303             rc->map_name = RC_MAP_HAUPPAUGE;
0304             ir->get_key_i2c = au0828_get_key_au8522;
0305             break;
0306         default:
0307             err = -ENODEV;
0308             goto error;
0309         }
0310 
0311         ir->i2c_dev_addr = i2c_rc_dev_addr;
0312     }
0313 
0314     /* This is how often we ask the chip for IR information */
0315     ir->polling = 100; /* ms */
0316 
0317     /* init input device */
0318     snprintf(ir->name, sizeof(ir->name), "au0828 IR (%s)",
0319          dev->board.name);
0320 
0321     usb_make_path(dev->usbdev, ir->phys, sizeof(ir->phys));
0322     strlcat(ir->phys, "/input0", sizeof(ir->phys));
0323 
0324     rc->device_name = ir->name;
0325     rc->input_phys = ir->phys;
0326     rc->input_id.bustype = BUS_USB;
0327     rc->input_id.version = 1;
0328     rc->input_id.vendor = le16_to_cpu(dev->usbdev->descriptor.idVendor);
0329     rc->input_id.product = le16_to_cpu(dev->usbdev->descriptor.idProduct);
0330     rc->dev.parent = &dev->usbdev->dev;
0331     rc->driver_name = "au0828-input";
0332     rc->allowed_protocols = RC_PROTO_BIT_NEC | RC_PROTO_BIT_NECX |
0333                 RC_PROTO_BIT_NEC32 | RC_PROTO_BIT_RC5;
0334 
0335     /* all done */
0336     err = rc_register_device(rc);
0337     if (err)
0338         goto error;
0339 
0340     pr_info("Remote controller %s initialized\n", ir->name);
0341 
0342     return 0;
0343 
0344 error:
0345     dev->ir = NULL;
0346     rc_free_device(rc);
0347     kfree(ir);
0348     return err;
0349 }
0350 
0351 void au0828_rc_unregister(struct au0828_dev *dev)
0352 {
0353     struct au0828_rc *ir = dev->ir;
0354 
0355     /* skip detach on non attached boards */
0356     if (!ir)
0357         return;
0358 
0359     rc_unregister_device(ir->rc);
0360 
0361     /* done */
0362     kfree(ir);
0363     dev->ir = NULL;
0364 }
0365 
0366 int au0828_rc_suspend(struct au0828_dev *dev)
0367 {
0368     struct au0828_rc *ir = dev->ir;
0369 
0370     if (!ir)
0371         return 0;
0372 
0373     pr_info("Stopping RC\n");
0374 
0375     cancel_delayed_work_sync(&ir->work);
0376 
0377     /* Disable IR */
0378     au8522_rc_clear(ir, 0xe0, 1 << 4);
0379 
0380     return 0;
0381 }
0382 
0383 int au0828_rc_resume(struct au0828_dev *dev)
0384 {
0385     struct au0828_rc *ir = dev->ir;
0386 
0387     if (!ir)
0388         return 0;
0389 
0390     pr_info("Restarting RC\n");
0391 
0392     /* Enable IR */
0393     au8522_rc_set(ir, 0xe0, 1 << 4);
0394 
0395     schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
0396 
0397     return 0;
0398 }