1 /* ir-rc6-decoder.c - A decoder for the RC6 IR protocol 2 * 3 * Copyright (C) 2010 by David Härdeman <david@hardeman.nu> 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 "rc-core-priv.h" 16 #include <linux/module.h> 17 18 /* 19 * This decoder currently supports: 20 * RC6-0-16 (standard toggle bit in header) 21 * RC6-6A-20 (no toggle bit) 22 * RC6-6A-24 (no toggle bit) 23 * RC6-6A-32 (MCE version with toggle bit in body) 24 */ 25 26 #define RC6_UNIT 444444 /* nanosecs */ 27 #define RC6_HEADER_NBITS 4 /* not including toggle bit */ 28 #define RC6_0_NBITS 16 29 #define RC6_6A_32_NBITS 32 30 #define RC6_6A_NBITS 128 /* Variable 8..128 */ 31 #define RC6_PREFIX_PULSE (6 * RC6_UNIT) 32 #define RC6_PREFIX_SPACE (2 * RC6_UNIT) 33 #define RC6_BIT_START (1 * RC6_UNIT) 34 #define RC6_BIT_END (1 * RC6_UNIT) 35 #define RC6_TOGGLE_START (2 * RC6_UNIT) 36 #define RC6_TOGGLE_END (2 * RC6_UNIT) 37 #define RC6_SUFFIX_SPACE (6 * RC6_UNIT) 38 #define RC6_MODE_MASK 0x07 /* for the header bits */ 39 #define RC6_STARTBIT_MASK 0x08 /* for the header bits */ 40 #define RC6_6A_MCE_TOGGLE_MASK 0x8000 /* for the body bits */ 41 #define RC6_6A_LCC_MASK 0xffff0000 /* RC6-6A-32 long customer code mask */ 42 #define RC6_6A_MCE_CC 0x800f0000 /* MCE customer code */ 43 #ifndef CHAR_BIT 44 #define CHAR_BIT 8 /* Normally in <limits.h> */ 45 #endif 46 47 enum rc6_mode { 48 RC6_MODE_0, 49 RC6_MODE_6A, 50 RC6_MODE_UNKNOWN, 51 }; 52 53 enum rc6_state { 54 STATE_INACTIVE, 55 STATE_PREFIX_SPACE, 56 STATE_HEADER_BIT_START, 57 STATE_HEADER_BIT_END, 58 STATE_TOGGLE_START, 59 STATE_TOGGLE_END, 60 STATE_BODY_BIT_START, 61 STATE_BODY_BIT_END, 62 STATE_FINISHED, 63 }; 64 65 static enum rc6_mode rc6_mode(struct rc6_dec *data) 66 { 67 switch (data->header & RC6_MODE_MASK) { 68 case 0: 69 return RC6_MODE_0; 70 case 6: 71 if (!data->toggle) 72 return RC6_MODE_6A; 73 /* fall through */ 74 default: 75 return RC6_MODE_UNKNOWN; 76 } 77 } 78 79 /** 80 * ir_rc6_decode() - Decode one RC6 pulse or space 81 * @dev: the struct rc_dev descriptor of the device 82 * @ev: the struct ir_raw_event descriptor of the pulse/space 83 * 84 * This function returns -EINVAL if the pulse violates the state machine 85 */ 86 static int ir_rc6_decode(struct rc_dev *dev, struct ir_raw_event ev) 87 { 88 struct rc6_dec *data = &dev->raw->rc6; 89 u32 scancode; 90 u8 toggle; 91 enum rc_proto protocol; 92 93 if (!is_timing_event(ev)) { 94 if (ev.reset) 95 data->state = STATE_INACTIVE; 96 return 0; 97 } 98 99 if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) 100 goto out; 101 102 again: 103 dev_dbg(&dev->dev, "RC6 decode started at state %i (%uus %s)\n", 104 data->state, TO_US(ev.duration), TO_STR(ev.pulse)); 105 106 if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) 107 return 0; 108 109 switch (data->state) { 110 111 case STATE_INACTIVE: 112 if (!ev.pulse) 113 break; 114 115 /* Note: larger margin on first pulse since each RC6_UNIT 116 is quite short and some hardware takes some time to 117 adjust to the signal */ 118 if (!eq_margin(ev.duration, RC6_PREFIX_PULSE, RC6_UNIT)) 119 break; 120 121 data->state = STATE_PREFIX_SPACE; 122 data->count = 0; 123 return 0; 124 125 case STATE_PREFIX_SPACE: 126 if (ev.pulse) 127 break; 128 129 if (!eq_margin(ev.duration, RC6_PREFIX_SPACE, RC6_UNIT / 2)) 130 break; 131 132 data->state = STATE_HEADER_BIT_START; 133 data->header = 0; 134 return 0; 135 136 case STATE_HEADER_BIT_START: 137 if (!eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2)) 138 break; 139 140 data->header <<= 1; 141 if (ev.pulse) 142 data->header |= 1; 143 data->count++; 144 data->state = STATE_HEADER_BIT_END; 145 return 0; 146 147 case STATE_HEADER_BIT_END: 148 if (data->count == RC6_HEADER_NBITS) 149 data->state = STATE_TOGGLE_START; 150 else 151 data->state = STATE_HEADER_BIT_START; 152 153 decrease_duration(&ev, RC6_BIT_END); 154 goto again; 155 156 case STATE_TOGGLE_START: 157 if (!eq_margin(ev.duration, RC6_TOGGLE_START, RC6_UNIT / 2)) 158 break; 159 160 data->toggle = ev.pulse; 161 data->state = STATE_TOGGLE_END; 162 return 0; 163 164 case STATE_TOGGLE_END: 165 if (!(data->header & RC6_STARTBIT_MASK)) { 166 dev_dbg(&dev->dev, "RC6 invalid start bit\n"); 167 break; 168 } 169 170 data->state = STATE_BODY_BIT_START; 171 decrease_duration(&ev, RC6_TOGGLE_END); 172 data->count = 0; 173 data->body = 0; 174 175 switch (rc6_mode(data)) { 176 case RC6_MODE_0: 177 data->wanted_bits = RC6_0_NBITS; 178 break; 179 case RC6_MODE_6A: 180 data->wanted_bits = RC6_6A_NBITS; 181 break; 182 default: 183 dev_dbg(&dev->dev, "RC6 unknown mode\n"); 184 goto out; 185 } 186 goto again; 187 188 case STATE_BODY_BIT_START: 189 if (eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2)) { 190 /* Discard LSB's that won't fit in data->body */ 191 if (data->count++ < CHAR_BIT * sizeof data->body) { 192 data->body <<= 1; 193 if (ev.pulse) 194 data->body |= 1; 195 } 196 data->state = STATE_BODY_BIT_END; 197 return 0; 198 } else if (RC6_MODE_6A == rc6_mode(data) && !ev.pulse && 199 geq_margin(ev.duration, RC6_SUFFIX_SPACE, RC6_UNIT / 2)) { 200 data->state = STATE_FINISHED; 201 goto again; 202 } 203 break; 204 205 case STATE_BODY_BIT_END: 206 if (data->count == data->wanted_bits) 207 data->state = STATE_FINISHED; 208 else 209 data->state = STATE_BODY_BIT_START; 210 211 decrease_duration(&ev, RC6_BIT_END); 212 goto again; 213 214 case STATE_FINISHED: 215 if (ev.pulse) 216 break; 217 218 switch (rc6_mode(data)) { 219 case RC6_MODE_0: 220 scancode = data->body; 221 toggle = data->toggle; 222 protocol = RC_PROTO_RC6_0; 223 dev_dbg(&dev->dev, "RC6(0) scancode 0x%04x (toggle: %u)\n", 224 scancode, toggle); 225 break; 226 227 case RC6_MODE_6A: 228 if (data->count > CHAR_BIT * sizeof data->body) { 229 dev_dbg(&dev->dev, "RC6 too many (%u) data bits\n", 230 data->count); 231 goto out; 232 } 233 234 scancode = data->body; 235 switch (data->count) { 236 case 20: 237 protocol = RC_PROTO_RC6_6A_20; 238 toggle = 0; 239 break; 240 case 24: 241 protocol = RC_PROTO_RC6_6A_24; 242 toggle = 0; 243 break; 244 case 32: 245 if ((scancode & RC6_6A_LCC_MASK) == RC6_6A_MCE_CC) { 246 protocol = RC_PROTO_RC6_MCE; 247 toggle = !!(scancode & RC6_6A_MCE_TOGGLE_MASK); 248 scancode &= ~RC6_6A_MCE_TOGGLE_MASK; 249 } else { 250 protocol = RC_PROTO_RC6_6A_32; 251 toggle = 0; 252 } 253 break; 254 default: 255 dev_dbg(&dev->dev, "RC6(6A) unsupported length\n"); 256 goto out; 257 } 258 259 dev_dbg(&dev->dev, "RC6(6A) proto 0x%04x, scancode 0x%08x (toggle: %u)\n", 260 protocol, scancode, toggle); 261 break; 262 default: 263 dev_dbg(&dev->dev, "RC6 unknown mode\n"); 264 goto out; 265 } 266 267 rc_keydown(dev, protocol, scancode, toggle); 268 data->state = STATE_INACTIVE; 269 return 0; 270 } 271 272 out: 273 dev_dbg(&dev->dev, "RC6 decode failed at state %i (%uus %s)\n", 274 data->state, TO_US(ev.duration), TO_STR(ev.pulse)); 275 data->state = STATE_INACTIVE; 276 return -EINVAL; 277 } 278 279 static const struct ir_raw_timings_manchester ir_rc6_timings[4] = { 280 { 281 .leader_pulse = RC6_PREFIX_PULSE, 282 .leader_space = RC6_PREFIX_SPACE, 283 .clock = RC6_UNIT, 284 .invert = 1, 285 }, 286 { 287 .clock = RC6_UNIT * 2, 288 .invert = 1, 289 }, 290 { 291 .clock = RC6_UNIT, 292 .invert = 1, 293 .trailer_space = RC6_SUFFIX_SPACE, 294 }, 295 }; 296 297 /** 298 * ir_rc6_encode() - Encode a scancode as a stream of raw events 299 * 300 * @protocol: protocol to encode 301 * @scancode: scancode to encode 302 * @events: array of raw ir events to write into 303 * @max: maximum size of @events 304 * 305 * Returns: The number of events written. 306 * -ENOBUFS if there isn't enough space in the array to fit the 307 * encoding. In this case all @max events will have been written. 308 * -EINVAL if the scancode is ambiguous or invalid. 309 */ 310 static int ir_rc6_encode(enum rc_proto protocol, u32 scancode, 311 struct ir_raw_event *events, unsigned int max) 312 { 313 int ret; 314 struct ir_raw_event *e = events; 315 316 if (protocol == RC_PROTO_RC6_0) { 317 /* Modulate the header (Start Bit & Mode-0) */ 318 ret = ir_raw_gen_manchester(&e, max - (e - events), 319 &ir_rc6_timings[0], 320 RC6_HEADER_NBITS, (1 << 3)); 321 if (ret < 0) 322 return ret; 323 324 /* Modulate Trailer Bit */ 325 ret = ir_raw_gen_manchester(&e, max - (e - events), 326 &ir_rc6_timings[1], 1, 0); 327 if (ret < 0) 328 return ret; 329 330 /* Modulate rest of the data */ 331 ret = ir_raw_gen_manchester(&e, max - (e - events), 332 &ir_rc6_timings[2], RC6_0_NBITS, 333 scancode); 334 if (ret < 0) 335 return ret; 336 337 } else { 338 int bits; 339 340 switch (protocol) { 341 case RC_PROTO_RC6_MCE: 342 case RC_PROTO_RC6_6A_32: 343 bits = 32; 344 break; 345 case RC_PROTO_RC6_6A_24: 346 bits = 24; 347 break; 348 case RC_PROTO_RC6_6A_20: 349 bits = 20; 350 break; 351 default: 352 return -EINVAL; 353 } 354 355 /* Modulate the header (Start Bit & Header-version 6 */ 356 ret = ir_raw_gen_manchester(&e, max - (e - events), 357 &ir_rc6_timings[0], 358 RC6_HEADER_NBITS, (1 << 3 | 6)); 359 if (ret < 0) 360 return ret; 361 362 /* Modulate Trailer Bit */ 363 ret = ir_raw_gen_manchester(&e, max - (e - events), 364 &ir_rc6_timings[1], 1, 0); 365 if (ret < 0) 366 return ret; 367 368 /* Modulate rest of the data */ 369 ret = ir_raw_gen_manchester(&e, max - (e - events), 370 &ir_rc6_timings[2], 371 bits, 372 scancode); 373 if (ret < 0) 374 return ret; 375 } 376 377 return e - events; 378 } 379 380 static struct ir_raw_handler rc6_handler = { 381 .protocols = RC_PROTO_BIT_RC6_0 | RC_PROTO_BIT_RC6_6A_20 | 382 RC_PROTO_BIT_RC6_6A_24 | RC_PROTO_BIT_RC6_6A_32 | 383 RC_PROTO_BIT_RC6_MCE, 384 .decode = ir_rc6_decode, 385 .encode = ir_rc6_encode, 386 .carrier = 36000, 387 .min_timeout = RC6_SUFFIX_SPACE, 388 }; 389 390 static int __init ir_rc6_decode_init(void) 391 { 392 ir_raw_handler_register(&rc6_handler); 393 394 printk(KERN_INFO "IR RC6 protocol handler initialized\n"); 395 return 0; 396 } 397 398 static void __exit ir_rc6_decode_exit(void) 399 { 400 ir_raw_handler_unregister(&rc6_handler); 401 } 402 403 module_init(ir_rc6_decode_init); 404 module_exit(ir_rc6_decode_exit); 405 406 MODULE_LICENSE("GPL"); 407 MODULE_AUTHOR("David Härdeman <david@hardeman.nu>"); 408 MODULE_DESCRIPTION("RC6 IR protocol decoder"); 409