ir-sanyo-decoder.c (6113B)
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 563 /* us */ 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.overflow) { 55 dev_dbg(&dev->dev, "SANYO event overflow 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, 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, 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");