Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.24-rc4 382 lines 8.6 kB view raw
1/* 2 * 3 * some common structs and functions to handle infrared remotes via 4 * input layer ... 5 * 6 * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 */ 22 23#include <linux/module.h> 24#include <linux/string.h> 25#include <linux/jiffies.h> 26#include <media/ir-common.h> 27 28/* -------------------------------------------------------------------------- */ 29 30MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 31MODULE_LICENSE("GPL"); 32 33static int repeat = 1; 34module_param(repeat, int, 0444); 35MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)"); 36 37static int debug = 0; /* debug level (0,1,2) */ 38module_param(debug, int, 0644); 39 40#define dprintk(level, fmt, arg...) if (debug >= level) \ 41 printk(KERN_DEBUG fmt , ## arg) 42 43/* -------------------------------------------------------------------------- */ 44 45static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir) 46{ 47 if (KEY_RESERVED == ir->keycode) { 48 printk(KERN_INFO "%s: unknown key: key=0x%02x raw=0x%02x down=%d\n", 49 dev->name,ir->ir_key,ir->ir_raw,ir->keypressed); 50 return; 51 } 52 dprintk(1,"%s: key event code=%d down=%d\n", 53 dev->name,ir->keycode,ir->keypressed); 54 input_report_key(dev,ir->keycode,ir->keypressed); 55 input_sync(dev); 56} 57 58/* -------------------------------------------------------------------------- */ 59 60void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, 61 int ir_type, IR_KEYTAB_TYPE *ir_codes) 62{ 63 int i; 64 65 ir->ir_type = ir_type; 66 if (ir_codes) 67 memcpy(ir->ir_codes, ir_codes, sizeof(ir->ir_codes)); 68 69 70 dev->keycode = ir->ir_codes; 71 dev->keycodesize = sizeof(IR_KEYTAB_TYPE); 72 dev->keycodemax = IR_KEYTAB_SIZE; 73 for (i = 0; i < IR_KEYTAB_SIZE; i++) 74 set_bit(ir->ir_codes[i], dev->keybit); 75 clear_bit(0, dev->keybit); 76 77 set_bit(EV_KEY, dev->evbit); 78 if (repeat) 79 set_bit(EV_REP, dev->evbit); 80} 81 82void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir) 83{ 84 if (ir->keypressed) { 85 ir->keypressed = 0; 86 ir_input_key_event(dev,ir); 87 } 88} 89 90void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir, 91 u32 ir_key, u32 ir_raw) 92{ 93 u32 keycode = IR_KEYCODE(ir->ir_codes, ir_key); 94 95 if (ir->keypressed && ir->keycode != keycode) { 96 ir->keypressed = 0; 97 ir_input_key_event(dev,ir); 98 } 99 if (!ir->keypressed) { 100 ir->ir_key = ir_key; 101 ir->ir_raw = ir_raw; 102 ir->keycode = keycode; 103 ir->keypressed = 1; 104 ir_input_key_event(dev,ir); 105 } 106} 107 108/* -------------------------------------------------------------------------- */ 109/* extract mask bits out of data and pack them into the result */ 110u32 ir_extract_bits(u32 data, u32 mask) 111{ 112 u32 vbit = 1, value = 0; 113 114 do { 115 if (mask&1) { 116 if (data&1) 117 value |= vbit; 118 vbit<<=1; 119 } 120 data>>=1; 121 } while (mask>>=1); 122 123 return value; 124} 125 126static int inline getbit(u32 *samples, int bit) 127{ 128 return (samples[bit/32] & (1 << (31-(bit%32)))) ? 1 : 0; 129} 130 131/* sump raw samples for visual debugging ;) */ 132int ir_dump_samples(u32 *samples, int count) 133{ 134 int i, bit, start; 135 136 printk(KERN_DEBUG "ir samples: "); 137 start = 0; 138 for (i = 0; i < count * 32; i++) { 139 bit = getbit(samples,i); 140 if (bit) 141 start = 1; 142 if (0 == start) 143 continue; 144 printk("%s", bit ? "#" : "_"); 145 } 146 printk("\n"); 147 return 0; 148} 149 150/* decode raw samples, pulse distance coding used by NEC remotes */ 151int ir_decode_pulsedistance(u32 *samples, int count, int low, int high) 152{ 153 int i,last,bit,len; 154 u32 curBit; 155 u32 value; 156 157 /* find start burst */ 158 for (i = len = 0; i < count * 32; i++) { 159 bit = getbit(samples,i); 160 if (bit) { 161 len++; 162 } else { 163 if (len >= 29) 164 break; 165 len = 0; 166 } 167 } 168 169 /* start burst to short */ 170 if (len < 29) 171 return 0xffffffff; 172 173 /* find start silence */ 174 for (len = 0; i < count * 32; i++) { 175 bit = getbit(samples,i); 176 if (bit) { 177 break; 178 } else { 179 len++; 180 } 181 } 182 183 /* silence to short */ 184 if (len < 7) 185 return 0xffffffff; 186 187 /* go decoding */ 188 len = 0; 189 last = 1; 190 value = 0; curBit = 1; 191 for (; i < count * 32; i++) { 192 bit = getbit(samples,i); 193 if (last) { 194 if(bit) { 195 continue; 196 } else { 197 len = 1; 198 } 199 } else { 200 if (bit) { 201 if (len > (low + high) /2) 202 value |= curBit; 203 curBit <<= 1; 204 if (curBit == 1) 205 break; 206 } else { 207 len++; 208 } 209 } 210 last = bit; 211 } 212 213 return value; 214} 215 216/* decode raw samples, biphase coding, used by rc5 for example */ 217int ir_decode_biphase(u32 *samples, int count, int low, int high) 218{ 219 int i,last,bit,len,flips; 220 u32 value; 221 222 /* find start bit (1) */ 223 for (i = 0; i < 32; i++) { 224 bit = getbit(samples,i); 225 if (bit) 226 break; 227 } 228 229 /* go decoding */ 230 len = 0; 231 flips = 0; 232 value = 1; 233 for (; i < count * 32; i++) { 234 if (len > high) 235 break; 236 if (flips > 1) 237 break; 238 last = bit; 239 bit = getbit(samples,i); 240 if (last == bit) { 241 len++; 242 continue; 243 } 244 if (len < low) { 245 len++; 246 flips++; 247 continue; 248 } 249 value <<= 1; 250 value |= bit; 251 flips = 0; 252 len = 1; 253 } 254 return value; 255} 256 257/* RC5 decoding stuff, moved from bttv-input.c to share it with 258 * saa7134 */ 259 260/* decode raw bit pattern to RC5 code */ 261u32 ir_rc5_decode(unsigned int code) 262{ 263 unsigned int org_code = code; 264 unsigned int pair; 265 unsigned int rc5 = 0; 266 int i; 267 268 for (i = 0; i < 14; ++i) { 269 pair = code & 0x3; 270 code >>= 2; 271 272 rc5 <<= 1; 273 switch (pair) { 274 case 0: 275 case 2: 276 break; 277 case 1: 278 rc5 |= 1; 279 break; 280 case 3: 281 dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code); 282 return 0; 283 } 284 } 285 dprintk(1, "ir-common: code=%x, rc5=%x, start=%x, toggle=%x, address=%x, " 286 "instr=%x\n", rc5, org_code, RC5_START(rc5), 287 RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5)); 288 return rc5; 289} 290 291void ir_rc5_timer_end(unsigned long data) 292{ 293 struct card_ir *ir = (struct card_ir *)data; 294 struct timeval tv; 295 unsigned long current_jiffies, timeout; 296 u32 gap; 297 u32 rc5 = 0; 298 299 /* get time */ 300 current_jiffies = jiffies; 301 do_gettimeofday(&tv); 302 303 /* avoid overflow with gap >1s */ 304 if (tv.tv_sec - ir->base_time.tv_sec > 1) { 305 gap = 200000; 306 } else { 307 gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) + 308 tv.tv_usec - ir->base_time.tv_usec; 309 } 310 311 /* signal we're ready to start a new code */ 312 ir->active = 0; 313 314 /* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */ 315 if (gap < 28000) { 316 dprintk(1, "ir-common: spurious timer_end\n"); 317 return; 318 } 319 320 if (ir->last_bit < 20) { 321 /* ignore spurious codes (caused by light/other remotes) */ 322 dprintk(1, "ir-common: short code: %x\n", ir->code); 323 } else { 324 ir->code = (ir->code << ir->shift_by) | 1; 325 rc5 = ir_rc5_decode(ir->code); 326 327 /* two start bits? */ 328 if (RC5_START(rc5) != ir->start) { 329 dprintk(1, "ir-common: rc5 start bits invalid: %u\n", RC5_START(rc5)); 330 331 /* right address? */ 332 } else if (RC5_ADDR(rc5) == ir->addr) { 333 u32 toggle = RC5_TOGGLE(rc5); 334 u32 instr = RC5_INSTR(rc5); 335 336 /* Good code, decide if repeat/repress */ 337 if (toggle != RC5_TOGGLE(ir->last_rc5) || 338 instr != RC5_INSTR(ir->last_rc5)) { 339 dprintk(1, "ir-common: instruction %x, toggle %x\n", instr, 340 toggle); 341 ir_input_nokey(ir->dev, &ir->ir); 342 ir_input_keydown(ir->dev, &ir->ir, instr, 343 instr); 344 } 345 346 /* Set/reset key-up timer */ 347 timeout = current_jiffies + 348 msecs_to_jiffies(ir->rc5_key_timeout); 349 mod_timer(&ir->timer_keyup, timeout); 350 351 /* Save code for repeat test */ 352 ir->last_rc5 = rc5; 353 } 354 } 355} 356 357void ir_rc5_timer_keyup(unsigned long data) 358{ 359 struct card_ir *ir = (struct card_ir *)data; 360 361 dprintk(1, "ir-common: key released\n"); 362 ir_input_nokey(ir->dev, &ir->ir); 363} 364 365EXPORT_SYMBOL_GPL(ir_input_init); 366EXPORT_SYMBOL_GPL(ir_input_nokey); 367EXPORT_SYMBOL_GPL(ir_input_keydown); 368 369EXPORT_SYMBOL_GPL(ir_extract_bits); 370EXPORT_SYMBOL_GPL(ir_dump_samples); 371EXPORT_SYMBOL_GPL(ir_decode_biphase); 372EXPORT_SYMBOL_GPL(ir_decode_pulsedistance); 373 374EXPORT_SYMBOL_GPL(ir_rc5_decode); 375EXPORT_SYMBOL_GPL(ir_rc5_timer_end); 376EXPORT_SYMBOL_GPL(ir_rc5_timer_keyup); 377 378/* 379 * Local variables: 380 * c-basic-offset: 8 381 * End: 382 */