diff options
-rw-r--r-- | Documentation/input/appletouch.txt | 5 | ||||
-rw-r--r-- | drivers/input/evdev.c | 493 | ||||
-rw-r--r-- | drivers/input/gameport/Kconfig | 7 | ||||
-rw-r--r-- | drivers/input/misc/m68kspkr.c | 102 | ||||
-rw-r--r-- | drivers/input/misc/pcspkr.c | 86 | ||||
-rw-r--r-- | drivers/input/misc/sparcspkr.c | 162 | ||||
-rw-r--r-- | drivers/input/misc/wistron_btns.c | 133 | ||||
-rw-r--r-- | drivers/input/mouse/alps.c | 1 | ||||
-rw-r--r-- | drivers/input/mouse/lifebook.c | 7 | ||||
-rw-r--r-- | drivers/input/mouse/logips2pp.c | 2 | ||||
-rw-r--r-- | drivers/input/mouse/psmouse-base.c | 15 | ||||
-rw-r--r-- | drivers/input/mousedev.c | 10 | ||||
-rw-r--r-- | drivers/input/serio/ct82c710.c | 89 | ||||
-rw-r--r-- | drivers/input/serio/i8042-x86ia64io.h | 7 | ||||
-rw-r--r-- | drivers/input/serio/i8042.c | 116 | ||||
-rw-r--r-- | drivers/input/serio/maceps2.c | 68 | ||||
-rw-r--r-- | drivers/input/serio/q40kbd.c | 89 | ||||
-rw-r--r-- | drivers/usb/input/appletouch.c | 145 | ||||
-rw-r--r-- | drivers/usb/input/hid-debug.h | 1 |
19 files changed, 957 insertions, 581 deletions
diff --git a/Documentation/input/appletouch.txt b/Documentation/input/appletouch.txt index b48d11d0326d..4f7c633a76d2 100644 --- a/Documentation/input/appletouch.txt +++ b/Documentation/input/appletouch.txt | |||
@@ -3,7 +3,7 @@ Apple Touchpad Driver (appletouch) | |||
3 | Copyright (C) 2005 Stelian Pop <stelian@popies.net> | 3 | Copyright (C) 2005 Stelian Pop <stelian@popies.net> |
4 | 4 | ||
5 | appletouch is a Linux kernel driver for the USB touchpad found on post | 5 | appletouch is a Linux kernel driver for the USB touchpad found on post |
6 | February 2005 Apple Alu Powerbooks. | 6 | February 2005 and October 2005 Apple Aluminium Powerbooks. |
7 | 7 | ||
8 | This driver is derived from Johannes Berg's appletrackpad driver[1], but it has | 8 | This driver is derived from Johannes Berg's appletrackpad driver[1], but it has |
9 | been improved in some areas: | 9 | been improved in some areas: |
@@ -13,7 +13,8 @@ been improved in some areas: | |||
13 | 13 | ||
14 | Credits go to Johannes Berg for reverse-engineering the touchpad protocol, | 14 | Credits go to Johannes Berg for reverse-engineering the touchpad protocol, |
15 | Frank Arnold for further improvements, and Alex Harper for some additional | 15 | Frank Arnold for further improvements, and Alex Harper for some additional |
16 | information about the inner workings of the touchpad sensors. | 16 | information about the inner workings of the touchpad sensors. Michael |
17 | Hanselmann added support for the October 2005 models. | ||
17 | 18 | ||
18 | Usage: | 19 | Usage: |
19 | ------ | 20 | ------ |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 9f2352bd8348..0270d1ec9425 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -146,6 +146,7 @@ static int evdev_open(struct inode * inode, struct file * file) | |||
146 | } | 146 | } |
147 | 147 | ||
148 | #ifdef CONFIG_COMPAT | 148 | #ifdef CONFIG_COMPAT |
149 | |||
149 | struct input_event_compat { | 150 | struct input_event_compat { |
150 | struct compat_timeval time; | 151 | struct compat_timeval time; |
151 | __u16 type; | 152 | __u16 type; |
@@ -165,98 +166,107 @@ struct input_event_compat { | |||
165 | # define COMPAT_TEST test_thread_flag(TIF_32BIT) | 166 | # define COMPAT_TEST test_thread_flag(TIF_32BIT) |
166 | #endif | 167 | #endif |
167 | 168 | ||
168 | static ssize_t evdev_write_compat(struct file * file, const char __user * buffer, size_t count, loff_t *ppos) | 169 | static inline size_t evdev_event_size(void) |
169 | { | 170 | { |
170 | struct evdev_list *list = file->private_data; | 171 | return COMPAT_TEST ? |
171 | struct input_event_compat event; | 172 | sizeof(struct input_event_compat) : sizeof(struct input_event); |
172 | int retval = 0; | 173 | } |
173 | 174 | ||
174 | while (retval < count) { | 175 | static int evdev_event_from_user(const char __user *buffer, struct input_event *event) |
175 | if (copy_from_user(&event, buffer + retval, sizeof(struct input_event_compat))) | 176 | { |
177 | if (COMPAT_TEST) { | ||
178 | struct input_event_compat compat_event; | ||
179 | |||
180 | if (copy_from_user(&compat_event, buffer, sizeof(struct input_event_compat))) | ||
181 | return -EFAULT; | ||
182 | |||
183 | event->time.tv_sec = compat_event.time.tv_sec; | ||
184 | event->time.tv_usec = compat_event.time.tv_usec; | ||
185 | event->type = compat_event.type; | ||
186 | event->code = compat_event.code; | ||
187 | event->value = compat_event.value; | ||
188 | |||
189 | } else { | ||
190 | if (copy_from_user(event, buffer, sizeof(struct input_event))) | ||
176 | return -EFAULT; | 191 | return -EFAULT; |
177 | input_event(list->evdev->handle.dev, event.type, event.code, event.value); | ||
178 | retval += sizeof(struct input_event_compat); | ||
179 | } | 192 | } |
180 | 193 | ||
181 | return retval; | 194 | return 0; |
182 | } | 195 | } |
183 | #endif | ||
184 | 196 | ||
185 | static ssize_t evdev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos) | 197 | static int evdev_event_to_user(char __user *buffer, const struct input_event *event) |
186 | { | 198 | { |
187 | struct evdev_list *list = file->private_data; | 199 | if (COMPAT_TEST) { |
188 | struct input_event event; | 200 | struct input_event_compat compat_event; |
189 | int retval = 0; | ||
190 | |||
191 | if (!list->evdev->exist) return -ENODEV; | ||
192 | 201 | ||
193 | #ifdef CONFIG_COMPAT | 202 | compat_event.time.tv_sec = event->time.tv_sec; |
194 | if (COMPAT_TEST) | 203 | compat_event.time.tv_usec = event->time.tv_usec; |
195 | return evdev_write_compat(file, buffer, count, ppos); | 204 | compat_event.type = event->type; |
196 | #endif | 205 | compat_event.code = event->code; |
206 | compat_event.value = event->value; | ||
197 | 207 | ||
198 | while (retval < count) { | 208 | if (copy_to_user(buffer, &compat_event, sizeof(struct input_event_compat))) |
209 | return -EFAULT; | ||
199 | 210 | ||
200 | if (copy_from_user(&event, buffer + retval, sizeof(struct input_event))) | 211 | } else { |
212 | if (copy_to_user(buffer, event, sizeof(struct input_event))) | ||
201 | return -EFAULT; | 213 | return -EFAULT; |
202 | input_event(list->evdev->handle.dev, event.type, event.code, event.value); | ||
203 | retval += sizeof(struct input_event); | ||
204 | } | 214 | } |
205 | 215 | ||
206 | return retval; | 216 | return 0; |
207 | } | 217 | } |
208 | 218 | ||
209 | #ifdef CONFIG_COMPAT | 219 | #else |
210 | static ssize_t evdev_read_compat(struct file * file, char __user * buffer, size_t count, loff_t *ppos) | 220 | |
221 | static inline size_t evdev_event_size(void) | ||
211 | { | 222 | { |
212 | struct evdev_list *list = file->private_data; | 223 | return sizeof(struct input_event); |
213 | int retval; | 224 | } |
214 | 225 | ||
215 | if (count < sizeof(struct input_event_compat)) | 226 | static int evdev_event_from_user(const char __user *buffer, struct input_event *event) |
216 | return -EINVAL; | 227 | { |
228 | if (copy_from_user(event, buffer, sizeof(struct input_event))) | ||
229 | return -EFAULT; | ||
217 | 230 | ||
218 | if (list->head == list->tail && list->evdev->exist && (file->f_flags & O_NONBLOCK)) | 231 | return 0; |
219 | return -EAGAIN; | 232 | } |
220 | 233 | ||
221 | retval = wait_event_interruptible(list->evdev->wait, | 234 | static int evdev_event_to_user(char __user *buffer, const struct input_event *event) |
222 | list->head != list->tail || (!list->evdev->exist)); | 235 | { |
236 | if (copy_to_user(buffer, event, sizeof(struct input_event))) | ||
237 | return -EFAULT; | ||
223 | 238 | ||
224 | if (retval) | 239 | return 0; |
225 | return retval; | 240 | } |
241 | |||
242 | #endif /* CONFIG_COMPAT */ | ||
243 | |||
244 | static ssize_t evdev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos) | ||
245 | { | ||
246 | struct evdev_list *list = file->private_data; | ||
247 | struct input_event event; | ||
248 | int retval = 0; | ||
226 | 249 | ||
227 | if (!list->evdev->exist) | 250 | if (!list->evdev->exist) |
228 | return -ENODEV; | 251 | return -ENODEV; |
229 | 252 | ||
230 | while (list->head != list->tail && retval + sizeof(struct input_event_compat) <= count) { | 253 | while (retval < count) { |
231 | struct input_event *event = (struct input_event *) list->buffer + list->tail; | 254 | |
232 | struct input_event_compat event_compat; | 255 | if (evdev_event_from_user(buffer + retval, &event)) |
233 | event_compat.time.tv_sec = event->time.tv_sec; | 256 | return -EFAULT; |
234 | event_compat.time.tv_usec = event->time.tv_usec; | 257 | input_event(list->evdev->handle.dev, event.type, event.code, event.value); |
235 | event_compat.type = event->type; | 258 | retval += evdev_event_size(); |
236 | event_compat.code = event->code; | ||
237 | event_compat.value = event->value; | ||
238 | |||
239 | if (copy_to_user(buffer + retval, &event_compat, | ||
240 | sizeof(struct input_event_compat))) return -EFAULT; | ||
241 | list->tail = (list->tail + 1) & (EVDEV_BUFFER_SIZE - 1); | ||
242 | retval += sizeof(struct input_event_compat); | ||
243 | } | 259 | } |
244 | 260 | ||
245 | return retval; | 261 | return retval; |
246 | } | 262 | } |
247 | #endif | ||
248 | 263 | ||
249 | static ssize_t evdev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos) | 264 | static ssize_t evdev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos) |
250 | { | 265 | { |
251 | struct evdev_list *list = file->private_data; | 266 | struct evdev_list *list = file->private_data; |
252 | int retval; | 267 | int retval; |
253 | 268 | ||
254 | #ifdef CONFIG_COMPAT | 269 | if (count < evdev_event_size()) |
255 | if (COMPAT_TEST) | ||
256 | return evdev_read_compat(file, buffer, count, ppos); | ||
257 | #endif | ||
258 | |||
259 | if (count < sizeof(struct input_event)) | ||
260 | return -EINVAL; | 270 | return -EINVAL; |
261 | 271 | ||
262 | if (list->head == list->tail && list->evdev->exist && (file->f_flags & O_NONBLOCK)) | 272 | if (list->head == list->tail && list->evdev->exist && (file->f_flags & O_NONBLOCK)) |
@@ -271,11 +281,15 @@ static ssize_t evdev_read(struct file * file, char __user * buffer, size_t count | |||
271 | if (!list->evdev->exist) | 281 | if (!list->evdev->exist) |
272 | return -ENODEV; | 282 | return -ENODEV; |
273 | 283 | ||
274 | while (list->head != list->tail && retval + sizeof(struct input_event) <= count) { | 284 | while (list->head != list->tail && retval + evdev_event_size() <= count) { |
275 | if (copy_to_user(buffer + retval, list->buffer + list->tail, | 285 | |
276 | sizeof(struct input_event))) return -EFAULT; | 286 | struct input_event *event = (struct input_event *) list->buffer + list->tail; |
287 | |||
288 | if (evdev_event_to_user(buffer + retval, event)) | ||
289 | return -EFAULT; | ||
290 | |||
277 | list->tail = (list->tail + 1) & (EVDEV_BUFFER_SIZE - 1); | 291 | list->tail = (list->tail + 1) & (EVDEV_BUFFER_SIZE - 1); |
278 | retval += sizeof(struct input_event); | 292 | retval += evdev_event_size(); |
279 | } | 293 | } |
280 | 294 | ||
281 | return retval; | 295 | return retval; |
@@ -290,17 +304,95 @@ static unsigned int evdev_poll(struct file *file, poll_table *wait) | |||
290 | (list->evdev->exist ? 0 : (POLLHUP | POLLERR)); | 304 | (list->evdev->exist ? 0 : (POLLHUP | POLLERR)); |
291 | } | 305 | } |
292 | 306 | ||
293 | static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 307 | #ifdef CONFIG_COMPAT |
308 | |||
309 | #define BITS_PER_LONG_COMPAT (sizeof(compat_long_t) * 8) | ||
310 | #define NBITS_COMPAT(x) ((((x) - 1) / BITS_PER_LONG_COMPAT) + 1) | ||
311 | |||
312 | #ifdef __BIG_ENDIAN | ||
313 | static int bits_to_user(unsigned long *bits, unsigned int maxbit, | ||
314 | unsigned int maxlen, void __user *p, int compat) | ||
315 | { | ||
316 | int len, i; | ||
317 | |||
318 | if (compat) { | ||
319 | len = NBITS_COMPAT(maxbit) * sizeof(compat_long_t); | ||
320 | if (len < maxlen) | ||
321 | len = maxlen; | ||
322 | |||
323 | for (i = 0; i < len / sizeof(compat_long_t); i++) | ||
324 | if (copy_to_user((compat_long_t __user *) p + i, | ||
325 | (compat_long_t *) bits + | ||
326 | i + 1 - ((i % 2) << 1), | ||
327 | sizeof(compat_long_t))) | ||
328 | return -EFAULT; | ||
329 | } else { | ||
330 | len = NBITS(maxbit) * sizeof(long); | ||
331 | if (len > maxlen) | ||
332 | len = maxlen; | ||
333 | |||
334 | if (copy_to_user(p, bits, len)) | ||
335 | return -EFAULT; | ||
336 | } | ||
337 | |||
338 | return len; | ||
339 | } | ||
340 | #else | ||
341 | static int bits_to_user(unsigned long *bits, unsigned int maxbit, | ||
342 | unsigned int maxlen, void __user *p, int compat) | ||
343 | { | ||
344 | int len = compat ? | ||
345 | NBITS_COMPAT(maxbit) * sizeof(compat_long_t) : | ||
346 | NBITS(maxbit) * sizeof(long); | ||
347 | |||
348 | if (len > maxlen) | ||
349 | len = maxlen; | ||
350 | |||
351 | return copy_to_user(p, bits, len) ? -EFAULT : len; | ||
352 | } | ||
353 | #endif /* __BIG_ENDIAN */ | ||
354 | |||
355 | #else | ||
356 | |||
357 | static int bits_to_user(unsigned long *bits, unsigned int maxbit, | ||
358 | unsigned int maxlen, void __user *p, int compat) | ||
359 | { | ||
360 | int len = NBITS(maxbit) * sizeof(long); | ||
361 | |||
362 | if (len > maxlen) | ||
363 | len = maxlen; | ||
364 | |||
365 | return copy_to_user(p, bits, len) ? -EFAULT : len; | ||
366 | } | ||
367 | |||
368 | #endif /* CONFIG_COMPAT */ | ||
369 | |||
370 | static int str_to_user(const char *str, unsigned int maxlen, void __user *p) | ||
371 | { | ||
372 | int len; | ||
373 | |||
374 | if (!str) | ||
375 | return -ENOENT; | ||
376 | |||
377 | len = strlen(str) + 1; | ||
378 | if (len > maxlen) | ||
379 | len = maxlen; | ||
380 | |||
381 | return copy_to_user(p, str, len) ? -EFAULT : len; | ||
382 | } | ||
383 | |||
384 | static long evdev_ioctl_handler(struct file *file, unsigned int cmd, | ||
385 | void __user *p, int compat_mode) | ||
294 | { | 386 | { |
295 | struct evdev_list *list = file->private_data; | 387 | struct evdev_list *list = file->private_data; |
296 | struct evdev *evdev = list->evdev; | 388 | struct evdev *evdev = list->evdev; |
297 | struct input_dev *dev = evdev->handle.dev; | 389 | struct input_dev *dev = evdev->handle.dev; |
298 | struct input_absinfo abs; | 390 | struct input_absinfo abs; |
299 | void __user *p = (void __user *)arg; | 391 | int __user *ip = (int __user *)p; |
300 | int __user *ip = (int __user *)arg; | ||
301 | int i, t, u, v; | 392 | int i, t, u, v; |
302 | 393 | ||
303 | if (!evdev->exist) return -ENODEV; | 394 | if (!evdev->exist) |
395 | return -ENODEV; | ||
304 | 396 | ||
305 | switch (cmd) { | 397 | switch (cmd) { |
306 | 398 | ||
@@ -308,26 +400,39 @@ static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
308 | return put_user(EV_VERSION, ip); | 400 | return put_user(EV_VERSION, ip); |
309 | 401 | ||
310 | case EVIOCGID: | 402 | case EVIOCGID: |
311 | return copy_to_user(p, &dev->id, sizeof(struct input_id)) ? -EFAULT : 0; | 403 | if (copy_to_user(p, &dev->id, sizeof(struct input_id))) |
404 | return -EFAULT; | ||
405 | |||
406 | return 0; | ||
312 | 407 | ||
313 | case EVIOCGKEYCODE: | 408 | case EVIOCGKEYCODE: |
314 | if (get_user(t, ip)) return -EFAULT; | 409 | if (get_user(t, ip)) |
315 | if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) return -EINVAL; | 410 | return -EFAULT; |
316 | if (put_user(INPUT_KEYCODE(dev, t), ip + 1)) return -EFAULT; | 411 | if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) |
412 | return -EINVAL; | ||
413 | if (put_user(INPUT_KEYCODE(dev, t), ip + 1)) | ||
414 | return -EFAULT; | ||
317 | return 0; | 415 | return 0; |
318 | 416 | ||
319 | case EVIOCSKEYCODE: | 417 | case EVIOCSKEYCODE: |
320 | if (get_user(t, ip)) return -EFAULT; | 418 | if (get_user(t, ip)) |
321 | if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) return -EINVAL; | 419 | return -EFAULT; |
322 | if (get_user(v, ip + 1)) return -EFAULT; | 420 | if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) |
323 | if (v < 0 || v > KEY_MAX) return -EINVAL; | 421 | return -EINVAL; |
324 | if (dev->keycodesize < sizeof(v) && (v >> (dev->keycodesize * 8))) return -EINVAL; | 422 | if (get_user(v, ip + 1)) |
423 | return -EFAULT; | ||
424 | if (v < 0 || v > KEY_MAX) | ||
425 | return -EINVAL; | ||
426 | if (dev->keycodesize < sizeof(v) && (v >> (dev->keycodesize * 8))) | ||
427 | return -EINVAL; | ||
428 | |||
325 | u = SET_INPUT_KEYCODE(dev, t, v); | 429 | u = SET_INPUT_KEYCODE(dev, t, v); |
326 | clear_bit(u, dev->keybit); | 430 | clear_bit(u, dev->keybit); |
327 | set_bit(v, dev->keybit); | 431 | set_bit(v, dev->keybit); |
328 | for (i = 0; i < dev->keycodemax; i++) | 432 | for (i = 0; i < dev->keycodemax; i++) |
329 | if (INPUT_KEYCODE(dev,i) == u) | 433 | if (INPUT_KEYCODE(dev, i) == u) |
330 | set_bit(u, dev->keybit); | 434 | set_bit(u, dev->keybit); |
435 | |||
331 | return 0; | 436 | return 0; |
332 | 437 | ||
333 | case EVIOCSFF: | 438 | case EVIOCSFF: |
@@ -338,17 +443,17 @@ static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
338 | if (copy_from_user(&effect, p, sizeof(effect))) | 443 | if (copy_from_user(&effect, p, sizeof(effect))) |
339 | return -EFAULT; | 444 | return -EFAULT; |
340 | err = dev->upload_effect(dev, &effect); | 445 | err = dev->upload_effect(dev, &effect); |
341 | if (put_user(effect.id, &(((struct ff_effect __user *)arg)->id))) | 446 | if (put_user(effect.id, &(((struct ff_effect __user *)p)->id))) |
342 | return -EFAULT; | 447 | return -EFAULT; |
343 | return err; | 448 | return err; |
344 | } | 449 | } else |
345 | else return -ENOSYS; | 450 | return -ENOSYS; |
346 | 451 | ||
347 | case EVIOCRMFF: | 452 | case EVIOCRMFF: |
348 | if (dev->erase_effect) { | 453 | if (!dev->erase_effect) |
349 | return dev->erase_effect(dev, (int)arg); | 454 | return -ENOSYS; |
350 | } | 455 | |
351 | else return -ENOSYS; | 456 | return dev->erase_effect(dev, (int)(unsigned long) p); |
352 | 457 | ||
353 | case EVIOCGEFFECTS: | 458 | case EVIOCGEFFECTS: |
354 | if (put_user(dev->ff_effects_max, ip)) | 459 | if (put_user(dev->ff_effects_max, ip)) |
@@ -356,7 +461,7 @@ static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
356 | return 0; | 461 | return 0; |
357 | 462 | ||
358 | case EVIOCGRAB: | 463 | case EVIOCGRAB: |
359 | if (arg) { | 464 | if (p) { |
360 | if (evdev->grab) | 465 | if (evdev->grab) |
361 | return -EBUSY; | 466 | return -EBUSY; |
362 | if (input_grab_device(&evdev->handle)) | 467 | if (input_grab_device(&evdev->handle)) |
@@ -395,62 +500,33 @@ static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
395 | case EV_SW: bits = dev->swbit; len = SW_MAX; break; | 500 | case EV_SW: bits = dev->swbit; len = SW_MAX; break; |
396 | default: return -EINVAL; | 501 | default: return -EINVAL; |
397 | } | 502 | } |
398 | len = NBITS(len) * sizeof(long); | 503 | return bits_to_user(bits, len, _IOC_SIZE(cmd), p, compat_mode); |
399 | if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); | ||
400 | return copy_to_user(p, bits, len) ? -EFAULT : len; | ||
401 | } | 504 | } |
402 | 505 | ||
403 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0))) { | 506 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0))) |
404 | int len; | 507 | return bits_to_user(dev->key, KEY_MAX, _IOC_SIZE(cmd), |
405 | len = NBITS(KEY_MAX) * sizeof(long); | 508 | p, compat_mode); |
406 | if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); | ||
407 | return copy_to_user(p, dev->key, len) ? -EFAULT : len; | ||
408 | } | ||
409 | 509 | ||
410 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0))) { | 510 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0))) |
411 | int len; | 511 | return bits_to_user(dev->led, LED_MAX, _IOC_SIZE(cmd), |
412 | len = NBITS(LED_MAX) * sizeof(long); | 512 | p, compat_mode); |
413 | if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); | ||
414 | return copy_to_user(p, dev->led, len) ? -EFAULT : len; | ||
415 | } | ||
416 | 513 | ||
417 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0))) { | 514 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0))) |
418 | int len; | 515 | return bits_to_user(dev->snd, SND_MAX, _IOC_SIZE(cmd), |
419 | len = NBITS(SND_MAX) * sizeof(long); | 516 | p, compat_mode); |
420 | if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); | ||
421 | return copy_to_user(p, dev->snd, len) ? -EFAULT : len; | ||
422 | } | ||
423 | 517 | ||
424 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0))) { | 518 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0))) |
425 | int len; | 519 | return bits_to_user(dev->sw, SW_MAX, _IOC_SIZE(cmd), |
426 | len = NBITS(SW_MAX) * sizeof(long); | 520 | p, compat_mode); |
427 | if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); | ||
428 | return copy_to_user(p, dev->sw, len) ? -EFAULT : len; | ||
429 | } | ||
430 | 521 | ||
431 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) { | 522 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) |
432 | int len; | 523 | return str_to_user(dev->name, _IOC_SIZE(cmd), p); |
433 | if (!dev->name) return -ENOENT; | ||
434 | len = strlen(dev->name) + 1; | ||
435 | if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); | ||
436 | return copy_to_user(p, dev->name, len) ? -EFAULT : len; | ||
437 | } | ||
438 | 524 | ||
439 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) { | 525 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) |
440 | int len; | 526 | return str_to_user(dev->phys, _IOC_SIZE(cmd), p); |
441 | if (!dev->phys) return -ENOENT; | ||
442 | len = strlen(dev->phys) + 1; | ||
443 | if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); | ||
444 | return copy_to_user(p, dev->phys, len) ? -EFAULT : len; | ||
445 | } | ||
446 | 527 | ||
447 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0))) { | 528 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0))) |
448 | int len; | 529 | return str_to_user(dev->uniq, _IOC_SIZE(cmd), p); |
449 | if (!dev->uniq) return -ENOENT; | ||
450 | len = strlen(dev->uniq) + 1; | ||
451 | if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); | ||
452 | return copy_to_user(p, dev->uniq, len) ? -EFAULT : len; | ||
453 | } | ||
454 | 530 | ||
455 | if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) { | 531 | if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) { |
456 | 532 | ||
@@ -492,158 +568,15 @@ static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
492 | return -EINVAL; | 568 | return -EINVAL; |
493 | } | 569 | } |
494 | 570 | ||
495 | #ifdef CONFIG_COMPAT | 571 | static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
496 | 572 | { | |
497 | #define BITS_PER_LONG_COMPAT (sizeof(compat_long_t) * 8) | 573 | return evdev_ioctl_handler(file, cmd, (void __user *)arg, 0); |
498 | #define NBITS_COMPAT(x) ((((x)-1)/BITS_PER_LONG_COMPAT)+1) | 574 | } |
499 | #define OFF_COMPAT(x) ((x)%BITS_PER_LONG_COMPAT) | ||
500 | #define BIT_COMPAT(x) (1UL<<OFF_COMPAT(x)) | ||
501 | #define LONG_COMPAT(x) ((x)/BITS_PER_LONG_COMPAT) | ||
502 | #define test_bit_compat(bit, array) ((array[LONG_COMPAT(bit)] >> OFF_COMPAT(bit)) & 1) | ||
503 | |||
504 | #ifdef __BIG_ENDIAN | ||
505 | #define bit_to_user(bit, max) \ | ||
506 | do { \ | ||
507 | int i; \ | ||
508 | int len = NBITS_COMPAT((max)) * sizeof(compat_long_t); \ | ||
509 | if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); \ | ||
510 | for (i = 0; i < len / sizeof(compat_long_t); i++) \ | ||
511 | if (copy_to_user((compat_long_t __user *) p + i, \ | ||
512 | (compat_long_t*) (bit) + i + 1 - ((i % 2) << 1), \ | ||
513 | sizeof(compat_long_t))) \ | ||
514 | return -EFAULT; \ | ||
515 | return len; \ | ||
516 | } while (0) | ||
517 | #else | ||
518 | #define bit_to_user(bit, max) \ | ||
519 | do { \ | ||
520 | int len = NBITS_COMPAT((max)) * sizeof(compat_long_t); \ | ||
521 | if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); \ | ||
522 | return copy_to_user(p, (bit), len) ? -EFAULT : len; \ | ||
523 | } while (0) | ||
524 | #endif | ||
525 | 575 | ||
576 | #ifdef CONFIG_COMPAT | ||
526 | static long evdev_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg) | 577 | static long evdev_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg) |
527 | { | 578 | { |
528 | struct evdev_list *list = file->private_data; | 579 | return evdev_ioctl_handler(file, cmd, compat_ptr(arg), 1); |
529 | struct evdev *evdev = list->evdev; | ||
530 | struct input_dev *dev = evdev->handle.dev; | ||
531 | struct input_absinfo abs; | ||
532 | void __user *p = compat_ptr(arg); | ||
533 | |||
534 | if (!evdev->exist) return -ENODEV; | ||
535 | |||
536 | switch (cmd) { | ||
537 | |||
538 | case EVIOCGVERSION: | ||
539 | case EVIOCGID: | ||
540 | case EVIOCGKEYCODE: | ||
541 | case EVIOCSKEYCODE: | ||
542 | case EVIOCSFF: | ||
543 | case EVIOCRMFF: | ||
544 | case EVIOCGEFFECTS: | ||
545 | case EVIOCGRAB: | ||
546 | return evdev_ioctl(file, cmd, (unsigned long) p); | ||
547 | |||
548 | default: | ||
549 | |||
550 | if (_IOC_TYPE(cmd) != 'E') | ||
551 | return -EINVAL; | ||
552 | |||
553 | if (_IOC_DIR(cmd) == _IOC_READ) { | ||
554 | |||
555 | if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0,0))) { | ||
556 | long *bits; | ||
557 | int max; | ||
558 | |||
559 | switch (_IOC_NR(cmd) & EV_MAX) { | ||
560 | case 0: bits = dev->evbit; max = EV_MAX; break; | ||
561 | case EV_KEY: bits = dev->keybit; max = KEY_MAX; break; | ||
562 | case EV_REL: bits = dev->relbit; max = REL_MAX; break; | ||
563 | case EV_ABS: bits = dev->absbit; max = ABS_MAX; break; | ||
564 | case EV_MSC: bits = dev->mscbit; max = MSC_MAX; break; | ||
565 | case EV_LED: bits = dev->ledbit; max = LED_MAX; break; | ||
566 | case EV_SND: bits = dev->sndbit; max = SND_MAX; break; | ||
567 | case EV_FF: bits = dev->ffbit; max = FF_MAX; break; | ||
568 | case EV_SW: bits = dev->swbit; max = SW_MAX; break; | ||
569 | default: return -EINVAL; | ||
570 | } | ||
571 | bit_to_user(bits, max); | ||
572 | } | ||
573 | |||
574 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0))) | ||
575 | bit_to_user(dev->key, KEY_MAX); | ||
576 | |||
577 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0))) | ||
578 | bit_to_user(dev->led, LED_MAX); | ||
579 | |||
580 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0))) | ||
581 | bit_to_user(dev->snd, SND_MAX); | ||
582 | |||
583 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0))) | ||
584 | bit_to_user(dev->sw, SW_MAX); | ||
585 | |||
586 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) { | ||
587 | int len; | ||
588 | if (!dev->name) return -ENOENT; | ||
589 | len = strlen(dev->name) + 1; | ||
590 | if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); | ||
591 | return copy_to_user(p, dev->name, len) ? -EFAULT : len; | ||
592 | } | ||
593 | |||
594 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) { | ||
595 | int len; | ||
596 | if (!dev->phys) return -ENOENT; | ||
597 | len = strlen(dev->phys) + 1; | ||
598 | if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); | ||
599 | return copy_to_user(p, dev->phys, len) ? -EFAULT : len; | ||
600 | } | ||
601 | |||
602 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0))) { | ||
603 | int len; | ||
604 | if (!dev->uniq) return -ENOENT; | ||
605 | len = strlen(dev->uniq) + 1; | ||
606 | if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); | ||
607 | return copy_to_user(p, dev->uniq, len) ? -EFAULT : len; | ||
608 | } | ||
609 | |||
610 | if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) { | ||
611 | |||
612 | int t = _IOC_NR(cmd) & ABS_MAX; | ||
613 | |||
614 | abs.value = dev->abs[t]; | ||
615 | abs.minimum = dev->absmin[t]; | ||
616 | abs.maximum = dev->absmax[t]; | ||
617 | abs.fuzz = dev->absfuzz[t]; | ||
618 | abs.flat = dev->absflat[t]; | ||
619 | |||
620 | if (copy_to_user(p, &abs, sizeof(struct input_absinfo))) | ||
621 | return -EFAULT; | ||
622 | |||
623 | return 0; | ||
624 | } | ||
625 | } | ||
626 | |||
627 | if (_IOC_DIR(cmd) == _IOC_WRITE) { | ||
628 | |||
629 | if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) { | ||
630 | |||
631 | int t = _IOC_NR(cmd) & ABS_MAX; | ||
632 | |||
633 | if (copy_from_user(&abs, p, sizeof(struct input_absinfo))) | ||
634 | return -EFAULT; | ||
635 | |||
636 | dev->abs[t] = abs.value; | ||
637 | dev->absmin[t] = abs.minimum; | ||
638 | dev->absmax[t] = abs.maximum; | ||
639 | dev->absfuzz[t] = abs.fuzz; | ||
640 | dev->absflat[t] = abs.flat; | ||
641 | |||
642 | return 0; | ||
643 | } | ||
644 | } | ||
645 | } | ||
646 | return -EINVAL; | ||
647 | } | 580 | } |
648 | #endif | 581 | #endif |
649 | 582 | ||
diff --git a/drivers/input/gameport/Kconfig b/drivers/input/gameport/Kconfig index 7524bd7d8b8f..d279454a5c9e 100644 --- a/drivers/input/gameport/Kconfig +++ b/drivers/input/gameport/Kconfig | |||
@@ -52,5 +52,12 @@ config GAMEPORT_EMU10K1 | |||
52 | config GAMEPORT_FM801 | 52 | config GAMEPORT_FM801 |
53 | tristate "ForteMedia FM801 gameport support" | 53 | tristate "ForteMedia FM801 gameport support" |
54 | depends on PCI | 54 | depends on PCI |
55 | help | ||
56 | Say Y here if you have ForteMedia FM801 PCI audio controller | ||
57 | (Abit AU10, Genius Sound Maker, HP Workstation zx2000, | ||
58 | and others), and want to use its gameport. | ||
59 | |||
60 | To compile this driver as a module, choose M here: the | ||
61 | module will be called fm801-gp. | ||
55 | 62 | ||
56 | endif | 63 | endif |
diff --git a/drivers/input/misc/m68kspkr.c b/drivers/input/misc/m68kspkr.c index 04489ad7702a..8d6c3837badb 100644 --- a/drivers/input/misc/m68kspkr.c +++ b/drivers/input/misc/m68kspkr.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/input.h> | 19 | #include <linux/input.h> |
20 | #include <linux/platform_device.h> | ||
20 | #include <asm/machdep.h> | 21 | #include <asm/machdep.h> |
21 | #include <asm/io.h> | 22 | #include <asm/io.h> |
22 | 23 | ||
@@ -24,7 +25,7 @@ MODULE_AUTHOR("Richard Zidlicky <rz@linux-m68k.org>"); | |||
24 | MODULE_DESCRIPTION("m68k beeper driver"); | 25 | MODULE_DESCRIPTION("m68k beeper driver"); |
25 | MODULE_LICENSE("GPL"); | 26 | MODULE_LICENSE("GPL"); |
26 | 27 | ||
27 | static struct input_dev *m68kspkr_dev; | 28 | static struct platform_device *m68kspkr_platform_device; |
28 | 29 | ||
29 | static int m68kspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 30 | static int m68kspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) |
30 | { | 31 | { |
@@ -47,36 +48,103 @@ static int m68kspkr_event(struct input_dev *dev, unsigned int type, unsigned int | |||
47 | return 0; | 48 | return 0; |
48 | } | 49 | } |
49 | 50 | ||
51 | static int __devinit m68kspkr_probe(struct platform_device *dev) | ||
52 | { | ||
53 | struct input_dev *input_dev; | ||
54 | int err; | ||
55 | |||
56 | input_dev = input_allocate_device(); | ||
57 | if (!input_dev) | ||
58 | return -ENOMEM; | ||
59 | |||
60 | input_dev->name = "m68k beeper"; | ||
61 | input_dev->phys = "m68k/generic"; | ||
62 | input_dev->id.bustype = BUS_HOST; | ||
63 | input_dev->id.vendor = 0x001f; | ||
64 | input_dev->id.product = 0x0001; | ||
65 | input_dev->id.version = 0x0100; | ||
66 | input_dev->cdev.dev = &dev->dev; | ||
67 | |||
68 | input_dev->evbit[0] = BIT(EV_SND); | ||
69 | input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); | ||
70 | input_dev->event = m68kspkr_event; | ||
71 | |||
72 | err = input_register_device(input_dev); | ||
73 | if (err) { | ||
74 | input_free_device(input_dev); | ||
75 | return err; | ||
76 | } | ||
77 | |||
78 | platform_set_drvdata(dev, input_dev); | ||
79 | |||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | static int __devexit m68kspkr_remove(struct platform_device *dev) | ||
84 | { | ||
85 | struct input_dev *input_dev = platform_get_drvdata(dev); | ||
86 | |||
87 | input_unregister_device(input_dev); | ||
88 | platform_set_drvdata(dev, NULL); | ||
89 | /* turn off the speaker */ | ||
90 | m68kspkr_event(NULL, EV_SND, SND_BELL, 0); | ||
91 | |||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | static void m68kspkr_shutdown(struct platform_device *dev) | ||
96 | { | ||
97 | /* turn off the speaker */ | ||
98 | m68kspkr_event(NULL, EV_SND, SND_BELL, 0); | ||
99 | } | ||
100 | |||
101 | static struct platform_driver m68kspkr_platform_driver = { | ||
102 | .driver = { | ||
103 | .name = "m68kspkr", | ||
104 | .owner = THIS_MODULE, | ||
105 | }, | ||
106 | .probe = m68kspkr_probe, | ||
107 | .remove = __devexit_p(m68kspkr_remove), | ||
108 | .shutdown = m68kspkr_shutdown, | ||
109 | }; | ||
110 | |||
50 | static int __init m68kspkr_init(void) | 111 | static int __init m68kspkr_init(void) |
51 | { | 112 | { |
52 | if (!mach_beep) { | 113 | int err; |
114 | |||
115 | if (!mach_beep) { | ||
53 | printk(KERN_INFO "m68kspkr: no lowlevel beep support\n"); | 116 | printk(KERN_INFO "m68kspkr: no lowlevel beep support\n"); |
54 | return -ENODEV; | 117 | return -ENODEV; |
55 | } | 118 | } |
56 | 119 | ||
57 | m68kspkr_dev = input_allocate_device(); | 120 | err = platform_driver_register(&m68kspkr_platform_driver); |
58 | if (!m68kspkr_dev) | 121 | if (err) |
59 | return -ENOMEM; | 122 | return err; |
60 | |||
61 | m68kspkr_dev->name = "m68k beeper"; | ||
62 | m68kspkr_dev->phys = "m68k/generic"; | ||
63 | m68kspkr_dev->id.bustype = BUS_HOST; | ||
64 | m68kspkr_dev->id.vendor = 0x001f; | ||
65 | m68kspkr_dev->id.product = 0x0001; | ||
66 | m68kspkr_dev->id.version = 0x0100; | ||
67 | 123 | ||
68 | m68kspkr_dev->evbit[0] = BIT(EV_SND); | 124 | m68kspkr_platform_device = platform_device_alloc("m68kspkr", -1); |
69 | m68kspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); | 125 | if (!m68kspkr_platform_device) { |
70 | m68kspkr_dev->event = m68kspkr_event; | 126 | err = -ENOMEM; |
127 | goto err_unregister_driver; | ||
128 | } | ||
71 | 129 | ||
72 | input_register_device(m68kspkr_dev); | 130 | err = platform_device_add(m68kspkr_platform_device); |
131 | if (err) | ||
132 | goto err_free_device; | ||
73 | 133 | ||
74 | return 0; | 134 | return 0; |
135 | |||
136 | err_free_device: | ||
137 | platform_device_put(m68kspkr_platform_device); | ||
138 | err_unregister_driver: | ||
139 | platform_driver_unregister(&m68kspkr_platform_driver); | ||
140 | |||
141 | return err; | ||
75 | } | 142 | } |
76 | 143 | ||
77 | static void __exit m68kspkr_exit(void) | 144 | static void __exit m68kspkr_exit(void) |
78 | { | 145 | { |
79 | input_unregister_device(m68kspkr_dev); | 146 | platform_device_unregister(m68kspkr_platform_device); |
147 | platform_driver_unregister(&m68kspkr_platform_driver); | ||
80 | } | 148 | } |
81 | 149 | ||
82 | module_init(m68kspkr_init); | 150 | module_init(m68kspkr_init); |
diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c index 68ac97f101b0..1ef477f4469c 100644 --- a/drivers/input/misc/pcspkr.c +++ b/drivers/input/misc/pcspkr.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/input.h> | 18 | #include <linux/input.h> |
19 | #include <linux/platform_device.h> | ||
19 | #include <asm/8253pit.h> | 20 | #include <asm/8253pit.h> |
20 | #include <asm/io.h> | 21 | #include <asm/io.h> |
21 | 22 | ||
@@ -23,8 +24,7 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); | |||
23 | MODULE_DESCRIPTION("PC Speaker beeper driver"); | 24 | MODULE_DESCRIPTION("PC Speaker beeper driver"); |
24 | MODULE_LICENSE("GPL"); | 25 | MODULE_LICENSE("GPL"); |
25 | 26 | ||
26 | static struct input_dev *pcspkr_dev; | 27 | static struct platform_device *pcspkr_platform_device; |
27 | |||
28 | static DEFINE_SPINLOCK(i8253_beep_lock); | 28 | static DEFINE_SPINLOCK(i8253_beep_lock); |
29 | 29 | ||
30 | static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 30 | static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) |
@@ -64,8 +64,11 @@ static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int c | |||
64 | return 0; | 64 | return 0; |
65 | } | 65 | } |
66 | 66 | ||
67 | static int __init pcspkr_init(void) | 67 | static int __devinit pcspkr_probe(struct platform_device *dev) |
68 | { | 68 | { |
69 | struct input_dev *pcspkr_dev; | ||
70 | int err; | ||
71 | |||
69 | pcspkr_dev = input_allocate_device(); | 72 | pcspkr_dev = input_allocate_device(); |
70 | if (!pcspkr_dev) | 73 | if (!pcspkr_dev) |
71 | return -ENOMEM; | 74 | return -ENOMEM; |
@@ -76,22 +79,93 @@ static int __init pcspkr_init(void) | |||
76 | pcspkr_dev->id.vendor = 0x001f; | 79 | pcspkr_dev->id.vendor = 0x001f; |
77 | pcspkr_dev->id.product = 0x0001; | 80 | pcspkr_dev->id.product = 0x0001; |
78 | pcspkr_dev->id.version = 0x0100; | 81 | pcspkr_dev->id.version = 0x0100; |
82 | pcspkr_dev->cdev.dev = &dev->dev; | ||
79 | 83 | ||
80 | pcspkr_dev->evbit[0] = BIT(EV_SND); | 84 | pcspkr_dev->evbit[0] = BIT(EV_SND); |
81 | pcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); | 85 | pcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); |
82 | pcspkr_dev->event = pcspkr_event; | 86 | pcspkr_dev->event = pcspkr_event; |
83 | 87 | ||
84 | input_register_device(pcspkr_dev); | 88 | err = input_register_device(pcspkr_dev); |
89 | if (err) { | ||
90 | input_free_device(pcspkr_dev); | ||
91 | return err; | ||
92 | } | ||
93 | |||
94 | platform_set_drvdata(dev, pcspkr_dev); | ||
85 | 95 | ||
86 | return 0; | 96 | return 0; |
87 | } | 97 | } |
88 | 98 | ||
89 | static void __exit pcspkr_exit(void) | 99 | static int __devexit pcspkr_remove(struct platform_device *dev) |
100 | { | ||
101 | struct input_dev *pcspkr_dev = platform_get_drvdata(dev); | ||
102 | |||
103 | input_unregister_device(pcspkr_dev); | ||
104 | platform_set_drvdata(dev, NULL); | ||
105 | /* turn off the speaker */ | ||
106 | pcspkr_event(NULL, EV_SND, SND_BELL, 0); | ||
107 | |||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | static int pcspkr_suspend(struct platform_device *dev, pm_message_t state) | ||
112 | { | ||
113 | pcspkr_event(NULL, EV_SND, SND_BELL, 0); | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | static void pcspkr_shutdown(struct platform_device *dev) | ||
90 | { | 119 | { |
91 | input_unregister_device(pcspkr_dev); | ||
92 | /* turn off the speaker */ | 120 | /* turn off the speaker */ |
93 | pcspkr_event(NULL, EV_SND, SND_BELL, 0); | 121 | pcspkr_event(NULL, EV_SND, SND_BELL, 0); |
94 | } | 122 | } |
95 | 123 | ||
124 | static struct platform_driver pcspkr_platform_driver = { | ||
125 | .driver = { | ||
126 | .name = "pcspkr", | ||
127 | .owner = THIS_MODULE, | ||
128 | }, | ||
129 | .probe = pcspkr_probe, | ||
130 | .remove = __devexit_p(pcspkr_remove), | ||
131 | .suspend = pcspkr_suspend, | ||
132 | .shutdown = pcspkr_shutdown, | ||
133 | }; | ||
134 | |||
135 | |||
136 | static int __init pcspkr_init(void) | ||
137 | { | ||
138 | int err; | ||
139 | |||
140 | err = platform_driver_register(&pcspkr_platform_driver); | ||
141 | if (err) | ||
142 | return err; | ||
143 | |||
144 | pcspkr_platform_device = platform_device_alloc("pcspkr", -1); | ||
145 | if (!pcspkr_platform_device) { | ||
146 | err = -ENOMEM; | ||
147 | goto err_unregister_driver; | ||
148 | } | ||
149 | |||
150 | err = platform_device_add(pcspkr_platform_device); | ||
151 | if (err) | ||
152 | goto err_free_device; | ||
153 | |||
154 | return 0; | ||
155 | |||
156 | err_free_device: | ||
157 | platform_device_put(pcspkr_platform_device); | ||
158 | err_unregister_driver: | ||
159 | platform_driver_unregister(&pcspkr_platform_driver); | ||
160 | |||
161 | return err; | ||
162 | } | ||
163 | |||
164 | static void __exit pcspkr_exit(void) | ||
165 | { | ||
166 | platform_device_unregister(pcspkr_platform_device); | ||
167 | platform_driver_unregister(&pcspkr_platform_driver); | ||
168 | } | ||
169 | |||
96 | module_init(pcspkr_init); | 170 | module_init(pcspkr_init); |
97 | module_exit(pcspkr_exit); | 171 | module_exit(pcspkr_exit); |
diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c index 29d97b12be7a..f0fd2c4740f1 100644 --- a/drivers/input/misc/sparcspkr.c +++ b/drivers/input/misc/sparcspkr.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
11 | #include <linux/input.h> | 11 | #include <linux/input.h> |
12 | #include <linux/platform_device.h> | ||
12 | 13 | ||
13 | #include <asm/io.h> | 14 | #include <asm/io.h> |
14 | #include <asm/ebus.h> | 15 | #include <asm/ebus.h> |
@@ -20,22 +21,10 @@ MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); | |||
20 | MODULE_DESCRIPTION("Sparc Speaker beeper driver"); | 21 | MODULE_DESCRIPTION("Sparc Speaker beeper driver"); |
21 | MODULE_LICENSE("GPL"); | 22 | MODULE_LICENSE("GPL"); |
22 | 23 | ||
24 | const char *beep_name; | ||
23 | static unsigned long beep_iobase; | 25 | static unsigned long beep_iobase; |
24 | static struct input_dev *sparcspkr_dev; | 26 | static int (*beep_event)(struct input_dev *dev, unsigned int type, unsigned int code, int value); |
25 | 27 | static DEFINE_SPINLOCK(beep_lock); | |
26 | DEFINE_SPINLOCK(beep_lock); | ||
27 | |||
28 | static void __init init_sparcspkr_struct(void) | ||
29 | { | ||
30 | sparcspkr_dev->evbit[0] = BIT(EV_SND); | ||
31 | sparcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); | ||
32 | |||
33 | sparcspkr_dev->phys = "sparc/input0"; | ||
34 | sparcspkr_dev->id.bustype = BUS_ISA; | ||
35 | sparcspkr_dev->id.vendor = 0x001f; | ||
36 | sparcspkr_dev->id.product = 0x0001; | ||
37 | sparcspkr_dev->id.version = 0x0100; | ||
38 | } | ||
39 | 28 | ||
40 | static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 29 | static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) |
41 | { | 30 | { |
@@ -59,39 +48,16 @@ static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned in | |||
59 | /* EBUS speaker only has on/off state, the frequency does not | 48 | /* EBUS speaker only has on/off state, the frequency does not |
60 | * appear to be programmable. | 49 | * appear to be programmable. |
61 | */ | 50 | */ |
62 | if (count) { | 51 | if (beep_iobase & 0x2UL) |
63 | if (beep_iobase & 0x2UL) | 52 | outb(!!count, beep_iobase); |
64 | outb(1, beep_iobase); | 53 | else |
65 | else | 54 | outl(!!count, beep_iobase); |
66 | outl(1, beep_iobase); | ||
67 | } else { | ||
68 | if (beep_iobase & 0x2UL) | ||
69 | outb(0, beep_iobase); | ||
70 | else | ||
71 | outl(0, beep_iobase); | ||
72 | } | ||
73 | 55 | ||
74 | spin_unlock_irqrestore(&beep_lock, flags); | 56 | spin_unlock_irqrestore(&beep_lock, flags); |
75 | 57 | ||
76 | return 0; | 58 | return 0; |
77 | } | 59 | } |
78 | 60 | ||
79 | static int __init init_ebus_beep(struct linux_ebus_device *edev) | ||
80 | { | ||
81 | beep_iobase = edev->resource[0].start; | ||
82 | |||
83 | sparcspkr_dev = input_allocate_device(); | ||
84 | if (!sparcspkr_dev) | ||
85 | return -ENOMEM; | ||
86 | |||
87 | sparcspkr_dev->name = "Sparc EBUS Speaker"; | ||
88 | sparcspkr_dev->event = ebus_spkr_event; | ||
89 | |||
90 | input_register_device(sparcspkr_dev); | ||
91 | |||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | #ifdef CONFIG_SPARC64 | 61 | #ifdef CONFIG_SPARC64 |
96 | static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 62 | static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) |
97 | { | 63 | { |
@@ -129,30 +95,103 @@ static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int | |||
129 | 95 | ||
130 | return 0; | 96 | return 0; |
131 | } | 97 | } |
98 | #endif | ||
132 | 99 | ||
133 | static int __init init_isa_beep(struct sparc_isa_device *isa_dev) | 100 | static int __devinit sparcspkr_probe(struct platform_device *dev) |
134 | { | 101 | { |
135 | beep_iobase = isa_dev->resource.start; | 102 | struct input_dev *input_dev; |
103 | int error; | ||
136 | 104 | ||
137 | sparcspkr_dev = input_allocate_device(); | 105 | input_dev = input_allocate_device(); |
138 | if (!sparcspkr_dev) | 106 | if (!input_dev) |
139 | return -ENOMEM; | 107 | return -ENOMEM; |
140 | 108 | ||
141 | init_sparcspkr_struct(); | 109 | input_dev->name = beep_name; |
110 | input_dev->phys = "sparc/input0"; | ||
111 | input_dev->id.bustype = BUS_ISA; | ||
112 | input_dev->id.vendor = 0x001f; | ||
113 | input_dev->id.product = 0x0001; | ||
114 | input_dev->id.version = 0x0100; | ||
115 | input_dev->cdev.dev = &dev->dev; | ||
142 | 116 | ||
143 | sparcspkr_dev->name = "Sparc ISA Speaker"; | 117 | input_dev->evbit[0] = BIT(EV_SND); |
144 | sparcspkr_dev->event = isa_spkr_event; | 118 | input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); |
145 | 119 | ||
146 | input_register_device(sparcspkr_dev); | 120 | input_dev->event = beep_event; |
121 | |||
122 | error = input_register_device(input_dev); | ||
123 | if (error) { | ||
124 | input_free_device(input_dev); | ||
125 | return error; | ||
126 | } | ||
127 | |||
128 | platform_set_drvdata(dev, input_dev); | ||
147 | 129 | ||
148 | return 0; | 130 | return 0; |
149 | } | 131 | } |
150 | #endif | 132 | |
133 | static int __devexit sparcspkr_remove(struct platform_device *dev) | ||
134 | { | ||
135 | struct input_dev *input_dev = platform_get_drvdata(dev); | ||
136 | |||
137 | input_unregister_device(input_dev); | ||
138 | platform_set_drvdata(dev, NULL); | ||
139 | /* turn off the speaker */ | ||
140 | beep_event(NULL, EV_SND, SND_BELL, 0); | ||
141 | |||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | static void sparcspkr_shutdown(struct platform_device *dev) | ||
146 | { | ||
147 | /* turn off the speaker */ | ||
148 | beep_event(NULL, EV_SND, SND_BELL, 0); | ||
149 | } | ||
150 | |||
151 | static struct platform_driver sparcspkr_platform_driver = { | ||
152 | .driver = { | ||
153 | .name = "sparcspkr", | ||
154 | .owner = THIS_MODULE, | ||
155 | }, | ||
156 | .probe = sparcspkr_probe, | ||
157 | .remove = __devexit_p(sparcspkr_remove), | ||
158 | .shutdown = sparcspkr_shutdown, | ||
159 | }; | ||
160 | |||
161 | static struct platform_device *sparcspkr_platform_device; | ||
162 | |||
163 | static int __init sparcspkr_drv_init(void) | ||
164 | { | ||
165 | int error; | ||
166 | |||
167 | error = platform_driver_register(&sparcspkr_platform_driver); | ||
168 | if (error) | ||
169 | return error; | ||
170 | |||
171 | sparcspkr_platform_device = platform_device_alloc("sparcspkr", -1); | ||
172 | if (!sparcspkr_platform_device) { | ||
173 | error = -ENOMEM; | ||
174 | goto err_unregister_driver; | ||
175 | } | ||
176 | |||
177 | error = platform_device_add(sparcspkr_platform_device); | ||
178 | if (error) | ||
179 | goto err_free_device; | ||
180 | |||
181 | return 0; | ||
182 | |||
183 | err_free_device: | ||
184 | platform_device_put(sparcspkr_platform_device); | ||
185 | err_unregister_driver: | ||
186 | platform_driver_unregister(&sparcspkr_platform_driver); | ||
187 | |||
188 | return error; | ||
189 | } | ||
151 | 190 | ||
152 | static int __init sparcspkr_init(void) | 191 | static int __init sparcspkr_init(void) |
153 | { | 192 | { |
154 | struct linux_ebus *ebus; | 193 | struct linux_ebus *ebus; |
155 | struct linux_ebus_device *edev = NULL; | 194 | struct linux_ebus_device *edev; |
156 | #ifdef CONFIG_SPARC64 | 195 | #ifdef CONFIG_SPARC64 |
157 | struct sparc_isa_bridge *isa_br; | 196 | struct sparc_isa_bridge *isa_br; |
158 | struct sparc_isa_device *isa_dev; | 197 | struct sparc_isa_device *isa_dev; |
@@ -160,8 +199,12 @@ static int __init sparcspkr_init(void) | |||
160 | 199 | ||
161 | for_each_ebus(ebus) { | 200 | for_each_ebus(ebus) { |
162 | for_each_ebusdev(edev, ebus) { | 201 | for_each_ebusdev(edev, ebus) { |
163 | if (!strcmp(edev->prom_name, "beep")) | 202 | if (!strcmp(edev->prom_name, "beep")) { |
164 | return init_ebus_beep(edev); | 203 | beep_name = "Sparc EBUS Speaker"; |
204 | beep_event = ebus_spkr_event; | ||
205 | beep_iobase = edev->resource[0].start; | ||
206 | return sparcspkr_drv_init(); | ||
207 | } | ||
165 | } | 208 | } |
166 | } | 209 | } |
167 | #ifdef CONFIG_SPARC64 | 210 | #ifdef CONFIG_SPARC64 |
@@ -170,8 +213,12 @@ static int __init sparcspkr_init(void) | |||
170 | /* A hack, the beep device's base lives in | 213 | /* A hack, the beep device's base lives in |
171 | * the DMA isa node. | 214 | * the DMA isa node. |
172 | */ | 215 | */ |
173 | if (!strcmp(isa_dev->prom_name, "dma")) | 216 | if (!strcmp(isa_dev->prom_name, "dma")) { |
174 | return init_isa_beep(isa_dev); | 217 | beep_name = "Sparc ISA Speaker"; |
218 | beep_event = isa_spkr_event, | ||
219 | beep_iobase = isa_dev->resource.start; | ||
220 | return sparcspkr_drv_init(); | ||
221 | } | ||
175 | } | 222 | } |
176 | } | 223 | } |
177 | #endif | 224 | #endif |
@@ -181,7 +228,8 @@ static int __init sparcspkr_init(void) | |||
181 | 228 | ||
182 | static void __exit sparcspkr_exit(void) | 229 | static void __exit sparcspkr_exit(void) |
183 | { | 230 | { |
184 | input_unregister_device(sparcspkr_dev); | 231 | platform_device_unregister(sparcspkr_platform_device); |
232 | platform_driver_unregister(&sparcspkr_platform_driver); | ||
185 | } | 233 | } |
186 | 234 | ||
187 | module_init(sparcspkr_init); | 235 | module_init(sparcspkr_init); |
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index bac3085185fe..a05b8557842f 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c | |||
@@ -174,7 +174,7 @@ static u16 bios_pop_queue(void) | |||
174 | return regs.eax; | 174 | return regs.eax; |
175 | } | 175 | } |
176 | 176 | ||
177 | static void __init bios_attach(void) | 177 | static void __devinit bios_attach(void) |
178 | { | 178 | { |
179 | struct regs regs; | 179 | struct regs regs; |
180 | 180 | ||
@@ -194,7 +194,7 @@ static void bios_detach(void) | |||
194 | call_bios(®s); | 194 | call_bios(®s); |
195 | } | 195 | } |
196 | 196 | ||
197 | static u8 __init bios_get_cmos_address(void) | 197 | static u8 __devinit bios_get_cmos_address(void) |
198 | { | 198 | { |
199 | struct regs regs; | 199 | struct regs regs; |
200 | 200 | ||
@@ -206,7 +206,7 @@ static u8 __init bios_get_cmos_address(void) | |||
206 | return regs.ecx; | 206 | return regs.ecx; |
207 | } | 207 | } |
208 | 208 | ||
209 | static u16 __init bios_get_default_setting(u8 subsys) | 209 | static u16 __devinit bios_get_default_setting(u8 subsys) |
210 | { | 210 | { |
211 | struct regs regs; | 211 | struct regs regs; |
212 | 212 | ||
@@ -296,6 +296,16 @@ static struct key_entry keymap_acer_aspire_1500[] = { | |||
296 | { KE_END, 0 } | 296 | { KE_END, 0 } |
297 | }; | 297 | }; |
298 | 298 | ||
299 | static struct key_entry keymap_acer_travelmate_240[] = { | ||
300 | { KE_KEY, 0x31, KEY_MAIL }, | ||
301 | { KE_KEY, 0x36, KEY_WWW }, | ||
302 | { KE_KEY, 0x11, KEY_PROG1 }, | ||
303 | { KE_KEY, 0x12, KEY_PROG2 }, | ||
304 | { KE_BLUETOOTH, 0x44, 0 }, | ||
305 | { KE_WIFI, 0x30, 0 }, | ||
306 | { KE_END, 0 } | ||
307 | }; | ||
308 | |||
299 | /* | 309 | /* |
300 | * If your machine is not here (which is currently rather likely), please send | 310 | * If your machine is not here (which is currently rather likely), please send |
301 | * a list of buttons and their key codes (reported when loading this module | 311 | * a list of buttons and their key codes (reported when loading this module |
@@ -320,6 +330,15 @@ static struct dmi_system_id dmi_ids[] = { | |||
320 | }, | 330 | }, |
321 | .driver_data = keymap_acer_aspire_1500 | 331 | .driver_data = keymap_acer_aspire_1500 |
322 | }, | 332 | }, |
333 | { | ||
334 | .callback = dmi_matched, | ||
335 | .ident = "Acer TravelMate 240", | ||
336 | .matches = { | ||
337 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
338 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 240"), | ||
339 | }, | ||
340 | .driver_data = keymap_acer_travelmate_240 | ||
341 | }, | ||
323 | { NULL, } | 342 | { NULL, } |
324 | }; | 343 | }; |
325 | 344 | ||
@@ -348,7 +367,7 @@ static int __init select_keymap(void) | |||
348 | 367 | ||
349 | static struct input_dev *input_dev; | 368 | static struct input_dev *input_dev; |
350 | 369 | ||
351 | static int __init setup_input_dev(void) | 370 | static int __devinit setup_input_dev(void) |
352 | { | 371 | { |
353 | const struct key_entry *key; | 372 | const struct key_entry *key; |
354 | int error; | 373 | int error; |
@@ -447,6 +466,52 @@ static void poll_bios(unsigned long discard) | |||
447 | mod_timer(&poll_timer, jiffies + HZ / POLL_FREQUENCY); | 466 | mod_timer(&poll_timer, jiffies + HZ / POLL_FREQUENCY); |
448 | } | 467 | } |
449 | 468 | ||
469 | static int __devinit wistron_probe(struct platform_device *dev) | ||
470 | { | ||
471 | int err = setup_input_dev(); | ||
472 | if (err) | ||
473 | return err; | ||
474 | |||
475 | bios_attach(); | ||
476 | cmos_address = bios_get_cmos_address(); | ||
477 | |||
478 | if (have_wifi) { | ||
479 | u16 wifi = bios_get_default_setting(WIFI); | ||
480 | if (wifi & 1) | ||
481 | wifi_enabled = (wifi & 2) ? 1 : 0; | ||
482 | else | ||
483 | have_wifi = 0; | ||
484 | |||
485 | if (have_wifi) | ||
486 | bios_set_state(WIFI, wifi_enabled); | ||
487 | } | ||
488 | |||
489 | if (have_bluetooth) { | ||
490 | u16 bt = bios_get_default_setting(BLUETOOTH); | ||
491 | if (bt & 1) | ||
492 | bluetooth_enabled = (bt & 2) ? 1 : 0; | ||
493 | else | ||
494 | have_bluetooth = 0; | ||
495 | |||
496 | if (have_bluetooth) | ||
497 | bios_set_state(BLUETOOTH, bluetooth_enabled); | ||
498 | } | ||
499 | |||
500 | poll_bios(1); /* Flush stale event queue and arm timer */ | ||
501 | |||
502 | return 0; | ||
503 | } | ||
504 | |||
505 | static int __devexit wistron_remove(struct platform_device *dev) | ||
506 | { | ||
507 | del_timer_sync(&poll_timer); | ||
508 | input_unregister_device(input_dev); | ||
509 | bios_detach(); | ||
510 | |||
511 | return 0; | ||
512 | } | ||
513 | |||
514 | #ifdef CONFIG_PM | ||
450 | static int wistron_suspend(struct platform_device *dev, pm_message_t state) | 515 | static int wistron_suspend(struct platform_device *dev, pm_message_t state) |
451 | { | 516 | { |
452 | del_timer_sync(&poll_timer); | 517 | del_timer_sync(&poll_timer); |
@@ -472,13 +537,20 @@ static int wistron_resume(struct platform_device *dev) | |||
472 | 537 | ||
473 | return 0; | 538 | return 0; |
474 | } | 539 | } |
540 | #else | ||
541 | #define wistron_suspend NULL | ||
542 | #define wistron_resume NULL | ||
543 | #endif | ||
475 | 544 | ||
476 | static struct platform_driver wistron_driver = { | 545 | static struct platform_driver wistron_driver = { |
477 | .suspend = wistron_suspend, | ||
478 | .resume = wistron_resume, | ||
479 | .driver = { | 546 | .driver = { |
480 | .name = "wistron-bios", | 547 | .name = "wistron-bios", |
548 | .owner = THIS_MODULE, | ||
481 | }, | 549 | }, |
550 | .probe = wistron_probe, | ||
551 | .remove = __devexit_p(wistron_remove), | ||
552 | .suspend = wistron_suspend, | ||
553 | .resume = wistron_resume, | ||
482 | }; | 554 | }; |
483 | 555 | ||
484 | static int __init wb_module_init(void) | 556 | static int __init wb_module_init(void) |
@@ -493,55 +565,27 @@ static int __init wb_module_init(void) | |||
493 | if (err) | 565 | if (err) |
494 | return err; | 566 | return err; |
495 | 567 | ||
496 | bios_attach(); | ||
497 | cmos_address = bios_get_cmos_address(); | ||
498 | |||
499 | err = platform_driver_register(&wistron_driver); | 568 | err = platform_driver_register(&wistron_driver); |
500 | if (err) | 569 | if (err) |
501 | goto err_detach_bios; | 570 | goto err_unmap_bios; |
502 | 571 | ||
503 | wistron_device = platform_device_register_simple("wistron-bios", -1, NULL, 0); | 572 | wistron_device = platform_device_alloc("wistron-bios", -1); |
504 | if (IS_ERR(wistron_device)) { | 573 | if (!wistron_device) { |
505 | err = PTR_ERR(wistron_device); | 574 | err = -ENOMEM; |
506 | goto err_unregister_driver; | 575 | goto err_unregister_driver; |
507 | } | 576 | } |
508 | 577 | ||
509 | if (have_wifi) { | 578 | err = platform_device_add(wistron_device); |
510 | u16 wifi = bios_get_default_setting(WIFI); | ||
511 | if (wifi & 1) | ||
512 | wifi_enabled = (wifi & 2) ? 1 : 0; | ||
513 | else | ||
514 | have_wifi = 0; | ||
515 | |||
516 | if (have_wifi) | ||
517 | bios_set_state(WIFI, wifi_enabled); | ||
518 | } | ||
519 | |||
520 | if (have_bluetooth) { | ||
521 | u16 bt = bios_get_default_setting(BLUETOOTH); | ||
522 | if (bt & 1) | ||
523 | bluetooth_enabled = (bt & 2) ? 1 : 0; | ||
524 | else | ||
525 | have_bluetooth = 0; | ||
526 | |||
527 | if (have_bluetooth) | ||
528 | bios_set_state(BLUETOOTH, bluetooth_enabled); | ||
529 | } | ||
530 | |||
531 | err = setup_input_dev(); | ||
532 | if (err) | 579 | if (err) |
533 | goto err_unregister_device; | 580 | goto err_free_device; |
534 | |||
535 | poll_bios(1); /* Flush stale event queue and arm timer */ | ||
536 | 581 | ||
537 | return 0; | 582 | return 0; |
538 | 583 | ||
539 | err_unregister_device: | 584 | err_free_device: |
540 | platform_device_unregister(wistron_device); | 585 | platform_device_put(wistron_device); |
541 | err_unregister_driver: | 586 | err_unregister_driver: |
542 | platform_driver_unregister(&wistron_driver); | 587 | platform_driver_unregister(&wistron_driver); |
543 | err_detach_bios: | 588 | err_unmap_bios: |
544 | bios_detach(); | ||
545 | unmap_bios(); | 589 | unmap_bios(); |
546 | 590 | ||
547 | return err; | 591 | return err; |
@@ -549,11 +593,8 @@ static int __init wb_module_init(void) | |||
549 | 593 | ||
550 | static void __exit wb_module_exit(void) | 594 | static void __exit wb_module_exit(void) |
551 | { | 595 | { |
552 | del_timer_sync(&poll_timer); | ||
553 | input_unregister_device(input_dev); | ||
554 | platform_device_unregister(wistron_device); | 596 | platform_device_unregister(wistron_device); |
555 | platform_driver_unregister(&wistron_driver); | 597 | platform_driver_unregister(&wistron_driver); |
556 | bios_detach(); | ||
557 | unmap_bios(); | 598 | unmap_bios(); |
558 | } | 599 | } |
559 | 600 | ||
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 4f41ec3e4332..24474335dfd1 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -40,6 +40,7 @@ static struct alps_model_info alps_model_data[] = { | |||
40 | { { 0x33, 0x02, 0x0a }, 0x88, 0xf8, ALPS_OLDPROTO }, /* UMAX-530T */ | 40 | { { 0x33, 0x02, 0x0a }, 0x88, 0xf8, ALPS_OLDPROTO }, /* UMAX-530T */ |
41 | { { 0x53, 0x02, 0x0a }, 0xf8, 0xf8, 0 }, | 41 | { { 0x53, 0x02, 0x0a }, 0xf8, 0xf8, 0 }, |
42 | { { 0x53, 0x02, 0x14 }, 0xf8, 0xf8, 0 }, | 42 | { { 0x53, 0x02, 0x14 }, 0xf8, 0xf8, 0 }, |
43 | { { 0x60, 0x03, 0xc8 }, 0xf8, 0xf8, 0 }, /* HP ze1115 */ | ||
43 | { { 0x63, 0x02, 0x0a }, 0xf8, 0xf8, 0 }, | 44 | { { 0x63, 0x02, 0x0a }, 0xf8, 0xf8, 0 }, |
44 | { { 0x63, 0x02, 0x14 }, 0xf8, 0xf8, 0 }, | 45 | { { 0x63, 0x02, 0x14 }, 0xf8, 0xf8, 0 }, |
45 | { { 0x63, 0x02, 0x28 }, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Fujitsu Siemens S6010 */ | 46 | { { 0x63, 0x02, 0x28 }, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Fujitsu Siemens S6010 */ |
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index 55991424ac91..5ccc3ef3b89e 100644 --- a/drivers/input/mouse/lifebook.c +++ b/drivers/input/mouse/lifebook.c | |||
@@ -27,6 +27,13 @@ static struct dmi_system_id lifebook_dmi_table[] = { | |||
27 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK B Series"), | 27 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK B Series"), |
28 | }, | 28 | }, |
29 | }, | 29 | }, |
30 | { | ||
31 | .ident = "Lifebook B142", | ||
32 | .matches = { | ||
33 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"), | ||
34 | }, | ||
35 | |||
36 | }, | ||
30 | { } | 37 | { } |
31 | }; | 38 | }; |
32 | 39 | ||
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index 31a59f7abfaf..025a71de5404 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c | |||
@@ -226,7 +226,9 @@ static struct ps2pp_info *get_model_info(unsigned char model) | |||
226 | { 80, PS2PP_KIND_WHEEL, PS2PP_SIDE_BTN | PS2PP_WHEEL }, | 226 | { 80, PS2PP_KIND_WHEEL, PS2PP_SIDE_BTN | PS2PP_WHEEL }, |
227 | { 81, PS2PP_KIND_WHEEL, PS2PP_WHEEL }, | 227 | { 81, PS2PP_KIND_WHEEL, PS2PP_WHEEL }, |
228 | { 83, PS2PP_KIND_WHEEL, PS2PP_WHEEL }, | 228 | { 83, PS2PP_KIND_WHEEL, PS2PP_WHEEL }, |
229 | { 85, PS2PP_KIND_WHEEL, PS2PP_WHEEL }, | ||
229 | { 86, PS2PP_KIND_WHEEL, PS2PP_WHEEL }, | 230 | { 86, PS2PP_KIND_WHEEL, PS2PP_WHEEL }, |
231 | { 87, PS2PP_KIND_WHEEL, PS2PP_WHEEL }, | ||
230 | { 88, PS2PP_KIND_WHEEL, PS2PP_WHEEL }, | 232 | { 88, PS2PP_KIND_WHEEL, PS2PP_WHEEL }, |
231 | { 96, 0, 0 }, | 233 | { 96, 0, 0 }, |
232 | { 97, PS2PP_KIND_TP3, PS2PP_WHEEL | PS2PP_HWHEEL }, | 234 | { 97, PS2PP_KIND_TP3, PS2PP_WHEEL | PS2PP_HWHEEL }, |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 6ee9999a2eaa..4d5ecc04c5b6 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -527,11 +527,15 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
527 | if (max_proto > PSMOUSE_IMEX && ps2pp_init(psmouse, set_properties) == 0) | 527 | if (max_proto > PSMOUSE_IMEX && ps2pp_init(psmouse, set_properties) == 0) |
528 | return PSMOUSE_PS2PP; | 528 | return PSMOUSE_PS2PP; |
529 | 529 | ||
530 | if (max_proto > PSMOUSE_IMEX && trackpoint_detect(psmouse, set_properties) == 0) | ||
531 | return PSMOUSE_TRACKPOINT; | ||
532 | |||
530 | /* | 533 | /* |
531 | * Reset to defaults in case the device got confused by extended | 534 | * Reset to defaults in case the device got confused by extended |
532 | * protocol probes. | 535 | * protocol probes. Note that we do full reset becuase some mice |
536 | * put themselves to sleep when see PSMOUSE_RESET_DIS. | ||
533 | */ | 537 | */ |
534 | ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS); | 538 | psmouse_reset(psmouse); |
535 | 539 | ||
536 | if (max_proto >= PSMOUSE_IMEX && im_explorer_detect(psmouse, set_properties) == 0) | 540 | if (max_proto >= PSMOUSE_IMEX && im_explorer_detect(psmouse, set_properties) == 0) |
537 | return PSMOUSE_IMEX; | 541 | return PSMOUSE_IMEX; |
@@ -540,12 +544,6 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
540 | return PSMOUSE_IMPS; | 544 | return PSMOUSE_IMPS; |
541 | 545 | ||
542 | /* | 546 | /* |
543 | * Try to initialize the IBM TrackPoint | ||
544 | */ | ||
545 | if (max_proto > PSMOUSE_IMEX && trackpoint_detect(psmouse, set_properties) == 0) | ||
546 | return PSMOUSE_TRACKPOINT; | ||
547 | |||
548 | /* | ||
549 | * Okay, all failed, we have a standard mouse here. The number of the buttons | 547 | * Okay, all failed, we have a standard mouse here. The number of the buttons |
550 | * is still a question, though. We assume 3. | 548 | * is still a question, though. We assume 3. |
551 | */ | 549 | */ |
@@ -559,7 +557,6 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
559 | * extensions. | 557 | * extensions. |
560 | */ | 558 | */ |
561 | psmouse_reset(psmouse); | 559 | psmouse_reset(psmouse); |
562 | ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS); | ||
563 | } | 560 | } |
564 | 561 | ||
565 | return PSMOUSE_PS2; | 562 | return PSMOUSE_PS2; |
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 2d0af44ac4b9..81fd7a97a93d 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c | |||
@@ -40,15 +40,15 @@ MODULE_LICENSE("GPL"); | |||
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | static int xres = CONFIG_INPUT_MOUSEDEV_SCREEN_X; | 42 | static int xres = CONFIG_INPUT_MOUSEDEV_SCREEN_X; |
43 | module_param(xres, uint, 0); | 43 | module_param(xres, uint, 0644); |
44 | MODULE_PARM_DESC(xres, "Horizontal screen resolution"); | 44 | MODULE_PARM_DESC(xres, "Horizontal screen resolution"); |
45 | 45 | ||
46 | static int yres = CONFIG_INPUT_MOUSEDEV_SCREEN_Y; | 46 | static int yres = CONFIG_INPUT_MOUSEDEV_SCREEN_Y; |
47 | module_param(yres, uint, 0); | 47 | module_param(yres, uint, 0644); |
48 | MODULE_PARM_DESC(yres, "Vertical screen resolution"); | 48 | MODULE_PARM_DESC(yres, "Vertical screen resolution"); |
49 | 49 | ||
50 | static unsigned tap_time = 200; | 50 | static unsigned tap_time = 200; |
51 | module_param(tap_time, uint, 0); | 51 | module_param(tap_time, uint, 0644); |
52 | MODULE_PARM_DESC(tap_time, "Tap time for touchpads in absolute mode (msecs)"); | 52 | MODULE_PARM_DESC(tap_time, "Tap time for touchpads in absolute mode (msecs)"); |
53 | 53 | ||
54 | struct mousedev_hw_data { | 54 | struct mousedev_hw_data { |
@@ -155,7 +155,7 @@ static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev, | |||
155 | switch (code) { | 155 | switch (code) { |
156 | case ABS_X: | 156 | case ABS_X: |
157 | size = dev->absmax[ABS_X] - dev->absmin[ABS_X]; | 157 | size = dev->absmax[ABS_X] - dev->absmin[ABS_X]; |
158 | if (size == 0) size = xres; | 158 | if (size == 0) size = xres ? : 1; |
159 | if (value > dev->absmax[ABS_X]) value = dev->absmax[ABS_X]; | 159 | if (value > dev->absmax[ABS_X]) value = dev->absmax[ABS_X]; |
160 | if (value < dev->absmin[ABS_X]) value = dev->absmin[ABS_X]; | 160 | if (value < dev->absmin[ABS_X]) value = dev->absmin[ABS_X]; |
161 | mousedev->packet.x = ((value - dev->absmin[ABS_X]) * xres) / size; | 161 | mousedev->packet.x = ((value - dev->absmin[ABS_X]) * xres) / size; |
@@ -164,7 +164,7 @@ static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev, | |||
164 | 164 | ||
165 | case ABS_Y: | 165 | case ABS_Y: |
166 | size = dev->absmax[ABS_Y] - dev->absmin[ABS_Y]; | 166 | size = dev->absmax[ABS_Y] - dev->absmin[ABS_Y]; |
167 | if (size == 0) size = yres; | 167 | if (size == 0) size = yres ? : 1; |
168 | if (value > dev->absmax[ABS_Y]) value = dev->absmax[ABS_Y]; | 168 | if (value > dev->absmax[ABS_Y]) value = dev->absmax[ABS_Y]; |
169 | if (value < dev->absmin[ABS_Y]) value = dev->absmin[ABS_Y]; | 169 | if (value < dev->absmin[ABS_Y]) value = dev->absmin[ABS_Y]; |
170 | mousedev->packet.y = yres - ((value - dev->absmin[ABS_Y]) * yres) / size; | 170 | mousedev->packet.y = yres - ((value - dev->absmin[ABS_Y]) * yres) / size; |
diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c index 4da6c86b5d76..096b6a0b5cca 100644 --- a/drivers/input/serio/ct82c710.c +++ b/drivers/input/serio/ct82c710.c | |||
@@ -154,7 +154,7 @@ static int ct82c710_write(struct serio *port, unsigned char c) | |||
154 | * See if we can find a 82C710 device. Read mouse address. | 154 | * See if we can find a 82C710 device. Read mouse address. |
155 | */ | 155 | */ |
156 | 156 | ||
157 | static int __init ct82c710_probe(void) | 157 | static int __init ct82c710_detect(void) |
158 | { | 158 | { |
159 | outb_p(0x55, 0x2fa); /* Any value except 9, ff or 36 */ | 159 | outb_p(0x55, 0x2fa); /* Any value except 9, ff or 36 */ |
160 | outb_p(0xaa, 0x3fa); /* Inverse of 55 */ | 160 | outb_p(0xaa, 0x3fa); /* Inverse of 55 */ |
@@ -163,7 +163,7 @@ static int __init ct82c710_probe(void) | |||
163 | outb_p(0x1b, 0x2fa); /* Inverse of e4 */ | 163 | outb_p(0x1b, 0x2fa); /* Inverse of e4 */ |
164 | outb_p(0x0f, 0x390); /* Write index */ | 164 | outb_p(0x0f, 0x390); /* Write index */ |
165 | if (inb_p(0x391) != 0xe4) /* Config address found? */ | 165 | if (inb_p(0x391) != 0xe4) /* Config address found? */ |
166 | return -1; /* No: no 82C710 here */ | 166 | return -ENODEV; /* No: no 82C710 here */ |
167 | 167 | ||
168 | outb_p(0x0d, 0x390); /* Write index */ | 168 | outb_p(0x0d, 0x390); /* Write index */ |
169 | ct82c710_iores.start = inb_p(0x391) << 2; /* Get mouse I/O address */ | 169 | ct82c710_iores.start = inb_p(0x391) << 2; /* Get mouse I/O address */ |
@@ -175,51 +175,88 @@ static int __init ct82c710_probe(void) | |||
175 | return 0; | 175 | return 0; |
176 | } | 176 | } |
177 | 177 | ||
178 | static struct serio * __init ct82c710_allocate_port(void) | 178 | static int __devinit ct82c710_probe(struct platform_device *dev) |
179 | { | 179 | { |
180 | struct serio *serio; | 180 | ct82c710_port = kzalloc(sizeof(struct serio), GFP_KERNEL); |
181 | 181 | if (!ct82c710_port) | |
182 | serio = kmalloc(sizeof(struct serio), GFP_KERNEL); | 182 | return -ENOMEM; |
183 | if (serio) { | 183 | |
184 | memset(serio, 0, sizeof(struct serio)); | 184 | ct82c710_port->id.type = SERIO_8042; |
185 | serio->id.type = SERIO_8042; | 185 | ct82c710_port->dev.parent = &dev->dev; |
186 | serio->open = ct82c710_open; | 186 | ct82c710_port->open = ct82c710_open; |
187 | serio->close = ct82c710_close; | 187 | ct82c710_port->close = ct82c710_close; |
188 | serio->write = ct82c710_write; | 188 | ct82c710_port->write = ct82c710_write; |
189 | serio->dev.parent = &ct82c710_device->dev; | 189 | strlcpy(ct82c710_port->name, "C&T 82c710 mouse port", |
190 | strlcpy(serio->name, "C&T 82c710 mouse port", sizeof(serio->name)); | 190 | sizeof(ct82c710_port->name)); |
191 | snprintf(serio->phys, sizeof(serio->phys), "isa%04lx/serio0", CT82C710_DATA); | 191 | snprintf(ct82c710_port->phys, sizeof(ct82c710_port->phys), |
192 | } | 192 | "isa%04lx/serio0", CT82C710_DATA); |
193 | |||
194 | serio_register_port(ct82c710_port); | ||
195 | |||
196 | return 0; | ||
197 | } | ||
198 | |||
199 | static int __devexit ct82c710_remove(struct platform_device *dev) | ||
200 | { | ||
201 | serio_unregister_port(ct82c710_port); | ||
193 | 202 | ||
194 | return serio; | 203 | return 0; |
195 | } | 204 | } |
196 | 205 | ||
206 | static struct platform_driver ct82c710_driver = { | ||
207 | .driver = { | ||
208 | .name = "ct82c710", | ||
209 | .owner = THIS_MODULE, | ||
210 | }, | ||
211 | .probe = ct82c710_probe, | ||
212 | .remove = __devexit_p(ct82c710_remove), | ||
213 | }; | ||
214 | |||
215 | |||
197 | static int __init ct82c710_init(void) | 216 | static int __init ct82c710_init(void) |
198 | { | 217 | { |
199 | if (ct82c710_probe()) | 218 | int error; |
200 | return -ENODEV; | ||
201 | 219 | ||
202 | ct82c710_device = platform_device_register_simple("ct82c710", -1, &ct82c710_iores, 1); | 220 | error = ct82c710_detect(); |
203 | if (IS_ERR(ct82c710_device)) | 221 | if (error) |
204 | return PTR_ERR(ct82c710_device); | 222 | return error; |
205 | 223 | ||
206 | if (!(ct82c710_port = ct82c710_allocate_port())) { | 224 | error = platform_driver_register(&ct82c710_driver); |
207 | platform_device_unregister(ct82c710_device); | 225 | if (error) |
208 | return -ENOMEM; | 226 | return error; |
227 | |||
228 | ct82c710_device = platform_device_alloc("ct82c710", -1); | ||
229 | if (!ct82c710_device) { | ||
230 | error = -ENOMEM; | ||
231 | goto err_unregister_driver; | ||
209 | } | 232 | } |
210 | 233 | ||
234 | error = platform_device_add_resources(ct82c710_device, &ct82c710_iores, 1); | ||
235 | if (error) | ||
236 | goto err_free_device; | ||
237 | |||
238 | error = platform_device_add(ct82c710_device); | ||
239 | if (error) | ||
240 | goto err_free_device; | ||
241 | |||
211 | serio_register_port(ct82c710_port); | 242 | serio_register_port(ct82c710_port); |
212 | 243 | ||
213 | printk(KERN_INFO "serio: C&T 82c710 mouse port at %#lx irq %d\n", | 244 | printk(KERN_INFO "serio: C&T 82c710 mouse port at %#lx irq %d\n", |
214 | CT82C710_DATA, CT82C710_IRQ); | 245 | CT82C710_DATA, CT82C710_IRQ); |
215 | 246 | ||
216 | return 0; | 247 | return 0; |
248 | |||
249 | err_free_device: | ||
250 | platform_device_put(ct82c710_device); | ||
251 | err_unregister_driver: | ||
252 | platform_driver_unregister(&ct82c710_driver); | ||
253 | return error; | ||
217 | } | 254 | } |
218 | 255 | ||
219 | static void __exit ct82c710_exit(void) | 256 | static void __exit ct82c710_exit(void) |
220 | { | 257 | { |
221 | serio_unregister_port(ct82c710_port); | ||
222 | platform_device_unregister(ct82c710_device); | 258 | platform_device_unregister(ct82c710_device); |
259 | platform_driver_unregister(&ct82c710_driver); | ||
223 | } | 260 | } |
224 | 261 | ||
225 | module_init(ct82c710_init); | 262 | module_init(ct82c710_init); |
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 273bb3b08cfa..057beca1986a 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -158,6 +158,13 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { | |||
158 | DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"), | 158 | DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"), |
159 | }, | 159 | }, |
160 | }, | 160 | }, |
161 | { | ||
162 | .ident = "Sharp Actius MM20", | ||
163 | .matches = { | ||
164 | DMI_MATCH(DMI_SYS_VENDOR, "SHARP"), | ||
165 | DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"), | ||
166 | }, | ||
167 | }, | ||
161 | { } | 168 | { } |
162 | }; | 169 | }; |
163 | 170 | ||
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index ac86c1d1d83e..a7d91d5356a5 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -572,7 +572,7 @@ static int i8042_enable_mux_ports(void) | |||
572 | * LCS/Telegraphics. | 572 | * LCS/Telegraphics. |
573 | */ | 573 | */ |
574 | 574 | ||
575 | static int __init i8042_check_mux(void) | 575 | static int __devinit i8042_check_mux(void) |
576 | { | 576 | { |
577 | unsigned char mux_version; | 577 | unsigned char mux_version; |
578 | 578 | ||
@@ -600,7 +600,7 @@ static int __init i8042_check_mux(void) | |||
600 | * the presence of an AUX interface. | 600 | * the presence of an AUX interface. |
601 | */ | 601 | */ |
602 | 602 | ||
603 | static int __init i8042_check_aux(void) | 603 | static int __devinit i8042_check_aux(void) |
604 | { | 604 | { |
605 | unsigned char param; | 605 | unsigned char param; |
606 | static int i8042_check_aux_cookie; | 606 | static int i8042_check_aux_cookie; |
@@ -678,7 +678,7 @@ static int __init i8042_check_aux(void) | |||
678 | * registers it, and reports to the user. | 678 | * registers it, and reports to the user. |
679 | */ | 679 | */ |
680 | 680 | ||
681 | static int __init i8042_port_register(struct i8042_port *port) | 681 | static int __devinit i8042_port_register(struct i8042_port *port) |
682 | { | 682 | { |
683 | i8042_ctr &= ~port->disable; | 683 | i8042_ctr &= ~port->disable; |
684 | 684 | ||
@@ -956,7 +956,6 @@ static int i8042_resume(struct platform_device *dev) | |||
956 | panic_blink = i8042_panic_blink; | 956 | panic_blink = i8042_panic_blink; |
957 | 957 | ||
958 | return 0; | 958 | return 0; |
959 | |||
960 | } | 959 | } |
961 | 960 | ||
962 | /* | 961 | /* |
@@ -969,16 +968,7 @@ static void i8042_shutdown(struct platform_device *dev) | |||
969 | i8042_controller_cleanup(); | 968 | i8042_controller_cleanup(); |
970 | } | 969 | } |
971 | 970 | ||
972 | static struct platform_driver i8042_driver = { | 971 | static int __devinit i8042_create_kbd_port(void) |
973 | .suspend = i8042_suspend, | ||
974 | .resume = i8042_resume, | ||
975 | .shutdown = i8042_shutdown, | ||
976 | .driver = { | ||
977 | .name = "i8042", | ||
978 | }, | ||
979 | }; | ||
980 | |||
981 | static int __init i8042_create_kbd_port(void) | ||
982 | { | 972 | { |
983 | struct serio *serio; | 973 | struct serio *serio; |
984 | struct i8042_port *port = &i8042_ports[I8042_KBD_PORT_NO]; | 974 | struct i8042_port *port = &i8042_ports[I8042_KBD_PORT_NO]; |
@@ -1003,7 +993,7 @@ static int __init i8042_create_kbd_port(void) | |||
1003 | return i8042_port_register(port); | 993 | return i8042_port_register(port); |
1004 | } | 994 | } |
1005 | 995 | ||
1006 | static int __init i8042_create_aux_port(void) | 996 | static int __devinit i8042_create_aux_port(void) |
1007 | { | 997 | { |
1008 | struct serio *serio; | 998 | struct serio *serio; |
1009 | struct i8042_port *port = &i8042_ports[I8042_AUX_PORT_NO]; | 999 | struct i8042_port *port = &i8042_ports[I8042_AUX_PORT_NO]; |
@@ -1028,7 +1018,7 @@ static int __init i8042_create_aux_port(void) | |||
1028 | return i8042_port_register(port); | 1018 | return i8042_port_register(port); |
1029 | } | 1019 | } |
1030 | 1020 | ||
1031 | static int __init i8042_create_mux_port(int index) | 1021 | static int __devinit i8042_create_mux_port(int index) |
1032 | { | 1022 | { |
1033 | struct serio *serio; | 1023 | struct serio *serio; |
1034 | struct i8042_port *port = &i8042_ports[I8042_MUX_PORT_NO + index]; | 1024 | struct i8042_port *port = &i8042_ports[I8042_MUX_PORT_NO + index]; |
@@ -1057,37 +1047,16 @@ static int __init i8042_create_mux_port(int index) | |||
1057 | return i8042_port_register(port); | 1047 | return i8042_port_register(port); |
1058 | } | 1048 | } |
1059 | 1049 | ||
1060 | static int __init i8042_init(void) | 1050 | static int __devinit i8042_probe(struct platform_device *dev) |
1061 | { | 1051 | { |
1062 | int i, have_ports = 0; | 1052 | int i, have_ports = 0; |
1063 | int err; | 1053 | int err; |
1064 | 1054 | ||
1065 | dbg_init(); | ||
1066 | |||
1067 | init_timer(&i8042_timer); | 1055 | init_timer(&i8042_timer); |
1068 | i8042_timer.function = i8042_timer_func; | 1056 | i8042_timer.function = i8042_timer_func; |
1069 | 1057 | ||
1070 | err = i8042_platform_init(); | 1058 | if (i8042_controller_init()) |
1071 | if (err) | 1059 | return -ENODEV; |
1072 | return err; | ||
1073 | |||
1074 | i8042_ports[I8042_AUX_PORT_NO].irq = I8042_AUX_IRQ; | ||
1075 | i8042_ports[I8042_KBD_PORT_NO].irq = I8042_KBD_IRQ; | ||
1076 | |||
1077 | if (i8042_controller_init()) { | ||
1078 | err = -ENODEV; | ||
1079 | goto err_platform_exit; | ||
1080 | } | ||
1081 | |||
1082 | err = platform_driver_register(&i8042_driver); | ||
1083 | if (err) | ||
1084 | goto err_controller_cleanup; | ||
1085 | |||
1086 | i8042_platform_device = platform_device_register_simple("i8042", -1, NULL, 0); | ||
1087 | if (IS_ERR(i8042_platform_device)) { | ||
1088 | err = PTR_ERR(i8042_platform_device); | ||
1089 | goto err_unregister_driver; | ||
1090 | } | ||
1091 | 1060 | ||
1092 | if (!i8042_noaux && !i8042_check_aux()) { | 1061 | if (!i8042_noaux && !i8042_check_aux()) { |
1093 | if (!i8042_nomux && !i8042_check_mux()) { | 1062 | if (!i8042_nomux && !i8042_check_mux()) { |
@@ -1113,30 +1082,23 @@ static int __init i8042_init(void) | |||
1113 | 1082 | ||
1114 | if (!have_ports) { | 1083 | if (!have_ports) { |
1115 | err = -ENODEV; | 1084 | err = -ENODEV; |
1116 | goto err_unregister_device; | 1085 | goto err_controller_cleanup; |
1117 | } | 1086 | } |
1118 | 1087 | ||
1119 | mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD); | 1088 | mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD); |
1120 | |||
1121 | return 0; | 1089 | return 0; |
1122 | 1090 | ||
1123 | err_unregister_ports: | 1091 | err_unregister_ports: |
1124 | for (i = 0; i < I8042_NUM_PORTS; i++) | 1092 | for (i = 0; i < I8042_NUM_PORTS; i++) |
1125 | if (i8042_ports[i].serio) | 1093 | if (i8042_ports[i].serio) |
1126 | serio_unregister_port(i8042_ports[i].serio); | 1094 | serio_unregister_port(i8042_ports[i].serio); |
1127 | err_unregister_device: | ||
1128 | platform_device_unregister(i8042_platform_device); | ||
1129 | err_unregister_driver: | ||
1130 | platform_driver_unregister(&i8042_driver); | ||
1131 | err_controller_cleanup: | 1095 | err_controller_cleanup: |
1132 | i8042_controller_cleanup(); | 1096 | i8042_controller_cleanup(); |
1133 | err_platform_exit: | ||
1134 | i8042_platform_exit(); | ||
1135 | 1097 | ||
1136 | return err; | 1098 | return err; |
1137 | } | 1099 | } |
1138 | 1100 | ||
1139 | static void __exit i8042_exit(void) | 1101 | static int __devexit i8042_remove(struct platform_device *dev) |
1140 | { | 1102 | { |
1141 | int i; | 1103 | int i; |
1142 | 1104 | ||
@@ -1148,6 +1110,62 @@ static void __exit i8042_exit(void) | |||
1148 | 1110 | ||
1149 | del_timer_sync(&i8042_timer); | 1111 | del_timer_sync(&i8042_timer); |
1150 | 1112 | ||
1113 | return 0; | ||
1114 | } | ||
1115 | |||
1116 | static struct platform_driver i8042_driver = { | ||
1117 | .driver = { | ||
1118 | .name = "i8042", | ||
1119 | .owner = THIS_MODULE, | ||
1120 | }, | ||
1121 | .probe = i8042_probe, | ||
1122 | .remove = __devexit_p(i8042_remove), | ||
1123 | .suspend = i8042_suspend, | ||
1124 | .resume = i8042_resume, | ||
1125 | .shutdown = i8042_shutdown, | ||
1126 | }; | ||
1127 | |||
1128 | static int __init i8042_init(void) | ||
1129 | { | ||
1130 | int err; | ||
1131 | |||
1132 | dbg_init(); | ||
1133 | |||
1134 | err = i8042_platform_init(); | ||
1135 | if (err) | ||
1136 | return err; | ||
1137 | |||
1138 | i8042_ports[I8042_AUX_PORT_NO].irq = I8042_AUX_IRQ; | ||
1139 | i8042_ports[I8042_KBD_PORT_NO].irq = I8042_KBD_IRQ; | ||
1140 | |||
1141 | err = platform_driver_register(&i8042_driver); | ||
1142 | if (err) | ||
1143 | goto err_platform_exit; | ||
1144 | |||
1145 | i8042_platform_device = platform_device_alloc("i8042", -1); | ||
1146 | if (!i8042_platform_device) { | ||
1147 | err = -ENOMEM; | ||
1148 | goto err_unregister_driver; | ||
1149 | } | ||
1150 | |||
1151 | err = platform_device_add(i8042_platform_device); | ||
1152 | if (err) | ||
1153 | goto err_free_device; | ||
1154 | |||
1155 | return 0; | ||
1156 | |||
1157 | err_free_device: | ||
1158 | platform_device_put(i8042_platform_device); | ||
1159 | err_unregister_driver: | ||
1160 | platform_driver_unregister(&i8042_driver); | ||
1161 | err_platform_exit: | ||
1162 | i8042_platform_exit(); | ||
1163 | |||
1164 | return err; | ||
1165 | } | ||
1166 | |||
1167 | static void __exit i8042_exit(void) | ||
1168 | { | ||
1151 | platform_device_unregister(i8042_platform_device); | 1169 | platform_device_unregister(i8042_platform_device); |
1152 | platform_driver_unregister(&i8042_driver); | 1170 | platform_driver_unregister(&i8042_driver); |
1153 | 1171 | ||
diff --git a/drivers/input/serio/maceps2.c b/drivers/input/serio/maceps2.c index d857f7081adb..f08a5d0cd5fa 100644 --- a/drivers/input/serio/maceps2.c +++ b/drivers/input/serio/maceps2.c | |||
@@ -118,13 +118,12 @@ static void maceps2_close(struct serio *dev) | |||
118 | } | 118 | } |
119 | 119 | ||
120 | 120 | ||
121 | static struct serio * __init maceps2_allocate_port(int idx) | 121 | static struct serio * __devinit maceps2_allocate_port(int idx) |
122 | { | 122 | { |
123 | struct serio *serio; | 123 | struct serio *serio; |
124 | 124 | ||
125 | serio = kmalloc(sizeof(struct serio), GFP_KERNEL); | 125 | serio = kzalloc(sizeof(struct serio), GFP_KERNEL); |
126 | if (serio) { | 126 | if (serio) { |
127 | memset(serio, 0, sizeof(struct serio)); | ||
128 | serio->id.type = SERIO_8042; | 127 | serio->id.type = SERIO_8042; |
129 | serio->write = maceps2_write; | 128 | serio->write = maceps2_write; |
130 | serio->open = maceps2_open; | 129 | serio->open = maceps2_open; |
@@ -138,24 +137,13 @@ static struct serio * __init maceps2_allocate_port(int idx) | |||
138 | return serio; | 137 | return serio; |
139 | } | 138 | } |
140 | 139 | ||
141 | 140 | static int __devinit maceps2_probe(struct platform_device *dev) | |
142 | static int __init maceps2_init(void) | ||
143 | { | 141 | { |
144 | maceps2_device = platform_device_register_simple("maceps2", -1, NULL, 0); | ||
145 | if (IS_ERR(maceps2_device)) | ||
146 | return PTR_ERR(maceps2_device); | ||
147 | |||
148 | port_data[0].port = &mace->perif.ps2.keyb; | ||
149 | port_data[0].irq = MACEISA_KEYB_IRQ; | ||
150 | port_data[1].port = &mace->perif.ps2.mouse; | ||
151 | port_data[1].irq = MACEISA_MOUSE_IRQ; | ||
152 | |||
153 | maceps2_port[0] = maceps2_allocate_port(0); | 142 | maceps2_port[0] = maceps2_allocate_port(0); |
154 | maceps2_port[1] = maceps2_allocate_port(1); | 143 | maceps2_port[1] = maceps2_allocate_port(1); |
155 | if (!maceps2_port[0] || !maceps2_port[1]) { | 144 | if (!maceps2_port[0] || !maceps2_port[1]) { |
156 | kfree(maceps2_port[0]); | 145 | kfree(maceps2_port[0]); |
157 | kfree(maceps2_port[1]); | 146 | kfree(maceps2_port[1]); |
158 | platform_device_unregister(maceps2_device); | ||
159 | return -ENOMEM; | 147 | return -ENOMEM; |
160 | } | 148 | } |
161 | 149 | ||
@@ -165,11 +153,59 @@ static int __init maceps2_init(void) | |||
165 | return 0; | 153 | return 0; |
166 | } | 154 | } |
167 | 155 | ||
168 | static void __exit maceps2_exit(void) | 156 | static int __devexit maceps2_remove(struct platform_device *dev) |
169 | { | 157 | { |
170 | serio_unregister_port(maceps2_port[0]); | 158 | serio_unregister_port(maceps2_port[0]); |
171 | serio_unregister_port(maceps2_port[1]); | 159 | serio_unregister_port(maceps2_port[1]); |
160 | |||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | static struct platform_driver maceps2_driver = { | ||
165 | .driver = { | ||
166 | .name = "maceps2", | ||
167 | .owner = THIS_MODULE, | ||
168 | }, | ||
169 | .probe = maceps2_probe, | ||
170 | .remove = __devexit_p(maceps2_remove), | ||
171 | }; | ||
172 | |||
173 | static int __init maceps2_init(void) | ||
174 | { | ||
175 | int error; | ||
176 | |||
177 | error = platform_driver_register(&maceps2_driver); | ||
178 | if (error) | ||
179 | return error; | ||
180 | |||
181 | maceps2_device = platform_device_alloc("maceps2", -1); | ||
182 | if (!maceps2_device) { | ||
183 | error = -ENOMEM; | ||
184 | goto err_unregister_driver; | ||
185 | } | ||
186 | |||
187 | port_data[0].port = &mace->perif.ps2.keyb; | ||
188 | port_data[0].irq = MACEISA_KEYB_IRQ; | ||
189 | port_data[1].port = &mace->perif.ps2.mouse; | ||
190 | port_data[1].irq = MACEISA_MOUSE_IRQ; | ||
191 | |||
192 | error = platform_device_add(maceps2_device); | ||
193 | if (error) | ||
194 | goto err_free_device; | ||
195 | |||
196 | return 0; | ||
197 | |||
198 | err_free_device: | ||
199 | platform_device_put(maceps2_device); | ||
200 | err_unregister_driver: | ||
201 | platform_driver_unregister(&maceps2_driver); | ||
202 | return error; | ||
203 | } | ||
204 | |||
205 | static void __exit maceps2_exit(void) | ||
206 | { | ||
172 | platform_device_unregister(maceps2_device); | 207 | platform_device_unregister(maceps2_device); |
208 | platform_driver_unregister(&maceps2_driver); | ||
173 | } | 209 | } |
174 | 210 | ||
175 | module_init(maceps2_init); | 211 | module_init(maceps2_init); |
diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c index b44d255596c2..d3827c5fe119 100644 --- a/drivers/input/serio/q40kbd.c +++ b/drivers/input/serio/q40kbd.c | |||
@@ -75,13 +75,13 @@ static irqreturn_t q40kbd_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
75 | 75 | ||
76 | static void q40kbd_flush(void) | 76 | static void q40kbd_flush(void) |
77 | { | 77 | { |
78 | int maxread = 100; | 78 | int maxread = 100; |
79 | unsigned long flags; | 79 | unsigned long flags; |
80 | 80 | ||
81 | spin_lock_irqsave(&q40kbd_lock, flags); | 81 | spin_lock_irqsave(&q40kbd_lock, flags); |
82 | 82 | ||
83 | while (maxread-- && (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG))) | 83 | while (maxread-- && (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG))) |
84 | master_inb(KEYCODE_REG); | 84 | master_inb(KEYCODE_REG); |
85 | 85 | ||
86 | spin_unlock_irqrestore(&q40kbd_lock, flags); | 86 | spin_unlock_irqrestore(&q40kbd_lock, flags); |
87 | } | 87 | } |
@@ -97,14 +97,14 @@ static int q40kbd_open(struct serio *port) | |||
97 | 97 | ||
98 | if (request_irq(Q40_IRQ_KEYBOARD, q40kbd_interrupt, 0, "q40kbd", NULL)) { | 98 | if (request_irq(Q40_IRQ_KEYBOARD, q40kbd_interrupt, 0, "q40kbd", NULL)) { |
99 | printk(KERN_ERR "q40kbd.c: Can't get irq %d.\n", Q40_IRQ_KEYBOARD); | 99 | printk(KERN_ERR "q40kbd.c: Can't get irq %d.\n", Q40_IRQ_KEYBOARD); |
100 | return -1; | 100 | return -EBUSY; |
101 | } | 101 | } |
102 | 102 | ||
103 | /* off we go */ | 103 | /* off we go */ |
104 | master_outb(-1, KEYBOARD_UNLOCK_REG); | 104 | master_outb(-1, KEYBOARD_UNLOCK_REG); |
105 | master_outb(1, KEY_IRQ_ENABLE_REG); | 105 | master_outb(1, KEY_IRQ_ENABLE_REG); |
106 | 106 | ||
107 | return 0; | 107 | return 0; |
108 | } | 108 | } |
109 | 109 | ||
110 | static void q40kbd_close(struct serio *port) | 110 | static void q40kbd_close(struct serio *port) |
@@ -116,48 +116,73 @@ static void q40kbd_close(struct serio *port) | |||
116 | q40kbd_flush(); | 116 | q40kbd_flush(); |
117 | } | 117 | } |
118 | 118 | ||
119 | static struct serio * __init q40kbd_allocate_port(void) | 119 | static int __devinit q40kbd_probe(struct platform_device *dev) |
120 | { | 120 | { |
121 | struct serio *serio; | 121 | q40kbd_port = kzalloc(sizeof(struct serio), GFP_KERNEL); |
122 | 122 | if (!q40kbd_port) | |
123 | serio = kmalloc(sizeof(struct serio), GFP_KERNEL); | 123 | return -ENOMEM; |
124 | if (serio) { | 124 | |
125 | memset(serio, 0, sizeof(struct serio)); | 125 | q40kbd_port->id.type = SERIO_8042; |
126 | serio->id.type = SERIO_8042; | 126 | q40kbd_port->open = q40kbd_open; |
127 | serio->open = q40kbd_open; | 127 | q40kbd_port->close = q40kbd_close; |
128 | serio->close = q40kbd_close; | 128 | q40kbd_port->dev.parent = &dev->dev; |
129 | serio->dev.parent = &q40kbd_device->dev; | 129 | strlcpy(q40kbd_port->name, "Q40 Kbd Port", sizeof(q40kbd_port->name)); |
130 | strlcpy(serio->name, "Q40 Kbd Port", sizeof(serio->name)); | 130 | strlcpy(q40kbd_port->phys, "Q40", sizeof(q40kbd_port->phys)); |
131 | strlcpy(serio->phys, "Q40", sizeof(serio->phys)); | 131 | |
132 | } | 132 | serio_register_port(q40kbd_port); |
133 | printk(KERN_INFO "serio: Q40 kbd registered\n"); | ||
133 | 134 | ||
134 | return serio; | 135 | return 0; |
135 | } | 136 | } |
136 | 137 | ||
138 | static int __devexit q40kbd_remove(struct platform_device *dev) | ||
139 | { | ||
140 | serio_unregister_port(q40kbd_port); | ||
141 | |||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | static struct platform_driver q40kbd_driver = { | ||
146 | .driver = { | ||
147 | .name = "q40kbd", | ||
148 | .owner = THIS_MODULE, | ||
149 | }, | ||
150 | .probe = q40kbd_probe, | ||
151 | .remove = __devexit_p(q40kbd_remove), | ||
152 | }; | ||
153 | |||
137 | static int __init q40kbd_init(void) | 154 | static int __init q40kbd_init(void) |
138 | { | 155 | { |
156 | int error; | ||
157 | |||
139 | if (!MACH_IS_Q40) | 158 | if (!MACH_IS_Q40) |
140 | return -EIO; | 159 | return -EIO; |
141 | 160 | ||
142 | q40kbd_device = platform_device_register_simple("q40kbd", -1, NULL, 0); | 161 | error = platform_driver_register(&q40kbd_driver); |
143 | if (IS_ERR(q40kbd_device)) | 162 | if (error) |
144 | return PTR_ERR(q40kbd_device); | 163 | return error; |
145 | 164 | ||
146 | if (!(q40kbd_port = q40kbd_allocate_port())) { | 165 | q40kbd_device = platform_device_alloc("q40kbd", -1); |
147 | platform_device_unregister(q40kbd_device); | 166 | if (!q40kbd_device) |
148 | return -ENOMEM; | 167 | goto err_unregister_driver; |
149 | } | ||
150 | 168 | ||
151 | serio_register_port(q40kbd_port); | 169 | error = platform_device_add(q40kbd_device); |
152 | printk(KERN_INFO "serio: Q40 kbd registered\n"); | 170 | if (error) |
171 | goto err_free_device; | ||
153 | 172 | ||
154 | return 0; | 173 | return 0; |
174 | |||
175 | err_free_device: | ||
176 | platform_device_put(q40kbd_device); | ||
177 | err_unregister_driver: | ||
178 | platform_driver_unregister(&q40kbd_driver); | ||
179 | return error; | ||
155 | } | 180 | } |
156 | 181 | ||
157 | static void __exit q40kbd_exit(void) | 182 | static void __exit q40kbd_exit(void) |
158 | { | 183 | { |
159 | serio_unregister_port(q40kbd_port); | ||
160 | platform_device_unregister(q40kbd_device); | 184 | platform_device_unregister(q40kbd_device); |
185 | platform_driver_unregister(&q40kbd_driver); | ||
161 | } | 186 | } |
162 | 187 | ||
163 | module_init(q40kbd_init); | 188 | module_init(q40kbd_init); |
diff --git a/drivers/usb/input/appletouch.c b/drivers/usb/input/appletouch.c index 1949b54f41f2..c222ed13deab 100644 --- a/drivers/usb/input/appletouch.c +++ b/drivers/usb/input/appletouch.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * Copyright (C) 2005 Stelian Pop (stelian@popies.net) | 6 | * Copyright (C) 2005 Stelian Pop (stelian@popies.net) |
7 | * Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de) | 7 | * Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de) |
8 | * Copyright (C) 2005 Peter Osterlund (petero2@telia.com) | 8 | * Copyright (C) 2005 Peter Osterlund (petero2@telia.com) |
9 | * Copyright (C) 2005 Michael Hanselmann (linux-kernel@hansmi.ch) | ||
9 | * | 10 | * |
10 | * Thanks to Alex Harper <basilisk@foobox.net> for his inputs. | 11 | * Thanks to Alex Harper <basilisk@foobox.net> for his inputs. |
11 | * | 12 | * |
@@ -38,6 +39,11 @@ | |||
38 | /* Apple has powerbooks which have the keyboard with different Product IDs */ | 39 | /* Apple has powerbooks which have the keyboard with different Product IDs */ |
39 | #define APPLE_VENDOR_ID 0x05AC | 40 | #define APPLE_VENDOR_ID 0x05AC |
40 | 41 | ||
42 | /* These names come from Info.plist in AppleUSBTrackpad.kext */ | ||
43 | #define GEYSER_ANSI_PRODUCT_ID 0x0214 | ||
44 | #define GEYSER_ISO_PRODUCT_ID 0x0215 | ||
45 | #define GEYSER_JIS_PRODUCT_ID 0x0216 | ||
46 | |||
41 | #define ATP_DEVICE(prod) \ | 47 | #define ATP_DEVICE(prod) \ |
42 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ | 48 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ |
43 | USB_DEVICE_ID_MATCH_INT_CLASS | \ | 49 | USB_DEVICE_ID_MATCH_INT_CLASS | \ |
@@ -53,13 +59,17 @@ static struct usb_device_id atp_table [] = { | |||
53 | { ATP_DEVICE(0x020F) }, | 59 | { ATP_DEVICE(0x020F) }, |
54 | { ATP_DEVICE(0x030A) }, | 60 | { ATP_DEVICE(0x030A) }, |
55 | { ATP_DEVICE(0x030B) }, | 61 | { ATP_DEVICE(0x030B) }, |
56 | { } /* Terminating entry */ | 62 | |
63 | /* PowerBooks Oct 2005 */ | ||
64 | { ATP_DEVICE(GEYSER_ANSI_PRODUCT_ID) }, | ||
65 | { ATP_DEVICE(GEYSER_ISO_PRODUCT_ID) }, | ||
66 | { ATP_DEVICE(GEYSER_JIS_PRODUCT_ID) }, | ||
67 | |||
68 | /* Terminating entry */ | ||
69 | { } | ||
57 | }; | 70 | }; |
58 | MODULE_DEVICE_TABLE (usb, atp_table); | 71 | MODULE_DEVICE_TABLE (usb, atp_table); |
59 | 72 | ||
60 | /* size of a USB urb transfer */ | ||
61 | #define ATP_DATASIZE 81 | ||
62 | |||
63 | /* | 73 | /* |
64 | * number of sensors. Note that only 16 instead of 26 X (horizontal) | 74 | * number of sensors. Note that only 16 instead of 26 X (horizontal) |
65 | * sensors exist on 12" and 15" PowerBooks. All models have 16 Y | 75 | * sensors exist on 12" and 15" PowerBooks. All models have 16 Y |
@@ -108,6 +118,8 @@ struct atp { | |||
108 | signed char xy_old[ATP_XSENSORS + ATP_YSENSORS]; | 118 | signed char xy_old[ATP_XSENSORS + ATP_YSENSORS]; |
109 | /* accumulated sensors */ | 119 | /* accumulated sensors */ |
110 | int xy_acc[ATP_XSENSORS + ATP_YSENSORS]; | 120 | int xy_acc[ATP_XSENSORS + ATP_YSENSORS]; |
121 | int overflowwarn; /* overflow warning printed? */ | ||
122 | int datalen; /* size of an USB urb transfer */ | ||
111 | }; | 123 | }; |
112 | 124 | ||
113 | #define dbg_dump(msg, tab) \ | 125 | #define dbg_dump(msg, tab) \ |
@@ -124,7 +136,7 @@ struct atp { | |||
124 | if (debug) printk(format, ##a); \ | 136 | if (debug) printk(format, ##a); \ |
125 | } while (0) | 137 | } while (0) |
126 | 138 | ||
127 | MODULE_AUTHOR("Johannes Berg, Stelian Pop, Frank Arnold"); | 139 | MODULE_AUTHOR("Johannes Berg, Stelian Pop, Frank Arnold, Michael Hanselmann"); |
128 | MODULE_DESCRIPTION("Apple PowerBooks USB touchpad driver"); | 140 | MODULE_DESCRIPTION("Apple PowerBooks USB touchpad driver"); |
129 | MODULE_LICENSE("GPL"); | 141 | MODULE_LICENSE("GPL"); |
130 | 142 | ||
@@ -132,6 +144,16 @@ static int debug = 1; | |||
132 | module_param(debug, int, 0644); | 144 | module_param(debug, int, 0644); |
133 | MODULE_PARM_DESC(debug, "Activate debugging output"); | 145 | MODULE_PARM_DESC(debug, "Activate debugging output"); |
134 | 146 | ||
147 | /* Checks if the device a Geyser 2 (ANSI, ISO, JIS) */ | ||
148 | static inline int atp_is_geyser_2(struct atp *dev) | ||
149 | { | ||
150 | int16_t productId = le16_to_cpu(dev->udev->descriptor.idProduct); | ||
151 | |||
152 | return (productId == GEYSER_ANSI_PRODUCT_ID) || | ||
153 | (productId == GEYSER_ISO_PRODUCT_ID) || | ||
154 | (productId == GEYSER_JIS_PRODUCT_ID); | ||
155 | } | ||
156 | |||
135 | static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact, | 157 | static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact, |
136 | int *z, int *fingers) | 158 | int *z, int *fingers) |
137 | { | 159 | { |
@@ -168,13 +190,20 @@ static inline void atp_report_fingers(struct input_dev *input, int fingers) | |||
168 | static void atp_complete(struct urb* urb, struct pt_regs* regs) | 190 | static void atp_complete(struct urb* urb, struct pt_regs* regs) |
169 | { | 191 | { |
170 | int x, y, x_z, y_z, x_f, y_f; | 192 | int x, y, x_z, y_z, x_f, y_f; |
171 | int retval, i; | 193 | int retval, i, j; |
172 | struct atp *dev = urb->context; | 194 | struct atp *dev = urb->context; |
173 | 195 | ||
174 | switch (urb->status) { | 196 | switch (urb->status) { |
175 | case 0: | 197 | case 0: |
176 | /* success */ | 198 | /* success */ |
177 | break; | 199 | break; |
200 | case -EOVERFLOW: | ||
201 | if(!dev->overflowwarn) { | ||
202 | printk("appletouch: OVERFLOW with data " | ||
203 | "length %d, actual length is %d\n", | ||
204 | dev->datalen, dev->urb->actual_length); | ||
205 | dev->overflowwarn = 1; | ||
206 | } | ||
178 | case -ECONNRESET: | 207 | case -ECONNRESET: |
179 | case -ENOENT: | 208 | case -ENOENT: |
180 | case -ESHUTDOWN: | 209 | case -ESHUTDOWN: |
@@ -189,23 +218,45 @@ static void atp_complete(struct urb* urb, struct pt_regs* regs) | |||
189 | } | 218 | } |
190 | 219 | ||
191 | /* drop incomplete datasets */ | 220 | /* drop incomplete datasets */ |
192 | if (dev->urb->actual_length != ATP_DATASIZE) { | 221 | if (dev->urb->actual_length != dev->datalen) { |
193 | dprintk("appletouch: incomplete data package.\n"); | 222 | dprintk("appletouch: incomplete data package.\n"); |
194 | goto exit; | 223 | goto exit; |
195 | } | 224 | } |
196 | 225 | ||
197 | /* reorder the sensors values */ | 226 | /* reorder the sensors values */ |
198 | for (i = 0; i < 8; i++) { | 227 | if (atp_is_geyser_2(dev)) { |
199 | /* X values */ | 228 | memset(dev->xy_cur, 0, sizeof(dev->xy_cur)); |
200 | dev->xy_cur[i ] = dev->data[5 * i + 2]; | 229 | |
201 | dev->xy_cur[i + 8] = dev->data[5 * i + 4]; | 230 | /* |
202 | dev->xy_cur[i + 16] = dev->data[5 * i + 42]; | 231 | * The values are laid out like this: |
203 | if (i < 2) | 232 | * Y1, Y2, -, Y3, Y4, -, ..., X1, X2, -, X3, X4, -, ... |
204 | dev->xy_cur[i + 24] = dev->data[5 * i + 44]; | 233 | * '-' is an unused value. |
205 | 234 | */ | |
206 | /* Y values */ | 235 | |
207 | dev->xy_cur[i + 26] = dev->data[5 * i + 1]; | 236 | /* read X values */ |
208 | dev->xy_cur[i + 34] = dev->data[5 * i + 3]; | 237 | for (i = 0, j = 19; i < 20; i += 2, j += 3) { |
238 | dev->xy_cur[i] = dev->data[j]; | ||
239 | dev->xy_cur[i + 1] = dev->data[j + 1]; | ||
240 | } | ||
241 | |||
242 | /* read Y values */ | ||
243 | for (i = 0, j = 1; i < 9; i += 2, j += 3) { | ||
244 | dev->xy_cur[ATP_XSENSORS + i] = dev->data[j]; | ||
245 | dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 1]; | ||
246 | } | ||
247 | } else { | ||
248 | for (i = 0; i < 8; i++) { | ||
249 | /* X values */ | ||
250 | dev->xy_cur[i ] = dev->data[5 * i + 2]; | ||
251 | dev->xy_cur[i + 8] = dev->data[5 * i + 4]; | ||
252 | dev->xy_cur[i + 16] = dev->data[5 * i + 42]; | ||
253 | if (i < 2) | ||
254 | dev->xy_cur[i + 24] = dev->data[5 * i + 44]; | ||
255 | |||
256 | /* Y values */ | ||
257 | dev->xy_cur[i + 26] = dev->data[5 * i + 1]; | ||
258 | dev->xy_cur[i + 34] = dev->data[5 * i + 3]; | ||
259 | } | ||
209 | } | 260 | } |
210 | 261 | ||
211 | dbg_dump("sample", dev->xy_cur); | 262 | dbg_dump("sample", dev->xy_cur); |
@@ -216,16 +267,24 @@ static void atp_complete(struct urb* urb, struct pt_regs* regs) | |||
216 | dev->x_old = dev->y_old = -1; | 267 | dev->x_old = dev->y_old = -1; |
217 | memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old)); | 268 | memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old)); |
218 | 269 | ||
219 | /* 17" Powerbooks have 10 extra X sensors */ | 270 | /* 17" Powerbooks have extra X sensors */ |
220 | for (i = 16; i < ATP_XSENSORS; i++) | 271 | for (i = (atp_is_geyser_2(dev)?15:16); i < ATP_XSENSORS; i++) { |
221 | if (dev->xy_cur[i]) { | 272 | if (!dev->xy_cur[i]) continue; |
222 | printk("appletouch: 17\" model detected.\n"); | 273 | |
274 | printk("appletouch: 17\" model detected.\n"); | ||
275 | if(atp_is_geyser_2(dev)) | ||
276 | input_set_abs_params(dev->input, ABS_X, 0, | ||
277 | (20 - 1) * | ||
278 | ATP_XFACT - 1, | ||
279 | ATP_FUZZ, 0); | ||
280 | else | ||
223 | input_set_abs_params(dev->input, ABS_X, 0, | 281 | input_set_abs_params(dev->input, ABS_X, 0, |
224 | (ATP_XSENSORS - 1) * | 282 | (ATP_XSENSORS - 1) * |
225 | ATP_XFACT - 1, | 283 | ATP_XFACT - 1, |
226 | ATP_FUZZ, 0); | 284 | ATP_FUZZ, 0); |
227 | break; | 285 | |
228 | } | 286 | break; |
287 | } | ||
229 | 288 | ||
230 | goto exit; | 289 | goto exit; |
231 | } | 290 | } |
@@ -282,7 +341,8 @@ static void atp_complete(struct urb* urb, struct pt_regs* regs) | |||
282 | memset(dev->xy_acc, 0, sizeof(dev->xy_acc)); | 341 | memset(dev->xy_acc, 0, sizeof(dev->xy_acc)); |
283 | } | 342 | } |
284 | 343 | ||
285 | input_report_key(dev->input, BTN_LEFT, !!dev->data[80]); | 344 | input_report_key(dev->input, BTN_LEFT, |
345 | !!dev->data[dev->datalen - 1]); | ||
286 | 346 | ||
287 | input_sync(dev->input); | 347 | input_sync(dev->input); |
288 | 348 | ||
@@ -353,6 +413,8 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id | |||
353 | 413 | ||
354 | dev->udev = udev; | 414 | dev->udev = udev; |
355 | dev->input = input_dev; | 415 | dev->input = input_dev; |
416 | dev->overflowwarn = 0; | ||
417 | dev->datalen = (atp_is_geyser_2(dev)?64:81); | ||
356 | 418 | ||
357 | dev->urb = usb_alloc_urb(0, GFP_KERNEL); | 419 | dev->urb = usb_alloc_urb(0, GFP_KERNEL); |
358 | if (!dev->urb) { | 420 | if (!dev->urb) { |
@@ -360,7 +422,7 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id | |||
360 | goto err_free_devs; | 422 | goto err_free_devs; |
361 | } | 423 | } |
362 | 424 | ||
363 | dev->data = usb_buffer_alloc(dev->udev, ATP_DATASIZE, GFP_KERNEL, | 425 | dev->data = usb_buffer_alloc(dev->udev, dev->datalen, GFP_KERNEL, |
364 | &dev->urb->transfer_dma); | 426 | &dev->urb->transfer_dma); |
365 | if (!dev->data) { | 427 | if (!dev->data) { |
366 | retval = -ENOMEM; | 428 | retval = -ENOMEM; |
@@ -369,7 +431,7 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id | |||
369 | 431 | ||
370 | usb_fill_int_urb(dev->urb, udev, | 432 | usb_fill_int_urb(dev->urb, udev, |
371 | usb_rcvintpipe(udev, int_in_endpointAddr), | 433 | usb_rcvintpipe(udev, int_in_endpointAddr), |
372 | dev->data, ATP_DATASIZE, atp_complete, dev, 1); | 434 | dev->data, dev->datalen, atp_complete, dev, 1); |
373 | 435 | ||
374 | usb_make_path(udev, dev->phys, sizeof(dev->phys)); | 436 | usb_make_path(udev, dev->phys, sizeof(dev->phys)); |
375 | strlcat(dev->phys, "/input0", sizeof(dev->phys)); | 437 | strlcat(dev->phys, "/input0", sizeof(dev->phys)); |
@@ -385,14 +447,25 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id | |||
385 | 447 | ||
386 | set_bit(EV_ABS, input_dev->evbit); | 448 | set_bit(EV_ABS, input_dev->evbit); |
387 | 449 | ||
388 | /* | 450 | if (atp_is_geyser_2(dev)) { |
389 | * 12" and 15" Powerbooks only have 16 x sensors, | 451 | /* |
390 | * 17" models are detected later. | 452 | * Oct 2005 15" PowerBooks have 15 X sensors, 17" are detected |
391 | */ | 453 | * later. |
392 | input_set_abs_params(input_dev, ABS_X, 0, | 454 | */ |
393 | (16 - 1) * ATP_XFACT - 1, ATP_FUZZ, 0); | 455 | input_set_abs_params(input_dev, ABS_X, 0, |
394 | input_set_abs_params(input_dev, ABS_Y, 0, | 456 | ((15 - 1) * ATP_XFACT) - 1, ATP_FUZZ, 0); |
395 | (ATP_YSENSORS - 1) * ATP_YFACT - 1, ATP_FUZZ, 0); | 457 | input_set_abs_params(input_dev, ABS_Y, 0, |
458 | ((9 - 1) * ATP_YFACT) - 1, ATP_FUZZ, 0); | ||
459 | } else { | ||
460 | /* | ||
461 | * 12" and 15" Powerbooks only have 16 x sensors, | ||
462 | * 17" models are detected later. | ||
463 | */ | ||
464 | input_set_abs_params(input_dev, ABS_X, 0, | ||
465 | (16 - 1) * ATP_XFACT - 1, ATP_FUZZ, 0); | ||
466 | input_set_abs_params(input_dev, ABS_Y, 0, | ||
467 | (ATP_YSENSORS - 1) * ATP_YFACT - 1, ATP_FUZZ, 0); | ||
468 | } | ||
396 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0); | 469 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0); |
397 | 470 | ||
398 | set_bit(EV_KEY, input_dev->evbit); | 471 | set_bit(EV_KEY, input_dev->evbit); |
@@ -427,7 +500,7 @@ static void atp_disconnect(struct usb_interface *iface) | |||
427 | usb_kill_urb(dev->urb); | 500 | usb_kill_urb(dev->urb); |
428 | input_unregister_device(dev->input); | 501 | input_unregister_device(dev->input); |
429 | usb_free_urb(dev->urb); | 502 | usb_free_urb(dev->urb); |
430 | usb_buffer_free(dev->udev, ATP_DATASIZE, | 503 | usb_buffer_free(dev->udev, dev->datalen, |
431 | dev->data, dev->urb->transfer_dma); | 504 | dev->data, dev->urb->transfer_dma); |
432 | kfree(dev); | 505 | kfree(dev); |
433 | } | 506 | } |
diff --git a/drivers/usb/input/hid-debug.h b/drivers/usb/input/hid-debug.h index ceebab99eff2..4a42162ee2ea 100644 --- a/drivers/usb/input/hid-debug.h +++ b/drivers/usb/input/hid-debug.h | |||
@@ -681,6 +681,7 @@ static char *keys[KEY_MAX + 1] = { | |||
681 | [KEY_SEND] = "Send", [KEY_REPLY] = "Reply", | 681 | [KEY_SEND] = "Send", [KEY_REPLY] = "Reply", |
682 | [KEY_FORWARDMAIL] = "ForwardMail", [KEY_SAVE] = "Save", | 682 | [KEY_FORWARDMAIL] = "ForwardMail", [KEY_SAVE] = "Save", |
683 | [KEY_DOCUMENTS] = "Documents", | 683 | [KEY_DOCUMENTS] = "Documents", |
684 | [KEY_FN] = "Fn", | ||
684 | }; | 685 | }; |
685 | 686 | ||
686 | static char *relatives[REL_MAX + 1] = { | 687 | static char *relatives[REL_MAX + 1] = { |