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