1 /* ir-jvc-decoder.c - handle JVC IR Pulse/Space 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 <linux/bitrev.h> 16 #include <linux/module.h> 17 #include "rc-core-priv.h" 18 19 #define JVC_NBITS 16 /* dev(8) + func(8) */ 20 #define JVC_UNIT 525000 /* ns */ 21 #define JVC_HEADER_PULSE (16 * JVC_UNIT) /* lack of header -> repeat */ 22 #define JVC_HEADER_SPACE (8 * JVC_UNIT) 23 #define JVC_BIT_PULSE (1 * JVC_UNIT) 24 #define JVC_BIT_0_SPACE (1 * JVC_UNIT) 25 #define JVC_BIT_1_SPACE (3 * JVC_UNIT) 26 #define JVC_TRAILER_PULSE (1 * JVC_UNIT) 27 #define JVC_TRAILER_SPACE (35 * JVC_UNIT) 28 29 enum jvc_state { 30 STATE_INACTIVE, 31 STATE_HEADER_SPACE, 32 STATE_BIT_PULSE, 33 STATE_BIT_SPACE, 34 STATE_TRAILER_PULSE, 35 STATE_TRAILER_SPACE, 36 STATE_CHECK_REPEAT, 37 }; 38 39 /** 40 * ir_jvc_decode() - Decode one JVC pulse or space 41 * @dev: the struct rc_dev descriptor of the device 42 * @duration: the struct ir_raw_event descriptor of the pulse/space 43 * 44 * This function returns -EINVAL if the pulse violates the state machine 45 */ 46 static int ir_jvc_decode(struct rc_dev *dev, struct ir_raw_event ev) 47 { 48 struct jvc_dec *data = &dev->raw->jvc; 49 50 if (!(dev->raw->enabled_protocols & RC_BIT_JVC)) 51 return 0; 52 53 if (!is_timing_event(ev)) { 54 if (ev.reset) 55 data->state = STATE_INACTIVE; 56 return 0; 57 } 58 59 if (!geq_margin(ev.duration, JVC_UNIT, JVC_UNIT / 2)) 60 goto out; 61 62 IR_dprintk(2, "JVC decode started at state %d (%uus %s)\n", 63 data->state, TO_US(ev.duration), TO_STR(ev.pulse)); 64 65 again: 66 switch (data->state) { 67 68 case STATE_INACTIVE: 69 if (!ev.pulse) 70 break; 71 72 if (!eq_margin(ev.duration, JVC_HEADER_PULSE, JVC_UNIT / 2)) 73 break; 74 75 data->count = 0; 76 data->first = true; 77 data->toggle = !data->toggle; 78 data->state = STATE_HEADER_SPACE; 79 return 0; 80 81 case STATE_HEADER_SPACE: 82 if (ev.pulse) 83 break; 84 85 if (!eq_margin(ev.duration, JVC_HEADER_SPACE, JVC_UNIT / 2)) 86 break; 87 88 data->state = STATE_BIT_PULSE; 89 return 0; 90 91 case STATE_BIT_PULSE: 92 if (!ev.pulse) 93 break; 94 95 if (!eq_margin(ev.duration, JVC_BIT_PULSE, JVC_UNIT / 2)) 96 break; 97 98 data->state = STATE_BIT_SPACE; 99 return 0; 100 101 case STATE_BIT_SPACE: 102 if (ev.pulse) 103 break; 104 105 data->bits <<= 1; 106 if (eq_margin(ev.duration, JVC_BIT_1_SPACE, JVC_UNIT / 2)) { 107 data->bits |= 1; 108 decrease_duration(&ev, JVC_BIT_1_SPACE); 109 } else if (eq_margin(ev.duration, JVC_BIT_0_SPACE, JVC_UNIT / 2)) 110 decrease_duration(&ev, JVC_BIT_0_SPACE); 111 else 112 break; 113 data->count++; 114 115 if (data->count == JVC_NBITS) 116 data->state = STATE_TRAILER_PULSE; 117 else 118 data->state = STATE_BIT_PULSE; 119 return 0; 120 121 case STATE_TRAILER_PULSE: 122 if (!ev.pulse) 123 break; 124 125 if (!eq_margin(ev.duration, JVC_TRAILER_PULSE, JVC_UNIT / 2)) 126 break; 127 128 data->state = STATE_TRAILER_SPACE; 129 return 0; 130 131 case STATE_TRAILER_SPACE: 132 if (ev.pulse) 133 break; 134 135 if (!geq_margin(ev.duration, JVC_TRAILER_SPACE, JVC_UNIT / 2)) 136 break; 137 138 if (data->first) { 139 u32 scancode; 140 scancode = (bitrev8((data->bits >> 8) & 0xff) << 8) | 141 (bitrev8((data->bits >> 0) & 0xff) << 0); 142 IR_dprintk(1, "JVC scancode 0x%04x\n", scancode); 143 rc_keydown(dev, scancode, data->toggle); 144 data->first = false; 145 data->old_bits = data->bits; 146 } else if (data->bits == data->old_bits) { 147 IR_dprintk(1, "JVC repeat\n"); 148 rc_repeat(dev); 149 } else { 150 IR_dprintk(1, "JVC invalid repeat msg\n"); 151 break; 152 } 153 154 data->count = 0; 155 data->state = STATE_CHECK_REPEAT; 156 return 0; 157 158 case STATE_CHECK_REPEAT: 159 if (!ev.pulse) 160 break; 161 162 if (eq_margin(ev.duration, JVC_HEADER_PULSE, JVC_UNIT / 2)) 163 data->state = STATE_INACTIVE; 164 else 165 data->state = STATE_BIT_PULSE; 166 goto again; 167 } 168 169 out: 170 IR_dprintk(1, "JVC decode failed at state %d (%uus %s)\n", 171 data->state, TO_US(ev.duration), TO_STR(ev.pulse)); 172 data->state = STATE_INACTIVE; 173 return -EINVAL; 174 } 175 176 static struct ir_raw_handler jvc_handler = { 177 .protocols = RC_BIT_JVC, 178 .decode = ir_jvc_decode, 179 }; 180 181 static int __init ir_jvc_decode_init(void) 182 { 183 ir_raw_handler_register(&jvc_handler); 184 185 printk(KERN_INFO "IR JVC protocol handler initialized\n"); 186 return 0; 187 } 188 189 static void __exit ir_jvc_decode_exit(void) 190 { 191 ir_raw_handler_unregister(&jvc_handler); 192 } 193 194 module_init(ir_jvc_decode_init); 195 module_exit(ir_jvc_decode_exit); 196 197 MODULE_LICENSE("GPL"); 198 MODULE_AUTHOR("David Härdeman <david@hardeman.nu>"); 199 MODULE_DESCRIPTION("JVC IR protocol decoder"); 200