]>
Commit | Line | Data |
---|---|---|
dd3f616d | 1 | /* ir-keytable.c - handle IR scancode->keycode tables |
ef53a115 MCC |
2 | * |
3 | * Copyright (C) 2009 by Mauro Carvalho Chehab <mchehab@redhat.com> | |
446e4a64 MCC |
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. | |
ef53a115 MCC |
13 | */ |
14 | ||
ef53a115 | 15 | |
882ead32 | 16 | #include <linux/input.h> |
5a0e3ad6 | 17 | #include <linux/slab.h> |
3f113e36 | 18 | #include "ir-core-priv.h" |
ef53a115 | 19 | |
b3074c0a DH |
20 | /* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */ |
21 | #define IR_TAB_MIN_SIZE 256 | |
22 | #define IR_TAB_MAX_SIZE 8192 | |
f6fc5049 | 23 | |
a374fef4 DH |
24 | /* FIXME: IR_KEYPRESS_TIMEOUT should be protocol specific */ |
25 | #define IR_KEYPRESS_TIMEOUT 250 | |
26 | ||
9f470095 DT |
27 | /** |
28 | * ir_create_table() - initializes a scancode table | |
29 | * @rc_tab: the ir_scancode_table to initialize | |
30 | * @name: name to assign to the table | |
31 | * @ir_type: ir type to assign to the new table | |
32 | * @size: initial size of the table | |
33 | * @return: zero on success or a negative error code | |
34 | * | |
35 | * This routine will initialize the ir_scancode_table and will allocate | |
36 | * memory to hold at least the specified number elements. | |
37 | */ | |
38 | static int ir_create_table(struct ir_scancode_table *rc_tab, | |
39 | const char *name, u64 ir_type, size_t size) | |
40 | { | |
41 | rc_tab->name = name; | |
42 | rc_tab->ir_type = ir_type; | |
43 | rc_tab->alloc = roundup_pow_of_two(size * sizeof(struct ir_scancode)); | |
44 | rc_tab->size = rc_tab->alloc / sizeof(struct ir_scancode); | |
45 | rc_tab->scan = kmalloc(rc_tab->alloc, GFP_KERNEL); | |
46 | if (!rc_tab->scan) | |
47 | return -ENOMEM; | |
48 | ||
49 | IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n", | |
50 | rc_tab->size, rc_tab->alloc); | |
51 | return 0; | |
52 | } | |
53 | ||
54 | /** | |
55 | * ir_free_table() - frees memory allocated by a scancode table | |
56 | * @rc_tab: the table whose mappings need to be freed | |
57 | * | |
58 | * This routine will free memory alloctaed for key mappings used by given | |
59 | * scancode table. | |
60 | */ | |
61 | static void ir_free_table(struct ir_scancode_table *rc_tab) | |
62 | { | |
63 | rc_tab->size = 0; | |
64 | kfree(rc_tab->scan); | |
65 | rc_tab->scan = NULL; | |
66 | } | |
67 | ||
7fee03e4 | 68 | /** |
b3074c0a DH |
69 | * ir_resize_table() - resizes a scancode table if necessary |
70 | * @rc_tab: the ir_scancode_table to resize | |
9f470095 | 71 | * @gfp_flags: gfp flags to use when allocating memory |
b3074c0a | 72 | * @return: zero on success or a negative error code |
7fee03e4 | 73 | * |
b3074c0a DH |
74 | * This routine will shrink the ir_scancode_table if it has lots of |
75 | * unused entries and grow it if it is full. | |
7fee03e4 | 76 | */ |
9f470095 | 77 | static int ir_resize_table(struct ir_scancode_table *rc_tab, gfp_t gfp_flags) |
7fee03e4 | 78 | { |
b3074c0a DH |
79 | unsigned int oldalloc = rc_tab->alloc; |
80 | unsigned int newalloc = oldalloc; | |
81 | struct ir_scancode *oldscan = rc_tab->scan; | |
82 | struct ir_scancode *newscan; | |
83 | ||
84 | if (rc_tab->size == rc_tab->len) { | |
85 | /* All entries in use -> grow keytable */ | |
86 | if (rc_tab->alloc >= IR_TAB_MAX_SIZE) | |
87 | return -ENOMEM; | |
7fee03e4 | 88 | |
b3074c0a DH |
89 | newalloc *= 2; |
90 | IR_dprintk(1, "Growing table to %u bytes\n", newalloc); | |
91 | } | |
7fee03e4 | 92 | |
b3074c0a DH |
93 | if ((rc_tab->len * 3 < rc_tab->size) && (oldalloc > IR_TAB_MIN_SIZE)) { |
94 | /* Less than 1/3 of entries in use -> shrink keytable */ | |
95 | newalloc /= 2; | |
96 | IR_dprintk(1, "Shrinking table to %u bytes\n", newalloc); | |
97 | } | |
7fee03e4 | 98 | |
b3074c0a DH |
99 | if (newalloc == oldalloc) |
100 | return 0; | |
7fee03e4 | 101 | |
9f470095 | 102 | newscan = kmalloc(newalloc, gfp_flags); |
b3074c0a DH |
103 | if (!newscan) { |
104 | IR_dprintk(1, "Failed to kmalloc %u bytes\n", newalloc); | |
105 | return -ENOMEM; | |
106 | } | |
7fee03e4 | 107 | |
b3074c0a DH |
108 | memcpy(newscan, rc_tab->scan, rc_tab->len * sizeof(struct ir_scancode)); |
109 | rc_tab->scan = newscan; | |
110 | rc_tab->alloc = newalloc; | |
111 | rc_tab->size = rc_tab->alloc / sizeof(struct ir_scancode); | |
112 | kfree(oldscan); | |
113 | return 0; | |
7fee03e4 MCC |
114 | } |
115 | ||
f6fc5049 | 116 | /** |
9f470095 | 117 | * ir_update_mapping() - set a keycode in the scancode->keycode table |
b3074c0a | 118 | * @dev: the struct input_dev device descriptor |
9f470095 DT |
119 | * @rc_tab: scancode table to be adjusted |
120 | * @index: index of the mapping that needs to be updated | |
121 | * @keycode: the desired keycode | |
122 | * @return: previous keycode assigned to the mapping | |
123 | * | |
124 | * This routine is used to update scancode->keycopde mapping at given | |
125 | * position. | |
126 | */ | |
127 | static unsigned int ir_update_mapping(struct input_dev *dev, | |
128 | struct ir_scancode_table *rc_tab, | |
129 | unsigned int index, | |
130 | unsigned int new_keycode) | |
131 | { | |
132 | int old_keycode = rc_tab->scan[index].keycode; | |
133 | int i; | |
134 | ||
135 | /* Did the user wish to remove the mapping? */ | |
136 | if (new_keycode == KEY_RESERVED || new_keycode == KEY_UNKNOWN) { | |
137 | IR_dprintk(1, "#%d: Deleting scan 0x%04x\n", | |
138 | index, rc_tab->scan[index].scancode); | |
139 | rc_tab->len--; | |
140 | memmove(&rc_tab->scan[index], &rc_tab->scan[index+ 1], | |
141 | (rc_tab->len - index) * sizeof(struct ir_scancode)); | |
142 | } else { | |
143 | IR_dprintk(1, "#%d: %s scan 0x%04x with key 0x%04x\n", | |
144 | index, | |
145 | old_keycode == KEY_RESERVED ? "New" : "Replacing", | |
146 | rc_tab->scan[index].scancode, new_keycode); | |
147 | rc_tab->scan[index].keycode = new_keycode; | |
148 | __set_bit(new_keycode, dev->keybit); | |
149 | } | |
150 | ||
151 | if (old_keycode != KEY_RESERVED) { | |
152 | /* A previous mapping was updated... */ | |
153 | __clear_bit(old_keycode, dev->keybit); | |
154 | /* ... but another scancode might use the same keycode */ | |
155 | for (i = 0; i < rc_tab->len; i++) { | |
156 | if (rc_tab->scan[i].keycode == old_keycode) { | |
157 | __set_bit(old_keycode, dev->keybit); | |
158 | break; | |
159 | } | |
160 | } | |
161 | ||
162 | /* Possibly shrink the keytable, failure is not a problem */ | |
163 | ir_resize_table(rc_tab, GFP_ATOMIC); | |
164 | } | |
165 | ||
166 | return old_keycode; | |
167 | } | |
168 | ||
169 | /** | |
170 | * ir_locate_scancode() - set a keycode in the scancode->keycode table | |
171 | * @ir_dev: the struct ir_input_dev device descriptor | |
172 | * @rc_tab: scancode table to be searched | |
173 | * @scancode: the desired scancode | |
174 | * @resize: controls whether we allowed to resize the table to | |
175 | * accomodate not yet present scancodes | |
176 | * @return: index of the mapping containing scancode in question | |
177 | * or -1U in case of failure. | |
f6fc5049 | 178 | * |
9f470095 DT |
179 | * This routine is used to locate given scancode in ir_scancode_table. |
180 | * If scancode is not yet present the routine will allocate a new slot | |
181 | * for it. | |
f6fc5049 | 182 | */ |
9f470095 DT |
183 | static unsigned int ir_establish_scancode(struct ir_input_dev *ir_dev, |
184 | struct ir_scancode_table *rc_tab, | |
185 | unsigned int scancode, | |
186 | bool resize) | |
f6fc5049 | 187 | { |
b3074c0a | 188 | unsigned int i; |
9dfe4e83 MCC |
189 | |
190 | /* | |
191 | * Unfortunately, some hardware-based IR decoders don't provide | |
192 | * all bits for the complete IR code. In general, they provide only | |
193 | * the command part of the IR code. Yet, as it is possible to replace | |
194 | * the provided IR with another one, it is needed to allow loading | |
195 | * IR tables from other remotes. So, | |
196 | */ | |
9f470095 | 197 | if (ir_dev->props && ir_dev->props->scanmask) |
9dfe4e83 | 198 | scancode &= ir_dev->props->scanmask; |
b3074c0a DH |
199 | |
200 | /* First check if we already have a mapping for this ir command */ | |
201 | for (i = 0; i < rc_tab->len; i++) { | |
9f470095 DT |
202 | if (rc_tab->scan[i].scancode == scancode) |
203 | return i; | |
204 | ||
b3074c0a | 205 | /* Keytable is sorted from lowest to highest scancode */ |
9f470095 | 206 | if (rc_tab->scan[i].scancode >= scancode) |
b3074c0a | 207 | break; |
b3074c0a | 208 | } |
f6fc5049 | 209 | |
9f470095 DT |
210 | /* No previous mapping found, we might need to grow the table */ |
211 | if (rc_tab->size == rc_tab->len) { | |
212 | if (!resize || ir_resize_table(rc_tab, GFP_ATOMIC)) | |
213 | return -1U; | |
214 | } | |
35438946 | 215 | |
9f470095 DT |
216 | /* i is the proper index to insert our new keycode */ |
217 | if (i < rc_tab->len) | |
b3074c0a DH |
218 | memmove(&rc_tab->scan[i + 1], &rc_tab->scan[i], |
219 | (rc_tab->len - i) * sizeof(struct ir_scancode)); | |
9f470095 DT |
220 | rc_tab->scan[i].scancode = scancode; |
221 | rc_tab->scan[i].keycode = KEY_RESERVED; | |
222 | rc_tab->len++; | |
f6fc5049 | 223 | |
9f470095 | 224 | return i; |
f6fc5049 MCC |
225 | } |
226 | ||
ef53a115 | 227 | /** |
b3074c0a | 228 | * ir_setkeycode() - set a keycode in the scancode->keycode table |
ef53a115 MCC |
229 | * @dev: the struct input_dev device descriptor |
230 | * @scancode: the desired scancode | |
b3074c0a DH |
231 | * @keycode: result |
232 | * @return: -EINVAL if the keycode could not be inserted, otherwise zero. | |
ef53a115 | 233 | * |
b3074c0a | 234 | * This routine is used to handle evdev EVIOCSKEY ioctl. |
ef53a115 | 235 | */ |
b3074c0a | 236 | static int ir_setkeycode(struct input_dev *dev, |
9f470095 DT |
237 | const struct input_keymap_entry *ke, |
238 | unsigned int *old_keycode) | |
ef53a115 | 239 | { |
75543cce MCC |
240 | struct ir_input_dev *ir_dev = input_get_drvdata(dev); |
241 | struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; | |
9f470095 DT |
242 | unsigned int index; |
243 | unsigned int scancode; | |
244 | int retval; | |
245 | unsigned long flags; | |
ef53a115 | 246 | |
b3074c0a | 247 | spin_lock_irqsave(&rc_tab->lock, flags); |
9f470095 DT |
248 | |
249 | if (ke->flags & INPUT_KEYMAP_BY_INDEX) { | |
250 | index = ke->index; | |
251 | if (index >= rc_tab->len) { | |
252 | retval = -EINVAL; | |
253 | goto out; | |
254 | } | |
255 | } else { | |
256 | retval = input_scancode_to_scalar(ke, &scancode); | |
257 | if (retval) | |
258 | goto out; | |
259 | ||
260 | index = ir_establish_scancode(ir_dev, rc_tab, scancode, true); | |
261 | if (index >= rc_tab->len) { | |
262 | retval = -ENOMEM; | |
263 | goto out; | |
264 | } | |
265 | } | |
266 | ||
267 | *old_keycode = ir_update_mapping(dev, rc_tab, index, ke->keycode); | |
268 | ||
269 | out: | |
b3074c0a | 270 | spin_unlock_irqrestore(&rc_tab->lock, flags); |
9f470095 | 271 | return retval; |
e97f4677 MCC |
272 | } |
273 | ||
274 | /** | |
b3074c0a DH |
275 | * ir_setkeytable() - sets several entries in the scancode->keycode table |
276 | * @dev: the struct input_dev device descriptor | |
277 | * @to: the struct ir_scancode_table to copy entries to | |
278 | * @from: the struct ir_scancode_table to copy entries from | |
9f470095 | 279 | * @return: -ENOMEM if all keycodes could not be inserted, otherwise zero. |
e97f4677 | 280 | * |
b3074c0a | 281 | * This routine is used to handle table initialization. |
e97f4677 | 282 | */ |
9f470095 | 283 | static int ir_setkeytable(struct ir_input_dev *ir_dev, |
b3074c0a | 284 | const struct ir_scancode_table *from) |
e97f4677 | 285 | { |
b3074c0a | 286 | struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; |
9f470095 DT |
287 | unsigned int i, index; |
288 | int rc; | |
289 | ||
290 | rc = ir_create_table(&ir_dev->rc_tab, | |
291 | from->name, from->ir_type, from->size); | |
292 | if (rc) | |
293 | return rc; | |
294 | ||
295 | IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n", | |
296 | rc_tab->size, rc_tab->alloc); | |
e97f4677 | 297 | |
b3074c0a | 298 | for (i = 0; i < from->size; i++) { |
9f470095 DT |
299 | index = ir_establish_scancode(ir_dev, rc_tab, |
300 | from->scan[i].scancode, false); | |
301 | if (index >= rc_tab->len) { | |
302 | rc = -ENOMEM; | |
b3074c0a | 303 | break; |
9f470095 DT |
304 | } |
305 | ||
306 | ir_update_mapping(ir_dev->input_dev, rc_tab, index, | |
307 | from->scan[i].keycode); | |
e97f4677 | 308 | } |
9f470095 DT |
309 | |
310 | if (rc) | |
311 | ir_free_table(rc_tab); | |
312 | ||
b3074c0a | 313 | return rc; |
ef53a115 MCC |
314 | } |
315 | ||
9f470095 DT |
316 | /** |
317 | * ir_lookup_by_scancode() - locate mapping by scancode | |
318 | * @rc_tab: the &struct ir_scancode_table to search | |
319 | * @scancode: scancode to look for in the table | |
320 | * @return: index in the table, -1U if not found | |
321 | * | |
322 | * This routine performs binary search in RC keykeymap table for | |
323 | * given scancode. | |
324 | */ | |
325 | static unsigned int ir_lookup_by_scancode(const struct ir_scancode_table *rc_tab, | |
326 | unsigned int scancode) | |
327 | { | |
0d07025e DH |
328 | int start = 0; |
329 | int end = rc_tab->len - 1; | |
330 | int mid; | |
9f470095 DT |
331 | |
332 | while (start <= end) { | |
333 | mid = (start + end) / 2; | |
334 | if (rc_tab->scan[mid].scancode < scancode) | |
335 | start = mid + 1; | |
336 | else if (rc_tab->scan[mid].scancode > scancode) | |
337 | end = mid - 1; | |
338 | else | |
339 | return mid; | |
340 | } | |
341 | ||
342 | return -1U; | |
343 | } | |
344 | ||
ef53a115 | 345 | /** |
b3074c0a | 346 | * ir_getkeycode() - get a keycode from the scancode->keycode table |
ef53a115 MCC |
347 | * @dev: the struct input_dev device descriptor |
348 | * @scancode: the desired scancode | |
b3074c0a DH |
349 | * @keycode: used to return the keycode, if found, or KEY_RESERVED |
350 | * @return: always returns zero. | |
ef53a115 | 351 | * |
b3074c0a | 352 | * This routine is used to handle evdev EVIOCGKEY ioctl. |
ef53a115 | 353 | */ |
b3074c0a | 354 | static int ir_getkeycode(struct input_dev *dev, |
9f470095 | 355 | struct input_keymap_entry *ke) |
ef53a115 | 356 | { |
75543cce MCC |
357 | struct ir_input_dev *ir_dev = input_get_drvdata(dev); |
358 | struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; | |
9f470095 DT |
359 | struct ir_scancode *entry; |
360 | unsigned long flags; | |
361 | unsigned int index; | |
362 | unsigned int scancode; | |
363 | int retval; | |
ef53a115 | 364 | |
b3074c0a | 365 | spin_lock_irqsave(&rc_tab->lock, flags); |
9f470095 DT |
366 | |
367 | if (ke->flags & INPUT_KEYMAP_BY_INDEX) { | |
368 | index = ke->index; | |
369 | } else { | |
370 | retval = input_scancode_to_scalar(ke, &scancode); | |
371 | if (retval) | |
372 | goto out; | |
373 | ||
374 | index = ir_lookup_by_scancode(rc_tab, scancode); | |
375 | } | |
376 | ||
377 | if (index >= rc_tab->len) { | |
378 | if (!(ke->flags & INPUT_KEYMAP_BY_INDEX)) | |
379 | IR_dprintk(1, "unknown key for scancode 0x%04x\n", | |
380 | scancode); | |
381 | retval = -EINVAL; | |
382 | goto out; | |
e97f4677 MCC |
383 | } |
384 | ||
9f470095 | 385 | entry = &rc_tab->scan[index]; |
35438946 | 386 | |
9f470095 DT |
387 | ke->index = index; |
388 | ke->keycode = entry->keycode; | |
389 | ke->len = sizeof(entry->scancode); | |
390 | memcpy(ke->scancode, &entry->scancode, sizeof(entry->scancode)); | |
391 | ||
47c5ba53 DT |
392 | retval = 0; |
393 | ||
9f470095 DT |
394 | out: |
395 | spin_unlock_irqrestore(&rc_tab->lock, flags); | |
396 | return retval; | |
ef53a115 MCC |
397 | } |
398 | ||
399 | /** | |
400 | * ir_g_keycode_from_table() - gets the keycode that corresponds to a scancode | |
7fee03e4 | 401 | * @input_dev: the struct input_dev descriptor of the device |
ef53a115 MCC |
402 | * @scancode: the scancode that we're seeking |
403 | * | |
404 | * This routine is used by the input routines when a key is pressed at the | |
405 | * IR. The scancode is received and needs to be converted into a keycode. | |
6660de56 | 406 | * If the key is not found, it returns KEY_RESERVED. Otherwise, returns the |
ef53a115 MCC |
407 | * corresponding keycode from the table. |
408 | */ | |
409 | u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode) | |
410 | { | |
9f470095 DT |
411 | struct ir_input_dev *ir_dev = input_get_drvdata(dev); |
412 | struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; | |
413 | unsigned int keycode; | |
414 | unsigned int index; | |
415 | unsigned long flags; | |
416 | ||
417 | spin_lock_irqsave(&rc_tab->lock, flags); | |
418 | ||
419 | index = ir_lookup_by_scancode(rc_tab, scancode); | |
420 | keycode = index < rc_tab->len ? | |
421 | rc_tab->scan[index].keycode : KEY_RESERVED; | |
422 | ||
423 | spin_unlock_irqrestore(&rc_tab->lock, flags); | |
ef53a115 | 424 | |
35438946 MCC |
425 | if (keycode != KEY_RESERVED) |
426 | IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n", | |
427 | dev->name, scancode, keycode); | |
9f470095 | 428 | |
b3074c0a | 429 | return keycode; |
ef53a115 | 430 | } |
446e4a64 | 431 | EXPORT_SYMBOL_GPL(ir_g_keycode_from_table); |
ef53a115 | 432 | |
6660de56 MCC |
433 | /** |
434 | * ir_keyup() - generates input event to cleanup a key press | |
a374fef4 | 435 | * @ir: the struct ir_input_dev descriptor of the device |
6660de56 | 436 | * |
a374fef4 DH |
437 | * This routine is used to signal that a key has been released on the |
438 | * remote control. It reports a keyup input event via input_report_key(). | |
439 | */ | |
ee089405 | 440 | void ir_keyup(struct ir_input_dev *ir) |
a374fef4 DH |
441 | { |
442 | if (!ir->keypressed) | |
443 | return; | |
444 | ||
445 | IR_dprintk(1, "keyup key 0x%04x\n", ir->last_keycode); | |
446 | input_report_key(ir->input_dev, ir->last_keycode, 0); | |
447 | input_sync(ir->input_dev); | |
448 | ir->keypressed = false; | |
449 | } | |
ee089405 | 450 | EXPORT_SYMBOL_GPL(ir_keyup); |
a374fef4 DH |
451 | |
452 | /** | |
453 | * ir_timer_keyup() - generates a keyup event after a timeout | |
454 | * @cookie: a pointer to struct ir_input_dev passed to setup_timer() | |
455 | * | |
456 | * This routine will generate a keyup event some time after a keydown event | |
457 | * is generated when no further activity has been detected. | |
6660de56 | 458 | */ |
a374fef4 | 459 | static void ir_timer_keyup(unsigned long cookie) |
6660de56 | 460 | { |
a374fef4 DH |
461 | struct ir_input_dev *ir = (struct ir_input_dev *)cookie; |
462 | unsigned long flags; | |
463 | ||
464 | /* | |
465 | * ir->keyup_jiffies is used to prevent a race condition if a | |
466 | * hardware interrupt occurs at this point and the keyup timer | |
467 | * event is moved further into the future as a result. | |
468 | * | |
469 | * The timer will then be reactivated and this function called | |
470 | * again in the future. We need to exit gracefully in that case | |
471 | * to allow the input subsystem to do its auto-repeat magic or | |
472 | * a keyup event might follow immediately after the keydown. | |
473 | */ | |
474 | spin_lock_irqsave(&ir->keylock, flags); | |
e0172fd3 | 475 | if (time_is_before_eq_jiffies(ir->keyup_jiffies)) |
a374fef4 DH |
476 | ir_keyup(ir); |
477 | spin_unlock_irqrestore(&ir->keylock, flags); | |
478 | } | |
479 | ||
480 | /** | |
481 | * ir_repeat() - notifies the IR core that a key is still pressed | |
482 | * @dev: the struct input_dev descriptor of the device | |
483 | * | |
484 | * This routine is used by IR decoders when a repeat message which does | |
485 | * not include the necessary bits to reproduce the scancode has been | |
486 | * received. | |
487 | */ | |
488 | void ir_repeat(struct input_dev *dev) | |
489 | { | |
490 | unsigned long flags; | |
6660de56 MCC |
491 | struct ir_input_dev *ir = input_get_drvdata(dev); |
492 | ||
a374fef4 DH |
493 | spin_lock_irqsave(&ir->keylock, flags); |
494 | ||
ed4d3876 ML |
495 | input_event(dev, EV_MSC, MSC_SCAN, ir->last_scancode); |
496 | ||
6660de56 | 497 | if (!ir->keypressed) |
a374fef4 | 498 | goto out; |
6660de56 | 499 | |
a374fef4 DH |
500 | ir->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT); |
501 | mod_timer(&ir->timer_keyup, ir->keyup_jiffies); | |
502 | ||
503 | out: | |
504 | spin_unlock_irqrestore(&ir->keylock, flags); | |
6660de56 | 505 | } |
a374fef4 | 506 | EXPORT_SYMBOL_GPL(ir_repeat); |
6660de56 MCC |
507 | |
508 | /** | |
509 | * ir_keydown() - generates input event for a key press | |
a374fef4 DH |
510 | * @dev: the struct input_dev descriptor of the device |
511 | * @scancode: the scancode that we're seeking | |
512 | * @toggle: the toggle value (protocol dependent, if the protocol doesn't | |
513 | * support toggle values, this should be set to zero) | |
6660de56 MCC |
514 | * |
515 | * This routine is used by the input routines when a key is pressed at the | |
516 | * IR. It gets the keycode for a scancode and reports an input event via | |
517 | * input_report_key(). | |
518 | */ | |
a374fef4 | 519 | void ir_keydown(struct input_dev *dev, int scancode, u8 toggle) |
6660de56 | 520 | { |
a374fef4 | 521 | unsigned long flags; |
6660de56 MCC |
522 | struct ir_input_dev *ir = input_get_drvdata(dev); |
523 | ||
524 | u32 keycode = ir_g_keycode_from_table(dev, scancode); | |
525 | ||
a374fef4 | 526 | spin_lock_irqsave(&ir->keylock, flags); |
6660de56 | 527 | |
ed4d3876 ML |
528 | input_event(dev, EV_MSC, MSC_SCAN, scancode); |
529 | ||
a374fef4 DH |
530 | /* Repeat event? */ |
531 | if (ir->keypressed && | |
532 | ir->last_scancode == scancode && | |
533 | ir->last_toggle == toggle) | |
534 | goto set_timer; | |
6660de56 | 535 | |
a374fef4 DH |
536 | /* Release old keypress */ |
537 | ir_keyup(ir); | |
6660de56 | 538 | |
a374fef4 DH |
539 | ir->last_scancode = scancode; |
540 | ir->last_toggle = toggle; | |
541 | ir->last_keycode = keycode; | |
542 | ||
ed4d3876 | 543 | |
a374fef4 DH |
544 | if (keycode == KEY_RESERVED) |
545 | goto out; | |
6660de56 | 546 | |
ed4d3876 | 547 | |
a374fef4 DH |
548 | /* Register a keypress */ |
549 | ir->keypressed = true; | |
550 | IR_dprintk(1, "%s: key down event, key 0x%04x, scancode 0x%04x\n", | |
551 | dev->name, keycode, scancode); | |
552 | input_report_key(dev, ir->last_keycode, 1); | |
6660de56 MCC |
553 | input_sync(dev); |
554 | ||
a374fef4 DH |
555 | set_timer: |
556 | ir->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT); | |
557 | mod_timer(&ir->timer_keyup, ir->keyup_jiffies); | |
558 | out: | |
559 | spin_unlock_irqrestore(&ir->keylock, flags); | |
6660de56 MCC |
560 | } |
561 | EXPORT_SYMBOL_GPL(ir_keydown); | |
562 | ||
716aab44 MCC |
563 | static int ir_open(struct input_dev *input_dev) |
564 | { | |
565 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | |
566 | ||
567 | return ir_dev->props->open(ir_dev->props->priv); | |
568 | } | |
569 | ||
570 | static void ir_close(struct input_dev *input_dev) | |
571 | { | |
572 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | |
573 | ||
574 | ir_dev->props->close(ir_dev->props->priv); | |
575 | } | |
6660de56 | 576 | |
ef53a115 | 577 | /** |
b2245ba1 | 578 | * __ir_input_register() - sets the IR keycode table and add the handlers |
ef53a115 MCC |
579 | * for keymap table get/set |
580 | * @input_dev: the struct input_dev descriptor of the device | |
581 | * @rc_tab: the struct ir_scancode_table table of scancode/keymap | |
582 | * | |
d4b778d3 MCC |
583 | * This routine is used to initialize the input infrastructure |
584 | * to work with an IR. | |
585 | * It will register the input/evdev interface for the device and | |
586 | * register the syfs code for IR class | |
ef53a115 | 587 | */ |
b2245ba1 | 588 | int __ir_input_register(struct input_dev *input_dev, |
e93854da | 589 | const struct ir_scancode_table *rc_tab, |
4a702ebf | 590 | struct ir_dev_props *props, |
727e625c | 591 | const char *driver_name) |
ef53a115 | 592 | { |
75543cce | 593 | struct ir_input_dev *ir_dev; |
b3074c0a | 594 | int rc; |
ef53a115 MCC |
595 | |
596 | if (rc_tab->scan == NULL || !rc_tab->size) | |
597 | return -EINVAL; | |
598 | ||
75543cce MCC |
599 | ir_dev = kzalloc(sizeof(*ir_dev), GFP_KERNEL); |
600 | if (!ir_dev) | |
601 | return -ENOMEM; | |
602 | ||
b3074c0a DH |
603 | ir_dev->driver_name = kasprintf(GFP_KERNEL, "%s", driver_name); |
604 | if (!ir_dev->driver_name) { | |
605 | rc = -ENOMEM; | |
606 | goto out_dev; | |
607 | } | |
75543cce | 608 | |
9f470095 DT |
609 | input_dev->getkeycode_new = ir_getkeycode; |
610 | input_dev->setkeycode_new = ir_setkeycode; | |
b3074c0a | 611 | input_set_drvdata(input_dev, ir_dev); |
a374fef4 | 612 | ir_dev->input_dev = input_dev; |
b3074c0a DH |
613 | |
614 | spin_lock_init(&ir_dev->rc_tab.lock); | |
a374fef4 DH |
615 | spin_lock_init(&ir_dev->keylock); |
616 | setup_timer(&ir_dev->timer_keyup, ir_timer_keyup, (unsigned long)ir_dev); | |
617 | ||
9dfe4e83 MCC |
618 | if (props) { |
619 | ir_dev->props = props; | |
620 | if (props->open) | |
621 | input_dev->open = ir_open; | |
622 | if (props->close) | |
623 | input_dev->close = ir_close; | |
624 | } | |
b3074c0a | 625 | |
b3074c0a | 626 | set_bit(EV_KEY, input_dev->evbit); |
a374fef4 | 627 | set_bit(EV_REP, input_dev->evbit); |
ed4d3876 ML |
628 | set_bit(EV_MSC, input_dev->evbit); |
629 | set_bit(MSC_SCAN, input_dev->mscbit); | |
a374fef4 | 630 | |
9f470095 DT |
631 | rc = ir_setkeytable(ir_dev, rc_tab); |
632 | if (rc) | |
633 | goto out_name; | |
75543cce | 634 | |
4714eda8 | 635 | rc = ir_register_class(input_dev); |
945cdfa2 | 636 | if (rc < 0) |
b3074c0a | 637 | goto out_table; |
579e7d60 | 638 | |
84b14f18 IL |
639 | if (ir_dev->props) |
640 | if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) { | |
641 | rc = ir_raw_event_register(input_dev); | |
642 | if (rc < 0) | |
643 | goto out_event; | |
644 | } | |
626cf697 | 645 | |
58b3dd44 | 646 | rc = ir_register_input(input_dev); |
991369e3 MCC |
647 | if (rc < 0) |
648 | goto out_event; | |
58b3dd44 | 649 | |
844a9e93 MCC |
650 | IR_dprintk(1, "Registered input device on %s for %s remote%s.\n", |
651 | driver_name, rc_tab->name, | |
ede67a30 DC |
652 | (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_IR_RAW) ? |
653 | " in raw mode" : ""); | |
35438946 | 654 | |
04cab131 MCC |
655 | /* |
656 | * Default delay of 250ms is too short for some protocols, expecially | |
657 | * since the timeout is currently set to 250ms. Increase it to 500ms, | |
658 | * to avoid wrong repetition of the keycodes. | |
659 | */ | |
660 | input_dev->rep[REP_DELAY] = 500; | |
661 | ||
4714eda8 MCC |
662 | return 0; |
663 | ||
626cf697 MCC |
664 | out_event: |
665 | ir_unregister_class(input_dev); | |
b3074c0a | 666 | out_table: |
9f470095 | 667 | ir_free_table(&ir_dev->rc_tab); |
b3074c0a DH |
668 | out_name: |
669 | kfree(ir_dev->driver_name); | |
670 | out_dev: | |
4714eda8 | 671 | kfree(ir_dev); |
579e7d60 | 672 | return rc; |
ef53a115 | 673 | } |
b2245ba1 | 674 | EXPORT_SYMBOL_GPL(__ir_input_register); |
f6fc5049 | 675 | |
d4b778d3 MCC |
676 | /** |
677 | * ir_input_unregister() - unregisters IR and frees resources | |
678 | * @input_dev: the struct input_dev descriptor of the device | |
679 | ||
680 | * This routine is used to free memory and de-register interfaces. | |
681 | */ | |
626cf697 | 682 | void ir_input_unregister(struct input_dev *input_dev) |
f6fc5049 | 683 | { |
626cf697 | 684 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); |
f6fc5049 | 685 | |
579e7d60 | 686 | if (!ir_dev) |
05395a3d MCC |
687 | return; |
688 | ||
f6fc5049 | 689 | IR_dprintk(1, "Freed keycode table\n"); |
626cf697 | 690 | |
a374fef4 | 691 | del_timer_sync(&ir_dev->timer_keyup); |
84b14f18 IL |
692 | if (ir_dev->props) |
693 | if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) | |
694 | ir_raw_event_unregister(input_dev); | |
695 | ||
9f470095 | 696 | ir_free_table(&ir_dev->rc_tab); |
75543cce | 697 | |
626cf697 | 698 | ir_unregister_class(input_dev); |
4714eda8 | 699 | |
b3074c0a | 700 | kfree(ir_dev->driver_name); |
75543cce | 701 | kfree(ir_dev); |
f6fc5049 | 702 | } |
38ef6aa8 | 703 | EXPORT_SYMBOL_GPL(ir_input_unregister); |
f6fc5049 | 704 | |
446e4a64 MCC |
705 | int ir_core_debug; /* ir_debug level (0,1,2) */ |
706 | EXPORT_SYMBOL_GPL(ir_core_debug); | |
707 | module_param_named(debug, ir_core_debug, int, 0644); | |
708 | ||
709 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); | |
710 | MODULE_LICENSE("GPL"); |