0001
0002
0003
0004
0005
0006
0007 #include <linux/bitrev.h>
0008 #include <linux/module.h>
0009 #include "rc-core-priv.h"
0010
0011 #define JVC_NBITS 16
0012 #define JVC_UNIT 525
0013 #define JVC_HEADER_PULSE (16 * JVC_UNIT)
0014 #define JVC_HEADER_SPACE (8 * JVC_UNIT)
0015 #define JVC_BIT_PULSE (1 * JVC_UNIT)
0016 #define JVC_BIT_0_SPACE (1 * JVC_UNIT)
0017 #define JVC_BIT_1_SPACE (3 * JVC_UNIT)
0018 #define JVC_TRAILER_PULSE (1 * JVC_UNIT)
0019 #define JVC_TRAILER_SPACE (35 * JVC_UNIT)
0020
0021 enum jvc_state {
0022 STATE_INACTIVE,
0023 STATE_HEADER_SPACE,
0024 STATE_BIT_PULSE,
0025 STATE_BIT_SPACE,
0026 STATE_TRAILER_PULSE,
0027 STATE_TRAILER_SPACE,
0028 STATE_CHECK_REPEAT,
0029 };
0030
0031
0032
0033
0034
0035
0036
0037
0038 static int ir_jvc_decode(struct rc_dev *dev, struct ir_raw_event ev)
0039 {
0040 struct jvc_dec *data = &dev->raw->jvc;
0041
0042 if (!is_timing_event(ev)) {
0043 if (ev.overflow)
0044 data->state = STATE_INACTIVE;
0045 return 0;
0046 }
0047
0048 if (!geq_margin(ev.duration, JVC_UNIT, JVC_UNIT / 2))
0049 goto out;
0050
0051 dev_dbg(&dev->dev, "JVC decode started at state %d (%uus %s)\n",
0052 data->state, ev.duration, TO_STR(ev.pulse));
0053
0054 again:
0055 switch (data->state) {
0056
0057 case STATE_INACTIVE:
0058 if (!ev.pulse)
0059 break;
0060
0061 if (!eq_margin(ev.duration, JVC_HEADER_PULSE, JVC_UNIT / 2))
0062 break;
0063
0064 data->count = 0;
0065 data->first = true;
0066 data->toggle = !data->toggle;
0067 data->state = STATE_HEADER_SPACE;
0068 return 0;
0069
0070 case STATE_HEADER_SPACE:
0071 if (ev.pulse)
0072 break;
0073
0074 if (!eq_margin(ev.duration, JVC_HEADER_SPACE, JVC_UNIT / 2))
0075 break;
0076
0077 data->state = STATE_BIT_PULSE;
0078 return 0;
0079
0080 case STATE_BIT_PULSE:
0081 if (!ev.pulse)
0082 break;
0083
0084 if (!eq_margin(ev.duration, JVC_BIT_PULSE, JVC_UNIT / 2))
0085 break;
0086
0087 data->state = STATE_BIT_SPACE;
0088 return 0;
0089
0090 case STATE_BIT_SPACE:
0091 if (ev.pulse)
0092 break;
0093
0094 data->bits <<= 1;
0095 if (eq_margin(ev.duration, JVC_BIT_1_SPACE, JVC_UNIT / 2)) {
0096 data->bits |= 1;
0097 decrease_duration(&ev, JVC_BIT_1_SPACE);
0098 } else if (eq_margin(ev.duration, JVC_BIT_0_SPACE, JVC_UNIT / 2))
0099 decrease_duration(&ev, JVC_BIT_0_SPACE);
0100 else
0101 break;
0102 data->count++;
0103
0104 if (data->count == JVC_NBITS)
0105 data->state = STATE_TRAILER_PULSE;
0106 else
0107 data->state = STATE_BIT_PULSE;
0108 return 0;
0109
0110 case STATE_TRAILER_PULSE:
0111 if (!ev.pulse)
0112 break;
0113
0114 if (!eq_margin(ev.duration, JVC_TRAILER_PULSE, JVC_UNIT / 2))
0115 break;
0116
0117 data->state = STATE_TRAILER_SPACE;
0118 return 0;
0119
0120 case STATE_TRAILER_SPACE:
0121 if (ev.pulse)
0122 break;
0123
0124 if (!geq_margin(ev.duration, JVC_TRAILER_SPACE, JVC_UNIT / 2))
0125 break;
0126
0127 if (data->first) {
0128 u32 scancode;
0129 scancode = (bitrev8((data->bits >> 8) & 0xff) << 8) |
0130 (bitrev8((data->bits >> 0) & 0xff) << 0);
0131 dev_dbg(&dev->dev, "JVC scancode 0x%04x\n", scancode);
0132 rc_keydown(dev, RC_PROTO_JVC, scancode, data->toggle);
0133 data->first = false;
0134 data->old_bits = data->bits;
0135 } else if (data->bits == data->old_bits) {
0136 dev_dbg(&dev->dev, "JVC repeat\n");
0137 rc_repeat(dev);
0138 } else {
0139 dev_dbg(&dev->dev, "JVC invalid repeat msg\n");
0140 break;
0141 }
0142
0143 data->count = 0;
0144 data->state = STATE_CHECK_REPEAT;
0145 return 0;
0146
0147 case STATE_CHECK_REPEAT:
0148 if (!ev.pulse)
0149 break;
0150
0151 if (eq_margin(ev.duration, JVC_HEADER_PULSE, JVC_UNIT / 2))
0152 data->state = STATE_INACTIVE;
0153 else
0154 data->state = STATE_BIT_PULSE;
0155 goto again;
0156 }
0157
0158 out:
0159 dev_dbg(&dev->dev, "JVC decode failed at state %d (%uus %s)\n",
0160 data->state, ev.duration, TO_STR(ev.pulse));
0161 data->state = STATE_INACTIVE;
0162 return -EINVAL;
0163 }
0164
0165 static const struct ir_raw_timings_pd ir_jvc_timings = {
0166 .header_pulse = JVC_HEADER_PULSE,
0167 .header_space = JVC_HEADER_SPACE,
0168 .bit_pulse = JVC_BIT_PULSE,
0169 .bit_space[0] = JVC_BIT_0_SPACE,
0170 .bit_space[1] = JVC_BIT_1_SPACE,
0171 .trailer_pulse = JVC_TRAILER_PULSE,
0172 .trailer_space = JVC_TRAILER_SPACE,
0173 .msb_first = 1,
0174 };
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188 static int ir_jvc_encode(enum rc_proto protocol, u32 scancode,
0189 struct ir_raw_event *events, unsigned int max)
0190 {
0191 struct ir_raw_event *e = events;
0192 int ret;
0193 u32 raw = (bitrev8((scancode >> 8) & 0xff) << 8) |
0194 (bitrev8((scancode >> 0) & 0xff) << 0);
0195
0196 ret = ir_raw_gen_pd(&e, max, &ir_jvc_timings, JVC_NBITS, raw);
0197 if (ret < 0)
0198 return ret;
0199
0200 return e - events;
0201 }
0202
0203 static struct ir_raw_handler jvc_handler = {
0204 .protocols = RC_PROTO_BIT_JVC,
0205 .decode = ir_jvc_decode,
0206 .encode = ir_jvc_encode,
0207 .carrier = 38000,
0208 .min_timeout = JVC_TRAILER_SPACE,
0209 };
0210
0211 static int __init ir_jvc_decode_init(void)
0212 {
0213 ir_raw_handler_register(&jvc_handler);
0214
0215 printk(KERN_INFO "IR JVC protocol handler initialized\n");
0216 return 0;
0217 }
0218
0219 static void __exit ir_jvc_decode_exit(void)
0220 {
0221 ir_raw_handler_unregister(&jvc_handler);
0222 }
0223
0224 module_init(ir_jvc_decode_init);
0225 module_exit(ir_jvc_decode_exit);
0226
0227 MODULE_LICENSE("GPL");
0228 MODULE_AUTHOR("David Härdeman <david@hardeman.nu>");
0229 MODULE_DESCRIPTION("JVC IR protocol decoder");