linux/drivers/media/common/ir-functions.c
<<
>>
Prefs
   1/*
   2 *
   3 * some common structs and functions to handle infrared remotes via
   4 * input layer ...
   5 *
   6 * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
   7 *
   8 *  This program is free software; you can redistribute it and/or modify
   9 *  it under the terms of the GNU General Public License as published by
  10 *  the Free Software Foundation; either version 2 of the License, or
  11 *  (at your option) any later version.
  12 *
  13 *  This program is distributed in the hope that it will be useful,
  14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 *  GNU General Public License for more details.
  17 *
  18 *  You should have received a copy of the GNU General Public License
  19 *  along with this program; if not, write to the Free Software
  20 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  21 */
  22
  23#include <linux/module.h>
  24#include <linux/string.h>
  25#include <linux/jiffies.h>
  26#include <media/ir-common.h>
  27
  28/* -------------------------------------------------------------------------- */
  29
  30MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
  31MODULE_LICENSE("GPL");
  32
  33static int repeat = 1;
  34module_param(repeat, int, 0444);
  35MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)");
  36
  37static int debug;    /* debug level (0,1,2) */
  38module_param(debug, int, 0644);
  39
  40#define dprintk(level, fmt, arg...)     if (debug >= level) \
  41        printk(KERN_DEBUG fmt , ## arg)
  42
  43/* -------------------------------------------------------------------------- */
  44
  45static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
  46{
  47        if (KEY_RESERVED == ir->keycode) {
  48                printk(KERN_INFO "%s: unknown key: key=0x%02x raw=0x%02x down=%d\n",
  49                       dev->name,ir->ir_key,ir->ir_raw,ir->keypressed);
  50                return;
  51        }
  52        dprintk(1,"%s: key event code=%d down=%d\n",
  53                dev->name,ir->keycode,ir->keypressed);
  54        input_report_key(dev,ir->keycode,ir->keypressed);
  55        input_sync(dev);
  56}
  57
  58/* -------------------------------------------------------------------------- */
  59
  60void ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
  61                   int ir_type, IR_KEYTAB_TYPE *ir_codes)
  62{
  63        int i;
  64
  65        ir->ir_type = ir_type;
  66        if (ir_codes)
  67                memcpy(ir->ir_codes, ir_codes, sizeof(ir->ir_codes));
  68
  69        dev->keycode     = ir->ir_codes;
  70        dev->keycodesize = sizeof(IR_KEYTAB_TYPE);
  71        dev->keycodemax  = IR_KEYTAB_SIZE;
  72        for (i = 0; i < IR_KEYTAB_SIZE; i++)
  73                set_bit(ir->ir_codes[i], dev->keybit);
  74        clear_bit(0, dev->keybit);
  75
  76        set_bit(EV_KEY, dev->evbit);
  77        if (repeat)
  78                set_bit(EV_REP, dev->evbit);
  79}
  80EXPORT_SYMBOL_GPL(ir_input_init);
  81
  82void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir)
  83{
  84        if (ir->keypressed) {
  85                ir->keypressed = 0;
  86                ir_input_key_event(dev,ir);
  87        }
  88}
  89EXPORT_SYMBOL_GPL(ir_input_nokey);
  90
  91void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
  92                      u32 ir_key, u32 ir_raw)
  93{
  94        u32 keycode = IR_KEYCODE(ir->ir_codes, ir_key);
  95
  96        if (ir->keypressed && ir->keycode != keycode) {
  97                ir->keypressed = 0;
  98                ir_input_key_event(dev,ir);
  99        }
 100        if (!ir->keypressed) {
 101                ir->ir_key  = ir_key;
 102                ir->ir_raw  = ir_raw;
 103                ir->keycode = keycode;
 104                ir->keypressed = 1;
 105                ir_input_key_event(dev,ir);
 106        }
 107}
 108EXPORT_SYMBOL_GPL(ir_input_keydown);
 109
 110/* -------------------------------------------------------------------------- */
 111/* extract mask bits out of data and pack them into the result */
 112u32 ir_extract_bits(u32 data, u32 mask)
 113{
 114        u32 vbit = 1, value = 0;
 115
 116        do {
 117            if (mask&1) {
 118                if (data&1)
 119                        value |= vbit;
 120                vbit<<=1;
 121            }
 122            data>>=1;
 123        } while (mask>>=1);
 124
 125        return value;
 126}
 127EXPORT_SYMBOL_GPL(ir_extract_bits);
 128
 129static int inline getbit(u32 *samples, int bit)
 130{
 131        return (samples[bit/32] & (1 << (31-(bit%32)))) ? 1 : 0;
 132}
 133
 134/* sump raw samples for visual debugging ;) */
 135int ir_dump_samples(u32 *samples, int count)
 136{
 137        int i, bit, start;
 138
 139        printk(KERN_DEBUG "ir samples: ");
 140        start = 0;
 141        for (i = 0; i < count * 32; i++) {
 142                bit = getbit(samples,i);
 143                if (bit)
 144                        start = 1;
 145                if (0 == start)
 146                        continue;
 147                printk("%s", bit ? "#" : "_");
 148        }
 149        printk("\n");
 150        return 0;
 151}
 152EXPORT_SYMBOL_GPL(ir_dump_samples);
 153
 154/* decode raw samples, pulse distance coding used by NEC remotes */
 155int ir_decode_pulsedistance(u32 *samples, int count, int low, int high)
 156{
 157        int i,last,bit,len;
 158        u32 curBit;
 159        u32 value;
 160
 161        /* find start burst */
 162        for (i = len = 0; i < count * 32; i++) {
 163                bit = getbit(samples,i);
 164                if (bit) {
 165                        len++;
 166                } else {
 167                        if (len >= 29)
 168                                break;
 169                        len = 0;
 170                }
 171        }
 172
 173        /* start burst to short */
 174        if (len < 29)
 175                return 0xffffffff;
 176
 177        /* find start silence */
 178        for (len = 0; i < count * 32; i++) {
 179                bit = getbit(samples,i);
 180                if (bit) {
 181                        break;
 182                } else {
 183                        len++;
 184                }
 185        }
 186
 187        /* silence to short */
 188        if (len < 7)
 189                return 0xffffffff;
 190
 191        /* go decoding */
 192        len   = 0;
 193        last = 1;
 194        value = 0; curBit = 1;
 195        for (; i < count * 32; i++) {
 196                bit  = getbit(samples,i);
 197                if (last) {
 198                        if(bit) {
 199                                continue;
 200                        } else {
 201                                len = 1;
 202                        }
 203                } else {
 204                        if (bit) {
 205                                if (len > (low + high) /2)
 206                                        value |= curBit;
 207                                curBit <<= 1;
 208                                if (curBit == 1)
 209                                        break;
 210                        } else {
 211                                len++;
 212                        }
 213                }
 214                last = bit;
 215        }
 216
 217        return value;
 218}
 219EXPORT_SYMBOL_GPL(ir_decode_pulsedistance);
 220
 221/* decode raw samples, biphase coding, used by rc5 for example */
 222int ir_decode_biphase(u32 *samples, int count, int low, int high)
 223{
 224        int i,last,bit,len,flips;
 225        u32 value;
 226
 227        /* find start bit (1) */
 228        for (i = 0; i < 32; i++) {
 229                bit = getbit(samples,i);
 230                if (bit)
 231                        break;
 232        }
 233
 234        /* go decoding */
 235        len   = 0;
 236        flips = 0;
 237        value = 1;
 238        for (; i < count * 32; i++) {
 239                if (len > high)
 240                        break;
 241                if (flips > 1)
 242                        break;
 243                last = bit;
 244                bit  = getbit(samples,i);
 245                if (last == bit) {
 246                        len++;
 247                        continue;
 248                }
 249                if (len < low) {
 250                        len++;
 251                        flips++;
 252                        continue;
 253                }
 254                value <<= 1;
 255                value |= bit;
 256                flips = 0;
 257                len   = 1;
 258        }
 259        return value;
 260}
 261EXPORT_SYMBOL_GPL(ir_decode_biphase);
 262
 263/* RC5 decoding stuff, moved from bttv-input.c to share it with
 264 * saa7134 */
 265
 266/* decode raw bit pattern to RC5 code */
 267static u32 ir_rc5_decode(unsigned int code)
 268{
 269        unsigned int org_code = code;
 270        unsigned int pair;
 271        unsigned int rc5 = 0;
 272        int i;
 273
 274        for (i = 0; i < 14; ++i) {
 275                pair = code & 0x3;
 276                code >>= 2;
 277
 278                rc5 <<= 1;
 279                switch (pair) {
 280                case 0:
 281                case 2:
 282                        break;
 283                case 1:
 284                        rc5 |= 1;
 285                        break;
 286                case 3:
 287                        dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code);
 288                        return 0;
 289                }
 290        }
 291        dprintk(1, "ir-common: code=%x, rc5=%x, start=%x, toggle=%x, address=%x, "
 292                "instr=%x\n", rc5, org_code, RC5_START(rc5),
 293                RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
 294        return rc5;
 295}
 296
 297void ir_rc5_timer_end(unsigned long data)
 298{
 299        struct card_ir *ir = (struct card_ir *)data;
 300        struct timeval tv;
 301        unsigned long current_jiffies, timeout;
 302        u32 gap;
 303        u32 rc5 = 0;
 304
 305        /* get time */
 306        current_jiffies = jiffies;
 307        do_gettimeofday(&tv);
 308
 309        /* avoid overflow with gap >1s */
 310        if (tv.tv_sec - ir->base_time.tv_sec > 1) {
 311                gap = 200000;
 312        } else {
 313                gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
 314                    tv.tv_usec - ir->base_time.tv_usec;
 315        }
 316
 317        /* signal we're ready to start a new code */
 318        ir->active = 0;
 319
 320        /* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */
 321        if (gap < 28000) {
 322                dprintk(1, "ir-common: spurious timer_end\n");
 323                return;
 324        }
 325
 326        if (ir->last_bit < 20) {
 327                /* ignore spurious codes (caused by light/other remotes) */
 328                dprintk(1, "ir-common: short code: %x\n", ir->code);
 329        } else {
 330                ir->code = (ir->code << ir->shift_by) | 1;
 331                rc5 = ir_rc5_decode(ir->code);
 332
 333                /* two start bits? */
 334                if (RC5_START(rc5) != ir->start) {
 335                        dprintk(1, "ir-common: rc5 start bits invalid: %u\n", RC5_START(rc5));
 336
 337                        /* right address? */
 338                } else if (RC5_ADDR(rc5) == ir->addr) {
 339                        u32 toggle = RC5_TOGGLE(rc5);
 340                        u32 instr = RC5_INSTR(rc5);
 341
 342                        /* Good code, decide if repeat/repress */
 343                        if (toggle != RC5_TOGGLE(ir->last_rc5) ||
 344                            instr != RC5_INSTR(ir->last_rc5)) {
 345                                dprintk(1, "ir-common: instruction %x, toggle %x\n", instr,
 346                                        toggle);
 347                                ir_input_nokey(ir->dev, &ir->ir);
 348                                ir_input_keydown(ir->dev, &ir->ir, instr,
 349                                                 instr);
 350                        }
 351
 352                        /* Set/reset key-up timer */
 353                        timeout = current_jiffies +
 354                                  msecs_to_jiffies(ir->rc5_key_timeout);
 355                        mod_timer(&ir->timer_keyup, timeout);
 356
 357                        /* Save code for repeat test */
 358                        ir->last_rc5 = rc5;
 359                }
 360        }
 361}
 362EXPORT_SYMBOL_GPL(ir_rc5_timer_end);
 363
 364void ir_rc5_timer_keyup(unsigned long data)
 365{
 366        struct card_ir *ir = (struct card_ir *)data;
 367
 368        dprintk(1, "ir-common: key released\n");
 369        ir_input_nokey(ir->dev, &ir->ir);
 370}
 371EXPORT_SYMBOL_GPL(ir_rc5_timer_keyup);
 372