0001
0002
0003
0004
0005
0006
0007 #include "rc-core-priv.h"
0008 #include <linux/module.h>
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #define RC6_UNIT 444
0019 #define RC6_HEADER_NBITS 4
0020 #define RC6_0_NBITS 16
0021 #define RC6_6A_32_NBITS 32
0022 #define RC6_6A_NBITS 128
0023 #define RC6_PREFIX_PULSE (6 * RC6_UNIT)
0024 #define RC6_PREFIX_SPACE (2 * RC6_UNIT)
0025 #define RC6_BIT_START (1 * RC6_UNIT)
0026 #define RC6_BIT_END (1 * RC6_UNIT)
0027 #define RC6_TOGGLE_START (2 * RC6_UNIT)
0028 #define RC6_TOGGLE_END (2 * RC6_UNIT)
0029 #define RC6_SUFFIX_SPACE (6 * RC6_UNIT)
0030 #define RC6_MODE_MASK 0x07
0031 #define RC6_STARTBIT_MASK 0x08
0032 #define RC6_6A_MCE_TOGGLE_MASK 0x8000
0033 #define RC6_6A_LCC_MASK 0xffff0000
0034 #define RC6_6A_MCE_CC 0x800f0000
0035 #define RC6_6A_ZOTAC_CC 0x80340000
0036 #define RC6_6A_KATHREIN_CC 0x80460000
0037 #ifndef CHAR_BIT
0038 #define CHAR_BIT 8
0039 #endif
0040
0041 enum rc6_mode {
0042 RC6_MODE_0,
0043 RC6_MODE_6A,
0044 RC6_MODE_UNKNOWN,
0045 };
0046
0047 enum rc6_state {
0048 STATE_INACTIVE,
0049 STATE_PREFIX_SPACE,
0050 STATE_HEADER_BIT_START,
0051 STATE_HEADER_BIT_END,
0052 STATE_TOGGLE_START,
0053 STATE_TOGGLE_END,
0054 STATE_BODY_BIT_START,
0055 STATE_BODY_BIT_END,
0056 STATE_FINISHED,
0057 };
0058
0059 static enum rc6_mode rc6_mode(struct rc6_dec *data)
0060 {
0061 switch (data->header & RC6_MODE_MASK) {
0062 case 0:
0063 return RC6_MODE_0;
0064 case 6:
0065 if (!data->toggle)
0066 return RC6_MODE_6A;
0067 fallthrough;
0068 default:
0069 return RC6_MODE_UNKNOWN;
0070 }
0071 }
0072
0073
0074
0075
0076
0077
0078
0079
0080 static int ir_rc6_decode(struct rc_dev *dev, struct ir_raw_event ev)
0081 {
0082 struct rc6_dec *data = &dev->raw->rc6;
0083 u32 scancode;
0084 u8 toggle;
0085 enum rc_proto protocol;
0086
0087 if (!is_timing_event(ev)) {
0088 if (ev.overflow)
0089 data->state = STATE_INACTIVE;
0090 return 0;
0091 }
0092
0093 if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2))
0094 goto out;
0095
0096 again:
0097 dev_dbg(&dev->dev, "RC6 decode started at state %i (%uus %s)\n",
0098 data->state, ev.duration, TO_STR(ev.pulse));
0099
0100 if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2))
0101 return 0;
0102
0103 switch (data->state) {
0104
0105 case STATE_INACTIVE:
0106 if (!ev.pulse)
0107 break;
0108
0109
0110
0111
0112 if (!eq_margin(ev.duration, RC6_PREFIX_PULSE, RC6_UNIT))
0113 break;
0114
0115 data->state = STATE_PREFIX_SPACE;
0116 data->count = 0;
0117 return 0;
0118
0119 case STATE_PREFIX_SPACE:
0120 if (ev.pulse)
0121 break;
0122
0123 if (!eq_margin(ev.duration, RC6_PREFIX_SPACE, RC6_UNIT / 2))
0124 break;
0125
0126 data->state = STATE_HEADER_BIT_START;
0127 data->header = 0;
0128 return 0;
0129
0130 case STATE_HEADER_BIT_START:
0131 if (!eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2))
0132 break;
0133
0134 data->header <<= 1;
0135 if (ev.pulse)
0136 data->header |= 1;
0137 data->count++;
0138 data->state = STATE_HEADER_BIT_END;
0139 return 0;
0140
0141 case STATE_HEADER_BIT_END:
0142 if (data->count == RC6_HEADER_NBITS)
0143 data->state = STATE_TOGGLE_START;
0144 else
0145 data->state = STATE_HEADER_BIT_START;
0146
0147 decrease_duration(&ev, RC6_BIT_END);
0148 goto again;
0149
0150 case STATE_TOGGLE_START:
0151 if (!eq_margin(ev.duration, RC6_TOGGLE_START, RC6_UNIT / 2))
0152 break;
0153
0154 data->toggle = ev.pulse;
0155 data->state = STATE_TOGGLE_END;
0156 return 0;
0157
0158 case STATE_TOGGLE_END:
0159 if (!(data->header & RC6_STARTBIT_MASK)) {
0160 dev_dbg(&dev->dev, "RC6 invalid start bit\n");
0161 break;
0162 }
0163
0164 data->state = STATE_BODY_BIT_START;
0165 decrease_duration(&ev, RC6_TOGGLE_END);
0166 data->count = 0;
0167 data->body = 0;
0168
0169 switch (rc6_mode(data)) {
0170 case RC6_MODE_0:
0171 data->wanted_bits = RC6_0_NBITS;
0172 break;
0173 case RC6_MODE_6A:
0174 data->wanted_bits = RC6_6A_NBITS;
0175 break;
0176 default:
0177 dev_dbg(&dev->dev, "RC6 unknown mode\n");
0178 goto out;
0179 }
0180 goto again;
0181
0182 case STATE_BODY_BIT_START:
0183 if (eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2)) {
0184
0185 if (data->count++ < CHAR_BIT * sizeof data->body) {
0186 data->body <<= 1;
0187 if (ev.pulse)
0188 data->body |= 1;
0189 }
0190 data->state = STATE_BODY_BIT_END;
0191 return 0;
0192 } else if (RC6_MODE_6A == rc6_mode(data) && !ev.pulse &&
0193 geq_margin(ev.duration, RC6_SUFFIX_SPACE, RC6_UNIT / 2)) {
0194 data->state = STATE_FINISHED;
0195 goto again;
0196 }
0197 break;
0198
0199 case STATE_BODY_BIT_END:
0200 if (data->count == data->wanted_bits)
0201 data->state = STATE_FINISHED;
0202 else
0203 data->state = STATE_BODY_BIT_START;
0204
0205 decrease_duration(&ev, RC6_BIT_END);
0206 goto again;
0207
0208 case STATE_FINISHED:
0209 if (ev.pulse)
0210 break;
0211
0212 switch (rc6_mode(data)) {
0213 case RC6_MODE_0:
0214 scancode = data->body;
0215 toggle = data->toggle;
0216 protocol = RC_PROTO_RC6_0;
0217 dev_dbg(&dev->dev, "RC6(0) scancode 0x%04x (toggle: %u)\n",
0218 scancode, toggle);
0219 break;
0220
0221 case RC6_MODE_6A:
0222 if (data->count > CHAR_BIT * sizeof data->body) {
0223 dev_dbg(&dev->dev, "RC6 too many (%u) data bits\n",
0224 data->count);
0225 goto out;
0226 }
0227
0228 scancode = data->body;
0229 switch (data->count) {
0230 case 20:
0231 protocol = RC_PROTO_RC6_6A_20;
0232 toggle = 0;
0233 break;
0234 case 24:
0235 protocol = RC_PROTO_RC6_6A_24;
0236 toggle = 0;
0237 break;
0238 case 32:
0239 switch (scancode & RC6_6A_LCC_MASK) {
0240 case RC6_6A_MCE_CC:
0241 case RC6_6A_KATHREIN_CC:
0242 case RC6_6A_ZOTAC_CC:
0243 protocol = RC_PROTO_RC6_MCE;
0244 toggle = !!(scancode & RC6_6A_MCE_TOGGLE_MASK);
0245 scancode &= ~RC6_6A_MCE_TOGGLE_MASK;
0246 break;
0247 default:
0248 protocol = RC_PROTO_RC6_6A_32;
0249 toggle = 0;
0250 break;
0251 }
0252 break;
0253 default:
0254 dev_dbg(&dev->dev, "RC6(6A) unsupported length\n");
0255 goto out;
0256 }
0257
0258 dev_dbg(&dev->dev, "RC6(6A) proto 0x%04x, scancode 0x%08x (toggle: %u)\n",
0259 protocol, scancode, toggle);
0260 break;
0261 default:
0262 dev_dbg(&dev->dev, "RC6 unknown mode\n");
0263 goto out;
0264 }
0265
0266 rc_keydown(dev, protocol, scancode, toggle);
0267 data->state = STATE_INACTIVE;
0268 return 0;
0269 }
0270
0271 out:
0272 dev_dbg(&dev->dev, "RC6 decode failed at state %i (%uus %s)\n",
0273 data->state, ev.duration, TO_STR(ev.pulse));
0274 data->state = STATE_INACTIVE;
0275 return -EINVAL;
0276 }
0277
0278 static const struct ir_raw_timings_manchester ir_rc6_timings[4] = {
0279 {
0280 .leader_pulse = RC6_PREFIX_PULSE,
0281 .leader_space = RC6_PREFIX_SPACE,
0282 .clock = RC6_UNIT,
0283 .invert = 1,
0284 },
0285 {
0286 .clock = RC6_UNIT * 2,
0287 .invert = 1,
0288 },
0289 {
0290 .clock = RC6_UNIT,
0291 .invert = 1,
0292 .trailer_space = RC6_SUFFIX_SPACE,
0293 },
0294 };
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309 static int ir_rc6_encode(enum rc_proto protocol, u32 scancode,
0310 struct ir_raw_event *events, unsigned int max)
0311 {
0312 int ret;
0313 struct ir_raw_event *e = events;
0314
0315 if (protocol == RC_PROTO_RC6_0) {
0316
0317 ret = ir_raw_gen_manchester(&e, max - (e - events),
0318 &ir_rc6_timings[0],
0319 RC6_HEADER_NBITS, (1 << 3));
0320 if (ret < 0)
0321 return ret;
0322
0323
0324 ret = ir_raw_gen_manchester(&e, max - (e - events),
0325 &ir_rc6_timings[1], 1, 0);
0326 if (ret < 0)
0327 return ret;
0328
0329
0330 ret = ir_raw_gen_manchester(&e, max - (e - events),
0331 &ir_rc6_timings[2], RC6_0_NBITS,
0332 scancode);
0333 if (ret < 0)
0334 return ret;
0335
0336 } else {
0337 int bits;
0338
0339 switch (protocol) {
0340 case RC_PROTO_RC6_MCE:
0341 case RC_PROTO_RC6_6A_32:
0342 bits = 32;
0343 break;
0344 case RC_PROTO_RC6_6A_24:
0345 bits = 24;
0346 break;
0347 case RC_PROTO_RC6_6A_20:
0348 bits = 20;
0349 break;
0350 default:
0351 return -EINVAL;
0352 }
0353
0354
0355 ret = ir_raw_gen_manchester(&e, max - (e - events),
0356 &ir_rc6_timings[0],
0357 RC6_HEADER_NBITS, (1 << 3 | 6));
0358 if (ret < 0)
0359 return ret;
0360
0361
0362 ret = ir_raw_gen_manchester(&e, max - (e - events),
0363 &ir_rc6_timings[1], 1, 0);
0364 if (ret < 0)
0365 return ret;
0366
0367
0368 ret = ir_raw_gen_manchester(&e, max - (e - events),
0369 &ir_rc6_timings[2],
0370 bits,
0371 scancode);
0372 if (ret < 0)
0373 return ret;
0374 }
0375
0376 return e - events;
0377 }
0378
0379 static struct ir_raw_handler rc6_handler = {
0380 .protocols = RC_PROTO_BIT_RC6_0 | RC_PROTO_BIT_RC6_6A_20 |
0381 RC_PROTO_BIT_RC6_6A_24 | RC_PROTO_BIT_RC6_6A_32 |
0382 RC_PROTO_BIT_RC6_MCE,
0383 .decode = ir_rc6_decode,
0384 .encode = ir_rc6_encode,
0385 .carrier = 36000,
0386 .min_timeout = RC6_SUFFIX_SPACE,
0387 };
0388
0389 static int __init ir_rc6_decode_init(void)
0390 {
0391 ir_raw_handler_register(&rc6_handler);
0392
0393 printk(KERN_INFO "IR RC6 protocol handler initialized\n");
0394 return 0;
0395 }
0396
0397 static void __exit ir_rc6_decode_exit(void)
0398 {
0399 ir_raw_handler_unregister(&rc6_handler);
0400 }
0401
0402 module_init(ir_rc6_decode_init);
0403 module_exit(ir_rc6_decode_exit);
0404
0405 MODULE_LICENSE("GPL");
0406 MODULE_AUTHOR("David Härdeman <david@hardeman.nu>");
0407 MODULE_DESCRIPTION("RC6 IR protocol decoder");