1 /* ir-sony-decoder.c - handle Sony 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 SONY_UNIT 600000 /* ns */ 20 #define SONY_HEADER_PULSE (4 * SONY_UNIT) 21 #define SONY_HEADER_SPACE (1 * SONY_UNIT) 22 #define SONY_BIT_0_PULSE (1 * SONY_UNIT) 23 #define SONY_BIT_1_PULSE (2 * SONY_UNIT) 24 #define SONY_BIT_SPACE (1 * SONY_UNIT) 25 #define SONY_TRAILER_SPACE (10 * SONY_UNIT) /* minimum */ 26 27 enum sony_state { 28 STATE_INACTIVE, 29 STATE_HEADER_SPACE, 30 STATE_BIT_PULSE, 31 STATE_BIT_SPACE, 32 STATE_FINISHED, 33 }; 34 35 /** 36 * ir_sony_decode() - Decode one Sony pulse or space 37 * @dev: the struct rc_dev descriptor of the device 38 * @ev: the struct ir_raw_event descriptor of the pulse/space 39 * 40 * This function returns -EINVAL if the pulse violates the state machine 41 */ 42 static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev) 43 { 44 struct sony_dec *data = &dev->raw->sony; 45 u32 scancode; 46 u8 device, subdevice, function; 47 48 if (!(dev->enabled_protocols & 49 (RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20))) 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, SONY_UNIT, SONY_UNIT / 2)) 59 goto out; 60 61 IR_dprintk(2, "Sony decode started at state %d (%uus %s)\n", 62 data->state, TO_US(ev.duration), TO_STR(ev.pulse)); 63 64 switch (data->state) { 65 66 case STATE_INACTIVE: 67 if (!ev.pulse) 68 break; 69 70 if (!eq_margin(ev.duration, SONY_HEADER_PULSE, SONY_UNIT / 2)) 71 break; 72 73 data->count = 0; 74 data->state = STATE_HEADER_SPACE; 75 return 0; 76 77 case STATE_HEADER_SPACE: 78 if (ev.pulse) 79 break; 80 81 if (!eq_margin(ev.duration, SONY_HEADER_SPACE, SONY_UNIT / 2)) 82 break; 83 84 data->state = STATE_BIT_PULSE; 85 return 0; 86 87 case STATE_BIT_PULSE: 88 if (!ev.pulse) 89 break; 90 91 data->bits <<= 1; 92 if (eq_margin(ev.duration, SONY_BIT_1_PULSE, SONY_UNIT / 2)) 93 data->bits |= 1; 94 else if (!eq_margin(ev.duration, SONY_BIT_0_PULSE, SONY_UNIT / 2)) 95 break; 96 97 data->count++; 98 data->state = STATE_BIT_SPACE; 99 return 0; 100 101 case STATE_BIT_SPACE: 102 if (ev.pulse) 103 break; 104 105 if (!geq_margin(ev.duration, SONY_BIT_SPACE, SONY_UNIT / 2)) 106 break; 107 108 decrease_duration(&ev, SONY_BIT_SPACE); 109 110 if (!geq_margin(ev.duration, SONY_UNIT, SONY_UNIT / 2)) { 111 data->state = STATE_BIT_PULSE; 112 return 0; 113 } 114 115 data->state = STATE_FINISHED; 116 /* Fall through */ 117 118 case STATE_FINISHED: 119 if (ev.pulse) 120 break; 121 122 if (!geq_margin(ev.duration, SONY_TRAILER_SPACE, SONY_UNIT / 2)) 123 break; 124 125 switch (data->count) { 126 case 12: 127 if (!(dev->enabled_protocols & RC_BIT_SONY12)) { 128 data->state = STATE_INACTIVE; 129 return 0; 130 } 131 device = bitrev8((data->bits << 3) & 0xF8); 132 subdevice = 0; 133 function = bitrev8((data->bits >> 4) & 0xFE); 134 break; 135 case 15: 136 if (!(dev->enabled_protocols & RC_BIT_SONY15)) { 137 data->state = STATE_INACTIVE; 138 return 0; 139 } 140 device = bitrev8((data->bits >> 0) & 0xFF); 141 subdevice = 0; 142 function = bitrev8((data->bits >> 7) & 0xFE); 143 break; 144 case 20: 145 if (!(dev->enabled_protocols & RC_BIT_SONY20)) { 146 data->state = STATE_INACTIVE; 147 return 0; 148 } 149 device = bitrev8((data->bits >> 5) & 0xF8); 150 subdevice = bitrev8((data->bits >> 0) & 0xFF); 151 function = bitrev8((data->bits >> 12) & 0xFE); 152 break; 153 default: 154 IR_dprintk(1, "Sony invalid bitcount %u\n", data->count); 155 goto out; 156 } 157 158 scancode = device << 16 | subdevice << 8 | function; 159 IR_dprintk(1, "Sony(%u) scancode 0x%05x\n", data->count, scancode); 160 rc_keydown(dev, scancode, 0); 161 data->state = STATE_INACTIVE; 162 return 0; 163 } 164 165 out: 166 IR_dprintk(1, "Sony decode failed at state %d (%uus %s)\n", 167 data->state, TO_US(ev.duration), TO_STR(ev.pulse)); 168 data->state = STATE_INACTIVE; 169 return -EINVAL; 170 } 171 172 static struct ir_raw_handler sony_handler = { 173 .protocols = RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20, 174 .decode = ir_sony_decode, 175 }; 176 177 static int __init ir_sony_decode_init(void) 178 { 179 ir_raw_handler_register(&sony_handler); 180 181 printk(KERN_INFO "IR Sony protocol handler initialized\n"); 182 return 0; 183 } 184 185 static void __exit ir_sony_decode_exit(void) 186 { 187 ir_raw_handler_unregister(&sony_handler); 188 } 189 190 module_init(ir_sony_decode_init); 191 module_exit(ir_sony_decode_exit); 192 193 MODULE_LICENSE("GPL"); 194 MODULE_AUTHOR("David Härdeman <david@hardeman.nu>"); 195 MODULE_DESCRIPTION("Sony IR protocol decoder"); 196