aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/keyboard.c71
1 files changed, 23 insertions, 48 deletions
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index cb8d691576da..3d211e8553f7 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -159,65 +159,41 @@ static int sysrq_alt_use;
159static int sysrq_alt; 159static int sysrq_alt;
160 160
161/* 161/*
162 * Translation of scancodes to keycodes. We set them on only the first attached 162 * Translation of scancodes to keycodes. We set them on only the first
163 * keyboard - for per-keyboard setting, /dev/input/event is more useful. 163 * keyboard in the list that accepts the scancode and keycode.
164 * Explanation for not choosing the first attached keyboard anymore:
165 * USB keyboards for example have two event devices: one for all "normal"
166 * keys and one for extra function keys (like "volume up", "make coffee",
167 * etc.). So this means that scancodes for the extra function keys won't
168 * be valid for the first event device, but will be for the second.
164 */ 169 */
165int getkeycode(unsigned int scancode) 170int getkeycode(unsigned int scancode)
166{ 171{
167 struct list_head *node; 172 struct input_handle *handle;
168 struct input_dev *dev = NULL; 173 int keycode;
174 int error = -ENODEV;
169 175
170 list_for_each(node, &kbd_handler.h_list) { 176 list_for_each_entry(handle, &kbd_handler.h_list, h_node) {
171 struct input_handle *handle = to_handle_h(node); 177 error = handle->dev->getkeycode(handle->dev, scancode, &keycode);
172 if (handle->dev->keycodesize) { 178 if (!error)
173 dev = handle->dev; 179 return keycode;
174 break;
175 }
176 } 180 }
177 181
178 if (!dev) 182 return error;
179 return -ENODEV;
180
181 if (scancode >= dev->keycodemax)
182 return -EINVAL;
183
184 return INPUT_KEYCODE(dev, scancode);
185} 183}
186 184
187int setkeycode(unsigned int scancode, unsigned int keycode) 185int setkeycode(unsigned int scancode, unsigned int keycode)
188{ 186{
189 struct list_head *node; 187 struct input_handle *handle;
190 struct input_dev *dev = NULL; 188 int error = -ENODEV;
191 unsigned int i, oldkey;
192 189
193 list_for_each(node, &kbd_handler.h_list) { 190 list_for_each_entry(handle, &kbd_handler.h_list, h_node) {
194 struct input_handle *handle = to_handle_h(node); 191 error = handle->dev->setkeycode(handle->dev, scancode, keycode);
195 if (handle->dev->keycodesize) { 192 if (!error)
196 dev = handle->dev;
197 break; 193 break;
198 }
199 } 194 }
200 195
201 if (!dev) 196 return error;
202 return -ENODEV;
203
204 if (scancode >= dev->keycodemax)
205 return -EINVAL;
206 if (keycode < 0 || keycode > KEY_MAX)
207 return -EINVAL;
208 if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8)))
209 return -EINVAL;
210
211 oldkey = SET_INPUT_KEYCODE(dev, scancode, keycode);
212
213 clear_bit(oldkey, dev->keybit);
214 set_bit(keycode, dev->keybit);
215
216 for (i = 0; i < dev->keycodemax; i++)
217 if (INPUT_KEYCODE(dev,i) == oldkey)
218 set_bit(oldkey, dev->keybit);
219
220 return 0;
221} 197}
222 198
223/* 199/*
@@ -225,10 +201,9 @@ int setkeycode(unsigned int scancode, unsigned int keycode)
225 */ 201 */
226static void kd_nosound(unsigned long ignored) 202static void kd_nosound(unsigned long ignored)
227{ 203{
228 struct list_head *node; 204 struct input_handle *handle;
229 205
230 list_for_each(node, &kbd_handler.h_list) { 206 list_for_each_entry(handle, &kbd_handler.h_list, h_node) {
231 struct input_handle *handle = to_handle_h(node);
232 if (test_bit(EV_SND, handle->dev->evbit)) { 207 if (test_bit(EV_SND, handle->dev->evbit)) {
233 if (test_bit(SND_TONE, handle->dev->sndbit)) 208 if (test_bit(SND_TONE, handle->dev->sndbit))
234 input_inject_event(handle, EV_SND, SND_TONE, 0); 209 input_inject_event(handle, EV_SND, SND_TONE, 0);