USB: goku_udc: remove potential null dereference
[linux-2.6.git] / drivers / input / sparse-keymap.c
1 /*
2  * Generic support for sparse keymaps
3  *
4  * Copyright (c) 2009 Dmitry Torokhov
5  *
6  * Derived from wistron button driver:
7  * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
8  * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>
9  * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru>
10  *
11  * This program is free software; you can redistribute it and/or modify it
12  * under the terms of the GNU General Public License version 2 as published by
13  * the Free Software Foundation.
14  */
15
16 #include <linux/input.h>
17 #include <linux/input/sparse-keymap.h>
18
19 MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
20 MODULE_DESCRIPTION("Generic support for sparse keymaps");
21 MODULE_LICENSE("GPL v2");
22 MODULE_VERSION("0.1");
23
24 /**
25  * sparse_keymap_entry_from_scancode - perform sparse keymap lookup
26  * @dev: Input device using sparse keymap
27  * @code: Scan code
28  *
29  * This function is used to perform &struct key_entry lookup in an
30  * input device using sparse keymap.
31  */
32 struct key_entry *sparse_keymap_entry_from_scancode(struct input_dev *dev,
33                                                     unsigned int code)
34 {
35         struct key_entry *key;
36
37         for (key = dev->keycode; key->type != KE_END; key++)
38                 if (code == key->code)
39                         return key;
40
41         return NULL;
42 }
43 EXPORT_SYMBOL(sparse_keymap_entry_from_scancode);
44
45 /**
46  * sparse_keymap_entry_from_keycode - perform sparse keymap lookup
47  * @dev: Input device using sparse keymap
48  * @keycode: Key code
49  *
50  * This function is used to perform &struct key_entry lookup in an
51  * input device using sparse keymap.
52  */
53 struct key_entry *sparse_keymap_entry_from_keycode(struct input_dev *dev,
54                                                    unsigned int keycode)
55 {
56         struct key_entry *key;
57
58         for (key = dev->keycode; key->type != KE_END; key++)
59                 if (key->type == KE_KEY && keycode == key->keycode)
60                         return key;
61
62         return NULL;
63 }
64 EXPORT_SYMBOL(sparse_keymap_entry_from_keycode);
65
66 static int sparse_keymap_getkeycode(struct input_dev *dev,
67                                     unsigned int scancode,
68                                     unsigned int *keycode)
69 {
70         const struct key_entry *key =
71                         sparse_keymap_entry_from_scancode(dev, scancode);
72
73         if (key && key->type == KE_KEY) {
74                 *keycode = key->keycode;
75                 return 0;
76         }
77
78         return -EINVAL;
79 }
80
81 static int sparse_keymap_setkeycode(struct input_dev *dev,
82                                     unsigned int scancode,
83                                     unsigned int keycode)
84 {
85         struct key_entry *key;
86         int old_keycode;
87
88         if (keycode < 0 || keycode > KEY_MAX)
89                 return -EINVAL;
90
91         key = sparse_keymap_entry_from_scancode(dev, scancode);
92         if (key && key->type == KE_KEY) {
93                 old_keycode = key->keycode;
94                 key->keycode = keycode;
95                 set_bit(keycode, dev->keybit);
96                 if (!sparse_keymap_entry_from_keycode(dev, old_keycode))
97                         clear_bit(old_keycode, dev->keybit);
98                 return 0;
99         }
100
101         return -EINVAL;
102 }
103
104 /**
105  * sparse_keymap_setup - set up sparse keymap for an input device
106  * @dev: Input device
107  * @keymap: Keymap in form of array of &key_entry structures ending
108  *      with %KE_END type entry
109  * @setup: Function that can be used to adjust keymap entries
110  *      depending on device's deeds, may be %NULL
111  *
112  * The function calculates size and allocates copy of the original
113  * keymap after which sets up input device event bits appropriately.
114  * Before destroying input device allocated keymap should be freed
115  * with a call to sparse_keymap_free().
116  */
117 int sparse_keymap_setup(struct input_dev *dev,
118                         const struct key_entry *keymap,
119                         int (*setup)(struct input_dev *, struct key_entry *))
120 {
121         size_t map_size = 1; /* to account for the last KE_END entry */
122         const struct key_entry *e;
123         struct key_entry *map, *entry;
124         int i;
125         int error;
126
127         for (e = keymap; e->type != KE_END; e++)
128                 map_size++;
129
130         map = kcalloc(map_size, sizeof (struct key_entry), GFP_KERNEL);
131         if (!map)
132                 return -ENOMEM;
133
134         memcpy(map, keymap, map_size * sizeof (struct key_entry));
135
136         for (i = 0; i < map_size; i++) {
137                 entry = &map[i];
138
139                 if (setup) {
140                         error = setup(dev, entry);
141                         if (error)
142                                 goto err_out;
143                 }
144
145                 switch (entry->type) {
146                 case KE_KEY:
147                         __set_bit(EV_KEY, dev->evbit);
148                         __set_bit(entry->keycode, dev->keybit);
149                         break;
150
151                 case KE_SW:
152                         __set_bit(EV_SW, dev->evbit);
153                         __set_bit(entry->sw.code, dev->swbit);
154                         break;
155                 }
156         }
157
158         dev->keycode = map;
159         dev->keycodemax = map_size;
160         dev->getkeycode = sparse_keymap_getkeycode;
161         dev->setkeycode = sparse_keymap_setkeycode;
162
163         return 0;
164
165  err_out:
166         kfree(keymap);
167         return error;
168
169 }
170 EXPORT_SYMBOL(sparse_keymap_setup);
171
172 /**
173  * sparse_keymap_free - free memory allocated for sparse keymap
174  * @dev: Input device using sparse keymap
175  *
176  * This function is used to free memory allocated by sparse keymap
177  * in an input device that was set up by sparse_keymap_setup().
178  */
179 void sparse_keymap_free(struct input_dev *dev)
180 {
181         kfree(dev->keycode);
182         dev->keycode = NULL;
183         dev->keycodemax = 0;
184         dev->getkeycode = NULL;
185         dev->setkeycode = NULL;
186 }
187 EXPORT_SYMBOL(sparse_keymap_free);
188
189 /**
190  * sparse_keymap_report_entry - report event corresponding to given key entry
191  * @dev: Input device for which event should be reported
192  * @ke: key entry describing event
193  * @value: Value that should be reported (ignored by %KE_SW entries)
194  * @autorelease: Signals whether release event should be emitted for %KE_KEY
195  *      entries right after reporting press event, ignored by all other
196  *      entries
197  *
198  * This function is used to report input event described by given
199  * &struct key_entry.
200  */
201 void sparse_keymap_report_entry(struct input_dev *dev, const struct key_entry *ke,
202                                 unsigned int value, bool autorelease)
203 {
204         switch (ke->type) {
205         case KE_KEY:
206                 input_report_key(dev, ke->keycode, value);
207                 input_sync(dev);
208                 if (value && autorelease) {
209                         input_report_key(dev, ke->keycode, 0);
210                         input_sync(dev);
211                 }
212                 break;
213
214         case KE_SW:
215                 value = ke->sw.value;
216                 /* fall through */
217
218         case KE_VSW:
219                 input_report_switch(dev, ke->sw.code, value);
220                 break;
221         }
222 }
223 EXPORT_SYMBOL(sparse_keymap_report_entry);
224
225 /**
226  * sparse_keymap_report_event - report event corresponding to given scancode
227  * @dev: Input device using sparse keymap
228  * @code: Scan code
229  * @value: Value that should be reported (ignored by %KE_SW entries)
230  * @autorelease: Signals whether release event should be emitted for %KE_KEY
231  *      entries right after reporting press event, ignored by all other
232  *      entries
233  *
234  * This function is used to perform lookup in an input device using sparse
235  * keymap and report corresponding event. Returns %true if lookup was
236  * successful and %false otherwise.
237  */
238 bool sparse_keymap_report_event(struct input_dev *dev, unsigned int code,
239                                 unsigned int value, bool autorelease)
240 {
241         const struct key_entry *ke =
242                 sparse_keymap_entry_from_scancode(dev, code);
243
244         if (ke) {
245                 sparse_keymap_report_entry(dev, ke, value, autorelease);
246                 return true;
247         }
248
249         return false;
250 }
251 EXPORT_SYMBOL(sparse_keymap_report_event);
252