^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) // ir-rcmm-decoder.c - A decoder for the RCMM IR protocol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) // Copyright (C) 2018 by Patrick Lerda <patrick9876@free.fr>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include "rc-core-priv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #define RCMM_UNIT 166 /* microseconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #define RCMM_PREFIX_PULSE 417 /* 166.666666666666*2.5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #define RCMM_PULSE_0 278 /* 166.666666666666*(1+2/3) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #define RCMM_PULSE_1 444 /* 166.666666666666*(2+2/3) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #define RCMM_PULSE_2 611 /* 166.666666666666*(3+2/3) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define RCMM_PULSE_3 778 /* 166.666666666666*(4+2/3) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) enum rcmm_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) STATE_INACTIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) STATE_LOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) STATE_BUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) STATE_VALUE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) STATE_FINISHED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) static bool rcmm_mode(const struct rcmm_dec *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) return !((0x000c0000 & data->bits) == 0x000c0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static int rcmm_miscmode(struct rc_dev *dev, struct rcmm_dec *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) switch (data->count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) case 24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) if (dev->enabled_protocols & RC_PROTO_BIT_RCMM24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) rc_keydown(dev, RC_PROTO_RCMM24, data->bits, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) data->state = STATE_INACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) case 12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) if (dev->enabled_protocols & RC_PROTO_BIT_RCMM12) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) rc_keydown(dev, RC_PROTO_RCMM12, data->bits, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) data->state = STATE_INACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * ir_rcmm_decode() - Decode one RCMM pulse or space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * @dev: the struct rc_dev descriptor of the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * @ev: the struct ir_raw_event descriptor of the pulse/space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * This function returns -EINVAL if the pulse violates the state machine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static int ir_rcmm_decode(struct rc_dev *dev, struct ir_raw_event ev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct rcmm_dec *data = &dev->raw->rcmm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) u32 scancode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) u8 toggle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) int value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (!(dev->enabled_protocols & (RC_PROTO_BIT_RCMM32 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) RC_PROTO_BIT_RCMM24 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) RC_PROTO_BIT_RCMM12)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if (!is_timing_event(ev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (ev.reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) data->state = STATE_INACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) switch (data->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) case STATE_INACTIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (!ev.pulse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (!eq_margin(ev.duration, RCMM_PREFIX_PULSE, RCMM_UNIT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) data->state = STATE_LOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) data->count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) data->bits = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) case STATE_LOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (ev.pulse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (!eq_margin(ev.duration, RCMM_PULSE_0, RCMM_UNIT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) data->state = STATE_BUMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) case STATE_BUMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (!ev.pulse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (!eq_margin(ev.duration, RCMM_UNIT, RCMM_UNIT / 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) data->state = STATE_VALUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) case STATE_VALUE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (ev.pulse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (eq_margin(ev.duration, RCMM_PULSE_0, RCMM_UNIT / 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) else if (eq_margin(ev.duration, RCMM_PULSE_1, RCMM_UNIT / 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) value = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) else if (eq_margin(ev.duration, RCMM_PULSE_2, RCMM_UNIT / 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) value = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) else if (eq_margin(ev.duration, RCMM_PULSE_3, RCMM_UNIT / 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) value = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) value = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (value == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (!rcmm_miscmode(dev, data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) data->bits <<= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) data->bits |= value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) data->count += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (data->count < 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) data->state = STATE_BUMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) data->state = STATE_FINISHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) case STATE_FINISHED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (!ev.pulse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (!eq_margin(ev.duration, RCMM_UNIT, RCMM_UNIT / 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (rcmm_mode(data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) toggle = !!(0x8000 & data->bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) scancode = data->bits & ~0x8000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) toggle = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) scancode = data->bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (dev->enabled_protocols & RC_PROTO_BIT_RCMM32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) rc_keydown(dev, RC_PROTO_RCMM32, scancode, toggle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) data->state = STATE_INACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) dev_dbg(&dev->dev, "RC-MM decode failed at count %d state %d (%uus %s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) data->count, data->state, ev.duration, TO_STR(ev.pulse));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) data->state = STATE_INACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static const int rcmmspace[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) RCMM_PULSE_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) RCMM_PULSE_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) RCMM_PULSE_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) RCMM_PULSE_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static int ir_rcmm_rawencoder(struct ir_raw_event **ev, unsigned int max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) unsigned int n, u32 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) ret = ir_raw_gen_pulse_space(ev, &max, RCMM_PREFIX_PULSE, RCMM_PULSE_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) for (i = n - 2; i >= 0; i -= 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) const unsigned int space = rcmmspace[(data >> i) & 3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) ret = ir_raw_gen_pulse_space(ev, &max, RCMM_UNIT, space);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return ir_raw_gen_pulse_space(ev, &max, RCMM_UNIT, RCMM_PULSE_3 * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static int ir_rcmm_encode(enum rc_proto protocol, u32 scancode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct ir_raw_event *events, unsigned int max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct ir_raw_event *e = events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) switch (protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) case RC_PROTO_RCMM32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) ret = ir_rcmm_rawencoder(&e, max, 32, scancode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) case RC_PROTO_RCMM24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) ret = ir_rcmm_rawencoder(&e, max, 24, scancode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) case RC_PROTO_RCMM12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) ret = ir_rcmm_rawencoder(&e, max, 12, scancode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return e - events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static struct ir_raw_handler rcmm_handler = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) .protocols = RC_PROTO_BIT_RCMM32 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) RC_PROTO_BIT_RCMM24 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) RC_PROTO_BIT_RCMM12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) .decode = ir_rcmm_decode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) .encode = ir_rcmm_encode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) .carrier = 36000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) .min_timeout = RCMM_PULSE_3 + RCMM_UNIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static int __init ir_rcmm_decode_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) ir_raw_handler_register(&rcmm_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) pr_info("IR RCMM protocol handler initialized\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) static void __exit ir_rcmm_decode_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) ir_raw_handler_unregister(&rcmm_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) module_init(ir_rcmm_decode_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) module_exit(ir_rcmm_decode_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) MODULE_AUTHOR("Patrick Lerda");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) MODULE_DESCRIPTION("RCMM IR protocol decoder");