Commit | Line | Data |
---|---|---|
829ba9fe | 1 | /* rc-main.c - Remote Controller core module |
ef53a115 | 2 | * |
bc2a6c57 | 3 | * Copyright (C) 2009-2010 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 | ||
6bda9644 | 15 | #include <media/rc-core.h> |
631493ec MCC |
16 | #include <linux/spinlock.h> |
17 | #include <linux/delay.h> | |
882ead32 | 18 | #include <linux/input.h> |
5a0e3ad6 | 19 | #include <linux/slab.h> |
bc2a6c57 | 20 | #include <linux/device.h> |
f62de675 | 21 | #include "rc-core-priv.h" |
ef53a115 | 22 | |
b3074c0a DH |
23 | /* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */ |
24 | #define IR_TAB_MIN_SIZE 256 | |
25 | #define IR_TAB_MAX_SIZE 8192 | |
f6fc5049 | 26 | |
a374fef4 DH |
27 | /* FIXME: IR_KEYPRESS_TIMEOUT should be protocol specific */ |
28 | #define IR_KEYPRESS_TIMEOUT 250 | |
29 | ||
4c7b355d | 30 | /* Used to keep track of known keymaps */ |
631493ec MCC |
31 | static LIST_HEAD(rc_map_list); |
32 | static DEFINE_SPINLOCK(rc_map_lock); | |
33 | ||
d100e659 | 34 | static struct rc_map_list *seek_rc_map(const char *name) |
631493ec | 35 | { |
d100e659 | 36 | struct rc_map_list *map = NULL; |
631493ec MCC |
37 | |
38 | spin_lock(&rc_map_lock); | |
39 | list_for_each_entry(map, &rc_map_list, list) { | |
40 | if (!strcmp(name, map->map.name)) { | |
41 | spin_unlock(&rc_map_lock); | |
42 | return map; | |
43 | } | |
44 | } | |
45 | spin_unlock(&rc_map_lock); | |
46 | ||
47 | return NULL; | |
48 | } | |
49 | ||
d100e659 | 50 | struct rc_map *rc_map_get(const char *name) |
631493ec MCC |
51 | { |
52 | ||
d100e659 | 53 | struct rc_map_list *map; |
631493ec MCC |
54 | |
55 | map = seek_rc_map(name); | |
56 | #ifdef MODULE | |
57 | if (!map) { | |
58 | int rc = request_module(name); | |
59 | if (rc < 0) { | |
60 | printk(KERN_ERR "Couldn't load IR keymap %s\n", name); | |
61 | return NULL; | |
62 | } | |
63 | msleep(20); /* Give some time for IR to register */ | |
64 | ||
65 | map = seek_rc_map(name); | |
66 | } | |
67 | #endif | |
68 | if (!map) { | |
69 | printk(KERN_ERR "IR keymap %s not found\n", name); | |
70 | return NULL; | |
71 | } | |
72 | ||
73 | printk(KERN_INFO "Registered IR keymap %s\n", map->map.name); | |
74 | ||
75 | return &map->map; | |
76 | } | |
d100e659 | 77 | EXPORT_SYMBOL_GPL(rc_map_get); |
631493ec | 78 | |
d100e659 | 79 | int rc_map_register(struct rc_map_list *map) |
631493ec MCC |
80 | { |
81 | spin_lock(&rc_map_lock); | |
82 | list_add_tail(&map->list, &rc_map_list); | |
83 | spin_unlock(&rc_map_lock); | |
84 | return 0; | |
85 | } | |
d100e659 | 86 | EXPORT_SYMBOL_GPL(rc_map_register); |
631493ec | 87 | |
d100e659 | 88 | void rc_map_unregister(struct rc_map_list *map) |
631493ec MCC |
89 | { |
90 | spin_lock(&rc_map_lock); | |
91 | list_del(&map->list); | |
92 | spin_unlock(&rc_map_lock); | |
93 | } | |
d100e659 | 94 | EXPORT_SYMBOL_GPL(rc_map_unregister); |
631493ec MCC |
95 | |
96 | ||
2f4f58d6 | 97 | static struct rc_map_table empty[] = { |
631493ec MCC |
98 | { 0x2a, KEY_COFFEE }, |
99 | }; | |
100 | ||
d100e659 | 101 | static struct rc_map_list empty_map = { |
631493ec MCC |
102 | .map = { |
103 | .scan = empty, | |
104 | .size = ARRAY_SIZE(empty), | |
52b66144 | 105 | .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ |
631493ec MCC |
106 | .name = RC_MAP_EMPTY, |
107 | } | |
108 | }; | |
109 | ||
9f470095 DT |
110 | /** |
111 | * ir_create_table() - initializes a scancode table | |
b088ba65 | 112 | * @rc_map: the rc_map to initialize |
9f470095 | 113 | * @name: name to assign to the table |
52b66144 | 114 | * @rc_type: ir type to assign to the new table |
9f470095 DT |
115 | * @size: initial size of the table |
116 | * @return: zero on success or a negative error code | |
117 | * | |
b088ba65 | 118 | * This routine will initialize the rc_map and will allocate |
d8b4b582 | 119 | * memory to hold at least the specified number of elements. |
9f470095 | 120 | */ |
b088ba65 | 121 | static int ir_create_table(struct rc_map *rc_map, |
52b66144 | 122 | const char *name, u64 rc_type, size_t size) |
9f470095 | 123 | { |
b088ba65 MCC |
124 | rc_map->name = name; |
125 | rc_map->rc_type = rc_type; | |
2f4f58d6 MCC |
126 | rc_map->alloc = roundup_pow_of_two(size * sizeof(struct rc_map_table)); |
127 | rc_map->size = rc_map->alloc / sizeof(struct rc_map_table); | |
b088ba65 MCC |
128 | rc_map->scan = kmalloc(rc_map->alloc, GFP_KERNEL); |
129 | if (!rc_map->scan) | |
9f470095 DT |
130 | return -ENOMEM; |
131 | ||
132 | IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n", | |
b088ba65 | 133 | rc_map->size, rc_map->alloc); |
9f470095 DT |
134 | return 0; |
135 | } | |
136 | ||
137 | /** | |
138 | * ir_free_table() - frees memory allocated by a scancode table | |
b088ba65 | 139 | * @rc_map: the table whose mappings need to be freed |
9f470095 DT |
140 | * |
141 | * This routine will free memory alloctaed for key mappings used by given | |
142 | * scancode table. | |
143 | */ | |
b088ba65 | 144 | static void ir_free_table(struct rc_map *rc_map) |
9f470095 | 145 | { |
b088ba65 MCC |
146 | rc_map->size = 0; |
147 | kfree(rc_map->scan); | |
148 | rc_map->scan = NULL; | |
9f470095 DT |
149 | } |
150 | ||
7fee03e4 | 151 | /** |
b3074c0a | 152 | * ir_resize_table() - resizes a scancode table if necessary |
b088ba65 | 153 | * @rc_map: the rc_map to resize |
9f470095 | 154 | * @gfp_flags: gfp flags to use when allocating memory |
b3074c0a | 155 | * @return: zero on success or a negative error code |
7fee03e4 | 156 | * |
b088ba65 | 157 | * This routine will shrink the rc_map if it has lots of |
b3074c0a | 158 | * unused entries and grow it if it is full. |
7fee03e4 | 159 | */ |
b088ba65 | 160 | static int ir_resize_table(struct rc_map *rc_map, gfp_t gfp_flags) |
7fee03e4 | 161 | { |
b088ba65 | 162 | unsigned int oldalloc = rc_map->alloc; |
b3074c0a | 163 | unsigned int newalloc = oldalloc; |
2f4f58d6 MCC |
164 | struct rc_map_table *oldscan = rc_map->scan; |
165 | struct rc_map_table *newscan; | |
b3074c0a | 166 | |
b088ba65 | 167 | if (rc_map->size == rc_map->len) { |
b3074c0a | 168 | /* All entries in use -> grow keytable */ |
b088ba65 | 169 | if (rc_map->alloc >= IR_TAB_MAX_SIZE) |
b3074c0a | 170 | return -ENOMEM; |
7fee03e4 | 171 | |
b3074c0a DH |
172 | newalloc *= 2; |
173 | IR_dprintk(1, "Growing table to %u bytes\n", newalloc); | |
174 | } | |
7fee03e4 | 175 | |
b088ba65 | 176 | if ((rc_map->len * 3 < rc_map->size) && (oldalloc > IR_TAB_MIN_SIZE)) { |
b3074c0a DH |
177 | /* Less than 1/3 of entries in use -> shrink keytable */ |
178 | newalloc /= 2; | |
179 | IR_dprintk(1, "Shrinking table to %u bytes\n", newalloc); | |
180 | } | |
7fee03e4 | 181 | |
b3074c0a DH |
182 | if (newalloc == oldalloc) |
183 | return 0; | |
7fee03e4 | 184 | |
9f470095 | 185 | newscan = kmalloc(newalloc, gfp_flags); |
b3074c0a DH |
186 | if (!newscan) { |
187 | IR_dprintk(1, "Failed to kmalloc %u bytes\n", newalloc); | |
188 | return -ENOMEM; | |
189 | } | |
7fee03e4 | 190 | |
2f4f58d6 | 191 | memcpy(newscan, rc_map->scan, rc_map->len * sizeof(struct rc_map_table)); |
b088ba65 MCC |
192 | rc_map->scan = newscan; |
193 | rc_map->alloc = newalloc; | |
2f4f58d6 | 194 | rc_map->size = rc_map->alloc / sizeof(struct rc_map_table); |
b3074c0a DH |
195 | kfree(oldscan); |
196 | return 0; | |
7fee03e4 MCC |
197 | } |
198 | ||
f6fc5049 | 199 | /** |
9f470095 | 200 | * ir_update_mapping() - set a keycode in the scancode->keycode table |
d8b4b582 | 201 | * @dev: the struct rc_dev device descriptor |
b088ba65 | 202 | * @rc_map: scancode table to be adjusted |
9f470095 DT |
203 | * @index: index of the mapping that needs to be updated |
204 | * @keycode: the desired keycode | |
205 | * @return: previous keycode assigned to the mapping | |
206 | * | |
d8b4b582 | 207 | * This routine is used to update scancode->keycode mapping at given |
9f470095 DT |
208 | * position. |
209 | */ | |
d8b4b582 | 210 | static unsigned int ir_update_mapping(struct rc_dev *dev, |
b088ba65 | 211 | struct rc_map *rc_map, |
9f470095 DT |
212 | unsigned int index, |
213 | unsigned int new_keycode) | |
214 | { | |
b088ba65 | 215 | int old_keycode = rc_map->scan[index].keycode; |
9f470095 DT |
216 | int i; |
217 | ||
218 | /* Did the user wish to remove the mapping? */ | |
219 | if (new_keycode == KEY_RESERVED || new_keycode == KEY_UNKNOWN) { | |
220 | IR_dprintk(1, "#%d: Deleting scan 0x%04x\n", | |
b088ba65 MCC |
221 | index, rc_map->scan[index].scancode); |
222 | rc_map->len--; | |
223 | memmove(&rc_map->scan[index], &rc_map->scan[index+ 1], | |
2f4f58d6 | 224 | (rc_map->len - index) * sizeof(struct rc_map_table)); |
9f470095 DT |
225 | } else { |
226 | IR_dprintk(1, "#%d: %s scan 0x%04x with key 0x%04x\n", | |
227 | index, | |
228 | old_keycode == KEY_RESERVED ? "New" : "Replacing", | |
b088ba65 MCC |
229 | rc_map->scan[index].scancode, new_keycode); |
230 | rc_map->scan[index].keycode = new_keycode; | |
d8b4b582 | 231 | __set_bit(new_keycode, dev->input_dev->keybit); |
9f470095 DT |
232 | } |
233 | ||
234 | if (old_keycode != KEY_RESERVED) { | |
235 | /* A previous mapping was updated... */ | |
d8b4b582 | 236 | __clear_bit(old_keycode, dev->input_dev->keybit); |
9f470095 | 237 | /* ... but another scancode might use the same keycode */ |
b088ba65 MCC |
238 | for (i = 0; i < rc_map->len; i++) { |
239 | if (rc_map->scan[i].keycode == old_keycode) { | |
d8b4b582 | 240 | __set_bit(old_keycode, dev->input_dev->keybit); |
9f470095 DT |
241 | break; |
242 | } | |
243 | } | |
244 | ||
245 | /* Possibly shrink the keytable, failure is not a problem */ | |
b088ba65 | 246 | ir_resize_table(rc_map, GFP_ATOMIC); |
9f470095 DT |
247 | } |
248 | ||
249 | return old_keycode; | |
250 | } | |
251 | ||
252 | /** | |
4c7b355d | 253 | * ir_establish_scancode() - set a keycode in the scancode->keycode table |
d8b4b582 | 254 | * @dev: the struct rc_dev device descriptor |
b088ba65 | 255 | * @rc_map: scancode table to be searched |
9f470095 DT |
256 | * @scancode: the desired scancode |
257 | * @resize: controls whether we allowed to resize the table to | |
25985edc | 258 | * accommodate not yet present scancodes |
9f470095 DT |
259 | * @return: index of the mapping containing scancode in question |
260 | * or -1U in case of failure. | |
f6fc5049 | 261 | * |
b088ba65 | 262 | * This routine is used to locate given scancode in rc_map. |
9f470095 DT |
263 | * If scancode is not yet present the routine will allocate a new slot |
264 | * for it. | |
f6fc5049 | 265 | */ |
d8b4b582 | 266 | static unsigned int ir_establish_scancode(struct rc_dev *dev, |
b088ba65 | 267 | struct rc_map *rc_map, |
9f470095 DT |
268 | unsigned int scancode, |
269 | bool resize) | |
f6fc5049 | 270 | { |
b3074c0a | 271 | unsigned int i; |
9dfe4e83 MCC |
272 | |
273 | /* | |
274 | * Unfortunately, some hardware-based IR decoders don't provide | |
275 | * all bits for the complete IR code. In general, they provide only | |
276 | * the command part of the IR code. Yet, as it is possible to replace | |
277 | * the provided IR with another one, it is needed to allow loading | |
d8b4b582 DH |
278 | * IR tables from other remotes. So, we support specifying a mask to |
279 | * indicate the valid bits of the scancodes. | |
9dfe4e83 | 280 | */ |
d8b4b582 DH |
281 | if (dev->scanmask) |
282 | scancode &= dev->scanmask; | |
b3074c0a DH |
283 | |
284 | /* First check if we already have a mapping for this ir command */ | |
b088ba65 MCC |
285 | for (i = 0; i < rc_map->len; i++) { |
286 | if (rc_map->scan[i].scancode == scancode) | |
9f470095 DT |
287 | return i; |
288 | ||
b3074c0a | 289 | /* Keytable is sorted from lowest to highest scancode */ |
b088ba65 | 290 | if (rc_map->scan[i].scancode >= scancode) |
b3074c0a | 291 | break; |
b3074c0a | 292 | } |
f6fc5049 | 293 | |
9f470095 | 294 | /* No previous mapping found, we might need to grow the table */ |
b088ba65 MCC |
295 | if (rc_map->size == rc_map->len) { |
296 | if (!resize || ir_resize_table(rc_map, GFP_ATOMIC)) | |
9f470095 DT |
297 | return -1U; |
298 | } | |
35438946 | 299 | |
9f470095 | 300 | /* i is the proper index to insert our new keycode */ |
b088ba65 MCC |
301 | if (i < rc_map->len) |
302 | memmove(&rc_map->scan[i + 1], &rc_map->scan[i], | |
2f4f58d6 | 303 | (rc_map->len - i) * sizeof(struct rc_map_table)); |
b088ba65 MCC |
304 | rc_map->scan[i].scancode = scancode; |
305 | rc_map->scan[i].keycode = KEY_RESERVED; | |
306 | rc_map->len++; | |
f6fc5049 | 307 | |
9f470095 | 308 | return i; |
f6fc5049 MCC |
309 | } |
310 | ||
ef53a115 | 311 | /** |
b3074c0a | 312 | * ir_setkeycode() - set a keycode in the scancode->keycode table |
d8b4b582 | 313 | * @idev: the struct input_dev device descriptor |
ef53a115 | 314 | * @scancode: the desired scancode |
b3074c0a DH |
315 | * @keycode: result |
316 | * @return: -EINVAL if the keycode could not be inserted, otherwise zero. | |
ef53a115 | 317 | * |
b3074c0a | 318 | * This routine is used to handle evdev EVIOCSKEY ioctl. |
ef53a115 | 319 | */ |
d8b4b582 | 320 | static int ir_setkeycode(struct input_dev *idev, |
9f470095 DT |
321 | const struct input_keymap_entry *ke, |
322 | unsigned int *old_keycode) | |
ef53a115 | 323 | { |
d8b4b582 | 324 | struct rc_dev *rdev = input_get_drvdata(idev); |
b088ba65 | 325 | struct rc_map *rc_map = &rdev->rc_map; |
9f470095 DT |
326 | unsigned int index; |
327 | unsigned int scancode; | |
dea8a39f | 328 | int retval = 0; |
9f470095 | 329 | unsigned long flags; |
ef53a115 | 330 | |
b088ba65 | 331 | spin_lock_irqsave(&rc_map->lock, flags); |
9f470095 DT |
332 | |
333 | if (ke->flags & INPUT_KEYMAP_BY_INDEX) { | |
334 | index = ke->index; | |
b088ba65 | 335 | if (index >= rc_map->len) { |
9f470095 DT |
336 | retval = -EINVAL; |
337 | goto out; | |
338 | } | |
339 | } else { | |
340 | retval = input_scancode_to_scalar(ke, &scancode); | |
341 | if (retval) | |
342 | goto out; | |
343 | ||
b088ba65 MCC |
344 | index = ir_establish_scancode(rdev, rc_map, scancode, true); |
345 | if (index >= rc_map->len) { | |
9f470095 DT |
346 | retval = -ENOMEM; |
347 | goto out; | |
348 | } | |
349 | } | |
350 | ||
b088ba65 | 351 | *old_keycode = ir_update_mapping(rdev, rc_map, index, ke->keycode); |
9f470095 DT |
352 | |
353 | out: | |
b088ba65 | 354 | spin_unlock_irqrestore(&rc_map->lock, flags); |
9f470095 | 355 | return retval; |
e97f4677 MCC |
356 | } |
357 | ||
358 | /** | |
b3074c0a | 359 | * ir_setkeytable() - sets several entries in the scancode->keycode table |
d8b4b582 | 360 | * @dev: the struct rc_dev device descriptor |
b088ba65 MCC |
361 | * @to: the struct rc_map to copy entries to |
362 | * @from: the struct rc_map to copy entries from | |
9f470095 | 363 | * @return: -ENOMEM if all keycodes could not be inserted, otherwise zero. |
e97f4677 | 364 | * |
b3074c0a | 365 | * This routine is used to handle table initialization. |
e97f4677 | 366 | */ |
d8b4b582 | 367 | static int ir_setkeytable(struct rc_dev *dev, |
b088ba65 | 368 | const struct rc_map *from) |
e97f4677 | 369 | { |
b088ba65 | 370 | struct rc_map *rc_map = &dev->rc_map; |
9f470095 DT |
371 | unsigned int i, index; |
372 | int rc; | |
373 | ||
b088ba65 | 374 | rc = ir_create_table(rc_map, from->name, |
52b66144 | 375 | from->rc_type, from->size); |
9f470095 DT |
376 | if (rc) |
377 | return rc; | |
378 | ||
379 | IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n", | |
b088ba65 | 380 | rc_map->size, rc_map->alloc); |
e97f4677 | 381 | |
b3074c0a | 382 | for (i = 0; i < from->size; i++) { |
b088ba65 | 383 | index = ir_establish_scancode(dev, rc_map, |
9f470095 | 384 | from->scan[i].scancode, false); |
b088ba65 | 385 | if (index >= rc_map->len) { |
9f470095 | 386 | rc = -ENOMEM; |
b3074c0a | 387 | break; |
9f470095 DT |
388 | } |
389 | ||
b088ba65 | 390 | ir_update_mapping(dev, rc_map, index, |
9f470095 | 391 | from->scan[i].keycode); |
e97f4677 | 392 | } |
9f470095 DT |
393 | |
394 | if (rc) | |
b088ba65 | 395 | ir_free_table(rc_map); |
9f470095 | 396 | |
b3074c0a | 397 | return rc; |
ef53a115 MCC |
398 | } |
399 | ||
9f470095 DT |
400 | /** |
401 | * ir_lookup_by_scancode() - locate mapping by scancode | |
b088ba65 | 402 | * @rc_map: the struct rc_map to search |
9f470095 DT |
403 | * @scancode: scancode to look for in the table |
404 | * @return: index in the table, -1U if not found | |
405 | * | |
406 | * This routine performs binary search in RC keykeymap table for | |
407 | * given scancode. | |
408 | */ | |
b088ba65 | 409 | static unsigned int ir_lookup_by_scancode(const struct rc_map *rc_map, |
9f470095 DT |
410 | unsigned int scancode) |
411 | { | |
0d07025e | 412 | int start = 0; |
b088ba65 | 413 | int end = rc_map->len - 1; |
0d07025e | 414 | int mid; |
9f470095 DT |
415 | |
416 | while (start <= end) { | |
417 | mid = (start + end) / 2; | |
b088ba65 | 418 | if (rc_map->scan[mid].scancode < scancode) |
9f470095 | 419 | start = mid + 1; |
b088ba65 | 420 | else if (rc_map->scan[mid].scancode > scancode) |
9f470095 DT |
421 | end = mid - 1; |
422 | else | |
423 | return mid; | |
424 | } | |
425 | ||
426 | return -1U; | |
427 | } | |
428 | ||
ef53a115 | 429 | /** |
b3074c0a | 430 | * ir_getkeycode() - get a keycode from the scancode->keycode table |
d8b4b582 | 431 | * @idev: the struct input_dev device descriptor |
ef53a115 | 432 | * @scancode: the desired scancode |
b3074c0a DH |
433 | * @keycode: used to return the keycode, if found, or KEY_RESERVED |
434 | * @return: always returns zero. | |
ef53a115 | 435 | * |
b3074c0a | 436 | * This routine is used to handle evdev EVIOCGKEY ioctl. |
ef53a115 | 437 | */ |
d8b4b582 | 438 | static int ir_getkeycode(struct input_dev *idev, |
9f470095 | 439 | struct input_keymap_entry *ke) |
ef53a115 | 440 | { |
d8b4b582 | 441 | struct rc_dev *rdev = input_get_drvdata(idev); |
b088ba65 | 442 | struct rc_map *rc_map = &rdev->rc_map; |
2f4f58d6 | 443 | struct rc_map_table *entry; |
9f470095 DT |
444 | unsigned long flags; |
445 | unsigned int index; | |
446 | unsigned int scancode; | |
447 | int retval; | |
ef53a115 | 448 | |
b088ba65 | 449 | spin_lock_irqsave(&rc_map->lock, flags); |
9f470095 DT |
450 | |
451 | if (ke->flags & INPUT_KEYMAP_BY_INDEX) { | |
452 | index = ke->index; | |
453 | } else { | |
454 | retval = input_scancode_to_scalar(ke, &scancode); | |
455 | if (retval) | |
456 | goto out; | |
457 | ||
b088ba65 | 458 | index = ir_lookup_by_scancode(rc_map, scancode); |
9f470095 DT |
459 | } |
460 | ||
54e74b87 DT |
461 | if (index < rc_map->len) { |
462 | entry = &rc_map->scan[index]; | |
463 | ||
464 | ke->index = index; | |
465 | ke->keycode = entry->keycode; | |
466 | ke->len = sizeof(entry->scancode); | |
467 | memcpy(ke->scancode, &entry->scancode, sizeof(entry->scancode)); | |
468 | ||
469 | } else if (!(ke->flags & INPUT_KEYMAP_BY_INDEX)) { | |
470 | /* | |
471 | * We do not really know the valid range of scancodes | |
472 | * so let's respond with KEY_RESERVED to anything we | |
473 | * do not have mapping for [yet]. | |
474 | */ | |
475 | ke->index = index; | |
476 | ke->keycode = KEY_RESERVED; | |
477 | } else { | |
9f470095 DT |
478 | retval = -EINVAL; |
479 | goto out; | |
e97f4677 MCC |
480 | } |
481 | ||
47c5ba53 DT |
482 | retval = 0; |
483 | ||
9f470095 | 484 | out: |
b088ba65 | 485 | spin_unlock_irqrestore(&rc_map->lock, flags); |
9f470095 | 486 | return retval; |
ef53a115 MCC |
487 | } |
488 | ||
489 | /** | |
ca86674b | 490 | * rc_g_keycode_from_table() - gets the keycode that corresponds to a scancode |
d8b4b582 DH |
491 | * @dev: the struct rc_dev descriptor of the device |
492 | * @scancode: the scancode to look for | |
493 | * @return: the corresponding keycode, or KEY_RESERVED | |
ef53a115 | 494 | * |
d8b4b582 DH |
495 | * This routine is used by drivers which need to convert a scancode to a |
496 | * keycode. Normally it should not be used since drivers should have no | |
497 | * interest in keycodes. | |
ef53a115 | 498 | */ |
ca86674b | 499 | u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode) |
ef53a115 | 500 | { |
b088ba65 | 501 | struct rc_map *rc_map = &dev->rc_map; |
9f470095 DT |
502 | unsigned int keycode; |
503 | unsigned int index; | |
504 | unsigned long flags; | |
505 | ||
b088ba65 | 506 | spin_lock_irqsave(&rc_map->lock, flags); |
9f470095 | 507 | |
b088ba65 MCC |
508 | index = ir_lookup_by_scancode(rc_map, scancode); |
509 | keycode = index < rc_map->len ? | |
510 | rc_map->scan[index].keycode : KEY_RESERVED; | |
9f470095 | 511 | |
b088ba65 | 512 | spin_unlock_irqrestore(&rc_map->lock, flags); |
ef53a115 | 513 | |
35438946 MCC |
514 | if (keycode != KEY_RESERVED) |
515 | IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n", | |
d8b4b582 | 516 | dev->input_name, scancode, keycode); |
9f470095 | 517 | |
b3074c0a | 518 | return keycode; |
ef53a115 | 519 | } |
ca86674b | 520 | EXPORT_SYMBOL_GPL(rc_g_keycode_from_table); |
ef53a115 | 521 | |
6660de56 | 522 | /** |
62c65031 | 523 | * ir_do_keyup() - internal function to signal the release of a keypress |
d8b4b582 | 524 | * @dev: the struct rc_dev descriptor of the device |
6660de56 | 525 | * |
62c65031 DH |
526 | * This function is used internally to release a keypress, it must be |
527 | * called with keylock held. | |
a374fef4 | 528 | */ |
d8b4b582 | 529 | static void ir_do_keyup(struct rc_dev *dev) |
a374fef4 | 530 | { |
d8b4b582 | 531 | if (!dev->keypressed) |
a374fef4 DH |
532 | return; |
533 | ||
d8b4b582 DH |
534 | IR_dprintk(1, "keyup key 0x%04x\n", dev->last_keycode); |
535 | input_report_key(dev->input_dev, dev->last_keycode, 0); | |
536 | input_sync(dev->input_dev); | |
537 | dev->keypressed = false; | |
a374fef4 | 538 | } |
62c65031 DH |
539 | |
540 | /** | |
ca86674b | 541 | * rc_keyup() - signals the release of a keypress |
d8b4b582 | 542 | * @dev: the struct rc_dev descriptor of the device |
62c65031 DH |
543 | * |
544 | * This routine is used to signal that a key has been released on the | |
545 | * remote control. | |
546 | */ | |
ca86674b | 547 | void rc_keyup(struct rc_dev *dev) |
62c65031 DH |
548 | { |
549 | unsigned long flags; | |
62c65031 | 550 | |
d8b4b582 DH |
551 | spin_lock_irqsave(&dev->keylock, flags); |
552 | ir_do_keyup(dev); | |
553 | spin_unlock_irqrestore(&dev->keylock, flags); | |
62c65031 | 554 | } |
ca86674b | 555 | EXPORT_SYMBOL_GPL(rc_keyup); |
a374fef4 DH |
556 | |
557 | /** | |
558 | * ir_timer_keyup() - generates a keyup event after a timeout | |
d8b4b582 | 559 | * @cookie: a pointer to the struct rc_dev for the device |
a374fef4 DH |
560 | * |
561 | * This routine will generate a keyup event some time after a keydown event | |
562 | * is generated when no further activity has been detected. | |
6660de56 | 563 | */ |
a374fef4 | 564 | static void ir_timer_keyup(unsigned long cookie) |
6660de56 | 565 | { |
d8b4b582 | 566 | struct rc_dev *dev = (struct rc_dev *)cookie; |
a374fef4 DH |
567 | unsigned long flags; |
568 | ||
569 | /* | |
570 | * ir->keyup_jiffies is used to prevent a race condition if a | |
571 | * hardware interrupt occurs at this point and the keyup timer | |
572 | * event is moved further into the future as a result. | |
573 | * | |
574 | * The timer will then be reactivated and this function called | |
575 | * again in the future. We need to exit gracefully in that case | |
576 | * to allow the input subsystem to do its auto-repeat magic or | |
577 | * a keyup event might follow immediately after the keydown. | |
578 | */ | |
d8b4b582 DH |
579 | spin_lock_irqsave(&dev->keylock, flags); |
580 | if (time_is_before_eq_jiffies(dev->keyup_jiffies)) | |
581 | ir_do_keyup(dev); | |
582 | spin_unlock_irqrestore(&dev->keylock, flags); | |
a374fef4 DH |
583 | } |
584 | ||
585 | /** | |
ca86674b | 586 | * rc_repeat() - signals that a key is still pressed |
d8b4b582 | 587 | * @dev: the struct rc_dev descriptor of the device |
a374fef4 DH |
588 | * |
589 | * This routine is used by IR decoders when a repeat message which does | |
590 | * not include the necessary bits to reproduce the scancode has been | |
591 | * received. | |
592 | */ | |
ca86674b | 593 | void rc_repeat(struct rc_dev *dev) |
a374fef4 DH |
594 | { |
595 | unsigned long flags; | |
6660de56 | 596 | |
d8b4b582 | 597 | spin_lock_irqsave(&dev->keylock, flags); |
a374fef4 | 598 | |
d8b4b582 | 599 | input_event(dev->input_dev, EV_MSC, MSC_SCAN, dev->last_scancode); |
ed4d3876 | 600 | |
d8b4b582 | 601 | if (!dev->keypressed) |
a374fef4 | 602 | goto out; |
6660de56 | 603 | |
d8b4b582 DH |
604 | dev->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT); |
605 | mod_timer(&dev->timer_keyup, dev->keyup_jiffies); | |
a374fef4 DH |
606 | |
607 | out: | |
d8b4b582 | 608 | spin_unlock_irqrestore(&dev->keylock, flags); |
6660de56 | 609 | } |
ca86674b | 610 | EXPORT_SYMBOL_GPL(rc_repeat); |
6660de56 MCC |
611 | |
612 | /** | |
62c65031 | 613 | * ir_do_keydown() - internal function to process a keypress |
d8b4b582 | 614 | * @dev: the struct rc_dev descriptor of the device |
62c65031 DH |
615 | * @scancode: the scancode of the keypress |
616 | * @keycode: the keycode of the keypress | |
617 | * @toggle: the toggle value of the keypress | |
6660de56 | 618 | * |
62c65031 DH |
619 | * This function is used internally to register a keypress, it must be |
620 | * called with keylock held. | |
6660de56 | 621 | */ |
d8b4b582 | 622 | static void ir_do_keydown(struct rc_dev *dev, int scancode, |
62c65031 | 623 | u32 keycode, u8 toggle) |
6660de56 | 624 | { |
d8b4b582 | 625 | input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode); |
ed4d3876 | 626 | |
a374fef4 | 627 | /* Repeat event? */ |
d8b4b582 DH |
628 | if (dev->keypressed && |
629 | dev->last_scancode == scancode && | |
630 | dev->last_toggle == toggle) | |
62c65031 | 631 | return; |
6660de56 | 632 | |
a374fef4 | 633 | /* Release old keypress */ |
d8b4b582 | 634 | ir_do_keyup(dev); |
6660de56 | 635 | |
d8b4b582 DH |
636 | dev->last_scancode = scancode; |
637 | dev->last_toggle = toggle; | |
638 | dev->last_keycode = keycode; | |
a374fef4 DH |
639 | |
640 | if (keycode == KEY_RESERVED) | |
62c65031 | 641 | return; |
ed4d3876 | 642 | |
a374fef4 | 643 | /* Register a keypress */ |
d8b4b582 | 644 | dev->keypressed = true; |
a374fef4 | 645 | IR_dprintk(1, "%s: key down event, key 0x%04x, scancode 0x%04x\n", |
d8b4b582 DH |
646 | dev->input_name, keycode, scancode); |
647 | input_report_key(dev->input_dev, dev->last_keycode, 1); | |
648 | input_sync(dev->input_dev); | |
62c65031 | 649 | } |
6660de56 | 650 | |
62c65031 | 651 | /** |
ca86674b | 652 | * rc_keydown() - generates input event for a key press |
d8b4b582 | 653 | * @dev: the struct rc_dev descriptor of the device |
62c65031 DH |
654 | * @scancode: the scancode that we're seeking |
655 | * @toggle: the toggle value (protocol dependent, if the protocol doesn't | |
656 | * support toggle values, this should be set to zero) | |
657 | * | |
d8b4b582 DH |
658 | * This routine is used to signal that a key has been pressed on the |
659 | * remote control. | |
62c65031 | 660 | */ |
ca86674b | 661 | void rc_keydown(struct rc_dev *dev, int scancode, u8 toggle) |
62c65031 DH |
662 | { |
663 | unsigned long flags; | |
ca86674b | 664 | u32 keycode = rc_g_keycode_from_table(dev, scancode); |
62c65031 | 665 | |
d8b4b582 | 666 | spin_lock_irqsave(&dev->keylock, flags); |
62c65031 DH |
667 | ir_do_keydown(dev, scancode, keycode, toggle); |
668 | ||
d8b4b582 DH |
669 | if (dev->keypressed) { |
670 | dev->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT); | |
671 | mod_timer(&dev->timer_keyup, dev->keyup_jiffies); | |
62c65031 | 672 | } |
d8b4b582 | 673 | spin_unlock_irqrestore(&dev->keylock, flags); |
6660de56 | 674 | } |
ca86674b | 675 | EXPORT_SYMBOL_GPL(rc_keydown); |
6660de56 | 676 | |
62c65031 | 677 | /** |
ca86674b | 678 | * rc_keydown_notimeout() - generates input event for a key press without |
62c65031 | 679 | * an automatic keyup event at a later time |
d8b4b582 | 680 | * @dev: the struct rc_dev descriptor of the device |
62c65031 DH |
681 | * @scancode: the scancode that we're seeking |
682 | * @toggle: the toggle value (protocol dependent, if the protocol doesn't | |
683 | * support toggle values, this should be set to zero) | |
684 | * | |
d8b4b582 | 685 | * This routine is used to signal that a key has been pressed on the |
ca86674b | 686 | * remote control. The driver must manually call rc_keyup() at a later stage. |
62c65031 | 687 | */ |
ca86674b | 688 | void rc_keydown_notimeout(struct rc_dev *dev, int scancode, u8 toggle) |
62c65031 DH |
689 | { |
690 | unsigned long flags; | |
ca86674b | 691 | u32 keycode = rc_g_keycode_from_table(dev, scancode); |
62c65031 | 692 | |
d8b4b582 | 693 | spin_lock_irqsave(&dev->keylock, flags); |
62c65031 | 694 | ir_do_keydown(dev, scancode, keycode, toggle); |
d8b4b582 | 695 | spin_unlock_irqrestore(&dev->keylock, flags); |
62c65031 | 696 | } |
ca86674b | 697 | EXPORT_SYMBOL_GPL(rc_keydown_notimeout); |
62c65031 | 698 | |
d8b4b582 | 699 | static int ir_open(struct input_dev *idev) |
ef53a115 | 700 | { |
d8b4b582 | 701 | struct rc_dev *rdev = input_get_drvdata(idev); |
75543cce | 702 | |
d8b4b582 | 703 | return rdev->open(rdev); |
ef53a115 | 704 | } |
d4b778d3 | 705 | |
d8b4b582 | 706 | static void ir_close(struct input_dev *idev) |
f6fc5049 | 707 | { |
d8b4b582 | 708 | struct rc_dev *rdev = input_get_drvdata(idev); |
626cf697 | 709 | |
88fda561 HAT |
710 | if (rdev) |
711 | rdev->close(rdev); | |
f6fc5049 | 712 | } |
f6fc5049 | 713 | |
bc2a6c57 MCC |
714 | /* class for /sys/class/rc */ |
715 | static char *ir_devnode(struct device *dev, mode_t *mode) | |
716 | { | |
717 | return kasprintf(GFP_KERNEL, "rc/%s", dev_name(dev)); | |
718 | } | |
719 | ||
720 | static struct class ir_input_class = { | |
721 | .name = "rc", | |
722 | .devnode = ir_devnode, | |
723 | }; | |
724 | ||
725 | static struct { | |
726 | u64 type; | |
727 | char *name; | |
728 | } proto_names[] = { | |
52b66144 MCC |
729 | { RC_TYPE_UNKNOWN, "unknown" }, |
730 | { RC_TYPE_RC5, "rc-5" }, | |
731 | { RC_TYPE_NEC, "nec" }, | |
732 | { RC_TYPE_RC6, "rc-6" }, | |
733 | { RC_TYPE_JVC, "jvc" }, | |
734 | { RC_TYPE_SONY, "sony" }, | |
735 | { RC_TYPE_RC5_SZ, "rc-5-sz" }, | |
736 | { RC_TYPE_LIRC, "lirc" }, | |
b3003933 | 737 | { RC_TYPE_OTHER, "other" }, |
bc2a6c57 MCC |
738 | }; |
739 | ||
740 | #define PROTO_NONE "none" | |
741 | ||
742 | /** | |
743 | * show_protocols() - shows the current IR protocol(s) | |
d8b4b582 | 744 | * @device: the device descriptor |
bc2a6c57 MCC |
745 | * @mattr: the device attribute struct (unused) |
746 | * @buf: a pointer to the output buffer | |
747 | * | |
748 | * This routine is a callback routine for input read the IR protocol type(s). | |
749 | * it is trigged by reading /sys/class/rc/rc?/protocols. | |
750 | * It returns the protocol names of supported protocols. | |
751 | * Enabled protocols are printed in brackets. | |
752 | */ | |
d8b4b582 | 753 | static ssize_t show_protocols(struct device *device, |
bc2a6c57 MCC |
754 | struct device_attribute *mattr, char *buf) |
755 | { | |
d8b4b582 | 756 | struct rc_dev *dev = to_rc_dev(device); |
bc2a6c57 MCC |
757 | u64 allowed, enabled; |
758 | char *tmp = buf; | |
759 | int i; | |
760 | ||
761 | /* Device is being removed */ | |
d8b4b582 | 762 | if (!dev) |
bc2a6c57 MCC |
763 | return -EINVAL; |
764 | ||
d8b4b582 | 765 | if (dev->driver_type == RC_DRIVER_SCANCODE) { |
b088ba65 | 766 | enabled = dev->rc_map.rc_type; |
d8b4b582 DH |
767 | allowed = dev->allowed_protos; |
768 | } else { | |
769 | enabled = dev->raw->enabled_protocols; | |
bc2a6c57 | 770 | allowed = ir_raw_get_allowed_protocols(); |
d8b4b582 | 771 | } |
bc2a6c57 MCC |
772 | |
773 | IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n", | |
774 | (long long)allowed, | |
775 | (long long)enabled); | |
776 | ||
777 | for (i = 0; i < ARRAY_SIZE(proto_names); i++) { | |
778 | if (allowed & enabled & proto_names[i].type) | |
779 | tmp += sprintf(tmp, "[%s] ", proto_names[i].name); | |
780 | else if (allowed & proto_names[i].type) | |
781 | tmp += sprintf(tmp, "%s ", proto_names[i].name); | |
782 | } | |
783 | ||
784 | if (tmp != buf) | |
785 | tmp--; | |
786 | *tmp = '\n'; | |
787 | return tmp + 1 - buf; | |
788 | } | |
789 | ||
790 | /** | |
791 | * store_protocols() - changes the current IR protocol(s) | |
d8b4b582 | 792 | * @device: the device descriptor |
bc2a6c57 MCC |
793 | * @mattr: the device attribute struct (unused) |
794 | * @buf: a pointer to the input buffer | |
795 | * @len: length of the input buffer | |
796 | * | |
d8b4b582 | 797 | * This routine is for changing the IR protocol type. |
bc2a6c57 MCC |
798 | * It is trigged by writing to /sys/class/rc/rc?/protocols. |
799 | * Writing "+proto" will add a protocol to the list of enabled protocols. | |
800 | * Writing "-proto" will remove a protocol from the list of enabled protocols. | |
801 | * Writing "proto" will enable only "proto". | |
802 | * Writing "none" will disable all protocols. | |
803 | * Returns -EINVAL if an invalid protocol combination or unknown protocol name | |
804 | * is used, otherwise @len. | |
805 | */ | |
d8b4b582 | 806 | static ssize_t store_protocols(struct device *device, |
bc2a6c57 MCC |
807 | struct device_attribute *mattr, |
808 | const char *data, | |
809 | size_t len) | |
810 | { | |
d8b4b582 | 811 | struct rc_dev *dev = to_rc_dev(device); |
bc2a6c57 MCC |
812 | bool enable, disable; |
813 | const char *tmp; | |
814 | u64 type; | |
815 | u64 mask; | |
816 | int rc, i, count = 0; | |
817 | unsigned long flags; | |
818 | ||
819 | /* Device is being removed */ | |
d8b4b582 | 820 | if (!dev) |
bc2a6c57 MCC |
821 | return -EINVAL; |
822 | ||
d8b4b582 | 823 | if (dev->driver_type == RC_DRIVER_SCANCODE) |
b088ba65 | 824 | type = dev->rc_map.rc_type; |
d8b4b582 DH |
825 | else if (dev->raw) |
826 | type = dev->raw->enabled_protocols; | |
bc2a6c57 MCC |
827 | else { |
828 | IR_dprintk(1, "Protocol switching not supported\n"); | |
829 | return -EINVAL; | |
830 | } | |
831 | ||
832 | while ((tmp = strsep((char **) &data, " \n")) != NULL) { | |
833 | if (!*tmp) | |
834 | break; | |
835 | ||
836 | if (*tmp == '+') { | |
837 | enable = true; | |
838 | disable = false; | |
839 | tmp++; | |
840 | } else if (*tmp == '-') { | |
841 | enable = false; | |
842 | disable = true; | |
843 | tmp++; | |
844 | } else { | |
845 | enable = false; | |
846 | disable = false; | |
847 | } | |
848 | ||
849 | if (!enable && !disable && !strncasecmp(tmp, PROTO_NONE, sizeof(PROTO_NONE))) { | |
850 | tmp += sizeof(PROTO_NONE); | |
851 | mask = 0; | |
852 | count++; | |
853 | } else { | |
854 | for (i = 0; i < ARRAY_SIZE(proto_names); i++) { | |
0a91be40 | 855 | if (!strcasecmp(tmp, proto_names[i].name)) { |
bc2a6c57 MCC |
856 | tmp += strlen(proto_names[i].name); |
857 | mask = proto_names[i].type; | |
858 | break; | |
859 | } | |
860 | } | |
861 | if (i == ARRAY_SIZE(proto_names)) { | |
862 | IR_dprintk(1, "Unknown protocol: '%s'\n", tmp); | |
863 | return -EINVAL; | |
864 | } | |
865 | count++; | |
866 | } | |
867 | ||
868 | if (enable) | |
869 | type |= mask; | |
870 | else if (disable) | |
871 | type &= ~mask; | |
872 | else | |
873 | type = mask; | |
874 | } | |
875 | ||
876 | if (!count) { | |
877 | IR_dprintk(1, "Protocol not specified\n"); | |
878 | return -EINVAL; | |
879 | } | |
880 | ||
d8b4b582 DH |
881 | if (dev->change_protocol) { |
882 | rc = dev->change_protocol(dev, type); | |
bc2a6c57 MCC |
883 | if (rc < 0) { |
884 | IR_dprintk(1, "Error setting protocols to 0x%llx\n", | |
885 | (long long)type); | |
886 | return -EINVAL; | |
887 | } | |
888 | } | |
889 | ||
d8b4b582 | 890 | if (dev->driver_type == RC_DRIVER_SCANCODE) { |
b088ba65 MCC |
891 | spin_lock_irqsave(&dev->rc_map.lock, flags); |
892 | dev->rc_map.rc_type = type; | |
893 | spin_unlock_irqrestore(&dev->rc_map.lock, flags); | |
bc2a6c57 | 894 | } else { |
d8b4b582 | 895 | dev->raw->enabled_protocols = type; |
bc2a6c57 MCC |
896 | } |
897 | ||
898 | IR_dprintk(1, "Current protocol(s): 0x%llx\n", | |
899 | (long long)type); | |
900 | ||
901 | return len; | |
902 | } | |
903 | ||
d8b4b582 DH |
904 | static void rc_dev_release(struct device *device) |
905 | { | |
906 | struct rc_dev *dev = to_rc_dev(device); | |
907 | ||
908 | kfree(dev); | |
909 | module_put(THIS_MODULE); | |
910 | } | |
911 | ||
bc2a6c57 MCC |
912 | #define ADD_HOTPLUG_VAR(fmt, val...) \ |
913 | do { \ | |
914 | int err = add_uevent_var(env, fmt, val); \ | |
915 | if (err) \ | |
916 | return err; \ | |
917 | } while (0) | |
918 | ||
919 | static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env) | |
920 | { | |
d8b4b582 | 921 | struct rc_dev *dev = to_rc_dev(device); |
bc2a6c57 | 922 | |
b088ba65 MCC |
923 | if (dev->rc_map.name) |
924 | ADD_HOTPLUG_VAR("NAME=%s", dev->rc_map.name); | |
d8b4b582 DH |
925 | if (dev->driver_name) |
926 | ADD_HOTPLUG_VAR("DRV_NAME=%s", dev->driver_name); | |
bc2a6c57 MCC |
927 | |
928 | return 0; | |
929 | } | |
930 | ||
931 | /* | |
932 | * Static device attribute struct with the sysfs attributes for IR's | |
933 | */ | |
934 | static DEVICE_ATTR(protocols, S_IRUGO | S_IWUSR, | |
935 | show_protocols, store_protocols); | |
936 | ||
937 | static struct attribute *rc_dev_attrs[] = { | |
938 | &dev_attr_protocols.attr, | |
939 | NULL, | |
940 | }; | |
941 | ||
942 | static struct attribute_group rc_dev_attr_grp = { | |
943 | .attrs = rc_dev_attrs, | |
944 | }; | |
945 | ||
946 | static const struct attribute_group *rc_dev_attr_groups[] = { | |
947 | &rc_dev_attr_grp, | |
948 | NULL | |
949 | }; | |
950 | ||
951 | static struct device_type rc_dev_type = { | |
952 | .groups = rc_dev_attr_groups, | |
d8b4b582 | 953 | .release = rc_dev_release, |
bc2a6c57 MCC |
954 | .uevent = rc_dev_uevent, |
955 | }; | |
956 | ||
d8b4b582 | 957 | struct rc_dev *rc_allocate_device(void) |
bc2a6c57 | 958 | { |
d8b4b582 | 959 | struct rc_dev *dev; |
bc2a6c57 | 960 | |
d8b4b582 DH |
961 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
962 | if (!dev) | |
963 | return NULL; | |
964 | ||
965 | dev->input_dev = input_allocate_device(); | |
966 | if (!dev->input_dev) { | |
967 | kfree(dev); | |
968 | return NULL; | |
969 | } | |
970 | ||
aebd636b DT |
971 | dev->input_dev->getkeycode = ir_getkeycode; |
972 | dev->input_dev->setkeycode = ir_setkeycode; | |
d8b4b582 DH |
973 | input_set_drvdata(dev->input_dev, dev); |
974 | ||
b088ba65 | 975 | spin_lock_init(&dev->rc_map.lock); |
d8b4b582 DH |
976 | spin_lock_init(&dev->keylock); |
977 | setup_timer(&dev->timer_keyup, ir_timer_keyup, (unsigned long)dev); | |
bc2a6c57 | 978 | |
d8b4b582 DH |
979 | dev->dev.type = &rc_dev_type; |
980 | dev->dev.class = &ir_input_class; | |
981 | device_initialize(&dev->dev); | |
982 | ||
983 | __module_get(THIS_MODULE); | |
984 | return dev; | |
985 | } | |
986 | EXPORT_SYMBOL_GPL(rc_allocate_device); | |
987 | ||
988 | void rc_free_device(struct rc_dev *dev) | |
bc2a6c57 | 989 | { |
d8b4b582 DH |
990 | if (dev) { |
991 | input_free_device(dev->input_dev); | |
992 | put_device(&dev->dev); | |
993 | } | |
994 | } | |
995 | EXPORT_SYMBOL_GPL(rc_free_device); | |
996 | ||
997 | int rc_register_device(struct rc_dev *dev) | |
998 | { | |
999 | static atomic_t devno = ATOMIC_INIT(0); | |
b088ba65 | 1000 | struct rc_map *rc_map; |
bc2a6c57 | 1001 | const char *path; |
d8b4b582 | 1002 | int rc; |
bc2a6c57 | 1003 | |
d8b4b582 DH |
1004 | if (!dev || !dev->map_name) |
1005 | return -EINVAL; | |
bc2a6c57 | 1006 | |
d100e659 | 1007 | rc_map = rc_map_get(dev->map_name); |
b088ba65 | 1008 | if (!rc_map) |
d100e659 | 1009 | rc_map = rc_map_get(RC_MAP_EMPTY); |
b088ba65 | 1010 | if (!rc_map || !rc_map->scan || rc_map->size == 0) |
d8b4b582 DH |
1011 | return -EINVAL; |
1012 | ||
1013 | set_bit(EV_KEY, dev->input_dev->evbit); | |
1014 | set_bit(EV_REP, dev->input_dev->evbit); | |
1015 | set_bit(EV_MSC, dev->input_dev->evbit); | |
1016 | set_bit(MSC_SCAN, dev->input_dev->mscbit); | |
1017 | if (dev->open) | |
1018 | dev->input_dev->open = ir_open; | |
1019 | if (dev->close) | |
1020 | dev->input_dev->close = ir_close; | |
1021 | ||
1022 | dev->devno = (unsigned long)(atomic_inc_return(&devno) - 1); | |
1023 | dev_set_name(&dev->dev, "rc%ld", dev->devno); | |
1024 | dev_set_drvdata(&dev->dev, dev); | |
1025 | rc = device_add(&dev->dev); | |
1026 | if (rc) | |
bc2a6c57 | 1027 | return rc; |
bc2a6c57 | 1028 | |
b088ba65 | 1029 | rc = ir_setkeytable(dev, rc_map); |
d8b4b582 DH |
1030 | if (rc) |
1031 | goto out_dev; | |
1032 | ||
1033 | dev->input_dev->dev.parent = &dev->dev; | |
1034 | memcpy(&dev->input_dev->id, &dev->input_id, sizeof(dev->input_id)); | |
1035 | dev->input_dev->phys = dev->input_phys; | |
1036 | dev->input_dev->name = dev->input_name; | |
1037 | rc = input_register_device(dev->input_dev); | |
1038 | if (rc) | |
1039 | goto out_table; | |
bc2a6c57 | 1040 | |
d8b4b582 | 1041 | /* |
25985edc | 1042 | * Default delay of 250ms is too short for some protocols, especially |
d8b4b582 DH |
1043 | * since the timeout is currently set to 250ms. Increase it to 500ms, |
1044 | * to avoid wrong repetition of the keycodes. Note that this must be | |
1045 | * set after the call to input_register_device(). | |
1046 | */ | |
1047 | dev->input_dev->rep[REP_DELAY] = 500; | |
1048 | ||
1049 | path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL); | |
bc2a6c57 | 1050 | printk(KERN_INFO "%s: %s as %s\n", |
d8b4b582 DH |
1051 | dev_name(&dev->dev), |
1052 | dev->input_name ? dev->input_name : "Unspecified device", | |
bc2a6c57 MCC |
1053 | path ? path : "N/A"); |
1054 | kfree(path); | |
1055 | ||
d8b4b582 DH |
1056 | if (dev->driver_type == RC_DRIVER_IR_RAW) { |
1057 | rc = ir_raw_event_register(dev); | |
1058 | if (rc < 0) | |
1059 | goto out_input; | |
1060 | } | |
1061 | ||
1062 | if (dev->change_protocol) { | |
b088ba65 | 1063 | rc = dev->change_protocol(dev, rc_map->rc_type); |
d8b4b582 DH |
1064 | if (rc < 0) |
1065 | goto out_raw; | |
1066 | } | |
1067 | ||
1068 | IR_dprintk(1, "Registered rc%ld (driver: %s, remote: %s, mode %s)\n", | |
1069 | dev->devno, | |
1070 | dev->driver_name ? dev->driver_name : "unknown", | |
b088ba65 | 1071 | rc_map->name ? rc_map->name : "unknown", |
d8b4b582 DH |
1072 | dev->driver_type == RC_DRIVER_IR_RAW ? "raw" : "cooked"); |
1073 | ||
bc2a6c57 | 1074 | return 0; |
d8b4b582 DH |
1075 | |
1076 | out_raw: | |
1077 | if (dev->driver_type == RC_DRIVER_IR_RAW) | |
1078 | ir_raw_event_unregister(dev); | |
1079 | out_input: | |
1080 | input_unregister_device(dev->input_dev); | |
1081 | dev->input_dev = NULL; | |
1082 | out_table: | |
b088ba65 | 1083 | ir_free_table(&dev->rc_map); |
d8b4b582 DH |
1084 | out_dev: |
1085 | device_del(&dev->dev); | |
1086 | return rc; | |
bc2a6c57 | 1087 | } |
d8b4b582 | 1088 | EXPORT_SYMBOL_GPL(rc_register_device); |
bc2a6c57 | 1089 | |
d8b4b582 | 1090 | void rc_unregister_device(struct rc_dev *dev) |
bc2a6c57 | 1091 | { |
d8b4b582 DH |
1092 | if (!dev) |
1093 | return; | |
bc2a6c57 | 1094 | |
d8b4b582 | 1095 | del_timer_sync(&dev->timer_keyup); |
bc2a6c57 | 1096 | |
d8b4b582 DH |
1097 | if (dev->driver_type == RC_DRIVER_IR_RAW) |
1098 | ir_raw_event_unregister(dev); | |
1099 | ||
1100 | input_unregister_device(dev->input_dev); | |
1101 | dev->input_dev = NULL; | |
1102 | ||
b088ba65 | 1103 | ir_free_table(&dev->rc_map); |
d8b4b582 DH |
1104 | IR_dprintk(1, "Freed keycode table\n"); |
1105 | ||
1106 | device_unregister(&dev->dev); | |
bc2a6c57 | 1107 | } |
d8b4b582 | 1108 | EXPORT_SYMBOL_GPL(rc_unregister_device); |
bc2a6c57 MCC |
1109 | |
1110 | /* | |
1111 | * Init/exit code for the module. Basically, creates/removes /sys/class/rc | |
1112 | */ | |
1113 | ||
6bda9644 | 1114 | static int __init rc_core_init(void) |
bc2a6c57 MCC |
1115 | { |
1116 | int rc = class_register(&ir_input_class); | |
1117 | if (rc) { | |
6bda9644 | 1118 | printk(KERN_ERR "rc_core: unable to register rc class\n"); |
bc2a6c57 MCC |
1119 | return rc; |
1120 | } | |
1121 | ||
1122 | /* Initialize/load the decoders/keymap code that will be used */ | |
1123 | ir_raw_init(); | |
d100e659 | 1124 | rc_map_register(&empty_map); |
bc2a6c57 MCC |
1125 | |
1126 | return 0; | |
1127 | } | |
1128 | ||
6bda9644 | 1129 | static void __exit rc_core_exit(void) |
bc2a6c57 MCC |
1130 | { |
1131 | class_unregister(&ir_input_class); | |
d100e659 | 1132 | rc_map_unregister(&empty_map); |
bc2a6c57 MCC |
1133 | } |
1134 | ||
6bda9644 MCC |
1135 | module_init(rc_core_init); |
1136 | module_exit(rc_core_exit); | |
bc2a6c57 | 1137 | |
6bda9644 MCC |
1138 | int rc_core_debug; /* ir_debug level (0,1,2) */ |
1139 | EXPORT_SYMBOL_GPL(rc_core_debug); | |
1140 | module_param_named(debug, rc_core_debug, int, 0644); | |
446e4a64 MCC |
1141 | |
1142 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); | |
1143 | MODULE_LICENSE("GPL"); |