0001
0002
0003
0004
0005
0006 #include "rc-core-priv.h"
0007 #include <linux/module.h>
0008
0009 #define RCMM_UNIT 166
0010 #define RCMM_PREFIX_PULSE 417
0011 #define RCMM_PULSE_0 278
0012 #define RCMM_PULSE_1 444
0013 #define RCMM_PULSE_2 611
0014 #define RCMM_PULSE_3 778
0015
0016 enum rcmm_state {
0017 STATE_INACTIVE,
0018 STATE_LOW,
0019 STATE_BUMP,
0020 STATE_VALUE,
0021 STATE_FINISHED,
0022 };
0023
0024 static bool rcmm_mode(const struct rcmm_dec *data)
0025 {
0026 return !((0x000c0000 & data->bits) == 0x000c0000);
0027 }
0028
0029 static int rcmm_miscmode(struct rc_dev *dev, struct rcmm_dec *data)
0030 {
0031 switch (data->count) {
0032 case 24:
0033 if (dev->enabled_protocols & RC_PROTO_BIT_RCMM24) {
0034 rc_keydown(dev, RC_PROTO_RCMM24, data->bits, 0);
0035 data->state = STATE_INACTIVE;
0036 return 0;
0037 }
0038 return -1;
0039
0040 case 12:
0041 if (dev->enabled_protocols & RC_PROTO_BIT_RCMM12) {
0042 rc_keydown(dev, RC_PROTO_RCMM12, data->bits, 0);
0043 data->state = STATE_INACTIVE;
0044 return 0;
0045 }
0046 return -1;
0047 }
0048
0049 return -1;
0050 }
0051
0052
0053
0054
0055
0056
0057
0058
0059 static int ir_rcmm_decode(struct rc_dev *dev, struct ir_raw_event ev)
0060 {
0061 struct rcmm_dec *data = &dev->raw->rcmm;
0062 u32 scancode;
0063 u8 toggle;
0064 int value;
0065
0066 if (!(dev->enabled_protocols & (RC_PROTO_BIT_RCMM32 |
0067 RC_PROTO_BIT_RCMM24 |
0068 RC_PROTO_BIT_RCMM12)))
0069 return 0;
0070
0071 if (!is_timing_event(ev)) {
0072 if (ev.overflow)
0073 data->state = STATE_INACTIVE;
0074 return 0;
0075 }
0076
0077 switch (data->state) {
0078 case STATE_INACTIVE:
0079 if (!ev.pulse)
0080 break;
0081
0082 if (!eq_margin(ev.duration, RCMM_PREFIX_PULSE, RCMM_UNIT))
0083 break;
0084
0085 data->state = STATE_LOW;
0086 data->count = 0;
0087 data->bits = 0;
0088 return 0;
0089
0090 case STATE_LOW:
0091 if (ev.pulse)
0092 break;
0093
0094 if (!eq_margin(ev.duration, RCMM_PULSE_0, RCMM_UNIT))
0095 break;
0096
0097 data->state = STATE_BUMP;
0098 return 0;
0099
0100 case STATE_BUMP:
0101 if (!ev.pulse)
0102 break;
0103
0104 if (!eq_margin(ev.duration, RCMM_UNIT, RCMM_UNIT / 2))
0105 break;
0106
0107 data->state = STATE_VALUE;
0108 return 0;
0109
0110 case STATE_VALUE:
0111 if (ev.pulse)
0112 break;
0113
0114 if (eq_margin(ev.duration, RCMM_PULSE_0, RCMM_UNIT / 2))
0115 value = 0;
0116 else if (eq_margin(ev.duration, RCMM_PULSE_1, RCMM_UNIT / 2))
0117 value = 1;
0118 else if (eq_margin(ev.duration, RCMM_PULSE_2, RCMM_UNIT / 2))
0119 value = 2;
0120 else if (eq_margin(ev.duration, RCMM_PULSE_3, RCMM_UNIT / 2))
0121 value = 3;
0122 else
0123 value = -1;
0124
0125 if (value == -1) {
0126 if (!rcmm_miscmode(dev, data))
0127 return 0;
0128 break;
0129 }
0130
0131 data->bits <<= 2;
0132 data->bits |= value;
0133
0134 data->count += 2;
0135
0136 if (data->count < 32)
0137 data->state = STATE_BUMP;
0138 else
0139 data->state = STATE_FINISHED;
0140
0141 return 0;
0142
0143 case STATE_FINISHED:
0144 if (!ev.pulse)
0145 break;
0146
0147 if (!eq_margin(ev.duration, RCMM_UNIT, RCMM_UNIT / 2))
0148 break;
0149
0150 if (rcmm_mode(data)) {
0151 toggle = !!(0x8000 & data->bits);
0152 scancode = data->bits & ~0x8000;
0153 } else {
0154 toggle = 0;
0155 scancode = data->bits;
0156 }
0157
0158 if (dev->enabled_protocols & RC_PROTO_BIT_RCMM32) {
0159 rc_keydown(dev, RC_PROTO_RCMM32, scancode, toggle);
0160 data->state = STATE_INACTIVE;
0161 return 0;
0162 }
0163
0164 break;
0165 }
0166
0167 dev_dbg(&dev->dev, "RC-MM decode failed at count %d state %d (%uus %s)\n",
0168 data->count, data->state, ev.duration, TO_STR(ev.pulse));
0169 data->state = STATE_INACTIVE;
0170 return -EINVAL;
0171 }
0172
0173 static const int rcmmspace[] = {
0174 RCMM_PULSE_0,
0175 RCMM_PULSE_1,
0176 RCMM_PULSE_2,
0177 RCMM_PULSE_3,
0178 };
0179
0180 static int ir_rcmm_rawencoder(struct ir_raw_event **ev, unsigned int max,
0181 unsigned int n, u32 data)
0182 {
0183 int i;
0184 int ret;
0185
0186 ret = ir_raw_gen_pulse_space(ev, &max, RCMM_PREFIX_PULSE, RCMM_PULSE_0);
0187 if (ret)
0188 return ret;
0189
0190 for (i = n - 2; i >= 0; i -= 2) {
0191 const unsigned int space = rcmmspace[(data >> i) & 3];
0192
0193 ret = ir_raw_gen_pulse_space(ev, &max, RCMM_UNIT, space);
0194 if (ret)
0195 return ret;
0196 }
0197
0198 return ir_raw_gen_pulse_space(ev, &max, RCMM_UNIT, RCMM_PULSE_3 * 2);
0199 }
0200
0201 static int ir_rcmm_encode(enum rc_proto protocol, u32 scancode,
0202 struct ir_raw_event *events, unsigned int max)
0203 {
0204 struct ir_raw_event *e = events;
0205 int ret;
0206
0207 switch (protocol) {
0208 case RC_PROTO_RCMM32:
0209 ret = ir_rcmm_rawencoder(&e, max, 32, scancode);
0210 break;
0211 case RC_PROTO_RCMM24:
0212 ret = ir_rcmm_rawencoder(&e, max, 24, scancode);
0213 break;
0214 case RC_PROTO_RCMM12:
0215 ret = ir_rcmm_rawencoder(&e, max, 12, scancode);
0216 break;
0217 default:
0218 ret = -EINVAL;
0219 }
0220
0221 if (ret < 0)
0222 return ret;
0223
0224 return e - events;
0225 }
0226
0227 static struct ir_raw_handler rcmm_handler = {
0228 .protocols = RC_PROTO_BIT_RCMM32 |
0229 RC_PROTO_BIT_RCMM24 |
0230 RC_PROTO_BIT_RCMM12,
0231 .decode = ir_rcmm_decode,
0232 .encode = ir_rcmm_encode,
0233 .carrier = 36000,
0234 .min_timeout = RCMM_PULSE_3 + RCMM_UNIT,
0235 };
0236
0237 static int __init ir_rcmm_decode_init(void)
0238 {
0239 ir_raw_handler_register(&rcmm_handler);
0240
0241 pr_info("IR RCMM protocol handler initialized\n");
0242 return 0;
0243 }
0244
0245 static void __exit ir_rcmm_decode_exit(void)
0246 {
0247 ir_raw_handler_unregister(&rcmm_handler);
0248 }
0249
0250 module_init(ir_rcmm_decode_init);
0251 module_exit(ir_rcmm_decode_exit);
0252
0253 MODULE_LICENSE("GPL");
0254 MODULE_AUTHOR("Patrick Lerda");
0255 MODULE_DESCRIPTION("RCMM IR protocol decoder");