linux/drivers/media/usb/au0828/au0828-input.c
<<
>>
Prefs
   1/*
   2  handle au0828 IR remotes via linux kernel input layer.
   3
   4   Copyright (C) 2014 Mauro Carvalho Chehab <mchehab@samsung.com>
   5   Copyright (c) 2014 Samsung Electronics Co., Ltd.
   6
   7  Based on em28xx-input.c.
   8
   9  This program is free software; you can redistribute it and/or modify
  10  it under the terms of the GNU General Public License as published by
  11  the Free Software Foundation; either version 2 of the License, or
  12  (at your option) any later version.
  13
  14  This program is distributed in the hope that it will be useful,
  15  but WITHOUT ANY WARRANTY; without even the implied warranty of
  16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17  GNU General Public License for more details.
  18 */
  19
  20#include "au0828.h"
  21
  22#include <linux/module.h>
  23#include <linux/init.h>
  24#include <linux/delay.h>
  25#include <linux/interrupt.h>
  26#include <linux/usb.h>
  27#include <linux/slab.h>
  28#include <media/rc-core.h>
  29
  30static int disable_ir;
  31module_param(disable_ir,        int, 0444);
  32MODULE_PARM_DESC(disable_ir, "disable infrared remote support");
  33
  34struct au0828_rc {
  35        struct au0828_dev *dev;
  36        struct rc_dev *rc;
  37        char name[32];
  38        char phys[32];
  39
  40        /* poll decoder */
  41        int polling;
  42        struct delayed_work work;
  43
  44        /* i2c slave address of external device (if used) */
  45        u16 i2c_dev_addr;
  46
  47        int  (*get_key_i2c)(struct au0828_rc *ir);
  48};
  49
  50/*
  51 * AU8522 has a builtin IR receiver. Add functions to get IR from it
  52 */
  53
  54static int au8522_rc_write(struct au0828_rc *ir, u16 reg, u8 data)
  55{
  56        int rc;
  57        char buf[] = { (reg >> 8) | 0x80, reg & 0xff, data };
  58        struct i2c_msg msg = { .addr = ir->i2c_dev_addr, .flags = 0,
  59                               .buf = buf, .len = sizeof(buf) };
  60
  61        rc = i2c_transfer(ir->dev->i2c_client.adapter, &msg, 1);
  62
  63        if (rc < 0)
  64                return rc;
  65
  66        return (rc == 1) ? 0 : -EIO;
  67}
  68
  69static int au8522_rc_read(struct au0828_rc *ir, u16 reg, int val,
  70                                 char *buf, int size)
  71{
  72        int rc;
  73        char obuf[3];
  74        struct i2c_msg msg[2] = { { .addr = ir->i2c_dev_addr, .flags = 0,
  75                                    .buf = obuf, .len = 2 },
  76                                  { .addr = ir->i2c_dev_addr, .flags = I2C_M_RD,
  77                                    .buf = buf, .len = size } };
  78
  79        obuf[0] = 0x40 | reg >> 8;
  80        obuf[1] = reg & 0xff;
  81        if (val >= 0) {
  82                obuf[2] = val;
  83                msg[0].len++;
  84        }
  85
  86        rc = i2c_transfer(ir->dev->i2c_client.adapter, msg, 2);
  87
  88        if (rc < 0)
  89                return rc;
  90
  91        return (rc == 2) ? 0 : -EIO;
  92}
  93
  94static int au8522_rc_andor(struct au0828_rc *ir, u16 reg, u8 mask, u8 value)
  95{
  96        int rc;
  97        char buf, oldbuf;
  98
  99        rc = au8522_rc_read(ir, reg, -1, &buf, 1);
 100        if (rc < 0)
 101                return rc;
 102
 103        oldbuf = buf;
 104        buf = (buf & ~mask) | (value & mask);
 105
 106        /* Nothing to do, just return */
 107        if (buf == oldbuf)
 108                return 0;
 109
 110        return au8522_rc_write(ir, reg, buf);
 111}
 112
 113#define au8522_rc_set(ir, reg, bit) au8522_rc_andor(ir, (reg), (bit), (bit))
 114#define au8522_rc_clear(ir, reg, bit) au8522_rc_andor(ir, (reg), (bit), 0)
 115
 116/* Remote Controller time units */
 117
 118#define AU8522_UNIT             200000 /* ns */
 119#define NEC_START_SPACE         (4500000 / AU8522_UNIT)
 120#define NEC_START_PULSE         (562500 * 16)
 121#define RC5_START_SPACE         (4 * AU8522_UNIT)
 122#define RC5_START_PULSE         888888
 123
 124static int au0828_get_key_au8522(struct au0828_rc *ir)
 125{
 126        unsigned char buf[40];
 127        DEFINE_IR_RAW_EVENT(rawir);
 128        int i, j, rc;
 129        int prv_bit, bit, width;
 130        bool first = true;
 131
 132        /* do nothing if device is disconnected */
 133        if (test_bit(DEV_DISCONNECTED, &ir->dev->dev_state))
 134                return 0;
 135
 136        /* Check IR int */
 137        rc = au8522_rc_read(ir, 0xe1, -1, buf, 1);
 138        if (rc < 0 || !(buf[0] & (1 << 4))) {
 139                /* Be sure that IR is enabled */
 140                au8522_rc_set(ir, 0xe0, 1 << 4);
 141                return 0;
 142        }
 143
 144        /* Something arrived. Get the data */
 145        rc = au8522_rc_read(ir, 0xe3, 0x11, buf, sizeof(buf));
 146
 147
 148        if (rc < 0)
 149                return rc;
 150
 151        /* Disable IR */
 152        au8522_rc_clear(ir, 0xe0, 1 << 4);
 153
 154        /* Enable IR */
 155        au8522_rc_set(ir, 0xe0, 1 << 4);
 156
 157        dprintk(16, "RC data received: %*ph\n", 40, buf);
 158
 159        prv_bit = (buf[0] >> 7) & 0x01;
 160        width = 0;
 161        for (i = 0; i < sizeof(buf); i++) {
 162                for (j = 7; j >= 0; j--) {
 163                        bit = (buf[i] >> j) & 0x01;
 164                        if (bit == prv_bit) {
 165                                width++;
 166                                continue;
 167                        }
 168
 169                        /*
 170                         * Fix an au8522 bug: the first pulse event
 171                         * is lost. So, we need to fake it, based on the
 172                         * protocol. That means that not all raw decoders
 173                         * will work, as we need to add a hack for each
 174                         * protocol, based on the first space.
 175                         * So, we only support RC5 and NEC.
 176                         */
 177
 178                        if (first) {
 179                                first = false;
 180
 181                                init_ir_raw_event(&rawir);
 182                                rawir.pulse = true;
 183                                if (width > NEC_START_SPACE - 2 &&
 184                                    width < NEC_START_SPACE + 2) {
 185                                        /* NEC protocol */
 186                                        rawir.duration = NEC_START_PULSE;
 187                                        dprintk(16, "Storing NEC start %s with duration %d",
 188                                                rawir.pulse ? "pulse" : "space",
 189                                                rawir.duration);
 190                                } else {
 191                                        /* RC5 protocol */
 192                                        rawir.duration = RC5_START_PULSE;
 193                                        dprintk(16, "Storing RC5 start %s with duration %d",
 194                                                rawir.pulse ? "pulse" : "space",
 195                                                rawir.duration);
 196                                }
 197                                ir_raw_event_store(ir->rc, &rawir);
 198                        }
 199
 200                        init_ir_raw_event(&rawir);
 201                        rawir.pulse = prv_bit ? false : true;
 202                        rawir.duration = AU8522_UNIT * width;
 203                        dprintk(16, "Storing %s with duration %d",
 204                                rawir.pulse ? "pulse" : "space",
 205                                rawir.duration);
 206                        ir_raw_event_store(ir->rc, &rawir);
 207
 208                        width = 1;
 209                        prv_bit = bit;
 210                }
 211        }
 212
 213        init_ir_raw_event(&rawir);
 214        rawir.pulse = prv_bit ? false : true;
 215        rawir.duration = AU8522_UNIT * width;
 216        dprintk(16, "Storing end %s with duration %d",
 217                rawir.pulse ? "pulse" : "space",
 218                rawir.duration);
 219        ir_raw_event_store(ir->rc, &rawir);
 220
 221        ir_raw_event_handle(ir->rc);
 222
 223        return 1;
 224}
 225
 226/*
 227 * Generic IR code
 228 */
 229
 230static void au0828_rc_work(struct work_struct *work)
 231{
 232        struct au0828_rc *ir = container_of(work, struct au0828_rc, work.work);
 233        int rc;
 234
 235        rc = ir->get_key_i2c(ir);
 236        if (rc < 0)
 237                pr_info("Error while getting RC scancode\n");
 238
 239        schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
 240}
 241
 242static int au0828_rc_start(struct rc_dev *rc)
 243{
 244        struct au0828_rc *ir = rc->priv;
 245
 246        INIT_DELAYED_WORK(&ir->work, au0828_rc_work);
 247
 248        /* Enable IR */
 249        au8522_rc_set(ir, 0xe0, 1 << 4);
 250
 251        schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
 252
 253        return 0;
 254}
 255
 256static void au0828_rc_stop(struct rc_dev *rc)
 257{
 258        struct au0828_rc *ir = rc->priv;
 259
 260        cancel_delayed_work_sync(&ir->work);
 261
 262        /* do nothing if device is disconnected */
 263        if (!test_bit(DEV_DISCONNECTED, &ir->dev->dev_state)) {
 264                /* Disable IR */
 265                au8522_rc_clear(ir, 0xe0, 1 << 4);
 266        }
 267}
 268
 269static int au0828_probe_i2c_ir(struct au0828_dev *dev)
 270{
 271        int i = 0;
 272        const unsigned short addr_list[] = {
 273                 0x47, I2C_CLIENT_END
 274        };
 275
 276        while (addr_list[i] != I2C_CLIENT_END) {
 277                if (i2c_probe_func_quick_read(dev->i2c_client.adapter,
 278                                              addr_list[i]) == 1)
 279                        return addr_list[i];
 280                i++;
 281        }
 282
 283        return -ENODEV;
 284}
 285
 286int au0828_rc_register(struct au0828_dev *dev)
 287{
 288        struct au0828_rc *ir;
 289        struct rc_dev *rc;
 290        int err = -ENOMEM;
 291        u16 i2c_rc_dev_addr = 0;
 292
 293        if (!dev->board.has_ir_i2c || disable_ir)
 294                return 0;
 295
 296        i2c_rc_dev_addr = au0828_probe_i2c_ir(dev);
 297        if (!i2c_rc_dev_addr)
 298                return -ENODEV;
 299
 300        ir = kzalloc(sizeof(*ir), GFP_KERNEL);
 301        rc = rc_allocate_device();
 302        if (!ir || !rc)
 303                goto error;
 304
 305        /* record handles to ourself */
 306        ir->dev = dev;
 307        dev->ir = ir;
 308        ir->rc = rc;
 309
 310        rc->priv = ir;
 311        rc->open = au0828_rc_start;
 312        rc->close = au0828_rc_stop;
 313
 314        if (dev->board.has_ir_i2c) {    /* external i2c device */
 315                switch (dev->boardnr) {
 316                case AU0828_BOARD_HAUPPAUGE_HVR950Q:
 317                        rc->map_name = RC_MAP_HAUPPAUGE;
 318                        ir->get_key_i2c = au0828_get_key_au8522;
 319                        break;
 320                default:
 321                        err = -ENODEV;
 322                        goto error;
 323                }
 324
 325                ir->i2c_dev_addr = i2c_rc_dev_addr;
 326        }
 327
 328        /* This is how often we ask the chip for IR information */
 329        ir->polling = 100; /* ms */
 330
 331        /* init input device */
 332        snprintf(ir->name, sizeof(ir->name), "au0828 IR (%s)",
 333                 dev->board.name);
 334
 335        usb_make_path(dev->usbdev, ir->phys, sizeof(ir->phys));
 336        strlcat(ir->phys, "/input0", sizeof(ir->phys));
 337
 338        rc->input_name = ir->name;
 339        rc->input_phys = ir->phys;
 340        rc->input_id.bustype = BUS_USB;
 341        rc->input_id.version = 1;
 342        rc->input_id.vendor = le16_to_cpu(dev->usbdev->descriptor.idVendor);
 343        rc->input_id.product = le16_to_cpu(dev->usbdev->descriptor.idProduct);
 344        rc->dev.parent = &dev->usbdev->dev;
 345        rc->driver_name = "au0828-input";
 346        rc->driver_type = RC_DRIVER_IR_RAW;
 347        rc->allowed_protocols = RC_BIT_NEC | RC_BIT_RC5;
 348
 349        /* all done */
 350        err = rc_register_device(rc);
 351        if (err)
 352                goto error;
 353
 354        pr_info("Remote controller %s initalized\n", ir->name);
 355
 356        return 0;
 357
 358error:
 359        dev->ir = NULL;
 360        rc_free_device(rc);
 361        kfree(ir);
 362        return err;
 363}
 364
 365void au0828_rc_unregister(struct au0828_dev *dev)
 366{
 367        struct au0828_rc *ir = dev->ir;
 368
 369        /* skip detach on non attached boards */
 370        if (!ir)
 371                return;
 372
 373        rc_unregister_device(ir->rc);
 374
 375        /* done */
 376        kfree(ir);
 377        dev->ir = NULL;
 378}
 379
 380int au0828_rc_suspend(struct au0828_dev *dev)
 381{
 382        struct au0828_rc *ir = dev->ir;
 383
 384        if (!ir)
 385                return 0;
 386
 387        pr_info("Stopping RC\n");
 388
 389        cancel_delayed_work_sync(&ir->work);
 390
 391        /* Disable IR */
 392        au8522_rc_clear(ir, 0xe0, 1 << 4);
 393
 394        return 0;
 395}
 396
 397int au0828_rc_resume(struct au0828_dev *dev)
 398{
 399        struct au0828_rc *ir = dev->ir;
 400
 401        if (!ir)
 402                return 0;
 403
 404        pr_info("Restarting RC\n");
 405
 406        /* Enable IR */
 407        au8522_rc_set(ir, 0xe0, 1 << 4);
 408
 409        schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
 410
 411        return 0;
 412}
 413