linux/drivers/media/rc/ir-nec-decoder.c
<<
>>
Prefs
   1/* ir-nec-decoder.c - handle NEC IR Pulse/Space protocol
   2 *
   3 * Copyright (C) 2010 by Mauro Carvalho Chehab
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 *  it under the terms of the GNU General Public License as published by
   7 *  the Free Software Foundation version 2 of the License.
   8 *
   9 *  This program is distributed in the hope that it will be useful,
  10 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 *  GNU General Public License for more details.
  13 */
  14
  15#include <linux/bitrev.h>
  16#include <linux/module.h>
  17#include "rc-core-priv.h"
  18
  19#define NEC_NBITS               32
  20#define NEC_UNIT                562500  /* ns */
  21#define NEC_HEADER_PULSE        (16 * NEC_UNIT)
  22#define NECX_HEADER_PULSE       (8  * NEC_UNIT) /* Less common NEC variant */
  23#define NEC_HEADER_SPACE        (8  * NEC_UNIT)
  24#define NEC_REPEAT_SPACE        (4  * NEC_UNIT)
  25#define NEC_BIT_PULSE           (1  * NEC_UNIT)
  26#define NEC_BIT_0_SPACE         (1  * NEC_UNIT)
  27#define NEC_BIT_1_SPACE         (3  * NEC_UNIT)
  28#define NEC_TRAILER_PULSE       (1  * NEC_UNIT)
  29#define NEC_TRAILER_SPACE       (10 * NEC_UNIT) /* even longer in reality */
  30#define NECX_REPEAT_BITS        1
  31
  32enum nec_state {
  33        STATE_INACTIVE,
  34        STATE_HEADER_SPACE,
  35        STATE_BIT_PULSE,
  36        STATE_BIT_SPACE,
  37        STATE_TRAILER_PULSE,
  38        STATE_TRAILER_SPACE,
  39};
  40
  41/**
  42 * ir_nec_decode() - Decode one NEC pulse or space
  43 * @dev:        the struct rc_dev descriptor of the device
  44 * @duration:   the struct ir_raw_event descriptor of the pulse/space
  45 *
  46 * This function returns -EINVAL if the pulse violates the state machine
  47 */
  48static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev)
  49{
  50        struct nec_dec *data = &dev->raw->nec;
  51        u32 scancode;
  52        enum rc_type rc_type;
  53        u8 address, not_address, command, not_command;
  54        bool send_32bits = false;
  55
  56        if (!is_timing_event(ev)) {
  57                if (ev.reset)
  58                        data->state = STATE_INACTIVE;
  59                return 0;
  60        }
  61
  62        IR_dprintk(2, "NEC decode started at state %d (%uus %s)\n",
  63                   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
  64
  65        switch (data->state) {
  66
  67        case STATE_INACTIVE:
  68                if (!ev.pulse)
  69                        break;
  70
  71                if (eq_margin(ev.duration, NEC_HEADER_PULSE, NEC_UNIT * 2)) {
  72                        data->is_nec_x = false;
  73                        data->necx_repeat = false;
  74                } else if (eq_margin(ev.duration, NECX_HEADER_PULSE, NEC_UNIT / 2))
  75                        data->is_nec_x = true;
  76                else
  77                        break;
  78
  79                data->count = 0;
  80                data->state = STATE_HEADER_SPACE;
  81                return 0;
  82
  83        case STATE_HEADER_SPACE:
  84                if (ev.pulse)
  85                        break;
  86
  87                if (eq_margin(ev.duration, NEC_HEADER_SPACE, NEC_UNIT)) {
  88                        data->state = STATE_BIT_PULSE;
  89                        return 0;
  90                } else if (eq_margin(ev.duration, NEC_REPEAT_SPACE, NEC_UNIT / 2)) {
  91                        if (!dev->keypressed) {
  92                                IR_dprintk(1, "Discarding last key repeat: event after key up\n");
  93                        } else {
  94                                rc_repeat(dev);
  95                                IR_dprintk(1, "Repeat last key\n");
  96                                data->state = STATE_TRAILER_PULSE;
  97                        }
  98                        return 0;
  99                }
 100
 101                break;
 102
 103        case STATE_BIT_PULSE:
 104                if (!ev.pulse)
 105                        break;
 106
 107                if (!eq_margin(ev.duration, NEC_BIT_PULSE, NEC_UNIT / 2))
 108                        break;
 109
 110                data->state = STATE_BIT_SPACE;
 111                return 0;
 112
 113        case STATE_BIT_SPACE:
 114                if (ev.pulse)
 115                        break;
 116
 117                if (data->necx_repeat && data->count == NECX_REPEAT_BITS &&
 118                        geq_margin(ev.duration,
 119                        NEC_TRAILER_SPACE, NEC_UNIT / 2)) {
 120                                IR_dprintk(1, "Repeat last key\n");
 121                                rc_repeat(dev);
 122                                data->state = STATE_INACTIVE;
 123                                return 0;
 124
 125                } else if (data->count > NECX_REPEAT_BITS)
 126                        data->necx_repeat = false;
 127
 128                data->bits <<= 1;
 129                if (eq_margin(ev.duration, NEC_BIT_1_SPACE, NEC_UNIT / 2))
 130                        data->bits |= 1;
 131                else if (!eq_margin(ev.duration, NEC_BIT_0_SPACE, NEC_UNIT / 2))
 132                        break;
 133                data->count++;
 134
 135                if (data->count == NEC_NBITS)
 136                        data->state = STATE_TRAILER_PULSE;
 137                else
 138                        data->state = STATE_BIT_PULSE;
 139
 140                return 0;
 141
 142        case STATE_TRAILER_PULSE:
 143                if (!ev.pulse)
 144                        break;
 145
 146                if (!eq_margin(ev.duration, NEC_TRAILER_PULSE, NEC_UNIT / 2))
 147                        break;
 148
 149                data->state = STATE_TRAILER_SPACE;
 150                return 0;
 151
 152        case STATE_TRAILER_SPACE:
 153                if (ev.pulse)
 154                        break;
 155
 156                if (!geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2))
 157                        break;
 158
 159                address     = bitrev8((data->bits >> 24) & 0xff);
 160                not_address = bitrev8((data->bits >> 16) & 0xff);
 161                command     = bitrev8((data->bits >>  8) & 0xff);
 162                not_command = bitrev8((data->bits >>  0) & 0xff);
 163
 164                if ((command ^ not_command) != 0xff) {
 165                        IR_dprintk(1, "NEC checksum error: received 0x%08x\n",
 166                                   data->bits);
 167                        send_32bits = true;
 168                }
 169
 170                if (send_32bits) {
 171                        /* NEC transport, but modified protocol, used by at
 172                         * least Apple and TiVo remotes */
 173                        scancode = data->bits;
 174                        IR_dprintk(1, "NEC (modified) scancode 0x%08x\n", scancode);
 175                        rc_type = RC_TYPE_NEC32;
 176                } else if ((address ^ not_address) != 0xff) {
 177                        /* Extended NEC */
 178                        scancode = address     << 16 |
 179                                   not_address <<  8 |
 180                                   command;
 181                        IR_dprintk(1, "NEC (Ext) scancode 0x%06x\n", scancode);
 182                        rc_type = RC_TYPE_NECX;
 183                } else {
 184                        /* Normal NEC */
 185                        scancode = address << 8 | command;
 186                        IR_dprintk(1, "NEC scancode 0x%04x\n", scancode);
 187                        rc_type = RC_TYPE_NEC;
 188                }
 189
 190                if (data->is_nec_x)
 191                        data->necx_repeat = true;
 192
 193                rc_keydown(dev, rc_type, scancode, 0);
 194                data->state = STATE_INACTIVE;
 195                return 0;
 196        }
 197
 198        IR_dprintk(1, "NEC decode failed at count %d state %d (%uus %s)\n",
 199                   data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse));
 200        data->state = STATE_INACTIVE;
 201        return -EINVAL;
 202}
 203
 204static struct ir_raw_handler nec_handler = {
 205        .protocols      = RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32,
 206        .decode         = ir_nec_decode,
 207};
 208
 209static int __init ir_nec_decode_init(void)
 210{
 211        ir_raw_handler_register(&nec_handler);
 212
 213        printk(KERN_INFO "IR NEC protocol handler initialized\n");
 214        return 0;
 215}
 216
 217static void __exit ir_nec_decode_exit(void)
 218{
 219        ir_raw_handler_unregister(&nec_handler);
 220}
 221
 222module_init(ir_nec_decode_init);
 223module_exit(ir_nec_decode_exit);
 224
 225MODULE_LICENSE("GPL");
 226MODULE_AUTHOR("Mauro Carvalho Chehab");
 227MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
 228MODULE_DESCRIPTION("NEC IR protocol decoder");
 229