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