linux/drivers/media/rc/ir-sanyo-decoder.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2// ir-sanyo-decoder.c - handle SANYO IR Pulse/Space protocol
   3//
   4// Copyright (C) 2011 by Mauro Carvalho Chehab
   5//
   6// This protocol uses the NEC protocol timings. However, data is formatted as:
   7//      13 bits Custom Code
   8//      13 bits NOT(Custom Code)
   9//      8 bits Key data
  10//      8 bits NOT(Key data)
  11//
  12// According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon
  13// Information for this protocol is available at the Sanyo LC7461 datasheet.
  14
  15#include <linux/module.h>
  16#include <linux/bitrev.h>
  17#include "rc-core-priv.h"
  18
  19#define SANYO_NBITS             (13+13+8+8)
  20#define SANYO_UNIT              562500  /* ns */
  21#define SANYO_HEADER_PULSE      (16  * SANYO_UNIT)
  22#define SANYO_HEADER_SPACE      (8   * SANYO_UNIT)
  23#define SANYO_BIT_PULSE         (1   * SANYO_UNIT)
  24#define SANYO_BIT_0_SPACE       (1   * SANYO_UNIT)
  25#define SANYO_BIT_1_SPACE       (3   * SANYO_UNIT)
  26#define SANYO_REPEAT_SPACE      (150 * SANYO_UNIT)
  27#define SANYO_TRAILER_PULSE     (1   * SANYO_UNIT)
  28#define SANYO_TRAILER_SPACE     (10  * SANYO_UNIT)      /* in fact, 42 */
  29
  30enum sanyo_state {
  31        STATE_INACTIVE,
  32        STATE_HEADER_SPACE,
  33        STATE_BIT_PULSE,
  34        STATE_BIT_SPACE,
  35        STATE_TRAILER_PULSE,
  36        STATE_TRAILER_SPACE,
  37};
  38
  39/**
  40 * ir_sanyo_decode() - Decode one SANYO pulse or space
  41 * @dev:        the struct rc_dev descriptor of the device
  42 * @ev:         the struct ir_raw_event descriptor of the pulse/space
  43 *
  44 * This function returns -EINVAL if the pulse violates the state machine
  45 */
  46static int ir_sanyo_decode(struct rc_dev *dev, struct ir_raw_event ev)
  47{
  48        struct sanyo_dec *data = &dev->raw->sanyo;
  49        u32 scancode;
  50        u16 address;
  51        u8 command, not_command;
  52
  53        if (!is_timing_event(ev)) {
  54                if (ev.reset) {
  55                        dev_dbg(&dev->dev, "SANYO event reset received. reset to state 0\n");
  56                        data->state = STATE_INACTIVE;
  57                }
  58                return 0;
  59        }
  60
  61        dev_dbg(&dev->dev, "SANYO decode started at state %d (%uus %s)\n",
  62                data->state, TO_US(ev.duration), TO_STR(ev.pulse));
  63
  64        switch (data->state) {
  65
  66        case STATE_INACTIVE:
  67                if (!ev.pulse)
  68                        break;
  69
  70                if (eq_margin(ev.duration, SANYO_HEADER_PULSE, SANYO_UNIT / 2)) {
  71                        data->count = 0;
  72                        data->state = STATE_HEADER_SPACE;
  73                        return 0;
  74                }
  75                break;
  76
  77
  78        case STATE_HEADER_SPACE:
  79                if (ev.pulse)
  80                        break;
  81
  82                if (eq_margin(ev.duration, SANYO_HEADER_SPACE, SANYO_UNIT / 2)) {
  83                        data->state = STATE_BIT_PULSE;
  84                        return 0;
  85                }
  86
  87                break;
  88
  89        case STATE_BIT_PULSE:
  90                if (!ev.pulse)
  91                        break;
  92
  93                if (!eq_margin(ev.duration, SANYO_BIT_PULSE, SANYO_UNIT / 2))
  94                        break;
  95
  96                data->state = STATE_BIT_SPACE;
  97                return 0;
  98
  99        case STATE_BIT_SPACE:
 100                if (ev.pulse)
 101                        break;
 102
 103                if (!data->count && geq_margin(ev.duration, SANYO_REPEAT_SPACE, SANYO_UNIT / 2)) {
 104                        rc_repeat(dev);
 105                        dev_dbg(&dev->dev, "SANYO repeat last key\n");
 106                        data->state = STATE_INACTIVE;
 107                        return 0;
 108                }
 109
 110                data->bits <<= 1;
 111                if (eq_margin(ev.duration, SANYO_BIT_1_SPACE, SANYO_UNIT / 2))
 112                        data->bits |= 1;
 113                else if (!eq_margin(ev.duration, SANYO_BIT_0_SPACE, SANYO_UNIT / 2))
 114                        break;
 115                data->count++;
 116
 117                if (data->count == SANYO_NBITS)
 118                        data->state = STATE_TRAILER_PULSE;
 119                else
 120                        data->state = STATE_BIT_PULSE;
 121
 122                return 0;
 123
 124        case STATE_TRAILER_PULSE:
 125                if (!ev.pulse)
 126                        break;
 127
 128                if (!eq_margin(ev.duration, SANYO_TRAILER_PULSE, SANYO_UNIT / 2))
 129                        break;
 130
 131                data->state = STATE_TRAILER_SPACE;
 132                return 0;
 133
 134        case STATE_TRAILER_SPACE:
 135                if (ev.pulse)
 136                        break;
 137
 138                if (!geq_margin(ev.duration, SANYO_TRAILER_SPACE, SANYO_UNIT / 2))
 139                        break;
 140
 141                address     = bitrev16((data->bits >> 29) & 0x1fff) >> 3;
 142                /* not_address = bitrev16((data->bits >> 16) & 0x1fff) >> 3; */
 143                command     = bitrev8((data->bits >>  8) & 0xff);
 144                not_command = bitrev8((data->bits >>  0) & 0xff);
 145
 146                if ((command ^ not_command) != 0xff) {
 147                        dev_dbg(&dev->dev, "SANYO checksum error: received 0x%08llx\n",
 148                                data->bits);
 149                        data->state = STATE_INACTIVE;
 150                        return 0;
 151                }
 152
 153                scancode = address << 8 | command;
 154                dev_dbg(&dev->dev, "SANYO scancode: 0x%06x\n", scancode);
 155                rc_keydown(dev, RC_PROTO_SANYO, scancode, 0);
 156                data->state = STATE_INACTIVE;
 157                return 0;
 158        }
 159
 160        dev_dbg(&dev->dev, "SANYO decode failed at count %d state %d (%uus %s)\n",
 161                data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse));
 162        data->state = STATE_INACTIVE;
 163        return -EINVAL;
 164}
 165
 166static const struct ir_raw_timings_pd ir_sanyo_timings = {
 167        .header_pulse  = SANYO_HEADER_PULSE,
 168        .header_space  = SANYO_HEADER_SPACE,
 169        .bit_pulse     = SANYO_BIT_PULSE,
 170        .bit_space[0]  = SANYO_BIT_0_SPACE,
 171        .bit_space[1]  = SANYO_BIT_1_SPACE,
 172        .trailer_pulse = SANYO_TRAILER_PULSE,
 173        .trailer_space = SANYO_TRAILER_SPACE,
 174        .msb_first     = 1,
 175};
 176
 177/**
 178 * ir_sanyo_encode() - Encode a scancode as a stream of raw events
 179 *
 180 * @protocol:   protocol to encode
 181 * @scancode:   scancode to encode
 182 * @events:     array of raw ir events to write into
 183 * @max:        maximum size of @events
 184 *
 185 * Returns:     The number of events written.
 186 *              -ENOBUFS if there isn't enough space in the array to fit the
 187 *              encoding. In this case all @max events will have been written.
 188 */
 189static int ir_sanyo_encode(enum rc_proto protocol, u32 scancode,
 190                           struct ir_raw_event *events, unsigned int max)
 191{
 192        struct ir_raw_event *e = events;
 193        int ret;
 194        u64 raw;
 195
 196        raw = ((u64)(bitrev16(scancode >> 8) & 0xfff8) << (8 + 8 + 13 - 3)) |
 197              ((u64)(bitrev16(~scancode >> 8) & 0xfff8) << (8 + 8 +  0 - 3)) |
 198              ((bitrev8(scancode) & 0xff) << 8) |
 199              (bitrev8(~scancode) & 0xff);
 200
 201        ret = ir_raw_gen_pd(&e, max, &ir_sanyo_timings, SANYO_NBITS, raw);
 202        if (ret < 0)
 203                return ret;
 204
 205        return e - events;
 206}
 207
 208static struct ir_raw_handler sanyo_handler = {
 209        .protocols      = RC_PROTO_BIT_SANYO,
 210        .decode         = ir_sanyo_decode,
 211        .encode         = ir_sanyo_encode,
 212        .carrier        = 38000,
 213        .min_timeout    = SANYO_TRAILER_SPACE,
 214};
 215
 216static int __init ir_sanyo_decode_init(void)
 217{
 218        ir_raw_handler_register(&sanyo_handler);
 219
 220        printk(KERN_INFO "IR SANYO protocol handler initialized\n");
 221        return 0;
 222}
 223
 224static void __exit ir_sanyo_decode_exit(void)
 225{
 226        ir_raw_handler_unregister(&sanyo_handler);
 227}
 228
 229module_init(ir_sanyo_decode_init);
 230module_exit(ir_sanyo_decode_exit);
 231
 232MODULE_LICENSE("GPL v2");
 233MODULE_AUTHOR("Mauro Carvalho Chehab");
 234MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
 235MODULE_DESCRIPTION("SANYO IR protocol decoder");
 236