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 enum rc_type protocol; 46 u32 scancode; 47 u8 device, subdevice, function; 48 49 if (!(dev->enabled_protocols & 50 (RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20))) 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, SONY_UNIT, SONY_UNIT / 2)) 60 goto out; 61 62 IR_dprintk(2, "Sony decode started at state %d (%uus %s)\n", 63 data->state, TO_US(ev.duration), TO_STR(ev.pulse)); 64 65 switch (data->state) { 66 67 case STATE_INACTIVE: 68 if (!ev.pulse) 69 break; 70 71 if (!eq_margin(ev.duration, SONY_HEADER_PULSE, SONY_UNIT / 2)) 72 break; 73 74 data->count = 0; 75 data->state = STATE_HEADER_SPACE; 76 return 0; 77 78 case STATE_HEADER_SPACE: 79 if (ev.pulse) 80 break; 81 82 if (!eq_margin(ev.duration, SONY_HEADER_SPACE, SONY_UNIT / 2)) 83 break; 84 85 data->state = STATE_BIT_PULSE; 86 return 0; 87 88 case STATE_BIT_PULSE: 89 if (!ev.pulse) 90 break; 91 92 data->bits <<= 1; 93 if (eq_margin(ev.duration, SONY_BIT_1_PULSE, SONY_UNIT / 2)) 94 data->bits |= 1; 95 else if (!eq_margin(ev.duration, SONY_BIT_0_PULSE, SONY_UNIT / 2)) 96 break; 97 98 data->count++; 99 data->state = STATE_BIT_SPACE; 100 return 0; 101 102 case STATE_BIT_SPACE: 103 if (ev.pulse) 104 break; 105 106 if (!geq_margin(ev.duration, SONY_BIT_SPACE, SONY_UNIT / 2)) 107 break; 108 109 decrease_duration(&ev, SONY_BIT_SPACE); 110 111 if (!geq_margin(ev.duration, SONY_UNIT, SONY_UNIT / 2)) { 112 data->state = STATE_BIT_PULSE; 113 return 0; 114 } 115 116 data->state = STATE_FINISHED; 117 /* Fall through */ 118 119 case STATE_FINISHED: 120 if (ev.pulse) 121 break; 122 123 if (!geq_margin(ev.duration, SONY_TRAILER_SPACE, SONY_UNIT / 2)) 124 break; 125 126 switch (data->count) { 127 case 12: 128 if (!(dev->enabled_protocols & RC_BIT_SONY12)) { 129 data->state = STATE_INACTIVE; 130 return 0; 131 } 132 device = bitrev8((data->bits << 3) & 0xF8); 133 subdevice = 0; 134 function = bitrev8((data->bits >> 4) & 0xFE); 135 protocol = RC_TYPE_SONY12; 136 break; 137 case 15: 138 if (!(dev->enabled_protocols & RC_BIT_SONY15)) { 139 data->state = STATE_INACTIVE; 140 return 0; 141 } 142 device = bitrev8((data->bits >> 0) & 0xFF); 143 subdevice = 0; 144 function = bitrev8((data->bits >> 7) & 0xFE); 145 protocol = RC_TYPE_SONY15; 146 break; 147 case 20: 148 if (!(dev->enabled_protocols & RC_BIT_SONY20)) { 149 data->state = STATE_INACTIVE; 150 return 0; 151 } 152 device = bitrev8((data->bits >> 5) & 0xF8); 153 subdevice = bitrev8((data->bits >> 0) & 0xFF); 154 function = bitrev8((data->bits >> 12) & 0xFE); 155 protocol = RC_TYPE_SONY20; 156 break; 157 default: 158 IR_dprintk(1, "Sony invalid bitcount %u\n", data->count); 159 goto out; 160 } 161 162 scancode = device << 16 | subdevice << 8 | function; 163 IR_dprintk(1, "Sony(%u) scancode 0x%05x\n", data->count, scancode); 164 rc_keydown(dev, protocol, scancode, 0); 165 data->state = STATE_INACTIVE; 166 return 0; 167 } 168 169 out: 170 IR_dprintk(1, "Sony 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 sony_handler = { 177 .protocols = RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20, 178 .decode = ir_sony_decode, 179 }; 180 181 static int __init ir_sony_decode_init(void) 182 { 183 ir_raw_handler_register(&sony_handler); 184 185 printk(KERN_INFO "IR Sony protocol handler initialized\n"); 186 return 0; 187 } 188 189 static void __exit ir_sony_decode_exit(void) 190 { 191 ir_raw_handler_unregister(&sony_handler); 192 } 193 194 module_init(ir_sony_decode_init); 195 module_exit(ir_sony_decode_exit); 196 197 MODULE_LICENSE("GPL"); 198 MODULE_AUTHOR("David Härdeman <david@hardeman.nu>"); 199 MODULE_DESCRIPTION("Sony IR protocol decoder"); 200