diff options
Diffstat (limited to 'drivers/media/common/ir-common.c')
| -rw-r--r-- | drivers/media/common/ir-common.c | 519 |
1 files changed, 0 insertions, 519 deletions
diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c deleted file mode 100644 index 97fa3fc571c4..000000000000 --- a/drivers/media/common/ir-common.c +++ /dev/null | |||
| @@ -1,519 +0,0 @@ | |||
| 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/moduleparam.h> | ||
| 25 | #include <linux/string.h> | ||
| 26 | #include <media/ir-common.h> | ||
| 27 | |||
| 28 | /* -------------------------------------------------------------------------- */ | ||
| 29 | |||
| 30 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); | ||
| 31 | MODULE_LICENSE("GPL"); | ||
| 32 | |||
| 33 | static int repeat = 1; | ||
| 34 | module_param(repeat, int, 0444); | ||
| 35 | MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)"); | ||
| 36 | |||
| 37 | static int debug = 0; /* debug level (0,1,2) */ | ||
| 38 | module_param(debug, int, 0644); | ||
| 39 | |||
| 40 | #define dprintk(level, fmt, arg...) if (debug >= level) \ | ||
| 41 | printk(KERN_DEBUG fmt , ## arg) | ||
| 42 | |||
| 43 | /* -------------------------------------------------------------------------- */ | ||
| 44 | |||
| 45 | /* generic RC5 keytable */ | ||
| 46 | /* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */ | ||
| 47 | /* used by old (black) Hauppauge remotes */ | ||
| 48 | IR_KEYTAB_TYPE ir_codes_rc5_tv[IR_KEYTAB_SIZE] = { | ||
| 49 | /* Keys 0 to 9 */ | ||
| 50 | [ 0x00 ] = KEY_KP0, | ||
| 51 | [ 0x01 ] = KEY_KP1, | ||
| 52 | [ 0x02 ] = KEY_KP2, | ||
| 53 | [ 0x03 ] = KEY_KP3, | ||
| 54 | [ 0x04 ] = KEY_KP4, | ||
| 55 | [ 0x05 ] = KEY_KP5, | ||
| 56 | [ 0x06 ] = KEY_KP6, | ||
| 57 | [ 0x07 ] = KEY_KP7, | ||
| 58 | [ 0x08 ] = KEY_KP8, | ||
| 59 | [ 0x09 ] = KEY_KP9, | ||
| 60 | |||
| 61 | [ 0x0b ] = KEY_CHANNEL, /* channel / program (japan: 11) */ | ||
| 62 | [ 0x0c ] = KEY_POWER, /* standby */ | ||
| 63 | [ 0x0d ] = KEY_MUTE, /* mute / demute */ | ||
| 64 | [ 0x0f ] = KEY_TV, /* display */ | ||
| 65 | [ 0x10 ] = KEY_VOLUMEUP, | ||
| 66 | [ 0x11 ] = KEY_VOLUMEDOWN, | ||
| 67 | [ 0x12 ] = KEY_BRIGHTNESSUP, | ||
| 68 | [ 0x13 ] = KEY_BRIGHTNESSDOWN, | ||
| 69 | [ 0x1e ] = KEY_SEARCH, /* search + */ | ||
| 70 | [ 0x20 ] = KEY_CHANNELUP, /* channel / program + */ | ||
| 71 | [ 0x21 ] = KEY_CHANNELDOWN, /* channel / program - */ | ||
| 72 | [ 0x22 ] = KEY_CHANNEL, /* alt / channel */ | ||
| 73 | [ 0x23 ] = KEY_LANGUAGE, /* 1st / 2nd language */ | ||
| 74 | [ 0x26 ] = KEY_SLEEP, /* sleeptimer */ | ||
| 75 | [ 0x2e ] = KEY_MENU, /* 2nd controls (USA: menu) */ | ||
| 76 | [ 0x30 ] = KEY_PAUSE, | ||
| 77 | [ 0x32 ] = KEY_REWIND, | ||
| 78 | [ 0x33 ] = KEY_GOTO, | ||
| 79 | [ 0x35 ] = KEY_PLAY, | ||
| 80 | [ 0x36 ] = KEY_STOP, | ||
| 81 | [ 0x37 ] = KEY_RECORD, /* recording */ | ||
| 82 | [ 0x3c ] = KEY_TEXT, /* teletext submode (Japan: 12) */ | ||
| 83 | [ 0x3d ] = KEY_SUSPEND, /* system standby */ | ||
| 84 | |||
| 85 | }; | ||
| 86 | EXPORT_SYMBOL_GPL(ir_codes_rc5_tv); | ||
| 87 | |||
| 88 | /* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */ | ||
| 89 | IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = { | ||
| 90 | /* Keys 0 to 9 */ | ||
| 91 | [ 18 ] = KEY_KP0, | ||
| 92 | [ 5 ] = KEY_KP1, | ||
| 93 | [ 6 ] = KEY_KP2, | ||
| 94 | [ 7 ] = KEY_KP3, | ||
| 95 | [ 9 ] = KEY_KP4, | ||
| 96 | [ 10 ] = KEY_KP5, | ||
| 97 | [ 11 ] = KEY_KP6, | ||
| 98 | [ 13 ] = KEY_KP7, | ||
| 99 | [ 14 ] = KEY_KP8, | ||
| 100 | [ 15 ] = KEY_KP9, | ||
| 101 | |||
| 102 | [ 0 ] = KEY_POWER, | ||
| 103 | [ 2 ] = KEY_TUNER, /* TV/FM */ | ||
| 104 | [ 30 ] = KEY_VIDEO, | ||
| 105 | [ 4 ] = KEY_VOLUMEUP, | ||
| 106 | [ 8 ] = KEY_VOLUMEDOWN, | ||
| 107 | [ 12 ] = KEY_CHANNELUP, | ||
| 108 | [ 16 ] = KEY_CHANNELDOWN, | ||
| 109 | [ 3 ] = KEY_ZOOM, /* fullscreen */ | ||
| 110 | [ 31 ] = KEY_SUBTITLE, /* closed caption/teletext */ | ||
| 111 | [ 32 ] = KEY_SLEEP, | ||
| 112 | [ 20 ] = KEY_MUTE, | ||
| 113 | [ 43 ] = KEY_RED, | ||
| 114 | [ 44 ] = KEY_GREEN, | ||
| 115 | [ 45 ] = KEY_YELLOW, | ||
| 116 | [ 46 ] = KEY_BLUE, | ||
| 117 | [ 24 ] = KEY_KPPLUS, /* fine tune + */ | ||
| 118 | [ 25 ] = KEY_KPMINUS, /* fine tune - */ | ||
| 119 | [ 33 ] = KEY_KPDOT, | ||
| 120 | [ 19 ] = KEY_KPENTER, | ||
| 121 | [ 34 ] = KEY_BACK, | ||
| 122 | [ 35 ] = KEY_PLAYPAUSE, | ||
| 123 | [ 36 ] = KEY_NEXT, | ||
| 124 | [ 38 ] = KEY_STOP, | ||
| 125 | [ 39 ] = KEY_RECORD | ||
| 126 | }; | ||
| 127 | EXPORT_SYMBOL_GPL(ir_codes_winfast); | ||
| 128 | |||
| 129 | IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = { | ||
| 130 | [ 0x59 ] = KEY_MUTE, | ||
| 131 | [ 0x4a ] = KEY_POWER, | ||
| 132 | |||
| 133 | [ 0x18 ] = KEY_TEXT, | ||
| 134 | [ 0x26 ] = KEY_TV, | ||
| 135 | [ 0x3d ] = KEY_PRINT, | ||
| 136 | |||
| 137 | [ 0x48 ] = KEY_RED, | ||
| 138 | [ 0x04 ] = KEY_GREEN, | ||
| 139 | [ 0x11 ] = KEY_YELLOW, | ||
| 140 | [ 0x00 ] = KEY_BLUE, | ||
| 141 | |||
| 142 | [ 0x2d ] = KEY_VOLUMEUP, | ||
| 143 | [ 0x1e ] = KEY_VOLUMEDOWN, | ||
| 144 | |||
| 145 | [ 0x49 ] = KEY_MENU, | ||
| 146 | |||
| 147 | [ 0x16 ] = KEY_CHANNELUP, | ||
| 148 | [ 0x17 ] = KEY_CHANNELDOWN, | ||
| 149 | |||
| 150 | [ 0x20 ] = KEY_UP, | ||
| 151 | [ 0x21 ] = KEY_DOWN, | ||
| 152 | [ 0x22 ] = KEY_LEFT, | ||
| 153 | [ 0x23 ] = KEY_RIGHT, | ||
| 154 | [ 0x0d ] = KEY_SELECT, | ||
| 155 | |||
| 156 | |||
| 157 | |||
| 158 | [ 0x08 ] = KEY_BACK, | ||
| 159 | [ 0x07 ] = KEY_REFRESH, | ||
| 160 | |||
| 161 | [ 0x2f ] = KEY_ZOOM, | ||
| 162 | [ 0x29 ] = KEY_RECORD, | ||
| 163 | |||
| 164 | [ 0x4b ] = KEY_PAUSE, | ||
| 165 | [ 0x4d ] = KEY_REWIND, | ||
| 166 | [ 0x2e ] = KEY_PLAY, | ||
| 167 | [ 0x4e ] = KEY_FORWARD, | ||
| 168 | [ 0x53 ] = KEY_PREVIOUS, | ||
| 169 | [ 0x4c ] = KEY_STOP, | ||
| 170 | [ 0x54 ] = KEY_NEXT, | ||
| 171 | |||
| 172 | [ 0x69 ] = KEY_KP0, | ||
| 173 | [ 0x6a ] = KEY_KP1, | ||
| 174 | [ 0x6b ] = KEY_KP2, | ||
| 175 | [ 0x6c ] = KEY_KP3, | ||
| 176 | [ 0x6d ] = KEY_KP4, | ||
| 177 | [ 0x6e ] = KEY_KP5, | ||
| 178 | [ 0x6f ] = KEY_KP6, | ||
| 179 | [ 0x70 ] = KEY_KP7, | ||
| 180 | [ 0x71 ] = KEY_KP8, | ||
| 181 | [ 0x72 ] = KEY_KP9, | ||
| 182 | |||
| 183 | [ 0x74 ] = KEY_CHANNEL, | ||
| 184 | [ 0x0a ] = KEY_BACKSPACE, | ||
| 185 | }; | ||
| 186 | |||
| 187 | EXPORT_SYMBOL_GPL(ir_codes_pinnacle); | ||
| 188 | |||
| 189 | /* empty keytable, can be used as placeholder for not-yet created keytables */ | ||
| 190 | IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE] = { | ||
| 191 | [ 42 ] = KEY_COFFEE, | ||
| 192 | }; | ||
| 193 | EXPORT_SYMBOL_GPL(ir_codes_empty); | ||
| 194 | |||
| 195 | /* Hauppauge: the newer, gray remotes (seems there are multiple | ||
| 196 | * slightly different versions), shipped with cx88+ivtv cards. | ||
| 197 | * almost rc5 coding, but some non-standard keys */ | ||
| 198 | IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE] = { | ||
| 199 | /* Keys 0 to 9 */ | ||
| 200 | [ 0x00 ] = KEY_KP0, | ||
| 201 | [ 0x01 ] = KEY_KP1, | ||
| 202 | [ 0x02 ] = KEY_KP2, | ||
| 203 | [ 0x03 ] = KEY_KP3, | ||
| 204 | [ 0x04 ] = KEY_KP4, | ||
| 205 | [ 0x05 ] = KEY_KP5, | ||
| 206 | [ 0x06 ] = KEY_KP6, | ||
| 207 | [ 0x07 ] = KEY_KP7, | ||
| 208 | [ 0x08 ] = KEY_KP8, | ||
| 209 | [ 0x09 ] = KEY_KP9, | ||
| 210 | |||
| 211 | [ 0x0a ] = KEY_TEXT, /* keypad asterisk as well */ | ||
| 212 | [ 0x0b ] = KEY_RED, /* red button */ | ||
| 213 | [ 0x0c ] = KEY_RADIO, | ||
| 214 | [ 0x0d ] = KEY_MENU, | ||
| 215 | [ 0x0e ] = KEY_SUBTITLE, /* also the # key */ | ||
| 216 | [ 0x0f ] = KEY_MUTE, | ||
| 217 | [ 0x10 ] = KEY_VOLUMEUP, | ||
| 218 | [ 0x11 ] = KEY_VOLUMEDOWN, | ||
| 219 | [ 0x12 ] = KEY_PREVIOUS, /* previous channel */ | ||
| 220 | [ 0x14 ] = KEY_UP, | ||
| 221 | [ 0x15 ] = KEY_DOWN, | ||
| 222 | [ 0x16 ] = KEY_LEFT, | ||
| 223 | [ 0x17 ] = KEY_RIGHT, | ||
| 224 | [ 0x18 ] = KEY_VIDEO, /* Videos */ | ||
| 225 | [ 0x19 ] = KEY_AUDIO, /* Music */ | ||
| 226 | /* 0x1a: Pictures - presume this means | ||
| 227 | "Multimedia Home Platform" - | ||
| 228 | no "PICTURES" key in input.h | ||
| 229 | */ | ||
| 230 | [ 0x1a ] = KEY_MHP, | ||
| 231 | |||
| 232 | [ 0x1b ] = KEY_EPG, /* Guide */ | ||
| 233 | [ 0x1c ] = KEY_TV, | ||
| 234 | [ 0x1e ] = KEY_NEXTSONG, /* skip >| */ | ||
| 235 | [ 0x1f ] = KEY_EXIT, /* back/exit */ | ||
| 236 | [ 0x20 ] = KEY_CHANNELUP, /* channel / program + */ | ||
| 237 | [ 0x21 ] = KEY_CHANNELDOWN, /* channel / program - */ | ||
| 238 | [ 0x22 ] = KEY_CHANNEL, /* source (old black remote) */ | ||
| 239 | [ 0x24 ] = KEY_PREVIOUSSONG, /* replay |< */ | ||
| 240 | [ 0x25 ] = KEY_ENTER, /* OK */ | ||
| 241 | [ 0x26 ] = KEY_SLEEP, /* minimize (old black remote) */ | ||
| 242 | [ 0x29 ] = KEY_BLUE, /* blue key */ | ||
| 243 | [ 0x2e ] = KEY_GREEN, /* green button */ | ||
| 244 | [ 0x30 ] = KEY_PAUSE, /* pause */ | ||
| 245 | [ 0x32 ] = KEY_REWIND, /* backward << */ | ||
| 246 | [ 0x34 ] = KEY_FASTFORWARD, /* forward >> */ | ||
| 247 | [ 0x35 ] = KEY_PLAY, | ||
| 248 | [ 0x36 ] = KEY_STOP, | ||
| 249 | [ 0x37 ] = KEY_RECORD, /* recording */ | ||
| 250 | [ 0x38 ] = KEY_YELLOW, /* yellow key */ | ||
| 251 | [ 0x3b ] = KEY_SELECT, /* top right button */ | ||
| 252 | [ 0x3c ] = KEY_ZOOM, /* full */ | ||
| 253 | [ 0x3d ] = KEY_POWER, /* system power (green button) */ | ||
| 254 | }; | ||
| 255 | EXPORT_SYMBOL(ir_codes_hauppauge_new); | ||
| 256 | |||
| 257 | IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = { | ||
| 258 | [ 2 ] = KEY_KP0, | ||
| 259 | [ 1 ] = KEY_KP1, | ||
| 260 | [ 11 ] = KEY_KP2, | ||
| 261 | [ 27 ] = KEY_KP3, | ||
| 262 | [ 5 ] = KEY_KP4, | ||
| 263 | [ 9 ] = KEY_KP5, | ||
| 264 | [ 21 ] = KEY_KP6, | ||
| 265 | [ 6 ] = KEY_KP7, | ||
| 266 | [ 10 ] = KEY_KP8, | ||
| 267 | [ 18 ] = KEY_KP9, | ||
| 268 | |||
| 269 | [ 3 ] = KEY_TUNER, /* TV/FM */ | ||
| 270 | [ 7 ] = KEY_SEARCH, /* scan */ | ||
| 271 | [ 28 ] = KEY_ZOOM, /* full screen */ | ||
| 272 | [ 30 ] = KEY_POWER, | ||
| 273 | [ 23 ] = KEY_VOLUMEDOWN, | ||
| 274 | [ 31 ] = KEY_VOLUMEUP, | ||
| 275 | [ 20 ] = KEY_CHANNELDOWN, | ||
| 276 | [ 22 ] = KEY_CHANNELUP, | ||
| 277 | [ 24 ] = KEY_MUTE, | ||
| 278 | |||
| 279 | [ 0 ] = KEY_LIST, /* source */ | ||
| 280 | [ 19 ] = KEY_INFO, /* loop */ | ||
| 281 | [ 16 ] = KEY_LAST, /* +100 */ | ||
| 282 | [ 13 ] = KEY_CLEAR, /* reset */ | ||
| 283 | [ 12 ] = BTN_RIGHT, /* fun++ */ | ||
| 284 | [ 4 ] = BTN_LEFT, /* fun-- */ | ||
| 285 | [ 14 ] = KEY_GOTO, /* function */ | ||
| 286 | [ 15 ] = KEY_STOP, /* freeze */ | ||
| 287 | }; | ||
| 288 | EXPORT_SYMBOL(ir_codes_pixelview); | ||
| 289 | |||
| 290 | /* -------------------------------------------------------------------------- */ | ||
| 291 | |||
| 292 | static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir) | ||
| 293 | { | ||
| 294 | if (KEY_RESERVED == ir->keycode) { | ||
| 295 | printk(KERN_INFO "%s: unknown key: key=0x%02x raw=0x%02x down=%d\n", | ||
| 296 | dev->name,ir->ir_key,ir->ir_raw,ir->keypressed); | ||
| 297 | return; | ||
| 298 | } | ||
| 299 | dprintk(1,"%s: key event code=%d down=%d\n", | ||
| 300 | dev->name,ir->keycode,ir->keypressed); | ||
| 301 | input_report_key(dev,ir->keycode,ir->keypressed); | ||
| 302 | input_sync(dev); | ||
| 303 | } | ||
| 304 | |||
| 305 | /* -------------------------------------------------------------------------- */ | ||
| 306 | |||
| 307 | void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, | ||
| 308 | int ir_type, IR_KEYTAB_TYPE *ir_codes) | ||
| 309 | { | ||
| 310 | int i; | ||
| 311 | |||
| 312 | ir->ir_type = ir_type; | ||
| 313 | if (ir_codes) | ||
| 314 | memcpy(ir->ir_codes, ir_codes, sizeof(ir->ir_codes)); | ||
| 315 | |||
| 316 | |||
| 317 | dev->keycode = ir->ir_codes; | ||
| 318 | dev->keycodesize = sizeof(IR_KEYTAB_TYPE); | ||
| 319 | dev->keycodemax = IR_KEYTAB_SIZE; | ||
| 320 | for (i = 0; i < IR_KEYTAB_SIZE; i++) | ||
| 321 | set_bit(ir->ir_codes[i], dev->keybit); | ||
| 322 | clear_bit(0, dev->keybit); | ||
| 323 | |||
| 324 | set_bit(EV_KEY, dev->evbit); | ||
| 325 | if (repeat) | ||
| 326 | set_bit(EV_REP, dev->evbit); | ||
| 327 | } | ||
| 328 | |||
| 329 | void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir) | ||
| 330 | { | ||
| 331 | if (ir->keypressed) { | ||
| 332 | ir->keypressed = 0; | ||
| 333 | ir_input_key_event(dev,ir); | ||
| 334 | } | ||
| 335 | } | ||
| 336 | |||
| 337 | void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir, | ||
| 338 | u32 ir_key, u32 ir_raw) | ||
| 339 | { | ||
| 340 | u32 keycode = IR_KEYCODE(ir->ir_codes, ir_key); | ||
| 341 | |||
| 342 | if (ir->keypressed && ir->keycode != keycode) { | ||
| 343 | ir->keypressed = 0; | ||
| 344 | ir_input_key_event(dev,ir); | ||
| 345 | } | ||
| 346 | if (!ir->keypressed) { | ||
| 347 | ir->ir_key = ir_key; | ||
| 348 | ir->ir_raw = ir_raw; | ||
| 349 | ir->keycode = keycode; | ||
| 350 | ir->keypressed = 1; | ||
| 351 | ir_input_key_event(dev,ir); | ||
| 352 | } | ||
| 353 | } | ||
| 354 | |||
| 355 | /* -------------------------------------------------------------------------- */ | ||
| 356 | |||
| 357 | u32 ir_extract_bits(u32 data, u32 mask) | ||
| 358 | { | ||
| 359 | int mbit, vbit; | ||
| 360 | u32 value; | ||
| 361 | |||
| 362 | value = 0; | ||
| 363 | vbit = 0; | ||
| 364 | for (mbit = 0; mbit < 32; mbit++) { | ||
| 365 | if (!(mask & ((u32)1 << mbit))) | ||
| 366 | continue; | ||
| 367 | if (data & ((u32)1 << mbit)) | ||
| 368 | value |= (1 << vbit); | ||
| 369 | vbit++; | ||
| 370 | } | ||
| 371 | return value; | ||
| 372 | } | ||
| 373 | |||
| 374 | static int inline getbit(u32 *samples, int bit) | ||
| 375 | { | ||
| 376 | return (samples[bit/32] & (1 << (31-(bit%32)))) ? 1 : 0; | ||
| 377 | } | ||
| 378 | |||
| 379 | /* sump raw samples for visual debugging ;) */ | ||
| 380 | int ir_dump_samples(u32 *samples, int count) | ||
| 381 | { | ||
| 382 | int i, bit, start; | ||
| 383 | |||
| 384 | printk(KERN_DEBUG "ir samples: "); | ||
| 385 | start = 0; | ||
| 386 | for (i = 0; i < count * 32; i++) { | ||
| 387 | bit = getbit(samples,i); | ||
| 388 | if (bit) | ||
| 389 | start = 1; | ||
| 390 | if (0 == start) | ||
| 391 | continue; | ||
| 392 | printk("%s", bit ? "#" : "_"); | ||
| 393 | } | ||
| 394 | printk("\n"); | ||
| 395 | return 0; | ||
| 396 | } | ||
| 397 | |||
| 398 | /* decode raw samples, pulse distance coding used by NEC remotes */ | ||
| 399 | int ir_decode_pulsedistance(u32 *samples, int count, int low, int high) | ||
| 400 | { | ||
| 401 | int i,last,bit,len; | ||
| 402 | u32 curBit; | ||
| 403 | u32 value; | ||
| 404 | |||
| 405 | /* find start burst */ | ||
| 406 | for (i = len = 0; i < count * 32; i++) { | ||
| 407 | bit = getbit(samples,i); | ||
| 408 | if (bit) { | ||
| 409 | len++; | ||
| 410 | } else { | ||
| 411 | if (len >= 29) | ||
| 412 | break; | ||
| 413 | len = 0; | ||
| 414 | } | ||
| 415 | } | ||
| 416 | |||
| 417 | /* start burst to short */ | ||
| 418 | if (len < 29) | ||
| 419 | return 0xffffffff; | ||
| 420 | |||
| 421 | /* find start silence */ | ||
| 422 | for (len = 0; i < count * 32; i++) { | ||
| 423 | bit = getbit(samples,i); | ||
| 424 | if (bit) { | ||
| 425 | break; | ||
| 426 | } else { | ||
| 427 | len++; | ||
| 428 | } | ||
| 429 | } | ||
| 430 | |||
| 431 | /* silence to short */ | ||
| 432 | if (len < 7) | ||
| 433 | return 0xffffffff; | ||
| 434 | |||
| 435 | /* go decoding */ | ||
| 436 | len = 0; | ||
| 437 | last = 1; | ||
| 438 | value = 0; curBit = 1; | ||
| 439 | for (; i < count * 32; i++) { | ||
| 440 | bit = getbit(samples,i); | ||
| 441 | if (last) { | ||
| 442 | if(bit) { | ||
| 443 | continue; | ||
| 444 | } else { | ||
| 445 | len = 1; | ||
| 446 | } | ||
| 447 | } else { | ||
| 448 | if (bit) { | ||
| 449 | if (len > (low + high) /2) | ||
| 450 | value |= curBit; | ||
| 451 | curBit <<= 1; | ||
| 452 | if (curBit == 1) | ||
| 453 | break; | ||
| 454 | } else { | ||
| 455 | len++; | ||
| 456 | } | ||
| 457 | } | ||
| 458 | last = bit; | ||
| 459 | } | ||
| 460 | |||
| 461 | return value; | ||
| 462 | } | ||
| 463 | |||
| 464 | /* decode raw samples, biphase coding, used by rc5 for example */ | ||
| 465 | int ir_decode_biphase(u32 *samples, int count, int low, int high) | ||
| 466 | { | ||
| 467 | int i,last,bit,len,flips; | ||
| 468 | u32 value; | ||
| 469 | |||
| 470 | /* find start bit (1) */ | ||
| 471 | for (i = 0; i < 32; i++) { | ||
| 472 | bit = getbit(samples,i); | ||
| 473 | if (bit) | ||
| 474 | break; | ||
| 475 | } | ||
| 476 | |||
| 477 | /* go decoding */ | ||
| 478 | len = 0; | ||
| 479 | flips = 0; | ||
| 480 | value = 1; | ||
| 481 | for (; i < count * 32; i++) { | ||
| 482 | if (len > high) | ||
| 483 | break; | ||
| 484 | if (flips > 1) | ||
| 485 | break; | ||
| 486 | last = bit; | ||
| 487 | bit = getbit(samples,i); | ||
| 488 | if (last == bit) { | ||
| 489 | len++; | ||
| 490 | continue; | ||
| 491 | } | ||
| 492 | if (len < low) { | ||
| 493 | len++; | ||
| 494 | flips++; | ||
| 495 | continue; | ||
| 496 | } | ||
| 497 | value <<= 1; | ||
| 498 | value |= bit; | ||
| 499 | flips = 0; | ||
| 500 | len = 1; | ||
| 501 | } | ||
| 502 | return value; | ||
| 503 | } | ||
| 504 | |||
| 505 | EXPORT_SYMBOL_GPL(ir_input_init); | ||
| 506 | EXPORT_SYMBOL_GPL(ir_input_nokey); | ||
| 507 | EXPORT_SYMBOL_GPL(ir_input_keydown); | ||
| 508 | |||
| 509 | EXPORT_SYMBOL_GPL(ir_extract_bits); | ||
| 510 | EXPORT_SYMBOL_GPL(ir_dump_samples); | ||
| 511 | EXPORT_SYMBOL_GPL(ir_decode_biphase); | ||
| 512 | EXPORT_SYMBOL_GPL(ir_decode_pulsedistance); | ||
| 513 | |||
| 514 | /* | ||
| 515 | * Local variables: | ||
| 516 | * c-basic-offset: 8 | ||
| 517 | * End: | ||
| 518 | */ | ||
| 519 | |||
