diff options
Diffstat (limited to 'drivers/input')
97 files changed, 3926 insertions, 1659 deletions
diff --git a/drivers/input/Makefile b/drivers/input/Makefile index da575deb3c7a..b4cd10653c4f 100644 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile | |||
@@ -13,7 +13,6 @@ obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o | |||
13 | obj-$(CONFIG_INPUT_JOYDEV) += joydev.o | 13 | obj-$(CONFIG_INPUT_JOYDEV) += joydev.o |
14 | obj-$(CONFIG_INPUT_EVDEV) += evdev.o | 14 | obj-$(CONFIG_INPUT_EVDEV) += evdev.o |
15 | obj-$(CONFIG_INPUT_TSDEV) += tsdev.o | 15 | obj-$(CONFIG_INPUT_TSDEV) += tsdev.o |
16 | obj-$(CONFIG_INPUT_POWER) += power.o | ||
17 | obj-$(CONFIG_INPUT_EVBUG) += evbug.o | 16 | obj-$(CONFIG_INPUT_EVBUG) += evbug.o |
18 | 17 | ||
19 | obj-$(CONFIG_INPUT_KEYBOARD) += keyboard/ | 18 | obj-$(CONFIG_INPUT_KEYBOARD) += keyboard/ |
diff --git a/drivers/input/evbug.c b/drivers/input/evbug.c index 5a9653c3128a..c21f2f127234 100644 --- a/drivers/input/evbug.c +++ b/drivers/input/evbug.c | |||
@@ -38,31 +38,43 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); | |||
38 | MODULE_DESCRIPTION("Input driver event debug module"); | 38 | MODULE_DESCRIPTION("Input driver event debug module"); |
39 | MODULE_LICENSE("GPL"); | 39 | MODULE_LICENSE("GPL"); |
40 | 40 | ||
41 | static char evbug_name[] = "evbug"; | ||
42 | |||
43 | static void evbug_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) | 41 | static void evbug_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) |
44 | { | 42 | { |
45 | printk(KERN_DEBUG "evbug.c: Event. Dev: %s, Type: %d, Code: %d, Value: %d\n", | 43 | printk(KERN_DEBUG "evbug.c: Event. Dev: %s, Type: %d, Code: %d, Value: %d\n", |
46 | handle->dev->phys, type, code, value); | 44 | handle->dev->phys, type, code, value); |
47 | } | 45 | } |
48 | 46 | ||
49 | static struct input_handle *evbug_connect(struct input_handler *handler, struct input_dev *dev, | 47 | static int evbug_connect(struct input_handler *handler, struct input_dev *dev, |
50 | const struct input_device_id *id) | 48 | const struct input_device_id *id) |
51 | { | 49 | { |
52 | struct input_handle *handle; | 50 | struct input_handle *handle; |
51 | int error; | ||
53 | 52 | ||
54 | if (!(handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL))) | 53 | handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); |
55 | return NULL; | 54 | if (!handle) |
55 | return -ENOMEM; | ||
56 | 56 | ||
57 | handle->dev = dev; | 57 | handle->dev = dev; |
58 | handle->handler = handler; | 58 | handle->handler = handler; |
59 | handle->name = evbug_name; | 59 | handle->name = "evbug"; |
60 | |||
61 | error = input_register_handle(handle); | ||
62 | if (error) | ||
63 | goto err_free_handle; | ||
60 | 64 | ||
61 | input_open_device(handle); | 65 | error = input_open_device(handle); |
66 | if (error) | ||
67 | goto err_unregister_handle; | ||
62 | 68 | ||
63 | printk(KERN_DEBUG "evbug.c: Connected device: \"%s\", %s\n", dev->name, dev->phys); | 69 | printk(KERN_DEBUG "evbug.c: Connected device: \"%s\", %s\n", dev->name, dev->phys); |
64 | 70 | ||
65 | return handle; | 71 | return 0; |
72 | |||
73 | err_unregister_handle: | ||
74 | input_unregister_handle(handle); | ||
75 | err_free_handle: | ||
76 | kfree(handle); | ||
77 | return error; | ||
66 | } | 78 | } |
67 | 79 | ||
68 | static void evbug_disconnect(struct input_handle *handle) | 80 | static void evbug_disconnect(struct input_handle *handle) |
@@ -70,7 +82,7 @@ static void evbug_disconnect(struct input_handle *handle) | |||
70 | printk(KERN_DEBUG "evbug.c: Disconnected device: %s\n", handle->dev->phys); | 82 | printk(KERN_DEBUG "evbug.c: Disconnected device: %s\n", handle->dev->phys); |
71 | 83 | ||
72 | input_close_device(handle); | 84 | input_close_device(handle); |
73 | 85 | input_unregister_handle(handle); | |
74 | kfree(handle); | 86 | kfree(handle); |
75 | } | 87 | } |
76 | 88 | ||
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 6439f378f6cc..1f6fcec0c6fc 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -29,11 +29,11 @@ struct evdev { | |||
29 | char name[16]; | 29 | char name[16]; |
30 | struct input_handle handle; | 30 | struct input_handle handle; |
31 | wait_queue_head_t wait; | 31 | wait_queue_head_t wait; |
32 | struct evdev_list *grab; | 32 | struct evdev_client *grab; |
33 | struct list_head list; | 33 | struct list_head client_list; |
34 | }; | 34 | }; |
35 | 35 | ||
36 | struct evdev_list { | 36 | struct evdev_client { |
37 | struct input_event buffer[EVDEV_BUFFER_SIZE]; | 37 | struct input_event buffer[EVDEV_BUFFER_SIZE]; |
38 | int head; | 38 | int head; |
39 | int tail; | 39 | int tail; |
@@ -47,28 +47,28 @@ static struct evdev *evdev_table[EVDEV_MINORS]; | |||
47 | static void evdev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) | 47 | static void evdev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) |
48 | { | 48 | { |
49 | struct evdev *evdev = handle->private; | 49 | struct evdev *evdev = handle->private; |
50 | struct evdev_list *list; | 50 | struct evdev_client *client; |
51 | 51 | ||
52 | if (evdev->grab) { | 52 | if (evdev->grab) { |
53 | list = evdev->grab; | 53 | client = evdev->grab; |
54 | 54 | ||
55 | do_gettimeofday(&list->buffer[list->head].time); | 55 | do_gettimeofday(&client->buffer[client->head].time); |
56 | list->buffer[list->head].type = type; | 56 | client->buffer[client->head].type = type; |
57 | list->buffer[list->head].code = code; | 57 | client->buffer[client->head].code = code; |
58 | list->buffer[list->head].value = value; | 58 | client->buffer[client->head].value = value; |
59 | list->head = (list->head + 1) & (EVDEV_BUFFER_SIZE - 1); | 59 | client->head = (client->head + 1) & (EVDEV_BUFFER_SIZE - 1); |
60 | 60 | ||
61 | kill_fasync(&list->fasync, SIGIO, POLL_IN); | 61 | kill_fasync(&client->fasync, SIGIO, POLL_IN); |
62 | } else | 62 | } else |
63 | list_for_each_entry(list, &evdev->list, node) { | 63 | list_for_each_entry(client, &evdev->client_list, node) { |
64 | 64 | ||
65 | do_gettimeofday(&list->buffer[list->head].time); | 65 | do_gettimeofday(&client->buffer[client->head].time); |
66 | list->buffer[list->head].type = type; | 66 | client->buffer[client->head].type = type; |
67 | list->buffer[list->head].code = code; | 67 | client->buffer[client->head].code = code; |
68 | list->buffer[list->head].value = value; | 68 | client->buffer[client->head].value = value; |
69 | list->head = (list->head + 1) & (EVDEV_BUFFER_SIZE - 1); | 69 | client->head = (client->head + 1) & (EVDEV_BUFFER_SIZE - 1); |
70 | 70 | ||
71 | kill_fasync(&list->fasync, SIGIO, POLL_IN); | 71 | kill_fasync(&client->fasync, SIGIO, POLL_IN); |
72 | } | 72 | } |
73 | 73 | ||
74 | wake_up_interruptible(&evdev->wait); | 74 | wake_up_interruptible(&evdev->wait); |
@@ -76,22 +76,23 @@ static void evdev_event(struct input_handle *handle, unsigned int type, unsigned | |||
76 | 76 | ||
77 | static int evdev_fasync(int fd, struct file *file, int on) | 77 | static int evdev_fasync(int fd, struct file *file, int on) |
78 | { | 78 | { |
79 | struct evdev_client *client = file->private_data; | ||
79 | int retval; | 80 | int retval; |
80 | struct evdev_list *list = file->private_data; | ||
81 | 81 | ||
82 | retval = fasync_helper(fd, file, on, &list->fasync); | 82 | retval = fasync_helper(fd, file, on, &client->fasync); |
83 | 83 | ||
84 | return retval < 0 ? retval : 0; | 84 | return retval < 0 ? retval : 0; |
85 | } | 85 | } |
86 | 86 | ||
87 | static int evdev_flush(struct file *file, fl_owner_t id) | 87 | static int evdev_flush(struct file *file, fl_owner_t id) |
88 | { | 88 | { |
89 | struct evdev_list *list = file->private_data; | 89 | struct evdev_client *client = file->private_data; |
90 | struct evdev *evdev = client->evdev; | ||
90 | 91 | ||
91 | if (!list->evdev->exist) | 92 | if (!evdev->exist) |
92 | return -ENODEV; | 93 | return -ENODEV; |
93 | 94 | ||
94 | return input_flush_device(&list->evdev->handle, file); | 95 | return input_flush_device(&evdev->handle, file); |
95 | } | 96 | } |
96 | 97 | ||
97 | static void evdev_free(struct evdev *evdev) | 98 | static void evdev_free(struct evdev *evdev) |
@@ -100,48 +101,62 @@ static void evdev_free(struct evdev *evdev) | |||
100 | kfree(evdev); | 101 | kfree(evdev); |
101 | } | 102 | } |
102 | 103 | ||
103 | static int evdev_release(struct inode * inode, struct file * file) | 104 | static int evdev_release(struct inode *inode, struct file *file) |
104 | { | 105 | { |
105 | struct evdev_list *list = file->private_data; | 106 | struct evdev_client *client = file->private_data; |
107 | struct evdev *evdev = client->evdev; | ||
106 | 108 | ||
107 | if (list->evdev->grab == list) { | 109 | if (evdev->grab == client) { |
108 | input_release_device(&list->evdev->handle); | 110 | input_release_device(&evdev->handle); |
109 | list->evdev->grab = NULL; | 111 | evdev->grab = NULL; |
110 | } | 112 | } |
111 | 113 | ||
112 | evdev_fasync(-1, file, 0); | 114 | evdev_fasync(-1, file, 0); |
113 | list_del(&list->node); | 115 | list_del(&client->node); |
116 | kfree(client); | ||
114 | 117 | ||
115 | if (!--list->evdev->open) { | 118 | if (!--evdev->open) { |
116 | if (list->evdev->exist) | 119 | if (evdev->exist) |
117 | input_close_device(&list->evdev->handle); | 120 | input_close_device(&evdev->handle); |
118 | else | 121 | else |
119 | evdev_free(list->evdev); | 122 | evdev_free(evdev); |
120 | } | 123 | } |
121 | 124 | ||
122 | kfree(list); | ||
123 | return 0; | 125 | return 0; |
124 | } | 126 | } |
125 | 127 | ||
126 | static int evdev_open(struct inode * inode, struct file * file) | 128 | static int evdev_open(struct inode *inode, struct file *file) |
127 | { | 129 | { |
128 | struct evdev_list *list; | 130 | struct evdev_client *client; |
131 | struct evdev *evdev; | ||
129 | int i = iminor(inode) - EVDEV_MINOR_BASE; | 132 | int i = iminor(inode) - EVDEV_MINOR_BASE; |
133 | int error; | ||
130 | 134 | ||
131 | if (i >= EVDEV_MINORS || !evdev_table[i] || !evdev_table[i]->exist) | 135 | if (i >= EVDEV_MINORS) |
132 | return -ENODEV; | 136 | return -ENODEV; |
133 | 137 | ||
134 | if (!(list = kzalloc(sizeof(struct evdev_list), GFP_KERNEL))) | 138 | evdev = evdev_table[i]; |
139 | |||
140 | if (!evdev || !evdev->exist) | ||
141 | return -ENODEV; | ||
142 | |||
143 | client = kzalloc(sizeof(struct evdev_client), GFP_KERNEL); | ||
144 | if (!client) | ||
135 | return -ENOMEM; | 145 | return -ENOMEM; |
136 | 146 | ||
137 | list->evdev = evdev_table[i]; | 147 | client->evdev = evdev; |
138 | list_add_tail(&list->node, &evdev_table[i]->list); | 148 | list_add_tail(&client->node, &evdev->client_list); |
139 | file->private_data = list; | ||
140 | 149 | ||
141 | if (!list->evdev->open++) | 150 | if (!evdev->open++ && evdev->exist) { |
142 | if (list->evdev->exist) | 151 | error = input_open_device(&evdev->handle); |
143 | input_open_device(&list->evdev->handle); | 152 | if (error) { |
153 | list_del(&client->node); | ||
154 | kfree(client); | ||
155 | return error; | ||
156 | } | ||
157 | } | ||
144 | 158 | ||
159 | file->private_data = client; | ||
145 | return 0; | 160 | return 0; |
146 | } | 161 | } |
147 | 162 | ||
@@ -243,54 +258,55 @@ static int evdev_event_to_user(char __user *buffer, const struct input_event *ev | |||
243 | 258 | ||
244 | #endif /* CONFIG_COMPAT */ | 259 | #endif /* CONFIG_COMPAT */ |
245 | 260 | ||
246 | static ssize_t evdev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos) | 261 | static ssize_t evdev_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) |
247 | { | 262 | { |
248 | struct evdev_list *list = file->private_data; | 263 | struct evdev_client *client = file->private_data; |
264 | struct evdev *evdev = client->evdev; | ||
249 | struct input_event event; | 265 | struct input_event event; |
250 | int retval = 0; | 266 | int retval = 0; |
251 | 267 | ||
252 | if (!list->evdev->exist) | 268 | if (!evdev->exist) |
253 | return -ENODEV; | 269 | return -ENODEV; |
254 | 270 | ||
255 | while (retval < count) { | 271 | while (retval < count) { |
256 | 272 | ||
257 | if (evdev_event_from_user(buffer + retval, &event)) | 273 | if (evdev_event_from_user(buffer + retval, &event)) |
258 | return -EFAULT; | 274 | return -EFAULT; |
259 | input_inject_event(&list->evdev->handle, event.type, event.code, event.value); | 275 | input_inject_event(&evdev->handle, event.type, event.code, event.value); |
260 | retval += evdev_event_size(); | 276 | retval += evdev_event_size(); |
261 | } | 277 | } |
262 | 278 | ||
263 | return retval; | 279 | return retval; |
264 | } | 280 | } |
265 | 281 | ||
266 | static ssize_t evdev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos) | 282 | static ssize_t evdev_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) |
267 | { | 283 | { |
268 | struct evdev_list *list = file->private_data; | 284 | struct evdev_client *client = file->private_data; |
285 | struct evdev *evdev = client->evdev; | ||
269 | int retval; | 286 | int retval; |
270 | 287 | ||
271 | if (count < evdev_event_size()) | 288 | if (count < evdev_event_size()) |
272 | return -EINVAL; | 289 | return -EINVAL; |
273 | 290 | ||
274 | if (list->head == list->tail && list->evdev->exist && (file->f_flags & O_NONBLOCK)) | 291 | if (client->head == client->tail && evdev->exist && (file->f_flags & O_NONBLOCK)) |
275 | return -EAGAIN; | 292 | return -EAGAIN; |
276 | 293 | ||
277 | retval = wait_event_interruptible(list->evdev->wait, | 294 | retval = wait_event_interruptible(evdev->wait, |
278 | list->head != list->tail || (!list->evdev->exist)); | 295 | client->head != client->tail || !evdev->exist); |
279 | |||
280 | if (retval) | 296 | if (retval) |
281 | return retval; | 297 | return retval; |
282 | 298 | ||
283 | if (!list->evdev->exist) | 299 | if (!evdev->exist) |
284 | return -ENODEV; | 300 | return -ENODEV; |
285 | 301 | ||
286 | while (list->head != list->tail && retval + evdev_event_size() <= count) { | 302 | while (client->head != client->tail && retval + evdev_event_size() <= count) { |
287 | 303 | ||
288 | struct input_event *event = (struct input_event *) list->buffer + list->tail; | 304 | struct input_event *event = (struct input_event *) client->buffer + client->tail; |
289 | 305 | ||
290 | if (evdev_event_to_user(buffer + retval, event)) | 306 | if (evdev_event_to_user(buffer + retval, event)) |
291 | return -EFAULT; | 307 | return -EFAULT; |
292 | 308 | ||
293 | list->tail = (list->tail + 1) & (EVDEV_BUFFER_SIZE - 1); | 309 | client->tail = (client->tail + 1) & (EVDEV_BUFFER_SIZE - 1); |
294 | retval += evdev_event_size(); | 310 | retval += evdev_event_size(); |
295 | } | 311 | } |
296 | 312 | ||
@@ -300,11 +316,12 @@ static ssize_t evdev_read(struct file * file, char __user * buffer, size_t count | |||
300 | /* No kernel lock - fine */ | 316 | /* No kernel lock - fine */ |
301 | static unsigned int evdev_poll(struct file *file, poll_table *wait) | 317 | static unsigned int evdev_poll(struct file *file, poll_table *wait) |
302 | { | 318 | { |
303 | struct evdev_list *list = file->private_data; | 319 | struct evdev_client *client = file->private_data; |
320 | struct evdev *evdev = client->evdev; | ||
304 | 321 | ||
305 | poll_wait(file, &list->evdev->wait, wait); | 322 | poll_wait(file, &evdev->wait, wait); |
306 | return ((list->head == list->tail) ? 0 : (POLLIN | POLLRDNORM)) | | 323 | return ((client->head == client->tail) ? 0 : (POLLIN | POLLRDNORM)) | |
307 | (list->evdev->exist ? 0 : (POLLHUP | POLLERR)); | 324 | (evdev->exist ? 0 : (POLLHUP | POLLERR)); |
308 | } | 325 | } |
309 | 326 | ||
310 | #ifdef CONFIG_COMPAT | 327 | #ifdef CONFIG_COMPAT |
@@ -387,8 +404,8 @@ static int str_to_user(const char *str, unsigned int maxlen, void __user *p) | |||
387 | static long evdev_ioctl_handler(struct file *file, unsigned int cmd, | 404 | static long evdev_ioctl_handler(struct file *file, unsigned int cmd, |
388 | void __user *p, int compat_mode) | 405 | void __user *p, int compat_mode) |
389 | { | 406 | { |
390 | struct evdev_list *list = file->private_data; | 407 | struct evdev_client *client = file->private_data; |
391 | struct evdev *evdev = list->evdev; | 408 | struct evdev *evdev = client->evdev; |
392 | struct input_dev *dev = evdev->handle.dev; | 409 | struct input_dev *dev = evdev->handle.dev; |
393 | struct input_absinfo abs; | 410 | struct input_absinfo abs; |
394 | struct ff_effect effect; | 411 | struct ff_effect effect; |
@@ -434,32 +451,21 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd, | |||
434 | case EVIOCGKEYCODE: | 451 | case EVIOCGKEYCODE: |
435 | if (get_user(t, ip)) | 452 | if (get_user(t, ip)) |
436 | return -EFAULT; | 453 | return -EFAULT; |
437 | if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) | 454 | |
438 | return -EINVAL; | 455 | error = dev->getkeycode(dev, t, &v); |
439 | if (put_user(INPUT_KEYCODE(dev, t), ip + 1)) | 456 | if (error) |
457 | return error; | ||
458 | |||
459 | if (put_user(v, ip + 1)) | ||
440 | return -EFAULT; | 460 | return -EFAULT; |
461 | |||
441 | return 0; | 462 | return 0; |
442 | 463 | ||
443 | case EVIOCSKEYCODE: | 464 | case EVIOCSKEYCODE: |
444 | if (get_user(t, ip)) | 465 | if (get_user(t, ip) || get_user(v, ip + 1)) |
445 | return -EFAULT; | 466 | return -EFAULT; |
446 | if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) | ||
447 | return -EINVAL; | ||
448 | if (get_user(v, ip + 1)) | ||
449 | return -EFAULT; | ||
450 | if (v < 0 || v > KEY_MAX) | ||
451 | return -EINVAL; | ||
452 | if (dev->keycodesize < sizeof(v) && (v >> (dev->keycodesize * 8))) | ||
453 | return -EINVAL; | ||
454 | |||
455 | u = SET_INPUT_KEYCODE(dev, t, v); | ||
456 | clear_bit(u, dev->keybit); | ||
457 | set_bit(v, dev->keybit); | ||
458 | for (i = 0; i < dev->keycodemax; i++) | ||
459 | if (INPUT_KEYCODE(dev, i) == u) | ||
460 | set_bit(u, dev->keybit); | ||
461 | 467 | ||
462 | return 0; | 468 | return dev->setkeycode(dev, t, v); |
463 | 469 | ||
464 | case EVIOCSFF: | 470 | case EVIOCSFF: |
465 | if (copy_from_user(&effect, p, sizeof(effect))) | 471 | if (copy_from_user(&effect, p, sizeof(effect))) |
@@ -487,10 +493,10 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd, | |||
487 | return -EBUSY; | 493 | return -EBUSY; |
488 | if (input_grab_device(&evdev->handle)) | 494 | if (input_grab_device(&evdev->handle)) |
489 | return -EBUSY; | 495 | return -EBUSY; |
490 | evdev->grab = list; | 496 | evdev->grab = client; |
491 | return 0; | 497 | return 0; |
492 | } else { | 498 | } else { |
493 | if (evdev->grab != list) | 499 | if (evdev->grab != client) |
494 | return -EINVAL; | 500 | return -EINVAL; |
495 | input_release_device(&evdev->handle); | 501 | input_release_device(&evdev->handle); |
496 | evdev->grab = NULL; | 502 | evdev->grab = NULL; |
@@ -616,23 +622,26 @@ static const struct file_operations evdev_fops = { | |||
616 | .flush = evdev_flush | 622 | .flush = evdev_flush |
617 | }; | 623 | }; |
618 | 624 | ||
619 | static struct input_handle *evdev_connect(struct input_handler *handler, struct input_dev *dev, | 625 | static int evdev_connect(struct input_handler *handler, struct input_dev *dev, |
620 | const struct input_device_id *id) | 626 | const struct input_device_id *id) |
621 | { | 627 | { |
622 | struct evdev *evdev; | 628 | struct evdev *evdev; |
623 | struct class_device *cdev; | 629 | struct class_device *cdev; |
630 | dev_t devt; | ||
624 | int minor; | 631 | int minor; |
632 | int error; | ||
625 | 633 | ||
626 | for (minor = 0; minor < EVDEV_MINORS && evdev_table[minor]; minor++); | 634 | for (minor = 0; minor < EVDEV_MINORS && evdev_table[minor]; minor++); |
627 | if (minor == EVDEV_MINORS) { | 635 | if (minor == EVDEV_MINORS) { |
628 | printk(KERN_ERR "evdev: no more free evdev devices\n"); | 636 | printk(KERN_ERR "evdev: no more free evdev devices\n"); |
629 | return NULL; | 637 | return -ENFILE; |
630 | } | 638 | } |
631 | 639 | ||
632 | if (!(evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL))) | 640 | evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL); |
633 | return NULL; | 641 | if (!evdev) |
642 | return -ENOMEM; | ||
634 | 643 | ||
635 | INIT_LIST_HEAD(&evdev->list); | 644 | INIT_LIST_HEAD(&evdev->client_list); |
636 | init_waitqueue_head(&evdev->wait); | 645 | init_waitqueue_head(&evdev->wait); |
637 | 646 | ||
638 | evdev->exist = 1; | 647 | evdev->exist = 1; |
@@ -645,23 +654,45 @@ static struct input_handle *evdev_connect(struct input_handler *handler, struct | |||
645 | 654 | ||
646 | evdev_table[minor] = evdev; | 655 | evdev_table[minor] = evdev; |
647 | 656 | ||
648 | cdev = class_device_create(&input_class, &dev->cdev, | 657 | devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor), |
649 | MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor), | 658 | |
650 | dev->cdev.dev, evdev->name); | 659 | cdev = class_device_create(&input_class, &dev->cdev, devt, |
660 | dev->cdev.dev, evdev->name); | ||
661 | if (IS_ERR(cdev)) { | ||
662 | error = PTR_ERR(cdev); | ||
663 | goto err_free_evdev; | ||
664 | } | ||
651 | 665 | ||
652 | /* temporary symlink to keep userspace happy */ | 666 | /* temporary symlink to keep userspace happy */ |
653 | sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj, | 667 | error = sysfs_create_link(&input_class.subsys.kobj, |
654 | evdev->name); | 668 | &cdev->kobj, evdev->name); |
669 | if (error) | ||
670 | goto err_cdev_destroy; | ||
671 | |||
672 | error = input_register_handle(&evdev->handle); | ||
673 | if (error) | ||
674 | goto err_remove_link; | ||
655 | 675 | ||
656 | return &evdev->handle; | 676 | return 0; |
677 | |||
678 | err_remove_link: | ||
679 | sysfs_remove_link(&input_class.subsys.kobj, evdev->name); | ||
680 | err_cdev_destroy: | ||
681 | class_device_destroy(&input_class, devt); | ||
682 | err_free_evdev: | ||
683 | kfree(evdev); | ||
684 | evdev_table[minor] = NULL; | ||
685 | return error; | ||
657 | } | 686 | } |
658 | 687 | ||
659 | static void evdev_disconnect(struct input_handle *handle) | 688 | static void evdev_disconnect(struct input_handle *handle) |
660 | { | 689 | { |
661 | struct evdev *evdev = handle->private; | 690 | struct evdev *evdev = handle->private; |
662 | struct evdev_list *list; | 691 | struct evdev_client *client; |
692 | |||
693 | input_unregister_handle(handle); | ||
663 | 694 | ||
664 | sysfs_remove_link(&input_class.subsys.kset.kobj, evdev->name); | 695 | sysfs_remove_link(&input_class.subsys.kobj, evdev->name); |
665 | class_device_destroy(&input_class, | 696 | class_device_destroy(&input_class, |
666 | MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor)); | 697 | MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor)); |
667 | evdev->exist = 0; | 698 | evdev->exist = 0; |
@@ -670,8 +701,8 @@ static void evdev_disconnect(struct input_handle *handle) | |||
670 | input_flush_device(handle, NULL); | 701 | input_flush_device(handle, NULL); |
671 | input_close_device(handle); | 702 | input_close_device(handle); |
672 | wake_up_interruptible(&evdev->wait); | 703 | wake_up_interruptible(&evdev->wait); |
673 | list_for_each_entry(list, &evdev->list, node) | 704 | list_for_each_entry(client, &evdev->client_list, node) |
674 | kill_fasync(&list->fasync, SIGIO, POLL_HUP); | 705 | kill_fasync(&client->fasync, SIGIO, POLL_HUP); |
675 | } else | 706 | } else |
676 | evdev_free(evdev); | 707 | evdev_free(evdev); |
677 | } | 708 | } |
diff --git a/drivers/input/input.c b/drivers/input/input.c index a9a706f8fff9..915e9ab7cab0 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -299,12 +299,87 @@ void input_close_device(struct input_handle *handle) | |||
299 | } | 299 | } |
300 | EXPORT_SYMBOL(input_close_device); | 300 | EXPORT_SYMBOL(input_close_device); |
301 | 301 | ||
302 | static void input_link_handle(struct input_handle *handle) | 302 | static int input_fetch_keycode(struct input_dev *dev, int scancode) |
303 | { | 303 | { |
304 | list_add_tail(&handle->d_node, &handle->dev->h_list); | 304 | switch (dev->keycodesize) { |
305 | list_add_tail(&handle->h_node, &handle->handler->h_list); | 305 | case 1: |
306 | return ((u8 *)dev->keycode)[scancode]; | ||
307 | |||
308 | case 2: | ||
309 | return ((u16 *)dev->keycode)[scancode]; | ||
310 | |||
311 | default: | ||
312 | return ((u32 *)dev->keycode)[scancode]; | ||
313 | } | ||
314 | } | ||
315 | |||
316 | static int input_default_getkeycode(struct input_dev *dev, | ||
317 | int scancode, int *keycode) | ||
318 | { | ||
319 | if (!dev->keycodesize) | ||
320 | return -EINVAL; | ||
321 | |||
322 | if (scancode < 0 || scancode >= dev->keycodemax) | ||
323 | return -EINVAL; | ||
324 | |||
325 | *keycode = input_fetch_keycode(dev, scancode); | ||
326 | |||
327 | return 0; | ||
328 | } | ||
329 | |||
330 | static int input_default_setkeycode(struct input_dev *dev, | ||
331 | int scancode, int keycode) | ||
332 | { | ||
333 | int old_keycode; | ||
334 | int i; | ||
335 | |||
336 | if (scancode < 0 || scancode >= dev->keycodemax) | ||
337 | return -EINVAL; | ||
338 | |||
339 | if (keycode < 0 || keycode > KEY_MAX) | ||
340 | return -EINVAL; | ||
341 | |||
342 | if (!dev->keycodesize) | ||
343 | return -EINVAL; | ||
344 | |||
345 | if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8))) | ||
346 | return -EINVAL; | ||
347 | |||
348 | switch (dev->keycodesize) { | ||
349 | case 1: { | ||
350 | u8 *k = (u8 *)dev->keycode; | ||
351 | old_keycode = k[scancode]; | ||
352 | k[scancode] = keycode; | ||
353 | break; | ||
354 | } | ||
355 | case 2: { | ||
356 | u16 *k = (u16 *)dev->keycode; | ||
357 | old_keycode = k[scancode]; | ||
358 | k[scancode] = keycode; | ||
359 | break; | ||
360 | } | ||
361 | default: { | ||
362 | u32 *k = (u32 *)dev->keycode; | ||
363 | old_keycode = k[scancode]; | ||
364 | k[scancode] = keycode; | ||
365 | break; | ||
366 | } | ||
367 | } | ||
368 | |||
369 | clear_bit(old_keycode, dev->keybit); | ||
370 | set_bit(keycode, dev->keybit); | ||
371 | |||
372 | for (i = 0; i < dev->keycodemax; i++) { | ||
373 | if (input_fetch_keycode(dev, i) == old_keycode) { | ||
374 | set_bit(old_keycode, dev->keybit); | ||
375 | break; /* Setting the bit twice is useless, so break */ | ||
376 | } | ||
377 | } | ||
378 | |||
379 | return 0; | ||
306 | } | 380 | } |
307 | 381 | ||
382 | |||
308 | #define MATCH_BIT(bit, max) \ | 383 | #define MATCH_BIT(bit, max) \ |
309 | for (i = 0; i < NBITS(max); i++) \ | 384 | for (i = 0; i < NBITS(max); i++) \ |
310 | if ((id->bit[i] & dev->bit[i]) != id->bit[i]) \ | 385 | if ((id->bit[i] & dev->bit[i]) != id->bit[i]) \ |
@@ -351,6 +426,29 @@ static const struct input_device_id *input_match_device(const struct input_devic | |||
351 | return NULL; | 426 | return NULL; |
352 | } | 427 | } |
353 | 428 | ||
429 | static int input_attach_handler(struct input_dev *dev, struct input_handler *handler) | ||
430 | { | ||
431 | const struct input_device_id *id; | ||
432 | int error; | ||
433 | |||
434 | if (handler->blacklist && input_match_device(handler->blacklist, dev)) | ||
435 | return -ENODEV; | ||
436 | |||
437 | id = input_match_device(handler->id_table, dev); | ||
438 | if (!id) | ||
439 | return -ENODEV; | ||
440 | |||
441 | error = handler->connect(handler, dev, id); | ||
442 | if (error && error != -ENODEV) | ||
443 | printk(KERN_ERR | ||
444 | "input: failed to attach handler %s to device %s, " | ||
445 | "error: %d\n", | ||
446 | handler->name, kobject_name(&dev->cdev.kobj), error); | ||
447 | |||
448 | return error; | ||
449 | } | ||
450 | |||
451 | |||
354 | #ifdef CONFIG_PROC_FS | 452 | #ifdef CONFIG_PROC_FS |
355 | 453 | ||
356 | static struct proc_dir_entry *proc_bus_input_dir; | 454 | static struct proc_dir_entry *proc_bus_input_dir; |
@@ -439,6 +537,7 @@ static int input_devices_seq_show(struct seq_file *seq, void *v) | |||
439 | seq_printf(seq, "N: Name=\"%s\"\n", dev->name ? dev->name : ""); | 537 | seq_printf(seq, "N: Name=\"%s\"\n", dev->name ? dev->name : ""); |
440 | seq_printf(seq, "P: Phys=%s\n", dev->phys ? dev->phys : ""); | 538 | seq_printf(seq, "P: Phys=%s\n", dev->phys ? dev->phys : ""); |
441 | seq_printf(seq, "S: Sysfs=%s\n", path ? path : ""); | 539 | seq_printf(seq, "S: Sysfs=%s\n", path ? path : ""); |
540 | seq_printf(seq, "U: Uniq=%s\n", dev->uniq ? dev->uniq : ""); | ||
442 | seq_printf(seq, "H: Handlers="); | 541 | seq_printf(seq, "H: Handlers="); |
443 | 542 | ||
444 | list_for_each_entry(handle, &dev->h_list, d_node) | 543 | list_for_each_entry(handle, &dev->h_list, d_node) |
@@ -753,6 +852,13 @@ static struct attribute_group input_dev_caps_attr_group = { | |||
753 | .attrs = input_dev_caps_attrs, | 852 | .attrs = input_dev_caps_attrs, |
754 | }; | 853 | }; |
755 | 854 | ||
855 | static struct attribute_group *input_dev_attr_groups[] = { | ||
856 | &input_dev_attr_group, | ||
857 | &input_dev_id_attr_group, | ||
858 | &input_dev_caps_attr_group, | ||
859 | NULL | ||
860 | }; | ||
861 | |||
756 | static void input_dev_release(struct class_device *class_dev) | 862 | static void input_dev_release(struct class_device *class_dev) |
757 | { | 863 | { |
758 | struct input_dev *dev = to_input_dev(class_dev); | 864 | struct input_dev *dev = to_input_dev(class_dev); |
@@ -906,6 +1012,7 @@ struct input_dev *input_allocate_device(void) | |||
906 | dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL); | 1012 | dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL); |
907 | if (dev) { | 1013 | if (dev) { |
908 | dev->cdev.class = &input_class; | 1014 | dev->cdev.class = &input_class; |
1015 | dev->cdev.groups = input_dev_attr_groups; | ||
909 | class_device_initialize(&dev->cdev); | 1016 | class_device_initialize(&dev->cdev); |
910 | mutex_init(&dev->mutex); | 1017 | mutex_init(&dev->mutex); |
911 | INIT_LIST_HEAD(&dev->h_list); | 1018 | INIT_LIST_HEAD(&dev->h_list); |
@@ -934,23 +1041,71 @@ EXPORT_SYMBOL(input_allocate_device); | |||
934 | */ | 1041 | */ |
935 | void input_free_device(struct input_dev *dev) | 1042 | void input_free_device(struct input_dev *dev) |
936 | { | 1043 | { |
937 | if (dev) { | 1044 | if (dev) |
938 | |||
939 | mutex_lock(&dev->mutex); | ||
940 | dev->name = dev->phys = dev->uniq = NULL; | ||
941 | mutex_unlock(&dev->mutex); | ||
942 | |||
943 | input_put_device(dev); | 1045 | input_put_device(dev); |
944 | } | ||
945 | } | 1046 | } |
946 | EXPORT_SYMBOL(input_free_device); | 1047 | EXPORT_SYMBOL(input_free_device); |
947 | 1048 | ||
1049 | /** | ||
1050 | * input_set_capability - mark device as capable of a certain event | ||
1051 | * @dev: device that is capable of emitting or accepting event | ||
1052 | * @type: type of the event (EV_KEY, EV_REL, etc...) | ||
1053 | * @code: event code | ||
1054 | * | ||
1055 | * In addition to setting up corresponding bit in appropriate capability | ||
1056 | * bitmap the function also adjusts dev->evbit. | ||
1057 | */ | ||
1058 | void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code) | ||
1059 | { | ||
1060 | switch (type) { | ||
1061 | case EV_KEY: | ||
1062 | __set_bit(code, dev->keybit); | ||
1063 | break; | ||
1064 | |||
1065 | case EV_REL: | ||
1066 | __set_bit(code, dev->relbit); | ||
1067 | break; | ||
1068 | |||
1069 | case EV_ABS: | ||
1070 | __set_bit(code, dev->absbit); | ||
1071 | break; | ||
1072 | |||
1073 | case EV_MSC: | ||
1074 | __set_bit(code, dev->mscbit); | ||
1075 | break; | ||
1076 | |||
1077 | case EV_SW: | ||
1078 | __set_bit(code, dev->swbit); | ||
1079 | break; | ||
1080 | |||
1081 | case EV_LED: | ||
1082 | __set_bit(code, dev->ledbit); | ||
1083 | break; | ||
1084 | |||
1085 | case EV_SND: | ||
1086 | __set_bit(code, dev->sndbit); | ||
1087 | break; | ||
1088 | |||
1089 | case EV_FF: | ||
1090 | __set_bit(code, dev->ffbit); | ||
1091 | break; | ||
1092 | |||
1093 | default: | ||
1094 | printk(KERN_ERR | ||
1095 | "input_set_capability: unknown type %u (code %u)\n", | ||
1096 | type, code); | ||
1097 | dump_stack(); | ||
1098 | return; | ||
1099 | } | ||
1100 | |||
1101 | __set_bit(type, dev->evbit); | ||
1102 | } | ||
1103 | EXPORT_SYMBOL(input_set_capability); | ||
1104 | |||
948 | int input_register_device(struct input_dev *dev) | 1105 | int input_register_device(struct input_dev *dev) |
949 | { | 1106 | { |
950 | static atomic_t input_no = ATOMIC_INIT(0); | 1107 | static atomic_t input_no = ATOMIC_INIT(0); |
951 | struct input_handle *handle; | ||
952 | struct input_handler *handler; | 1108 | struct input_handler *handler; |
953 | const struct input_device_id *id; | ||
954 | const char *path; | 1109 | const char *path; |
955 | int error; | 1110 | int error; |
956 | 1111 | ||
@@ -969,55 +1124,41 @@ int input_register_device(struct input_dev *dev) | |||
969 | dev->rep[REP_PERIOD] = 33; | 1124 | dev->rep[REP_PERIOD] = 33; |
970 | } | 1125 | } |
971 | 1126 | ||
1127 | if (!dev->getkeycode) | ||
1128 | dev->getkeycode = input_default_getkeycode; | ||
1129 | |||
1130 | if (!dev->setkeycode) | ||
1131 | dev->setkeycode = input_default_setkeycode; | ||
1132 | |||
972 | list_add_tail(&dev->node, &input_dev_list); | 1133 | list_add_tail(&dev->node, &input_dev_list); |
973 | 1134 | ||
974 | snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id), | 1135 | snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id), |
975 | "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1); | 1136 | "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1); |
976 | 1137 | ||
1138 | if (!dev->cdev.dev) | ||
1139 | dev->cdev.dev = dev->dev.parent; | ||
1140 | |||
977 | error = class_device_add(&dev->cdev); | 1141 | error = class_device_add(&dev->cdev); |
978 | if (error) | 1142 | if (error) |
979 | return error; | 1143 | return error; |
980 | 1144 | ||
981 | error = sysfs_create_group(&dev->cdev.kobj, &input_dev_attr_group); | ||
982 | if (error) | ||
983 | goto fail1; | ||
984 | |||
985 | error = sysfs_create_group(&dev->cdev.kobj, &input_dev_id_attr_group); | ||
986 | if (error) | ||
987 | goto fail2; | ||
988 | |||
989 | error = sysfs_create_group(&dev->cdev.kobj, &input_dev_caps_attr_group); | ||
990 | if (error) | ||
991 | goto fail3; | ||
992 | |||
993 | path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL); | 1145 | path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL); |
994 | printk(KERN_INFO "input: %s as %s\n", | 1146 | printk(KERN_INFO "input: %s as %s\n", |
995 | dev->name ? dev->name : "Unspecified device", path ? path : "N/A"); | 1147 | dev->name ? dev->name : "Unspecified device", path ? path : "N/A"); |
996 | kfree(path); | 1148 | kfree(path); |
997 | 1149 | ||
998 | list_for_each_entry(handler, &input_handler_list, node) | 1150 | list_for_each_entry(handler, &input_handler_list, node) |
999 | if (!handler->blacklist || !input_match_device(handler->blacklist, dev)) | 1151 | input_attach_handler(dev, handler); |
1000 | if ((id = input_match_device(handler->id_table, dev))) | ||
1001 | if ((handle = handler->connect(handler, dev, id))) { | ||
1002 | input_link_handle(handle); | ||
1003 | if (handler->start) | ||
1004 | handler->start(handle); | ||
1005 | } | ||
1006 | 1152 | ||
1007 | input_wakeup_procfs_readers(); | 1153 | input_wakeup_procfs_readers(); |
1008 | 1154 | ||
1009 | return 0; | 1155 | return 0; |
1010 | |||
1011 | fail3: sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group); | ||
1012 | fail2: sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group); | ||
1013 | fail1: class_device_del(&dev->cdev); | ||
1014 | return error; | ||
1015 | } | 1156 | } |
1016 | EXPORT_SYMBOL(input_register_device); | 1157 | EXPORT_SYMBOL(input_register_device); |
1017 | 1158 | ||
1018 | void input_unregister_device(struct input_dev *dev) | 1159 | void input_unregister_device(struct input_dev *dev) |
1019 | { | 1160 | { |
1020 | struct list_head *node, *next; | 1161 | struct input_handle *handle, *next; |
1021 | int code; | 1162 | int code; |
1022 | 1163 | ||
1023 | for (code = 0; code <= KEY_MAX; code++) | 1164 | for (code = 0; code <= KEY_MAX; code++) |
@@ -1027,19 +1168,12 @@ void input_unregister_device(struct input_dev *dev) | |||
1027 | 1168 | ||
1028 | del_timer_sync(&dev->timer); | 1169 | del_timer_sync(&dev->timer); |
1029 | 1170 | ||
1030 | list_for_each_safe(node, next, &dev->h_list) { | 1171 | list_for_each_entry_safe(handle, next, &dev->h_list, d_node) |
1031 | struct input_handle * handle = to_handle(node); | ||
1032 | list_del_init(&handle->d_node); | ||
1033 | list_del_init(&handle->h_node); | ||
1034 | handle->handler->disconnect(handle); | 1172 | handle->handler->disconnect(handle); |
1035 | } | 1173 | WARN_ON(!list_empty(&dev->h_list)); |
1036 | 1174 | ||
1037 | list_del_init(&dev->node); | 1175 | list_del_init(&dev->node); |
1038 | 1176 | ||
1039 | sysfs_remove_group(&dev->cdev.kobj, &input_dev_caps_attr_group); | ||
1040 | sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group); | ||
1041 | sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group); | ||
1042 | |||
1043 | class_device_unregister(&dev->cdev); | 1177 | class_device_unregister(&dev->cdev); |
1044 | 1178 | ||
1045 | input_wakeup_procfs_readers(); | 1179 | input_wakeup_procfs_readers(); |
@@ -1049,8 +1183,6 @@ EXPORT_SYMBOL(input_unregister_device); | |||
1049 | int input_register_handler(struct input_handler *handler) | 1183 | int input_register_handler(struct input_handler *handler) |
1050 | { | 1184 | { |
1051 | struct input_dev *dev; | 1185 | struct input_dev *dev; |
1052 | struct input_handle *handle; | ||
1053 | const struct input_device_id *id; | ||
1054 | 1186 | ||
1055 | INIT_LIST_HEAD(&handler->h_list); | 1187 | INIT_LIST_HEAD(&handler->h_list); |
1056 | 1188 | ||
@@ -1064,13 +1196,7 @@ int input_register_handler(struct input_handler *handler) | |||
1064 | list_add_tail(&handler->node, &input_handler_list); | 1196 | list_add_tail(&handler->node, &input_handler_list); |
1065 | 1197 | ||
1066 | list_for_each_entry(dev, &input_dev_list, node) | 1198 | list_for_each_entry(dev, &input_dev_list, node) |
1067 | if (!handler->blacklist || !input_match_device(handler->blacklist, dev)) | 1199 | input_attach_handler(dev, handler); |
1068 | if ((id = input_match_device(handler->id_table, dev))) | ||
1069 | if ((handle = handler->connect(handler, dev, id))) { | ||
1070 | input_link_handle(handle); | ||
1071 | if (handler->start) | ||
1072 | handler->start(handle); | ||
1073 | } | ||
1074 | 1200 | ||
1075 | input_wakeup_procfs_readers(); | 1201 | input_wakeup_procfs_readers(); |
1076 | return 0; | 1202 | return 0; |
@@ -1079,14 +1205,11 @@ EXPORT_SYMBOL(input_register_handler); | |||
1079 | 1205 | ||
1080 | void input_unregister_handler(struct input_handler *handler) | 1206 | void input_unregister_handler(struct input_handler *handler) |
1081 | { | 1207 | { |
1082 | struct list_head *node, *next; | 1208 | struct input_handle *handle, *next; |
1083 | 1209 | ||
1084 | list_for_each_safe(node, next, &handler->h_list) { | 1210 | list_for_each_entry_safe(handle, next, &handler->h_list, h_node) |
1085 | struct input_handle * handle = to_handle_h(node); | ||
1086 | list_del_init(&handle->h_node); | ||
1087 | list_del_init(&handle->d_node); | ||
1088 | handler->disconnect(handle); | 1211 | handler->disconnect(handle); |
1089 | } | 1212 | WARN_ON(!list_empty(&handler->h_list)); |
1090 | 1213 | ||
1091 | list_del_init(&handler->node); | 1214 | list_del_init(&handler->node); |
1092 | 1215 | ||
@@ -1097,6 +1220,27 @@ void input_unregister_handler(struct input_handler *handler) | |||
1097 | } | 1220 | } |
1098 | EXPORT_SYMBOL(input_unregister_handler); | 1221 | EXPORT_SYMBOL(input_unregister_handler); |
1099 | 1222 | ||
1223 | int input_register_handle(struct input_handle *handle) | ||
1224 | { | ||
1225 | struct input_handler *handler = handle->handler; | ||
1226 | |||
1227 | list_add_tail(&handle->d_node, &handle->dev->h_list); | ||
1228 | list_add_tail(&handle->h_node, &handler->h_list); | ||
1229 | |||
1230 | if (handler->start) | ||
1231 | handler->start(handle); | ||
1232 | |||
1233 | return 0; | ||
1234 | } | ||
1235 | EXPORT_SYMBOL(input_register_handle); | ||
1236 | |||
1237 | void input_unregister_handle(struct input_handle *handle) | ||
1238 | { | ||
1239 | list_del_init(&handle->h_node); | ||
1240 | list_del_init(&handle->d_node); | ||
1241 | } | ||
1242 | EXPORT_SYMBOL(input_unregister_handle); | ||
1243 | |||
1100 | static int input_open_file(struct inode *inode, struct file *file) | 1244 | static int input_open_file(struct inode *inode, struct file *file) |
1101 | { | 1245 | { |
1102 | struct input_handler *handler = input_table[iminor(inode) >> 5]; | 1246 | struct input_handler *handler = input_table[iminor(inode) >> 5]; |
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 9f3529ad3fda..9bcc5425049b 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c | |||
@@ -43,7 +43,7 @@ struct joydev { | |||
43 | char name[16]; | 43 | char name[16]; |
44 | struct input_handle handle; | 44 | struct input_handle handle; |
45 | wait_queue_head_t wait; | 45 | wait_queue_head_t wait; |
46 | struct list_head list; | 46 | struct list_head client_list; |
47 | struct js_corr corr[ABS_MAX + 1]; | 47 | struct js_corr corr[ABS_MAX + 1]; |
48 | struct JS_DATA_SAVE_TYPE glue; | 48 | struct JS_DATA_SAVE_TYPE glue; |
49 | int nabs; | 49 | int nabs; |
@@ -55,7 +55,7 @@ struct joydev { | |||
55 | __s16 abs[ABS_MAX + 1]; | 55 | __s16 abs[ABS_MAX + 1]; |
56 | }; | 56 | }; |
57 | 57 | ||
58 | struct joydev_list { | 58 | struct joydev_client { |
59 | struct js_event buffer[JOYDEV_BUFFER_SIZE]; | 59 | struct js_event buffer[JOYDEV_BUFFER_SIZE]; |
60 | int head; | 60 | int head; |
61 | int tail; | 61 | int tail; |
@@ -87,7 +87,7 @@ static int joydev_correct(int value, struct js_corr *corr) | |||
87 | static void joydev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) | 87 | static void joydev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) |
88 | { | 88 | { |
89 | struct joydev *joydev = handle->private; | 89 | struct joydev *joydev = handle->private; |
90 | struct joydev_list *list; | 90 | struct joydev_client *client; |
91 | struct js_event event; | 91 | struct js_event event; |
92 | 92 | ||
93 | switch (type) { | 93 | switch (type) { |
@@ -115,15 +115,15 @@ static void joydev_event(struct input_handle *handle, unsigned int type, unsigne | |||
115 | 115 | ||
116 | event.time = jiffies_to_msecs(jiffies); | 116 | event.time = jiffies_to_msecs(jiffies); |
117 | 117 | ||
118 | list_for_each_entry(list, &joydev->list, node) { | 118 | list_for_each_entry(client, &joydev->client_list, node) { |
119 | 119 | ||
120 | memcpy(list->buffer + list->head, &event, sizeof(struct js_event)); | 120 | memcpy(client->buffer + client->head, &event, sizeof(struct js_event)); |
121 | 121 | ||
122 | if (list->startup == joydev->nabs + joydev->nkey) | 122 | if (client->startup == joydev->nabs + joydev->nkey) |
123 | if (list->tail == (list->head = (list->head + 1) & (JOYDEV_BUFFER_SIZE - 1))) | 123 | if (client->tail == (client->head = (client->head + 1) & (JOYDEV_BUFFER_SIZE - 1))) |
124 | list->startup = 0; | 124 | client->startup = 0; |
125 | 125 | ||
126 | kill_fasync(&list->fasync, SIGIO, POLL_IN); | 126 | kill_fasync(&client->fasync, SIGIO, POLL_IN); |
127 | } | 127 | } |
128 | 128 | ||
129 | wake_up_interruptible(&joydev->wait); | 129 | wake_up_interruptible(&joydev->wait); |
@@ -132,9 +132,9 @@ static void joydev_event(struct input_handle *handle, unsigned int type, unsigne | |||
132 | static int joydev_fasync(int fd, struct file *file, int on) | 132 | static int joydev_fasync(int fd, struct file *file, int on) |
133 | { | 133 | { |
134 | int retval; | 134 | int retval; |
135 | struct joydev_list *list = file->private_data; | 135 | struct joydev_client *client = file->private_data; |
136 | 136 | ||
137 | retval = fasync_helper(fd, file, on, &list->fasync); | 137 | retval = fasync_helper(fd, file, on, &client->fasync); |
138 | 138 | ||
139 | return retval < 0 ? retval : 0; | 139 | return retval < 0 ? retval : 0; |
140 | } | 140 | } |
@@ -145,60 +145,73 @@ static void joydev_free(struct joydev *joydev) | |||
145 | kfree(joydev); | 145 | kfree(joydev); |
146 | } | 146 | } |
147 | 147 | ||
148 | static int joydev_release(struct inode * inode, struct file * file) | 148 | static int joydev_release(struct inode *inode, struct file *file) |
149 | { | 149 | { |
150 | struct joydev_list *list = file->private_data; | 150 | struct joydev_client *client = file->private_data; |
151 | struct joydev *joydev = client->joydev; | ||
151 | 152 | ||
152 | joydev_fasync(-1, file, 0); | 153 | joydev_fasync(-1, file, 0); |
153 | 154 | ||
154 | list_del(&list->node); | 155 | list_del(&client->node); |
156 | kfree(client); | ||
155 | 157 | ||
156 | if (!--list->joydev->open) { | 158 | if (!--joydev->open) { |
157 | if (list->joydev->exist) | 159 | if (joydev->exist) |
158 | input_close_device(&list->joydev->handle); | 160 | input_close_device(&joydev->handle); |
159 | else | 161 | else |
160 | joydev_free(list->joydev); | 162 | joydev_free(joydev); |
161 | } | 163 | } |
162 | 164 | ||
163 | kfree(list); | ||
164 | return 0; | 165 | return 0; |
165 | } | 166 | } |
166 | 167 | ||
167 | static int joydev_open(struct inode *inode, struct file *file) | 168 | static int joydev_open(struct inode *inode, struct file *file) |
168 | { | 169 | { |
169 | struct joydev_list *list; | 170 | struct joydev_client *client; |
171 | struct joydev *joydev; | ||
170 | int i = iminor(inode) - JOYDEV_MINOR_BASE; | 172 | int i = iminor(inode) - JOYDEV_MINOR_BASE; |
173 | int error; | ||
174 | |||
175 | if (i >= JOYDEV_MINORS) | ||
176 | return -ENODEV; | ||
171 | 177 | ||
172 | if (i >= JOYDEV_MINORS || !joydev_table[i]) | 178 | joydev = joydev_table[i]; |
179 | if (!joydev || !joydev->exist) | ||
173 | return -ENODEV; | 180 | return -ENODEV; |
174 | 181 | ||
175 | if (!(list = kzalloc(sizeof(struct joydev_list), GFP_KERNEL))) | 182 | client = kzalloc(sizeof(struct joydev_client), GFP_KERNEL); |
183 | if (!client) | ||
176 | return -ENOMEM; | 184 | return -ENOMEM; |
177 | 185 | ||
178 | list->joydev = joydev_table[i]; | 186 | client->joydev = joydev; |
179 | list_add_tail(&list->node, &joydev_table[i]->list); | 187 | list_add_tail(&client->node, &joydev->client_list); |
180 | file->private_data = list; | ||
181 | 188 | ||
182 | if (!list->joydev->open++) | 189 | if (!joydev->open++ && joydev->exist) { |
183 | if (list->joydev->exist) | 190 | error = input_open_device(&joydev->handle); |
184 | input_open_device(&list->joydev->handle); | 191 | if (error) { |
192 | list_del(&client->node); | ||
193 | kfree(client); | ||
194 | return error; | ||
195 | } | ||
196 | } | ||
185 | 197 | ||
198 | file->private_data = client; | ||
186 | return 0; | 199 | return 0; |
187 | } | 200 | } |
188 | 201 | ||
189 | static ssize_t joydev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos) | 202 | static ssize_t joydev_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) |
190 | { | 203 | { |
191 | return -EINVAL; | 204 | return -EINVAL; |
192 | } | 205 | } |
193 | 206 | ||
194 | static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | 207 | static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) |
195 | { | 208 | { |
196 | struct joydev_list *list = file->private_data; | 209 | struct joydev_client *client = file->private_data; |
197 | struct joydev *joydev = list->joydev; | 210 | struct joydev *joydev = client->joydev; |
198 | struct input_dev *input = joydev->handle.dev; | 211 | struct input_dev *input = joydev->handle.dev; |
199 | int retval = 0; | 212 | int retval = 0; |
200 | 213 | ||
201 | if (!list->joydev->exist) | 214 | if (!joydev->exist) |
202 | return -ENODEV; | 215 | return -ENODEV; |
203 | 216 | ||
204 | if (count < sizeof(struct js_event)) | 217 | if (count < sizeof(struct js_event)) |
@@ -217,56 +230,55 @@ static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, lo | |||
217 | if (copy_to_user(buf, &data, sizeof(struct JS_DATA_TYPE))) | 230 | if (copy_to_user(buf, &data, sizeof(struct JS_DATA_TYPE))) |
218 | return -EFAULT; | 231 | return -EFAULT; |
219 | 232 | ||
220 | list->startup = 0; | 233 | client->startup = 0; |
221 | list->tail = list->head; | 234 | client->tail = client->head; |
222 | 235 | ||
223 | return sizeof(struct JS_DATA_TYPE); | 236 | return sizeof(struct JS_DATA_TYPE); |
224 | } | 237 | } |
225 | 238 | ||
226 | if (list->startup == joydev->nabs + joydev->nkey && | 239 | if (client->startup == joydev->nabs + joydev->nkey && |
227 | list->head == list->tail && (file->f_flags & O_NONBLOCK)) | 240 | client->head == client->tail && (file->f_flags & O_NONBLOCK)) |
228 | return -EAGAIN; | 241 | return -EAGAIN; |
229 | 242 | ||
230 | retval = wait_event_interruptible(list->joydev->wait, | 243 | retval = wait_event_interruptible(joydev->wait, |
231 | !list->joydev->exist || | 244 | !joydev->exist || |
232 | list->startup < joydev->nabs + joydev->nkey || | 245 | client->startup < joydev->nabs + joydev->nkey || |
233 | list->head != list->tail); | 246 | client->head != client->tail); |
234 | |||
235 | if (retval) | 247 | if (retval) |
236 | return retval; | 248 | return retval; |
237 | 249 | ||
238 | if (!list->joydev->exist) | 250 | if (!joydev->exist) |
239 | return -ENODEV; | 251 | return -ENODEV; |
240 | 252 | ||
241 | while (list->startup < joydev->nabs + joydev->nkey && retval + sizeof(struct js_event) <= count) { | 253 | while (client->startup < joydev->nabs + joydev->nkey && retval + sizeof(struct js_event) <= count) { |
242 | 254 | ||
243 | struct js_event event; | 255 | struct js_event event; |
244 | 256 | ||
245 | event.time = jiffies_to_msecs(jiffies); | 257 | event.time = jiffies_to_msecs(jiffies); |
246 | 258 | ||
247 | if (list->startup < joydev->nkey) { | 259 | if (client->startup < joydev->nkey) { |
248 | event.type = JS_EVENT_BUTTON | JS_EVENT_INIT; | 260 | event.type = JS_EVENT_BUTTON | JS_EVENT_INIT; |
249 | event.number = list->startup; | 261 | event.number = client->startup; |
250 | event.value = !!test_bit(joydev->keypam[event.number], input->key); | 262 | event.value = !!test_bit(joydev->keypam[event.number], input->key); |
251 | } else { | 263 | } else { |
252 | event.type = JS_EVENT_AXIS | JS_EVENT_INIT; | 264 | event.type = JS_EVENT_AXIS | JS_EVENT_INIT; |
253 | event.number = list->startup - joydev->nkey; | 265 | event.number = client->startup - joydev->nkey; |
254 | event.value = joydev->abs[event.number]; | 266 | event.value = joydev->abs[event.number]; |
255 | } | 267 | } |
256 | 268 | ||
257 | if (copy_to_user(buf + retval, &event, sizeof(struct js_event))) | 269 | if (copy_to_user(buf + retval, &event, sizeof(struct js_event))) |
258 | return -EFAULT; | 270 | return -EFAULT; |
259 | 271 | ||
260 | list->startup++; | 272 | client->startup++; |
261 | retval += sizeof(struct js_event); | 273 | retval += sizeof(struct js_event); |
262 | } | 274 | } |
263 | 275 | ||
264 | while (list->head != list->tail && retval + sizeof(struct js_event) <= count) { | 276 | while (client->head != client->tail && retval + sizeof(struct js_event) <= count) { |
265 | 277 | ||
266 | if (copy_to_user(buf + retval, list->buffer + list->tail, sizeof(struct js_event))) | 278 | if (copy_to_user(buf + retval, client->buffer + client->tail, sizeof(struct js_event))) |
267 | return -EFAULT; | 279 | return -EFAULT; |
268 | 280 | ||
269 | list->tail = (list->tail + 1) & (JOYDEV_BUFFER_SIZE - 1); | 281 | client->tail = (client->tail + 1) & (JOYDEV_BUFFER_SIZE - 1); |
270 | retval += sizeof(struct js_event); | 282 | retval += sizeof(struct js_event); |
271 | } | 283 | } |
272 | 284 | ||
@@ -276,11 +288,12 @@ static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, lo | |||
276 | /* No kernel lock - fine */ | 288 | /* No kernel lock - fine */ |
277 | static unsigned int joydev_poll(struct file *file, poll_table *wait) | 289 | static unsigned int joydev_poll(struct file *file, poll_table *wait) |
278 | { | 290 | { |
279 | struct joydev_list *list = file->private_data; | 291 | struct joydev_client *client = file->private_data; |
292 | struct joydev *joydev = client->joydev; | ||
280 | 293 | ||
281 | poll_wait(file, &list->joydev->wait, wait); | 294 | poll_wait(file, &joydev->wait, wait); |
282 | return ((list->head != list->tail || list->startup < list->joydev->nabs + list->joydev->nkey) ? | 295 | return ((client->head != client->tail || client->startup < joydev->nabs + joydev->nkey) ? |
283 | (POLLIN | POLLRDNORM) : 0) | (list->joydev->exist ? 0 : (POLLHUP | POLLERR)); | 296 | (POLLIN | POLLRDNORM) : 0) | (joydev->exist ? 0 : (POLLHUP | POLLERR)); |
284 | } | 297 | } |
285 | 298 | ||
286 | static int joydev_ioctl_common(struct joydev *joydev, unsigned int cmd, void __user *argp) | 299 | static int joydev_ioctl_common(struct joydev *joydev, unsigned int cmd, void __user *argp) |
@@ -374,8 +387,8 @@ static int joydev_ioctl_common(struct joydev *joydev, unsigned int cmd, void __u | |||
374 | #ifdef CONFIG_COMPAT | 387 | #ifdef CONFIG_COMPAT |
375 | static long joydev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 388 | static long joydev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
376 | { | 389 | { |
377 | struct joydev_list *list = file->private_data; | 390 | struct joydev_client *client = file->private_data; |
378 | struct joydev *joydev = list->joydev; | 391 | struct joydev *joydev = client->joydev; |
379 | void __user *argp = (void __user *)arg; | 392 | void __user *argp = (void __user *)arg; |
380 | s32 tmp32; | 393 | s32 tmp32; |
381 | struct JS_DATA_SAVE_TYPE_32 ds32; | 394 | struct JS_DATA_SAVE_TYPE_32 ds32; |
@@ -428,8 +441,8 @@ static long joydev_compat_ioctl(struct file *file, unsigned int cmd, unsigned lo | |||
428 | 441 | ||
429 | static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | 442 | static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) |
430 | { | 443 | { |
431 | struct joydev_list *list = file->private_data; | 444 | struct joydev_client *client = file->private_data; |
432 | struct joydev *joydev = list->joydev; | 445 | struct joydev *joydev = client->joydev; |
433 | void __user *argp = (void __user *)arg; | 446 | void __user *argp = (void __user *)arg; |
434 | 447 | ||
435 | if (!joydev->exist) | 448 | if (!joydev->exist) |
@@ -465,23 +478,26 @@ static const struct file_operations joydev_fops = { | |||
465 | .fasync = joydev_fasync, | 478 | .fasync = joydev_fasync, |
466 | }; | 479 | }; |
467 | 480 | ||
468 | static struct input_handle *joydev_connect(struct input_handler *handler, struct input_dev *dev, | 481 | static int joydev_connect(struct input_handler *handler, struct input_dev *dev, |
469 | const struct input_device_id *id) | 482 | const struct input_device_id *id) |
470 | { | 483 | { |
471 | struct joydev *joydev; | 484 | struct joydev *joydev; |
472 | struct class_device *cdev; | 485 | struct class_device *cdev; |
486 | dev_t devt; | ||
473 | int i, j, t, minor; | 487 | int i, j, t, minor; |
488 | int error; | ||
474 | 489 | ||
475 | for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++); | 490 | for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++); |
476 | if (minor == JOYDEV_MINORS) { | 491 | if (minor == JOYDEV_MINORS) { |
477 | printk(KERN_ERR "joydev: no more free joydev devices\n"); | 492 | printk(KERN_ERR "joydev: no more free joydev devices\n"); |
478 | return NULL; | 493 | return -ENFILE; |
479 | } | 494 | } |
480 | 495 | ||
481 | if (!(joydev = kzalloc(sizeof(struct joydev), GFP_KERNEL))) | 496 | joydev = kzalloc(sizeof(struct joydev), GFP_KERNEL); |
482 | return NULL; | 497 | if (!joydev) |
498 | return -ENOMEM; | ||
483 | 499 | ||
484 | INIT_LIST_HEAD(&joydev->list); | 500 | INIT_LIST_HEAD(&joydev->client_list); |
485 | init_waitqueue_head(&joydev->wait); | 501 | init_waitqueue_head(&joydev->wait); |
486 | 502 | ||
487 | joydev->minor = minor; | 503 | joydev->minor = minor; |
@@ -534,31 +550,54 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct | |||
534 | 550 | ||
535 | joydev_table[minor] = joydev; | 551 | joydev_table[minor] = joydev; |
536 | 552 | ||
537 | cdev = class_device_create(&input_class, &dev->cdev, | 553 | devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor), |
538 | MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor), | 554 | |
539 | dev->cdev.dev, joydev->name); | 555 | cdev = class_device_create(&input_class, &dev->cdev, devt, |
556 | dev->cdev.dev, joydev->name); | ||
557 | if (IS_ERR(cdev)) { | ||
558 | error = PTR_ERR(cdev); | ||
559 | goto err_free_joydev; | ||
560 | } | ||
540 | 561 | ||
541 | /* temporary symlink to keep userspace happy */ | 562 | /* temporary symlink to keep userspace happy */ |
542 | sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj, | 563 | error = sysfs_create_link(&input_class.subsys.kobj, |
543 | joydev->name); | 564 | &cdev->kobj, joydev->name); |
565 | if (error) | ||
566 | goto err_cdev_destroy; | ||
567 | |||
568 | error = input_register_handle(&joydev->handle); | ||
569 | if (error) | ||
570 | goto err_remove_link; | ||
571 | |||
572 | return 0; | ||
544 | 573 | ||
545 | return &joydev->handle; | 574 | err_remove_link: |
575 | sysfs_remove_link(&input_class.subsys.kobj, joydev->name); | ||
576 | err_cdev_destroy: | ||
577 | class_device_destroy(&input_class, devt); | ||
578 | err_free_joydev: | ||
579 | joydev_table[minor] = NULL; | ||
580 | kfree(joydev); | ||
581 | return error; | ||
546 | } | 582 | } |
547 | 583 | ||
584 | |||
548 | static void joydev_disconnect(struct input_handle *handle) | 585 | static void joydev_disconnect(struct input_handle *handle) |
549 | { | 586 | { |
550 | struct joydev *joydev = handle->private; | 587 | struct joydev *joydev = handle->private; |
551 | struct joydev_list *list; | 588 | struct joydev_client *client; |
589 | |||
590 | input_unregister_handle(handle); | ||
552 | 591 | ||
553 | sysfs_remove_link(&input_class.subsys.kset.kobj, joydev->name); | 592 | sysfs_remove_link(&input_class.subsys.kobj, joydev->name); |
554 | class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor)); | 593 | class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor)); |
555 | joydev->exist = 0; | 594 | joydev->exist = 0; |
556 | 595 | ||
557 | if (joydev->open) { | 596 | if (joydev->open) { |
558 | input_close_device(handle); | 597 | input_close_device(handle); |
559 | wake_up_interruptible(&joydev->wait); | 598 | wake_up_interruptible(&joydev->wait); |
560 | list_for_each_entry(list, &joydev->list, node) | 599 | list_for_each_entry(client, &joydev->client_list, node) |
561 | kill_fasync(&list->fasync, SIGIO, POLL_HUP); | 600 | kill_fasync(&client->fasync, SIGIO, POLL_HUP); |
562 | } else | 601 | } else |
563 | joydev_free(joydev); | 602 | joydev_free(joydev); |
564 | } | 603 | } |
diff --git a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c index b11a4bbc84c4..ff701ab10d74 100644 --- a/drivers/input/joystick/a3d.c +++ b/drivers/input/joystick/a3d.c | |||
@@ -241,7 +241,7 @@ static void a3d_adc_close(struct gameport *gameport) | |||
241 | 241 | ||
242 | static int a3d_open(struct input_dev *dev) | 242 | static int a3d_open(struct input_dev *dev) |
243 | { | 243 | { |
244 | struct a3d *a3d = dev->private; | 244 | struct a3d *a3d = input_get_drvdata(dev); |
245 | 245 | ||
246 | gameport_start_polling(a3d->gameport); | 246 | gameport_start_polling(a3d->gameport); |
247 | return 0; | 247 | return 0; |
@@ -253,7 +253,7 @@ static int a3d_open(struct input_dev *dev) | |||
253 | 253 | ||
254 | static void a3d_close(struct input_dev *dev) | 254 | static void a3d_close(struct input_dev *dev) |
255 | { | 255 | { |
256 | struct a3d *a3d = dev->private; | 256 | struct a3d *a3d = input_get_drvdata(dev); |
257 | 257 | ||
258 | gameport_stop_polling(a3d->gameport); | 258 | gameport_stop_polling(a3d->gameport); |
259 | } | 259 | } |
@@ -314,11 +314,12 @@ static int a3d_connect(struct gameport *gameport, struct gameport_driver *drv) | |||
314 | input_dev->id.vendor = GAMEPORT_ID_VENDOR_MADCATZ; | 314 | input_dev->id.vendor = GAMEPORT_ID_VENDOR_MADCATZ; |
315 | input_dev->id.product = a3d->mode; | 315 | input_dev->id.product = a3d->mode; |
316 | input_dev->id.version = 0x0100; | 316 | input_dev->id.version = 0x0100; |
317 | input_dev->cdev.dev = &gameport->dev; | 317 | input_dev->dev.parent = &gameport->dev; |
318 | input_dev->private = a3d; | ||
319 | input_dev->open = a3d_open; | 318 | input_dev->open = a3d_open; |
320 | input_dev->close = a3d_close; | 319 | input_dev->close = a3d_close; |
321 | 320 | ||
321 | input_set_drvdata(input_dev, a3d); | ||
322 | |||
322 | if (a3d->mode == A3D_MODE_PXL) { | 323 | if (a3d->mode == A3D_MODE_PXL) { |
323 | 324 | ||
324 | int axes[] = { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER }; | 325 | int axes[] = { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER }; |
diff --git a/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c index 6279ced8a35b..28140c4a110d 100644 --- a/drivers/input/joystick/adi.c +++ b/drivers/input/joystick/adi.c | |||
@@ -290,7 +290,7 @@ static void adi_poll(struct gameport *gameport) | |||
290 | 290 | ||
291 | static int adi_open(struct input_dev *dev) | 291 | static int adi_open(struct input_dev *dev) |
292 | { | 292 | { |
293 | struct adi_port *port = dev->private; | 293 | struct adi_port *port = input_get_drvdata(dev); |
294 | 294 | ||
295 | gameport_start_polling(port->gameport); | 295 | gameport_start_polling(port->gameport); |
296 | return 0; | 296 | return 0; |
@@ -302,7 +302,7 @@ static int adi_open(struct input_dev *dev) | |||
302 | 302 | ||
303 | static void adi_close(struct input_dev *dev) | 303 | static void adi_close(struct input_dev *dev) |
304 | { | 304 | { |
305 | struct adi_port *port = dev->private; | 305 | struct adi_port *port = input_get_drvdata(dev); |
306 | 306 | ||
307 | gameport_stop_polling(port->gameport); | 307 | gameport_stop_polling(port->gameport); |
308 | } | 308 | } |
@@ -424,8 +424,9 @@ static int adi_init_input(struct adi *adi, struct adi_port *port, int half) | |||
424 | input_dev->id.vendor = GAMEPORT_ID_VENDOR_LOGITECH; | 424 | input_dev->id.vendor = GAMEPORT_ID_VENDOR_LOGITECH; |
425 | input_dev->id.product = adi->id; | 425 | input_dev->id.product = adi->id; |
426 | input_dev->id.version = 0x0100; | 426 | input_dev->id.version = 0x0100; |
427 | input_dev->cdev.dev = &port->gameport->dev; | 427 | input_dev->dev.parent = &port->gameport->dev; |
428 | input_dev->private = port; | 428 | |
429 | input_set_drvdata(input_dev, port); | ||
429 | 430 | ||
430 | input_dev->open = adi_open; | 431 | input_dev->open = adi_open; |
431 | input_dev->close = adi_close; | 432 | input_dev->close = adi_close; |
diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c index 51f1e4bfff3e..1c1afb5d4684 100644 --- a/drivers/input/joystick/analog.c +++ b/drivers/input/joystick/analog.c | |||
@@ -343,7 +343,7 @@ static void analog_poll(struct gameport *gameport) | |||
343 | 343 | ||
344 | static int analog_open(struct input_dev *dev) | 344 | static int analog_open(struct input_dev *dev) |
345 | { | 345 | { |
346 | struct analog_port *port = dev->private; | 346 | struct analog_port *port = input_get_drvdata(dev); |
347 | 347 | ||
348 | gameport_start_polling(port->gameport); | 348 | gameport_start_polling(port->gameport); |
349 | return 0; | 349 | return 0; |
@@ -355,7 +355,7 @@ static int analog_open(struct input_dev *dev) | |||
355 | 355 | ||
356 | static void analog_close(struct input_dev *dev) | 356 | static void analog_close(struct input_dev *dev) |
357 | { | 357 | { |
358 | struct analog_port *port = dev->private; | 358 | struct analog_port *port = input_get_drvdata(dev); |
359 | 359 | ||
360 | gameport_stop_polling(port->gameport); | 360 | gameport_stop_polling(port->gameport); |
361 | } | 361 | } |
@@ -449,10 +449,13 @@ static int analog_init_device(struct analog_port *port, struct analog *analog, i | |||
449 | input_dev->id.vendor = GAMEPORT_ID_VENDOR_ANALOG; | 449 | input_dev->id.vendor = GAMEPORT_ID_VENDOR_ANALOG; |
450 | input_dev->id.product = analog->mask >> 4; | 450 | input_dev->id.product = analog->mask >> 4; |
451 | input_dev->id.version = 0x0100; | 451 | input_dev->id.version = 0x0100; |
452 | input_dev->dev.parent = &port->gameport->dev; | ||
453 | |||
454 | input_set_drvdata(input_dev, port); | ||
452 | 455 | ||
453 | input_dev->open = analog_open; | 456 | input_dev->open = analog_open; |
454 | input_dev->close = analog_close; | 457 | input_dev->close = analog_close; |
455 | input_dev->private = port; | 458 | |
456 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | 459 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); |
457 | 460 | ||
458 | for (i = j = 0; i < 4; i++) | 461 | for (i = j = 0; i < 4; i++) |
diff --git a/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c index 034ec39c251d..d3352a849b85 100644 --- a/drivers/input/joystick/cobra.c +++ b/drivers/input/joystick/cobra.c | |||
@@ -142,7 +142,7 @@ static void cobra_poll(struct gameport *gameport) | |||
142 | 142 | ||
143 | static int cobra_open(struct input_dev *dev) | 143 | static int cobra_open(struct input_dev *dev) |
144 | { | 144 | { |
145 | struct cobra *cobra = dev->private; | 145 | struct cobra *cobra = input_get_drvdata(dev); |
146 | 146 | ||
147 | gameport_start_polling(cobra->gameport); | 147 | gameport_start_polling(cobra->gameport); |
148 | return 0; | 148 | return 0; |
@@ -150,7 +150,7 @@ static int cobra_open(struct input_dev *dev) | |||
150 | 150 | ||
151 | static void cobra_close(struct input_dev *dev) | 151 | static void cobra_close(struct input_dev *dev) |
152 | { | 152 | { |
153 | struct cobra *cobra = dev->private; | 153 | struct cobra *cobra = input_get_drvdata(dev); |
154 | 154 | ||
155 | gameport_stop_polling(cobra->gameport); | 155 | gameport_stop_polling(cobra->gameport); |
156 | } | 156 | } |
@@ -211,8 +211,9 @@ static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv) | |||
211 | input_dev->id.vendor = GAMEPORT_ID_VENDOR_CREATIVE; | 211 | input_dev->id.vendor = GAMEPORT_ID_VENDOR_CREATIVE; |
212 | input_dev->id.product = 0x0008; | 212 | input_dev->id.product = 0x0008; |
213 | input_dev->id.version = 0x0100; | 213 | input_dev->id.version = 0x0100; |
214 | input_dev->cdev.dev = &gameport->dev; | 214 | input_dev->dev.parent = &gameport->dev; |
215 | input_dev->private = cobra; | 215 | |
216 | input_set_drvdata(input_dev, cobra); | ||
216 | 217 | ||
217 | input_dev->open = cobra_open; | 218 | input_dev->open = cobra_open; |
218 | input_dev->close = cobra_close; | 219 | input_dev->close = cobra_close; |
diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c index b41bd2eb37dd..c27593bf9978 100644 --- a/drivers/input/joystick/db9.c +++ b/drivers/input/joystick/db9.c | |||
@@ -518,7 +518,7 @@ static void db9_timer(unsigned long private) | |||
518 | 518 | ||
519 | static int db9_open(struct input_dev *dev) | 519 | static int db9_open(struct input_dev *dev) |
520 | { | 520 | { |
521 | struct db9 *db9 = dev->private; | 521 | struct db9 *db9 = input_get_drvdata(dev); |
522 | struct parport *port = db9->pd->port; | 522 | struct parport *port = db9->pd->port; |
523 | int err; | 523 | int err; |
524 | 524 | ||
@@ -542,7 +542,7 @@ static int db9_open(struct input_dev *dev) | |||
542 | 542 | ||
543 | static void db9_close(struct input_dev *dev) | 543 | static void db9_close(struct input_dev *dev) |
544 | { | 544 | { |
545 | struct db9 *db9 = dev->private; | 545 | struct db9 *db9 = input_get_drvdata(dev); |
546 | struct parport *port = db9->pd->port; | 546 | struct parport *port = db9->pd->port; |
547 | 547 | ||
548 | mutex_lock(&db9->mutex); | 548 | mutex_lock(&db9->mutex); |
@@ -625,7 +625,8 @@ static struct db9 __init *db9_probe(int parport, int mode) | |||
625 | input_dev->id.vendor = 0x0002; | 625 | input_dev->id.vendor = 0x0002; |
626 | input_dev->id.product = mode; | 626 | input_dev->id.product = mode; |
627 | input_dev->id.version = 0x0100; | 627 | input_dev->id.version = 0x0100; |
628 | input_dev->private = db9; | 628 | |
629 | input_set_drvdata(input_dev, db9); | ||
629 | 630 | ||
630 | input_dev->open = db9_open; | 631 | input_dev->open = db9_open; |
631 | input_dev->close = db9_close; | 632 | input_dev->close = db9_close; |
diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index 711e4b3e9e61..c71b58fe225d 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c | |||
@@ -591,7 +591,7 @@ static void gc_timer(unsigned long private) | |||
591 | 591 | ||
592 | static int gc_open(struct input_dev *dev) | 592 | static int gc_open(struct input_dev *dev) |
593 | { | 593 | { |
594 | struct gc *gc = dev->private; | 594 | struct gc *gc = input_get_drvdata(dev); |
595 | int err; | 595 | int err; |
596 | 596 | ||
597 | err = mutex_lock_interruptible(&gc->mutex); | 597 | err = mutex_lock_interruptible(&gc->mutex); |
@@ -610,7 +610,7 @@ static int gc_open(struct input_dev *dev) | |||
610 | 610 | ||
611 | static void gc_close(struct input_dev *dev) | 611 | static void gc_close(struct input_dev *dev) |
612 | { | 612 | { |
613 | struct gc *gc = dev->private; | 613 | struct gc *gc = input_get_drvdata(dev); |
614 | 614 | ||
615 | mutex_lock(&gc->mutex); | 615 | mutex_lock(&gc->mutex); |
616 | if (!--gc->used) { | 616 | if (!--gc->used) { |
@@ -646,7 +646,8 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) | |||
646 | input_dev->id.vendor = 0x0001; | 646 | input_dev->id.vendor = 0x0001; |
647 | input_dev->id.product = pad_type; | 647 | input_dev->id.product = pad_type; |
648 | input_dev->id.version = 0x0100; | 648 | input_dev->id.version = 0x0100; |
649 | input_dev->private = gc; | 649 | |
650 | input_set_drvdata(input_dev, gc); | ||
650 | 651 | ||
651 | input_dev->open = gc_open; | 652 | input_dev->open = gc_open; |
652 | input_dev->close = gc_close; | 653 | input_dev->close = gc_close; |
diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c index bacbab5d1b6f..d514aebf7554 100644 --- a/drivers/input/joystick/gf2k.c +++ b/drivers/input/joystick/gf2k.c | |||
@@ -220,7 +220,7 @@ static void gf2k_poll(struct gameport *gameport) | |||
220 | 220 | ||
221 | static int gf2k_open(struct input_dev *dev) | 221 | static int gf2k_open(struct input_dev *dev) |
222 | { | 222 | { |
223 | struct gf2k *gf2k = dev->private; | 223 | struct gf2k *gf2k = input_get_drvdata(dev); |
224 | 224 | ||
225 | gameport_start_polling(gf2k->gameport); | 225 | gameport_start_polling(gf2k->gameport); |
226 | return 0; | 226 | return 0; |
@@ -228,7 +228,7 @@ static int gf2k_open(struct input_dev *dev) | |||
228 | 228 | ||
229 | static void gf2k_close(struct input_dev *dev) | 229 | static void gf2k_close(struct input_dev *dev) |
230 | { | 230 | { |
231 | struct gf2k *gf2k = dev->private; | 231 | struct gf2k *gf2k = input_get_drvdata(dev); |
232 | 232 | ||
233 | gameport_stop_polling(gf2k->gameport); | 233 | gameport_stop_polling(gf2k->gameport); |
234 | } | 234 | } |
@@ -308,11 +308,13 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv) | |||
308 | input_dev->id.vendor = GAMEPORT_ID_VENDOR_GENIUS; | 308 | input_dev->id.vendor = GAMEPORT_ID_VENDOR_GENIUS; |
309 | input_dev->id.product = gf2k->id; | 309 | input_dev->id.product = gf2k->id; |
310 | input_dev->id.version = 0x0100; | 310 | input_dev->id.version = 0x0100; |
311 | input_dev->cdev.dev = &gameport->dev; | 311 | input_dev->dev.parent = &gameport->dev; |
312 | input_dev->private = gf2k; | 312 | |
313 | input_set_drvdata(input_dev, gf2k); | ||
313 | 314 | ||
314 | input_dev->open = gf2k_open; | 315 | input_dev->open = gf2k_open; |
315 | input_dev->close = gf2k_close; | 316 | input_dev->close = gf2k_close; |
317 | |||
316 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | 318 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); |
317 | 319 | ||
318 | for (i = 0; i < gf2k_axes[gf2k->id]; i++) | 320 | for (i = 0; i < gf2k_axes[gf2k->id]; i++) |
diff --git a/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c index 17a90c436de8..73eb5ab6f140 100644 --- a/drivers/input/joystick/grip.c +++ b/drivers/input/joystick/grip.c | |||
@@ -285,7 +285,7 @@ static void grip_poll(struct gameport *gameport) | |||
285 | 285 | ||
286 | static int grip_open(struct input_dev *dev) | 286 | static int grip_open(struct input_dev *dev) |
287 | { | 287 | { |
288 | struct grip *grip = dev->private; | 288 | struct grip *grip = input_get_drvdata(dev); |
289 | 289 | ||
290 | gameport_start_polling(grip->gameport); | 290 | gameport_start_polling(grip->gameport); |
291 | return 0; | 291 | return 0; |
@@ -293,7 +293,7 @@ static int grip_open(struct input_dev *dev) | |||
293 | 293 | ||
294 | static void grip_close(struct input_dev *dev) | 294 | static void grip_close(struct input_dev *dev) |
295 | { | 295 | { |
296 | struct grip *grip = dev->private; | 296 | struct grip *grip = input_get_drvdata(dev); |
297 | 297 | ||
298 | gameport_stop_polling(grip->gameport); | 298 | gameport_stop_polling(grip->gameport); |
299 | } | 299 | } |
@@ -363,8 +363,9 @@ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv) | |||
363 | input_dev->id.vendor = GAMEPORT_ID_VENDOR_GRAVIS; | 363 | input_dev->id.vendor = GAMEPORT_ID_VENDOR_GRAVIS; |
364 | input_dev->id.product = grip->mode[i]; | 364 | input_dev->id.product = grip->mode[i]; |
365 | input_dev->id.version = 0x0100; | 365 | input_dev->id.version = 0x0100; |
366 | input_dev->cdev.dev = &gameport->dev; | 366 | input_dev->dev.parent = &gameport->dev; |
367 | input_dev->private = grip; | 367 | |
368 | input_set_drvdata(input_dev, grip); | ||
368 | 369 | ||
369 | input_dev->open = grip_open; | 370 | input_dev->open = grip_open; |
370 | input_dev->close = grip_close; | 371 | input_dev->close = grip_close; |
diff --git a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c index 8120a9c40773..555319e6378c 100644 --- a/drivers/input/joystick/grip_mp.c +++ b/drivers/input/joystick/grip_mp.c | |||
@@ -562,7 +562,7 @@ static void grip_poll(struct gameport *gameport) | |||
562 | 562 | ||
563 | static int grip_open(struct input_dev *dev) | 563 | static int grip_open(struct input_dev *dev) |
564 | { | 564 | { |
565 | struct grip_mp *grip = dev->private; | 565 | struct grip_mp *grip = input_get_drvdata(dev); |
566 | 566 | ||
567 | gameport_start_polling(grip->gameport); | 567 | gameport_start_polling(grip->gameport); |
568 | return 0; | 568 | return 0; |
@@ -574,9 +574,9 @@ static int grip_open(struct input_dev *dev) | |||
574 | 574 | ||
575 | static void grip_close(struct input_dev *dev) | 575 | static void grip_close(struct input_dev *dev) |
576 | { | 576 | { |
577 | struct grip_mp *grip = dev->private; | 577 | struct grip_mp *grip = input_get_drvdata(dev); |
578 | 578 | ||
579 | gameport_start_polling(grip->gameport); | 579 | gameport_stop_polling(grip->gameport); |
580 | } | 580 | } |
581 | 581 | ||
582 | /* | 582 | /* |
@@ -599,8 +599,9 @@ static int register_slot(int slot, struct grip_mp *grip) | |||
599 | input_dev->id.vendor = GAMEPORT_ID_VENDOR_GRAVIS; | 599 | input_dev->id.vendor = GAMEPORT_ID_VENDOR_GRAVIS; |
600 | input_dev->id.product = 0x0100 + port->mode; | 600 | input_dev->id.product = 0x0100 + port->mode; |
601 | input_dev->id.version = 0x0100; | 601 | input_dev->id.version = 0x0100; |
602 | input_dev->cdev.dev = &grip->gameport->dev; | 602 | input_dev->dev.parent = &grip->gameport->dev; |
603 | input_dev->private = grip; | 603 | |
604 | input_set_drvdata(input_dev, grip); | ||
604 | 605 | ||
605 | input_dev->open = grip_open; | 606 | input_dev->open = grip_open; |
606 | input_dev->close = grip_close; | 607 | input_dev->close = grip_close; |
diff --git a/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c index dbc5d92858b8..d4e8073caf27 100644 --- a/drivers/input/joystick/guillemot.c +++ b/drivers/input/joystick/guillemot.c | |||
@@ -156,7 +156,7 @@ static void guillemot_poll(struct gameport *gameport) | |||
156 | 156 | ||
157 | static int guillemot_open(struct input_dev *dev) | 157 | static int guillemot_open(struct input_dev *dev) |
158 | { | 158 | { |
159 | struct guillemot *guillemot = dev->private; | 159 | struct guillemot *guillemot = input_get_drvdata(dev); |
160 | 160 | ||
161 | gameport_start_polling(guillemot->gameport); | 161 | gameport_start_polling(guillemot->gameport); |
162 | return 0; | 162 | return 0; |
@@ -168,7 +168,7 @@ static int guillemot_open(struct input_dev *dev) | |||
168 | 168 | ||
169 | static void guillemot_close(struct input_dev *dev) | 169 | static void guillemot_close(struct input_dev *dev) |
170 | { | 170 | { |
171 | struct guillemot *guillemot = dev->private; | 171 | struct guillemot *guillemot = input_get_drvdata(dev); |
172 | 172 | ||
173 | gameport_stop_polling(guillemot->gameport); | 173 | gameport_stop_polling(guillemot->gameport); |
174 | } | 174 | } |
@@ -231,8 +231,9 @@ static int guillemot_connect(struct gameport *gameport, struct gameport_driver * | |||
231 | input_dev->id.vendor = GAMEPORT_ID_VENDOR_GUILLEMOT; | 231 | input_dev->id.vendor = GAMEPORT_ID_VENDOR_GUILLEMOT; |
232 | input_dev->id.product = guillemot_type[i].id; | 232 | input_dev->id.product = guillemot_type[i].id; |
233 | input_dev->id.version = (int)data[14] << 8 | data[15]; | 233 | input_dev->id.version = (int)data[14] << 8 | data[15]; |
234 | input_dev->cdev.dev = &gameport->dev; | 234 | input_dev->dev.parent = &gameport->dev; |
235 | input_dev->private = guillemot; | 235 | |
236 | input_set_drvdata(input_dev, guillemot); | ||
236 | 237 | ||
237 | input_dev->open = guillemot_open; | 238 | input_dev->open = guillemot_open; |
238 | input_dev->close = guillemot_close; | 239 | input_dev->close = guillemot_close; |
diff --git a/drivers/input/joystick/iforce/iforce-ff.c b/drivers/input/joystick/iforce/iforce-ff.c index 8fb0c19cc60e..f2a4381d0ab8 100644 --- a/drivers/input/joystick/iforce/iforce-ff.c +++ b/drivers/input/joystick/iforce/iforce-ff.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * $Id: iforce-ff.c,v 1.9 2002/02/02 19:28:35 jdeneux Exp $ | 2 | * $Id: iforce-ff.c,v 1.9 2002/02/02 19:28:35 jdeneux Exp $ |
3 | * | 3 | * |
4 | * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz> | 4 | * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz> |
5 | * Copyright (c) 2001-2002 Johann Deneux <deneux@ifrance.com> | 5 | * Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com> |
6 | * | 6 | * |
7 | * USB/RS232 I-Force joysticks and wheels. | 7 | * USB/RS232 I-Force joysticks and wheels. |
8 | */ | 8 | */ |
@@ -205,7 +205,7 @@ static int need_condition_modifier(struct ff_effect *old, struct ff_effect *new) | |||
205 | int i; | 205 | int i; |
206 | 206 | ||
207 | if (new->type != FF_SPRING && new->type != FF_FRICTION) { | 207 | if (new->type != FF_SPRING && new->type != FF_FRICTION) { |
208 | printk(KERN_WARNING "iforce.c: bad effect type in need_condition_modifier\n"); | 208 | warn("bad effect type in need_condition_modifier"); |
209 | return 0; | 209 | return 0; |
210 | } | 210 | } |
211 | 211 | ||
@@ -227,7 +227,7 @@ static int need_condition_modifier(struct ff_effect *old, struct ff_effect *new) | |||
227 | static int need_magnitude_modifier(struct ff_effect *old, struct ff_effect *effect) | 227 | static int need_magnitude_modifier(struct ff_effect *old, struct ff_effect *effect) |
228 | { | 228 | { |
229 | if (effect->type != FF_CONSTANT) { | 229 | if (effect->type != FF_CONSTANT) { |
230 | printk(KERN_WARNING "iforce.c: bad effect type in need_envelope_modifier\n"); | 230 | warn("bad effect type in need_envelope_modifier"); |
231 | return 0; | 231 | return 0; |
232 | } | 232 | } |
233 | 233 | ||
@@ -258,7 +258,7 @@ static int need_envelope_modifier(struct ff_effect *old, struct ff_effect *effec | |||
258 | break; | 258 | break; |
259 | 259 | ||
260 | default: | 260 | default: |
261 | printk(KERN_WARNING "iforce.c: bad effect type in need_envelope_modifier\n"); | 261 | warn("bad effect type in need_envelope_modifier"); |
262 | } | 262 | } |
263 | 263 | ||
264 | return 0; | 264 | return 0; |
@@ -271,7 +271,7 @@ static int need_envelope_modifier(struct ff_effect *old, struct ff_effect *effec | |||
271 | static int need_period_modifier(struct ff_effect *old, struct ff_effect *new) | 271 | static int need_period_modifier(struct ff_effect *old, struct ff_effect *new) |
272 | { | 272 | { |
273 | if (new->type != FF_PERIODIC) { | 273 | if (new->type != FF_PERIODIC) { |
274 | printk(KERN_WARNING "iforce.c: bad effect type in need_period_modifier\n"); | 274 | warn("bad effect type in need_period_modifier"); |
275 | return 0; | 275 | return 0; |
276 | } | 276 | } |
277 | return (old->u.periodic.period != new->u.periodic.period | 277 | return (old->u.periodic.period != new->u.periodic.period |
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index 3393a37fec39..fb129c479a66 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * $Id: iforce-main.c,v 1.19 2002/07/07 10:22:50 jdeneux Exp $ | 2 | * $Id: iforce-main.c,v 1.19 2002/07/07 10:22:50 jdeneux Exp $ |
3 | * | 3 | * |
4 | * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz> | 4 | * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz> |
5 | * Copyright (c) 2001-2002 Johann Deneux <deneux@ifrance.com> | 5 | * Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com> |
6 | * | 6 | * |
7 | * USB/RS232 I-Force joysticks and wheels. | 7 | * USB/RS232 I-Force joysticks and wheels. |
8 | */ | 8 | */ |
@@ -29,7 +29,7 @@ | |||
29 | 29 | ||
30 | #include "iforce.h" | 30 | #include "iforce.h" |
31 | 31 | ||
32 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>, Johann Deneux <deneux@ifrance.com>"); | 32 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>, Johann Deneux <johann.deneux@gmail.com>"); |
33 | MODULE_DESCRIPTION("USB/RS232 I-Force joysticks and wheels driver"); | 33 | MODULE_DESCRIPTION("USB/RS232 I-Force joysticks and wheels driver"); |
34 | MODULE_LICENSE("GPL"); | 34 | MODULE_LICENSE("GPL"); |
35 | 35 | ||
@@ -220,7 +220,7 @@ static void iforce_release(struct input_dev *dev) | |||
220 | /* Check: no effects should be present in memory */ | 220 | /* Check: no effects should be present in memory */ |
221 | for (i = 0; i < dev->ff->max_effects; i++) { | 221 | for (i = 0; i < dev->ff->max_effects; i++) { |
222 | if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags)) { | 222 | if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags)) { |
223 | printk(KERN_WARNING "iforce_release: Device still owns effects\n"); | 223 | warn("iforce_release: Device still owns effects"); |
224 | break; | 224 | break; |
225 | } | 225 | } |
226 | } | 226 | } |
@@ -232,7 +232,7 @@ static void iforce_release(struct input_dev *dev) | |||
232 | switch (iforce->bus) { | 232 | switch (iforce->bus) { |
233 | #ifdef CONFIG_JOYSTICK_IFORCE_USB | 233 | #ifdef CONFIG_JOYSTICK_IFORCE_USB |
234 | case IFORCE_USB: | 234 | case IFORCE_USB: |
235 | usb_unlink_urb(iforce->irq); | 235 | usb_kill_urb(iforce->irq); |
236 | 236 | ||
237 | /* The device was unplugged before the file | 237 | /* The device was unplugged before the file |
238 | * was released */ | 238 | * was released */ |
@@ -287,13 +287,13 @@ int iforce_init_device(struct iforce *iforce) | |||
287 | #ifdef CONFIG_JOYSTICK_IFORCE_USB | 287 | #ifdef CONFIG_JOYSTICK_IFORCE_USB |
288 | case IFORCE_USB: | 288 | case IFORCE_USB: |
289 | input_dev->id.bustype = BUS_USB; | 289 | input_dev->id.bustype = BUS_USB; |
290 | input_dev->cdev.dev = &iforce->usbdev->dev; | 290 | input_dev->dev.parent = &iforce->usbdev->dev; |
291 | break; | 291 | break; |
292 | #endif | 292 | #endif |
293 | #ifdef CONFIG_JOYSTICK_IFORCE_232 | 293 | #ifdef CONFIG_JOYSTICK_IFORCE_232 |
294 | case IFORCE_232: | 294 | case IFORCE_232: |
295 | input_dev->id.bustype = BUS_RS232; | 295 | input_dev->id.bustype = BUS_RS232; |
296 | input_dev->cdev.dev = &iforce->serio->dev; | 296 | input_dev->dev.parent = &iforce->serio->dev; |
297 | break; | 297 | break; |
298 | #endif | 298 | #endif |
299 | } | 299 | } |
@@ -324,7 +324,7 @@ int iforce_init_device(struct iforce *iforce) | |||
324 | break; | 324 | break; |
325 | 325 | ||
326 | if (i == 20) { /* 5 seconds */ | 326 | if (i == 20) { /* 5 seconds */ |
327 | printk(KERN_ERR "iforce-main.c: Timeout waiting for response from device.\n"); | 327 | err("Timeout waiting for response from device."); |
328 | error = -ENODEV; | 328 | error = -ENODEV; |
329 | goto fail; | 329 | goto fail; |
330 | } | 330 | } |
@@ -336,26 +336,26 @@ int iforce_init_device(struct iforce *iforce) | |||
336 | if (!iforce_get_id_packet(iforce, "M")) | 336 | if (!iforce_get_id_packet(iforce, "M")) |
337 | input_dev->id.vendor = (iforce->edata[2] << 8) | iforce->edata[1]; | 337 | input_dev->id.vendor = (iforce->edata[2] << 8) | iforce->edata[1]; |
338 | else | 338 | else |
339 | printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet M\n"); | 339 | warn("Device does not respond to id packet M"); |
340 | 340 | ||
341 | if (!iforce_get_id_packet(iforce, "P")) | 341 | if (!iforce_get_id_packet(iforce, "P")) |
342 | input_dev->id.product = (iforce->edata[2] << 8) | iforce->edata[1]; | 342 | input_dev->id.product = (iforce->edata[2] << 8) | iforce->edata[1]; |
343 | else | 343 | else |
344 | printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet P\n"); | 344 | warn("Device does not respond to id packet P"); |
345 | 345 | ||
346 | if (!iforce_get_id_packet(iforce, "B")) | 346 | if (!iforce_get_id_packet(iforce, "B")) |
347 | iforce->device_memory.end = (iforce->edata[2] << 8) | iforce->edata[1]; | 347 | iforce->device_memory.end = (iforce->edata[2] << 8) | iforce->edata[1]; |
348 | else | 348 | else |
349 | printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet B\n"); | 349 | warn("Device does not respond to id packet B"); |
350 | 350 | ||
351 | if (!iforce_get_id_packet(iforce, "N")) | 351 | if (!iforce_get_id_packet(iforce, "N")) |
352 | ff_effects = iforce->edata[1]; | 352 | ff_effects = iforce->edata[1]; |
353 | else | 353 | else |
354 | printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet N\n"); | 354 | warn("Device does not respond to id packet N"); |
355 | 355 | ||
356 | /* Check if the device can store more effects than the driver can really handle */ | 356 | /* Check if the device can store more effects than the driver can really handle */ |
357 | if (ff_effects > IFORCE_EFFECTS_MAX) { | 357 | if (ff_effects > IFORCE_EFFECTS_MAX) { |
358 | printk(KERN_WARNING "iforce: Limiting number of effects to %d (device reports %d)\n", | 358 | warn("Limiting number of effects to %d (device reports %d)", |
359 | IFORCE_EFFECTS_MAX, ff_effects); | 359 | IFORCE_EFFECTS_MAX, ff_effects); |
360 | ff_effects = IFORCE_EFFECTS_MAX; | 360 | ff_effects = IFORCE_EFFECTS_MAX; |
361 | } | 361 | } |
@@ -457,8 +457,6 @@ int iforce_init_device(struct iforce *iforce) | |||
457 | if (error) | 457 | if (error) |
458 | goto fail; | 458 | goto fail; |
459 | 459 | ||
460 | printk(KERN_DEBUG "iforce->dev->open = %p\n", iforce->dev->open); | ||
461 | |||
462 | return 0; | 460 | return 0; |
463 | 461 | ||
464 | fail: input_free_device(input_dev); | 462 | fail: input_free_device(input_dev); |
diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c index 808f05932a6f..21c4e13d3a50 100644 --- a/drivers/input/joystick/iforce/iforce-packets.c +++ b/drivers/input/joystick/iforce/iforce-packets.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * $Id: iforce-packets.c,v 1.16 2002/07/07 10:22:50 jdeneux Exp $ | 2 | * $Id: iforce-packets.c,v 1.16 2002/07/07 10:22:50 jdeneux Exp $ |
3 | * | 3 | * |
4 | * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz> | 4 | * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz> |
5 | * Copyright (c) 2001-2002 Johann Deneux <deneux@ifrance.com> | 5 | * Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com> |
6 | * | 6 | * |
7 | * USB/RS232 I-Force joysticks and wheels. | 7 | * USB/RS232 I-Force joysticks and wheels. |
8 | */ | 8 | */ |
@@ -39,10 +39,10 @@ void iforce_dump_packet(char *msg, u16 cmd, unsigned char *data) | |||
39 | { | 39 | { |
40 | int i; | 40 | int i; |
41 | 41 | ||
42 | printk(KERN_DEBUG "iforce.c: %s ( cmd = %04x, data = ", msg, cmd); | 42 | printk(KERN_DEBUG __FILE__ ": %s cmd = %04x, data = ", msg, cmd); |
43 | for (i = 0; i < LO(cmd); i++) | 43 | for (i = 0; i < LO(cmd); i++) |
44 | printk("%02x ", data[i]); | 44 | printk("%02x ", data[i]); |
45 | printk(")\n"); | 45 | printk("\n"); |
46 | } | 46 | } |
47 | 47 | ||
48 | /* | 48 | /* |
@@ -65,8 +65,9 @@ int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data) | |||
65 | head = iforce->xmit.head; | 65 | head = iforce->xmit.head; |
66 | tail = iforce->xmit.tail; | 66 | tail = iforce->xmit.tail; |
67 | 67 | ||
68 | |||
68 | if (CIRC_SPACE(head, tail, XMIT_SIZE) < n+2) { | 69 | if (CIRC_SPACE(head, tail, XMIT_SIZE) < n+2) { |
69 | printk(KERN_WARNING "iforce.c: not enough space in xmit buffer to send new packet\n"); | 70 | warn("not enough space in xmit buffer to send new packet"); |
70 | spin_unlock_irqrestore(&iforce->xmit_lock, flags); | 71 | spin_unlock_irqrestore(&iforce->xmit_lock, flags); |
71 | return -1; | 72 | return -1; |
72 | } | 73 | } |
@@ -126,8 +127,6 @@ int iforce_control_playback(struct iforce* iforce, u16 id, unsigned int value) | |||
126 | { | 127 | { |
127 | unsigned char data[3]; | 128 | unsigned char data[3]; |
128 | 129 | ||
129 | printk(KERN_DEBUG "iforce-packets.c: control_playback %d %d\n", id, value); | ||
130 | |||
131 | data[0] = LO(id); | 130 | data[0] = LO(id); |
132 | data[1] = (value > 0) ? ((value > 1) ? 0x41 : 0x01) : 0; | 131 | data[1] = (value > 0) ? ((value > 1) ? 0x41 : 0x01) : 0; |
133 | data[2] = LO(value); | 132 | data[2] = LO(value); |
@@ -151,7 +150,7 @@ static int mark_core_as_ready(struct iforce *iforce, unsigned short addr) | |||
151 | return 0; | 150 | return 0; |
152 | } | 151 | } |
153 | } | 152 | } |
154 | printk(KERN_WARNING "iforce-packets.c: unused effect %04x updated !!!\n", addr); | 153 | warn("unused effect %04x updated !!!", addr); |
155 | return -1; | 154 | return -1; |
156 | } | 155 | } |
157 | 156 | ||
@@ -162,7 +161,7 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data) | |||
162 | static int being_used = 0; | 161 | static int being_used = 0; |
163 | 162 | ||
164 | if (being_used) | 163 | if (being_used) |
165 | printk(KERN_WARNING "iforce-packets.c: re-entrant call to iforce_process %d\n", being_used); | 164 | warn("re-entrant call to iforce_process %d", being_used); |
166 | being_used++; | 165 | being_used++; |
167 | 166 | ||
168 | #ifdef CONFIG_JOYSTICK_IFORCE_232 | 167 | #ifdef CONFIG_JOYSTICK_IFORCE_232 |
@@ -266,7 +265,7 @@ int iforce_get_id_packet(struct iforce *iforce, char *packet) | |||
266 | return -1; | 265 | return -1; |
267 | } | 266 | } |
268 | #else | 267 | #else |
269 | printk(KERN_ERR "iforce_get_id_packet: iforce->bus = USB!\n"); | 268 | err("iforce_get_id_packet: iforce->bus = USB!"); |
270 | #endif | 269 | #endif |
271 | break; | 270 | break; |
272 | 271 | ||
@@ -284,13 +283,12 @@ int iforce_get_id_packet(struct iforce *iforce, char *packet) | |||
284 | return -1; | 283 | return -1; |
285 | } | 284 | } |
286 | #else | 285 | #else |
287 | printk(KERN_ERR "iforce_get_id_packet: iforce->bus = SERIO!\n"); | 286 | err("iforce_get_id_packet: iforce->bus = SERIO!"); |
288 | #endif | 287 | #endif |
289 | break; | 288 | break; |
290 | 289 | ||
291 | default: | 290 | default: |
292 | printk(KERN_ERR "iforce_get_id_packet: iforce->bus = %d\n", | 291 | err("iforce_get_id_packet: iforce->bus = %d", iforce->bus); |
293 | iforce->bus); | ||
294 | break; | 292 | break; |
295 | } | 293 | } |
296 | 294 | ||
diff --git a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c index ec4be535f483..7b4bc19cef27 100644 --- a/drivers/input/joystick/iforce/iforce-serio.c +++ b/drivers/input/joystick/iforce/iforce-serio.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * $Id: iforce-serio.c,v 1.4 2002/01/28 22:45:00 jdeneux Exp $ | 2 | * $Id: iforce-serio.c,v 1.4 2002/01/28 22:45:00 jdeneux Exp $ |
3 | * | 3 | * |
4 | * Copyright (c) 2000-2001 Vojtech Pavlik <vojtech@ucw.cz> | 4 | * Copyright (c) 2000-2001 Vojtech Pavlik <vojtech@ucw.cz> |
5 | * Copyright (c) 2001 Johann Deneux <deneux@ifrance.com> | 5 | * Copyright (c) 2001, 2007 Johann Deneux <johann.deneux@gmail.com> |
6 | * | 6 | * |
7 | * USB/RS232 I-Force joysticks and wheels. | 7 | * USB/RS232 I-Force joysticks and wheels. |
8 | */ | 8 | */ |
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c index 80cdebcbcb99..750099d8e3c6 100644 --- a/drivers/input/joystick/iforce/iforce-usb.c +++ b/drivers/input/joystick/iforce/iforce-usb.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * $Id: iforce-usb.c,v 1.16 2002/06/09 11:08:04 jdeneux Exp $ | 2 | * $Id: iforce-usb.c,v 1.16 2002/06/09 11:08:04 jdeneux Exp $ |
3 | * | 3 | * |
4 | * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz> | 4 | * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz> |
5 | * Copyright (c) 2001-2002 Johann Deneux <deneux@ifrance.com> | 5 | * Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com> |
6 | * | 6 | * |
7 | * USB/RS232 I-Force joysticks and wheels. | 7 | * USB/RS232 I-Force joysticks and wheels. |
8 | */ | 8 | */ |
@@ -65,7 +65,7 @@ void iforce_usb_xmit(struct iforce *iforce) | |||
65 | XMIT_INC(iforce->xmit.tail, n); | 65 | XMIT_INC(iforce->xmit.tail, n); |
66 | 66 | ||
67 | if ( (n=usb_submit_urb(iforce->out, GFP_ATOMIC)) ) { | 67 | if ( (n=usb_submit_urb(iforce->out, GFP_ATOMIC)) ) { |
68 | printk(KERN_WARNING "iforce-usb.c: iforce_usb_xmit: usb_submit_urb failed %d\n", n); | 68 | warn("usb_submit_urb failed %d\n", n); |
69 | } | 69 | } |
70 | 70 | ||
71 | /* The IFORCE_XMIT_RUNNING bit is not cleared here. That's intended. | 71 | /* The IFORCE_XMIT_RUNNING bit is not cleared here. That's intended. |
@@ -110,7 +110,7 @@ static void iforce_usb_out(struct urb *urb) | |||
110 | struct iforce *iforce = urb->context; | 110 | struct iforce *iforce = urb->context; |
111 | 111 | ||
112 | if (urb->status) { | 112 | if (urb->status) { |
113 | printk(KERN_DEBUG "iforce_usb_out: urb->status %d, exiting", urb->status); | 113 | dbg("urb->status %d, exiting", urb->status); |
114 | return; | 114 | return; |
115 | } | 115 | } |
116 | 116 | ||
@@ -190,10 +190,9 @@ fail: | |||
190 | /* Called by iforce_delete() */ | 190 | /* Called by iforce_delete() */ |
191 | void iforce_usb_delete(struct iforce* iforce) | 191 | void iforce_usb_delete(struct iforce* iforce) |
192 | { | 192 | { |
193 | usb_unlink_urb(iforce->irq); | 193 | usb_kill_urb(iforce->irq); |
194 | /* Is it ok to unlink those ? */ | 194 | usb_kill_urb(iforce->out); |
195 | usb_unlink_urb(iforce->out); | 195 | usb_kill_urb(iforce->ctrl); |
196 | usb_unlink_urb(iforce->ctrl); | ||
197 | 196 | ||
198 | usb_free_urb(iforce->irq); | 197 | usb_free_urb(iforce->irq); |
199 | usb_free_urb(iforce->out); | 198 | usb_free_urb(iforce->out); |
diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h index ffaeaefa1a42..dadcf4fb92ae 100644 --- a/drivers/input/joystick/iforce/iforce.h +++ b/drivers/input/joystick/iforce/iforce.h | |||
@@ -2,7 +2,7 @@ | |||
2 | * $Id: iforce.h,v 1.13 2002/07/07 10:22:50 jdeneux Exp $ | 2 | * $Id: iforce.h,v 1.13 2002/07/07 10:22:50 jdeneux Exp $ |
3 | * | 3 | * |
4 | * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz> | 4 | * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz> |
5 | * Copyright (c) 2001-2002 Johann Deneux <deneux@ifrance.com> | 5 | * Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com> |
6 | * | 6 | * |
7 | * USB/RS232 I-Force joysticks and wheels. | 7 | * USB/RS232 I-Force joysticks and wheels. |
8 | */ | 8 | */ |
diff --git a/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c index fec8b3d0967d..1aec1e9d7c59 100644 --- a/drivers/input/joystick/interact.c +++ b/drivers/input/joystick/interact.c | |||
@@ -185,7 +185,7 @@ static void interact_poll(struct gameport *gameport) | |||
185 | 185 | ||
186 | static int interact_open(struct input_dev *dev) | 186 | static int interact_open(struct input_dev *dev) |
187 | { | 187 | { |
188 | struct interact *interact = dev->private; | 188 | struct interact *interact = input_get_drvdata(dev); |
189 | 189 | ||
190 | gameport_start_polling(interact->gameport); | 190 | gameport_start_polling(interact->gameport); |
191 | return 0; | 191 | return 0; |
@@ -197,7 +197,7 @@ static int interact_open(struct input_dev *dev) | |||
197 | 197 | ||
198 | static void interact_close(struct input_dev *dev) | 198 | static void interact_close(struct input_dev *dev) |
199 | { | 199 | { |
200 | struct interact *interact = dev->private; | 200 | struct interact *interact = input_get_drvdata(dev); |
201 | 201 | ||
202 | gameport_stop_polling(interact->gameport); | 202 | gameport_stop_polling(interact->gameport); |
203 | } | 203 | } |
@@ -262,7 +262,9 @@ static int interact_connect(struct gameport *gameport, struct gameport_driver *d | |||
262 | input_dev->id.vendor = GAMEPORT_ID_VENDOR_INTERACT; | 262 | input_dev->id.vendor = GAMEPORT_ID_VENDOR_INTERACT; |
263 | input_dev->id.product = interact_type[i].id; | 263 | input_dev->id.product = interact_type[i].id; |
264 | input_dev->id.version = 0x0100; | 264 | input_dev->id.version = 0x0100; |
265 | input_dev->private = interact; | 265 | input_dev->dev.parent = &gameport->dev; |
266 | |||
267 | input_set_drvdata(input_dev, interact); | ||
266 | 268 | ||
267 | input_dev->open = interact_open; | 269 | input_dev->open = interact_open; |
268 | input_dev->close = interact_close; | 270 | input_dev->close = interact_close; |
diff --git a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c index 4112789f1196..b35604ee43ae 100644 --- a/drivers/input/joystick/magellan.c +++ b/drivers/input/joystick/magellan.c | |||
@@ -168,8 +168,7 @@ static int magellan_connect(struct serio *serio, struct serio_driver *drv) | |||
168 | input_dev->id.vendor = SERIO_MAGELLAN; | 168 | input_dev->id.vendor = SERIO_MAGELLAN; |
169 | input_dev->id.product = 0x0001; | 169 | input_dev->id.product = 0x0001; |
170 | input_dev->id.version = 0x0100; | 170 | input_dev->id.version = 0x0100; |
171 | input_dev->cdev.dev = &serio->dev; | 171 | input_dev->dev.parent = &serio->dev; |
172 | input_dev->private = magellan; | ||
173 | 172 | ||
174 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | 173 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); |
175 | 174 | ||
diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c index e58b22c018e4..2adf73f63c94 100644 --- a/drivers/input/joystick/sidewinder.c +++ b/drivers/input/joystick/sidewinder.c | |||
@@ -509,7 +509,7 @@ static void sw_poll(struct gameport *gameport) | |||
509 | 509 | ||
510 | static int sw_open(struct input_dev *dev) | 510 | static int sw_open(struct input_dev *dev) |
511 | { | 511 | { |
512 | struct sw *sw = dev->private; | 512 | struct sw *sw = input_get_drvdata(dev); |
513 | 513 | ||
514 | gameport_start_polling(sw->gameport); | 514 | gameport_start_polling(sw->gameport); |
515 | return 0; | 515 | return 0; |
@@ -517,7 +517,7 @@ static int sw_open(struct input_dev *dev) | |||
517 | 517 | ||
518 | static void sw_close(struct input_dev *dev) | 518 | static void sw_close(struct input_dev *dev) |
519 | { | 519 | { |
520 | struct sw *sw = dev->private; | 520 | struct sw *sw = input_get_drvdata(dev); |
521 | 521 | ||
522 | gameport_stop_polling(sw->gameport); | 522 | gameport_stop_polling(sw->gameport); |
523 | } | 523 | } |
@@ -751,8 +751,9 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) | |||
751 | input_dev->id.vendor = GAMEPORT_ID_VENDOR_MICROSOFT; | 751 | input_dev->id.vendor = GAMEPORT_ID_VENDOR_MICROSOFT; |
752 | input_dev->id.product = sw->type; | 752 | input_dev->id.product = sw->type; |
753 | input_dev->id.version = 0x0100; | 753 | input_dev->id.version = 0x0100; |
754 | input_dev->cdev.dev = &gameport->dev; | 754 | input_dev->dev.parent = &gameport->dev; |
755 | input_dev->private = sw; | 755 | |
756 | input_set_drvdata(input_dev, sw); | ||
756 | 757 | ||
757 | input_dev->open = sw_open; | 758 | input_dev->open = sw_open; |
758 | input_dev->close = sw_close; | 759 | input_dev->close = sw_close; |
diff --git a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c index 08bf113e62eb..abb7c4cf54ad 100644 --- a/drivers/input/joystick/spaceball.c +++ b/drivers/input/joystick/spaceball.c | |||
@@ -226,8 +226,7 @@ static int spaceball_connect(struct serio *serio, struct serio_driver *drv) | |||
226 | input_dev->id.vendor = SERIO_SPACEBALL; | 226 | input_dev->id.vendor = SERIO_SPACEBALL; |
227 | input_dev->id.product = id; | 227 | input_dev->id.product = id; |
228 | input_dev->id.version = 0x0100; | 228 | input_dev->id.version = 0x0100; |
229 | input_dev->cdev.dev = &serio->dev; | 229 | input_dev->dev.parent = &serio->dev; |
230 | input_dev->private = spaceball; | ||
231 | 230 | ||
232 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | 231 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); |
233 | 232 | ||
diff --git a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c index c9c79211af71..c4937f1e837c 100644 --- a/drivers/input/joystick/spaceorb.c +++ b/drivers/input/joystick/spaceorb.c | |||
@@ -183,8 +183,7 @@ static int spaceorb_connect(struct serio *serio, struct serio_driver *drv) | |||
183 | input_dev->id.vendor = SERIO_SPACEORB; | 183 | input_dev->id.vendor = SERIO_SPACEORB; |
184 | input_dev->id.product = 0x0001; | 184 | input_dev->id.product = 0x0001; |
185 | input_dev->id.version = 0x0100; | 185 | input_dev->id.version = 0x0100; |
186 | input_dev->cdev.dev = &serio->dev; | 186 | input_dev->dev.parent = &serio->dev; |
187 | input_dev->private = spaceorb; | ||
188 | 187 | ||
189 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | 188 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); |
190 | 189 | ||
diff --git a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c index ecb0916215fa..8581ee991d4e 100644 --- a/drivers/input/joystick/stinger.c +++ b/drivers/input/joystick/stinger.c | |||
@@ -154,8 +154,7 @@ static int stinger_connect(struct serio *serio, struct serio_driver *drv) | |||
154 | input_dev->id.vendor = SERIO_STINGER; | 154 | input_dev->id.vendor = SERIO_STINGER; |
155 | input_dev->id.product = 0x0001; | 155 | input_dev->id.product = 0x0001; |
156 | input_dev->id.version = 0x0100; | 156 | input_dev->id.version = 0x0100; |
157 | input_dev->cdev.dev = &serio->dev; | 157 | input_dev->dev.parent = &serio->dev; |
158 | input_dev->private = stinger; | ||
159 | 158 | ||
160 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | 159 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); |
161 | input_dev->keybit[LONG(BTN_A)] = BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_X) | | 160 | input_dev->keybit[LONG(BTN_A)] = BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_X) | |
diff --git a/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c index bb23ed2a04a6..3b36ee04f726 100644 --- a/drivers/input/joystick/tmdc.c +++ b/drivers/input/joystick/tmdc.c | |||
@@ -265,7 +265,7 @@ static void tmdc_poll(struct gameport *gameport) | |||
265 | 265 | ||
266 | static int tmdc_open(struct input_dev *dev) | 266 | static int tmdc_open(struct input_dev *dev) |
267 | { | 267 | { |
268 | struct tmdc *tmdc = dev->private; | 268 | struct tmdc *tmdc = input_get_drvdata(dev); |
269 | 269 | ||
270 | gameport_start_polling(tmdc->gameport); | 270 | gameport_start_polling(tmdc->gameport); |
271 | return 0; | 271 | return 0; |
@@ -273,7 +273,7 @@ static int tmdc_open(struct input_dev *dev) | |||
273 | 273 | ||
274 | static void tmdc_close(struct input_dev *dev) | 274 | static void tmdc_close(struct input_dev *dev) |
275 | { | 275 | { |
276 | struct tmdc *tmdc = dev->private; | 276 | struct tmdc *tmdc = input_get_drvdata(dev); |
277 | 277 | ||
278 | gameport_stop_polling(tmdc->gameport); | 278 | gameport_stop_polling(tmdc->gameport); |
279 | } | 279 | } |
@@ -326,8 +326,9 @@ static int tmdc_setup_port(struct tmdc *tmdc, int idx, unsigned char *data) | |||
326 | input_dev->id.vendor = GAMEPORT_ID_VENDOR_THRUSTMASTER; | 326 | input_dev->id.vendor = GAMEPORT_ID_VENDOR_THRUSTMASTER; |
327 | input_dev->id.product = model->id; | 327 | input_dev->id.product = model->id; |
328 | input_dev->id.version = 0x0100; | 328 | input_dev->id.version = 0x0100; |
329 | input_dev->cdev.dev = &tmdc->gameport->dev; | 329 | input_dev->dev.parent = &tmdc->gameport->dev; |
330 | input_dev->private = tmdc; | 330 | |
331 | input_set_drvdata(input_dev, tmdc); | ||
331 | 332 | ||
332 | input_dev->open = tmdc_open; | 333 | input_dev->open = tmdc_open; |
333 | input_dev->close = tmdc_close; | 334 | input_dev->close = tmdc_close; |
diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c index 037d3487fcc7..0f2c60823b0b 100644 --- a/drivers/input/joystick/turbografx.c +++ b/drivers/input/joystick/turbografx.c | |||
@@ -122,7 +122,7 @@ static void tgfx_timer(unsigned long private) | |||
122 | 122 | ||
123 | static int tgfx_open(struct input_dev *dev) | 123 | static int tgfx_open(struct input_dev *dev) |
124 | { | 124 | { |
125 | struct tgfx *tgfx = dev->private; | 125 | struct tgfx *tgfx = input_get_drvdata(dev); |
126 | int err; | 126 | int err; |
127 | 127 | ||
128 | err = mutex_lock_interruptible(&tgfx->sem); | 128 | err = mutex_lock_interruptible(&tgfx->sem); |
@@ -141,7 +141,7 @@ static int tgfx_open(struct input_dev *dev) | |||
141 | 141 | ||
142 | static void tgfx_close(struct input_dev *dev) | 142 | static void tgfx_close(struct input_dev *dev) |
143 | { | 143 | { |
144 | struct tgfx *tgfx = dev->private; | 144 | struct tgfx *tgfx = input_get_drvdata(dev); |
145 | 145 | ||
146 | mutex_lock(&tgfx->sem); | 146 | mutex_lock(&tgfx->sem); |
147 | if (!--tgfx->used) { | 147 | if (!--tgfx->used) { |
@@ -224,7 +224,8 @@ static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs) | |||
224 | input_dev->id.product = n_buttons[i]; | 224 | input_dev->id.product = n_buttons[i]; |
225 | input_dev->id.version = 0x0100; | 225 | input_dev->id.version = 0x0100; |
226 | 226 | ||
227 | input_dev->private = tgfx; | 227 | input_set_drvdata(input_dev, tgfx); |
228 | |||
228 | input_dev->open = tgfx_open; | 229 | input_dev->open = tgfx_open; |
229 | input_dev->close = tgfx_close; | 230 | input_dev->close = tgfx_close; |
230 | 231 | ||
diff --git a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c index 9cf17d6ced82..c91504ec38eb 100644 --- a/drivers/input/joystick/twidjoy.c +++ b/drivers/input/joystick/twidjoy.c | |||
@@ -205,11 +205,9 @@ static int twidjoy_connect(struct serio *serio, struct serio_driver *drv) | |||
205 | input_dev->id.vendor = SERIO_TWIDJOY; | 205 | input_dev->id.vendor = SERIO_TWIDJOY; |
206 | input_dev->id.product = 0x0001; | 206 | input_dev->id.product = 0x0001; |
207 | input_dev->id.version = 0x0100; | 207 | input_dev->id.version = 0x0100; |
208 | input_dev->cdev.dev = &serio->dev; | 208 | input_dev->dev.parent = &serio->dev; |
209 | input_dev->private = twidjoy; | ||
210 | 209 | ||
211 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | 210 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); |
212 | input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y); | ||
213 | input_set_abs_params(input_dev, ABS_X, -50, 50, 4, 4); | 211 | input_set_abs_params(input_dev, ABS_X, -50, 50, 4, 4); |
214 | input_set_abs_params(input_dev, ABS_Y, -50, 50, 4, 4); | 212 | input_set_abs_params(input_dev, ABS_Y, -50, 50, 4, 4); |
215 | 213 | ||
diff --git a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c index 29d339acf430..4e85f72eefd7 100644 --- a/drivers/input/joystick/warrior.c +++ b/drivers/input/joystick/warrior.c | |||
@@ -160,8 +160,7 @@ static int warrior_connect(struct serio *serio, struct serio_driver *drv) | |||
160 | input_dev->id.vendor = SERIO_WARRIOR; | 160 | input_dev->id.vendor = SERIO_WARRIOR; |
161 | input_dev->id.product = 0x0001; | 161 | input_dev->id.product = 0x0001; |
162 | input_dev->id.version = 0x0100; | 162 | input_dev->id.version = 0x0100; |
163 | input_dev->cdev.dev = &serio->dev; | 163 | input_dev->dev.parent = &serio->dev; |
164 | input_dev->private = warrior; | ||
165 | 164 | ||
166 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS); | 165 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS); |
167 | input_dev->keybit[LONG(BTN_TRIGGER)] = BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) | BIT(BTN_TOP2); | 166 | input_dev->keybit[LONG(BTN_TRIGGER)] = BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) | BIT(BTN_TOP2); |
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index f17e9c7d4b36..9f42e4d3649e 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -164,6 +164,17 @@ config KEYBOARD_AMIGA | |||
164 | To compile this driver as a module, choose M here: the | 164 | To compile this driver as a module, choose M here: the |
165 | module will be called amikbd. | 165 | module will be called amikbd. |
166 | 166 | ||
167 | config KEYBOARD_ATARI | ||
168 | tristate "Atari keyboard" | ||
169 | depends on ATARI | ||
170 | select ATARI_KBD_CORE | ||
171 | help | ||
172 | Say Y here if you are running Linux on any Atari and have a keyboard | ||
173 | attached. | ||
174 | |||
175 | To compile this driver as a module, choose M here: the | ||
176 | module will be called atakbd. | ||
177 | |||
167 | config KEYBOARD_HIL_OLD | 178 | config KEYBOARD_HIL_OLD |
168 | tristate "HP HIL keyboard support (simple driver)" | 179 | tristate "HP HIL keyboard support (simple driver)" |
169 | depends on GSC || HP300 | 180 | depends on GSC || HP300 |
@@ -203,6 +214,15 @@ config KEYBOARD_OMAP | |||
203 | To compile this driver as a module, choose M here: the | 214 | To compile this driver as a module, choose M here: the |
204 | module will be called omap-keypad. | 215 | module will be called omap-keypad. |
205 | 216 | ||
217 | config KEYBOARD_PXA27x | ||
218 | tristate "PXA27x keyboard support" | ||
219 | depends on PXA27x | ||
220 | help | ||
221 | Enable support for PXA27x matrix keyboard controller | ||
222 | |||
223 | To compile this driver as a module, choose M here: the | ||
224 | module will be called pxa27x_keyboard. | ||
225 | |||
206 | config KEYBOARD_AAED2000 | 226 | config KEYBOARD_AAED2000 |
207 | tristate "AAED-2000 keyboard" | 227 | tristate "AAED-2000 keyboard" |
208 | depends on MACH_AAED2000 | 228 | depends on MACH_AAED2000 |
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 586a0fe53be6..28d211b87b14 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
@@ -9,6 +9,7 @@ obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o | |||
9 | obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o | 9 | obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o |
10 | obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o | 10 | obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o |
11 | obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o | 11 | obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o |
12 | obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o | ||
12 | obj-$(CONFIG_KEYBOARD_LOCOMO) += locomokbd.o | 13 | obj-$(CONFIG_KEYBOARD_LOCOMO) += locomokbd.o |
13 | obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o | 14 | obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o |
14 | obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o | 15 | obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o |
@@ -17,6 +18,7 @@ obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o | |||
17 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o | 18 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o |
18 | obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o | 19 | obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o |
19 | obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o | 20 | obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o |
21 | obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keyboard.o | ||
20 | obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o | 22 | obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o |
21 | obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o | 23 | obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o |
22 | 24 | ||
diff --git a/drivers/input/keyboard/aaed2000_kbd.c b/drivers/input/keyboard/aaed2000_kbd.c index 65fcb6af63a8..3a37505f067c 100644 --- a/drivers/input/keyboard/aaed2000_kbd.c +++ b/drivers/input/keyboard/aaed2000_kbd.c | |||
@@ -97,7 +97,7 @@ static void aaedkbd_work(void *data) | |||
97 | 97 | ||
98 | static int aaedkbd_open(struct input_dev *indev) | 98 | static int aaedkbd_open(struct input_dev *indev) |
99 | { | 99 | { |
100 | struct aaedkbd *aaedkbd = indev->private; | 100 | struct aaedkbd *aaedkbd = input_get_drvdata(indev); |
101 | 101 | ||
102 | schedule_delayed_work(&aaedkbd->workq, msecs_to_jiffies(SCAN_INTERVAL)); | 102 | schedule_delayed_work(&aaedkbd->workq, msecs_to_jiffies(SCAN_INTERVAL)); |
103 | 103 | ||
@@ -106,7 +106,7 @@ static int aaedkbd_open(struct input_dev *indev) | |||
106 | 106 | ||
107 | static void aaedkbd_close(struct input_dev *indev) | 107 | static void aaedkbd_close(struct input_dev *indev) |
108 | { | 108 | { |
109 | struct aaedkbd *aaedkbd = indev->private; | 109 | struct aaedkbd *aaedkbd = input_get_drvdata(indev); |
110 | 110 | ||
111 | cancel_delayed_work(&aaedkbd->workq); | 111 | cancel_delayed_work(&aaedkbd->workq); |
112 | flush_scheduled_work(); | 112 | flush_scheduled_work(); |
@@ -141,8 +141,9 @@ static int __devinit aaedkbd_probe(struct platform_device *pdev) | |||
141 | input_dev->id.vendor = 0x0001; | 141 | input_dev->id.vendor = 0x0001; |
142 | input_dev->id.product = 0x0001; | 142 | input_dev->id.product = 0x0001; |
143 | input_dev->id.version = 0x0100; | 143 | input_dev->id.version = 0x0100; |
144 | input_dev->cdev.dev = &pdev->dev; | 144 | input_dev->dev.parent = &pdev->dev; |
145 | input_dev->private = aaedkbd; | 145 | |
146 | input_set_drvdata(input_dev, aaedkbd); | ||
146 | 147 | ||
147 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); | 148 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); |
148 | input_dev->keycode = aaedkbd->keycode; | 149 | input_dev->keycode = aaedkbd->keycode; |
diff --git a/drivers/input/keyboard/atakbd.c b/drivers/input/keyboard/atakbd.c new file mode 100644 index 000000000000..ded1d6ac6ff3 --- /dev/null +++ b/drivers/input/keyboard/atakbd.c | |||
@@ -0,0 +1,134 @@ | |||
1 | /* | ||
2 | * atakbd.c | ||
3 | * | ||
4 | * Copyright (c) 2005 Michael Schmitz | ||
5 | * | ||
6 | * Based on amikbd.c, which is | ||
7 | * | ||
8 | * Copyright (c) 2000-2001 Vojtech Pavlik | ||
9 | * | ||
10 | * Based on the work of: | ||
11 | * Hamish Macdonald | ||
12 | */ | ||
13 | |||
14 | /* | ||
15 | * Atari keyboard driver for Linux/m68k | ||
16 | * | ||
17 | * The low level init and interrupt stuff is handled in arch/mm68k/atari/atakeyb.c | ||
18 | * (the keyboard ACIA also handles the mouse and joystick data, and the keyboard | ||
19 | * interrupt is shared with the MIDI ACIA so MIDI data also get handled there). | ||
20 | * This driver only deals with handing key events off to the input layer. | ||
21 | */ | ||
22 | |||
23 | /* | ||
24 | * This program is free software; you can redistribute it and/or modify | ||
25 | * it under the terms of the GNU General Public License as published by | ||
26 | * the Free Software Foundation; either version 2 of the License, or | ||
27 | * (at your option) any later version. | ||
28 | * | ||
29 | * This program is distributed in the hope that it will be useful, | ||
30 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
31 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
32 | * GNU General Public License for more details. | ||
33 | * | ||
34 | * You should have received a copy of the GNU General Public License | ||
35 | * along with this program; if not, write to the Free Software | ||
36 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
37 | * | ||
38 | * Should you need to contact me, the author, you can do so either by | ||
39 | * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: | ||
40 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic | ||
41 | */ | ||
42 | |||
43 | #include <linux/module.h> | ||
44 | #include <linux/init.h> | ||
45 | #include <linux/input.h> | ||
46 | #include <linux/delay.h> | ||
47 | #include <linux/interrupt.h> | ||
48 | |||
49 | #include <asm/atariints.h> | ||
50 | #include <asm/atarihw.h> | ||
51 | #include <asm/atarikb.h> | ||
52 | #include <asm/irq.h> | ||
53 | |||
54 | MODULE_AUTHOR("Michael Schmitz <schmitz@biophys.uni-duesseldorf.de>"); | ||
55 | MODULE_DESCRIPTION("Atari keyboard driver"); | ||
56 | MODULE_LICENSE("GPL"); | ||
57 | |||
58 | static unsigned char atakbd_keycode[0x72]; | ||
59 | |||
60 | static struct input_dev *atakbd_dev; | ||
61 | |||
62 | static void atakbd_interrupt(unsigned char scancode, char down) | ||
63 | { | ||
64 | |||
65 | if (scancode < 0x72) { /* scancodes < 0xf2 are keys */ | ||
66 | |||
67 | // report raw events here? | ||
68 | |||
69 | scancode = atakbd_keycode[scancode]; | ||
70 | |||
71 | if (scancode == KEY_CAPSLOCK) { /* CapsLock is a toggle switch key on Amiga */ | ||
72 | input_report_key(atakbd_dev, scancode, 1); | ||
73 | input_report_key(atakbd_dev, scancode, 0); | ||
74 | input_sync(atakbd_dev); | ||
75 | } else { | ||
76 | input_report_key(atakbd_dev, scancode, down); | ||
77 | input_sync(atakbd_dev); | ||
78 | } | ||
79 | } else /* scancodes >= 0xf2 are mouse data, most likely */ | ||
80 | printk(KERN_INFO "atakbd: unhandled scancode %x\n", scancode); | ||
81 | |||
82 | return; | ||
83 | } | ||
84 | |||
85 | static int __init atakbd_init(void) | ||
86 | { | ||
87 | int i; | ||
88 | |||
89 | if (!ATARIHW_PRESENT(ST_MFP)) | ||
90 | return -EIO; | ||
91 | |||
92 | // TODO: request_mem_region if not done in arch code | ||
93 | |||
94 | if (!(atakbd_dev = input_allocate_device())) | ||
95 | return -ENOMEM; | ||
96 | |||
97 | // need to init core driver if not already done so | ||
98 | if (atari_keyb_init()) | ||
99 | return -ENODEV; | ||
100 | |||
101 | atakbd_dev->name = "Atari Keyboard"; | ||
102 | atakbd_dev->phys = "atakbd/input0"; | ||
103 | atakbd_dev->id.bustype = BUS_ATARI; | ||
104 | atakbd_dev->id.vendor = 0x0001; | ||
105 | atakbd_dev->id.product = 0x0001; | ||
106 | atakbd_dev->id.version = 0x0100; | ||
107 | |||
108 | atakbd_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); | ||
109 | atakbd_dev->keycode = atakbd_keycode; | ||
110 | atakbd_dev->keycodesize = sizeof(unsigned char); | ||
111 | atakbd_dev->keycodemax = ARRAY_SIZE(atakbd_keycode); | ||
112 | |||
113 | for (i = 1; i < 0x72; i++) { | ||
114 | atakbd_keycode[i] = i; | ||
115 | set_bit(atakbd_keycode[i], atakbd_dev->keybit); | ||
116 | } | ||
117 | |||
118 | input_register_device(atakbd_dev); | ||
119 | |||
120 | atari_input_keyboard_interrupt_hook = atakbd_interrupt; | ||
121 | |||
122 | printk(KERN_INFO "input: %s at IKBD ACIA\n", atakbd_dev->name); | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | static void __exit atakbd_exit(void) | ||
128 | { | ||
129 | atari_input_keyboard_interrupt_hook = NULL; | ||
130 | input_unregister_device(atakbd_dev); | ||
131 | } | ||
132 | |||
133 | module_init(atakbd_init); | ||
134 | module_exit(atakbd_exit); | ||
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 663877076bc7..be1fe46cd308 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -586,7 +586,7 @@ static void atkbd_event_work(struct work_struct *work) | |||
586 | 586 | ||
587 | static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 587 | static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) |
588 | { | 588 | { |
589 | struct atkbd *atkbd = dev->private; | 589 | struct atkbd *atkbd = input_get_drvdata(dev); |
590 | 590 | ||
591 | if (!atkbd->write) | 591 | if (!atkbd->write) |
592 | return -1; | 592 | return -1; |
@@ -883,8 +883,9 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd) | |||
883 | input_dev->id.product = atkbd->translated ? 1 : atkbd->set; | 883 | input_dev->id.product = atkbd->translated ? 1 : atkbd->set; |
884 | input_dev->id.version = atkbd->id; | 884 | input_dev->id.version = atkbd->id; |
885 | input_dev->event = atkbd_event; | 885 | input_dev->event = atkbd_event; |
886 | input_dev->private = atkbd; | 886 | input_dev->dev.parent = &atkbd->ps2dev.serio->dev; |
887 | input_dev->cdev.dev = &atkbd->ps2dev.serio->dev; | 887 | |
888 | input_set_drvdata(input_dev, atkbd); | ||
888 | 889 | ||
889 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC); | 890 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC); |
890 | 891 | ||
diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c index 1016c94e65db..6578bfff644b 100644 --- a/drivers/input/keyboard/corgikbd.c +++ b/drivers/input/keyboard/corgikbd.c | |||
@@ -323,8 +323,7 @@ static int __init corgikbd_probe(struct platform_device *pdev) | |||
323 | input_dev->id.vendor = 0x0001; | 323 | input_dev->id.vendor = 0x0001; |
324 | input_dev->id.product = 0x0001; | 324 | input_dev->id.product = 0x0001; |
325 | input_dev->id.version = 0x0100; | 325 | input_dev->id.version = 0x0100; |
326 | input_dev->cdev.dev = &pdev->dev; | 326 | input_dev->dev.parent = &pdev->dev; |
327 | input_dev->private = corgikbd; | ||
328 | 327 | ||
329 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW); | 328 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW); |
330 | input_dev->keycode = corgikbd->keycode; | 329 | input_dev->keycode = corgikbd->keycode; |
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index ccf6df387b62..739212252b09 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c | |||
@@ -35,11 +35,14 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id) | |||
35 | struct input_dev *input = platform_get_drvdata(pdev); | 35 | struct input_dev *input = platform_get_drvdata(pdev); |
36 | 36 | ||
37 | for (i = 0; i < pdata->nbuttons; i++) { | 37 | for (i = 0; i < pdata->nbuttons; i++) { |
38 | int gpio = pdata->buttons[i].gpio; | 38 | struct gpio_keys_button *button = &pdata->buttons[i]; |
39 | int gpio = button->gpio; | ||
40 | |||
39 | if (irq == gpio_to_irq(gpio)) { | 41 | if (irq == gpio_to_irq(gpio)) { |
40 | int state = (gpio_get_value(gpio) ? 1 : 0) ^ (pdata->buttons[i].active_low); | 42 | unsigned int type = button->type ?: EV_KEY; |
43 | int state = (gpio_get_value(gpio) ? 1 : 0) ^ button->active_low; | ||
41 | 44 | ||
42 | input_report_key(input, pdata->buttons[i].keycode, state); | 45 | input_event(input, type, button->code, !!state); |
43 | input_sync(input); | 46 | input_sync(input); |
44 | } | 47 | } |
45 | } | 48 | } |
@@ -63,8 +66,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
63 | 66 | ||
64 | input->name = pdev->name; | 67 | input->name = pdev->name; |
65 | input->phys = "gpio-keys/input0"; | 68 | input->phys = "gpio-keys/input0"; |
66 | input->cdev.dev = &pdev->dev; | 69 | input->dev.parent = &pdev->dev; |
67 | input->private = pdata; | ||
68 | 70 | ||
69 | input->id.bustype = BUS_HOST; | 71 | input->id.bustype = BUS_HOST; |
70 | input->id.vendor = 0x0001; | 72 | input->id.vendor = 0x0001; |
@@ -72,19 +74,21 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
72 | input->id.version = 0x0100; | 74 | input->id.version = 0x0100; |
73 | 75 | ||
74 | for (i = 0; i < pdata->nbuttons; i++) { | 76 | for (i = 0; i < pdata->nbuttons; i++) { |
75 | int code = pdata->buttons[i].keycode; | 77 | struct gpio_keys_button *button = &pdata->buttons[i]; |
76 | int irq = gpio_to_irq(pdata->buttons[i].gpio); | 78 | int irq = gpio_to_irq(button->gpio); |
79 | unsigned int type = button->type ?: EV_KEY; | ||
77 | 80 | ||
78 | set_irq_type(irq, IRQ_TYPE_EDGE_BOTH); | 81 | set_irq_type(irq, IRQ_TYPE_EDGE_BOTH); |
79 | error = request_irq(irq, gpio_keys_isr, IRQF_SAMPLE_RANDOM, | 82 | error = request_irq(irq, gpio_keys_isr, IRQF_SAMPLE_RANDOM, |
80 | pdata->buttons[i].desc ? pdata->buttons[i].desc : "gpio_keys", | 83 | button->desc ? button->desc : "gpio_keys", |
81 | pdev); | 84 | pdev); |
82 | if (error) { | 85 | if (error) { |
83 | printk(KERN_ERR "gpio-keys: unable to claim irq %d; error %d\n", | 86 | printk(KERN_ERR "gpio-keys: unable to claim irq %d; error %d\n", |
84 | irq, error); | 87 | irq, error); |
85 | goto fail; | 88 | goto fail; |
86 | } | 89 | } |
87 | set_bit(code, input->keybit); | 90 | |
91 | input_set_capability(input, type, button->code); | ||
88 | } | 92 | } |
89 | 93 | ||
90 | error = input_register_device(input); | 94 | error = input_register_device(input); |
diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index 7cc9728b04df..cdd254f2e6c7 100644 --- a/drivers/input/keyboard/hil_kbd.c +++ b/drivers/input/keyboard/hil_kbd.c | |||
@@ -51,7 +51,7 @@ MODULE_LICENSE("Dual BSD/GPL"); | |||
51 | 51 | ||
52 | #define HIL_KBD_SET1_UPBIT 0x01 | 52 | #define HIL_KBD_SET1_UPBIT 0x01 |
53 | #define HIL_KBD_SET1_SHIFT 1 | 53 | #define HIL_KBD_SET1_SHIFT 1 |
54 | static unsigned int hil_kbd_set1[HIL_KEYCODES_SET1_TBLSIZE] = | 54 | static unsigned int hil_kbd_set1[HIL_KEYCODES_SET1_TBLSIZE] __read_mostly = |
55 | { HIL_KEYCODES_SET1 }; | 55 | { HIL_KEYCODES_SET1 }; |
56 | 56 | ||
57 | #define HIL_KBD_SET2_UPBIT 0x01 | 57 | #define HIL_KBD_SET2_UPBIT 0x01 |
@@ -60,10 +60,10 @@ static unsigned int hil_kbd_set1[HIL_KEYCODES_SET1_TBLSIZE] = | |||
60 | 60 | ||
61 | #define HIL_KBD_SET3_UPBIT 0x80 | 61 | #define HIL_KBD_SET3_UPBIT 0x80 |
62 | #define HIL_KBD_SET3_SHIFT 0 | 62 | #define HIL_KBD_SET3_SHIFT 0 |
63 | static unsigned int hil_kbd_set3[HIL_KEYCODES_SET3_TBLSIZE] = | 63 | static unsigned int hil_kbd_set3[HIL_KEYCODES_SET3_TBLSIZE] __read_mostly = |
64 | { HIL_KEYCODES_SET3 }; | 64 | { HIL_KEYCODES_SET3 }; |
65 | 65 | ||
66 | static char hil_language[][16] = { HIL_LOCALE_MAP }; | 66 | static const char hil_language[][16] = { HIL_LOCALE_MAP }; |
67 | 67 | ||
68 | struct hil_kbd { | 68 | struct hil_kbd { |
69 | struct input_dev *dev; | 69 | struct input_dev *dev; |
@@ -94,10 +94,12 @@ static void hil_kbd_process_record(struct hil_kbd *kbd) | |||
94 | idx = kbd->idx4/4; | 94 | idx = kbd->idx4/4; |
95 | p = data[idx - 1]; | 95 | p = data[idx - 1]; |
96 | 96 | ||
97 | if ((p & ~HIL_CMDCT_POL) == | 97 | if ((p & ~HIL_CMDCT_POL) == |
98 | (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) goto report; | 98 | (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) |
99 | if ((p & ~HIL_CMDCT_RPL) == | 99 | goto report; |
100 | (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL)) goto report; | 100 | if ((p & ~HIL_CMDCT_RPL) == |
101 | (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL)) | ||
102 | goto report; | ||
101 | 103 | ||
102 | /* Not a poll response. See if we are loading config records. */ | 104 | /* Not a poll response. See if we are loading config records. */ |
103 | switch (p & HIL_PKT_DATA_MASK) { | 105 | switch (p & HIL_PKT_DATA_MASK) { |
@@ -107,27 +109,32 @@ static void hil_kbd_process_record(struct hil_kbd *kbd) | |||
107 | for (; i < HIL_KBD_MAX_LENGTH; i++) | 109 | for (; i < HIL_KBD_MAX_LENGTH; i++) |
108 | kbd->idd[i] = 0; | 110 | kbd->idd[i] = 0; |
109 | break; | 111 | break; |
112 | |||
110 | case HIL_CMD_RSC: | 113 | case HIL_CMD_RSC: |
111 | for (i = 0; i < idx; i++) | 114 | for (i = 0; i < idx; i++) |
112 | kbd->rsc[i] = kbd->data[i] & HIL_PKT_DATA_MASK; | 115 | kbd->rsc[i] = kbd->data[i] & HIL_PKT_DATA_MASK; |
113 | for (; i < HIL_KBD_MAX_LENGTH; i++) | 116 | for (; i < HIL_KBD_MAX_LENGTH; i++) |
114 | kbd->rsc[i] = 0; | 117 | kbd->rsc[i] = 0; |
115 | break; | 118 | break; |
119 | |||
116 | case HIL_CMD_EXD: | 120 | case HIL_CMD_EXD: |
117 | for (i = 0; i < idx; i++) | 121 | for (i = 0; i < idx; i++) |
118 | kbd->exd[i] = kbd->data[i] & HIL_PKT_DATA_MASK; | 122 | kbd->exd[i] = kbd->data[i] & HIL_PKT_DATA_MASK; |
119 | for (; i < HIL_KBD_MAX_LENGTH; i++) | 123 | for (; i < HIL_KBD_MAX_LENGTH; i++) |
120 | kbd->exd[i] = 0; | 124 | kbd->exd[i] = 0; |
121 | break; | 125 | break; |
126 | |||
122 | case HIL_CMD_RNM: | 127 | case HIL_CMD_RNM: |
123 | for (i = 0; i < idx; i++) | 128 | for (i = 0; i < idx; i++) |
124 | kbd->rnm[i] = kbd->data[i] & HIL_PKT_DATA_MASK; | 129 | kbd->rnm[i] = kbd->data[i] & HIL_PKT_DATA_MASK; |
125 | for (; i < HIL_KBD_MAX_LENGTH + 1; i++) | 130 | for (; i < HIL_KBD_MAX_LENGTH + 1; i++) |
126 | kbd->rnm[i] = '\0'; | 131 | kbd->rnm[i] = '\0'; |
127 | break; | 132 | break; |
133 | |||
128 | default: | 134 | default: |
129 | /* These occur when device isn't present */ | 135 | /* These occur when device isn't present */ |
130 | if (p == (HIL_ERR_INT | HIL_PKT_CMD)) break; | 136 | if (p == (HIL_ERR_INT | HIL_PKT_CMD)) |
137 | break; | ||
131 | /* Anything else we'd like to know about. */ | 138 | /* Anything else we'd like to know about. */ |
132 | printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p); | 139 | printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p); |
133 | break; | 140 | break; |
@@ -139,16 +146,19 @@ static void hil_kbd_process_record(struct hil_kbd *kbd) | |||
139 | switch (kbd->data[0] & HIL_POL_CHARTYPE_MASK) { | 146 | switch (kbd->data[0] & HIL_POL_CHARTYPE_MASK) { |
140 | case HIL_POL_CHARTYPE_NONE: | 147 | case HIL_POL_CHARTYPE_NONE: |
141 | break; | 148 | break; |
149 | |||
142 | case HIL_POL_CHARTYPE_ASCII: | 150 | case HIL_POL_CHARTYPE_ASCII: |
143 | while (cnt < idx - 1) | 151 | while (cnt < idx - 1) |
144 | input_report_key(dev, kbd->data[cnt++] & 0x7f, 1); | 152 | input_report_key(dev, kbd->data[cnt++] & 0x7f, 1); |
145 | break; | 153 | break; |
154 | |||
146 | case HIL_POL_CHARTYPE_RSVD1: | 155 | case HIL_POL_CHARTYPE_RSVD1: |
147 | case HIL_POL_CHARTYPE_RSVD2: | 156 | case HIL_POL_CHARTYPE_RSVD2: |
148 | case HIL_POL_CHARTYPE_BINARY: | 157 | case HIL_POL_CHARTYPE_BINARY: |
149 | while (cnt < idx - 1) | 158 | while (cnt < idx - 1) |
150 | input_report_key(dev, kbd->data[cnt++], 1); | 159 | input_report_key(dev, kbd->data[cnt++], 1); |
151 | break; | 160 | break; |
161 | |||
152 | case HIL_POL_CHARTYPE_SET1: | 162 | case HIL_POL_CHARTYPE_SET1: |
153 | while (cnt < idx - 1) { | 163 | while (cnt < idx - 1) { |
154 | unsigned int key; | 164 | unsigned int key; |
@@ -161,6 +171,7 @@ static void hil_kbd_process_record(struct hil_kbd *kbd) | |||
161 | input_report_key(dev, key, !up); | 171 | input_report_key(dev, key, !up); |
162 | } | 172 | } |
163 | break; | 173 | break; |
174 | |||
164 | case HIL_POL_CHARTYPE_SET2: | 175 | case HIL_POL_CHARTYPE_SET2: |
165 | while (cnt < idx - 1) { | 176 | while (cnt < idx - 1) { |
166 | unsigned int key; | 177 | unsigned int key; |
@@ -173,6 +184,7 @@ static void hil_kbd_process_record(struct hil_kbd *kbd) | |||
173 | input_report_key(dev, key, !up); | 184 | input_report_key(dev, key, !up); |
174 | } | 185 | } |
175 | break; | 186 | break; |
187 | |||
176 | case HIL_POL_CHARTYPE_SET3: | 188 | case HIL_POL_CHARTYPE_SET3: |
177 | while (cnt < idx - 1) { | 189 | while (cnt < idx - 1) { |
178 | unsigned int key; | 190 | unsigned int key; |
@@ -191,42 +203,43 @@ static void hil_kbd_process_record(struct hil_kbd *kbd) | |||
191 | up(&kbd->sem); | 203 | up(&kbd->sem); |
192 | } | 204 | } |
193 | 205 | ||
194 | static void hil_kbd_process_err(struct hil_kbd *kbd) { | 206 | static void hil_kbd_process_err(struct hil_kbd *kbd) |
207 | { | ||
195 | printk(KERN_WARNING PREFIX "errored HIL packet\n"); | 208 | printk(KERN_WARNING PREFIX "errored HIL packet\n"); |
196 | kbd->idx4 = 0; | 209 | kbd->idx4 = 0; |
197 | up(&kbd->sem); | 210 | up(&kbd->sem); |
198 | } | 211 | } |
199 | 212 | ||
200 | static irqreturn_t hil_kbd_interrupt(struct serio *serio, | 213 | static irqreturn_t hil_kbd_interrupt(struct serio *serio, |
201 | unsigned char data, unsigned int flags) | 214 | unsigned char data, unsigned int flags) |
202 | { | 215 | { |
203 | struct hil_kbd *kbd; | 216 | struct hil_kbd *kbd; |
204 | hil_packet packet; | 217 | hil_packet packet; |
205 | int idx; | 218 | int idx; |
206 | 219 | ||
207 | kbd = serio_get_drvdata(serio); | 220 | kbd = serio_get_drvdata(serio); |
208 | if (kbd == NULL) { | 221 | BUG_ON(kbd == NULL); |
209 | BUG(); | ||
210 | return IRQ_HANDLED; | ||
211 | } | ||
212 | 222 | ||
213 | if (kbd->idx4 >= (HIL_KBD_MAX_LENGTH * sizeof(hil_packet))) { | 223 | if (kbd->idx4 >= (HIL_KBD_MAX_LENGTH * sizeof(hil_packet))) { |
214 | hil_kbd_process_err(kbd); | 224 | hil_kbd_process_err(kbd); |
215 | return IRQ_HANDLED; | 225 | return IRQ_HANDLED; |
216 | } | 226 | } |
217 | idx = kbd->idx4/4; | 227 | idx = kbd->idx4/4; |
218 | if (!(kbd->idx4 % 4)) kbd->data[idx] = 0; | 228 | if (!(kbd->idx4 % 4)) |
229 | kbd->data[idx] = 0; | ||
219 | packet = kbd->data[idx]; | 230 | packet = kbd->data[idx]; |
220 | packet |= ((hil_packet)data) << ((3 - (kbd->idx4 % 4)) * 8); | 231 | packet |= ((hil_packet)data) << ((3 - (kbd->idx4 % 4)) * 8); |
221 | kbd->data[idx] = packet; | 232 | kbd->data[idx] = packet; |
222 | 233 | ||
223 | /* Records of N 4-byte hil_packets must terminate with a command. */ | 234 | /* Records of N 4-byte hil_packets must terminate with a command. */ |
224 | if ((++(kbd->idx4)) % 4) return IRQ_HANDLED; | 235 | if ((++(kbd->idx4)) % 4) |
236 | return IRQ_HANDLED; | ||
225 | if ((packet & 0xffff0000) != HIL_ERR_INT) { | 237 | if ((packet & 0xffff0000) != HIL_ERR_INT) { |
226 | hil_kbd_process_err(kbd); | 238 | hil_kbd_process_err(kbd); |
227 | return IRQ_HANDLED; | 239 | return IRQ_HANDLED; |
228 | } | 240 | } |
229 | if (packet & HIL_PKT_CMD) hil_kbd_process_record(kbd); | 241 | if (packet & HIL_PKT_CMD) |
242 | hil_kbd_process_record(kbd); | ||
230 | return IRQ_HANDLED; | 243 | return IRQ_HANDLED; |
231 | } | 244 | } |
232 | 245 | ||
@@ -235,10 +248,7 @@ static void hil_kbd_disconnect(struct serio *serio) | |||
235 | struct hil_kbd *kbd; | 248 | struct hil_kbd *kbd; |
236 | 249 | ||
237 | kbd = serio_get_drvdata(serio); | 250 | kbd = serio_get_drvdata(serio); |
238 | if (kbd == NULL) { | 251 | BUG_ON(kbd == NULL); |
239 | BUG(); | ||
240 | return; | ||
241 | } | ||
242 | 252 | ||
243 | serio_close(serio); | 253 | serio_close(serio); |
244 | input_unregister_device(kbd->dev); | 254 | input_unregister_device(kbd->dev); |
@@ -259,42 +269,40 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) | |||
259 | if (!kbd->dev) | 269 | if (!kbd->dev) |
260 | goto bail0; | 270 | goto bail0; |
261 | 271 | ||
262 | kbd->dev->private = kbd; | ||
263 | |||
264 | if (serio_open(serio, drv)) | 272 | if (serio_open(serio, drv)) |
265 | goto bail1; | 273 | goto bail1; |
266 | 274 | ||
267 | serio_set_drvdata(serio, kbd); | 275 | serio_set_drvdata(serio, kbd); |
268 | kbd->serio = serio; | 276 | kbd->serio = serio; |
269 | 277 | ||
270 | init_MUTEX_LOCKED(&(kbd->sem)); | 278 | init_MUTEX_LOCKED(&kbd->sem); |
271 | 279 | ||
272 | /* Get device info. MLC driver supplies devid/status/etc. */ | 280 | /* Get device info. MLC driver supplies devid/status/etc. */ |
273 | serio->write(serio, 0); | 281 | serio->write(serio, 0); |
274 | serio->write(serio, 0); | 282 | serio->write(serio, 0); |
275 | serio->write(serio, HIL_PKT_CMD >> 8); | 283 | serio->write(serio, HIL_PKT_CMD >> 8); |
276 | serio->write(serio, HIL_CMD_IDD); | 284 | serio->write(serio, HIL_CMD_IDD); |
277 | down(&(kbd->sem)); | 285 | down(&kbd->sem); |
278 | 286 | ||
279 | serio->write(serio, 0); | 287 | serio->write(serio, 0); |
280 | serio->write(serio, 0); | 288 | serio->write(serio, 0); |
281 | serio->write(serio, HIL_PKT_CMD >> 8); | 289 | serio->write(serio, HIL_PKT_CMD >> 8); |
282 | serio->write(serio, HIL_CMD_RSC); | 290 | serio->write(serio, HIL_CMD_RSC); |
283 | down(&(kbd->sem)); | 291 | down(&kbd->sem); |
284 | 292 | ||
285 | serio->write(serio, 0); | 293 | serio->write(serio, 0); |
286 | serio->write(serio, 0); | 294 | serio->write(serio, 0); |
287 | serio->write(serio, HIL_PKT_CMD >> 8); | 295 | serio->write(serio, HIL_PKT_CMD >> 8); |
288 | serio->write(serio, HIL_CMD_RNM); | 296 | serio->write(serio, HIL_CMD_RNM); |
289 | down(&(kbd->sem)); | 297 | down(&kbd->sem); |
290 | 298 | ||
291 | serio->write(serio, 0); | 299 | serio->write(serio, 0); |
292 | serio->write(serio, 0); | 300 | serio->write(serio, 0); |
293 | serio->write(serio, HIL_PKT_CMD >> 8); | 301 | serio->write(serio, HIL_PKT_CMD >> 8); |
294 | serio->write(serio, HIL_CMD_EXD); | 302 | serio->write(serio, HIL_CMD_EXD); |
295 | down(&(kbd->sem)); | 303 | down(&kbd->sem); |
296 | 304 | ||
297 | up(&(kbd->sem)); | 305 | up(&kbd->sem); |
298 | 306 | ||
299 | did = kbd->idd[0]; | 307 | did = kbd->idd[0]; |
300 | idd = kbd->idd + 1; | 308 | idd = kbd->idd + 1; |
@@ -310,12 +318,11 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) | |||
310 | goto bail2; | 318 | goto bail2; |
311 | } | 319 | } |
312 | 320 | ||
313 | if(HIL_IDD_NUM_BUTTONS(idd) || HIL_IDD_NUM_AXES_PER_SET(*idd)) { | 321 | if (HIL_IDD_NUM_BUTTONS(idd) || HIL_IDD_NUM_AXES_PER_SET(*idd)) { |
314 | printk(KERN_INFO PREFIX "keyboards only, no combo devices supported.\n"); | 322 | printk(KERN_INFO PREFIX "keyboards only, no combo devices supported.\n"); |
315 | goto bail2; | 323 | goto bail2; |
316 | } | 324 | } |
317 | 325 | ||
318 | |||
319 | kbd->dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); | 326 | kbd->dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); |
320 | kbd->dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); | 327 | kbd->dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); |
321 | kbd->dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE; | 328 | kbd->dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE; |
@@ -328,7 +335,7 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) | |||
328 | kbd->dev->id.vendor = PCI_VENDOR_ID_HP; | 335 | kbd->dev->id.vendor = PCI_VENDOR_ID_HP; |
329 | kbd->dev->id.product = 0x0001; /* TODO: get from kbd->rsc */ | 336 | kbd->dev->id.product = 0x0001; /* TODO: get from kbd->rsc */ |
330 | kbd->dev->id.version = 0x0100; /* TODO: get from kbd->rsc */ | 337 | kbd->dev->id.version = 0x0100; /* TODO: get from kbd->rsc */ |
331 | kbd->dev->cdev.dev = &serio->dev; | 338 | kbd->dev->dev.parent = &serio->dev; |
332 | 339 | ||
333 | for (i = 0; i < 128; i++) { | 340 | for (i = 0; i < 128; i++) { |
334 | set_bit(hil_kbd_set1[i], kbd->dev->keybit); | 341 | set_bit(hil_kbd_set1[i], kbd->dev->keybit); |
@@ -344,8 +351,8 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) | |||
344 | serio->write(serio, 0); | 351 | serio->write(serio, 0); |
345 | serio->write(serio, HIL_PKT_CMD >> 8); | 352 | serio->write(serio, HIL_PKT_CMD >> 8); |
346 | serio->write(serio, HIL_CMD_EK1); /* Enable Keyswitch Autorepeat 1 */ | 353 | serio->write(serio, HIL_CMD_EK1); /* Enable Keyswitch Autorepeat 1 */ |
347 | down(&(kbd->sem)); | 354 | down(&kbd->sem); |
348 | up(&(kbd->sem)); | 355 | up(&kbd->sem); |
349 | 356 | ||
350 | return 0; | 357 | return 0; |
351 | bail2: | 358 | bail2: |
@@ -368,26 +375,26 @@ static struct serio_device_id hil_kbd_ids[] = { | |||
368 | { 0 } | 375 | { 0 } |
369 | }; | 376 | }; |
370 | 377 | ||
371 | struct serio_driver hil_kbd_serio_drv = { | 378 | static struct serio_driver hil_kbd_serio_drv = { |
372 | .driver = { | 379 | .driver = { |
373 | .name = "hil_kbd", | 380 | .name = "hil_kbd", |
374 | }, | 381 | }, |
375 | .description = "HP HIL keyboard driver", | 382 | .description = "HP HIL keyboard driver", |
376 | .id_table = hil_kbd_ids, | 383 | .id_table = hil_kbd_ids, |
377 | .connect = hil_kbd_connect, | 384 | .connect = hil_kbd_connect, |
378 | .disconnect = hil_kbd_disconnect, | 385 | .disconnect = hil_kbd_disconnect, |
379 | .interrupt = hil_kbd_interrupt | 386 | .interrupt = hil_kbd_interrupt |
380 | }; | 387 | }; |
381 | 388 | ||
382 | static int __init hil_kbd_init(void) | 389 | static int __init hil_kbd_init(void) |
383 | { | 390 | { |
384 | return serio_register_driver(&hil_kbd_serio_drv); | 391 | return serio_register_driver(&hil_kbd_serio_drv); |
385 | } | 392 | } |
386 | 393 | ||
387 | static void __exit hil_kbd_exit(void) | 394 | static void __exit hil_kbd_exit(void) |
388 | { | 395 | { |
389 | serio_unregister_driver(&hil_kbd_serio_drv); | 396 | serio_unregister_driver(&hil_kbd_serio_drv); |
390 | } | 397 | } |
391 | 398 | ||
392 | module_init(hil_kbd_init); | 399 | module_init(hil_kbd_init); |
393 | module_exit(hil_kbd_exit); | 400 | module_exit(hil_kbd_exit); |
diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c index 4de4dc297d50..499b6974457f 100644 --- a/drivers/input/keyboard/hilkbd.c +++ b/drivers/input/keyboard/hilkbd.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 1998 Philip Blundell <philb@gnu.org> | 4 | * Copyright (C) 1998 Philip Blundell <philb@gnu.org> |
5 | * Copyright (C) 1999 Matthew Wilcox <willy@bofh.ai> | 5 | * Copyright (C) 1999 Matthew Wilcox <willy@bofh.ai> |
6 | * Copyright (C) 1999-2006 Helge Deller <deller@gmx.de> | 6 | * Copyright (C) 1999-2007 Helge Deller <deller@gmx.de> |
7 | * | 7 | * |
8 | * Very basic HP Human Interface Loop (HIL) driver. | 8 | * Very basic HP Human Interface Loop (HIL) driver. |
9 | * This driver handles the keyboard on HP300 (m68k) and on some | 9 | * This driver handles the keyboard on HP300 (m68k) and on some |
@@ -52,7 +52,7 @@ MODULE_LICENSE("GPL v2"); | |||
52 | 52 | ||
53 | #elif defined(CONFIG_HP300) | 53 | #elif defined(CONFIG_HP300) |
54 | 54 | ||
55 | #define HILBASE 0xf0428000 /* HP300 (m86k) port address */ | 55 | #define HILBASE 0xf0428000UL /* HP300 (m68k) port address */ |
56 | #define HIL_DATA 0x1 | 56 | #define HIL_DATA 0x1 |
57 | #define HIL_CMD 0x3 | 57 | #define HIL_CMD 0x3 |
58 | #define HIL_IRQ 2 | 58 | #define HIL_IRQ 2 |
@@ -89,7 +89,7 @@ MODULE_LICENSE("GPL v2"); | |||
89 | #define HIL_READKBDSADR 0xF9 | 89 | #define HIL_READKBDSADR 0xF9 |
90 | #define HIL_WRITEKBDSADR 0xE9 | 90 | #define HIL_WRITEKBDSADR 0xE9 |
91 | 91 | ||
92 | static unsigned int hphilkeyb_keycode[HIL_KEYCODES_SET1_TBLSIZE] = | 92 | static unsigned int hphilkeyb_keycode[HIL_KEYCODES_SET1_TBLSIZE] __read_mostly = |
93 | { HIL_KEYCODES_SET1 }; | 93 | { HIL_KEYCODES_SET1 }; |
94 | 94 | ||
95 | /* HIL structure */ | 95 | /* HIL structure */ |
@@ -211,10 +211,10 @@ hil_keyb_init(void) | |||
211 | return -ENODEV; /* already initialized */ | 211 | return -ENODEV; /* already initialized */ |
212 | } | 212 | } |
213 | 213 | ||
214 | spin_lock_init(&hil_dev.lock); | ||
214 | hil_dev.dev = input_allocate_device(); | 215 | hil_dev.dev = input_allocate_device(); |
215 | if (!hil_dev.dev) | 216 | if (!hil_dev.dev) |
216 | return -ENOMEM; | 217 | return -ENOMEM; |
217 | hil_dev.dev->private = &hil_dev; | ||
218 | 218 | ||
219 | #if defined(CONFIG_HP300) | 219 | #if defined(CONFIG_HP300) |
220 | if (!hwreg_present((void *)(HILBASE + HIL_DATA))) { | 220 | if (!hwreg_present((void *)(HILBASE + HIL_DATA))) { |
diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c index 3d4d0a0ede28..1b08f4e79dd2 100644 --- a/drivers/input/keyboard/lkkbd.c +++ b/drivers/input/keyboard/lkkbd.c | |||
@@ -515,7 +515,7 @@ static int | |||
515 | lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code, | 515 | lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code, |
516 | int value) | 516 | int value) |
517 | { | 517 | { |
518 | struct lkkbd *lk = dev->private; | 518 | struct lkkbd *lk = input_get_drvdata (dev); |
519 | unsigned char leds_on = 0; | 519 | unsigned char leds_on = 0; |
520 | unsigned char leds_off = 0; | 520 | unsigned char leds_off = 0; |
521 | 521 | ||
@@ -666,9 +666,10 @@ lkkbd_connect (struct serio *serio, struct serio_driver *drv) | |||
666 | input_dev->id.vendor = SERIO_LKKBD; | 666 | input_dev->id.vendor = SERIO_LKKBD; |
667 | input_dev->id.product = 0; | 667 | input_dev->id.product = 0; |
668 | input_dev->id.version = 0x0100; | 668 | input_dev->id.version = 0x0100; |
669 | input_dev->cdev.dev = &serio->dev; | 669 | input_dev->dev.parent = &serio->dev; |
670 | input_dev->event = lkkbd_event; | 670 | input_dev->event = lkkbd_event; |
671 | input_dev->private = lk; | 671 | |
672 | input_set_drvdata (input_dev, lk); | ||
672 | 673 | ||
673 | set_bit (EV_KEY, input_dev->evbit); | 674 | set_bit (EV_KEY, input_dev->evbit); |
674 | set_bit (EV_LED, input_dev->evbit); | 675 | set_bit (EV_LED, input_dev->evbit); |
diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c index 2ade5186cc41..7a41b271f222 100644 --- a/drivers/input/keyboard/locomokbd.c +++ b/drivers/input/keyboard/locomokbd.c | |||
@@ -231,7 +231,7 @@ static int locomokbd_probe(struct locomo_dev *dev) | |||
231 | input_dev->id.vendor = 0x0001; | 231 | input_dev->id.vendor = 0x0001; |
232 | input_dev->id.product = 0x0001; | 232 | input_dev->id.product = 0x0001; |
233 | input_dev->id.version = 0x0100; | 233 | input_dev->id.version = 0x0100; |
234 | input_dev->private = locomokbd; | 234 | input_dev->dev.parent = &dev->dev; |
235 | 235 | ||
236 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); | 236 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); |
237 | input_dev->keycode = locomokbd->keycode; | 237 | input_dev->keycode = locomokbd->keycode; |
diff --git a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c index aa29b50765c9..b97a41e3ee56 100644 --- a/drivers/input/keyboard/newtonkbd.c +++ b/drivers/input/keyboard/newtonkbd.c | |||
@@ -104,8 +104,7 @@ static int nkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
104 | input_dev->id.vendor = SERIO_NEWTON; | 104 | input_dev->id.vendor = SERIO_NEWTON; |
105 | input_dev->id.product = 0x0001; | 105 | input_dev->id.product = 0x0001; |
106 | input_dev->id.version = 0x0100; | 106 | input_dev->id.version = 0x0100; |
107 | input_dev->cdev.dev = &serio->dev; | 107 | input_dev->dev.parent = &serio->dev; |
108 | input_dev->private = nkbd; | ||
109 | 108 | ||
110 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); | 109 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); |
111 | input_dev->keycode = nkbd->keycode; | 110 | input_dev->keycode = nkbd->keycode; |
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index 5680a6d95b2b..3a228634f101 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c | |||
@@ -370,8 +370,7 @@ static int __init omap_kp_probe(struct platform_device *pdev) | |||
370 | set_bit(keymap[i] & KEY_MAX, input_dev->keybit); | 370 | set_bit(keymap[i] & KEY_MAX, input_dev->keybit); |
371 | input_dev->name = "omap-keypad"; | 371 | input_dev->name = "omap-keypad"; |
372 | input_dev->phys = "omap-keypad/input0"; | 372 | input_dev->phys = "omap-keypad/input0"; |
373 | input_dev->cdev.dev = &pdev->dev; | 373 | input_dev->dev.parent = &pdev->dev; |
374 | input_dev->private = omap_kp; | ||
375 | 374 | ||
376 | input_dev->id.bustype = BUS_HOST; | 375 | input_dev->id.bustype = BUS_HOST; |
377 | input_dev->id.vendor = 0x0001; | 376 | input_dev->id.vendor = 0x0001; |
diff --git a/drivers/input/keyboard/pxa27x_keyboard.c b/drivers/input/keyboard/pxa27x_keyboard.c new file mode 100644 index 000000000000..06eaf766d9d2 --- /dev/null +++ b/drivers/input/keyboard/pxa27x_keyboard.c | |||
@@ -0,0 +1,258 @@ | |||
1 | /* | ||
2 | * linux/drivers/input/keyboard/pxa27x_keyboard.c | ||
3 | * | ||
4 | * Driver for the pxa27x matrix keyboard controller. | ||
5 | * | ||
6 | * Created: Feb 22, 2007 | ||
7 | * Author: Rodolfo Giometti <giometti@linux.it> | ||
8 | * | ||
9 | * Based on a previous implementations by Kevin O'Connor | ||
10 | * <kevin_at_koconnor.net> and Alex Osborne <bobofdoom@gmail.com> and | ||
11 | * on some suggestions by Nicolas Pitre <nico@cam.org>. | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License version 2 as | ||
15 | * published by the Free Software Foundation. | ||
16 | */ | ||
17 | |||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/input.h> | ||
24 | #include <linux/device.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | |||
27 | #include <asm/mach-types.h> | ||
28 | #include <asm/mach/arch.h> | ||
29 | #include <asm/mach/map.h> | ||
30 | |||
31 | #include <asm/arch/hardware.h> | ||
32 | #include <asm/arch/pxa-regs.h> | ||
33 | #include <asm/arch/irqs.h> | ||
34 | #include <asm/arch/pxa27x_keyboard.h> | ||
35 | |||
36 | #define DRIVER_NAME "pxa27x-keyboard" | ||
37 | |||
38 | #define KPASMKP(col) (col/2 == 0 ? KPASMKP0 : \ | ||
39 | col/2 == 1 ? KPASMKP1 : \ | ||
40 | col/2 == 2 ? KPASMKP2 : KPASMKP3) | ||
41 | #define KPASMKPx_MKC(row, col) (1 << (row + 16 * (col % 2))) | ||
42 | |||
43 | static irqreturn_t pxakbd_irq_handler(int irq, void *dev_id) | ||
44 | { | ||
45 | struct platform_device *pdev = dev_id; | ||
46 | struct pxa27x_keyboard_platform_data *pdata = pdev->dev.platform_data; | ||
47 | struct input_dev *input_dev = platform_get_drvdata(pdev); | ||
48 | unsigned long kpc = KPC; | ||
49 | int p, row, col, rel; | ||
50 | |||
51 | if (kpc & KPC_DI) { | ||
52 | unsigned long kpdk = KPDK; | ||
53 | |||
54 | if (!(kpdk & KPDK_DKP)) { | ||
55 | /* better luck next time */ | ||
56 | } else if (kpc & KPC_REE0) { | ||
57 | unsigned long kprec = KPREC; | ||
58 | KPREC = 0x7f; | ||
59 | |||
60 | if (kprec & KPREC_OF0) | ||
61 | rel = (kprec & 0xff) + 0x7f; | ||
62 | else if (kprec & KPREC_UF0) | ||
63 | rel = (kprec & 0xff) - 0x7f - 0xff; | ||
64 | else | ||
65 | rel = (kprec & 0xff) - 0x7f; | ||
66 | |||
67 | if (rel) { | ||
68 | input_report_rel(input_dev, REL_WHEEL, rel); | ||
69 | input_sync(input_dev); | ||
70 | } | ||
71 | } | ||
72 | } | ||
73 | |||
74 | if (kpc & KPC_MI) { | ||
75 | /* report the status of every button */ | ||
76 | for (row = 0; row < pdata->nr_rows; row++) { | ||
77 | for (col = 0; col < pdata->nr_cols; col++) { | ||
78 | p = KPASMKP(col) & KPASMKPx_MKC(row, col) ? | ||
79 | 1 : 0; | ||
80 | pr_debug("keycode %x - pressed %x\n", | ||
81 | pdata->keycodes[row][col], p); | ||
82 | input_report_key(input_dev, | ||
83 | pdata->keycodes[row][col], p); | ||
84 | } | ||
85 | } | ||
86 | input_sync(input_dev); | ||
87 | } | ||
88 | |||
89 | return IRQ_HANDLED; | ||
90 | } | ||
91 | |||
92 | static int pxakbd_open(struct input_dev *dev) | ||
93 | { | ||
94 | /* Set keypad control register */ | ||
95 | KPC |= (KPC_ASACT | | ||
96 | KPC_MS_ALL | | ||
97 | (2 << 6) | KPC_REE0 | KPC_DK_DEB_SEL | | ||
98 | KPC_ME | KPC_MIE | KPC_DE | KPC_DIE); | ||
99 | |||
100 | KPC &= ~KPC_AS; /* disable automatic scan */ | ||
101 | KPC &= ~KPC_IMKP; /* do not ignore multiple keypresses */ | ||
102 | |||
103 | /* Set rotary count to mid-point value */ | ||
104 | KPREC = 0x7F; | ||
105 | |||
106 | /* Enable unit clock */ | ||
107 | pxa_set_cken(CKEN19_KEYPAD, 1); | ||
108 | |||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | static void pxakbd_close(struct input_dev *dev) | ||
113 | { | ||
114 | /* Disable clock unit */ | ||
115 | pxa_set_cken(CKEN19_KEYPAD, 0); | ||
116 | } | ||
117 | |||
118 | #ifdef CONFIG_PM | ||
119 | static int pxakbd_suspend(struct platform_device *pdev, pm_message_t state) | ||
120 | { | ||
121 | struct pxa27x_keyboard_platform_data *pdata = pdev->dev.platform_data; | ||
122 | |||
123 | /* Save controller status */ | ||
124 | pdata->reg_kpc = KPC; | ||
125 | pdata->reg_kprec = KPREC; | ||
126 | |||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | static int pxakbd_resume(struct platform_device *pdev) | ||
131 | { | ||
132 | struct pxa27x_keyboard_platform_data *pdata = pdev->dev.platform_data; | ||
133 | struct input_dev *input_dev = platform_get_drvdata(pdev); | ||
134 | |||
135 | mutex_lock(&input_dev->mutex); | ||
136 | |||
137 | if (input_dev->users) { | ||
138 | /* Restore controller status */ | ||
139 | KPC = pdata->reg_kpc; | ||
140 | KPREC = pdata->reg_kprec; | ||
141 | |||
142 | /* Enable unit clock */ | ||
143 | pxa_set_cken(CKEN19_KEYPAD, 1); | ||
144 | } | ||
145 | |||
146 | mutex_unlock(&input_dev->mutex); | ||
147 | |||
148 | return 0; | ||
149 | } | ||
150 | #else | ||
151 | #define pxakbd_suspend NULL | ||
152 | #define pxakbd_resume NULL | ||
153 | #endif | ||
154 | |||
155 | static int __devinit pxakbd_probe(struct platform_device *pdev) | ||
156 | { | ||
157 | struct pxa27x_keyboard_platform_data *pdata = pdev->dev.platform_data; | ||
158 | struct input_dev *input_dev; | ||
159 | int i, row, col, error; | ||
160 | |||
161 | /* Create and register the input driver. */ | ||
162 | input_dev = input_allocate_device(); | ||
163 | if (!input_dev) { | ||
164 | printk(KERN_ERR "Cannot request keypad device\n"); | ||
165 | return -ENOMEM; | ||
166 | } | ||
167 | |||
168 | input_dev->name = DRIVER_NAME; | ||
169 | input_dev->id.bustype = BUS_HOST; | ||
170 | input_dev->open = pxakbd_open; | ||
171 | input_dev->close = pxakbd_close; | ||
172 | input_dev->dev.parent = &pdev->dev; | ||
173 | |||
174 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_REL); | ||
175 | input_dev->relbit[LONG(REL_WHEEL)] = BIT(REL_WHEEL); | ||
176 | for (row = 0; row < pdata->nr_rows; row++) { | ||
177 | for (col = 0; col < pdata->nr_cols; col++) { | ||
178 | int code = pdata->keycodes[row][col]; | ||
179 | if (code > 0) | ||
180 | set_bit(code, input_dev->keybit); | ||
181 | } | ||
182 | } | ||
183 | |||
184 | error = request_irq(IRQ_KEYPAD, pxakbd_irq_handler, IRQF_DISABLED, | ||
185 | DRIVER_NAME, pdev); | ||
186 | if (error) { | ||
187 | printk(KERN_ERR "Cannot request keypad IRQ\n"); | ||
188 | pxa_set_cken(CKEN19_KEYPAD, 0); | ||
189 | goto err_free_dev; | ||
190 | } | ||
191 | |||
192 | platform_set_drvdata(pdev, input_dev); | ||
193 | |||
194 | /* Register the input device */ | ||
195 | error = input_register_device(input_dev); | ||
196 | if (error) | ||
197 | goto err_free_irq; | ||
198 | |||
199 | /* Setup GPIOs. */ | ||
200 | for (i = 0; i < pdata->nr_rows + pdata->nr_cols; i++) | ||
201 | pxa_gpio_mode(pdata->gpio_modes[i]); | ||
202 | |||
203 | /* | ||
204 | * Store rows/cols info into keyboard registers. | ||
205 | */ | ||
206 | |||
207 | KPC |= (pdata->nr_rows - 1) << 26; | ||
208 | KPC |= (pdata->nr_cols - 1) << 23; | ||
209 | |||
210 | for (col = 0; col < pdata->nr_cols; col++) | ||
211 | KPC |= KPC_MS0 << col; | ||
212 | |||
213 | return 0; | ||
214 | |||
215 | err_free_irq: | ||
216 | platform_set_drvdata(pdev, NULL); | ||
217 | free_irq(IRQ_KEYPAD, pdev); | ||
218 | err_free_dev: | ||
219 | input_free_device(input_dev); | ||
220 | return error; | ||
221 | } | ||
222 | |||
223 | static int __devexit pxakbd_remove(struct platform_device *pdev) | ||
224 | { | ||
225 | struct input_dev *input_dev = platform_get_drvdata(pdev); | ||
226 | |||
227 | input_unregister_device(input_dev); | ||
228 | free_irq(IRQ_KEYPAD, pdev); | ||
229 | platform_set_drvdata(pdev, NULL); | ||
230 | |||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | static struct platform_driver pxakbd_driver = { | ||
235 | .probe = pxakbd_probe, | ||
236 | .remove = __devexit_p(pxakbd_remove), | ||
237 | .suspend = pxakbd_suspend, | ||
238 | .resume = pxakbd_resume, | ||
239 | .driver = { | ||
240 | .name = DRIVER_NAME, | ||
241 | }, | ||
242 | }; | ||
243 | |||
244 | static int __init pxakbd_init(void) | ||
245 | { | ||
246 | return platform_driver_register(&pxakbd_driver); | ||
247 | } | ||
248 | |||
249 | static void __exit pxakbd_exit(void) | ||
250 | { | ||
251 | platform_driver_unregister(&pxakbd_driver); | ||
252 | } | ||
253 | |||
254 | module_init(pxakbd_init); | ||
255 | module_exit(pxakbd_exit); | ||
256 | |||
257 | MODULE_DESCRIPTION("PXA27x Matrix Keyboard Driver"); | ||
258 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c index 8a2166c77ff4..41b80385476c 100644 --- a/drivers/input/keyboard/spitzkbd.c +++ b/drivers/input/keyboard/spitzkbd.c | |||
@@ -372,10 +372,9 @@ static int __init spitzkbd_probe(struct platform_device *dev) | |||
372 | 372 | ||
373 | spitzkbd->input = input_dev; | 373 | spitzkbd->input = input_dev; |
374 | 374 | ||
375 | input_dev->private = spitzkbd; | ||
376 | input_dev->name = "Spitz Keyboard"; | 375 | input_dev->name = "Spitz Keyboard"; |
377 | input_dev->phys = spitzkbd->phys; | 376 | input_dev->phys = spitzkbd->phys; |
378 | input_dev->cdev.dev = &dev->dev; | 377 | input_dev->dev.parent = &dev->dev; |
379 | 378 | ||
380 | input_dev->id.bustype = BUS_HOST; | 379 | input_dev->id.bustype = BUS_HOST; |
381 | input_dev->id.vendor = 0x0001; | 380 | input_dev->id.vendor = 0x0001; |
diff --git a/drivers/input/keyboard/stowaway.c b/drivers/input/keyboard/stowaway.c index f7b5c5b81451..b44b0684d543 100644 --- a/drivers/input/keyboard/stowaway.c +++ b/drivers/input/keyboard/stowaway.c | |||
@@ -108,8 +108,7 @@ static int skbd_connect(struct serio *serio, struct serio_driver *drv) | |||
108 | input_dev->id.vendor = SERIO_STOWAWAY; | 108 | input_dev->id.vendor = SERIO_STOWAWAY; |
109 | input_dev->id.product = 0x0001; | 109 | input_dev->id.product = 0x0001; |
110 | input_dev->id.version = 0x0100; | 110 | input_dev->id.version = 0x0100; |
111 | input_dev->cdev.dev = &serio->dev; | 111 | input_dev->dev.parent = &serio->dev; |
112 | input_dev->private = skbd; | ||
113 | 112 | ||
114 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); | 113 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); |
115 | input_dev->keycode = skbd->keycode; | 114 | input_dev->keycode = skbd->keycode; |
diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c index cc0238366414..1d4e39624cfe 100644 --- a/drivers/input/keyboard/sunkbd.c +++ b/drivers/input/keyboard/sunkbd.c | |||
@@ -146,7 +146,7 @@ out: | |||
146 | 146 | ||
147 | static int sunkbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 147 | static int sunkbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) |
148 | { | 148 | { |
149 | struct sunkbd *sunkbd = dev->private; | 149 | struct sunkbd *sunkbd = input_get_drvdata(dev); |
150 | 150 | ||
151 | switch (type) { | 151 | switch (type) { |
152 | 152 | ||
@@ -271,8 +271,10 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
271 | input_dev->id.vendor = SERIO_SUNKBD; | 271 | input_dev->id.vendor = SERIO_SUNKBD; |
272 | input_dev->id.product = sunkbd->type; | 272 | input_dev->id.product = sunkbd->type; |
273 | input_dev->id.version = 0x0100; | 273 | input_dev->id.version = 0x0100; |
274 | input_dev->cdev.dev = &serio->dev; | 274 | input_dev->dev.parent = &serio->dev; |
275 | input_dev->private = sunkbd; | 275 | |
276 | input_set_drvdata(input_dev, sunkbd); | ||
277 | |||
276 | input_dev->event = sunkbd_event; | 278 | input_dev->event = sunkbd_event; |
277 | 279 | ||
278 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_SND) | BIT(EV_REP); | 280 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_SND) | BIT(EV_REP); |
diff --git a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c index a82093432138..f3a56eb58ed1 100644 --- a/drivers/input/keyboard/xtkbd.c +++ b/drivers/input/keyboard/xtkbd.c | |||
@@ -108,8 +108,7 @@ static int xtkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
108 | input_dev->id.vendor = 0x0001; | 108 | input_dev->id.vendor = 0x0001; |
109 | input_dev->id.product = 0x0001; | 109 | input_dev->id.product = 0x0001; |
110 | input_dev->id.version = 0x0100; | 110 | input_dev->id.version = 0x0100; |
111 | input_dev->cdev.dev = &serio->dev; | 111 | input_dev->dev.parent = &serio->dev; |
112 | input_dev->private = xtkbd; | ||
113 | 112 | ||
114 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); | 113 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); |
115 | input_dev->keycode = xtkbd->keycode; | 114 | input_dev->keycode = xtkbd->keycode; |
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 41b42587f5e9..1d0d3e765db6 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig | |||
@@ -40,6 +40,16 @@ config INPUT_M68K_BEEP | |||
40 | tristate "M68k Beeper support" | 40 | tristate "M68k Beeper support" |
41 | depends on M68K | 41 | depends on M68K |
42 | 42 | ||
43 | config INPUT_COBALT_BTNS | ||
44 | tristate "Cobalt button interface" | ||
45 | depends on MIPS_COBALT | ||
46 | select INPUT_POLLDEV | ||
47 | help | ||
48 | Say Y here if you want to support MIPS Cobalt button interface. | ||
49 | |||
50 | To compile this driver as a module, choose M here: the | ||
51 | module will be called cobalt_btns. | ||
52 | |||
43 | config INPUT_WISTRON_BTNS | 53 | config INPUT_WISTRON_BTNS |
44 | tristate "x86 Wistron laptop button interface" | 54 | tristate "x86 Wistron laptop button interface" |
45 | depends on X86 && !X86_64 | 55 | depends on X86 && !X86_64 |
@@ -81,8 +91,19 @@ config INPUT_UINPUT | |||
81 | To compile this driver as a module, choose M here: the | 91 | To compile this driver as a module, choose M here: the |
82 | module will be called uinput. | 92 | module will be called uinput. |
83 | 93 | ||
94 | config INPUT_POLLDEV | ||
95 | tristate "Polled input device skeleton" | ||
96 | help | ||
97 | Say Y here if you are using a driver for an input | ||
98 | device that periodically polls hardware state. This | ||
99 | option is only useful for out-of-tree drivers since | ||
100 | in-tree drivers select it automatically. | ||
101 | |||
102 | To compile this driver as a module, choose M here: the | ||
103 | module will be called input-polldev. | ||
104 | |||
84 | config HP_SDC_RTC | 105 | config HP_SDC_RTC |
85 | tristate "HP SDC Real Time Clock" | 106 | tristate "HP SDC Real Time Clock" |
86 | depends on GSC || HP300 | 107 | depends on GSC || HP300 |
87 | select HP_SDC | 108 | select HP_SDC |
88 | help | 109 | help |
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index e0a8d58c9e9b..21e3cca0d33e 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile | |||
@@ -4,10 +4,12 @@ | |||
4 | 4 | ||
5 | # Each configuration option enables a list of files. | 5 | # Each configuration option enables a list of files. |
6 | 6 | ||
7 | obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o | ||
7 | obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o | 8 | obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o |
8 | obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o | 9 | obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o |
9 | obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o | 10 | obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o |
10 | obj-$(CONFIG_INPUT_UINPUT) += uinput.o | 11 | obj-$(CONFIG_INPUT_UINPUT) += uinput.o |
12 | obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o | ||
11 | obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o | 13 | obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o |
12 | obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o | 14 | obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o |
13 | obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o | 15 | obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o |
diff --git a/drivers/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c new file mode 100644 index 000000000000..064b07936019 --- /dev/null +++ b/drivers/input/misc/cobalt_btns.c | |||
@@ -0,0 +1,172 @@ | |||
1 | /* | ||
2 | * Cobalt button interface driver. | ||
3 | * | ||
4 | * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | */ | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/input-polldev.h> | ||
22 | #include <linux/ioport.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | |||
26 | #define BUTTONS_POLL_INTERVAL 30 /* msec */ | ||
27 | #define BUTTONS_COUNT_THRESHOLD 3 | ||
28 | #define BUTTONS_STATUS_MASK 0xfe000000 | ||
29 | |||
30 | struct buttons_dev { | ||
31 | struct input_polled_dev *poll_dev; | ||
32 | void __iomem *reg; | ||
33 | }; | ||
34 | |||
35 | struct buttons_map { | ||
36 | uint32_t mask; | ||
37 | int keycode; | ||
38 | int count; | ||
39 | }; | ||
40 | |||
41 | static struct buttons_map buttons_map[] = { | ||
42 | { 0x02000000, KEY_RESTART, }, | ||
43 | { 0x04000000, KEY_LEFT, }, | ||
44 | { 0x08000000, KEY_UP, }, | ||
45 | { 0x10000000, KEY_DOWN, }, | ||
46 | { 0x20000000, KEY_RIGHT, }, | ||
47 | { 0x40000000, KEY_ENTER, }, | ||
48 | { 0x80000000, KEY_SELECT, }, | ||
49 | }; | ||
50 | |||
51 | static void handle_buttons(struct input_polled_dev *dev) | ||
52 | { | ||
53 | struct buttons_map *button = buttons_map; | ||
54 | struct buttons_dev *bdev = dev->private; | ||
55 | struct input_dev *input = dev->input; | ||
56 | uint32_t status; | ||
57 | int i; | ||
58 | |||
59 | status = readl(bdev->reg); | ||
60 | status = ~status & BUTTONS_STATUS_MASK; | ||
61 | |||
62 | for (i = 0; i < ARRAY_SIZE(buttons_map); i++) { | ||
63 | if (status & button->mask) { | ||
64 | button->count++; | ||
65 | } else { | ||
66 | if (button->count >= BUTTONS_COUNT_THRESHOLD) { | ||
67 | input_report_key(input, button->keycode, 0); | ||
68 | input_sync(input); | ||
69 | } | ||
70 | button->count = 0; | ||
71 | } | ||
72 | |||
73 | if (button->count == BUTTONS_COUNT_THRESHOLD) { | ||
74 | input_report_key(input, button->keycode, 1); | ||
75 | input_sync(input); | ||
76 | } | ||
77 | |||
78 | button++; | ||
79 | } | ||
80 | } | ||
81 | |||
82 | static int __devinit cobalt_buttons_probe(struct platform_device *pdev) | ||
83 | { | ||
84 | struct buttons_dev *bdev; | ||
85 | struct input_polled_dev *poll_dev; | ||
86 | struct input_dev *input; | ||
87 | struct resource *res; | ||
88 | int error, i; | ||
89 | |||
90 | bdev = kzalloc(sizeof(struct buttons_dev), GFP_KERNEL); | ||
91 | poll_dev = input_allocate_polled_device(); | ||
92 | if (!bdev || !poll_dev) { | ||
93 | error = -ENOMEM; | ||
94 | goto err_free_mem; | ||
95 | } | ||
96 | |||
97 | poll_dev->private = bdev; | ||
98 | poll_dev->poll = handle_buttons; | ||
99 | poll_dev->poll_interval = BUTTONS_POLL_INTERVAL; | ||
100 | |||
101 | input = poll_dev->input; | ||
102 | input->name = "Cobalt buttons"; | ||
103 | input->phys = "cobalt/input0"; | ||
104 | input->id.bustype = BUS_HOST; | ||
105 | input->cdev.dev = &pdev->dev; | ||
106 | |||
107 | input->evbit[0] = BIT(EV_KEY); | ||
108 | for (i = 0; i < ARRAY_SIZE(buttons_map); i++) { | ||
109 | set_bit(buttons_map[i].keycode, input->keybit); | ||
110 | buttons_map[i].count = 0; | ||
111 | } | ||
112 | |||
113 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
114 | if (!res) { | ||
115 | error = -EBUSY; | ||
116 | goto err_free_mem; | ||
117 | } | ||
118 | |||
119 | bdev->poll_dev = poll_dev; | ||
120 | bdev->reg = ioremap(res->start, res->end - res->start + 1); | ||
121 | dev_set_drvdata(&pdev->dev, bdev); | ||
122 | |||
123 | error = input_register_polled_device(poll_dev); | ||
124 | if (error) | ||
125 | goto err_iounmap; | ||
126 | |||
127 | return 0; | ||
128 | |||
129 | err_iounmap: | ||
130 | iounmap(bdev->reg); | ||
131 | err_free_mem: | ||
132 | input_free_polled_device(poll_dev); | ||
133 | kfree(bdev); | ||
134 | dev_set_drvdata(&pdev->dev, NULL); | ||
135 | return error; | ||
136 | } | ||
137 | |||
138 | static int __devexit cobalt_buttons_remove(struct platform_device *pdev) | ||
139 | { | ||
140 | struct device *dev = &pdev->dev; | ||
141 | struct buttons_dev *bdev = dev_get_drvdata(dev); | ||
142 | |||
143 | input_unregister_polled_device(bdev->poll_dev); | ||
144 | input_free_polled_device(bdev->poll_dev); | ||
145 | iounmap(bdev->reg); | ||
146 | kfree(bdev); | ||
147 | dev_set_drvdata(dev, NULL); | ||
148 | |||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static struct platform_driver cobalt_buttons_driver = { | ||
153 | .probe = cobalt_buttons_probe, | ||
154 | .remove = __devexit_p(cobalt_buttons_remove), | ||
155 | .driver = { | ||
156 | .name = "Cobalt buttons", | ||
157 | .owner = THIS_MODULE, | ||
158 | }, | ||
159 | }; | ||
160 | |||
161 | static int __init cobalt_buttons_init(void) | ||
162 | { | ||
163 | return platform_driver_register(&cobalt_buttons_driver); | ||
164 | } | ||
165 | |||
166 | static void __exit cobalt_buttons_exit(void) | ||
167 | { | ||
168 | platform_driver_unregister(&cobalt_buttons_driver); | ||
169 | } | ||
170 | |||
171 | module_init(cobalt_buttons_init); | ||
172 | module_exit(cobalt_buttons_exit); | ||
diff --git a/drivers/input/misc/input-polldev.c b/drivers/input/misc/input-polldev.c new file mode 100644 index 000000000000..1b2b9c9c5d88 --- /dev/null +++ b/drivers/input/misc/input-polldev.c | |||
@@ -0,0 +1,171 @@ | |||
1 | /* | ||
2 | * Generic implementation of a polled input device | ||
3 | |||
4 | * Copyright (c) 2007 Dmitry Torokhov | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License version 2 as published by | ||
8 | * the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/jiffies.h> | ||
12 | #include <linux/mutex.h> | ||
13 | #include <linux/input-polldev.h> | ||
14 | |||
15 | static DEFINE_MUTEX(polldev_mutex); | ||
16 | static int polldev_users; | ||
17 | static struct workqueue_struct *polldev_wq; | ||
18 | |||
19 | static int input_polldev_start_workqueue(void) | ||
20 | { | ||
21 | int retval; | ||
22 | |||
23 | retval = mutex_lock_interruptible(&polldev_mutex); | ||
24 | if (retval) | ||
25 | return retval; | ||
26 | |||
27 | if (!polldev_users) { | ||
28 | polldev_wq = create_singlethread_workqueue("ipolldevd"); | ||
29 | if (!polldev_wq) { | ||
30 | printk(KERN_ERR "input-polldev: failed to create " | ||
31 | "ipolldevd workqueue\n"); | ||
32 | retval = -ENOMEM; | ||
33 | goto out; | ||
34 | } | ||
35 | } | ||
36 | |||
37 | polldev_users++; | ||
38 | |||
39 | out: | ||
40 | mutex_unlock(&polldev_mutex); | ||
41 | return retval; | ||
42 | } | ||
43 | |||
44 | static void input_polldev_stop_workqueue(void) | ||
45 | { | ||
46 | mutex_lock(&polldev_mutex); | ||
47 | |||
48 | if (!--polldev_users) | ||
49 | destroy_workqueue(polldev_wq); | ||
50 | |||
51 | mutex_unlock(&polldev_mutex); | ||
52 | } | ||
53 | |||
54 | static void input_polled_device_work(struct work_struct *work) | ||
55 | { | ||
56 | struct input_polled_dev *dev = | ||
57 | container_of(work, struct input_polled_dev, work.work); | ||
58 | |||
59 | dev->poll(dev); | ||
60 | queue_delayed_work(polldev_wq, &dev->work, | ||
61 | msecs_to_jiffies(dev->poll_interval)); | ||
62 | } | ||
63 | |||
64 | static int input_open_polled_device(struct input_dev *input) | ||
65 | { | ||
66 | struct input_polled_dev *dev = input->private; | ||
67 | int error; | ||
68 | |||
69 | error = input_polldev_start_workqueue(); | ||
70 | if (error) | ||
71 | return error; | ||
72 | |||
73 | if (dev->flush) | ||
74 | dev->flush(dev); | ||
75 | |||
76 | queue_delayed_work(polldev_wq, &dev->work, | ||
77 | msecs_to_jiffies(dev->poll_interval)); | ||
78 | |||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | static void input_close_polled_device(struct input_dev *input) | ||
83 | { | ||
84 | struct input_polled_dev *dev = input->private; | ||
85 | |||
86 | cancel_rearming_delayed_workqueue(polldev_wq, &dev->work); | ||
87 | input_polldev_stop_workqueue(); | ||
88 | } | ||
89 | |||
90 | /** | ||
91 | * input_allocate_polled_device - allocated memory polled device | ||
92 | * | ||
93 | * The function allocates memory for a polled device and also | ||
94 | * for an input device associated with this polled device. | ||
95 | */ | ||
96 | struct input_polled_dev *input_allocate_polled_device(void) | ||
97 | { | ||
98 | struct input_polled_dev *dev; | ||
99 | |||
100 | dev = kzalloc(sizeof(struct input_polled_dev), GFP_KERNEL); | ||
101 | if (!dev) | ||
102 | return NULL; | ||
103 | |||
104 | dev->input = input_allocate_device(); | ||
105 | if (!dev->input) { | ||
106 | kfree(dev); | ||
107 | return NULL; | ||
108 | } | ||
109 | |||
110 | return dev; | ||
111 | } | ||
112 | EXPORT_SYMBOL(input_allocate_polled_device); | ||
113 | |||
114 | /** | ||
115 | * input_free_polled_device - free memory allocated for polled device | ||
116 | * @dev: device to free | ||
117 | * | ||
118 | * The function frees memory allocated for polling device and drops | ||
119 | * reference to the associated input device (if present). | ||
120 | */ | ||
121 | void input_free_polled_device(struct input_polled_dev *dev) | ||
122 | { | ||
123 | if (dev) { | ||
124 | input_free_device(dev->input); | ||
125 | kfree(dev); | ||
126 | } | ||
127 | } | ||
128 | EXPORT_SYMBOL(input_free_polled_device); | ||
129 | |||
130 | /** | ||
131 | * input_register_polled_device - register polled device | ||
132 | * @dev: device to register | ||
133 | * | ||
134 | * The function registers previously initialized polled input device | ||
135 | * with input layer. The device should be allocated with call to | ||
136 | * input_allocate_polled_device(). Callers should also set up poll() | ||
137 | * method and set up capabilities (id, name, phys, bits) of the | ||
138 | * corresponing input_dev structure. | ||
139 | */ | ||
140 | int input_register_polled_device(struct input_polled_dev *dev) | ||
141 | { | ||
142 | struct input_dev *input = dev->input; | ||
143 | |||
144 | INIT_DELAYED_WORK(&dev->work, input_polled_device_work); | ||
145 | if (!dev->poll_interval) | ||
146 | dev->poll_interval = 500; | ||
147 | input->private = dev; | ||
148 | input->open = input_open_polled_device; | ||
149 | input->close = input_close_polled_device; | ||
150 | |||
151 | return input_register_device(input); | ||
152 | } | ||
153 | EXPORT_SYMBOL(input_register_polled_device); | ||
154 | |||
155 | /** | ||
156 | * input_unregister_polled_device - unregister polled device | ||
157 | * @dev: device to unregister | ||
158 | * | ||
159 | * The function unregisters previously registered polled input | ||
160 | * device from input layer. Polling is stopped and device is | ||
161 | * ready to be freed with call to input_free_polled_device(). | ||
162 | * Callers should not attempt to access dev->input pointer | ||
163 | * after calling this function. | ||
164 | */ | ||
165 | void input_unregister_polled_device(struct input_polled_dev *dev) | ||
166 | { | ||
167 | input_unregister_device(dev->input); | ||
168 | dev->input = NULL; | ||
169 | } | ||
170 | EXPORT_SYMBOL(input_unregister_polled_device); | ||
171 | |||
diff --git a/drivers/input/misc/ixp4xx-beeper.c b/drivers/input/misc/ixp4xx-beeper.c index 105c6fc27823..3d4b619dadab 100644 --- a/drivers/input/misc/ixp4xx-beeper.c +++ b/drivers/input/misc/ixp4xx-beeper.c | |||
@@ -51,7 +51,7 @@ static void ixp4xx_spkr_control(unsigned int pin, unsigned int count) | |||
51 | 51 | ||
52 | static int ixp4xx_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 52 | static int ixp4xx_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) |
53 | { | 53 | { |
54 | unsigned int pin = (unsigned int) dev->private; | 54 | unsigned int pin = (unsigned int) input_get_drvdata(input_dev); |
55 | unsigned int count = 0; | 55 | unsigned int count = 0; |
56 | 56 | ||
57 | if (type != EV_SND) | 57 | if (type != EV_SND) |
@@ -99,14 +99,15 @@ static int __devinit ixp4xx_spkr_probe(struct platform_device *dev) | |||
99 | if (!input_dev) | 99 | if (!input_dev) |
100 | return -ENOMEM; | 100 | return -ENOMEM; |
101 | 101 | ||
102 | input_dev->private = (void *) dev->id; | 102 | input_set_drvdata(input_dev, (void *) dev->id); |
103 | |||
103 | input_dev->name = "ixp4xx beeper", | 104 | input_dev->name = "ixp4xx beeper", |
104 | input_dev->phys = "ixp4xx/gpio"; | 105 | input_dev->phys = "ixp4xx/gpio"; |
105 | input_dev->id.bustype = BUS_HOST; | 106 | input_dev->id.bustype = BUS_HOST; |
106 | input_dev->id.vendor = 0x001f; | 107 | input_dev->id.vendor = 0x001f; |
107 | input_dev->id.product = 0x0001; | 108 | input_dev->id.product = 0x0001; |
108 | input_dev->id.version = 0x0100; | 109 | input_dev->id.version = 0x0100; |
109 | input_dev->cdev.dev = &dev->dev; | 110 | input_dev->dev.parent = &dev->dev; |
110 | 111 | ||
111 | input_dev->evbit[0] = BIT(EV_SND); | 112 | input_dev->evbit[0] = BIT(EV_SND); |
112 | input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); | 113 | input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); |
@@ -136,7 +137,7 @@ static int __devinit ixp4xx_spkr_probe(struct platform_device *dev) | |||
136 | static int __devexit ixp4xx_spkr_remove(struct platform_device *dev) | 137 | static int __devexit ixp4xx_spkr_remove(struct platform_device *dev) |
137 | { | 138 | { |
138 | struct input_dev *input_dev = platform_get_drvdata(dev); | 139 | struct input_dev *input_dev = platform_get_drvdata(dev); |
139 | unsigned int pin = (unsigned int) input_dev->private; | 140 | unsigned int pin = (unsigned int) input_get_drvdata(input_dev); |
140 | 141 | ||
141 | input_unregister_device(input_dev); | 142 | input_unregister_device(input_dev); |
142 | platform_set_drvdata(dev, NULL); | 143 | platform_set_drvdata(dev, NULL); |
@@ -153,7 +154,7 @@ static int __devexit ixp4xx_spkr_remove(struct platform_device *dev) | |||
153 | static void ixp4xx_spkr_shutdown(struct platform_device *dev) | 154 | static void ixp4xx_spkr_shutdown(struct platform_device *dev) |
154 | { | 155 | { |
155 | struct input_dev *input_dev = platform_get_drvdata(dev); | 156 | struct input_dev *input_dev = platform_get_drvdata(dev); |
156 | unsigned int pin = (unsigned int) input_dev->private; | 157 | unsigned int pin = (unsigned int) input_get_drvdata(input_dev); |
157 | 158 | ||
158 | /* turn off the speaker */ | 159 | /* turn off the speaker */ |
159 | disable_irq(IRQ_IXP4XX_TIMER2); | 160 | disable_irq(IRQ_IXP4XX_TIMER2); |
diff --git a/drivers/input/misc/m68kspkr.c b/drivers/input/misc/m68kspkr.c index 8d6c3837badb..e9f26e766b4d 100644 --- a/drivers/input/misc/m68kspkr.c +++ b/drivers/input/misc/m68kspkr.c | |||
@@ -63,7 +63,7 @@ static int __devinit m68kspkr_probe(struct platform_device *dev) | |||
63 | input_dev->id.vendor = 0x001f; | 63 | input_dev->id.vendor = 0x001f; |
64 | input_dev->id.product = 0x0001; | 64 | input_dev->id.product = 0x0001; |
65 | input_dev->id.version = 0x0100; | 65 | input_dev->id.version = 0x0100; |
66 | input_dev->cdev.dev = &dev->dev; | 66 | input_dev->dev.parent = &dev->dev; |
67 | 67 | ||
68 | input_dev->evbit[0] = BIT(EV_SND); | 68 | input_dev->evbit[0] = BIT(EV_SND); |
69 | input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); | 69 | input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); |
diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c index afd322185bbf..31989dcd922c 100644 --- a/drivers/input/misc/pcspkr.c +++ b/drivers/input/misc/pcspkr.c | |||
@@ -78,7 +78,7 @@ static int __devinit pcspkr_probe(struct platform_device *dev) | |||
78 | pcspkr_dev->id.vendor = 0x001f; | 78 | pcspkr_dev->id.vendor = 0x001f; |
79 | pcspkr_dev->id.product = 0x0001; | 79 | pcspkr_dev->id.product = 0x0001; |
80 | pcspkr_dev->id.version = 0x0100; | 80 | pcspkr_dev->id.version = 0x0100; |
81 | pcspkr_dev->cdev.dev = &dev->dev; | 81 | pcspkr_dev->dev.parent = &dev->dev; |
82 | 82 | ||
83 | pcspkr_dev->evbit[0] = BIT(EV_SND); | 83 | pcspkr_dev->evbit[0] = BIT(EV_SND); |
84 | pcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); | 84 | pcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); |
diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c index 106c94f33b93..e36ec1d92be8 100644 --- a/drivers/input/misc/sparcspkr.c +++ b/drivers/input/misc/sparcspkr.c | |||
@@ -28,7 +28,7 @@ struct sparcspkr_state { | |||
28 | 28 | ||
29 | 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) |
30 | { | 30 | { |
31 | struct sparcspkr_state *state = dev_get_drvdata(dev->cdev.dev); | 31 | struct sparcspkr_state *state = dev_get_drvdata(dev->dev.parent); |
32 | unsigned int count = 0; | 32 | unsigned int count = 0; |
33 | unsigned long flags; | 33 | unsigned long flags; |
34 | 34 | ||
@@ -61,7 +61,7 @@ static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned in | |||
61 | 61 | ||
62 | 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) |
63 | { | 63 | { |
64 | struct sparcspkr_state *state = dev_get_drvdata(dev->cdev.dev); | 64 | struct sparcspkr_state *state = dev_get_drvdata(dev->dev.parent); |
65 | unsigned int count = 0; | 65 | unsigned int count = 0; |
66 | unsigned long flags; | 66 | unsigned long flags; |
67 | 67 | ||
@@ -113,7 +113,7 @@ static int __devinit sparcspkr_probe(struct device *dev) | |||
113 | input_dev->id.vendor = 0x001f; | 113 | input_dev->id.vendor = 0x001f; |
114 | input_dev->id.product = 0x0001; | 114 | input_dev->id.product = 0x0001; |
115 | input_dev->id.version = 0x0100; | 115 | input_dev->id.version = 0x0100; |
116 | input_dev->cdev.dev = dev; | 116 | input_dev->dev.parent = dev; |
117 | 117 | ||
118 | input_dev->evbit[0] = BIT(EV_SND); | 118 | input_dev->evbit[0] = BIT(EV_SND); |
119 | input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); | 119 | input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); |
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index 42556232c523..031467eadd31 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c | |||
@@ -41,9 +41,7 @@ | |||
41 | 41 | ||
42 | static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 42 | static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) |
43 | { | 43 | { |
44 | struct uinput_device *udev; | 44 | struct uinput_device *udev = input_get_drvdata(dev); |
45 | |||
46 | udev = dev->private; | ||
47 | 45 | ||
48 | udev->buff[udev->head].type = type; | 46 | udev->buff[udev->head].type = type; |
49 | udev->buff[udev->head].code = code; | 47 | udev->buff[udev->head].code = code; |
@@ -136,7 +134,7 @@ static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *eff | |||
136 | request.u.upload.effect = effect; | 134 | request.u.upload.effect = effect; |
137 | request.u.upload.old = old; | 135 | request.u.upload.old = old; |
138 | 136 | ||
139 | retval = uinput_request_reserve_slot(dev->private, &request); | 137 | retval = uinput_request_reserve_slot(input_get_drvdata(dev), &request); |
140 | if (!retval) | 138 | if (!retval) |
141 | retval = uinput_request_submit(dev, &request); | 139 | retval = uinput_request_submit(dev, &request); |
142 | 140 | ||
@@ -156,7 +154,7 @@ static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id) | |||
156 | request.code = UI_FF_ERASE; | 154 | request.code = UI_FF_ERASE; |
157 | request.u.effect_id = effect_id; | 155 | request.u.effect_id = effect_id; |
158 | 156 | ||
159 | retval = uinput_request_reserve_slot(dev->private, &request); | 157 | retval = uinput_request_reserve_slot(input_get_drvdata(dev), &request); |
160 | if (!retval) | 158 | if (!retval) |
161 | retval = uinput_request_submit(dev, &request); | 159 | retval = uinput_request_submit(dev, &request); |
162 | 160 | ||
@@ -274,7 +272,7 @@ static int uinput_allocate_device(struct uinput_device *udev) | |||
274 | return -ENOMEM; | 272 | return -ENOMEM; |
275 | 273 | ||
276 | udev->dev->event = uinput_dev_event; | 274 | udev->dev->event = uinput_dev_event; |
277 | udev->dev->private = udev; | 275 | input_set_drvdata(udev->dev, udev); |
278 | 276 | ||
279 | return 0; | 277 | return 0; |
280 | } | 278 | } |
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index e1183aeb8ed5..961aad7a0476 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c | |||
@@ -50,7 +50,7 @@ | |||
50 | MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>"); | 50 | MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>"); |
51 | MODULE_DESCRIPTION("Wistron laptop button driver"); | 51 | MODULE_DESCRIPTION("Wistron laptop button driver"); |
52 | MODULE_LICENSE("GPL v2"); | 52 | MODULE_LICENSE("GPL v2"); |
53 | MODULE_VERSION("0.1"); | 53 | MODULE_VERSION("0.2"); |
54 | 54 | ||
55 | static int force; /* = 0; */ | 55 | static int force; /* = 0; */ |
56 | module_param(force, bool, 0); | 56 | module_param(force, bool, 0); |
@@ -58,7 +58,7 @@ MODULE_PARM_DESC(force, "Load even if computer is not in database"); | |||
58 | 58 | ||
59 | static char *keymap_name; /* = NULL; */ | 59 | static char *keymap_name; /* = NULL; */ |
60 | module_param_named(keymap, keymap_name, charp, 0); | 60 | module_param_named(keymap, keymap_name, charp, 0); |
61 | MODULE_PARM_DESC(keymap, "Keymap name, if it can't be autodetected"); | 61 | MODULE_PARM_DESC(keymap, "Keymap name, if it can't be autodetected [generic, 1557/MS2141]"); |
62 | 62 | ||
63 | static struct platform_device *wistron_device; | 63 | static struct platform_device *wistron_device; |
64 | 64 | ||
@@ -233,10 +233,20 @@ static void bios_set_state(u8 subsys, int enable) | |||
233 | struct key_entry { | 233 | struct key_entry { |
234 | char type; /* See KE_* below */ | 234 | char type; /* See KE_* below */ |
235 | u8 code; | 235 | u8 code; |
236 | unsigned keycode; /* For KE_KEY */ | 236 | union { |
237 | u16 keycode; /* For KE_KEY */ | ||
238 | struct { /* For KE_SW */ | ||
239 | u8 code; | ||
240 | u8 value; | ||
241 | } sw; | ||
242 | }; | ||
237 | }; | 243 | }; |
238 | 244 | ||
239 | enum { KE_END, KE_KEY, KE_WIFI, KE_BLUETOOTH }; | 245 | enum { KE_END, KE_KEY, KE_SW, KE_WIFI, KE_BLUETOOTH }; |
246 | |||
247 | #define FE_MAIL_LED 0x01 | ||
248 | #define FE_WIFI_LED 0x02 | ||
249 | #define FE_UNTESTED 0x80 | ||
240 | 250 | ||
241 | static const struct key_entry *keymap; /* = NULL; Current key map */ | 251 | static const struct key_entry *keymap; /* = NULL; Current key map */ |
242 | static int have_wifi; | 252 | static int have_wifi; |
@@ -256,93 +266,341 @@ static int __init dmi_matched(struct dmi_system_id *dmi) | |||
256 | return 1; | 266 | return 1; |
257 | } | 267 | } |
258 | 268 | ||
259 | static struct key_entry keymap_empty[] = { | 269 | static struct key_entry keymap_empty[] __initdata = { |
260 | { KE_END, 0 } | 270 | { KE_END, 0 } |
261 | }; | 271 | }; |
262 | 272 | ||
263 | static struct key_entry keymap_fs_amilo_pro_v2000[] = { | 273 | static struct key_entry keymap_fs_amilo_pro_v2000[] __initdata = { |
264 | { KE_KEY, 0x01, KEY_HELP }, | 274 | { KE_KEY, 0x01, {KEY_HELP} }, |
265 | { KE_KEY, 0x11, KEY_PROG1 }, | 275 | { KE_KEY, 0x11, {KEY_PROG1} }, |
266 | { KE_KEY, 0x12, KEY_PROG2 }, | 276 | { KE_KEY, 0x12, {KEY_PROG2} }, |
267 | { KE_WIFI, 0x30, 0 }, | 277 | { KE_WIFI, 0x30 }, |
268 | { KE_KEY, 0x31, KEY_MAIL }, | 278 | { KE_KEY, 0x31, {KEY_MAIL} }, |
269 | { KE_KEY, 0x36, KEY_WWW }, | 279 | { KE_KEY, 0x36, {KEY_WWW} }, |
270 | { KE_END, 0 } | 280 | { KE_END, 0 } |
271 | }; | 281 | }; |
272 | 282 | ||
273 | static struct key_entry keymap_fujitsu_n3510[] = { | 283 | static struct key_entry keymap_fujitsu_n3510[] __initdata = { |
274 | { KE_KEY, 0x11, KEY_PROG1 }, | 284 | { KE_KEY, 0x11, {KEY_PROG1} }, |
275 | { KE_KEY, 0x12, KEY_PROG2 }, | 285 | { KE_KEY, 0x12, {KEY_PROG2} }, |
276 | { KE_KEY, 0x36, KEY_WWW }, | 286 | { KE_KEY, 0x36, {KEY_WWW} }, |
277 | { KE_KEY, 0x31, KEY_MAIL }, | 287 | { KE_KEY, 0x31, {KEY_MAIL} }, |
278 | { KE_KEY, 0x71, KEY_STOPCD }, | 288 | { KE_KEY, 0x71, {KEY_STOPCD} }, |
279 | { KE_KEY, 0x72, KEY_PLAYPAUSE }, | 289 | { KE_KEY, 0x72, {KEY_PLAYPAUSE} }, |
280 | { KE_KEY, 0x74, KEY_REWIND }, | 290 | { KE_KEY, 0x74, {KEY_REWIND} }, |
281 | { KE_KEY, 0x78, KEY_FORWARD }, | 291 | { KE_KEY, 0x78, {KEY_FORWARD} }, |
282 | { KE_END, 0 } | 292 | { KE_END, 0 } |
283 | }; | 293 | }; |
284 | 294 | ||
285 | static struct key_entry keymap_wistron_ms2111[] = { | 295 | static struct key_entry keymap_wistron_ms2111[] __initdata = { |
286 | { KE_KEY, 0x11, KEY_PROG1 }, | 296 | { KE_KEY, 0x11, {KEY_PROG1} }, |
287 | { KE_KEY, 0x12, KEY_PROG2 }, | 297 | { KE_KEY, 0x12, {KEY_PROG2} }, |
288 | { KE_KEY, 0x13, KEY_PROG3 }, | 298 | { KE_KEY, 0x13, {KEY_PROG3} }, |
289 | { KE_KEY, 0x31, KEY_MAIL }, | 299 | { KE_KEY, 0x31, {KEY_MAIL} }, |
290 | { KE_KEY, 0x36, KEY_WWW }, | 300 | { KE_KEY, 0x36, {KEY_WWW} }, |
291 | { KE_END, 0 } | 301 | { KE_END, FE_MAIL_LED } |
302 | }; | ||
303 | |||
304 | static struct key_entry keymap_wistron_md40100[] __initdata = { | ||
305 | { KE_KEY, 0x01, {KEY_HELP} }, | ||
306 | { KE_KEY, 0x02, {KEY_CONFIG} }, | ||
307 | { KE_KEY, 0x31, {KEY_MAIL} }, | ||
308 | { KE_KEY, 0x36, {KEY_WWW} }, | ||
309 | { KE_KEY, 0x37, {KEY_DISPLAYTOGGLE} }, /* Display on/off */ | ||
310 | { KE_END, FE_MAIL_LED | FE_WIFI_LED | FE_UNTESTED } | ||
292 | }; | 311 | }; |
293 | 312 | ||
294 | static struct key_entry keymap_wistron_ms2141[] = { | 313 | static struct key_entry keymap_wistron_ms2141[] __initdata = { |
295 | { KE_KEY, 0x11, KEY_PROG1 }, | 314 | { KE_KEY, 0x11, {KEY_PROG1} }, |
296 | { KE_KEY, 0x12, KEY_PROG2 }, | 315 | { KE_KEY, 0x12, {KEY_PROG2} }, |
297 | { KE_WIFI, 0x30, 0 }, | 316 | { KE_WIFI, 0x30 }, |
298 | { KE_KEY, 0x22, KEY_REWIND }, | 317 | { KE_KEY, 0x22, {KEY_REWIND} }, |
299 | { KE_KEY, 0x23, KEY_FORWARD }, | 318 | { KE_KEY, 0x23, {KEY_FORWARD} }, |
300 | { KE_KEY, 0x24, KEY_PLAYPAUSE }, | 319 | { KE_KEY, 0x24, {KEY_PLAYPAUSE} }, |
301 | { KE_KEY, 0x25, KEY_STOPCD }, | 320 | { KE_KEY, 0x25, {KEY_STOPCD} }, |
302 | { KE_KEY, 0x31, KEY_MAIL }, | 321 | { KE_KEY, 0x31, {KEY_MAIL} }, |
303 | { KE_KEY, 0x36, KEY_WWW }, | 322 | { KE_KEY, 0x36, {KEY_WWW} }, |
304 | { KE_END, 0 } | 323 | { KE_END, 0 } |
305 | }; | 324 | }; |
306 | 325 | ||
307 | static struct key_entry keymap_acer_aspire_1500[] = { | 326 | static struct key_entry keymap_acer_aspire_1500[] __initdata = { |
308 | { KE_KEY, 0x11, KEY_PROG1 }, | 327 | { KE_KEY, 0x01, {KEY_HELP} }, |
309 | { KE_KEY, 0x12, KEY_PROG2 }, | 328 | { KE_KEY, 0x03, {KEY_POWER} }, |
310 | { KE_WIFI, 0x30, 0 }, | 329 | { KE_KEY, 0x11, {KEY_PROG1} }, |
311 | { KE_KEY, 0x31, KEY_MAIL }, | 330 | { KE_KEY, 0x12, {KEY_PROG2} }, |
312 | { KE_KEY, 0x36, KEY_WWW }, | 331 | { KE_WIFI, 0x30 }, |
313 | { KE_BLUETOOTH, 0x44, 0 }, | 332 | { KE_KEY, 0x31, {KEY_MAIL} }, |
314 | { KE_END, 0 } | 333 | { KE_KEY, 0x36, {KEY_WWW} }, |
334 | { KE_KEY, 0x49, {KEY_CONFIG} }, | ||
335 | { KE_BLUETOOTH, 0x44 }, | ||
336 | { KE_END, FE_UNTESTED } | ||
315 | }; | 337 | }; |
316 | 338 | ||
317 | static struct key_entry keymap_acer_travelmate_240[] = { | 339 | static struct key_entry keymap_acer_aspire_1600[] __initdata = { |
318 | { KE_KEY, 0x31, KEY_MAIL }, | 340 | { KE_KEY, 0x01, {KEY_HELP} }, |
319 | { KE_KEY, 0x36, KEY_WWW }, | 341 | { KE_KEY, 0x03, {KEY_POWER} }, |
320 | { KE_KEY, 0x11, KEY_PROG1 }, | 342 | { KE_KEY, 0x08, {KEY_MUTE} }, |
321 | { KE_KEY, 0x12, KEY_PROG2 }, | 343 | { KE_KEY, 0x11, {KEY_PROG1} }, |
322 | { KE_BLUETOOTH, 0x44, 0 }, | 344 | { KE_KEY, 0x12, {KEY_PROG2} }, |
323 | { KE_WIFI, 0x30, 0 }, | 345 | { KE_KEY, 0x13, {KEY_PROG3} }, |
324 | { KE_END, 0 } | 346 | { KE_KEY, 0x31, {KEY_MAIL} }, |
347 | { KE_KEY, 0x36, {KEY_WWW} }, | ||
348 | { KE_KEY, 0x49, {KEY_CONFIG} }, | ||
349 | { KE_WIFI, 0x30 }, | ||
350 | { KE_BLUETOOTH, 0x44 }, | ||
351 | { KE_END, FE_MAIL_LED | FE_UNTESTED } | ||
352 | }; | ||
353 | |||
354 | /* 3020 has been tested */ | ||
355 | static struct key_entry keymap_acer_aspire_5020[] __initdata = { | ||
356 | { KE_KEY, 0x01, {KEY_HELP} }, | ||
357 | { KE_KEY, 0x03, {KEY_POWER} }, | ||
358 | { KE_KEY, 0x05, {KEY_SWITCHVIDEOMODE} }, /* Display selection */ | ||
359 | { KE_KEY, 0x11, {KEY_PROG1} }, | ||
360 | { KE_KEY, 0x12, {KEY_PROG2} }, | ||
361 | { KE_KEY, 0x31, {KEY_MAIL} }, | ||
362 | { KE_KEY, 0x36, {KEY_WWW} }, | ||
363 | { KE_KEY, 0x6a, {KEY_CONFIG} }, | ||
364 | { KE_WIFI, 0x30 }, | ||
365 | { KE_BLUETOOTH, 0x44 }, | ||
366 | { KE_END, FE_MAIL_LED | FE_UNTESTED } | ||
367 | }; | ||
368 | |||
369 | static struct key_entry keymap_acer_travelmate_2410[] __initdata = { | ||
370 | { KE_KEY, 0x01, {KEY_HELP} }, | ||
371 | { KE_KEY, 0x6d, {KEY_POWER} }, | ||
372 | { KE_KEY, 0x11, {KEY_PROG1} }, | ||
373 | { KE_KEY, 0x12, {KEY_PROG2} }, | ||
374 | { KE_KEY, 0x31, {KEY_MAIL} }, | ||
375 | { KE_KEY, 0x36, {KEY_WWW} }, | ||
376 | { KE_KEY, 0x6a, {KEY_CONFIG} }, | ||
377 | { KE_WIFI, 0x30 }, | ||
378 | { KE_BLUETOOTH, 0x44 }, | ||
379 | { KE_END, FE_MAIL_LED | FE_UNTESTED } | ||
380 | }; | ||
381 | |||
382 | static struct key_entry keymap_acer_travelmate_110[] __initdata = { | ||
383 | { KE_KEY, 0x01, {KEY_HELP} }, | ||
384 | { KE_KEY, 0x02, {KEY_CONFIG} }, | ||
385 | { KE_KEY, 0x03, {KEY_POWER} }, | ||
386 | { KE_KEY, 0x08, {KEY_MUTE} }, | ||
387 | { KE_KEY, 0x11, {KEY_PROG1} }, | ||
388 | { KE_KEY, 0x12, {KEY_PROG2} }, | ||
389 | { KE_KEY, 0x20, {KEY_VOLUMEUP} }, | ||
390 | { KE_KEY, 0x21, {KEY_VOLUMEDOWN} }, | ||
391 | { KE_KEY, 0x31, {KEY_MAIL} }, | ||
392 | { KE_KEY, 0x36, {KEY_WWW} }, | ||
393 | { KE_SW, 0x4a, {.sw = {SW_LID, 1}} }, /* lid close */ | ||
394 | { KE_SW, 0x4b, {.sw = {SW_LID, 0}} }, /* lid open */ | ||
395 | { KE_WIFI, 0x30 }, | ||
396 | { KE_END, FE_MAIL_LED | FE_UNTESTED } | ||
397 | }; | ||
398 | |||
399 | static struct key_entry keymap_acer_travelmate_300[] __initdata = { | ||
400 | { KE_KEY, 0x01, {KEY_HELP} }, | ||
401 | { KE_KEY, 0x02, {KEY_CONFIG} }, | ||
402 | { KE_KEY, 0x03, {KEY_POWER} }, | ||
403 | { KE_KEY, 0x08, {KEY_MUTE} }, | ||
404 | { KE_KEY, 0x11, {KEY_PROG1} }, | ||
405 | { KE_KEY, 0x12, {KEY_PROG2} }, | ||
406 | { KE_KEY, 0x20, {KEY_VOLUMEUP} }, | ||
407 | { KE_KEY, 0x21, {KEY_VOLUMEDOWN} }, | ||
408 | { KE_KEY, 0x31, {KEY_MAIL} }, | ||
409 | { KE_KEY, 0x36, {KEY_WWW} }, | ||
410 | { KE_WIFI, 0x30 }, | ||
411 | { KE_BLUETOOTH, 0x44 }, | ||
412 | { KE_END, FE_MAIL_LED | FE_UNTESTED } | ||
325 | }; | 413 | }; |
326 | 414 | ||
327 | static struct key_entry keymap_aopen_1559as[] = { | 415 | static struct key_entry keymap_acer_travelmate_380[] __initdata = { |
328 | { KE_KEY, 0x01, KEY_HELP }, | 416 | { KE_KEY, 0x01, {KEY_HELP} }, |
329 | { KE_KEY, 0x06, KEY_PROG3 }, | 417 | { KE_KEY, 0x02, {KEY_CONFIG} }, |
330 | { KE_KEY, 0x11, KEY_PROG1 }, | 418 | { KE_KEY, 0x03, {KEY_POWER} }, /* not 370 */ |
331 | { KE_KEY, 0x12, KEY_PROG2 }, | 419 | { KE_KEY, 0x11, {KEY_PROG1} }, |
332 | { KE_WIFI, 0x30, 0 }, | 420 | { KE_KEY, 0x12, {KEY_PROG2} }, |
333 | { KE_KEY, 0x31, KEY_MAIL }, | 421 | { KE_KEY, 0x13, {KEY_PROG3} }, |
334 | { KE_KEY, 0x36, KEY_WWW }, | 422 | { KE_KEY, 0x31, {KEY_MAIL} }, |
423 | { KE_KEY, 0x36, {KEY_WWW} }, | ||
424 | { KE_WIFI, 0x30 }, | ||
425 | { KE_END, FE_MAIL_LED | FE_UNTESTED } | ||
426 | }; | ||
427 | |||
428 | /* unusual map */ | ||
429 | static struct key_entry keymap_acer_travelmate_220[] __initdata = { | ||
430 | { KE_KEY, 0x01, {KEY_HELP} }, | ||
431 | { KE_KEY, 0x02, {KEY_CONFIG} }, | ||
432 | { KE_KEY, 0x11, {KEY_MAIL} }, | ||
433 | { KE_KEY, 0x12, {KEY_WWW} }, | ||
434 | { KE_KEY, 0x13, {KEY_PROG2} }, | ||
435 | { KE_KEY, 0x31, {KEY_PROG1} }, | ||
436 | { KE_END, FE_WIFI_LED | FE_UNTESTED } | ||
437 | }; | ||
438 | |||
439 | static struct key_entry keymap_acer_travelmate_230[] __initdata = { | ||
440 | { KE_KEY, 0x01, {KEY_HELP} }, | ||
441 | { KE_KEY, 0x02, {KEY_CONFIG} }, | ||
442 | { KE_KEY, 0x11, {KEY_PROG1} }, | ||
443 | { KE_KEY, 0x12, {KEY_PROG2} }, | ||
444 | { KE_KEY, 0x31, {KEY_MAIL} }, | ||
445 | { KE_KEY, 0x36, {KEY_WWW} }, | ||
446 | { KE_END, FE_WIFI_LED | FE_UNTESTED } | ||
447 | }; | ||
448 | |||
449 | static struct key_entry keymap_acer_travelmate_240[] __initdata = { | ||
450 | { KE_KEY, 0x01, {KEY_HELP} }, | ||
451 | { KE_KEY, 0x02, {KEY_CONFIG} }, | ||
452 | { KE_KEY, 0x03, {KEY_POWER} }, | ||
453 | { KE_KEY, 0x08, {KEY_MUTE} }, | ||
454 | { KE_KEY, 0x31, {KEY_MAIL} }, | ||
455 | { KE_KEY, 0x36, {KEY_WWW} }, | ||
456 | { KE_KEY, 0x11, {KEY_PROG1} }, | ||
457 | { KE_KEY, 0x12, {KEY_PROG2} }, | ||
458 | { KE_BLUETOOTH, 0x44 }, | ||
459 | { KE_WIFI, 0x30 }, | ||
460 | { KE_END, FE_UNTESTED } | ||
461 | }; | ||
462 | |||
463 | static struct key_entry keymap_acer_travelmate_350[] __initdata = { | ||
464 | { KE_KEY, 0x01, {KEY_HELP} }, | ||
465 | { KE_KEY, 0x02, {KEY_CONFIG} }, | ||
466 | { KE_KEY, 0x11, {KEY_PROG1} }, | ||
467 | { KE_KEY, 0x12, {KEY_PROG2} }, | ||
468 | { KE_KEY, 0x13, {KEY_MAIL} }, | ||
469 | { KE_KEY, 0x14, {KEY_PROG3} }, | ||
470 | { KE_KEY, 0x15, {KEY_WWW} }, | ||
471 | { KE_END, FE_MAIL_LED | FE_WIFI_LED | FE_UNTESTED } | ||
472 | }; | ||
473 | |||
474 | static struct key_entry keymap_acer_travelmate_360[] __initdata = { | ||
475 | { KE_KEY, 0x01, {KEY_HELP} }, | ||
476 | { KE_KEY, 0x02, {KEY_CONFIG} }, | ||
477 | { KE_KEY, 0x11, {KEY_PROG1} }, | ||
478 | { KE_KEY, 0x12, {KEY_PROG2} }, | ||
479 | { KE_KEY, 0x13, {KEY_MAIL} }, | ||
480 | { KE_KEY, 0x14, {KEY_PROG3} }, | ||
481 | { KE_KEY, 0x15, {KEY_WWW} }, | ||
482 | { KE_KEY, 0x40, {KEY_WLAN} }, | ||
483 | { KE_END, FE_WIFI_LED | FE_UNTESTED } /* no mail led */ | ||
484 | }; | ||
485 | |||
486 | /* Wifi subsystem only activates the led. Therefore we need to pass | ||
487 | * wifi event as a normal key, then userspace can really change the wifi state. | ||
488 | * TODO we need to export led state to userspace (wifi and mail) */ | ||
489 | static struct key_entry keymap_acer_travelmate_610[] __initdata = { | ||
490 | { KE_KEY, 0x01, {KEY_HELP} }, | ||
491 | { KE_KEY, 0x02, {KEY_CONFIG} }, | ||
492 | { KE_KEY, 0x11, {KEY_PROG1} }, | ||
493 | { KE_KEY, 0x12, {KEY_PROG2} }, | ||
494 | { KE_KEY, 0x13, {KEY_PROG3} }, | ||
495 | { KE_KEY, 0x14, {KEY_MAIL} }, | ||
496 | { KE_KEY, 0x15, {KEY_WWW} }, | ||
497 | { KE_KEY, 0x40, {KEY_WLAN} }, | ||
498 | { KE_END, FE_MAIL_LED | FE_WIFI_LED } | ||
499 | }; | ||
500 | |||
501 | static struct key_entry keymap_acer_travelmate_630[] __initdata = { | ||
502 | { KE_KEY, 0x01, {KEY_HELP} }, | ||
503 | { KE_KEY, 0x02, {KEY_CONFIG} }, | ||
504 | { KE_KEY, 0x03, {KEY_POWER} }, | ||
505 | { KE_KEY, 0x08, {KEY_MUTE} }, /* not 620 */ | ||
506 | { KE_KEY, 0x11, {KEY_PROG1} }, | ||
507 | { KE_KEY, 0x12, {KEY_PROG2} }, | ||
508 | { KE_KEY, 0x13, {KEY_PROG3} }, | ||
509 | { KE_KEY, 0x20, {KEY_VOLUMEUP} }, | ||
510 | { KE_KEY, 0x21, {KEY_VOLUMEDOWN} }, | ||
511 | { KE_KEY, 0x31, {KEY_MAIL} }, | ||
512 | { KE_KEY, 0x36, {KEY_WWW} }, | ||
513 | { KE_WIFI, 0x30 }, | ||
514 | { KE_END, FE_MAIL_LED | FE_UNTESTED } | ||
515 | }; | ||
516 | |||
517 | static struct key_entry keymap_aopen_1559as[] __initdata = { | ||
518 | { KE_KEY, 0x01, {KEY_HELP} }, | ||
519 | { KE_KEY, 0x06, {KEY_PROG3} }, | ||
520 | { KE_KEY, 0x11, {KEY_PROG1} }, | ||
521 | { KE_KEY, 0x12, {KEY_PROG2} }, | ||
522 | { KE_WIFI, 0x30 }, | ||
523 | { KE_KEY, 0x31, {KEY_MAIL} }, | ||
524 | { KE_KEY, 0x36, {KEY_WWW} }, | ||
335 | { KE_END, 0 }, | 525 | { KE_END, 0 }, |
336 | }; | 526 | }; |
337 | 527 | ||
338 | static struct key_entry keymap_fs_amilo_d88x0[] = { | 528 | static struct key_entry keymap_fs_amilo_d88x0[] __initdata = { |
339 | { KE_KEY, 0x01, KEY_HELP }, | 529 | { KE_KEY, 0x01, {KEY_HELP} }, |
340 | { KE_KEY, 0x08, KEY_MUTE }, | 530 | { KE_KEY, 0x08, {KEY_MUTE} }, |
341 | { KE_KEY, 0x31, KEY_MAIL }, | 531 | { KE_KEY, 0x31, {KEY_MAIL} }, |
342 | { KE_KEY, 0x36, KEY_WWW }, | 532 | { KE_KEY, 0x36, {KEY_WWW} }, |
343 | { KE_KEY, 0x11, KEY_PROG1 }, | 533 | { KE_KEY, 0x11, {KEY_PROG1} }, |
344 | { KE_KEY, 0x12, KEY_PROG2 }, | 534 | { KE_KEY, 0x12, {KEY_PROG2} }, |
345 | { KE_KEY, 0x13, KEY_PROG3 }, | 535 | { KE_KEY, 0x13, {KEY_PROG3} }, |
536 | { KE_END, FE_MAIL_LED | FE_WIFI_LED | FE_UNTESTED } | ||
537 | }; | ||
538 | |||
539 | static struct key_entry keymap_wistron_md2900[] __initdata = { | ||
540 | { KE_KEY, 0x01, {KEY_HELP} }, | ||
541 | { KE_KEY, 0x02, {KEY_CONFIG} }, | ||
542 | { KE_KEY, 0x11, {KEY_PROG1} }, | ||
543 | { KE_KEY, 0x12, {KEY_PROG2} }, | ||
544 | { KE_KEY, 0x31, {KEY_MAIL} }, | ||
545 | { KE_KEY, 0x36, {KEY_WWW} }, | ||
546 | { KE_WIFI, 0x30 }, | ||
547 | { KE_END, FE_MAIL_LED | FE_UNTESTED } | ||
548 | }; | ||
549 | |||
550 | static struct key_entry keymap_wistron_md96500[] __initdata = { | ||
551 | { KE_KEY, 0x01, {KEY_HELP} }, | ||
552 | { KE_KEY, 0x02, {KEY_CONFIG} }, | ||
553 | { KE_KEY, 0x05, {KEY_SWITCHVIDEOMODE} }, /* Display selection */ | ||
554 | { KE_KEY, 0x06, {KEY_DISPLAYTOGGLE} }, /* Display on/off */ | ||
555 | { KE_KEY, 0x08, {KEY_MUTE} }, | ||
556 | { KE_KEY, 0x11, {KEY_PROG1} }, | ||
557 | { KE_KEY, 0x12, {KEY_PROG2} }, | ||
558 | { KE_KEY, 0x20, {KEY_VOLUMEUP} }, | ||
559 | { KE_KEY, 0x21, {KEY_VOLUMEDOWN} }, | ||
560 | { KE_KEY, 0x22, {KEY_REWIND} }, | ||
561 | { KE_KEY, 0x23, {KEY_FORWARD} }, | ||
562 | { KE_KEY, 0x24, {KEY_PLAYPAUSE} }, | ||
563 | { KE_KEY, 0x25, {KEY_STOPCD} }, | ||
564 | { KE_KEY, 0x31, {KEY_MAIL} }, | ||
565 | { KE_KEY, 0x36, {KEY_WWW} }, | ||
566 | { KE_WIFI, 0x30 }, | ||
567 | { KE_BLUETOOTH, 0x44 }, | ||
568 | { KE_END, FE_UNTESTED } | ||
569 | }; | ||
570 | |||
571 | static struct key_entry keymap_wistron_generic[] __initdata = { | ||
572 | { KE_KEY, 0x01, {KEY_HELP} }, | ||
573 | { KE_KEY, 0x02, {KEY_CONFIG} }, | ||
574 | { KE_KEY, 0x03, {KEY_POWER} }, | ||
575 | { KE_KEY, 0x05, {KEY_SWITCHVIDEOMODE} }, /* Display selection */ | ||
576 | { KE_KEY, 0x06, {KEY_DISPLAYTOGGLE} }, /* Display on/off */ | ||
577 | { KE_KEY, 0x08, {KEY_MUTE} }, | ||
578 | { KE_KEY, 0x11, {KEY_PROG1} }, | ||
579 | { KE_KEY, 0x12, {KEY_PROG2} }, | ||
580 | { KE_KEY, 0x13, {KEY_PROG3} }, | ||
581 | { KE_KEY, 0x14, {KEY_MAIL} }, | ||
582 | { KE_KEY, 0x15, {KEY_WWW} }, | ||
583 | { KE_KEY, 0x20, {KEY_VOLUMEUP} }, | ||
584 | { KE_KEY, 0x21, {KEY_VOLUMEDOWN} }, | ||
585 | { KE_KEY, 0x22, {KEY_REWIND} }, | ||
586 | { KE_KEY, 0x23, {KEY_FORWARD} }, | ||
587 | { KE_KEY, 0x24, {KEY_PLAYPAUSE} }, | ||
588 | { KE_KEY, 0x25, {KEY_STOPCD} }, | ||
589 | { KE_KEY, 0x31, {KEY_MAIL} }, | ||
590 | { KE_KEY, 0x36, {KEY_WWW} }, | ||
591 | { KE_KEY, 0x37, {KEY_DISPLAYTOGGLE} }, /* Display on/off */ | ||
592 | { KE_KEY, 0x40, {KEY_WLAN} }, | ||
593 | { KE_KEY, 0x49, {KEY_CONFIG} }, | ||
594 | { KE_SW, 0x4a, {.sw = {SW_LID, 1}} }, /* lid close */ | ||
595 | { KE_SW, 0x4b, {.sw = {SW_LID, 0}} }, /* lid open */ | ||
596 | { KE_KEY, 0x6a, {KEY_CONFIG} }, | ||
597 | { KE_KEY, 0x6d, {KEY_POWER} }, | ||
598 | { KE_KEY, 0x71, {KEY_STOPCD} }, | ||
599 | { KE_KEY, 0x72, {KEY_PLAYPAUSE} }, | ||
600 | { KE_KEY, 0x74, {KEY_REWIND} }, | ||
601 | { KE_KEY, 0x78, {KEY_FORWARD} }, | ||
602 | { KE_WIFI, 0x30 }, | ||
603 | { KE_BLUETOOTH, 0x44 }, | ||
346 | { KE_END, 0 } | 604 | { KE_END, 0 } |
347 | }; | 605 | }; |
348 | 606 | ||
@@ -390,6 +648,133 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
390 | }, | 648 | }, |
391 | { | 649 | { |
392 | .callback = dmi_matched, | 650 | .callback = dmi_matched, |
651 | .ident = "Acer Aspire 1600", | ||
652 | .matches = { | ||
653 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
654 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1600"), | ||
655 | }, | ||
656 | .driver_data = keymap_acer_aspire_1600 | ||
657 | }, | ||
658 | { | ||
659 | .callback = dmi_matched, | ||
660 | .ident = "Acer Aspire 3020", | ||
661 | .matches = { | ||
662 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
663 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3020"), | ||
664 | }, | ||
665 | .driver_data = keymap_acer_aspire_5020 | ||
666 | }, | ||
667 | { | ||
668 | .callback = dmi_matched, | ||
669 | .ident = "Acer Aspire 5020", | ||
670 | .matches = { | ||
671 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
672 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5020"), | ||
673 | }, | ||
674 | .driver_data = keymap_acer_aspire_5020 | ||
675 | }, | ||
676 | { | ||
677 | .callback = dmi_matched, | ||
678 | .ident = "Acer TravelMate 2100", | ||
679 | .matches = { | ||
680 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
681 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2100"), | ||
682 | }, | ||
683 | .driver_data = keymap_acer_aspire_5020 | ||
684 | }, | ||
685 | { | ||
686 | .callback = dmi_matched, | ||
687 | .ident = "Acer TravelMate 2410", | ||
688 | .matches = { | ||
689 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
690 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2410"), | ||
691 | }, | ||
692 | .driver_data = keymap_acer_travelmate_2410 | ||
693 | }, | ||
694 | { | ||
695 | .callback = dmi_matched, | ||
696 | .ident = "Acer TravelMate C300", | ||
697 | .matches = { | ||
698 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
699 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C300"), | ||
700 | }, | ||
701 | .driver_data = keymap_acer_travelmate_300 | ||
702 | }, | ||
703 | { | ||
704 | .callback = dmi_matched, | ||
705 | .ident = "Acer TravelMate C100", | ||
706 | .matches = { | ||
707 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
708 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C100"), | ||
709 | }, | ||
710 | .driver_data = keymap_acer_travelmate_300 | ||
711 | }, | ||
712 | { | ||
713 | .callback = dmi_matched, | ||
714 | .ident = "Acer TravelMate C110", | ||
715 | .matches = { | ||
716 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
717 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C110"), | ||
718 | }, | ||
719 | .driver_data = keymap_acer_travelmate_110 | ||
720 | }, | ||
721 | { | ||
722 | .callback = dmi_matched, | ||
723 | .ident = "Acer TravelMate 380", | ||
724 | .matches = { | ||
725 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
726 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 380"), | ||
727 | }, | ||
728 | .driver_data = keymap_acer_travelmate_380 | ||
729 | }, | ||
730 | { | ||
731 | .callback = dmi_matched, | ||
732 | .ident = "Acer TravelMate 370", | ||
733 | .matches = { | ||
734 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
735 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 370"), | ||
736 | }, | ||
737 | .driver_data = keymap_acer_travelmate_380 /* keyboard minus 1 key */ | ||
738 | }, | ||
739 | { | ||
740 | .callback = dmi_matched, | ||
741 | .ident = "Acer TravelMate 220", | ||
742 | .matches = { | ||
743 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
744 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 220"), | ||
745 | }, | ||
746 | .driver_data = keymap_acer_travelmate_220 | ||
747 | }, | ||
748 | { | ||
749 | .callback = dmi_matched, | ||
750 | .ident = "Acer TravelMate 260", | ||
751 | .matches = { | ||
752 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
753 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 260"), | ||
754 | }, | ||
755 | .driver_data = keymap_acer_travelmate_220 | ||
756 | }, | ||
757 | { | ||
758 | .callback = dmi_matched, | ||
759 | .ident = "Acer TravelMate 230", | ||
760 | .matches = { | ||
761 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
762 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 230"), | ||
763 | /* acerhk looks for "TravelMate F4..." ?! */ | ||
764 | }, | ||
765 | .driver_data = keymap_acer_travelmate_230 | ||
766 | }, | ||
767 | { | ||
768 | .callback = dmi_matched, | ||
769 | .ident = "Acer TravelMate 280", | ||
770 | .matches = { | ||
771 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
772 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 280"), | ||
773 | }, | ||
774 | .driver_data = keymap_acer_travelmate_230 | ||
775 | }, | ||
776 | { | ||
777 | .callback = dmi_matched, | ||
393 | .ident = "Acer TravelMate 240", | 778 | .ident = "Acer TravelMate 240", |
394 | .matches = { | 779 | .matches = { |
395 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 780 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
@@ -399,6 +784,15 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
399 | }, | 784 | }, |
400 | { | 785 | { |
401 | .callback = dmi_matched, | 786 | .callback = dmi_matched, |
787 | .ident = "Acer TravelMate 250", | ||
788 | .matches = { | ||
789 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
790 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 250"), | ||
791 | }, | ||
792 | .driver_data = keymap_acer_travelmate_240 | ||
793 | }, | ||
794 | { | ||
795 | .callback = dmi_matched, | ||
402 | .ident = "Acer TravelMate 2424NWXCi", | 796 | .ident = "Acer TravelMate 2424NWXCi", |
403 | .matches = { | 797 | .matches = { |
404 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 798 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
@@ -408,6 +802,51 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
408 | }, | 802 | }, |
409 | { | 803 | { |
410 | .callback = dmi_matched, | 804 | .callback = dmi_matched, |
805 | .ident = "Acer TravelMate 350", | ||
806 | .matches = { | ||
807 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
808 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 350"), | ||
809 | }, | ||
810 | .driver_data = keymap_acer_travelmate_350 | ||
811 | }, | ||
812 | { | ||
813 | .callback = dmi_matched, | ||
814 | .ident = "Acer TravelMate 360", | ||
815 | .matches = { | ||
816 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
817 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), | ||
818 | }, | ||
819 | .driver_data = keymap_acer_travelmate_360 | ||
820 | }, | ||
821 | { | ||
822 | .callback = dmi_matched, | ||
823 | .ident = "Acer TravelMate 610", | ||
824 | .matches = { | ||
825 | DMI_MATCH(DMI_SYS_VENDOR, "ACER"), | ||
826 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 610"), | ||
827 | }, | ||
828 | .driver_data = keymap_acer_travelmate_610 | ||
829 | }, | ||
830 | { | ||
831 | .callback = dmi_matched, | ||
832 | .ident = "Acer TravelMate 620", | ||
833 | .matches = { | ||
834 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
835 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 620"), | ||
836 | }, | ||
837 | .driver_data = keymap_acer_travelmate_630 | ||
838 | }, | ||
839 | { | ||
840 | .callback = dmi_matched, | ||
841 | .ident = "Acer TravelMate 630", | ||
842 | .matches = { | ||
843 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
844 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 630"), | ||
845 | }, | ||
846 | .driver_data = keymap_acer_travelmate_630 | ||
847 | }, | ||
848 | { | ||
849 | .callback = dmi_matched, | ||
411 | .ident = "AOpen 1559AS", | 850 | .ident = "AOpen 1559AS", |
412 | .matches = { | 851 | .matches = { |
413 | DMI_MATCH(DMI_PRODUCT_NAME, "E2U"), | 852 | DMI_MATCH(DMI_PRODUCT_NAME, "E2U"), |
@@ -426,6 +865,51 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
426 | }, | 865 | }, |
427 | { | 866 | { |
428 | .callback = dmi_matched, | 867 | .callback = dmi_matched, |
868 | .ident = "Medion MD 40100", | ||
869 | .matches = { | ||
870 | DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), | ||
871 | DMI_MATCH(DMI_PRODUCT_NAME, "WID2000"), | ||
872 | }, | ||
873 | .driver_data = keymap_wistron_md40100 | ||
874 | }, | ||
875 | { | ||
876 | .callback = dmi_matched, | ||
877 | .ident = "Medion MD 2900", | ||
878 | .matches = { | ||
879 | DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), | ||
880 | DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2000"), | ||
881 | }, | ||
882 | .driver_data = keymap_wistron_md2900 | ||
883 | }, | ||
884 | { | ||
885 | .callback = dmi_matched, | ||
886 | .ident = "Medion MD 96500", | ||
887 | .matches = { | ||
888 | DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"), | ||
889 | DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2040"), | ||
890 | }, | ||
891 | .driver_data = keymap_wistron_md96500 | ||
892 | }, | ||
893 | { | ||
894 | .callback = dmi_matched, | ||
895 | .ident = "Medion MD 95400", | ||
896 | .matches = { | ||
897 | DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"), | ||
898 | DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2050"), | ||
899 | }, | ||
900 | .driver_data = keymap_wistron_md96500 | ||
901 | }, | ||
902 | { | ||
903 | .callback = dmi_matched, | ||
904 | .ident = "Fujitsu Siemens Amilo D7820", | ||
905 | .matches = { | ||
906 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), /* not sure */ | ||
907 | DMI_MATCH(DMI_PRODUCT_NAME, "Amilo D"), | ||
908 | }, | ||
909 | .driver_data = keymap_fs_amilo_d88x0 | ||
910 | }, | ||
911 | { | ||
912 | .callback = dmi_matched, | ||
429 | .ident = "Fujitsu Siemens Amilo D88x0", | 913 | .ident = "Fujitsu Siemens Amilo D88x0", |
430 | .matches = { | 914 | .matches = { |
431 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 915 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
@@ -436,17 +920,39 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
436 | { NULL, } | 920 | { NULL, } |
437 | }; | 921 | }; |
438 | 922 | ||
923 | /* Copy the good keymap, as the original ones are free'd */ | ||
924 | static int __init copy_keymap(void) | ||
925 | { | ||
926 | const struct key_entry *key; | ||
927 | struct key_entry *new_keymap; | ||
928 | unsigned int length = 1; | ||
929 | |||
930 | for (key = keymap; key->type != KE_END; key++) | ||
931 | length++; | ||
932 | |||
933 | new_keymap = kmalloc(length * sizeof(struct key_entry), GFP_KERNEL); | ||
934 | if (!new_keymap) | ||
935 | return -ENOMEM; | ||
936 | |||
937 | memcpy(new_keymap, keymap, length * sizeof(struct key_entry)); | ||
938 | keymap = new_keymap; | ||
939 | |||
940 | return 0; | ||
941 | } | ||
942 | |||
439 | static int __init select_keymap(void) | 943 | static int __init select_keymap(void) |
440 | { | 944 | { |
945 | dmi_check_system(dmi_ids); | ||
441 | if (keymap_name != NULL) { | 946 | if (keymap_name != NULL) { |
442 | if (strcmp (keymap_name, "1557/MS2141") == 0) | 947 | if (strcmp (keymap_name, "1557/MS2141") == 0) |
443 | keymap = keymap_wistron_ms2141; | 948 | keymap = keymap_wistron_ms2141; |
949 | else if (strcmp (keymap_name, "generic") == 0) | ||
950 | keymap = keymap_wistron_generic; | ||
444 | else { | 951 | else { |
445 | printk(KERN_ERR "wistron_btns: Keymap unknown\n"); | 952 | printk(KERN_ERR "wistron_btns: Keymap unknown\n"); |
446 | return -EINVAL; | 953 | return -EINVAL; |
447 | } | 954 | } |
448 | } | 955 | } |
449 | dmi_check_system(dmi_ids); | ||
450 | if (keymap == NULL) { | 956 | if (keymap == NULL) { |
451 | if (!force) { | 957 | if (!force) { |
452 | printk(KERN_ERR "wistron_btns: System unknown\n"); | 958 | printk(KERN_ERR "wistron_btns: System unknown\n"); |
@@ -454,7 +960,8 @@ static int __init select_keymap(void) | |||
454 | } | 960 | } |
455 | keymap = keymap_empty; | 961 | keymap = keymap_empty; |
456 | } | 962 | } |
457 | return 0; | 963 | |
964 | return copy_keymap(); | ||
458 | } | 965 | } |
459 | 966 | ||
460 | /* Input layer interface */ | 967 | /* Input layer interface */ |
@@ -476,12 +983,28 @@ static int __devinit setup_input_dev(void) | |||
476 | input_dev->cdev.dev = &wistron_device->dev; | 983 | input_dev->cdev.dev = &wistron_device->dev; |
477 | 984 | ||
478 | for (key = keymap; key->type != KE_END; key++) { | 985 | for (key = keymap; key->type != KE_END; key++) { |
479 | if (key->type == KE_KEY) { | 986 | switch (key->type) { |
480 | input_dev->evbit[LONG(EV_KEY)] = BIT(EV_KEY); | 987 | case KE_KEY: |
481 | set_bit(key->keycode, input_dev->keybit); | 988 | set_bit(EV_KEY, input_dev->evbit); |
989 | set_bit(key->keycode, input_dev->keybit); | ||
990 | break; | ||
991 | |||
992 | case KE_SW: | ||
993 | set_bit(EV_SW, input_dev->evbit); | ||
994 | set_bit(key->sw.code, input_dev->swbit); | ||
995 | break; | ||
996 | |||
997 | default: | ||
998 | ; | ||
482 | } | 999 | } |
483 | } | 1000 | } |
484 | 1001 | ||
1002 | /* reads information flags on KE_END */ | ||
1003 | if (key->code & FE_UNTESTED) | ||
1004 | printk(KERN_WARNING "Untested laptop multimedia keys, " | ||
1005 | "please report success or failure to eric.piel" | ||
1006 | "@tremplin-utc.net\n"); | ||
1007 | |||
485 | error = input_register_device(input_dev); | 1008 | error = input_register_device(input_dev); |
486 | if (error) { | 1009 | if (error) { |
487 | input_free_device(input_dev); | 1010 | input_free_device(input_dev); |
@@ -499,6 +1022,12 @@ static void report_key(unsigned keycode) | |||
499 | input_sync(input_dev); | 1022 | input_sync(input_dev); |
500 | } | 1023 | } |
501 | 1024 | ||
1025 | static void report_switch(unsigned code, int value) | ||
1026 | { | ||
1027 | input_report_switch(input_dev, code, value); | ||
1028 | input_sync(input_dev); | ||
1029 | } | ||
1030 | |||
502 | /* Driver core */ | 1031 | /* Driver core */ |
503 | 1032 | ||
504 | static int wifi_enabled; | 1033 | static int wifi_enabled; |
@@ -519,6 +1048,10 @@ static void handle_key(u8 code) | |||
519 | report_key(key->keycode); | 1048 | report_key(key->keycode); |
520 | break; | 1049 | break; |
521 | 1050 | ||
1051 | case KE_SW: | ||
1052 | report_switch(key->sw.code, key->sw.value); | ||
1053 | break; | ||
1054 | |||
522 | case KE_WIFI: | 1055 | case KE_WIFI: |
523 | if (have_wifi) { | 1056 | if (have_wifi) { |
524 | wifi_enabled = !wifi_enabled; | 1057 | wifi_enabled = !wifi_enabled; |
@@ -534,6 +1067,7 @@ static void handle_key(u8 code) | |||
534 | break; | 1067 | break; |
535 | 1068 | ||
536 | case KE_END: | 1069 | case KE_END: |
1070 | break; | ||
537 | default: | 1071 | default: |
538 | BUG(); | 1072 | BUG(); |
539 | } | 1073 | } |
@@ -690,6 +1224,7 @@ static void __exit wb_module_exit(void) | |||
690 | platform_device_unregister(wistron_device); | 1224 | platform_device_unregister(wistron_device); |
691 | platform_driver_unregister(&wistron_driver); | 1225 | platform_driver_unregister(&wistron_driver); |
692 | unmap_bios(); | 1226 | unmap_bios(); |
1227 | kfree(keymap); | ||
693 | } | 1228 | } |
694 | 1229 | ||
695 | module_init(wb_module_init); | 1230 | module_init(wb_module_init); |
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index 35d998c3e578..81dd8c7211a7 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig | |||
@@ -37,6 +37,65 @@ config MOUSE_PS2 | |||
37 | To compile this driver as a module, choose M here: the | 37 | To compile this driver as a module, choose M here: the |
38 | module will be called psmouse. | 38 | module will be called psmouse. |
39 | 39 | ||
40 | config MOUSE_PS2_ALPS | ||
41 | bool "ALPS PS/2 mouse protocol extension" if EMBEDDED | ||
42 | default y | ||
43 | depends on MOUSE_PS2 | ||
44 | ---help--- | ||
45 | Say Y here if you have an ALPS PS/2 touchpad connected to | ||
46 | your system. | ||
47 | |||
48 | If unsure, say Y. | ||
49 | |||
50 | config MOUSE_PS2_LOGIPS2PP | ||
51 | bool "Logictech PS/2++ mouse protocol extension" if EMBEDDED | ||
52 | default y | ||
53 | depends on MOUSE_PS2 | ||
54 | ---help--- | ||
55 | Say Y here if you have a Logictech PS/2++ mouse connected to | ||
56 | your system. | ||
57 | |||
58 | If unsure, say Y. | ||
59 | |||
60 | config MOUSE_PS2_SYNAPTICS | ||
61 | bool "Synaptics PS/2 mouse protocol extension" if EMBEDDED | ||
62 | default y | ||
63 | depends on MOUSE_PS2 | ||
64 | ---help--- | ||
65 | Say Y here if you have a Synaptics PS/2 TouchPad connected to | ||
66 | your system. | ||
67 | |||
68 | If unsure, say Y. | ||
69 | |||
70 | config MOUSE_PS2_LIFEBOOK | ||
71 | bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EMBEDDED | ||
72 | default y | ||
73 | depends on MOUSE_PS2 | ||
74 | ---help--- | ||
75 | Say Y here if you have a Fujitsu B-series Lifebook PS/2 | ||
76 | TouchScreen connected to your system. | ||
77 | |||
78 | If unsure, say Y. | ||
79 | |||
80 | config MOUSE_PS2_TRACKPOINT | ||
81 | bool "IBM Trackpoint PS/2 mouse protocol extension" if EMBEDDED | ||
82 | default y | ||
83 | depends on MOUSE_PS2 | ||
84 | ---help--- | ||
85 | Say Y here if you have an IBM Trackpoint PS/2 mouse connected | ||
86 | to your system. | ||
87 | |||
88 | If unsure, say Y. | ||
89 | |||
90 | config MOUSE_PS2_TOUCHKIT | ||
91 | bool "eGalax TouchKit PS/2 protocol extension" | ||
92 | depends on MOUSE_PS2 | ||
93 | ---help--- | ||
94 | Say Y here if you have an eGalax TouchKit PS/2 touchscreen | ||
95 | connected to your system. | ||
96 | |||
97 | If unsure, say N. | ||
98 | |||
40 | config MOUSE_SERIAL | 99 | config MOUSE_SERIAL |
41 | tristate "Serial mouse" | 100 | tristate "Serial mouse" |
42 | select SERIO | 101 | select SERIO |
@@ -96,6 +155,17 @@ config MOUSE_AMIGA | |||
96 | To compile this driver as a module, choose M here: the | 155 | To compile this driver as a module, choose M here: the |
97 | module will be called amimouse. | 156 | module will be called amimouse. |
98 | 157 | ||
158 | config MOUSE_ATARI | ||
159 | tristate "Atari mouse" | ||
160 | depends on ATARI | ||
161 | select ATARI_KBD_CORE | ||
162 | help | ||
163 | Say Y here if you have an Atari and want its native mouse | ||
164 | supported by the kernel. | ||
165 | |||
166 | To compile this driver as a module, choose M here: the | ||
167 | module will be called atarimouse. | ||
168 | |||
99 | config MOUSE_RISCPC | 169 | config MOUSE_RISCPC |
100 | tristate "Acorn RiscPC mouse" | 170 | tristate "Acorn RiscPC mouse" |
101 | depends on ARCH_ACORN | 171 | depends on ARCH_ACORN |
@@ -118,7 +188,7 @@ config MOUSE_VSXXXAA | |||
118 | digitizer (VSXXX-AB) DEC produced. | 188 | digitizer (VSXXX-AB) DEC produced. |
119 | 189 | ||
120 | config MOUSE_HIL | 190 | config MOUSE_HIL |
121 | tristate "HIL pointers (mice etc)." | 191 | tristate "HIL pointers (mice etc)." |
122 | depends on GSC || HP300 | 192 | depends on GSC || HP300 |
123 | select HP_SDC | 193 | select HP_SDC |
124 | select HIL_MLC | 194 | select HIL_MLC |
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile index 21a1de61a79b..6a8f622927f2 100644 --- a/drivers/input/mouse/Makefile +++ b/drivers/input/mouse/Makefile | |||
@@ -5,6 +5,7 @@ | |||
5 | # Each configuration option enables a list of files. | 5 | # Each configuration option enables a list of files. |
6 | 6 | ||
7 | obj-$(CONFIG_MOUSE_AMIGA) += amimouse.o | 7 | obj-$(CONFIG_MOUSE_AMIGA) += amimouse.o |
8 | obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o | ||
8 | obj-$(CONFIG_MOUSE_RISCPC) += rpcmouse.o | 9 | obj-$(CONFIG_MOUSE_RISCPC) += rpcmouse.o |
9 | obj-$(CONFIG_MOUSE_INPORT) += inport.o | 10 | obj-$(CONFIG_MOUSE_INPORT) += inport.o |
10 | obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o | 11 | obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o |
@@ -14,4 +15,10 @@ obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o | |||
14 | obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o | 15 | obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o |
15 | obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o | 16 | obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o |
16 | 17 | ||
17 | psmouse-objs := psmouse-base.o alps.o logips2pp.o synaptics.o lifebook.o trackpoint.o | 18 | psmouse-objs := psmouse-base.o synaptics.o |
19 | |||
20 | psmouse-$(CONFIG_MOUSE_PS2_ALPS) += alps.o | ||
21 | psmouse-$(CONFIG_MOUSE_PS2_LOGIPS2PP) += logips2pp.o | ||
22 | psmouse-$(CONFIG_MOUSE_PS2_LIFEBOOK) += lifebook.o | ||
23 | psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o | ||
24 | psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT) += touchkit_ps2.o | ||
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 4e71a66fc7fc..cf3e4664e72b 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -424,14 +424,15 @@ int alps_init(struct psmouse *psmouse) | |||
424 | struct input_dev *dev1 = psmouse->dev, *dev2; | 424 | struct input_dev *dev1 = psmouse->dev, *dev2; |
425 | int version; | 425 | int version; |
426 | 426 | ||
427 | psmouse->private = priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL); | 427 | priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL); |
428 | dev2 = input_allocate_device(); | 428 | dev2 = input_allocate_device(); |
429 | if (!priv || !dev2) | 429 | if (!priv || !dev2) |
430 | goto init_fail; | 430 | goto init_fail; |
431 | 431 | ||
432 | priv->dev2 = dev2; | 432 | priv->dev2 = dev2; |
433 | 433 | ||
434 | if (!(priv->i = alps_get_model(psmouse, &version))) | 434 | priv->i = alps_get_model(psmouse, &version); |
435 | if (!priv->i) | ||
435 | goto init_fail; | 436 | goto init_fail; |
436 | 437 | ||
437 | if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1)) | 438 | if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1)) |
@@ -480,7 +481,8 @@ int alps_init(struct psmouse *psmouse) | |||
480 | dev2->relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y); | 481 | dev2->relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y); |
481 | dev2->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); | 482 | dev2->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); |
482 | 483 | ||
483 | input_register_device(priv->dev2); | 484 | if (input_register_device(priv->dev2)) |
485 | goto init_fail; | ||
484 | 486 | ||
485 | psmouse->protocol_handler = alps_process_byte; | 487 | psmouse->protocol_handler = alps_process_byte; |
486 | psmouse->poll = alps_poll; | 488 | psmouse->poll = alps_poll; |
@@ -491,9 +493,11 @@ int alps_init(struct psmouse *psmouse) | |||
491 | /* We are having trouble resyncing ALPS touchpads so disable it for now */ | 493 | /* We are having trouble resyncing ALPS touchpads so disable it for now */ |
492 | psmouse->resync_time = 0; | 494 | psmouse->resync_time = 0; |
493 | 495 | ||
496 | psmouse->private = priv; | ||
494 | return 0; | 497 | return 0; |
495 | 498 | ||
496 | init_fail: | 499 | init_fail: |
500 | psmouse_reset(psmouse); | ||
497 | input_free_device(dev2); | 501 | input_free_device(dev2); |
498 | kfree(priv); | 502 | kfree(priv); |
499 | return -1; | 503 | return -1; |
@@ -504,7 +508,8 @@ int alps_detect(struct psmouse *psmouse, int set_properties) | |||
504 | int version; | 508 | int version; |
505 | const struct alps_model_info *model; | 509 | const struct alps_model_info *model; |
506 | 510 | ||
507 | if (!(model = alps_get_model(psmouse, &version))) | 511 | model = alps_get_model(psmouse, &version); |
512 | if (!model) | ||
508 | return -1; | 513 | return -1; |
509 | 514 | ||
510 | if (set_properties) { | 515 | if (set_properties) { |
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h index 69db7325a494..4bbddc99962b 100644 --- a/drivers/input/mouse/alps.h +++ b/drivers/input/mouse/alps.h | |||
@@ -12,9 +12,6 @@ | |||
12 | #ifndef _ALPS_H | 12 | #ifndef _ALPS_H |
13 | #define _ALPS_H | 13 | #define _ALPS_H |
14 | 14 | ||
15 | int alps_detect(struct psmouse *psmouse, int set_properties); | ||
16 | int alps_init(struct psmouse *psmouse); | ||
17 | |||
18 | struct alps_model_info { | 15 | struct alps_model_info { |
19 | unsigned char signature[3]; | 16 | unsigned char signature[3]; |
20 | unsigned char byte0, mask0; | 17 | unsigned char byte0, mask0; |
@@ -23,10 +20,23 @@ struct alps_model_info { | |||
23 | 20 | ||
24 | struct alps_data { | 21 | struct alps_data { |
25 | struct input_dev *dev2; /* Relative device */ | 22 | struct input_dev *dev2; /* Relative device */ |
26 | char name[32]; /* Name */ | ||
27 | char phys[32]; /* Phys */ | 23 | char phys[32]; /* Phys */ |
28 | const struct alps_model_info *i;/* Info */ | 24 | const struct alps_model_info *i;/* Info */ |
29 | int prev_fin; /* Finger bit from previous packet */ | 25 | int prev_fin; /* Finger bit from previous packet */ |
30 | }; | 26 | }; |
31 | 27 | ||
28 | #ifdef CONFIG_MOUSE_PS2_ALPS | ||
29 | int alps_detect(struct psmouse *psmouse, int set_properties); | ||
30 | int alps_init(struct psmouse *psmouse); | ||
31 | #else | ||
32 | inline int alps_detect(struct psmouse *psmouse, int set_properties) | ||
33 | { | ||
34 | return -ENOSYS; | ||
35 | } | ||
36 | inline int alps_init(struct psmouse *psmouse) | ||
37 | { | ||
38 | return -ENOSYS; | ||
39 | } | ||
40 | #endif /* CONFIG_MOUSE_PS2_ALPS */ | ||
41 | |||
32 | #endif | 42 | #endif |
diff --git a/drivers/input/mouse/atarimouse.c b/drivers/input/mouse/atarimouse.c new file mode 100644 index 000000000000..43ab6566fb65 --- /dev/null +++ b/drivers/input/mouse/atarimouse.c | |||
@@ -0,0 +1,160 @@ | |||
1 | /* | ||
2 | * Atari mouse driver for Linux/m68k | ||
3 | * | ||
4 | * Copyright (c) 2005 Michael Schmitz | ||
5 | * | ||
6 | * Based on: | ||
7 | * Amiga mouse driver for Linux/m68k | ||
8 | * | ||
9 | * Copyright (c) 2000-2002 Vojtech Pavlik | ||
10 | * | ||
11 | */ | ||
12 | /* | ||
13 | * The low level init and interrupt stuff is handled in arch/mm68k/atari/atakeyb.c | ||
14 | * (the keyboard ACIA also handles the mouse and joystick data, and the keyboard | ||
15 | * interrupt is shared with the MIDI ACIA so MIDI data also get handled there). | ||
16 | * This driver only deals with handing key events off to the input layer. | ||
17 | * | ||
18 | * Largely based on the old: | ||
19 | * | ||
20 | * Atari Mouse Driver for Linux | ||
21 | * by Robert de Vries (robert@and.nl) 19Jul93 | ||
22 | * | ||
23 | * 16 Nov 1994 Andreas Schwab | ||
24 | * Compatibility with busmouse | ||
25 | * Support for three button mouse (shamelessly stolen from MiNT) | ||
26 | * third button wired to one of the joystick directions on joystick 1 | ||
27 | * | ||
28 | * 1996/02/11 Andreas Schwab | ||
29 | * Module support | ||
30 | * Allow multiple open's | ||
31 | * | ||
32 | * Converted to use new generic busmouse code. 5 Apr 1998 | ||
33 | * Russell King <rmk@arm.uk.linux.org> | ||
34 | */ | ||
35 | |||
36 | |||
37 | /* | ||
38 | * This program is free software; you can redistribute it and/or modify it | ||
39 | * under the terms of the GNU General Public License version 2 as published by | ||
40 | * the Free Software Foundation | ||
41 | */ | ||
42 | |||
43 | #include <linux/module.h> | ||
44 | #include <linux/init.h> | ||
45 | #include <linux/input.h> | ||
46 | #include <linux/interrupt.h> | ||
47 | |||
48 | #include <asm/irq.h> | ||
49 | #include <asm/setup.h> | ||
50 | #include <asm/system.h> | ||
51 | #include <asm/uaccess.h> | ||
52 | #include <asm/atarihw.h> | ||
53 | #include <asm/atarikb.h> | ||
54 | #include <asm/atariints.h> | ||
55 | |||
56 | MODULE_AUTHOR("Michael Schmitz <schmitz@biophys.uni-duesseldorf.de>"); | ||
57 | MODULE_DESCRIPTION("Atari mouse driver"); | ||
58 | MODULE_LICENSE("GPL"); | ||
59 | |||
60 | static int mouse_threshold[2] = {2,2}; | ||
61 | |||
62 | #ifdef __MODULE__ | ||
63 | MODULE_PARM(mouse_threshold, "2i"); | ||
64 | #endif | ||
65 | #ifdef FIXED_ATARI_JOYSTICK | ||
66 | extern int atari_mouse_buttons; | ||
67 | #endif | ||
68 | static int atamouse_used = 0; | ||
69 | |||
70 | static struct input_dev *atamouse_dev; | ||
71 | |||
72 | static void atamouse_interrupt(char *buf) | ||
73 | { | ||
74 | int buttons, dx, dy; | ||
75 | |||
76 | /* ikbd_mouse_disable(); */ | ||
77 | |||
78 | buttons = (buf[0] & 1) | ((buf[0] & 2) << 1); | ||
79 | #ifdef FIXED_ATARI_JOYSTICK | ||
80 | buttons |= atari_mouse_buttons & 2; | ||
81 | atari_mouse_buttons = buttons; | ||
82 | #endif | ||
83 | /* ikbd_mouse_rel_pos(); */ | ||
84 | |||
85 | /* only relative events get here */ | ||
86 | dx = buf[1]; | ||
87 | dy = -buf[2]; | ||
88 | |||
89 | input_report_rel(atamouse_dev, REL_X, dx); | ||
90 | input_report_rel(atamouse_dev, REL_Y, dy); | ||
91 | |||
92 | input_report_key(atamouse_dev, BTN_LEFT, buttons & 0x1); | ||
93 | input_report_key(atamouse_dev, BTN_MIDDLE, buttons & 0x2); | ||
94 | input_report_key(atamouse_dev, BTN_RIGHT, buttons & 0x4); | ||
95 | |||
96 | input_sync(atamouse_dev); | ||
97 | |||
98 | return; | ||
99 | } | ||
100 | |||
101 | static int atamouse_open(struct input_dev *dev) | ||
102 | { | ||
103 | if (atamouse_used++) | ||
104 | return 0; | ||
105 | |||
106 | #ifdef FIXED_ATARI_JOYSTICK | ||
107 | atari_mouse_buttons = 0; | ||
108 | #endif | ||
109 | ikbd_mouse_y0_top(); | ||
110 | ikbd_mouse_thresh(mouse_threshold[0], mouse_threshold[1]); | ||
111 | ikbd_mouse_rel_pos(); | ||
112 | atari_input_mouse_interrupt_hook = atamouse_interrupt; | ||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | static void atamouse_close(struct input_dev *dev) | ||
117 | { | ||
118 | if (!--atamouse_used) { | ||
119 | ikbd_mouse_disable(); | ||
120 | atari_mouse_interrupt_hook = NULL; | ||
121 | } | ||
122 | } | ||
123 | |||
124 | static int __init atamouse_init(void) | ||
125 | { | ||
126 | if (!MACH_IS_ATARI || !ATARIHW_PRESENT(ST_MFP)) | ||
127 | return -ENODEV; | ||
128 | |||
129 | if (!(atamouse_dev = input_allocate_device())) | ||
130 | return -ENOMEM; | ||
131 | |||
132 | if (!(atari_keyb_init())) | ||
133 | return -ENODEV; | ||
134 | |||
135 | atamouse_dev->name = "Atari mouse"; | ||
136 | atamouse_dev->phys = "atamouse/input0"; | ||
137 | atamouse_dev->id.bustype = BUS_ATARI; | ||
138 | atamouse_dev->id.vendor = 0x0001; | ||
139 | atamouse_dev->id.product = 0x0002; | ||
140 | atamouse_dev->id.version = 0x0100; | ||
141 | |||
142 | atamouse_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); | ||
143 | atamouse_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); | ||
144 | atamouse_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); | ||
145 | atamouse_dev->open = atamouse_open; | ||
146 | atamouse_dev->close = atamouse_close; | ||
147 | |||
148 | input_register_device(atamouse_dev); | ||
149 | |||
150 | printk(KERN_INFO "input: %s at keyboard ACIA\n", atamouse_dev->name); | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | static void __exit atamouse_exit(void) | ||
155 | { | ||
156 | input_unregister_device(atamouse_dev); | ||
157 | } | ||
158 | |||
159 | module_init(atamouse_init); | ||
160 | module_exit(atamouse_exit); | ||
diff --git a/drivers/input/mouse/hil_ptr.c b/drivers/input/mouse/hil_ptr.c index bfb174fe3230..449bf4dcbbcc 100644 --- a/drivers/input/mouse/hil_ptr.c +++ b/drivers/input/mouse/hil_ptr.c | |||
@@ -88,10 +88,12 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) | |||
88 | idx = ptr->idx4/4; | 88 | idx = ptr->idx4/4; |
89 | p = data[idx - 1]; | 89 | p = data[idx - 1]; |
90 | 90 | ||
91 | if ((p & ~HIL_CMDCT_POL) == | 91 | if ((p & ~HIL_CMDCT_POL) == |
92 | (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) goto report; | 92 | (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) |
93 | if ((p & ~HIL_CMDCT_RPL) == | 93 | goto report; |
94 | (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL)) goto report; | 94 | if ((p & ~HIL_CMDCT_RPL) == |
95 | (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL)) | ||
96 | goto report; | ||
95 | 97 | ||
96 | /* Not a poll response. See if we are loading config records. */ | 98 | /* Not a poll response. See if we are loading config records. */ |
97 | switch (p & HIL_PKT_DATA_MASK) { | 99 | switch (p & HIL_PKT_DATA_MASK) { |
@@ -101,27 +103,32 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) | |||
101 | for (; i < HIL_PTR_MAX_LENGTH; i++) | 103 | for (; i < HIL_PTR_MAX_LENGTH; i++) |
102 | ptr->idd[i] = 0; | 104 | ptr->idd[i] = 0; |
103 | break; | 105 | break; |
106 | |||
104 | case HIL_CMD_RSC: | 107 | case HIL_CMD_RSC: |
105 | for (i = 0; i < idx; i++) | 108 | for (i = 0; i < idx; i++) |
106 | ptr->rsc[i] = ptr->data[i] & HIL_PKT_DATA_MASK; | 109 | ptr->rsc[i] = ptr->data[i] & HIL_PKT_DATA_MASK; |
107 | for (; i < HIL_PTR_MAX_LENGTH; i++) | 110 | for (; i < HIL_PTR_MAX_LENGTH; i++) |
108 | ptr->rsc[i] = 0; | 111 | ptr->rsc[i] = 0; |
109 | break; | 112 | break; |
113 | |||
110 | case HIL_CMD_EXD: | 114 | case HIL_CMD_EXD: |
111 | for (i = 0; i < idx; i++) | 115 | for (i = 0; i < idx; i++) |
112 | ptr->exd[i] = ptr->data[i] & HIL_PKT_DATA_MASK; | 116 | ptr->exd[i] = ptr->data[i] & HIL_PKT_DATA_MASK; |
113 | for (; i < HIL_PTR_MAX_LENGTH; i++) | 117 | for (; i < HIL_PTR_MAX_LENGTH; i++) |
114 | ptr->exd[i] = 0; | 118 | ptr->exd[i] = 0; |
115 | break; | 119 | break; |
120 | |||
116 | case HIL_CMD_RNM: | 121 | case HIL_CMD_RNM: |
117 | for (i = 0; i < idx; i++) | 122 | for (i = 0; i < idx; i++) |
118 | ptr->rnm[i] = ptr->data[i] & HIL_PKT_DATA_MASK; | 123 | ptr->rnm[i] = ptr->data[i] & HIL_PKT_DATA_MASK; |
119 | for (; i < HIL_PTR_MAX_LENGTH + 1; i++) | 124 | for (; i < HIL_PTR_MAX_LENGTH + 1; i++) |
120 | ptr->rnm[i] = '\0'; | 125 | ptr->rnm[i] = 0; |
121 | break; | 126 | break; |
127 | |||
122 | default: | 128 | default: |
123 | /* These occur when device isn't present */ | 129 | /* These occur when device isn't present */ |
124 | if (p == (HIL_ERR_INT | HIL_PKT_CMD)) break; | 130 | if (p == (HIL_ERR_INT | HIL_PKT_CMD)) |
131 | break; | ||
125 | /* Anything else we'd like to know about. */ | 132 | /* Anything else we'd like to know about. */ |
126 | printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p); | 133 | printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p); |
127 | break; | 134 | break; |
@@ -130,7 +137,8 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) | |||
130 | 137 | ||
131 | report: | 138 | report: |
132 | if ((p & HIL_CMDCT_POL) != idx - 1) { | 139 | if ((p & HIL_CMDCT_POL) != idx - 1) { |
133 | printk(KERN_WARNING PREFIX "Malformed poll packet %x (idx = %i)\n", p, idx); | 140 | printk(KERN_WARNING PREFIX |
141 | "Malformed poll packet %x (idx = %i)\n", p, idx); | ||
134 | goto out; | 142 | goto out; |
135 | } | 143 | } |
136 | 144 | ||
@@ -139,7 +147,7 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) | |||
139 | laxis += i; | 147 | laxis += i; |
140 | 148 | ||
141 | ax16 = ptr->idd[1] & HIL_IDD_HEADER_16BIT; /* 8 or 16bit resolution */ | 149 | ax16 = ptr->idd[1] & HIL_IDD_HEADER_16BIT; /* 8 or 16bit resolution */ |
142 | absdev = ptr->idd[1] & HIL_IDD_HEADER_ABS; | 150 | absdev = ptr->idd[1] & HIL_IDD_HEADER_ABS; |
143 | 151 | ||
144 | for (cnt = 1; i < laxis; i++) { | 152 | for (cnt = 1; i < laxis; i++) { |
145 | unsigned int lo,hi,val; | 153 | unsigned int lo,hi,val; |
@@ -157,7 +165,8 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) | |||
157 | input_report_abs(dev, ABS_X + i, val); | 165 | input_report_abs(dev, ABS_X + i, val); |
158 | } else { | 166 | } else { |
159 | val = (int) (((int8_t)lo) | ((int8_t)hi<<8)); | 167 | val = (int) (((int8_t)lo) | ((int8_t)hi<<8)); |
160 | if (i%3) val *= -1; | 168 | if (i%3) |
169 | val *= -1; | ||
161 | input_report_rel(dev, REL_X + i, val); | 170 | input_report_rel(dev, REL_X + i, val); |
162 | } | 171 | } |
163 | } | 172 | } |
@@ -168,10 +177,11 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) | |||
168 | btn = ptr->data[cnt++]; | 177 | btn = ptr->data[cnt++]; |
169 | up = btn & 1; | 178 | up = btn & 1; |
170 | btn &= 0xfe; | 179 | btn &= 0xfe; |
171 | if (btn == 0x8e) { | 180 | if (btn == 0x8e) |
172 | continue; /* TODO: proximity == touch? */ | 181 | continue; /* TODO: proximity == touch? */ |
173 | } | 182 | else |
174 | else if ((btn > 0x8c) || (btn < 0x80)) continue; | 183 | if ((btn > 0x8c) || (btn < 0x80)) |
184 | continue; | ||
175 | btn = (btn - 0x80) >> 1; | 185 | btn = (btn - 0x80) >> 1; |
176 | btn = ptr->btnmap[btn]; | 186 | btn = ptr->btnmap[btn]; |
177 | input_report_key(dev, btn, !up); | 187 | input_report_key(dev, btn, !up); |
@@ -182,14 +192,14 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) | |||
182 | up(&ptr->sem); | 192 | up(&ptr->sem); |
183 | } | 193 | } |
184 | 194 | ||
185 | static void hil_ptr_process_err(struct hil_ptr *ptr) { | 195 | static void hil_ptr_process_err(struct hil_ptr *ptr) |
196 | { | ||
186 | printk(KERN_WARNING PREFIX "errored HIL packet\n"); | 197 | printk(KERN_WARNING PREFIX "errored HIL packet\n"); |
187 | ptr->idx4 = 0; | 198 | ptr->idx4 = 0; |
188 | up(&ptr->sem); | 199 | up(&ptr->sem); |
189 | return; | ||
190 | } | 200 | } |
191 | 201 | ||
192 | static irqreturn_t hil_ptr_interrupt(struct serio *serio, | 202 | static irqreturn_t hil_ptr_interrupt(struct serio *serio, |
193 | unsigned char data, unsigned int flags) | 203 | unsigned char data, unsigned int flags) |
194 | { | 204 | { |
195 | struct hil_ptr *ptr; | 205 | struct hil_ptr *ptr; |
@@ -197,29 +207,29 @@ static irqreturn_t hil_ptr_interrupt(struct serio *serio, | |||
197 | int idx; | 207 | int idx; |
198 | 208 | ||
199 | ptr = serio_get_drvdata(serio); | 209 | ptr = serio_get_drvdata(serio); |
200 | if (ptr == NULL) { | 210 | BUG_ON(ptr == NULL); |
201 | BUG(); | ||
202 | return IRQ_HANDLED; | ||
203 | } | ||
204 | 211 | ||
205 | if (ptr->idx4 >= (HIL_PTR_MAX_LENGTH * sizeof(hil_packet))) { | 212 | if (ptr->idx4 >= (HIL_PTR_MAX_LENGTH * sizeof(hil_packet))) { |
206 | hil_ptr_process_err(ptr); | 213 | hil_ptr_process_err(ptr); |
207 | return IRQ_HANDLED; | 214 | return IRQ_HANDLED; |
208 | } | 215 | } |
209 | idx = ptr->idx4/4; | 216 | idx = ptr->idx4/4; |
210 | if (!(ptr->idx4 % 4)) ptr->data[idx] = 0; | 217 | if (!(ptr->idx4 % 4)) |
218 | ptr->data[idx] = 0; | ||
211 | packet = ptr->data[idx]; | 219 | packet = ptr->data[idx]; |
212 | packet |= ((hil_packet)data) << ((3 - (ptr->idx4 % 4)) * 8); | 220 | packet |= ((hil_packet)data) << ((3 - (ptr->idx4 % 4)) * 8); |
213 | ptr->data[idx] = packet; | 221 | ptr->data[idx] = packet; |
214 | 222 | ||
215 | /* Records of N 4-byte hil_packets must terminate with a command. */ | 223 | /* Records of N 4-byte hil_packets must terminate with a command. */ |
216 | if ((++(ptr->idx4)) % 4) return IRQ_HANDLED; | 224 | if ((++(ptr->idx4)) % 4) |
225 | return IRQ_HANDLED; | ||
217 | if ((packet & 0xffff0000) != HIL_ERR_INT) { | 226 | if ((packet & 0xffff0000) != HIL_ERR_INT) { |
218 | hil_ptr_process_err(ptr); | 227 | hil_ptr_process_err(ptr); |
219 | return IRQ_HANDLED; | 228 | return IRQ_HANDLED; |
220 | } | 229 | } |
221 | if (packet & HIL_PKT_CMD) | 230 | if (packet & HIL_PKT_CMD) |
222 | hil_ptr_process_record(ptr); | 231 | hil_ptr_process_record(ptr); |
232 | |||
223 | return IRQ_HANDLED; | 233 | return IRQ_HANDLED; |
224 | } | 234 | } |
225 | 235 | ||
@@ -228,10 +238,7 @@ static void hil_ptr_disconnect(struct serio *serio) | |||
228 | struct hil_ptr *ptr; | 238 | struct hil_ptr *ptr; |
229 | 239 | ||
230 | ptr = serio_get_drvdata(serio); | 240 | ptr = serio_get_drvdata(serio); |
231 | if (ptr == NULL) { | 241 | BUG_ON(ptr == NULL); |
232 | BUG(); | ||
233 | return; | ||
234 | } | ||
235 | 242 | ||
236 | serio_close(serio); | 243 | serio_close(serio); |
237 | input_unregister_device(ptr->dev); | 244 | input_unregister_device(ptr->dev); |
@@ -241,7 +248,7 @@ static void hil_ptr_disconnect(struct serio *serio) | |||
241 | static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) | 248 | static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) |
242 | { | 249 | { |
243 | struct hil_ptr *ptr; | 250 | struct hil_ptr *ptr; |
244 | char *txt; | 251 | const char *txt; |
245 | unsigned int i, naxsets, btntype; | 252 | unsigned int i, naxsets, btntype; |
246 | uint8_t did, *idd; | 253 | uint8_t did, *idd; |
247 | 254 | ||
@@ -252,42 +259,40 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) | |||
252 | if (!ptr->dev) | 259 | if (!ptr->dev) |
253 | goto bail0; | 260 | goto bail0; |
254 | 261 | ||
255 | ptr->dev->private = ptr; | ||
256 | |||
257 | if (serio_open(serio, driver)) | 262 | if (serio_open(serio, driver)) |
258 | goto bail1; | 263 | goto bail1; |
259 | 264 | ||
260 | serio_set_drvdata(serio, ptr); | 265 | serio_set_drvdata(serio, ptr); |
261 | ptr->serio = serio; | 266 | ptr->serio = serio; |
262 | 267 | ||
263 | init_MUTEX_LOCKED(&(ptr->sem)); | 268 | init_MUTEX_LOCKED(&ptr->sem); |
264 | 269 | ||
265 | /* Get device info. MLC driver supplies devid/status/etc. */ | 270 | /* Get device info. MLC driver supplies devid/status/etc. */ |
266 | serio->write(serio, 0); | 271 | serio->write(serio, 0); |
267 | serio->write(serio, 0); | 272 | serio->write(serio, 0); |
268 | serio->write(serio, HIL_PKT_CMD >> 8); | 273 | serio->write(serio, HIL_PKT_CMD >> 8); |
269 | serio->write(serio, HIL_CMD_IDD); | 274 | serio->write(serio, HIL_CMD_IDD); |
270 | down(&(ptr->sem)); | 275 | down(&ptr->sem); |
271 | 276 | ||
272 | serio->write(serio, 0); | 277 | serio->write(serio, 0); |
273 | serio->write(serio, 0); | 278 | serio->write(serio, 0); |
274 | serio->write(serio, HIL_PKT_CMD >> 8); | 279 | serio->write(serio, HIL_PKT_CMD >> 8); |
275 | serio->write(serio, HIL_CMD_RSC); | 280 | serio->write(serio, HIL_CMD_RSC); |
276 | down(&(ptr->sem)); | 281 | down(&ptr->sem); |
277 | 282 | ||
278 | serio->write(serio, 0); | 283 | serio->write(serio, 0); |
279 | serio->write(serio, 0); | 284 | serio->write(serio, 0); |
280 | serio->write(serio, HIL_PKT_CMD >> 8); | 285 | serio->write(serio, HIL_PKT_CMD >> 8); |
281 | serio->write(serio, HIL_CMD_RNM); | 286 | serio->write(serio, HIL_CMD_RNM); |
282 | down(&(ptr->sem)); | 287 | down(&ptr->sem); |
283 | 288 | ||
284 | serio->write(serio, 0); | 289 | serio->write(serio, 0); |
285 | serio->write(serio, 0); | 290 | serio->write(serio, 0); |
286 | serio->write(serio, HIL_PKT_CMD >> 8); | 291 | serio->write(serio, HIL_PKT_CMD >> 8); |
287 | serio->write(serio, HIL_CMD_EXD); | 292 | serio->write(serio, HIL_CMD_EXD); |
288 | down(&(ptr->sem)); | 293 | down(&ptr->sem); |
289 | 294 | ||
290 | up(&(ptr->sem)); | 295 | up(&ptr->sem); |
291 | 296 | ||
292 | did = ptr->idd[0]; | 297 | did = ptr->idd[0]; |
293 | idd = ptr->idd + 1; | 298 | idd = ptr->idd + 1; |
@@ -301,12 +306,12 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) | |||
301 | ptr->dev->evbit[0] = BIT(EV_ABS); | 306 | ptr->dev->evbit[0] = BIT(EV_ABS); |
302 | txt = "absolute"; | 307 | txt = "absolute"; |
303 | } | 308 | } |
304 | if (!ptr->dev->evbit[0]) { | 309 | if (!ptr->dev->evbit[0]) |
305 | goto bail2; | 310 | goto bail2; |
306 | } | ||
307 | 311 | ||
308 | ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd); | 312 | ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd); |
309 | if (ptr->nbtn) ptr->dev->evbit[0] |= BIT(EV_KEY); | 313 | if (ptr->nbtn) |
314 | ptr->dev->evbit[0] |= BIT(EV_KEY); | ||
310 | 315 | ||
311 | naxsets = HIL_IDD_NUM_AXSETS(*idd); | 316 | naxsets = HIL_IDD_NUM_AXSETS(*idd); |
312 | ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd); | 317 | ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd); |
@@ -315,7 +320,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) | |||
315 | did, txt); | 320 | did, txt); |
316 | printk(KERN_INFO PREFIX "HIL pointer has %i buttons and %i sets of %i axes\n", | 321 | printk(KERN_INFO PREFIX "HIL pointer has %i buttons and %i sets of %i axes\n", |
317 | ptr->nbtn, naxsets, ptr->naxes); | 322 | ptr->nbtn, naxsets, ptr->naxes); |
318 | 323 | ||
319 | btntype = BTN_MISC; | 324 | btntype = BTN_MISC; |
320 | if ((did & HIL_IDD_DID_ABS_TABLET_MASK) == HIL_IDD_DID_ABS_TABLET) | 325 | if ((did & HIL_IDD_DID_ABS_TABLET_MASK) == HIL_IDD_DID_ABS_TABLET) |
321 | #ifdef TABLET_SIMULATES_MOUSE | 326 | #ifdef TABLET_SIMULATES_MOUSE |
@@ -325,7 +330,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) | |||
325 | #endif | 330 | #endif |
326 | if ((did & HIL_IDD_DID_ABS_TSCREEN_MASK) == HIL_IDD_DID_ABS_TSCREEN) | 331 | if ((did & HIL_IDD_DID_ABS_TSCREEN_MASK) == HIL_IDD_DID_ABS_TSCREEN) |
327 | btntype = BTN_TOUCH; | 332 | btntype = BTN_TOUCH; |
328 | 333 | ||
329 | if ((did & HIL_IDD_DID_REL_MOUSE_MASK) == HIL_IDD_DID_REL_MOUSE) | 334 | if ((did & HIL_IDD_DID_REL_MOUSE_MASK) == HIL_IDD_DID_REL_MOUSE) |
330 | btntype = BTN_MOUSE; | 335 | btntype = BTN_MOUSE; |
331 | 336 | ||
@@ -341,12 +346,10 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) | |||
341 | } | 346 | } |
342 | 347 | ||
343 | if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) { | 348 | if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) { |
344 | for (i = 0; i < ptr->naxes; i++) { | 349 | for (i = 0; i < ptr->naxes; i++) |
345 | set_bit(REL_X + i, ptr->dev->relbit); | 350 | set_bit(REL_X + i, ptr->dev->relbit); |
346 | } | 351 | for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) |
347 | for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) { | ||
348 | set_bit(REL_X + i, ptr->dev->relbit); | 352 | set_bit(REL_X + i, ptr->dev->relbit); |
349 | } | ||
350 | } else { | 353 | } else { |
351 | for (i = 0; i < ptr->naxes; i++) { | 354 | for (i = 0; i < ptr->naxes; i++) { |
352 | set_bit(ABS_X + i, ptr->dev->absbit); | 355 | set_bit(ABS_X + i, ptr->dev->absbit); |
@@ -375,7 +378,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) | |||
375 | ptr->dev->id.vendor = PCI_VENDOR_ID_HP; | 378 | ptr->dev->id.vendor = PCI_VENDOR_ID_HP; |
376 | ptr->dev->id.product = 0x0001; /* TODO: get from ptr->rsc */ | 379 | ptr->dev->id.product = 0x0001; /* TODO: get from ptr->rsc */ |
377 | ptr->dev->id.version = 0x0100; /* TODO: get from ptr->rsc */ | 380 | ptr->dev->id.version = 0x0100; /* TODO: get from ptr->rsc */ |
378 | ptr->dev->cdev.dev = &serio->dev; | 381 | ptr->dev->dev.parent = &serio->dev; |
379 | 382 | ||
380 | input_register_device(ptr->dev); | 383 | input_register_device(ptr->dev); |
381 | printk(KERN_INFO "input: %s (%s), ID: %d\n", | 384 | printk(KERN_INFO "input: %s (%s), ID: %d\n", |
@@ -419,11 +422,11 @@ static int __init hil_ptr_init(void) | |||
419 | { | 422 | { |
420 | return serio_register_driver(&hil_ptr_serio_driver); | 423 | return serio_register_driver(&hil_ptr_serio_driver); |
421 | } | 424 | } |
422 | 425 | ||
423 | static void __exit hil_ptr_exit(void) | 426 | static void __exit hil_ptr_exit(void) |
424 | { | 427 | { |
425 | serio_unregister_driver(&hil_ptr_serio_driver); | 428 | serio_unregister_driver(&hil_ptr_serio_driver); |
426 | } | 429 | } |
427 | 430 | ||
428 | module_init(hil_ptr_init); | 431 | module_init(hil_ptr_init); |
429 | module_exit(hil_ptr_exit); | 432 | module_exit(hil_ptr_exit); |
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index 29542f0631cb..1740cadd9594 100644 --- a/drivers/input/mouse/lifebook.c +++ b/drivers/input/mouse/lifebook.c | |||
@@ -20,6 +20,27 @@ | |||
20 | #include "psmouse.h" | 20 | #include "psmouse.h" |
21 | #include "lifebook.h" | 21 | #include "lifebook.h" |
22 | 22 | ||
23 | struct lifebook_data { | ||
24 | struct input_dev *dev2; /* Relative device */ | ||
25 | char phys[32]; | ||
26 | }; | ||
27 | |||
28 | static const char *desired_serio_phys; | ||
29 | |||
30 | static int lifebook_set_serio_phys(struct dmi_system_id *d) | ||
31 | { | ||
32 | desired_serio_phys = d->driver_data; | ||
33 | return 0; | ||
34 | } | ||
35 | |||
36 | static unsigned char lifebook_use_6byte_proto; | ||
37 | |||
38 | static int lifebook_set_6byte_proto(struct dmi_system_id *d) | ||
39 | { | ||
40 | lifebook_use_6byte_proto = 1; | ||
41 | return 0; | ||
42 | } | ||
43 | |||
23 | static struct dmi_system_id lifebook_dmi_table[] = { | 44 | static struct dmi_system_id lifebook_dmi_table[] = { |
24 | { | 45 | { |
25 | .ident = "FLORA-ie 55mi", | 46 | .ident = "FLORA-ie 55mi", |
@@ -56,6 +77,24 @@ static struct dmi_system_id lifebook_dmi_table[] = { | |||
56 | .matches = { | 77 | .matches = { |
57 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-18"), | 78 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-18"), |
58 | }, | 79 | }, |
80 | .callback = lifebook_set_serio_phys, | ||
81 | .driver_data = "isa0060/serio3", | ||
82 | }, | ||
83 | { | ||
84 | .ident = "Panasonic CF-28", | ||
85 | .matches = { | ||
86 | DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), | ||
87 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-28"), | ||
88 | }, | ||
89 | .callback = lifebook_set_6byte_proto, | ||
90 | }, | ||
91 | { | ||
92 | .ident = "Panasonic CF-29", | ||
93 | .matches = { | ||
94 | DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), | ||
95 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"), | ||
96 | }, | ||
97 | .callback = lifebook_set_6byte_proto, | ||
59 | }, | 98 | }, |
60 | { | 99 | { |
61 | .ident = "Lifebook B142", | 100 | .ident = "Lifebook B142", |
@@ -68,30 +107,70 @@ static struct dmi_system_id lifebook_dmi_table[] = { | |||
68 | 107 | ||
69 | static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) | 108 | static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) |
70 | { | 109 | { |
110 | struct lifebook_data *priv = psmouse->private; | ||
111 | struct input_dev *dev1 = psmouse->dev; | ||
112 | struct input_dev *dev2 = priv->dev2; | ||
71 | unsigned char *packet = psmouse->packet; | 113 | unsigned char *packet = psmouse->packet; |
72 | struct input_dev *dev = psmouse->dev; | 114 | int relative_packet = packet[0] & 0x08; |
73 | 115 | ||
74 | if (psmouse->pktcnt != 3) | 116 | if (relative_packet || !lifebook_use_6byte_proto) { |
75 | return PSMOUSE_GOOD_DATA; | 117 | if (psmouse->pktcnt != 3) |
118 | return PSMOUSE_GOOD_DATA; | ||
119 | } else { | ||
120 | switch (psmouse->pktcnt) { | ||
121 | case 1: | ||
122 | return (packet[0] & 0xf8) == 0x00 ? | ||
123 | PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA; | ||
124 | case 2: | ||
125 | return PSMOUSE_GOOD_DATA; | ||
126 | case 3: | ||
127 | return ((packet[2] & 0x30) << 2) == (packet[2] & 0xc0) ? | ||
128 | PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA; | ||
129 | case 4: | ||
130 | return (packet[3] & 0xf8) == 0xc0 ? | ||
131 | PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA; | ||
132 | case 5: | ||
133 | return (packet[4] & 0xc0) == (packet[2] & 0xc0) ? | ||
134 | PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA; | ||
135 | case 6: | ||
136 | if (((packet[5] & 0x30) << 2) != (packet[5] & 0xc0)) | ||
137 | return PSMOUSE_BAD_DATA; | ||
138 | if ((packet[5] & 0xc0) != (packet[1] & 0xc0)) | ||
139 | return PSMOUSE_BAD_DATA; | ||
140 | break; /* report data */ | ||
141 | } | ||
142 | } | ||
76 | 143 | ||
77 | /* calculate X and Y */ | 144 | if (relative_packet) { |
78 | if ((packet[0] & 0x08) == 0x00) { | 145 | if (!dev2) |
79 | input_report_abs(dev, ABS_X, | 146 | printk(KERN_WARNING "lifebook.c: got relative packet " |
147 | "but no relative device set up\n"); | ||
148 | } else if (lifebook_use_6byte_proto) { | ||
149 | input_report_abs(dev1, ABS_X, | ||
150 | ((packet[1] & 0x3f) << 6) | (packet[2] & 0x3f)); | ||
151 | input_report_abs(dev1, ABS_Y, | ||
152 | 4096 - (((packet[4] & 0x3f) << 6) | (packet[5] & 0x3f))); | ||
153 | } else { | ||
154 | input_report_abs(dev1, ABS_X, | ||
80 | (packet[1] | ((packet[0] & 0x30) << 4))); | 155 | (packet[1] | ((packet[0] & 0x30) << 4))); |
81 | input_report_abs(dev, ABS_Y, | 156 | input_report_abs(dev1, ABS_Y, |
82 | 1024 - (packet[2] | ((packet[0] & 0xC0) << 2))); | 157 | 1024 - (packet[2] | ((packet[0] & 0xC0) << 2))); |
83 | } else { | ||
84 | input_report_rel(dev, REL_X, | ||
85 | ((packet[0] & 0x10) ? packet[1] - 256 : packet[1])); | ||
86 | input_report_rel(dev, REL_Y, | ||
87 | -(int)((packet[0] & 0x20) ? packet[2] - 256 : packet[2])); | ||
88 | } | 158 | } |
89 | 159 | ||
90 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); | 160 | input_report_key(dev1, BTN_TOUCH, packet[0] & 0x04); |
91 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); | 161 | input_sync(dev1); |
92 | input_report_key(dev, BTN_TOUCH, packet[0] & 0x04); | ||
93 | 162 | ||
94 | input_sync(dev); | 163 | if (dev2) { |
164 | if (relative_packet) { | ||
165 | input_report_rel(dev2, REL_X, | ||
166 | ((packet[0] & 0x10) ? packet[1] - 256 : packet[1])); | ||
167 | input_report_rel(dev2, REL_Y, | ||
168 | -(int)((packet[0] & 0x20) ? packet[2] - 256 : packet[2])); | ||
169 | } | ||
170 | input_report_key(dev2, BTN_LEFT, packet[0] & 0x01); | ||
171 | input_report_key(dev2, BTN_RIGHT, packet[0] & 0x02); | ||
172 | input_sync(dev2); | ||
173 | } | ||
95 | 174 | ||
96 | return PSMOUSE_FULL_PACKET; | 175 | return PSMOUSE_FULL_PACKET; |
97 | } | 176 | } |
@@ -109,12 +188,20 @@ static int lifebook_absolute_mode(struct psmouse *psmouse) | |||
109 | you leave this call out the touchsreen will never send | 188 | you leave this call out the touchsreen will never send |
110 | absolute coordinates | 189 | absolute coordinates |
111 | */ | 190 | */ |
112 | param = 0x07; | 191 | param = lifebook_use_6byte_proto ? 0x08 : 0x07; |
113 | ps2_command(ps2dev, ¶m, PSMOUSE_CMD_SETRES); | 192 | ps2_command(ps2dev, ¶m, PSMOUSE_CMD_SETRES); |
114 | 193 | ||
115 | return 0; | 194 | return 0; |
116 | } | 195 | } |
117 | 196 | ||
197 | static void lifebook_relative_mode(struct psmouse *psmouse) | ||
198 | { | ||
199 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
200 | unsigned char param = 0x06; | ||
201 | |||
202 | ps2_command(ps2dev, ¶m, PSMOUSE_CMD_SETRES); | ||
203 | } | ||
204 | |||
118 | static void lifebook_set_resolution(struct psmouse *psmouse, unsigned int resolution) | 205 | static void lifebook_set_resolution(struct psmouse *psmouse, unsigned int resolution) |
119 | { | 206 | { |
120 | static const unsigned char params[] = { 0, 1, 2, 2, 3 }; | 207 | static const unsigned char params[] = { 0, 1, 2, 2, 3 }; |
@@ -131,6 +218,8 @@ static void lifebook_set_resolution(struct psmouse *psmouse, unsigned int resolu | |||
131 | static void lifebook_disconnect(struct psmouse *psmouse) | 218 | static void lifebook_disconnect(struct psmouse *psmouse) |
132 | { | 219 | { |
133 | psmouse_reset(psmouse); | 220 | psmouse_reset(psmouse); |
221 | kfree(psmouse->private); | ||
222 | psmouse->private = NULL; | ||
134 | } | 223 | } |
135 | 224 | ||
136 | int lifebook_detect(struct psmouse *psmouse, int set_properties) | 225 | int lifebook_detect(struct psmouse *psmouse, int set_properties) |
@@ -138,6 +227,10 @@ int lifebook_detect(struct psmouse *psmouse, int set_properties) | |||
138 | if (!dmi_check_system(lifebook_dmi_table)) | 227 | if (!dmi_check_system(lifebook_dmi_table)) |
139 | return -1; | 228 | return -1; |
140 | 229 | ||
230 | if (desired_serio_phys && | ||
231 | strcmp(psmouse->ps2dev.serio->phys, desired_serio_phys)) | ||
232 | return -1; | ||
233 | |||
141 | if (set_properties) { | 234 | if (set_properties) { |
142 | psmouse->vendor = "Fujitsu"; | 235 | psmouse->vendor = "Fujitsu"; |
143 | psmouse->name = "Lifebook TouchScreen"; | 236 | psmouse->name = "Lifebook TouchScreen"; |
@@ -146,24 +239,78 @@ int lifebook_detect(struct psmouse *psmouse, int set_properties) | |||
146 | return 0; | 239 | return 0; |
147 | } | 240 | } |
148 | 241 | ||
242 | static int lifebook_create_relative_device(struct psmouse *psmouse) | ||
243 | { | ||
244 | struct input_dev *dev2; | ||
245 | struct lifebook_data *priv; | ||
246 | int error = -ENOMEM; | ||
247 | |||
248 | priv = kzalloc(sizeof(struct lifebook_data), GFP_KERNEL); | ||
249 | dev2 = input_allocate_device(); | ||
250 | if (!priv || !dev2) | ||
251 | goto err_out; | ||
252 | |||
253 | priv->dev2 = dev2; | ||
254 | snprintf(priv->phys, sizeof(priv->phys), | ||
255 | "%s/input1", psmouse->ps2dev.serio->phys); | ||
256 | |||
257 | dev2->phys = priv->phys; | ||
258 | dev2->name = "PS/2 Touchpad"; | ||
259 | dev2->id.bustype = BUS_I8042; | ||
260 | dev2->id.vendor = 0x0002; | ||
261 | dev2->id.product = PSMOUSE_LIFEBOOK; | ||
262 | dev2->id.version = 0x0000; | ||
263 | dev2->dev.parent = &psmouse->ps2dev.serio->dev; | ||
264 | |||
265 | dev2->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); | ||
266 | dev2->relbit[LONG(REL_X)] = BIT(REL_X) | BIT(REL_Y); | ||
267 | dev2->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT); | ||
268 | |||
269 | error = input_register_device(priv->dev2); | ||
270 | if (error) | ||
271 | goto err_out; | ||
272 | |||
273 | psmouse->private = priv; | ||
274 | return 0; | ||
275 | |||
276 | err_out: | ||
277 | input_free_device(dev2); | ||
278 | kfree(priv); | ||
279 | return error; | ||
280 | } | ||
281 | |||
149 | int lifebook_init(struct psmouse *psmouse) | 282 | int lifebook_init(struct psmouse *psmouse) |
150 | { | 283 | { |
151 | struct input_dev *input_dev = psmouse->dev; | 284 | struct input_dev *dev1 = psmouse->dev; |
285 | int max_coord = lifebook_use_6byte_proto ? 1024 : 4096; | ||
152 | 286 | ||
153 | if (lifebook_absolute_mode(psmouse)) | 287 | if (lifebook_absolute_mode(psmouse)) |
154 | return -1; | 288 | return -1; |
155 | 289 | ||
156 | input_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY) | BIT(EV_REL); | 290 | dev1->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY); |
157 | input_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); | 291 | dev1->relbit[0] = 0; |
158 | input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); | 292 | dev1->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); |
159 | input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); | 293 | input_set_abs_params(dev1, ABS_X, 0, max_coord, 0, 0); |
160 | input_set_abs_params(input_dev, ABS_X, 0, 1024, 0, 0); | 294 | input_set_abs_params(dev1, ABS_Y, 0, max_coord, 0, 0); |
161 | input_set_abs_params(input_dev, ABS_Y, 0, 1024, 0, 0); | 295 | |
296 | if (!desired_serio_phys) { | ||
297 | if (lifebook_create_relative_device(psmouse)) { | ||
298 | lifebook_relative_mode(psmouse); | ||
299 | return -1; | ||
300 | } | ||
301 | } | ||
162 | 302 | ||
163 | psmouse->protocol_handler = lifebook_process_byte; | 303 | psmouse->protocol_handler = lifebook_process_byte; |
164 | psmouse->set_resolution = lifebook_set_resolution; | 304 | psmouse->set_resolution = lifebook_set_resolution; |
165 | psmouse->disconnect = lifebook_disconnect; | 305 | psmouse->disconnect = lifebook_disconnect; |
166 | psmouse->reconnect = lifebook_absolute_mode; | 306 | psmouse->reconnect = lifebook_absolute_mode; |
307 | |||
308 | psmouse->model = lifebook_use_6byte_proto ? 6 : 3; | ||
309 | |||
310 | /* | ||
311 | * Use packet size = 3 even when using 6-byte protocol because | ||
312 | * that's what POLL will return on Lifebooks (according to spec). | ||
313 | */ | ||
167 | psmouse->pktsize = 3; | 314 | psmouse->pktsize = 3; |
168 | 315 | ||
169 | return 0; | 316 | return 0; |
diff --git a/drivers/input/mouse/lifebook.h b/drivers/input/mouse/lifebook.h index be1c0943825d..c1647cf036c2 100644 --- a/drivers/input/mouse/lifebook.h +++ b/drivers/input/mouse/lifebook.h | |||
@@ -11,7 +11,18 @@ | |||
11 | #ifndef _LIFEBOOK_H | 11 | #ifndef _LIFEBOOK_H |
12 | #define _LIFEBOOK_H | 12 | #define _LIFEBOOK_H |
13 | 13 | ||
14 | #ifdef CONFIG_MOUSE_PS2_LIFEBOOK | ||
14 | int lifebook_detect(struct psmouse *psmouse, int set_properties); | 15 | int lifebook_detect(struct psmouse *psmouse, int set_properties); |
15 | int lifebook_init(struct psmouse *psmouse); | 16 | int lifebook_init(struct psmouse *psmouse); |
17 | #else | ||
18 | inline int lifebook_detect(struct psmouse *psmouse, int set_properties) | ||
19 | { | ||
20 | return -ENOSYS; | ||
21 | } | ||
22 | inline int lifebook_init(struct psmouse *psmouse) | ||
23 | { | ||
24 | return -ENOSYS; | ||
25 | } | ||
26 | #endif | ||
16 | 27 | ||
17 | #endif | 28 | #endif |
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index d3ddea26b8ca..9df74b72e6c4 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c | |||
@@ -200,6 +200,7 @@ static void ps2pp_disconnect(struct psmouse *psmouse) | |||
200 | static const struct ps2pp_info *get_model_info(unsigned char model) | 200 | static const struct ps2pp_info *get_model_info(unsigned char model) |
201 | { | 201 | { |
202 | static const struct ps2pp_info ps2pp_list[] = { | 202 | static const struct ps2pp_info ps2pp_list[] = { |
203 | { 1, 0, 0 }, /* Simple 2-button mouse */ | ||
203 | { 12, 0, PS2PP_SIDE_BTN}, | 204 | { 12, 0, PS2PP_SIDE_BTN}, |
204 | { 13, 0, 0 }, | 205 | { 13, 0, 0 }, |
205 | { 15, PS2PP_KIND_MX, /* MX1000 */ | 206 | { 15, PS2PP_KIND_MX, /* MX1000 */ |
@@ -338,12 +339,12 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties) | |||
338 | param[1] = 0; | 339 | param[1] = 0; |
339 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO); | 340 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO); |
340 | 341 | ||
341 | if (!param[1]) | ||
342 | return -1; | ||
343 | |||
344 | model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78); | 342 | model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78); |
345 | buttons = param[1]; | 343 | buttons = param[1]; |
346 | 344 | ||
345 | if (!model || !buttons) | ||
346 | return -1; | ||
347 | |||
347 | if ((model_info = get_model_info(model)) != NULL) { | 348 | if ((model_info = get_model_info(model)) != NULL) { |
348 | 349 | ||
349 | /* | 350 | /* |
diff --git a/drivers/input/mouse/logips2pp.h b/drivers/input/mouse/logips2pp.h index 64a8ec52ea6d..6e5712525fd6 100644 --- a/drivers/input/mouse/logips2pp.h +++ b/drivers/input/mouse/logips2pp.h | |||
@@ -11,6 +11,13 @@ | |||
11 | #ifndef _LOGIPS2PP_H | 11 | #ifndef _LOGIPS2PP_H |
12 | #define _LOGIPS2PP_H | 12 | #define _LOGIPS2PP_H |
13 | 13 | ||
14 | #ifdef CONFIG_MOUSE_PS2_LOGIPS2PP | ||
14 | int ps2pp_init(struct psmouse *psmouse, int set_properties); | 15 | int ps2pp_init(struct psmouse *psmouse, int set_properties); |
16 | #else | ||
17 | inline int ps2pp_init(struct psmouse *psmouse, int set_properties) | ||
18 | { | ||
19 | return -ENOSYS; | ||
20 | } | ||
21 | #endif /* CONFIG_MOUSE_PS2_LOGIPS2PP */ | ||
15 | 22 | ||
16 | #endif | 23 | #endif |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 0fe5869d7d4c..f15f695777f8 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "alps.h" | 28 | #include "alps.h" |
29 | #include "lifebook.h" | 29 | #include "lifebook.h" |
30 | #include "trackpoint.h" | 30 | #include "trackpoint.h" |
31 | #include "touchkit_ps2.h" | ||
31 | 32 | ||
32 | #define DRIVER_DESC "PS/2 mouse driver" | 33 | #define DRIVER_DESC "PS/2 mouse driver" |
33 | 34 | ||
@@ -569,7 +570,9 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
569 | return PSMOUSE_THINKPS; | 570 | return PSMOUSE_THINKPS; |
570 | 571 | ||
571 | /* | 572 | /* |
572 | * Try Synaptics TouchPad | 573 | * Try Synaptics TouchPad. Note that probing is done even if Synaptics protocol |
574 | * support is disabled in config - we need to know if it is synaptics so we | ||
575 | * can reset it properly after probing for intellimouse. | ||
573 | */ | 576 | */ |
574 | if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse, set_properties) == 0) { | 577 | if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse, set_properties) == 0) { |
575 | synaptics_hardware = 1; | 578 | synaptics_hardware = 1; |
@@ -605,14 +608,20 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
605 | } | 608 | } |
606 | } | 609 | } |
607 | 610 | ||
608 | if (max_proto > PSMOUSE_IMEX && genius_detect(psmouse, set_properties) == 0) | 611 | if (max_proto > PSMOUSE_IMEX) { |
609 | return PSMOUSE_GENPS; | 612 | |
613 | if (genius_detect(psmouse, set_properties) == 0) | ||
614 | return PSMOUSE_GENPS; | ||
610 | 615 | ||
611 | if (max_proto > PSMOUSE_IMEX && ps2pp_init(psmouse, set_properties) == 0) | 616 | if (ps2pp_init(psmouse, set_properties) == 0) |
612 | return PSMOUSE_PS2PP; | 617 | return PSMOUSE_PS2PP; |
613 | 618 | ||
614 | if (max_proto > PSMOUSE_IMEX && trackpoint_detect(psmouse, set_properties) == 0) | 619 | if (trackpoint_detect(psmouse, set_properties) == 0) |
615 | return PSMOUSE_TRACKPOINT; | 620 | return PSMOUSE_TRACKPOINT; |
621 | |||
622 | if (touchkit_ps2_detect(psmouse, set_properties) == 0) | ||
623 | return PSMOUSE_TOUCHKIT_PS2; | ||
624 | } | ||
616 | 625 | ||
617 | /* | 626 | /* |
618 | * Reset to defaults in case the device got confused by extended | 627 | * Reset to defaults in case the device got confused by extended |
@@ -654,12 +663,14 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
654 | .maxproto = 1, | 663 | .maxproto = 1, |
655 | .detect = ps2bare_detect, | 664 | .detect = ps2bare_detect, |
656 | }, | 665 | }, |
666 | #ifdef CONFIG_MOUSE_PS2_LOGIPS2PP | ||
657 | { | 667 | { |
658 | .type = PSMOUSE_PS2PP, | 668 | .type = PSMOUSE_PS2PP, |
659 | .name = "PS2++", | 669 | .name = "PS2++", |
660 | .alias = "logitech", | 670 | .alias = "logitech", |
661 | .detect = ps2pp_init, | 671 | .detect = ps2pp_init, |
662 | }, | 672 | }, |
673 | #endif | ||
663 | { | 674 | { |
664 | .type = PSMOUSE_THINKPS, | 675 | .type = PSMOUSE_THINKPS, |
665 | .name = "ThinkPS/2", | 676 | .name = "ThinkPS/2", |
@@ -686,6 +697,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
686 | .maxproto = 1, | 697 | .maxproto = 1, |
687 | .detect = im_explorer_detect, | 698 | .detect = im_explorer_detect, |
688 | }, | 699 | }, |
700 | #ifdef CONFIG_MOUSE_PS2_SYNAPTICS | ||
689 | { | 701 | { |
690 | .type = PSMOUSE_SYNAPTICS, | 702 | .type = PSMOUSE_SYNAPTICS, |
691 | .name = "SynPS/2", | 703 | .name = "SynPS/2", |
@@ -693,6 +705,8 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
693 | .detect = synaptics_detect, | 705 | .detect = synaptics_detect, |
694 | .init = synaptics_init, | 706 | .init = synaptics_init, |
695 | }, | 707 | }, |
708 | #endif | ||
709 | #ifdef CONFIG_MOUSE_PS2_ALPS | ||
696 | { | 710 | { |
697 | .type = PSMOUSE_ALPS, | 711 | .type = PSMOUSE_ALPS, |
698 | .name = "AlpsPS/2", | 712 | .name = "AlpsPS/2", |
@@ -700,18 +714,31 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
700 | .detect = alps_detect, | 714 | .detect = alps_detect, |
701 | .init = alps_init, | 715 | .init = alps_init, |
702 | }, | 716 | }, |
717 | #endif | ||
718 | #ifdef CONFIG_MOUSE_PS2_LIFEBOOK | ||
703 | { | 719 | { |
704 | .type = PSMOUSE_LIFEBOOK, | 720 | .type = PSMOUSE_LIFEBOOK, |
705 | .name = "LBPS/2", | 721 | .name = "LBPS/2", |
706 | .alias = "lifebook", | 722 | .alias = "lifebook", |
707 | .init = lifebook_init, | 723 | .init = lifebook_init, |
708 | }, | 724 | }, |
725 | #endif | ||
726 | #ifdef CONFIG_MOUSE_PS2_TRACKPOINT | ||
709 | { | 727 | { |
710 | .type = PSMOUSE_TRACKPOINT, | 728 | .type = PSMOUSE_TRACKPOINT, |
711 | .name = "TPPS/2", | 729 | .name = "TPPS/2", |
712 | .alias = "trackpoint", | 730 | .alias = "trackpoint", |
713 | .detect = trackpoint_detect, | 731 | .detect = trackpoint_detect, |
714 | }, | 732 | }, |
733 | #endif | ||
734 | #ifdef CONFIG_MOUSE_PS2_TOUCHKIT | ||
735 | { | ||
736 | .type = PSMOUSE_TOUCHKIT_PS2, | ||
737 | .name = "touchkitPS/2", | ||
738 | .alias = "touchkit", | ||
739 | .detect = touchkit_ps2_detect, | ||
740 | }, | ||
741 | #endif | ||
715 | { | 742 | { |
716 | .type = PSMOUSE_AUTO, | 743 | .type = PSMOUSE_AUTO, |
717 | .name = "auto", | 744 | .name = "auto", |
@@ -823,12 +850,6 @@ static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate) | |||
823 | static void psmouse_initialize(struct psmouse *psmouse) | 850 | static void psmouse_initialize(struct psmouse *psmouse) |
824 | { | 851 | { |
825 | /* | 852 | /* |
826 | * We set the mouse into streaming mode. | ||
827 | */ | ||
828 | |||
829 | ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM); | ||
830 | |||
831 | /* | ||
832 | * We set the mouse report rate, resolution and scaling. | 853 | * We set the mouse report rate, resolution and scaling. |
833 | */ | 854 | */ |
834 | 855 | ||
@@ -1062,8 +1083,7 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, const struct psmouse | |||
1062 | { | 1083 | { |
1063 | struct input_dev *input_dev = psmouse->dev; | 1084 | struct input_dev *input_dev = psmouse->dev; |
1064 | 1085 | ||
1065 | input_dev->private = psmouse; | 1086 | input_dev->dev.parent = &psmouse->ps2dev.serio->dev; |
1066 | input_dev->cdev.dev = &psmouse->ps2dev.serio->dev; | ||
1067 | 1087 | ||
1068 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); | 1088 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); |
1069 | input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); | 1089 | input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); |
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h index cf1de95b6f27..3964e8acbc54 100644 --- a/drivers/input/mouse/psmouse.h +++ b/drivers/input/mouse/psmouse.h | |||
@@ -87,6 +87,7 @@ enum psmouse_type { | |||
87 | PSMOUSE_ALPS, | 87 | PSMOUSE_ALPS, |
88 | PSMOUSE_LIFEBOOK, | 88 | PSMOUSE_LIFEBOOK, |
89 | PSMOUSE_TRACKPOINT, | 89 | PSMOUSE_TRACKPOINT, |
90 | PSMOUSE_TOUCHKIT_PS2, | ||
90 | PSMOUSE_AUTO /* This one should always be last */ | 91 | PSMOUSE_AUTO /* This one should always be last */ |
91 | }; | 92 | }; |
92 | 93 | ||
diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c index a85d74710b44..77b8ee2b9651 100644 --- a/drivers/input/mouse/sermouse.c +++ b/drivers/input/mouse/sermouse.c | |||
@@ -69,7 +69,8 @@ static void sermouse_process_msc(struct sermouse *sermouse, signed char data) | |||
69 | switch (sermouse->count) { | 69 | switch (sermouse->count) { |
70 | 70 | ||
71 | case 0: | 71 | case 0: |
72 | if ((data & 0xf8) != 0x80) return; | 72 | if ((data & 0xf8) != 0x80) |
73 | return; | ||
73 | input_report_key(dev, BTN_LEFT, !(data & 4)); | 74 | input_report_key(dev, BTN_LEFT, !(data & 4)); |
74 | input_report_key(dev, BTN_RIGHT, !(data & 1)); | 75 | input_report_key(dev, BTN_RIGHT, !(data & 1)); |
75 | input_report_key(dev, BTN_MIDDLE, !(data & 2)); | 76 | input_report_key(dev, BTN_MIDDLE, !(data & 2)); |
@@ -107,7 +108,10 @@ static void sermouse_process_ms(struct sermouse *sermouse, signed char data) | |||
107 | struct input_dev *dev = sermouse->dev; | 108 | struct input_dev *dev = sermouse->dev; |
108 | signed char *buf = sermouse->buf; | 109 | signed char *buf = sermouse->buf; |
109 | 110 | ||
110 | if (data & 0x40) sermouse->count = 0; | 111 | if (data & 0x40) |
112 | sermouse->count = 0; | ||
113 | else if (sermouse->count == 0) | ||
114 | return; | ||
111 | 115 | ||
112 | switch (sermouse->count) { | 116 | switch (sermouse->count) { |
113 | 117 | ||
@@ -169,7 +173,8 @@ static void sermouse_process_ms(struct sermouse *sermouse, signed char data) | |||
169 | 173 | ||
170 | case 5: | 174 | case 5: |
171 | case 7: /* Ignore anything besides MZ++ */ | 175 | case 7: /* Ignore anything besides MZ++ */ |
172 | if (sermouse->type != SERIO_MZPP) break; | 176 | if (sermouse->type != SERIO_MZPP) |
177 | break; | ||
173 | 178 | ||
174 | switch (buf[1]) { | 179 | switch (buf[1]) { |
175 | 180 | ||
@@ -206,13 +211,16 @@ static irqreturn_t sermouse_interrupt(struct serio *serio, | |||
206 | { | 211 | { |
207 | struct sermouse *sermouse = serio_get_drvdata(serio); | 212 | struct sermouse *sermouse = serio_get_drvdata(serio); |
208 | 213 | ||
209 | if (time_after(jiffies, sermouse->last + HZ/10)) sermouse->count = 0; | 214 | if (time_after(jiffies, sermouse->last + HZ/10)) |
215 | sermouse->count = 0; | ||
216 | |||
210 | sermouse->last = jiffies; | 217 | sermouse->last = jiffies; |
211 | 218 | ||
212 | if (sermouse->type > SERIO_SUN) | 219 | if (sermouse->type > SERIO_SUN) |
213 | sermouse_process_ms(sermouse, data); | 220 | sermouse_process_ms(sermouse, data); |
214 | else | 221 | else |
215 | sermouse_process_msc(sermouse, data); | 222 | sermouse_process_msc(sermouse, data); |
223 | |||
216 | return IRQ_HANDLED; | 224 | return IRQ_HANDLED; |
217 | } | 225 | } |
218 | 226 | ||
@@ -258,12 +266,11 @@ static int sermouse_connect(struct serio *serio, struct serio_driver *drv) | |||
258 | input_dev->id.vendor = sermouse->type; | 266 | input_dev->id.vendor = sermouse->type; |
259 | input_dev->id.product = c; | 267 | input_dev->id.product = c; |
260 | input_dev->id.version = 0x0100; | 268 | input_dev->id.version = 0x0100; |
261 | input_dev->cdev.dev = &serio->dev; | 269 | input_dev->dev.parent = &serio->dev; |
262 | 270 | ||
263 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); | 271 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); |
264 | input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT); | 272 | input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT); |
265 | input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); | 273 | input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); |
266 | input_dev->private = sermouse; | ||
267 | 274 | ||
268 | if (c & 0x01) set_bit(BTN_MIDDLE, input_dev->keybit); | 275 | if (c & 0x01) set_bit(BTN_MIDDLE, input_dev->keybit); |
269 | if (c & 0x02) set_bit(BTN_SIDE, input_dev->keybit); | 276 | if (c & 0x02) set_bit(BTN_SIDE, input_dev->keybit); |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index f0f9413d762c..c77788bf932d 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -40,33 +40,70 @@ | |||
40 | #define YMIN_NOMINAL 1408 | 40 | #define YMIN_NOMINAL 1408 |
41 | #define YMAX_NOMINAL 4448 | 41 | #define YMAX_NOMINAL 4448 |
42 | 42 | ||
43 | |||
43 | /***************************************************************************** | 44 | /***************************************************************************** |
44 | * Synaptics communications functions | 45 | * Stuff we need even when we do not want native Synaptics support |
45 | ****************************************************************************/ | 46 | ****************************************************************************/ |
46 | 47 | ||
47 | /* | 48 | /* |
48 | * Send a command to the synpatics touchpad by special commands | 49 | * Set the synaptics touchpad mode byte by special commands |
49 | */ | 50 | */ |
50 | static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, unsigned char *param) | 51 | static int synaptics_mode_cmd(struct psmouse *psmouse, unsigned char mode) |
51 | { | 52 | { |
52 | if (psmouse_sliced_command(psmouse, c)) | 53 | unsigned char param[1]; |
54 | |||
55 | if (psmouse_sliced_command(psmouse, mode)) | ||
53 | return -1; | 56 | return -1; |
54 | if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO)) | 57 | param[0] = SYN_PS_SET_MODE2; |
58 | if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_SETRATE)) | ||
55 | return -1; | 59 | return -1; |
56 | return 0; | 60 | return 0; |
57 | } | 61 | } |
58 | 62 | ||
63 | int synaptics_detect(struct psmouse *psmouse, int set_properties) | ||
64 | { | ||
65 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
66 | unsigned char param[4]; | ||
67 | |||
68 | param[0] = 0; | ||
69 | |||
70 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); | ||
71 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); | ||
72 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); | ||
73 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); | ||
74 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO); | ||
75 | |||
76 | if (param[1] != 0x47) | ||
77 | return -ENODEV; | ||
78 | |||
79 | if (set_properties) { | ||
80 | psmouse->vendor = "Synaptics"; | ||
81 | psmouse->name = "TouchPad"; | ||
82 | } | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | void synaptics_reset(struct psmouse *psmouse) | ||
88 | { | ||
89 | /* reset touchpad back to relative mode, gestures enabled */ | ||
90 | synaptics_mode_cmd(psmouse, 0); | ||
91 | } | ||
92 | |||
93 | #ifdef CONFIG_MOUSE_PS2_SYNAPTICS | ||
94 | |||
95 | /***************************************************************************** | ||
96 | * Synaptics communications functions | ||
97 | ****************************************************************************/ | ||
98 | |||
59 | /* | 99 | /* |
60 | * Set the synaptics touchpad mode byte by special commands | 100 | * Send a command to the synpatics touchpad by special commands |
61 | */ | 101 | */ |
62 | static int synaptics_mode_cmd(struct psmouse *psmouse, unsigned char mode) | 102 | static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, unsigned char *param) |
63 | { | 103 | { |
64 | unsigned char param[1]; | 104 | if (psmouse_sliced_command(psmouse, c)) |
65 | |||
66 | if (psmouse_sliced_command(psmouse, mode)) | ||
67 | return -1; | 105 | return -1; |
68 | param[0] = SYN_PS_SET_MODE2; | 106 | if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO)) |
69 | if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_SETRATE)) | ||
70 | return -1; | 107 | return -1; |
71 | return 0; | 108 | return 0; |
72 | } | 109 | } |
@@ -529,12 +566,6 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | |||
529 | clear_bit(REL_Y, dev->relbit); | 566 | clear_bit(REL_Y, dev->relbit); |
530 | } | 567 | } |
531 | 568 | ||
532 | void synaptics_reset(struct psmouse *psmouse) | ||
533 | { | ||
534 | /* reset touchpad back to relative mode, gestures enabled */ | ||
535 | synaptics_mode_cmd(psmouse, 0); | ||
536 | } | ||
537 | |||
538 | static void synaptics_disconnect(struct psmouse *psmouse) | 569 | static void synaptics_disconnect(struct psmouse *psmouse) |
539 | { | 570 | { |
540 | synaptics_reset(psmouse); | 571 | synaptics_reset(psmouse); |
@@ -569,30 +600,6 @@ static int synaptics_reconnect(struct psmouse *psmouse) | |||
569 | return 0; | 600 | return 0; |
570 | } | 601 | } |
571 | 602 | ||
572 | int synaptics_detect(struct psmouse *psmouse, int set_properties) | ||
573 | { | ||
574 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
575 | unsigned char param[4]; | ||
576 | |||
577 | param[0] = 0; | ||
578 | |||
579 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); | ||
580 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); | ||
581 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); | ||
582 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); | ||
583 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO); | ||
584 | |||
585 | if (param[1] != 0x47) | ||
586 | return -1; | ||
587 | |||
588 | if (set_properties) { | ||
589 | psmouse->vendor = "Synaptics"; | ||
590 | psmouse->name = "TouchPad"; | ||
591 | } | ||
592 | |||
593 | return 0; | ||
594 | } | ||
595 | |||
596 | #if defined(__i386__) | 603 | #if defined(__i386__) |
597 | #include <linux/dmi.h> | 604 | #include <linux/dmi.h> |
598 | static struct dmi_system_id toshiba_dmi_table[] = { | 605 | static struct dmi_system_id toshiba_dmi_table[] = { |
@@ -648,6 +655,16 @@ int synaptics_init(struct psmouse *psmouse) | |||
648 | 655 | ||
649 | set_input_params(psmouse->dev, priv); | 656 | set_input_params(psmouse->dev, priv); |
650 | 657 | ||
658 | /* | ||
659 | * Encode touchpad model so that it can be used to set | ||
660 | * input device->id.version and be visible to userspace. | ||
661 | * Because version is __u16 we have to drop something. | ||
662 | * Hardware info bits seem to be good candidates as they | ||
663 | * are documented to be for Synaptics corp. internal use. | ||
664 | */ | ||
665 | psmouse->model = ((priv->model_id & 0x00ff0000) >> 8) | | ||
666 | (priv->model_id & 0x000000ff); | ||
667 | |||
651 | psmouse->protocol_handler = synaptics_process_byte; | 668 | psmouse->protocol_handler = synaptics_process_byte; |
652 | psmouse->set_rate = synaptics_set_rate; | 669 | psmouse->set_rate = synaptics_set_rate; |
653 | psmouse->disconnect = synaptics_disconnect; | 670 | psmouse->disconnect = synaptics_disconnect; |
@@ -680,4 +697,12 @@ int synaptics_init(struct psmouse *psmouse) | |||
680 | return -1; | 697 | return -1; |
681 | } | 698 | } |
682 | 699 | ||
700 | #else /* CONFIG_MOUSE_PS2_SYNAPTICS */ | ||
701 | |||
702 | int synaptics_init(struct psmouse *psmouse) | ||
703 | { | ||
704 | return -ENOSYS; | ||
705 | } | ||
706 | |||
707 | #endif /* CONFIG_MOUSE_PS2_SYNAPTICS */ | ||
683 | 708 | ||
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index 68fff1dcd7de..02aa4cf7bc77 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h | |||
@@ -9,10 +9,6 @@ | |||
9 | #ifndef _SYNAPTICS_H | 9 | #ifndef _SYNAPTICS_H |
10 | #define _SYNAPTICS_H | 10 | #define _SYNAPTICS_H |
11 | 11 | ||
12 | extern int synaptics_detect(struct psmouse *psmouse, int set_properties); | ||
13 | extern int synaptics_init(struct psmouse *psmouse); | ||
14 | extern void synaptics_reset(struct psmouse *psmouse); | ||
15 | |||
16 | /* synaptics queries */ | 12 | /* synaptics queries */ |
17 | #define SYN_QUE_IDENTIFY 0x00 | 13 | #define SYN_QUE_IDENTIFY 0x00 |
18 | #define SYN_QUE_MODES 0x01 | 14 | #define SYN_QUE_MODES 0x01 |
@@ -62,9 +58,9 @@ extern void synaptics_reset(struct psmouse *psmouse); | |||
62 | #define SYN_MODE_WMODE(m) ((m) & (1 << 0)) | 58 | #define SYN_MODE_WMODE(m) ((m) & (1 << 0)) |
63 | 59 | ||
64 | /* synaptics identify query bits */ | 60 | /* synaptics identify query bits */ |
65 | #define SYN_ID_MODEL(i) (((i) >> 4) & 0x0f) | 61 | #define SYN_ID_MODEL(i) (((i) >> 4) & 0x0f) |
66 | #define SYN_ID_MAJOR(i) ((i) & 0x0f) | 62 | #define SYN_ID_MAJOR(i) ((i) & 0x0f) |
67 | #define SYN_ID_MINOR(i) (((i) >> 16) & 0xff) | 63 | #define SYN_ID_MINOR(i) (((i) >> 16) & 0xff) |
68 | #define SYN_ID_IS_SYNAPTICS(i) ((((i) >> 8) & 0xff) == 0x47) | 64 | #define SYN_ID_IS_SYNAPTICS(i) ((((i) >> 8) & 0xff) == 0x47) |
69 | 65 | ||
70 | /* synaptics special commands */ | 66 | /* synaptics special commands */ |
@@ -98,8 +94,8 @@ struct synaptics_hw_state { | |||
98 | struct synaptics_data { | 94 | struct synaptics_data { |
99 | /* Data read from the touchpad */ | 95 | /* Data read from the touchpad */ |
100 | unsigned long int model_id; /* Model-ID */ | 96 | unsigned long int model_id; /* Model-ID */ |
101 | unsigned long int capabilities; /* Capabilities */ | 97 | unsigned long int capabilities; /* Capabilities */ |
102 | unsigned long int ext_cap; /* Extended Capabilities */ | 98 | unsigned long int ext_cap; /* Extended Capabilities */ |
103 | unsigned long int identity; /* Identification */ | 99 | unsigned long int identity; /* Identification */ |
104 | 100 | ||
105 | unsigned char pkt_type; /* packet type - old, new, etc */ | 101 | unsigned char pkt_type; /* packet type - old, new, etc */ |
@@ -107,4 +103,8 @@ struct synaptics_data { | |||
107 | int scroll; | 103 | int scroll; |
108 | }; | 104 | }; |
109 | 105 | ||
106 | int synaptics_detect(struct psmouse *psmouse, int set_properties); | ||
107 | int synaptics_init(struct psmouse *psmouse); | ||
108 | void synaptics_reset(struct psmouse *psmouse); | ||
109 | |||
110 | #endif /* _SYNAPTICS_H */ | 110 | #endif /* _SYNAPTICS_H */ |
diff --git a/drivers/input/mouse/touchkit_ps2.c b/drivers/input/mouse/touchkit_ps2.c new file mode 100644 index 000000000000..7b977fd23571 --- /dev/null +++ b/drivers/input/mouse/touchkit_ps2.c | |||
@@ -0,0 +1,100 @@ | |||
1 | /* ---------------------------------------------------------------------------- | ||
2 | * touchkit_ps2.c -- Driver for eGalax TouchKit PS/2 Touchscreens | ||
3 | * | ||
4 | * Copyright (C) 2005 by Stefan Lucke | ||
5 | * Copyright (C) 2004 by Daniel Ritz | ||
6 | * Copyright (C) by Todd E. Johnson (mtouchusb.c) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License as | ||
10 | * published by the Free Software Foundation; either version 2 of the | ||
11 | * License, or (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | * | ||
22 | * Based upon touchkitusb.c | ||
23 | * | ||
24 | * Vendor documentation is available in support section of: | ||
25 | * http://www.egalax.com.tw/ | ||
26 | */ | ||
27 | |||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/slab.h> | ||
30 | |||
31 | #include <linux/input.h> | ||
32 | #include <linux/serio.h> | ||
33 | #include <linux/libps2.h> | ||
34 | |||
35 | #include "psmouse.h" | ||
36 | #include "touchkit_ps2.h" | ||
37 | |||
38 | #define TOUCHKIT_MAX_XC 0x07ff | ||
39 | #define TOUCHKIT_MAX_YC 0x07ff | ||
40 | |||
41 | #define TOUCHKIT_CMD 0x0a | ||
42 | #define TOUCHKIT_CMD_LENGTH 1 | ||
43 | |||
44 | #define TOUCHKIT_CMD_ACTIVE 'A' | ||
45 | #define TOUCHKIT_CMD_FIRMWARE_VERSION 'D' | ||
46 | #define TOUCHKIT_CMD_CONTROLLER_TYPE 'E' | ||
47 | |||
48 | #define TOUCHKIT_SEND_PARMS(s, r, c) ((s) << 12 | (r) << 8 | (c)) | ||
49 | |||
50 | #define TOUCHKIT_GET_TOUCHED(packet) (((packet)[0]) & 0x01) | ||
51 | #define TOUCHKIT_GET_X(packet) (((packet)[1] << 7) | (packet)[2]) | ||
52 | #define TOUCHKIT_GET_Y(packet) (((packet)[3] << 7) | (packet)[4]) | ||
53 | |||
54 | static psmouse_ret_t touchkit_ps2_process_byte(struct psmouse *psmouse) | ||
55 | { | ||
56 | unsigned char *packet = psmouse->packet; | ||
57 | struct input_dev *dev = psmouse->dev; | ||
58 | |||
59 | if (psmouse->pktcnt != 5) | ||
60 | return PSMOUSE_GOOD_DATA; | ||
61 | |||
62 | input_report_abs(dev, ABS_X, TOUCHKIT_GET_X(packet)); | ||
63 | input_report_abs(dev, ABS_Y, TOUCHKIT_GET_Y(packet)); | ||
64 | input_report_key(dev, BTN_TOUCH, TOUCHKIT_GET_TOUCHED(packet)); | ||
65 | input_sync(dev); | ||
66 | |||
67 | return PSMOUSE_FULL_PACKET; | ||
68 | } | ||
69 | |||
70 | int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties) | ||
71 | { | ||
72 | struct input_dev *dev = psmouse->dev; | ||
73 | unsigned char param[3]; | ||
74 | int command; | ||
75 | |||
76 | param[0] = TOUCHKIT_CMD_LENGTH; | ||
77 | param[1] = TOUCHKIT_CMD_ACTIVE; | ||
78 | command = TOUCHKIT_SEND_PARMS(2, 3, TOUCHKIT_CMD); | ||
79 | |||
80 | if (ps2_command(&psmouse->ps2dev, param, command)) | ||
81 | return -ENODEV; | ||
82 | |||
83 | if (param[0] != TOUCHKIT_CMD || param[1] != 0x01 || | ||
84 | param[2] != TOUCHKIT_CMD_ACTIVE) | ||
85 | return -ENODEV; | ||
86 | |||
87 | if (set_properties) { | ||
88 | dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | ||
89 | set_bit(BTN_TOUCH, dev->keybit); | ||
90 | input_set_abs_params(dev, ABS_X, 0, TOUCHKIT_MAX_XC, 0, 0); | ||
91 | input_set_abs_params(dev, ABS_Y, 0, TOUCHKIT_MAX_YC, 0, 0); | ||
92 | |||
93 | psmouse->vendor = "eGalax"; | ||
94 | psmouse->name = "Touchscreen"; | ||
95 | psmouse->protocol_handler = touchkit_ps2_process_byte; | ||
96 | psmouse->pktsize = 5; | ||
97 | } | ||
98 | |||
99 | return 0; | ||
100 | } | ||
diff --git a/drivers/input/mouse/touchkit_ps2.h b/drivers/input/mouse/touchkit_ps2.h new file mode 100644 index 000000000000..61e9dfd8419f --- /dev/null +++ b/drivers/input/mouse/touchkit_ps2.h | |||
@@ -0,0 +1,24 @@ | |||
1 | /* ---------------------------------------------------------------------------- | ||
2 | * touchkit_ps2.h -- Driver for eGalax TouchKit PS/2 Touchscreens | ||
3 | * | ||
4 | * Copyright (C) 2005 by Stefan Lucke | ||
5 | * Copyright (c) 2005 Vojtech Pavlik | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published by | ||
9 | * the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #ifndef _TOUCHKIT_PS2_H | ||
13 | #define _TOUCHKIT_PS2_H | ||
14 | |||
15 | #ifdef CONFIG_MOUSE_PS2_TOUCHKIT | ||
16 | int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties); | ||
17 | #else | ||
18 | inline int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties) | ||
19 | { | ||
20 | return -ENOSYS; | ||
21 | } | ||
22 | #endif /* CONFIG_MOUSE_PS2_TOUCHKIT */ | ||
23 | |||
24 | #endif | ||
diff --git a/drivers/input/mouse/trackpoint.h b/drivers/input/mouse/trackpoint.h index 050298b1a09d..c10a6e7d0101 100644 --- a/drivers/input/mouse/trackpoint.h +++ b/drivers/input/mouse/trackpoint.h | |||
@@ -142,6 +142,13 @@ struct trackpoint_data | |||
142 | unsigned char ext_dev; | 142 | unsigned char ext_dev; |
143 | }; | 143 | }; |
144 | 144 | ||
145 | extern int trackpoint_detect(struct psmouse *psmouse, int set_properties); | 145 | #ifdef CONFIG_MOUSE_PS2_TRACKPOINT |
146 | int trackpoint_detect(struct psmouse *psmouse, int set_properties); | ||
147 | #else | ||
148 | inline int trackpoint_detect(struct psmouse *psmouse, int set_properties) | ||
149 | { | ||
150 | return -ENOSYS; | ||
151 | } | ||
152 | #endif /* CONFIG_MOUSE_PS2_TRACKPOINT */ | ||
146 | 153 | ||
147 | #endif /* _TRACKPOINT_H */ | 154 | #endif /* _TRACKPOINT_H */ |
diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c index c3d64fcc858d..4a321576f345 100644 --- a/drivers/input/mouse/vsxxxaa.c +++ b/drivers/input/mouse/vsxxxaa.c | |||
@@ -508,8 +508,7 @@ vsxxxaa_connect (struct serio *serio, struct serio_driver *drv) | |||
508 | input_dev->name = mouse->name; | 508 | input_dev->name = mouse->name; |
509 | input_dev->phys = mouse->phys; | 509 | input_dev->phys = mouse->phys; |
510 | input_dev->id.bustype = BUS_RS232; | 510 | input_dev->id.bustype = BUS_RS232; |
511 | input_dev->cdev.dev = &serio->dev; | 511 | input_dev->dev.parent = &serio->dev; |
512 | input_dev->private = mouse; | ||
513 | 512 | ||
514 | set_bit (EV_KEY, input_dev->evbit); /* We have buttons */ | 513 | set_bit (EV_KEY, input_dev->evbit); /* We have buttons */ |
515 | set_bit (EV_REL, input_dev->evbit); | 514 | set_bit (EV_REL, input_dev->evbit); |
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 664bcc8116fc..7678e9876550 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c | |||
@@ -63,9 +63,12 @@ struct mousedev { | |||
63 | int minor; | 63 | int minor; |
64 | char name[16]; | 64 | char name[16]; |
65 | wait_queue_head_t wait; | 65 | wait_queue_head_t wait; |
66 | struct list_head list; | 66 | struct list_head client_list; |
67 | struct input_handle handle; | 67 | struct input_handle handle; |
68 | 68 | ||
69 | struct list_head mixdev_node; | ||
70 | int mixdev_open; | ||
71 | |||
69 | struct mousedev_hw_data packet; | 72 | struct mousedev_hw_data packet; |
70 | unsigned int pkt_count; | 73 | unsigned int pkt_count; |
71 | int old_x[4], old_y[4]; | 74 | int old_x[4], old_y[4]; |
@@ -85,7 +88,7 @@ struct mousedev_motion { | |||
85 | }; | 88 | }; |
86 | 89 | ||
87 | #define PACKET_QUEUE_LEN 16 | 90 | #define PACKET_QUEUE_LEN 16 |
88 | struct mousedev_list { | 91 | struct mousedev_client { |
89 | struct fasync_struct *fasync; | 92 | struct fasync_struct *fasync; |
90 | struct mousedev *mousedev; | 93 | struct mousedev *mousedev; |
91 | struct list_head node; | 94 | struct list_head node; |
@@ -111,6 +114,7 @@ static struct input_handler mousedev_handler; | |||
111 | 114 | ||
112 | static struct mousedev *mousedev_table[MOUSEDEV_MINORS]; | 115 | static struct mousedev *mousedev_table[MOUSEDEV_MINORS]; |
113 | static struct mousedev mousedev_mix; | 116 | static struct mousedev mousedev_mix; |
117 | static LIST_HEAD(mousedev_mix_list); | ||
114 | 118 | ||
115 | #define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03]) | 119 | #define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03]) |
116 | #define fy(i) (mousedev->old_y[(mousedev->pkt_count - (i)) & 03]) | 120 | #define fy(i) (mousedev->old_y[(mousedev->pkt_count - (i)) & 03]) |
@@ -120,32 +124,33 @@ static void mousedev_touchpad_event(struct input_dev *dev, struct mousedev *mous | |||
120 | int size, tmp; | 124 | int size, tmp; |
121 | enum { FRACTION_DENOM = 128 }; | 125 | enum { FRACTION_DENOM = 128 }; |
122 | 126 | ||
123 | if (mousedev->touch) { | 127 | switch (code) { |
124 | size = dev->absmax[ABS_X] - dev->absmin[ABS_X]; | 128 | case ABS_X: |
125 | if (size == 0) | 129 | fx(0) = value; |
126 | size = 256 * 2; | 130 | if (mousedev->touch && mousedev->pkt_count >= 2) { |
127 | 131 | size = dev->absmax[ABS_X] - dev->absmin[ABS_X]; | |
128 | switch (code) { | 132 | if (size == 0) |
129 | case ABS_X: | 133 | size = 256 * 2; |
130 | fx(0) = value; | 134 | tmp = ((value - fx(2)) * (256 * FRACTION_DENOM)) / size; |
131 | if (mousedev->pkt_count >= 2) { | 135 | tmp += mousedev->frac_dx; |
132 | tmp = ((value - fx(2)) * (256 * FRACTION_DENOM)) / size; | 136 | mousedev->packet.dx = tmp / FRACTION_DENOM; |
133 | tmp += mousedev->frac_dx; | 137 | mousedev->frac_dx = tmp - mousedev->packet.dx * FRACTION_DENOM; |
134 | mousedev->packet.dx = tmp / FRACTION_DENOM; | 138 | } |
135 | mousedev->frac_dx = tmp - mousedev->packet.dx * FRACTION_DENOM; | 139 | break; |
136 | } | ||
137 | break; | ||
138 | 140 | ||
139 | case ABS_Y: | 141 | case ABS_Y: |
140 | fy(0) = value; | 142 | fy(0) = value; |
141 | if (mousedev->pkt_count >= 2) { | 143 | if (mousedev->touch && mousedev->pkt_count >= 2) { |
142 | tmp = -((value - fy(2)) * (256 * FRACTION_DENOM)) / size; | 144 | /* use X size to keep the same scale */ |
143 | tmp += mousedev->frac_dy; | 145 | size = dev->absmax[ABS_X] - dev->absmin[ABS_X]; |
144 | mousedev->packet.dy = tmp / FRACTION_DENOM; | 146 | if (size == 0) |
145 | mousedev->frac_dy = tmp - mousedev->packet.dy * FRACTION_DENOM; | 147 | size = 256 * 2; |
146 | } | 148 | tmp = -((value - fy(2)) * (256 * FRACTION_DENOM)) / size; |
147 | break; | 149 | tmp += mousedev->frac_dy; |
148 | } | 150 | mousedev->packet.dy = tmp / FRACTION_DENOM; |
151 | mousedev->frac_dy = tmp - mousedev->packet.dy * FRACTION_DENOM; | ||
152 | } | ||
153 | break; | ||
149 | } | 154 | } |
150 | } | 155 | } |
151 | 156 | ||
@@ -223,47 +228,47 @@ static void mousedev_key_event(struct mousedev *mousedev, unsigned int code, int | |||
223 | 228 | ||
224 | static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_hw_data *packet) | 229 | static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_hw_data *packet) |
225 | { | 230 | { |
226 | struct mousedev_list *list; | 231 | struct mousedev_client *client; |
227 | struct mousedev_motion *p; | 232 | struct mousedev_motion *p; |
228 | unsigned long flags; | 233 | unsigned long flags; |
229 | int wake_readers = 0; | 234 | int wake_readers = 0; |
230 | 235 | ||
231 | list_for_each_entry(list, &mousedev->list, node) { | 236 | list_for_each_entry(client, &mousedev->client_list, node) { |
232 | spin_lock_irqsave(&list->packet_lock, flags); | 237 | spin_lock_irqsave(&client->packet_lock, flags); |
233 | 238 | ||
234 | p = &list->packets[list->head]; | 239 | p = &client->packets[client->head]; |
235 | if (list->ready && p->buttons != mousedev->packet.buttons) { | 240 | if (client->ready && p->buttons != mousedev->packet.buttons) { |
236 | unsigned int new_head = (list->head + 1) % PACKET_QUEUE_LEN; | 241 | unsigned int new_head = (client->head + 1) % PACKET_QUEUE_LEN; |
237 | if (new_head != list->tail) { | 242 | if (new_head != client->tail) { |
238 | p = &list->packets[list->head = new_head]; | 243 | p = &client->packets[client->head = new_head]; |
239 | memset(p, 0, sizeof(struct mousedev_motion)); | 244 | memset(p, 0, sizeof(struct mousedev_motion)); |
240 | } | 245 | } |
241 | } | 246 | } |
242 | 247 | ||
243 | if (packet->abs_event) { | 248 | if (packet->abs_event) { |
244 | p->dx += packet->x - list->pos_x; | 249 | p->dx += packet->x - client->pos_x; |
245 | p->dy += packet->y - list->pos_y; | 250 | p->dy += packet->y - client->pos_y; |
246 | list->pos_x = packet->x; | 251 | client->pos_x = packet->x; |
247 | list->pos_y = packet->y; | 252 | client->pos_y = packet->y; |
248 | } | 253 | } |
249 | 254 | ||
250 | list->pos_x += packet->dx; | 255 | client->pos_x += packet->dx; |
251 | list->pos_x = list->pos_x < 0 ? 0 : (list->pos_x >= xres ? xres : list->pos_x); | 256 | client->pos_x = client->pos_x < 0 ? 0 : (client->pos_x >= xres ? xres : client->pos_x); |
252 | list->pos_y += packet->dy; | 257 | client->pos_y += packet->dy; |
253 | list->pos_y = list->pos_y < 0 ? 0 : (list->pos_y >= yres ? yres : list->pos_y); | 258 | client->pos_y = client->pos_y < 0 ? 0 : (client->pos_y >= yres ? yres : client->pos_y); |
254 | 259 | ||
255 | p->dx += packet->dx; | 260 | p->dx += packet->dx; |
256 | p->dy += packet->dy; | 261 | p->dy += packet->dy; |
257 | p->dz += packet->dz; | 262 | p->dz += packet->dz; |
258 | p->buttons = mousedev->packet.buttons; | 263 | p->buttons = mousedev->packet.buttons; |
259 | 264 | ||
260 | if (p->dx || p->dy || p->dz || p->buttons != list->last_buttons) | 265 | if (p->dx || p->dy || p->dz || p->buttons != client->last_buttons) |
261 | list->ready = 1; | 266 | client->ready = 1; |
262 | 267 | ||
263 | spin_unlock_irqrestore(&list->packet_lock, flags); | 268 | spin_unlock_irqrestore(&client->packet_lock, flags); |
264 | 269 | ||
265 | if (list->ready) { | 270 | if (client->ready) { |
266 | kill_fasync(&list->fasync, SIGIO, POLL_IN); | 271 | kill_fasync(&client->fasync, SIGIO, POLL_IN); |
267 | wake_readers = 1; | 272 | wake_readers = 1; |
268 | } | 273 | } |
269 | } | 274 | } |
@@ -351,9 +356,9 @@ static void mousedev_event(struct input_handle *handle, unsigned int type, unsig | |||
351 | static int mousedev_fasync(int fd, struct file *file, int on) | 356 | static int mousedev_fasync(int fd, struct file *file, int on) |
352 | { | 357 | { |
353 | int retval; | 358 | int retval; |
354 | struct mousedev_list *list = file->private_data; | 359 | struct mousedev_client *client = file->private_data; |
355 | 360 | ||
356 | retval = fasync_helper(fd, file, on, &list->fasync); | 361 | retval = fasync_helper(fd, file, on, &client->fasync); |
357 | 362 | ||
358 | return retval < 0 ? retval : 0; | 363 | return retval < 0 ? retval : 0; |
359 | } | 364 | } |
@@ -364,50 +369,95 @@ static void mousedev_free(struct mousedev *mousedev) | |||
364 | kfree(mousedev); | 369 | kfree(mousedev); |
365 | } | 370 | } |
366 | 371 | ||
367 | static void mixdev_release(void) | 372 | static int mixdev_add_device(struct mousedev *mousedev) |
368 | { | 373 | { |
369 | struct input_handle *handle; | 374 | int error; |
370 | 375 | ||
371 | list_for_each_entry(handle, &mousedev_handler.h_list, h_node) { | 376 | if (mousedev_mix.open) { |
372 | struct mousedev *mousedev = handle->private; | 377 | error = input_open_device(&mousedev->handle); |
378 | if (error) | ||
379 | return error; | ||
373 | 380 | ||
374 | if (!mousedev->open) { | 381 | mousedev->open++; |
375 | if (mousedev->exist) | 382 | mousedev->mixdev_open++; |
376 | input_close_device(&mousedev->handle); | 383 | } |
377 | else | 384 | |
378 | mousedev_free(mousedev); | 385 | list_add_tail(&mousedev->mixdev_node, &mousedev_mix_list); |
386 | |||
387 | return 0; | ||
388 | } | ||
389 | |||
390 | static void mixdev_remove_device(struct mousedev *mousedev) | ||
391 | { | ||
392 | if (mousedev->mixdev_open) { | ||
393 | mousedev->mixdev_open = 0; | ||
394 | if (!--mousedev->open && mousedev->exist) | ||
395 | input_close_device(&mousedev->handle); | ||
396 | } | ||
397 | |||
398 | list_del_init(&mousedev->mixdev_node); | ||
399 | } | ||
400 | |||
401 | static void mixdev_open_devices(void) | ||
402 | { | ||
403 | struct mousedev *mousedev; | ||
404 | |||
405 | list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) { | ||
406 | if (mousedev->exist && !mousedev->open) { | ||
407 | if (input_open_device(&mousedev->handle)) | ||
408 | continue; | ||
409 | |||
410 | mousedev->open++; | ||
411 | mousedev->mixdev_open++; | ||
412 | } | ||
413 | } | ||
414 | } | ||
415 | |||
416 | static void mixdev_close_devices(void) | ||
417 | { | ||
418 | struct mousedev *mousedev, *next; | ||
419 | |||
420 | list_for_each_entry_safe(mousedev, next, &mousedev_mix_list, mixdev_node) { | ||
421 | if (mousedev->mixdev_open) { | ||
422 | mousedev->mixdev_open = 0; | ||
423 | if (!--mousedev->open) { | ||
424 | if (mousedev->exist) | ||
425 | input_close_device(&mousedev->handle); | ||
426 | else | ||
427 | mousedev_free(mousedev); | ||
428 | } | ||
379 | } | 429 | } |
380 | } | 430 | } |
381 | } | 431 | } |
382 | 432 | ||
383 | static int mousedev_release(struct inode * inode, struct file * file) | 433 | static int mousedev_release(struct inode *inode, struct file *file) |
384 | { | 434 | { |
385 | struct mousedev_list *list = file->private_data; | 435 | struct mousedev_client *client = file->private_data; |
436 | struct mousedev *mousedev = client->mousedev; | ||
386 | 437 | ||
387 | mousedev_fasync(-1, file, 0); | 438 | mousedev_fasync(-1, file, 0); |
388 | 439 | ||
389 | list_del(&list->node); | 440 | list_del(&client->node); |
441 | kfree(client); | ||
390 | 442 | ||
391 | if (!--list->mousedev->open) { | 443 | if (!--mousedev->open) { |
392 | if (list->mousedev->minor == MOUSEDEV_MIX) | 444 | if (mousedev->minor == MOUSEDEV_MIX) |
393 | mixdev_release(); | 445 | mixdev_close_devices(); |
394 | else if (!mousedev_mix.open) { | 446 | else if (mousedev->exist) |
395 | if (list->mousedev->exist) | 447 | input_close_device(&mousedev->handle); |
396 | input_close_device(&list->mousedev->handle); | 448 | else |
397 | else | 449 | mousedev_free(mousedev); |
398 | mousedev_free(list->mousedev); | ||
399 | } | ||
400 | } | 450 | } |
401 | 451 | ||
402 | kfree(list); | ||
403 | return 0; | 452 | return 0; |
404 | } | 453 | } |
405 | 454 | ||
406 | static int mousedev_open(struct inode * inode, struct file * file) | 455 | |
456 | static int mousedev_open(struct inode *inode, struct file *file) | ||
407 | { | 457 | { |
408 | struct mousedev_list *list; | 458 | struct mousedev_client *client; |
409 | struct input_handle *handle; | ||
410 | struct mousedev *mousedev; | 459 | struct mousedev *mousedev; |
460 | int error; | ||
411 | int i; | 461 | int i; |
412 | 462 | ||
413 | #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX | 463 | #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX |
@@ -417,31 +467,37 @@ static int mousedev_open(struct inode * inode, struct file * file) | |||
417 | #endif | 467 | #endif |
418 | i = iminor(inode) - MOUSEDEV_MINOR_BASE; | 468 | i = iminor(inode) - MOUSEDEV_MINOR_BASE; |
419 | 469 | ||
420 | if (i >= MOUSEDEV_MINORS || !mousedev_table[i]) | 470 | if (i >= MOUSEDEV_MINORS) |
471 | return -ENODEV; | ||
472 | |||
473 | mousedev = mousedev_table[i]; | ||
474 | if (!mousedev) | ||
421 | return -ENODEV; | 475 | return -ENODEV; |
422 | 476 | ||
423 | if (!(list = kzalloc(sizeof(struct mousedev_list), GFP_KERNEL))) | 477 | client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL); |
478 | if (!client) | ||
424 | return -ENOMEM; | 479 | return -ENOMEM; |
425 | 480 | ||
426 | spin_lock_init(&list->packet_lock); | 481 | spin_lock_init(&client->packet_lock); |
427 | list->pos_x = xres / 2; | 482 | client->pos_x = xres / 2; |
428 | list->pos_y = yres / 2; | 483 | client->pos_y = yres / 2; |
429 | list->mousedev = mousedev_table[i]; | 484 | client->mousedev = mousedev; |
430 | list_add_tail(&list->node, &mousedev_table[i]->list); | 485 | list_add_tail(&client->node, &mousedev->client_list); |
431 | file->private_data = list; | 486 | |
432 | 487 | if (!mousedev->open++) { | |
433 | if (!list->mousedev->open++) { | 488 | if (mousedev->minor == MOUSEDEV_MIX) |
434 | if (list->mousedev->minor == MOUSEDEV_MIX) { | 489 | mixdev_open_devices(); |
435 | list_for_each_entry(handle, &mousedev_handler.h_list, h_node) { | 490 | else if (mousedev->exist) { |
436 | mousedev = handle->private; | 491 | error = input_open_device(&mousedev->handle); |
437 | if (!mousedev->open && mousedev->exist) | 492 | if (error) { |
438 | input_open_device(handle); | 493 | list_del(&client->node); |
494 | kfree(client); | ||
495 | return error; | ||
439 | } | 496 | } |
440 | } else | 497 | } |
441 | if (!mousedev_mix.open && list->mousedev->exist) | ||
442 | input_open_device(&list->mousedev->handle); | ||
443 | } | 498 | } |
444 | 499 | ||
500 | file->private_data = client; | ||
445 | return 0; | 501 | return 0; |
446 | } | 502 | } |
447 | 503 | ||
@@ -450,13 +506,13 @@ static inline int mousedev_limit_delta(int delta, int limit) | |||
450 | return delta > limit ? limit : (delta < -limit ? -limit : delta); | 506 | return delta > limit ? limit : (delta < -limit ? -limit : delta); |
451 | } | 507 | } |
452 | 508 | ||
453 | static void mousedev_packet(struct mousedev_list *list, signed char *ps2_data) | 509 | static void mousedev_packet(struct mousedev_client *client, signed char *ps2_data) |
454 | { | 510 | { |
455 | struct mousedev_motion *p; | 511 | struct mousedev_motion *p; |
456 | unsigned long flags; | 512 | unsigned long flags; |
457 | 513 | ||
458 | spin_lock_irqsave(&list->packet_lock, flags); | 514 | spin_lock_irqsave(&client->packet_lock, flags); |
459 | p = &list->packets[list->tail]; | 515 | p = &client->packets[client->tail]; |
460 | 516 | ||
461 | ps2_data[0] = 0x08 | ((p->dx < 0) << 4) | ((p->dy < 0) << 5) | (p->buttons & 0x07); | 517 | ps2_data[0] = 0x08 | ((p->dx < 0) << 4) | ((p->dy < 0) << 5) | (p->buttons & 0x07); |
462 | ps2_data[1] = mousedev_limit_delta(p->dx, 127); | 518 | ps2_data[1] = mousedev_limit_delta(p->dx, 127); |
@@ -464,44 +520,44 @@ static void mousedev_packet(struct mousedev_list *list, signed char *ps2_data) | |||
464 | p->dx -= ps2_data[1]; | 520 | p->dx -= ps2_data[1]; |
465 | p->dy -= ps2_data[2]; | 521 | p->dy -= ps2_data[2]; |
466 | 522 | ||
467 | switch (list->mode) { | 523 | switch (client->mode) { |
468 | case MOUSEDEV_EMUL_EXPS: | 524 | case MOUSEDEV_EMUL_EXPS: |
469 | ps2_data[3] = mousedev_limit_delta(p->dz, 7); | 525 | ps2_data[3] = mousedev_limit_delta(p->dz, 7); |
470 | p->dz -= ps2_data[3]; | 526 | p->dz -= ps2_data[3]; |
471 | ps2_data[3] = (ps2_data[3] & 0x0f) | ((p->buttons & 0x18) << 1); | 527 | ps2_data[3] = (ps2_data[3] & 0x0f) | ((p->buttons & 0x18) << 1); |
472 | list->bufsiz = 4; | 528 | client->bufsiz = 4; |
473 | break; | 529 | break; |
474 | 530 | ||
475 | case MOUSEDEV_EMUL_IMPS: | 531 | case MOUSEDEV_EMUL_IMPS: |
476 | ps2_data[0] |= ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1); | 532 | ps2_data[0] |= ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1); |
477 | ps2_data[3] = mousedev_limit_delta(p->dz, 127); | 533 | ps2_data[3] = mousedev_limit_delta(p->dz, 127); |
478 | p->dz -= ps2_data[3]; | 534 | p->dz -= ps2_data[3]; |
479 | list->bufsiz = 4; | 535 | client->bufsiz = 4; |
480 | break; | 536 | break; |
481 | 537 | ||
482 | case MOUSEDEV_EMUL_PS2: | 538 | case MOUSEDEV_EMUL_PS2: |
483 | default: | 539 | default: |
484 | ps2_data[0] |= ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1); | 540 | ps2_data[0] |= ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1); |
485 | p->dz = 0; | 541 | p->dz = 0; |
486 | list->bufsiz = 3; | 542 | client->bufsiz = 3; |
487 | break; | 543 | break; |
488 | } | 544 | } |
489 | 545 | ||
490 | if (!p->dx && !p->dy && !p->dz) { | 546 | if (!p->dx && !p->dy && !p->dz) { |
491 | if (list->tail == list->head) { | 547 | if (client->tail == client->head) { |
492 | list->ready = 0; | 548 | client->ready = 0; |
493 | list->last_buttons = p->buttons; | 549 | client->last_buttons = p->buttons; |
494 | } else | 550 | } else |
495 | list->tail = (list->tail + 1) % PACKET_QUEUE_LEN; | 551 | client->tail = (client->tail + 1) % PACKET_QUEUE_LEN; |
496 | } | 552 | } |
497 | 553 | ||
498 | spin_unlock_irqrestore(&list->packet_lock, flags); | 554 | spin_unlock_irqrestore(&client->packet_lock, flags); |
499 | } | 555 | } |
500 | 556 | ||
501 | 557 | ||
502 | static ssize_t mousedev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos) | 558 | static ssize_t mousedev_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) |
503 | { | 559 | { |
504 | struct mousedev_list *list = file->private_data; | 560 | struct mousedev_client *client = file->private_data; |
505 | unsigned char c; | 561 | unsigned char c; |
506 | unsigned int i; | 562 | unsigned int i; |
507 | 563 | ||
@@ -510,95 +566,95 @@ static ssize_t mousedev_write(struct file * file, const char __user * buffer, si | |||
510 | if (get_user(c, buffer + i)) | 566 | if (get_user(c, buffer + i)) |
511 | return -EFAULT; | 567 | return -EFAULT; |
512 | 568 | ||
513 | if (c == mousedev_imex_seq[list->imexseq]) { | 569 | if (c == mousedev_imex_seq[client->imexseq]) { |
514 | if (++list->imexseq == MOUSEDEV_SEQ_LEN) { | 570 | if (++client->imexseq == MOUSEDEV_SEQ_LEN) { |
515 | list->imexseq = 0; | 571 | client->imexseq = 0; |
516 | list->mode = MOUSEDEV_EMUL_EXPS; | 572 | client->mode = MOUSEDEV_EMUL_EXPS; |
517 | } | 573 | } |
518 | } else | 574 | } else |
519 | list->imexseq = 0; | 575 | client->imexseq = 0; |
520 | 576 | ||
521 | if (c == mousedev_imps_seq[list->impsseq]) { | 577 | if (c == mousedev_imps_seq[client->impsseq]) { |
522 | if (++list->impsseq == MOUSEDEV_SEQ_LEN) { | 578 | if (++client->impsseq == MOUSEDEV_SEQ_LEN) { |
523 | list->impsseq = 0; | 579 | client->impsseq = 0; |
524 | list->mode = MOUSEDEV_EMUL_IMPS; | 580 | client->mode = MOUSEDEV_EMUL_IMPS; |
525 | } | 581 | } |
526 | } else | 582 | } else |
527 | list->impsseq = 0; | 583 | client->impsseq = 0; |
528 | 584 | ||
529 | list->ps2[0] = 0xfa; | 585 | client->ps2[0] = 0xfa; |
530 | 586 | ||
531 | switch (c) { | 587 | switch (c) { |
532 | 588 | ||
533 | case 0xeb: /* Poll */ | 589 | case 0xeb: /* Poll */ |
534 | mousedev_packet(list, &list->ps2[1]); | 590 | mousedev_packet(client, &client->ps2[1]); |
535 | list->bufsiz++; /* account for leading ACK */ | 591 | client->bufsiz++; /* account for leading ACK */ |
536 | break; | 592 | break; |
537 | 593 | ||
538 | case 0xf2: /* Get ID */ | 594 | case 0xf2: /* Get ID */ |
539 | switch (list->mode) { | 595 | switch (client->mode) { |
540 | case MOUSEDEV_EMUL_PS2: list->ps2[1] = 0; break; | 596 | case MOUSEDEV_EMUL_PS2: client->ps2[1] = 0; break; |
541 | case MOUSEDEV_EMUL_IMPS: list->ps2[1] = 3; break; | 597 | case MOUSEDEV_EMUL_IMPS: client->ps2[1] = 3; break; |
542 | case MOUSEDEV_EMUL_EXPS: list->ps2[1] = 4; break; | 598 | case MOUSEDEV_EMUL_EXPS: client->ps2[1] = 4; break; |
543 | } | 599 | } |
544 | list->bufsiz = 2; | 600 | client->bufsiz = 2; |
545 | break; | 601 | break; |
546 | 602 | ||
547 | case 0xe9: /* Get info */ | 603 | case 0xe9: /* Get info */ |
548 | list->ps2[1] = 0x60; list->ps2[2] = 3; list->ps2[3] = 200; | 604 | client->ps2[1] = 0x60; client->ps2[2] = 3; client->ps2[3] = 200; |
549 | list->bufsiz = 4; | 605 | client->bufsiz = 4; |
550 | break; | 606 | break; |
551 | 607 | ||
552 | case 0xff: /* Reset */ | 608 | case 0xff: /* Reset */ |
553 | list->impsseq = list->imexseq = 0; | 609 | client->impsseq = client->imexseq = 0; |
554 | list->mode = MOUSEDEV_EMUL_PS2; | 610 | client->mode = MOUSEDEV_EMUL_PS2; |
555 | list->ps2[1] = 0xaa; list->ps2[2] = 0x00; | 611 | client->ps2[1] = 0xaa; client->ps2[2] = 0x00; |
556 | list->bufsiz = 3; | 612 | client->bufsiz = 3; |
557 | break; | 613 | break; |
558 | 614 | ||
559 | default: | 615 | default: |
560 | list->bufsiz = 1; | 616 | client->bufsiz = 1; |
561 | break; | 617 | break; |
562 | } | 618 | } |
563 | 619 | ||
564 | list->buffer = list->bufsiz; | 620 | client->buffer = client->bufsiz; |
565 | } | 621 | } |
566 | 622 | ||
567 | kill_fasync(&list->fasync, SIGIO, POLL_IN); | 623 | kill_fasync(&client->fasync, SIGIO, POLL_IN); |
568 | 624 | ||
569 | wake_up_interruptible(&list->mousedev->wait); | 625 | wake_up_interruptible(&client->mousedev->wait); |
570 | 626 | ||
571 | return count; | 627 | return count; |
572 | } | 628 | } |
573 | 629 | ||
574 | static ssize_t mousedev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos) | 630 | static ssize_t mousedev_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) |
575 | { | 631 | { |
576 | struct mousedev_list *list = file->private_data; | 632 | struct mousedev_client *client = file->private_data; |
577 | int retval = 0; | 633 | int retval = 0; |
578 | 634 | ||
579 | if (!list->ready && !list->buffer && (file->f_flags & O_NONBLOCK)) | 635 | if (!client->ready && !client->buffer && (file->f_flags & O_NONBLOCK)) |
580 | return -EAGAIN; | 636 | return -EAGAIN; |
581 | 637 | ||
582 | retval = wait_event_interruptible(list->mousedev->wait, | 638 | retval = wait_event_interruptible(client->mousedev->wait, |
583 | !list->mousedev->exist || list->ready || list->buffer); | 639 | !client->mousedev->exist || client->ready || client->buffer); |
584 | 640 | ||
585 | if (retval) | 641 | if (retval) |
586 | return retval; | 642 | return retval; |
587 | 643 | ||
588 | if (!list->mousedev->exist) | 644 | if (!client->mousedev->exist) |
589 | return -ENODEV; | 645 | return -ENODEV; |
590 | 646 | ||
591 | if (!list->buffer && list->ready) { | 647 | if (!client->buffer && client->ready) { |
592 | mousedev_packet(list, list->ps2); | 648 | mousedev_packet(client, client->ps2); |
593 | list->buffer = list->bufsiz; | 649 | client->buffer = client->bufsiz; |
594 | } | 650 | } |
595 | 651 | ||
596 | if (count > list->buffer) | 652 | if (count > client->buffer) |
597 | count = list->buffer; | 653 | count = client->buffer; |
598 | 654 | ||
599 | list->buffer -= count; | 655 | client->buffer -= count; |
600 | 656 | ||
601 | if (copy_to_user(buffer, list->ps2 + list->bufsiz - list->buffer - count, count)) | 657 | if (copy_to_user(buffer, client->ps2 + client->bufsiz - client->buffer - count, count)) |
602 | return -EFAULT; | 658 | return -EFAULT; |
603 | 659 | ||
604 | return count; | 660 | return count; |
@@ -607,11 +663,12 @@ static ssize_t mousedev_read(struct file * file, char __user * buffer, size_t co | |||
607 | /* No kernel lock - fine */ | 663 | /* No kernel lock - fine */ |
608 | static unsigned int mousedev_poll(struct file *file, poll_table *wait) | 664 | static unsigned int mousedev_poll(struct file *file, poll_table *wait) |
609 | { | 665 | { |
610 | struct mousedev_list *list = file->private_data; | 666 | struct mousedev_client *client = file->private_data; |
667 | struct mousedev *mousedev = client->mousedev; | ||
611 | 668 | ||
612 | poll_wait(file, &list->mousedev->wait, wait); | 669 | poll_wait(file, &mousedev->wait, wait); |
613 | return ((list->ready || list->buffer) ? (POLLIN | POLLRDNORM) : 0) | | 670 | return ((client->ready || client->buffer) ? (POLLIN | POLLRDNORM) : 0) | |
614 | (list->mousedev->exist ? 0 : (POLLHUP | POLLERR)); | 671 | (mousedev->exist ? 0 : (POLLHUP | POLLERR)); |
615 | } | 672 | } |
616 | 673 | ||
617 | static const struct file_operations mousedev_fops = { | 674 | static const struct file_operations mousedev_fops = { |
@@ -624,23 +681,27 @@ static const struct file_operations mousedev_fops = { | |||
624 | .fasync = mousedev_fasync, | 681 | .fasync = mousedev_fasync, |
625 | }; | 682 | }; |
626 | 683 | ||
627 | static struct input_handle *mousedev_connect(struct input_handler *handler, struct input_dev *dev, | 684 | static int mousedev_connect(struct input_handler *handler, struct input_dev *dev, |
628 | const struct input_device_id *id) | 685 | const struct input_device_id *id) |
629 | { | 686 | { |
630 | struct mousedev *mousedev; | 687 | struct mousedev *mousedev; |
631 | struct class_device *cdev; | 688 | struct class_device *cdev; |
632 | int minor = 0; | 689 | dev_t devt; |
690 | int minor; | ||
691 | int error; | ||
633 | 692 | ||
634 | for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++); | 693 | for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++); |
635 | if (minor == MOUSEDEV_MINORS) { | 694 | if (minor == MOUSEDEV_MINORS) { |
636 | printk(KERN_ERR "mousedev: no more free mousedev devices\n"); | 695 | printk(KERN_ERR "mousedev: no more free mousedev devices\n"); |
637 | return NULL; | 696 | return -ENFILE; |
638 | } | 697 | } |
639 | 698 | ||
640 | if (!(mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL))) | 699 | mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL); |
641 | return NULL; | 700 | if (!mousedev) |
701 | return -ENOMEM; | ||
642 | 702 | ||
643 | INIT_LIST_HEAD(&mousedev->list); | 703 | INIT_LIST_HEAD(&mousedev->client_list); |
704 | INIT_LIST_HEAD(&mousedev->mixdev_node); | ||
644 | init_waitqueue_head(&mousedev->wait); | 705 | init_waitqueue_head(&mousedev->wait); |
645 | 706 | ||
646 | mousedev->minor = minor; | 707 | mousedev->minor = minor; |
@@ -651,42 +712,66 @@ static struct input_handle *mousedev_connect(struct input_handler *handler, stru | |||
651 | mousedev->handle.private = mousedev; | 712 | mousedev->handle.private = mousedev; |
652 | sprintf(mousedev->name, "mouse%d", minor); | 713 | sprintf(mousedev->name, "mouse%d", minor); |
653 | 714 | ||
654 | if (mousedev_mix.open) | ||
655 | input_open_device(&mousedev->handle); | ||
656 | |||
657 | mousedev_table[minor] = mousedev; | 715 | mousedev_table[minor] = mousedev; |
658 | 716 | ||
659 | cdev = class_device_create(&input_class, &dev->cdev, | 717 | devt = MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor), |
660 | MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor), | 718 | |
661 | dev->cdev.dev, mousedev->name); | 719 | cdev = class_device_create(&input_class, &dev->cdev, devt, |
720 | dev->cdev.dev, mousedev->name); | ||
721 | if (IS_ERR(cdev)) { | ||
722 | error = PTR_ERR(cdev); | ||
723 | goto err_free_mousedev; | ||
724 | } | ||
662 | 725 | ||
663 | /* temporary symlink to keep userspace happy */ | 726 | /* temporary symlink to keep userspace happy */ |
664 | sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj, | 727 | error = sysfs_create_link(&input_class.subsys.kobj, |
665 | mousedev->name); | 728 | &cdev->kobj, mousedev->name); |
729 | if (error) | ||
730 | goto err_cdev_destroy; | ||
731 | |||
732 | error = input_register_handle(&mousedev->handle); | ||
733 | if (error) | ||
734 | goto err_remove_link; | ||
735 | |||
736 | error = mixdev_add_device(mousedev); | ||
737 | if (error) | ||
738 | goto err_unregister_handle; | ||
739 | |||
740 | return 0; | ||
666 | 741 | ||
667 | return &mousedev->handle; | 742 | err_unregister_handle: |
743 | input_unregister_handle(&mousedev->handle); | ||
744 | err_remove_link: | ||
745 | sysfs_remove_link(&input_class.subsys.kobj, mousedev->name); | ||
746 | err_cdev_destroy: | ||
747 | class_device_destroy(&input_class, devt); | ||
748 | err_free_mousedev: | ||
749 | mousedev_table[minor] = NULL; | ||
750 | kfree(mousedev); | ||
751 | return error; | ||
668 | } | 752 | } |
669 | 753 | ||
670 | static void mousedev_disconnect(struct input_handle *handle) | 754 | static void mousedev_disconnect(struct input_handle *handle) |
671 | { | 755 | { |
672 | struct mousedev *mousedev = handle->private; | 756 | struct mousedev *mousedev = handle->private; |
673 | struct mousedev_list *list; | 757 | struct mousedev_client *client; |
674 | 758 | ||
675 | sysfs_remove_link(&input_class.subsys.kset.kobj, mousedev->name); | 759 | input_unregister_handle(handle); |
760 | |||
761 | sysfs_remove_link(&input_class.subsys.kobj, mousedev->name); | ||
676 | class_device_destroy(&input_class, | 762 | class_device_destroy(&input_class, |
677 | MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor)); | 763 | MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor)); |
678 | mousedev->exist = 0; | 764 | mousedev->exist = 0; |
679 | 765 | ||
766 | mixdev_remove_device(mousedev); | ||
767 | |||
680 | if (mousedev->open) { | 768 | if (mousedev->open) { |
681 | input_close_device(handle); | 769 | input_close_device(handle); |
682 | wake_up_interruptible(&mousedev->wait); | 770 | wake_up_interruptible(&mousedev->wait); |
683 | list_for_each_entry(list, &mousedev->list, node) | 771 | list_for_each_entry(client, &mousedev->client_list, node) |
684 | kill_fasync(&list->fasync, SIGIO, POLL_HUP); | 772 | kill_fasync(&client->fasync, SIGIO, POLL_HUP); |
685 | } else { | 773 | } else |
686 | if (mousedev_mix.open) | ||
687 | input_close_device(handle); | ||
688 | mousedev_free(mousedev); | 774 | mousedev_free(mousedev); |
689 | } | ||
690 | } | 775 | } |
691 | 776 | ||
692 | static const struct input_device_id mousedev_ids[] = { | 777 | static const struct input_device_id mousedev_ids[] = { |
@@ -714,7 +799,7 @@ static const struct input_device_id mousedev_ids[] = { | |||
714 | .absbit = { BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) | BIT(ABS_TOOL_WIDTH) }, | 799 | .absbit = { BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) | BIT(ABS_TOOL_WIDTH) }, |
715 | }, /* A touchpad */ | 800 | }, /* A touchpad */ |
716 | 801 | ||
717 | { }, /* Terminating entry */ | 802 | { }, /* Terminating entry */ |
718 | }; | 803 | }; |
719 | 804 | ||
720 | MODULE_DEVICE_TABLE(input, mousedev_ids); | 805 | MODULE_DEVICE_TABLE(input, mousedev_ids); |
@@ -746,7 +831,7 @@ static int __init mousedev_init(void) | |||
746 | return error; | 831 | return error; |
747 | 832 | ||
748 | memset(&mousedev_mix, 0, sizeof(struct mousedev)); | 833 | memset(&mousedev_mix, 0, sizeof(struct mousedev)); |
749 | INIT_LIST_HEAD(&mousedev_mix.list); | 834 | INIT_LIST_HEAD(&mousedev_mix.client_list); |
750 | init_waitqueue_head(&mousedev_mix.wait); | 835 | init_waitqueue_head(&mousedev_mix.wait); |
751 | mousedev_table[MOUSEDEV_MIX] = &mousedev_mix; | 836 | mousedev_table[MOUSEDEV_MIX] = &mousedev_mix; |
752 | mousedev_mix.exist = 1; | 837 | mousedev_mix.exist = 1; |
diff --git a/drivers/input/power.c b/drivers/input/power.c deleted file mode 100644 index ee82464a2fa7..000000000000 --- a/drivers/input/power.c +++ /dev/null | |||
@@ -1,166 +0,0 @@ | |||
1 | /* | ||
2 | * $Id: power.c,v 1.10 2001/09/25 09:17:15 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 2001 "Crazy" James Simmons | ||
5 | * | ||
6 | * Input driver Power Management. | ||
7 | * | ||
8 | * Sponsored by Transvirtual Technology. | ||
9 | */ | ||
10 | |||
11 | /* | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2 of the License, or | ||
15 | * (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
25 | * | ||
26 | * Should you need to contact me, the author, you can do so by | ||
27 | * e-mail - mail your message to <jsimmons@transvirtual.com>. | ||
28 | */ | ||
29 | |||
30 | #include <linux/module.h> | ||
31 | #include <linux/input.h> | ||
32 | #include <linux/slab.h> | ||
33 | #include <linux/init.h> | ||
34 | #include <linux/tty.h> | ||
35 | #include <linux/delay.h> | ||
36 | #include <linux/pm.h> | ||
37 | |||
38 | static struct input_handler power_handler; | ||
39 | |||
40 | /* | ||
41 | * Power management can't be done in a interrupt context. So we have to | ||
42 | * use keventd. | ||
43 | */ | ||
44 | static int suspend_button_pushed = 0; | ||
45 | static void suspend_button_task_handler(void *data) | ||
46 | { | ||
47 | udelay(200); /* debounce */ | ||
48 | suspend_button_pushed = 0; | ||
49 | } | ||
50 | |||
51 | static DECLARE_WORK(suspend_button_task, suspend_button_task_handler, NULL); | ||
52 | |||
53 | static void power_event(struct input_handle *handle, unsigned int type, | ||
54 | unsigned int code, int down) | ||
55 | { | ||
56 | struct input_dev *dev = handle->dev; | ||
57 | |||
58 | printk("Entering power_event\n"); | ||
59 | |||
60 | if (type == EV_PWR) { | ||
61 | switch (code) { | ||
62 | case KEY_SUSPEND: | ||
63 | printk("Powering down entire device\n"); | ||
64 | |||
65 | if (!suspend_button_pushed) { | ||
66 | suspend_button_pushed = 1; | ||
67 | schedule_work(&suspend_button_task); | ||
68 | } | ||
69 | break; | ||
70 | case KEY_POWER: | ||
71 | /* Hum power down the machine. */ | ||
72 | break; | ||
73 | default: | ||
74 | return; | ||
75 | } | ||
76 | } | ||
77 | |||
78 | if (type == EV_KEY) { | ||
79 | switch (code) { | ||
80 | case KEY_SUSPEND: | ||
81 | printk("Powering down input device\n"); | ||
82 | /* This is risky. See pm.h for details. */ | ||
83 | if (dev->state != PM_RESUME) | ||
84 | dev->state = PM_RESUME; | ||
85 | else | ||
86 | dev->state = PM_SUSPEND; | ||
87 | pm_send(dev->pm_dev, dev->state, dev); | ||
88 | break; | ||
89 | case KEY_POWER: | ||
90 | /* Turn the input device off completely ? */ | ||
91 | break; | ||
92 | default: | ||
93 | return; | ||
94 | } | ||
95 | } | ||
96 | return; | ||
97 | } | ||
98 | |||
99 | static struct input_handle *power_connect(struct input_handler *handler, | ||
100 | struct input_dev *dev, | ||
101 | const struct input_device_id *id) | ||
102 | { | ||
103 | struct input_handle *handle; | ||
104 | |||
105 | if (!(handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL))) | ||
106 | return NULL; | ||
107 | |||
108 | handle->dev = dev; | ||
109 | handle->handler = handler; | ||
110 | |||
111 | input_open_device(handle); | ||
112 | |||
113 | printk(KERN_INFO "power.c: Adding power management to input layer\n"); | ||
114 | return handle; | ||
115 | } | ||
116 | |||
117 | static void power_disconnect(struct input_handle *handle) | ||
118 | { | ||
119 | input_close_device(handle); | ||
120 | kfree(handle); | ||
121 | } | ||
122 | |||
123 | static const struct input_device_id power_ids[] = { | ||
124 | { | ||
125 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, | ||
126 | .evbit = { BIT(EV_KEY) }, | ||
127 | .keybit = { [LONG(KEY_SUSPEND)] = BIT(KEY_SUSPEND) } | ||
128 | }, | ||
129 | { | ||
130 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, | ||
131 | .evbit = { BIT(EV_KEY) }, | ||
132 | .keybit = { [LONG(KEY_POWER)] = BIT(KEY_POWER) } | ||
133 | }, | ||
134 | { | ||
135 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT, | ||
136 | .evbit = { BIT(EV_PWR) }, | ||
137 | }, | ||
138 | { }, /* Terminating entry */ | ||
139 | }; | ||
140 | |||
141 | MODULE_DEVICE_TABLE(input, power_ids); | ||
142 | |||
143 | static struct input_handler power_handler = { | ||
144 | .event = power_event, | ||
145 | .connect = power_connect, | ||
146 | .disconnect = power_disconnect, | ||
147 | .name = "power", | ||
148 | .id_table = power_ids, | ||
149 | }; | ||
150 | |||
151 | static int __init power_init(void) | ||
152 | { | ||
153 | return input_register_handler(&power_handler); | ||
154 | } | ||
155 | |||
156 | static void __exit power_exit(void) | ||
157 | { | ||
158 | input_unregister_handler(&power_handler); | ||
159 | } | ||
160 | |||
161 | module_init(power_init); | ||
162 | module_exit(power_exit); | ||
163 | |||
164 | MODULE_AUTHOR("James Simmons <jsimmons@transvirtual.com>"); | ||
165 | MODULE_DESCRIPTION("Input Power Management driver"); | ||
166 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c index 4fa93ff30919..93a1a6ba216a 100644 --- a/drivers/input/serio/hil_mlc.c +++ b/drivers/input/serio/hil_mlc.c | |||
@@ -32,11 +32,11 @@ | |||
32 | * | 32 | * |
33 | * Driver theory of operation: | 33 | * Driver theory of operation: |
34 | * | 34 | * |
35 | * Some access methods and an ISR is defined by the sub-driver | 35 | * Some access methods and an ISR is defined by the sub-driver |
36 | * (e.g. hp_sdc_mlc.c). These methods are expected to provide a | 36 | * (e.g. hp_sdc_mlc.c). These methods are expected to provide a |
37 | * few bits of logic in addition to raw access to the HIL MLC, | 37 | * few bits of logic in addition to raw access to the HIL MLC, |
38 | * specifically, the ISR, which is entirely registered by the | 38 | * specifically, the ISR, which is entirely registered by the |
39 | * sub-driver and invoked directly, must check for record | 39 | * sub-driver and invoked directly, must check for record |
40 | * termination or packet match, at which point a semaphore must | 40 | * termination or packet match, at which point a semaphore must |
41 | * be cleared and then the hil_mlcs_tasklet must be scheduled. | 41 | * be cleared and then the hil_mlcs_tasklet must be scheduled. |
42 | * | 42 | * |
@@ -47,7 +47,7 @@ | |||
47 | * itself if output is pending. (This rescheduling should be replaced | 47 | * itself if output is pending. (This rescheduling should be replaced |
48 | * at some point with a sub-driver-specific mechanism.) | 48 | * at some point with a sub-driver-specific mechanism.) |
49 | * | 49 | * |
50 | * A timer task prods the tasklet once per second to prevent | 50 | * A timer task prods the tasklet once per second to prevent |
51 | * hangups when attached devices do not return expected data | 51 | * hangups when attached devices do not return expected data |
52 | * and to initiate probes of the loop for new devices. | 52 | * and to initiate probes of the loop for new devices. |
53 | */ | 53 | */ |
@@ -83,69 +83,85 @@ DECLARE_TASKLET_DISABLED(hil_mlcs_tasklet, hil_mlcs_process, 0); | |||
83 | 83 | ||
84 | /********************** Device info/instance management **********************/ | 84 | /********************** Device info/instance management **********************/ |
85 | 85 | ||
86 | static void hil_mlc_clear_di_map (hil_mlc *mlc, int val) { | 86 | static void hil_mlc_clear_di_map(hil_mlc *mlc, int val) |
87 | { | ||
87 | int j; | 88 | int j; |
88 | for (j = val; j < 7 ; j++) { | 89 | |
90 | for (j = val; j < 7 ; j++) | ||
89 | mlc->di_map[j] = -1; | 91 | mlc->di_map[j] = -1; |
90 | } | ||
91 | } | 92 | } |
92 | 93 | ||
93 | static void hil_mlc_clear_di_scratch (hil_mlc *mlc) { | 94 | static void hil_mlc_clear_di_scratch(hil_mlc *mlc) |
94 | memset(&(mlc->di_scratch), 0, sizeof(mlc->di_scratch)); | 95 | { |
96 | memset(&mlc->di_scratch, 0, sizeof(mlc->di_scratch)); | ||
95 | } | 97 | } |
96 | 98 | ||
97 | static void hil_mlc_copy_di_scratch (hil_mlc *mlc, int idx) { | 99 | static void hil_mlc_copy_di_scratch(hil_mlc *mlc, int idx) |
98 | memcpy(&(mlc->di[idx]), &(mlc->di_scratch), sizeof(mlc->di_scratch)); | 100 | { |
101 | memcpy(&mlc->di[idx], &mlc->di_scratch, sizeof(mlc->di_scratch)); | ||
99 | } | 102 | } |
100 | 103 | ||
101 | static int hil_mlc_match_di_scratch (hil_mlc *mlc) { | 104 | static int hil_mlc_match_di_scratch(hil_mlc *mlc) |
105 | { | ||
102 | int idx; | 106 | int idx; |
103 | 107 | ||
104 | for (idx = 0; idx < HIL_MLC_DEVMEM; idx++) { | 108 | for (idx = 0; idx < HIL_MLC_DEVMEM; idx++) { |
105 | int j, found; | 109 | int j, found = 0; |
106 | 110 | ||
107 | /* In-use slots are not eligible. */ | 111 | /* In-use slots are not eligible. */ |
108 | found = 0; | 112 | for (j = 0; j < 7 ; j++) |
109 | for (j = 0; j < 7 ; j++) { | 113 | if (mlc->di_map[j] == idx) |
110 | if (mlc->di_map[j] == idx) found++; | 114 | found++; |
111 | } | 115 | |
112 | if (found) continue; | 116 | if (found) |
113 | if (!memcmp(mlc->di + idx, | 117 | continue; |
114 | &(mlc->di_scratch), | 118 | |
115 | sizeof(mlc->di_scratch))) break; | 119 | if (!memcmp(mlc->di + idx, &mlc->di_scratch, |
120 | sizeof(mlc->di_scratch))) | ||
121 | break; | ||
116 | } | 122 | } |
117 | return((idx >= HIL_MLC_DEVMEM) ? -1 : idx); | 123 | return idx >= HIL_MLC_DEVMEM ? -1 : idx; |
118 | } | 124 | } |
119 | 125 | ||
120 | static int hil_mlc_find_free_di(hil_mlc *mlc) { | 126 | static int hil_mlc_find_free_di(hil_mlc *mlc) |
127 | { | ||
121 | int idx; | 128 | int idx; |
122 | /* TODO: Pick all-zero slots first, failing that, | 129 | |
123 | * randomize the slot picked among those eligible. | 130 | /* TODO: Pick all-zero slots first, failing that, |
131 | * randomize the slot picked among those eligible. | ||
124 | */ | 132 | */ |
125 | for (idx = 0; idx < HIL_MLC_DEVMEM; idx++) { | 133 | for (idx = 0; idx < HIL_MLC_DEVMEM; idx++) { |
126 | int j, found; | 134 | int j, found = 0; |
127 | found = 0; | 135 | |
128 | for (j = 0; j < 7 ; j++) { | 136 | for (j = 0; j < 7 ; j++) |
129 | if (mlc->di_map[j] == idx) found++; | 137 | if (mlc->di_map[j] == idx) |
130 | } | 138 | found++; |
131 | if (!found) break; | 139 | |
140 | if (!found) | ||
141 | break; | ||
132 | } | 142 | } |
133 | return(idx); /* Note: It is guaranteed at least one above will match */ | 143 | |
144 | return idx; /* Note: It is guaranteed at least one above will match */ | ||
134 | } | 145 | } |
135 | 146 | ||
136 | static inline void hil_mlc_clean_serio_map(hil_mlc *mlc) { | 147 | static inline void hil_mlc_clean_serio_map(hil_mlc *mlc) |
148 | { | ||
137 | int idx; | 149 | int idx; |
150 | |||
138 | for (idx = 0; idx < HIL_MLC_DEVMEM; idx++) { | 151 | for (idx = 0; idx < HIL_MLC_DEVMEM; idx++) { |
139 | int j, found; | 152 | int j, found = 0; |
140 | found = 0; | 153 | |
141 | for (j = 0; j < 7 ; j++) { | 154 | for (j = 0; j < 7 ; j++) |
142 | if (mlc->di_map[j] == idx) found++; | 155 | if (mlc->di_map[j] == idx) |
143 | } | 156 | found++; |
144 | if (!found) mlc->serio_map[idx].di_revmap = -1; | 157 | |
158 | if (!found) | ||
159 | mlc->serio_map[idx].di_revmap = -1; | ||
145 | } | 160 | } |
146 | } | 161 | } |
147 | 162 | ||
148 | static void hil_mlc_send_polls(hil_mlc *mlc) { | 163 | static void hil_mlc_send_polls(hil_mlc *mlc) |
164 | { | ||
149 | int did, i, cnt; | 165 | int did, i, cnt; |
150 | struct serio *serio; | 166 | struct serio *serio; |
151 | struct serio_driver *drv; | 167 | struct serio_driver *drv; |
@@ -157,26 +173,31 @@ static void hil_mlc_send_polls(hil_mlc *mlc) { | |||
157 | 173 | ||
158 | while (mlc->icount < 15 - i) { | 174 | while (mlc->icount < 15 - i) { |
159 | hil_packet p; | 175 | hil_packet p; |
176 | |||
160 | p = mlc->ipacket[i]; | 177 | p = mlc->ipacket[i]; |
161 | if (did != (p & HIL_PKT_ADDR_MASK) >> 8) { | 178 | if (did != (p & HIL_PKT_ADDR_MASK) >> 8) { |
162 | if (drv == NULL || drv->interrupt == NULL) goto skip; | 179 | if (drv && drv->interrupt) { |
180 | drv->interrupt(serio, 0, 0); | ||
181 | drv->interrupt(serio, HIL_ERR_INT >> 16, 0); | ||
182 | drv->interrupt(serio, HIL_PKT_CMD >> 8, 0); | ||
183 | drv->interrupt(serio, HIL_CMD_POL + cnt, 0); | ||
184 | } | ||
163 | 185 | ||
164 | drv->interrupt(serio, 0, 0); | ||
165 | drv->interrupt(serio, HIL_ERR_INT >> 16, 0); | ||
166 | drv->interrupt(serio, HIL_PKT_CMD >> 8, 0); | ||
167 | drv->interrupt(serio, HIL_CMD_POL + cnt, 0); | ||
168 | skip: | ||
169 | did = (p & HIL_PKT_ADDR_MASK) >> 8; | 186 | did = (p & HIL_PKT_ADDR_MASK) >> 8; |
170 | serio = did ? mlc->serio[mlc->di_map[did-1]] : NULL; | 187 | serio = did ? mlc->serio[mlc->di_map[did-1]] : NULL; |
171 | drv = (serio != NULL) ? serio->drv : NULL; | 188 | drv = (serio != NULL) ? serio->drv : NULL; |
172 | cnt = 0; | 189 | cnt = 0; |
173 | } | 190 | } |
174 | cnt++; i++; | 191 | |
175 | if (drv == NULL || drv->interrupt == NULL) continue; | 192 | cnt++; |
176 | drv->interrupt(serio, (p >> 24), 0); | 193 | i++; |
177 | drv->interrupt(serio, (p >> 16) & 0xff, 0); | 194 | |
178 | drv->interrupt(serio, (p >> 8) & ~HIL_PKT_ADDR_MASK, 0); | 195 | if (drv && drv->interrupt) { |
179 | drv->interrupt(serio, p & 0xff, 0); | 196 | drv->interrupt(serio, (p >> 24), 0); |
197 | drv->interrupt(serio, (p >> 16) & 0xff, 0); | ||
198 | drv->interrupt(serio, (p >> 8) & ~HIL_PKT_ADDR_MASK, 0); | ||
199 | drv->interrupt(serio, p & 0xff, 0); | ||
200 | } | ||
180 | } | 201 | } |
181 | } | 202 | } |
182 | 203 | ||
@@ -215,12 +236,16 @@ static void hil_mlc_send_polls(hil_mlc *mlc) { | |||
215 | #define HILSEN_DOZE (HILSEN_SAME | HILSEN_SCHED | HILSEN_BREAK) | 236 | #define HILSEN_DOZE (HILSEN_SAME | HILSEN_SCHED | HILSEN_BREAK) |
216 | #define HILSEN_SLEEP (HILSEN_SAME | HILSEN_BREAK) | 237 | #define HILSEN_SLEEP (HILSEN_SAME | HILSEN_BREAK) |
217 | 238 | ||
218 | static int hilse_match(hil_mlc *mlc, int unused) { | 239 | static int hilse_match(hil_mlc *mlc, int unused) |
240 | { | ||
219 | int rc; | 241 | int rc; |
242 | |||
220 | rc = hil_mlc_match_di_scratch(mlc); | 243 | rc = hil_mlc_match_di_scratch(mlc); |
221 | if (rc == -1) { | 244 | if (rc == -1) { |
222 | rc = hil_mlc_find_free_di(mlc); | 245 | rc = hil_mlc_find_free_di(mlc); |
223 | if (rc == -1) goto err; | 246 | if (rc == -1) |
247 | goto err; | ||
248 | |||
224 | #ifdef HIL_MLC_DEBUG | 249 | #ifdef HIL_MLC_DEBUG |
225 | printk(KERN_DEBUG PREFIX "new in slot %i\n", rc); | 250 | printk(KERN_DEBUG PREFIX "new in slot %i\n", rc); |
226 | #endif | 251 | #endif |
@@ -231,6 +256,7 @@ static int hilse_match(hil_mlc *mlc, int unused) { | |||
231 | serio_rescan(mlc->serio[rc]); | 256 | serio_rescan(mlc->serio[rc]); |
232 | return -1; | 257 | return -1; |
233 | } | 258 | } |
259 | |||
234 | mlc->di_map[mlc->ddi] = rc; | 260 | mlc->di_map[mlc->ddi] = rc; |
235 | #ifdef HIL_MLC_DEBUG | 261 | #ifdef HIL_MLC_DEBUG |
236 | printk(KERN_DEBUG PREFIX "same in slot %i\n", rc); | 262 | printk(KERN_DEBUG PREFIX "same in slot %i\n", rc); |
@@ -238,152 +264,177 @@ static int hilse_match(hil_mlc *mlc, int unused) { | |||
238 | mlc->serio_map[rc].di_revmap = mlc->ddi; | 264 | mlc->serio_map[rc].di_revmap = mlc->ddi; |
239 | hil_mlc_clean_serio_map(mlc); | 265 | hil_mlc_clean_serio_map(mlc); |
240 | return 0; | 266 | return 0; |
267 | |||
241 | err: | 268 | err: |
242 | printk(KERN_ERR PREFIX "Residual device slots exhausted, close some serios!\n"); | 269 | printk(KERN_ERR PREFIX "Residual device slots exhausted, close some serios!\n"); |
243 | return 1; | 270 | return 1; |
244 | } | 271 | } |
245 | 272 | ||
246 | /* An LCV used to prevent runaway loops, forces 5 second sleep when reset. */ | 273 | /* An LCV used to prevent runaway loops, forces 5 second sleep when reset. */ |
247 | static int hilse_init_lcv(hil_mlc *mlc, int unused) { | 274 | static int hilse_init_lcv(hil_mlc *mlc, int unused) |
275 | { | ||
248 | struct timeval tv; | 276 | struct timeval tv; |
249 | 277 | ||
250 | do_gettimeofday(&tv); | 278 | do_gettimeofday(&tv); |
251 | 279 | ||
252 | if(mlc->lcv == 0) goto restart; /* First init, no need to dally */ | 280 | if (mlc->lcv && (tv.tv_sec - mlc->lcv_tv.tv_sec) < 5) |
253 | if(tv.tv_sec - mlc->lcv_tv.tv_sec < 5) return -1; | 281 | return -1; |
254 | restart: | 282 | |
255 | mlc->lcv_tv = tv; | 283 | mlc->lcv_tv = tv; |
256 | mlc->lcv = 0; | 284 | mlc->lcv = 0; |
285 | |||
257 | return 0; | 286 | return 0; |
258 | } | 287 | } |
259 | 288 | ||
260 | static int hilse_inc_lcv(hil_mlc *mlc, int lim) { | 289 | static int hilse_inc_lcv(hil_mlc *mlc, int lim) |
261 | if (mlc->lcv++ >= lim) return -1; | 290 | { |
262 | return 0; | 291 | return mlc->lcv++ >= lim ? -1 : 0; |
263 | } | 292 | } |
264 | 293 | ||
265 | #if 0 | 294 | #if 0 |
266 | static int hilse_set_lcv(hil_mlc *mlc, int val) { | 295 | static int hilse_set_lcv(hil_mlc *mlc, int val) |
296 | { | ||
267 | mlc->lcv = val; | 297 | mlc->lcv = val; |
298 | |||
268 | return 0; | 299 | return 0; |
269 | } | 300 | } |
270 | #endif | 301 | #endif |
271 | 302 | ||
272 | /* Management of the discovered device index (zero based, -1 means no devs) */ | 303 | /* Management of the discovered device index (zero based, -1 means no devs) */ |
273 | static int hilse_set_ddi(hil_mlc *mlc, int val) { | 304 | static int hilse_set_ddi(hil_mlc *mlc, int val) |
305 | { | ||
274 | mlc->ddi = val; | 306 | mlc->ddi = val; |
275 | hil_mlc_clear_di_map(mlc, val + 1); | 307 | hil_mlc_clear_di_map(mlc, val + 1); |
308 | |||
276 | return 0; | 309 | return 0; |
277 | } | 310 | } |
278 | 311 | ||
279 | static int hilse_dec_ddi(hil_mlc *mlc, int unused) { | 312 | static int hilse_dec_ddi(hil_mlc *mlc, int unused) |
313 | { | ||
280 | mlc->ddi--; | 314 | mlc->ddi--; |
281 | if (mlc->ddi <= -1) { | 315 | if (mlc->ddi <= -1) { |
282 | mlc->ddi = -1; | 316 | mlc->ddi = -1; |
283 | hil_mlc_clear_di_map(mlc, 0); | 317 | hil_mlc_clear_di_map(mlc, 0); |
284 | return -1; | 318 | return -1; |
285 | } | 319 | } |
286 | hil_mlc_clear_di_map(mlc, mlc->ddi + 1); | 320 | hil_mlc_clear_di_map(mlc, mlc->ddi + 1); |
321 | |||
287 | return 0; | 322 | return 0; |
288 | } | 323 | } |
289 | 324 | ||
290 | static int hilse_inc_ddi(hil_mlc *mlc, int unused) { | 325 | static int hilse_inc_ddi(hil_mlc *mlc, int unused) |
291 | if (mlc->ddi >= 6) { | 326 | { |
292 | BUG(); | 327 | BUG_ON(mlc->ddi >= 6); |
293 | return -1; | ||
294 | } | ||
295 | mlc->ddi++; | 328 | mlc->ddi++; |
329 | |||
296 | return 0; | 330 | return 0; |
297 | } | 331 | } |
298 | 332 | ||
299 | static int hilse_take_idd(hil_mlc *mlc, int unused) { | 333 | static int hilse_take_idd(hil_mlc *mlc, int unused) |
334 | { | ||
300 | int i; | 335 | int i; |
301 | 336 | ||
302 | /* Help the state engine: | 337 | /* Help the state engine: |
303 | * Is this a real IDD response or just an echo? | 338 | * Is this a real IDD response or just an echo? |
304 | * | 339 | * |
305 | * Real IDD response does not start with a command. | 340 | * Real IDD response does not start with a command. |
306 | */ | 341 | */ |
307 | if (mlc->ipacket[0] & HIL_PKT_CMD) goto bail; | 342 | if (mlc->ipacket[0] & HIL_PKT_CMD) |
343 | goto bail; | ||
344 | |||
308 | /* Should have the command echoed further down. */ | 345 | /* Should have the command echoed further down. */ |
309 | for (i = 1; i < 16; i++) { | 346 | for (i = 1; i < 16; i++) { |
310 | if (((mlc->ipacket[i] & HIL_PKT_ADDR_MASK) == | 347 | if (((mlc->ipacket[i] & HIL_PKT_ADDR_MASK) == |
311 | (mlc->ipacket[0] & HIL_PKT_ADDR_MASK)) && | 348 | (mlc->ipacket[0] & HIL_PKT_ADDR_MASK)) && |
312 | (mlc->ipacket[i] & HIL_PKT_CMD) && | 349 | (mlc->ipacket[i] & HIL_PKT_CMD) && |
313 | ((mlc->ipacket[i] & HIL_PKT_DATA_MASK) == HIL_CMD_IDD)) | 350 | ((mlc->ipacket[i] & HIL_PKT_DATA_MASK) == HIL_CMD_IDD)) |
314 | break; | 351 | break; |
315 | } | 352 | } |
316 | if (i > 15) goto bail; | 353 | if (i > 15) |
354 | goto bail; | ||
355 | |||
317 | /* And the rest of the packets should still be clear. */ | 356 | /* And the rest of the packets should still be clear. */ |
318 | while (++i < 16) { | 357 | while (++i < 16) |
319 | if (mlc->ipacket[i]) break; | 358 | if (mlc->ipacket[i]) |
320 | } | 359 | break; |
321 | if (i < 16) goto bail; | 360 | |
322 | for (i = 0; i < 16; i++) { | 361 | if (i < 16) |
323 | mlc->di_scratch.idd[i] = | 362 | goto bail; |
363 | |||
364 | for (i = 0; i < 16; i++) | ||
365 | mlc->di_scratch.idd[i] = | ||
324 | mlc->ipacket[i] & HIL_PKT_DATA_MASK; | 366 | mlc->ipacket[i] & HIL_PKT_DATA_MASK; |
325 | } | 367 | |
326 | /* Next step is to see if RSC supported */ | 368 | /* Next step is to see if RSC supported */ |
327 | if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_RSC) | 369 | if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_RSC) |
328 | return HILSEN_NEXT; | 370 | return HILSEN_NEXT; |
329 | if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_EXD) | 371 | |
372 | if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_EXD) | ||
330 | return HILSEN_DOWN | 4; | 373 | return HILSEN_DOWN | 4; |
374 | |||
331 | return 0; | 375 | return 0; |
376 | |||
332 | bail: | 377 | bail: |
333 | mlc->ddi--; | 378 | mlc->ddi--; |
379 | |||
334 | return -1; /* This should send us off to ACF */ | 380 | return -1; /* This should send us off to ACF */ |
335 | } | 381 | } |
336 | 382 | ||
337 | static int hilse_take_rsc(hil_mlc *mlc, int unused) { | 383 | static int hilse_take_rsc(hil_mlc *mlc, int unused) |
384 | { | ||
338 | int i; | 385 | int i; |
339 | 386 | ||
340 | for (i = 0; i < 16; i++) { | 387 | for (i = 0; i < 16; i++) |
341 | mlc->di_scratch.rsc[i] = | 388 | mlc->di_scratch.rsc[i] = |
342 | mlc->ipacket[i] & HIL_PKT_DATA_MASK; | 389 | mlc->ipacket[i] & HIL_PKT_DATA_MASK; |
343 | } | 390 | |
344 | /* Next step is to see if EXD supported (IDD has already been read) */ | 391 | /* Next step is to see if EXD supported (IDD has already been read) */ |
345 | if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_EXD) | 392 | if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_EXD) |
346 | return HILSEN_NEXT; | 393 | return HILSEN_NEXT; |
394 | |||
347 | return 0; | 395 | return 0; |
348 | } | 396 | } |
349 | 397 | ||
350 | static int hilse_take_exd(hil_mlc *mlc, int unused) { | 398 | static int hilse_take_exd(hil_mlc *mlc, int unused) |
399 | { | ||
351 | int i; | 400 | int i; |
352 | 401 | ||
353 | for (i = 0; i < 16; i++) { | 402 | for (i = 0; i < 16; i++) |
354 | mlc->di_scratch.exd[i] = | 403 | mlc->di_scratch.exd[i] = |
355 | mlc->ipacket[i] & HIL_PKT_DATA_MASK; | 404 | mlc->ipacket[i] & HIL_PKT_DATA_MASK; |
356 | } | 405 | |
357 | /* Next step is to see if RNM supported. */ | 406 | /* Next step is to see if RNM supported. */ |
358 | if (mlc->di_scratch.exd[0] & HIL_EXD_HEADER_RNM) | 407 | if (mlc->di_scratch.exd[0] & HIL_EXD_HEADER_RNM) |
359 | return HILSEN_NEXT; | 408 | return HILSEN_NEXT; |
409 | |||
360 | return 0; | 410 | return 0; |
361 | } | 411 | } |
362 | 412 | ||
363 | static int hilse_take_rnm(hil_mlc *mlc, int unused) { | 413 | static int hilse_take_rnm(hil_mlc *mlc, int unused) |
414 | { | ||
364 | int i; | 415 | int i; |
365 | 416 | ||
366 | for (i = 0; i < 16; i++) { | 417 | for (i = 0; i < 16; i++) |
367 | mlc->di_scratch.rnm[i] = | 418 | mlc->di_scratch.rnm[i] = |
368 | mlc->ipacket[i] & HIL_PKT_DATA_MASK; | 419 | mlc->ipacket[i] & HIL_PKT_DATA_MASK; |
369 | } | 420 | |
370 | do { | 421 | printk(KERN_INFO PREFIX "Device name gotten: %16s\n", |
371 | char nam[17]; | 422 | mlc->di_scratch.rnm); |
372 | snprintf(nam, 16, "%s", mlc->di_scratch.rnm); | 423 | |
373 | nam[16] = '\0'; | ||
374 | printk(KERN_INFO PREFIX "Device name gotten: %s\n", nam); | ||
375 | } while (0); | ||
376 | return 0; | 424 | return 0; |
377 | } | 425 | } |
378 | 426 | ||
379 | static int hilse_operate(hil_mlc *mlc, int repoll) { | 427 | static int hilse_operate(hil_mlc *mlc, int repoll) |
428 | { | ||
380 | 429 | ||
381 | if (mlc->opercnt == 0) hil_mlcs_probe = 0; | 430 | if (mlc->opercnt == 0) |
431 | hil_mlcs_probe = 0; | ||
382 | mlc->opercnt = 1; | 432 | mlc->opercnt = 1; |
383 | 433 | ||
384 | hil_mlc_send_polls(mlc); | 434 | hil_mlc_send_polls(mlc); |
385 | 435 | ||
386 | if (!hil_mlcs_probe) return 0; | 436 | if (!hil_mlcs_probe) |
437 | return 0; | ||
387 | hil_mlcs_probe = 0; | 438 | hil_mlcs_probe = 0; |
388 | mlc->opercnt = 0; | 439 | mlc->opercnt = 0; |
389 | return 1; | 440 | return 1; |
@@ -408,7 +459,7 @@ static int hilse_operate(hil_mlc *mlc, int repoll) { | |||
408 | #define OUT_LAST(pack) \ | 459 | #define OUT_LAST(pack) \ |
409 | { HILSE_OUT_LAST, { .packet = pack }, 0, 0, 0, 0 }, | 460 | { HILSE_OUT_LAST, { .packet = pack }, 0, 0, 0, 0 }, |
410 | 461 | ||
411 | struct hilse_node hil_mlc_se[HILSEN_END] = { | 462 | const struct hilse_node hil_mlc_se[HILSEN_END] = { |
412 | 463 | ||
413 | /* 0 HILSEN_START */ | 464 | /* 0 HILSEN_START */ |
414 | FUNC(hilse_init_lcv, 0, HILSEN_NEXT, HILSEN_SLEEP, 0) | 465 | FUNC(hilse_init_lcv, 0, HILSEN_NEXT, HILSEN_SLEEP, 0) |
@@ -428,7 +479,7 @@ struct hilse_node hil_mlc_se[HILSEN_END] = { | |||
428 | EXPECT(HIL_ERR_INT | TEST_PACKET(0xa), | 479 | EXPECT(HIL_ERR_INT | TEST_PACKET(0xa), |
429 | 2000, HILSEN_NEXT, HILSEN_RESTART, HILSEN_RESTART) | 480 | 2000, HILSEN_NEXT, HILSEN_RESTART, HILSEN_RESTART) |
430 | OUT(HIL_CTRL_ONLY | 0) /* Disable test mode */ | 481 | OUT(HIL_CTRL_ONLY | 0) /* Disable test mode */ |
431 | 482 | ||
432 | /* 9 HILSEN_DHR */ | 483 | /* 9 HILSEN_DHR */ |
433 | FUNC(hilse_init_lcv, 0, HILSEN_NEXT, HILSEN_SLEEP, 0) | 484 | FUNC(hilse_init_lcv, 0, HILSEN_NEXT, HILSEN_SLEEP, 0) |
434 | 485 | ||
@@ -439,7 +490,7 @@ struct hilse_node hil_mlc_se[HILSEN_END] = { | |||
439 | IN(300000, HILSEN_DHR2, HILSEN_DHR2, HILSEN_NEXT) | 490 | IN(300000, HILSEN_DHR2, HILSEN_DHR2, HILSEN_NEXT) |
440 | 491 | ||
441 | /* 14 HILSEN_IFC */ | 492 | /* 14 HILSEN_IFC */ |
442 | OUT(HIL_PKT_CMD | HIL_CMD_IFC) | 493 | OUT(HIL_PKT_CMD | HIL_CMD_IFC) |
443 | EXPECT(HIL_PKT_CMD | HIL_CMD_IFC | HIL_ERR_INT, | 494 | EXPECT(HIL_PKT_CMD | HIL_CMD_IFC | HIL_ERR_INT, |
444 | 20000, HILSEN_DISC, HILSEN_DHR2, HILSEN_NEXT ) | 495 | 20000, HILSEN_DISC, HILSEN_DHR2, HILSEN_NEXT ) |
445 | 496 | ||
@@ -455,7 +506,7 @@ struct hilse_node hil_mlc_se[HILSEN_END] = { | |||
455 | 506 | ||
456 | /* 18 HILSEN_HEAL */ | 507 | /* 18 HILSEN_HEAL */ |
457 | OUT_LAST(HIL_CMD_ELB) | 508 | OUT_LAST(HIL_CMD_ELB) |
458 | EXPECT_LAST(HIL_CMD_ELB | HIL_ERR_INT, | 509 | EXPECT_LAST(HIL_CMD_ELB | HIL_ERR_INT, |
459 | 20000, HILSEN_REPOLL, HILSEN_DSR, HILSEN_NEXT) | 510 | 20000, HILSEN_REPOLL, HILSEN_DSR, HILSEN_NEXT) |
460 | FUNC(hilse_dec_ddi, 0, HILSEN_HEAL, HILSEN_NEXT, 0) | 511 | FUNC(hilse_dec_ddi, 0, HILSEN_HEAL, HILSEN_NEXT, 0) |
461 | 512 | ||
@@ -503,7 +554,7 @@ struct hilse_node hil_mlc_se[HILSEN_END] = { | |||
503 | 554 | ||
504 | /* 44 HILSEN_PROBE */ | 555 | /* 44 HILSEN_PROBE */ |
505 | OUT_LAST(HIL_PKT_CMD | HIL_CMD_EPT) | 556 | OUT_LAST(HIL_PKT_CMD | HIL_CMD_EPT) |
506 | IN(10000, HILSEN_DISC, HILSEN_DSR, HILSEN_NEXT) | 557 | IN(10000, HILSEN_DISC, HILSEN_DSR, HILSEN_NEXT) |
507 | OUT_DISC(HIL_PKT_CMD | HIL_CMD_ELB) | 558 | OUT_DISC(HIL_PKT_CMD | HIL_CMD_ELB) |
508 | IN(10000, HILSEN_DISC, HILSEN_DSR, HILSEN_NEXT) | 559 | IN(10000, HILSEN_DISC, HILSEN_DSR, HILSEN_NEXT) |
509 | OUT(HIL_PKT_CMD | HIL_CMD_ACF | 1) | 560 | OUT(HIL_PKT_CMD | HIL_CMD_ACF | 1) |
@@ -514,7 +565,7 @@ struct hilse_node hil_mlc_se[HILSEN_END] = { | |||
514 | /* 52 HILSEN_DSR */ | 565 | /* 52 HILSEN_DSR */ |
515 | FUNC(hilse_set_ddi, -1, HILSEN_NEXT, 0, 0) | 566 | FUNC(hilse_set_ddi, -1, HILSEN_NEXT, 0, 0) |
516 | OUT(HIL_PKT_CMD | HIL_CMD_DSR) | 567 | OUT(HIL_PKT_CMD | HIL_CMD_DSR) |
517 | IN(20000, HILSEN_DHR, HILSEN_DHR, HILSEN_IFC) | 568 | IN(20000, HILSEN_DHR, HILSEN_DHR, HILSEN_IFC) |
518 | 569 | ||
519 | /* 55 HILSEN_REPOLL */ | 570 | /* 55 HILSEN_REPOLL */ |
520 | OUT(HIL_PKT_CMD | HIL_CMD_RPL) | 571 | OUT(HIL_PKT_CMD | HIL_CMD_RPL) |
@@ -523,14 +574,15 @@ struct hilse_node hil_mlc_se[HILSEN_END] = { | |||
523 | FUNC(hilse_operate, 1, HILSEN_OPERATE, HILSEN_IFC, HILSEN_PROBE) | 574 | FUNC(hilse_operate, 1, HILSEN_OPERATE, HILSEN_IFC, HILSEN_PROBE) |
524 | 575 | ||
525 | /* 58 HILSEN_IFCACF */ | 576 | /* 58 HILSEN_IFCACF */ |
526 | OUT(HIL_PKT_CMD | HIL_CMD_IFC) | 577 | OUT(HIL_PKT_CMD | HIL_CMD_IFC) |
527 | EXPECT(HIL_PKT_CMD | HIL_CMD_IFC | HIL_ERR_INT, | 578 | EXPECT(HIL_PKT_CMD | HIL_CMD_IFC | HIL_ERR_INT, |
528 | 20000, HILSEN_ACF2, HILSEN_DHR2, HILSEN_HEAL) | 579 | 20000, HILSEN_ACF2, HILSEN_DHR2, HILSEN_HEAL) |
529 | 580 | ||
530 | /* 60 HILSEN_END */ | 581 | /* 60 HILSEN_END */ |
531 | }; | 582 | }; |
532 | 583 | ||
533 | static inline void hilse_setup_input(hil_mlc *mlc, struct hilse_node *node) { | 584 | static inline void hilse_setup_input(hil_mlc *mlc, const struct hilse_node *node) |
585 | { | ||
534 | 586 | ||
535 | switch (node->act) { | 587 | switch (node->act) { |
536 | case HILSE_EXPECT_DISC: | 588 | case HILSE_EXPECT_DISC: |
@@ -555,29 +607,27 @@ static inline void hilse_setup_input(hil_mlc *mlc, struct hilse_node *node) { | |||
555 | do_gettimeofday(&(mlc->instart)); | 607 | do_gettimeofday(&(mlc->instart)); |
556 | mlc->icount = 15; | 608 | mlc->icount = 15; |
557 | memset(mlc->ipacket, 0, 16 * sizeof(hil_packet)); | 609 | memset(mlc->ipacket, 0, 16 * sizeof(hil_packet)); |
558 | BUG_ON(down_trylock(&(mlc->isem))); | 610 | BUG_ON(down_trylock(&mlc->isem)); |
559 | |||
560 | return; | ||
561 | } | 611 | } |
562 | 612 | ||
563 | #ifdef HIL_MLC_DEBUG | 613 | #ifdef HIL_MLC_DEBUG |
564 | static int doze = 0; | 614 | static int doze; |
565 | static int seidx; /* For debug */ | 615 | static int seidx; /* For debug */ |
566 | static int kick = 1; | ||
567 | #endif | 616 | #endif |
568 | 617 | ||
569 | static int hilse_donode (hil_mlc *mlc) { | 618 | static int hilse_donode(hil_mlc *mlc) |
570 | struct hilse_node *node; | 619 | { |
620 | const struct hilse_node *node; | ||
571 | int nextidx = 0; | 621 | int nextidx = 0; |
572 | int sched_long = 0; | 622 | int sched_long = 0; |
573 | unsigned long flags; | 623 | unsigned long flags; |
574 | 624 | ||
575 | #ifdef HIL_MLC_DEBUG | 625 | #ifdef HIL_MLC_DEBUG |
576 | if (mlc->seidx && (mlc->seidx != seidx) && mlc->seidx != 41 && mlc->seidx != 42 && mlc->seidx != 43) { | 626 | if (mlc->seidx && mlc->seidx != seidx && |
577 | printk(KERN_DEBUG PREFIX "z%i \n%s {%i}", doze, kick ? "K" : "", mlc->seidx); | 627 | mlc->seidx != 41 && mlc->seidx != 42 && mlc->seidx != 43) { |
628 | printk(KERN_DEBUG PREFIX "z%i \n {%i}", doze, mlc->seidx); | ||
578 | doze = 0; | 629 | doze = 0; |
579 | } | 630 | } |
580 | kick = 0; | ||
581 | 631 | ||
582 | seidx = mlc->seidx; | 632 | seidx = mlc->seidx; |
583 | #endif | 633 | #endif |
@@ -588,52 +638,61 @@ static int hilse_donode (hil_mlc *mlc) { | |||
588 | hil_packet pack; | 638 | hil_packet pack; |
589 | 639 | ||
590 | case HILSE_FUNC: | 640 | case HILSE_FUNC: |
591 | if (node->object.func == NULL) break; | 641 | BUG_ON(node->object.func == NULL); |
592 | rc = node->object.func(mlc, node->arg); | 642 | rc = node->object.func(mlc, node->arg); |
593 | nextidx = (rc > 0) ? node->ugly : | 643 | nextidx = (rc > 0) ? node->ugly : |
594 | ((rc < 0) ? node->bad : node->good); | 644 | ((rc < 0) ? node->bad : node->good); |
595 | if (nextidx == HILSEN_FOLLOW) nextidx = rc; | 645 | if (nextidx == HILSEN_FOLLOW) |
646 | nextidx = rc; | ||
596 | break; | 647 | break; |
648 | |||
597 | case HILSE_EXPECT_LAST: | 649 | case HILSE_EXPECT_LAST: |
598 | case HILSE_EXPECT_DISC: | 650 | case HILSE_EXPECT_DISC: |
599 | case HILSE_EXPECT: | 651 | case HILSE_EXPECT: |
600 | case HILSE_IN: | 652 | case HILSE_IN: |
601 | /* Already set up from previous HILSE_OUT_* */ | 653 | /* Already set up from previous HILSE_OUT_* */ |
602 | write_lock_irqsave(&(mlc->lock), flags); | 654 | write_lock_irqsave(&mlc->lock, flags); |
603 | rc = mlc->in(mlc, node->arg); | 655 | rc = mlc->in(mlc, node->arg); |
604 | if (rc == 2) { | 656 | if (rc == 2) { |
605 | nextidx = HILSEN_DOZE; | 657 | nextidx = HILSEN_DOZE; |
606 | sched_long = 1; | 658 | sched_long = 1; |
607 | write_unlock_irqrestore(&(mlc->lock), flags); | 659 | write_unlock_irqrestore(&mlc->lock, flags); |
608 | break; | 660 | break; |
609 | } | 661 | } |
610 | if (rc == 1) nextidx = node->ugly; | 662 | if (rc == 1) |
611 | else if (rc == 0) nextidx = node->good; | 663 | nextidx = node->ugly; |
612 | else nextidx = node->bad; | 664 | else if (rc == 0) |
665 | nextidx = node->good; | ||
666 | else | ||
667 | nextidx = node->bad; | ||
613 | mlc->istarted = 0; | 668 | mlc->istarted = 0; |
614 | write_unlock_irqrestore(&(mlc->lock), flags); | 669 | write_unlock_irqrestore(&mlc->lock, flags); |
615 | break; | 670 | break; |
671 | |||
616 | case HILSE_OUT_LAST: | 672 | case HILSE_OUT_LAST: |
617 | write_lock_irqsave(&(mlc->lock), flags); | 673 | write_lock_irqsave(&mlc->lock, flags); |
618 | pack = node->object.packet; | 674 | pack = node->object.packet; |
619 | pack |= ((mlc->ddi + 1) << HIL_PKT_ADDR_SHIFT); | 675 | pack |= ((mlc->ddi + 1) << HIL_PKT_ADDR_SHIFT); |
620 | goto out; | 676 | goto out; |
677 | |||
621 | case HILSE_OUT_DISC: | 678 | case HILSE_OUT_DISC: |
622 | write_lock_irqsave(&(mlc->lock), flags); | 679 | write_lock_irqsave(&mlc->lock, flags); |
623 | pack = node->object.packet; | 680 | pack = node->object.packet; |
624 | pack |= ((mlc->ddi + 2) << HIL_PKT_ADDR_SHIFT); | 681 | pack |= ((mlc->ddi + 2) << HIL_PKT_ADDR_SHIFT); |
625 | goto out; | 682 | goto out; |
683 | |||
626 | case HILSE_OUT: | 684 | case HILSE_OUT: |
627 | write_lock_irqsave(&(mlc->lock), flags); | 685 | write_lock_irqsave(&mlc->lock, flags); |
628 | pack = node->object.packet; | 686 | pack = node->object.packet; |
629 | out: | 687 | out: |
630 | if (mlc->istarted) goto out2; | 688 | if (mlc->istarted) |
689 | goto out2; | ||
631 | /* Prepare to receive input */ | 690 | /* Prepare to receive input */ |
632 | if ((node + 1)->act & HILSE_IN) | 691 | if ((node + 1)->act & HILSE_IN) |
633 | hilse_setup_input(mlc, node + 1); | 692 | hilse_setup_input(mlc, node + 1); |
634 | 693 | ||
635 | out2: | 694 | out2: |
636 | write_unlock_irqrestore(&(mlc->lock), flags); | 695 | write_unlock_irqrestore(&mlc->lock, flags); |
637 | 696 | ||
638 | if (down_trylock(&mlc->osem)) { | 697 | if (down_trylock(&mlc->osem)) { |
639 | nextidx = HILSEN_DOZE; | 698 | nextidx = HILSEN_DOZE; |
@@ -641,60 +700,71 @@ static int hilse_donode (hil_mlc *mlc) { | |||
641 | } | 700 | } |
642 | up(&mlc->osem); | 701 | up(&mlc->osem); |
643 | 702 | ||
644 | write_lock_irqsave(&(mlc->lock), flags); | 703 | write_lock_irqsave(&mlc->lock, flags); |
645 | if (!(mlc->ostarted)) { | 704 | if (!mlc->ostarted) { |
646 | mlc->ostarted = 1; | 705 | mlc->ostarted = 1; |
647 | mlc->opacket = pack; | 706 | mlc->opacket = pack; |
648 | mlc->out(mlc); | 707 | mlc->out(mlc); |
649 | nextidx = HILSEN_DOZE; | 708 | nextidx = HILSEN_DOZE; |
650 | write_unlock_irqrestore(&(mlc->lock), flags); | 709 | write_unlock_irqrestore(&mlc->lock, flags); |
651 | break; | 710 | break; |
652 | } | 711 | } |
653 | mlc->ostarted = 0; | 712 | mlc->ostarted = 0; |
654 | do_gettimeofday(&(mlc->instart)); | 713 | do_gettimeofday(&(mlc->instart)); |
655 | write_unlock_irqrestore(&(mlc->lock), flags); | 714 | write_unlock_irqrestore(&mlc->lock, flags); |
656 | nextidx = HILSEN_NEXT; | 715 | nextidx = HILSEN_NEXT; |
657 | break; | 716 | break; |
717 | |||
658 | case HILSE_CTS: | 718 | case HILSE_CTS: |
719 | write_lock_irqsave(&mlc->lock, flags); | ||
659 | nextidx = mlc->cts(mlc) ? node->bad : node->good; | 720 | nextidx = mlc->cts(mlc) ? node->bad : node->good; |
721 | write_unlock_irqrestore(&mlc->lock, flags); | ||
660 | break; | 722 | break; |
723 | |||
661 | default: | 724 | default: |
662 | BUG(); | 725 | BUG(); |
663 | nextidx = 0; | ||
664 | break; | ||
665 | } | 726 | } |
666 | 727 | ||
667 | #ifdef HIL_MLC_DEBUG | 728 | #ifdef HIL_MLC_DEBUG |
668 | if (nextidx == HILSEN_DOZE) doze++; | 729 | if (nextidx == HILSEN_DOZE) |
730 | doze++; | ||
669 | #endif | 731 | #endif |
670 | 732 | ||
671 | while (nextidx & HILSEN_SCHED) { | 733 | while (nextidx & HILSEN_SCHED) { |
672 | struct timeval tv; | 734 | struct timeval tv; |
673 | 735 | ||
674 | if (!sched_long) goto sched; | 736 | if (!sched_long) |
737 | goto sched; | ||
675 | 738 | ||
676 | do_gettimeofday(&tv); | 739 | do_gettimeofday(&tv); |
677 | tv.tv_usec += 1000000 * (tv.tv_sec - mlc->instart.tv_sec); | 740 | tv.tv_usec += USEC_PER_SEC * (tv.tv_sec - mlc->instart.tv_sec); |
678 | tv.tv_usec -= mlc->instart.tv_usec; | 741 | tv.tv_usec -= mlc->instart.tv_usec; |
679 | if (tv.tv_usec >= mlc->intimeout) goto sched; | 742 | if (tv.tv_usec >= mlc->intimeout) goto sched; |
680 | tv.tv_usec = (mlc->intimeout - tv.tv_usec) * HZ / 1000000; | 743 | tv.tv_usec = (mlc->intimeout - tv.tv_usec) * HZ / USEC_PER_SEC; |
681 | if (!tv.tv_usec) goto sched; | 744 | if (!tv.tv_usec) goto sched; |
682 | mod_timer(&hil_mlcs_kicker, jiffies + tv.tv_usec); | 745 | mod_timer(&hil_mlcs_kicker, jiffies + tv.tv_usec); |
683 | break; | 746 | break; |
684 | sched: | 747 | sched: |
685 | tasklet_schedule(&hil_mlcs_tasklet); | 748 | tasklet_schedule(&hil_mlcs_tasklet); |
686 | break; | 749 | break; |
687 | } | 750 | } |
688 | if (nextidx & HILSEN_DOWN) mlc->seidx += nextidx & HILSEN_MASK; | 751 | |
689 | else if (nextidx & HILSEN_UP) mlc->seidx -= nextidx & HILSEN_MASK; | 752 | if (nextidx & HILSEN_DOWN) |
690 | else mlc->seidx = nextidx & HILSEN_MASK; | 753 | mlc->seidx += nextidx & HILSEN_MASK; |
754 | else if (nextidx & HILSEN_UP) | ||
755 | mlc->seidx -= nextidx & HILSEN_MASK; | ||
756 | else | ||
757 | mlc->seidx = nextidx & HILSEN_MASK; | ||
758 | |||
759 | if (nextidx & HILSEN_BREAK) | ||
760 | return 1; | ||
691 | 761 | ||
692 | if (nextidx & HILSEN_BREAK) return 1; | ||
693 | return 0; | 762 | return 0; |
694 | } | 763 | } |
695 | 764 | ||
696 | /******************** tasklet context functions **************************/ | 765 | /******************** tasklet context functions **************************/ |
697 | static void hil_mlcs_process(unsigned long unused) { | 766 | static void hil_mlcs_process(unsigned long unused) |
767 | { | ||
698 | struct list_head *tmp; | 768 | struct list_head *tmp; |
699 | 769 | ||
700 | read_lock(&hil_mlcs_lock); | 770 | read_lock(&hil_mlcs_lock); |
@@ -702,19 +772,20 @@ static void hil_mlcs_process(unsigned long unused) { | |||
702 | struct hil_mlc *mlc = list_entry(tmp, hil_mlc, list); | 772 | struct hil_mlc *mlc = list_entry(tmp, hil_mlc, list); |
703 | while (hilse_donode(mlc) == 0) { | 773 | while (hilse_donode(mlc) == 0) { |
704 | #ifdef HIL_MLC_DEBUG | 774 | #ifdef HIL_MLC_DEBUG |
705 | if (mlc->seidx != 41 && | 775 | if (mlc->seidx != 41 && |
706 | mlc->seidx != 42 && | 776 | mlc->seidx != 42 && |
707 | mlc->seidx != 43) | 777 | mlc->seidx != 43) |
708 | printk(KERN_DEBUG PREFIX " + "); | 778 | printk(KERN_DEBUG PREFIX " + "); |
709 | #endif | 779 | #endif |
710 | }; | 780 | } |
711 | } | 781 | } |
712 | read_unlock(&hil_mlcs_lock); | 782 | read_unlock(&hil_mlcs_lock); |
713 | } | 783 | } |
714 | 784 | ||
715 | /************************* Keepalive timer task *********************/ | 785 | /************************* Keepalive timer task *********************/ |
716 | 786 | ||
717 | void hil_mlcs_timer (unsigned long data) { | 787 | void hil_mlcs_timer(unsigned long data) |
788 | { | ||
718 | hil_mlcs_probe = 1; | 789 | hil_mlcs_probe = 1; |
719 | tasklet_schedule(&hil_mlcs_tasklet); | 790 | tasklet_schedule(&hil_mlcs_tasklet); |
720 | /* Re-insert the periodic task. */ | 791 | /* Re-insert the periodic task. */ |
@@ -724,28 +795,25 @@ void hil_mlcs_timer (unsigned long data) { | |||
724 | 795 | ||
725 | /******************** user/kernel context functions **********************/ | 796 | /******************** user/kernel context functions **********************/ |
726 | 797 | ||
727 | static int hil_mlc_serio_write(struct serio *serio, unsigned char c) { | 798 | static int hil_mlc_serio_write(struct serio *serio, unsigned char c) |
799 | { | ||
728 | struct hil_mlc_serio_map *map; | 800 | struct hil_mlc_serio_map *map; |
729 | struct hil_mlc *mlc; | 801 | struct hil_mlc *mlc; |
730 | struct serio_driver *drv; | 802 | struct serio_driver *drv; |
731 | uint8_t *idx, *last; | 803 | uint8_t *idx, *last; |
732 | 804 | ||
733 | map = serio->port_data; | 805 | map = serio->port_data; |
734 | if (map == NULL) { | 806 | BUG_ON(map == NULL); |
735 | BUG(); | 807 | |
736 | return -EIO; | ||
737 | } | ||
738 | mlc = map->mlc; | 808 | mlc = map->mlc; |
739 | if (mlc == NULL) { | 809 | BUG_ON(mlc == NULL); |
740 | BUG(); | 810 | |
741 | return -EIO; | 811 | mlc->serio_opacket[map->didx] |= |
742 | } | ||
743 | mlc->serio_opacket[map->didx] |= | ||
744 | ((hil_packet)c) << (8 * (3 - mlc->serio_oidx[map->didx])); | 812 | ((hil_packet)c) << (8 * (3 - mlc->serio_oidx[map->didx])); |
745 | 813 | ||
746 | if (mlc->serio_oidx[map->didx] >= 3) { | 814 | if (mlc->serio_oidx[map->didx] >= 3) { |
747 | /* for now only commands */ | 815 | /* for now only commands */ |
748 | if (!(mlc->serio_opacket[map->didx] & HIL_PKT_CMD)) | 816 | if (!(mlc->serio_opacket[map->didx] & HIL_PKT_CMD)) |
749 | return -EIO; | 817 | return -EIO; |
750 | switch (mlc->serio_opacket[map->didx] & HIL_PKT_DATA_MASK) { | 818 | switch (mlc->serio_opacket[map->didx] & HIL_PKT_DATA_MASK) { |
751 | case HIL_CMD_IDD: | 819 | case HIL_CMD_IDD: |
@@ -771,12 +839,11 @@ static int hil_mlc_serio_write(struct serio *serio, unsigned char c) { | |||
771 | return -EIO; | 839 | return -EIO; |
772 | emu: | 840 | emu: |
773 | drv = serio->drv; | 841 | drv = serio->drv; |
774 | if (drv == NULL) { | 842 | BUG_ON(drv == NULL); |
775 | BUG(); | 843 | |
776 | return -EIO; | ||
777 | } | ||
778 | last = idx + 15; | 844 | last = idx + 15; |
779 | while ((last != idx) && (*last == 0)) last--; | 845 | while ((last != idx) && (*last == 0)) |
846 | last--; | ||
780 | 847 | ||
781 | while (idx != last) { | 848 | while (idx != last) { |
782 | drv->interrupt(serio, 0, 0); | 849 | drv->interrupt(serio, 0, 0); |
@@ -789,14 +856,15 @@ static int hil_mlc_serio_write(struct serio *serio, unsigned char c) { | |||
789 | drv->interrupt(serio, HIL_ERR_INT >> 16, 0); | 856 | drv->interrupt(serio, HIL_ERR_INT >> 16, 0); |
790 | drv->interrupt(serio, HIL_PKT_CMD >> 8, 0); | 857 | drv->interrupt(serio, HIL_PKT_CMD >> 8, 0); |
791 | drv->interrupt(serio, *idx, 0); | 858 | drv->interrupt(serio, *idx, 0); |
792 | 859 | ||
793 | mlc->serio_oidx[map->didx] = 0; | 860 | mlc->serio_oidx[map->didx] = 0; |
794 | mlc->serio_opacket[map->didx] = 0; | 861 | mlc->serio_opacket[map->didx] = 0; |
795 | 862 | ||
796 | return 0; | 863 | return 0; |
797 | } | 864 | } |
798 | 865 | ||
799 | static int hil_mlc_serio_open(struct serio *serio) { | 866 | static int hil_mlc_serio_open(struct serio *serio) |
867 | { | ||
800 | struct hil_mlc_serio_map *map; | 868 | struct hil_mlc_serio_map *map; |
801 | struct hil_mlc *mlc; | 869 | struct hil_mlc *mlc; |
802 | 870 | ||
@@ -804,67 +872,57 @@ static int hil_mlc_serio_open(struct serio *serio) { | |||
804 | return -EBUSY; | 872 | return -EBUSY; |
805 | 873 | ||
806 | map = serio->port_data; | 874 | map = serio->port_data; |
807 | if (map == NULL) { | 875 | BUG_ON(map == NULL); |
808 | BUG(); | 876 | |
809 | return -ENODEV; | ||
810 | } | ||
811 | mlc = map->mlc; | 877 | mlc = map->mlc; |
812 | if (mlc == NULL) { | 878 | BUG_ON(mlc == NULL); |
813 | BUG(); | ||
814 | return -ENODEV; | ||
815 | } | ||
816 | 879 | ||
817 | return 0; | 880 | return 0; |
818 | } | 881 | } |
819 | 882 | ||
820 | static void hil_mlc_serio_close(struct serio *serio) { | 883 | static void hil_mlc_serio_close(struct serio *serio) |
884 | { | ||
821 | struct hil_mlc_serio_map *map; | 885 | struct hil_mlc_serio_map *map; |
822 | struct hil_mlc *mlc; | 886 | struct hil_mlc *mlc; |
823 | 887 | ||
824 | map = serio->port_data; | 888 | map = serio->port_data; |
825 | if (map == NULL) { | 889 | BUG_ON(map == NULL); |
826 | BUG(); | 890 | |
827 | return; | ||
828 | } | ||
829 | mlc = map->mlc; | 891 | mlc = map->mlc; |
830 | if (mlc == NULL) { | 892 | BUG_ON(mlc == NULL); |
831 | BUG(); | ||
832 | return; | ||
833 | } | ||
834 | 893 | ||
835 | serio_set_drvdata(serio, NULL); | 894 | serio_set_drvdata(serio, NULL); |
836 | serio->drv = NULL; | 895 | serio->drv = NULL; |
837 | /* TODO wake up interruptable */ | 896 | /* TODO wake up interruptable */ |
838 | } | 897 | } |
839 | 898 | ||
840 | static struct serio_device_id hil_mlc_serio_id = { | 899 | static const struct serio_device_id hil_mlc_serio_id = { |
841 | .type = SERIO_HIL_MLC, | 900 | .type = SERIO_HIL_MLC, |
842 | .proto = SERIO_HIL, | 901 | .proto = SERIO_HIL, |
843 | .extra = SERIO_ANY, | 902 | .extra = SERIO_ANY, |
844 | .id = SERIO_ANY, | 903 | .id = SERIO_ANY, |
845 | }; | 904 | }; |
846 | 905 | ||
847 | int hil_mlc_register(hil_mlc *mlc) { | 906 | int hil_mlc_register(hil_mlc *mlc) |
907 | { | ||
848 | int i; | 908 | int i; |
849 | unsigned long flags; | 909 | unsigned long flags; |
850 | 910 | ||
851 | if (mlc == NULL) { | 911 | BUG_ON(mlc == NULL); |
852 | return -EINVAL; | ||
853 | } | ||
854 | 912 | ||
855 | mlc->istarted = 0; | 913 | mlc->istarted = 0; |
856 | mlc->ostarted = 0; | 914 | mlc->ostarted = 0; |
857 | 915 | ||
858 | rwlock_init(&mlc->lock); | 916 | rwlock_init(&mlc->lock); |
859 | init_MUTEX(&(mlc->osem)); | 917 | init_MUTEX(&mlc->osem); |
860 | 918 | ||
861 | init_MUTEX(&(mlc->isem)); | 919 | init_MUTEX(&mlc->isem); |
862 | mlc->icount = -1; | 920 | mlc->icount = -1; |
863 | mlc->imatch = 0; | 921 | mlc->imatch = 0; |
864 | 922 | ||
865 | mlc->opercnt = 0; | 923 | mlc->opercnt = 0; |
866 | 924 | ||
867 | init_MUTEX_LOCKED(&(mlc->csem)); | 925 | init_MUTEX_LOCKED(&(mlc->csem)); |
868 | 926 | ||
869 | hil_mlc_clear_di_scratch(mlc); | 927 | hil_mlc_clear_di_scratch(mlc); |
870 | hil_mlc_clear_di_map(mlc, 0); | 928 | hil_mlc_clear_di_map(mlc, 0); |
@@ -873,6 +931,8 @@ int hil_mlc_register(hil_mlc *mlc) { | |||
873 | hil_mlc_copy_di_scratch(mlc, i); | 931 | hil_mlc_copy_di_scratch(mlc, i); |
874 | mlc_serio = kzalloc(sizeof(*mlc_serio), GFP_KERNEL); | 932 | mlc_serio = kzalloc(sizeof(*mlc_serio), GFP_KERNEL); |
875 | mlc->serio[i] = mlc_serio; | 933 | mlc->serio[i] = mlc_serio; |
934 | snprintf(mlc_serio->name, sizeof(mlc_serio->name)-1, "HIL_SERIO%d", i); | ||
935 | snprintf(mlc_serio->phys, sizeof(mlc_serio->phys)-1, "HIL%d", i); | ||
876 | mlc_serio->id = hil_mlc_serio_id; | 936 | mlc_serio->id = hil_mlc_serio_id; |
877 | mlc_serio->write = hil_mlc_serio_write; | 937 | mlc_serio->write = hil_mlc_serio_write; |
878 | mlc_serio->open = hil_mlc_serio_open; | 938 | mlc_serio->open = hil_mlc_serio_open; |
@@ -897,19 +957,18 @@ int hil_mlc_register(hil_mlc *mlc) { | |||
897 | return 0; | 957 | return 0; |
898 | } | 958 | } |
899 | 959 | ||
900 | int hil_mlc_unregister(hil_mlc *mlc) { | 960 | int hil_mlc_unregister(hil_mlc *mlc) |
961 | { | ||
901 | struct list_head *tmp; | 962 | struct list_head *tmp; |
902 | unsigned long flags; | 963 | unsigned long flags; |
903 | int i; | 964 | int i; |
904 | 965 | ||
905 | if (mlc == NULL) | 966 | BUG_ON(mlc == NULL); |
906 | return -EINVAL; | ||
907 | 967 | ||
908 | write_lock_irqsave(&hil_mlcs_lock, flags); | 968 | write_lock_irqsave(&hil_mlcs_lock, flags); |
909 | list_for_each(tmp, &hil_mlcs) { | 969 | list_for_each(tmp, &hil_mlcs) |
910 | if (list_entry(tmp, hil_mlc, list) == mlc) | 970 | if (list_entry(tmp, hil_mlc, list) == mlc) |
911 | goto found; | 971 | goto found; |
912 | } | ||
913 | 972 | ||
914 | /* not found in list */ | 973 | /* not found in list */ |
915 | write_unlock_irqrestore(&hil_mlcs_lock, flags); | 974 | write_unlock_irqrestore(&hil_mlcs_lock, flags); |
@@ -918,7 +977,7 @@ int hil_mlc_unregister(hil_mlc *mlc) { | |||
918 | 977 | ||
919 | found: | 978 | found: |
920 | list_del(tmp); | 979 | list_del(tmp); |
921 | write_unlock_irqrestore(&hil_mlcs_lock, flags); | 980 | write_unlock_irqrestore(&hil_mlcs_lock, flags); |
922 | 981 | ||
923 | for (i = 0; i < HIL_MLC_DEVMEM; i++) { | 982 | for (i = 0; i < HIL_MLC_DEVMEM; i++) { |
924 | serio_unregister_port(mlc->serio[i]); | 983 | serio_unregister_port(mlc->serio[i]); |
@@ -942,7 +1001,7 @@ static int __init hil_mlc_init(void) | |||
942 | 1001 | ||
943 | return 0; | 1002 | return 0; |
944 | } | 1003 | } |
945 | 1004 | ||
946 | static void __exit hil_mlc_exit(void) | 1005 | static void __exit hil_mlc_exit(void) |
947 | { | 1006 | { |
948 | del_timer(&hil_mlcs_kicker); | 1007 | del_timer(&hil_mlcs_kicker); |
@@ -950,6 +1009,6 @@ static void __exit hil_mlc_exit(void) | |||
950 | tasklet_disable(&hil_mlcs_tasklet); | 1009 | tasklet_disable(&hil_mlcs_tasklet); |
951 | tasklet_kill(&hil_mlcs_tasklet); | 1010 | tasklet_kill(&hil_mlcs_tasklet); |
952 | } | 1011 | } |
953 | 1012 | ||
954 | module_init(hil_mlc_init); | 1013 | module_init(hil_mlc_init); |
955 | module_exit(hil_mlc_exit); | 1014 | module_exit(hil_mlc_exit); |
diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c index b57370dc4e3d..6af199805ffc 100644 --- a/drivers/input/serio/hp_sdc.c +++ b/drivers/input/serio/hp_sdc.c | |||
@@ -34,27 +34,27 @@ | |||
34 | * | 34 | * |
35 | * Driver theory of operation: | 35 | * Driver theory of operation: |
36 | * | 36 | * |
37 | * hp_sdc_put does all writing to the SDC. ISR can run on a different | 37 | * hp_sdc_put does all writing to the SDC. ISR can run on a different |
38 | * CPU than hp_sdc_put, but only one CPU runs hp_sdc_put at a time | 38 | * CPU than hp_sdc_put, but only one CPU runs hp_sdc_put at a time |
39 | * (it cannot really benefit from SMP anyway.) A tasket fit this perfectly. | 39 | * (it cannot really benefit from SMP anyway.) A tasket fit this perfectly. |
40 | * | 40 | * |
41 | * All data coming back from the SDC is sent via interrupt and can be read | 41 | * All data coming back from the SDC is sent via interrupt and can be read |
42 | * fully in the ISR, so there are no latency/throughput problems there. | 42 | * fully in the ISR, so there are no latency/throughput problems there. |
43 | * The problem is with output, due to the slow clock speed of the SDC | 43 | * The problem is with output, due to the slow clock speed of the SDC |
44 | * compared to the CPU. This should not be too horrible most of the time, | 44 | * compared to the CPU. This should not be too horrible most of the time, |
45 | * but if used with HIL devices that support the multibyte transfer command, | 45 | * but if used with HIL devices that support the multibyte transfer command, |
46 | * keeping outbound throughput flowing at the 6500KBps that the HIL is | 46 | * keeping outbound throughput flowing at the 6500KBps that the HIL is |
47 | * capable of is more than can be done at HZ=100. | 47 | * capable of is more than can be done at HZ=100. |
48 | * | 48 | * |
49 | * Busy polling for IBF clear wastes CPU cycles and bus cycles. hp_sdc.ibf | 49 | * Busy polling for IBF clear wastes CPU cycles and bus cycles. hp_sdc.ibf |
50 | * is set to 0 when the IBF flag in the status register has cleared. ISR | 50 | * is set to 0 when the IBF flag in the status register has cleared. ISR |
51 | * may do this, and may also access the parts of queued transactions related | 51 | * may do this, and may also access the parts of queued transactions related |
52 | * to reading data back from the SDC, but otherwise will not touch the | 52 | * to reading data back from the SDC, but otherwise will not touch the |
53 | * hp_sdc state. Whenever a register is written hp_sdc.ibf is set to 1. | 53 | * hp_sdc state. Whenever a register is written hp_sdc.ibf is set to 1. |
54 | * | 54 | * |
55 | * The i8042 write index and the values in the 4-byte input buffer | 55 | * The i8042 write index and the values in the 4-byte input buffer |
56 | * starting at 0x70 are kept track of in hp_sdc.wi, and .r7[], respectively, | 56 | * starting at 0x70 are kept track of in hp_sdc.wi, and .r7[], respectively, |
57 | * to minimize the amount of IO needed to the SDC. However these values | 57 | * to minimize the amount of IO needed to the SDC. However these values |
58 | * do not need to be locked since they are only ever accessed by hp_sdc_put. | 58 | * do not need to be locked since they are only ever accessed by hp_sdc_put. |
59 | * | 59 | * |
60 | * A timer task schedules the tasklet once per second just to make | 60 | * A timer task schedules the tasklet once per second just to make |
@@ -100,39 +100,46 @@ EXPORT_SYMBOL(hp_sdc_release_timer_irq); | |||
100 | EXPORT_SYMBOL(hp_sdc_release_hil_irq); | 100 | EXPORT_SYMBOL(hp_sdc_release_hil_irq); |
101 | EXPORT_SYMBOL(hp_sdc_release_cooked_irq); | 101 | EXPORT_SYMBOL(hp_sdc_release_cooked_irq); |
102 | 102 | ||
103 | EXPORT_SYMBOL(__hp_sdc_enqueue_transaction); | ||
103 | EXPORT_SYMBOL(hp_sdc_enqueue_transaction); | 104 | EXPORT_SYMBOL(hp_sdc_enqueue_transaction); |
104 | EXPORT_SYMBOL(hp_sdc_dequeue_transaction); | 105 | EXPORT_SYMBOL(hp_sdc_dequeue_transaction); |
105 | 106 | ||
106 | static hp_i8042_sdc hp_sdc; /* All driver state is kept in here. */ | 107 | static hp_i8042_sdc hp_sdc; /* All driver state is kept in here. */ |
107 | 108 | ||
108 | /*************** primitives for use in any context *********************/ | 109 | /*************** primitives for use in any context *********************/ |
109 | static inline uint8_t hp_sdc_status_in8 (void) { | 110 | static inline uint8_t hp_sdc_status_in8(void) |
111 | { | ||
110 | uint8_t status; | 112 | uint8_t status; |
111 | unsigned long flags; | 113 | unsigned long flags; |
112 | 114 | ||
113 | write_lock_irqsave(&hp_sdc.ibf_lock, flags); | 115 | write_lock_irqsave(&hp_sdc.ibf_lock, flags); |
114 | status = sdc_readb(hp_sdc.status_io); | 116 | status = sdc_readb(hp_sdc.status_io); |
115 | if (!(status & HP_SDC_STATUS_IBF)) hp_sdc.ibf = 0; | 117 | if (!(status & HP_SDC_STATUS_IBF)) |
118 | hp_sdc.ibf = 0; | ||
116 | write_unlock_irqrestore(&hp_sdc.ibf_lock, flags); | 119 | write_unlock_irqrestore(&hp_sdc.ibf_lock, flags); |
117 | 120 | ||
118 | return status; | 121 | return status; |
119 | } | 122 | } |
120 | 123 | ||
121 | static inline uint8_t hp_sdc_data_in8 (void) { | 124 | static inline uint8_t hp_sdc_data_in8(void) |
122 | return sdc_readb(hp_sdc.data_io); | 125 | { |
126 | return sdc_readb(hp_sdc.data_io); | ||
123 | } | 127 | } |
124 | 128 | ||
125 | static inline void hp_sdc_status_out8 (uint8_t val) { | 129 | static inline void hp_sdc_status_out8(uint8_t val) |
130 | { | ||
126 | unsigned long flags; | 131 | unsigned long flags; |
127 | 132 | ||
128 | write_lock_irqsave(&hp_sdc.ibf_lock, flags); | 133 | write_lock_irqsave(&hp_sdc.ibf_lock, flags); |
129 | hp_sdc.ibf = 1; | 134 | hp_sdc.ibf = 1; |
130 | if ((val & 0xf0) == 0xe0) hp_sdc.wi = 0xff; | 135 | if ((val & 0xf0) == 0xe0) |
136 | hp_sdc.wi = 0xff; | ||
131 | sdc_writeb(val, hp_sdc.status_io); | 137 | sdc_writeb(val, hp_sdc.status_io); |
132 | write_unlock_irqrestore(&hp_sdc.ibf_lock, flags); | 138 | write_unlock_irqrestore(&hp_sdc.ibf_lock, flags); |
133 | } | 139 | } |
134 | 140 | ||
135 | static inline void hp_sdc_data_out8 (uint8_t val) { | 141 | static inline void hp_sdc_data_out8(uint8_t val) |
142 | { | ||
136 | unsigned long flags; | 143 | unsigned long flags; |
137 | 144 | ||
138 | write_lock_irqsave(&hp_sdc.ibf_lock, flags); | 145 | write_lock_irqsave(&hp_sdc.ibf_lock, flags); |
@@ -141,11 +148,12 @@ static inline void hp_sdc_data_out8 (uint8_t val) { | |||
141 | write_unlock_irqrestore(&hp_sdc.ibf_lock, flags); | 148 | write_unlock_irqrestore(&hp_sdc.ibf_lock, flags); |
142 | } | 149 | } |
143 | 150 | ||
144 | /* Care must be taken to only invoke hp_sdc_spin_ibf when | 151 | /* Care must be taken to only invoke hp_sdc_spin_ibf when |
145 | * absolutely needed, or in rarely invoked subroutines. | 152 | * absolutely needed, or in rarely invoked subroutines. |
146 | * Not only does it waste CPU cycles, it also wastes bus cycles. | 153 | * Not only does it waste CPU cycles, it also wastes bus cycles. |
147 | */ | 154 | */ |
148 | static inline void hp_sdc_spin_ibf(void) { | 155 | static inline void hp_sdc_spin_ibf(void) |
156 | { | ||
149 | unsigned long flags; | 157 | unsigned long flags; |
150 | rwlock_t *lock; | 158 | rwlock_t *lock; |
151 | 159 | ||
@@ -158,19 +166,21 @@ static inline void hp_sdc_spin_ibf(void) { | |||
158 | } | 166 | } |
159 | read_unlock(lock); | 167 | read_unlock(lock); |
160 | write_lock(lock); | 168 | write_lock(lock); |
161 | while (sdc_readb(hp_sdc.status_io) & HP_SDC_STATUS_IBF) {}; | 169 | while (sdc_readb(hp_sdc.status_io) & HP_SDC_STATUS_IBF) |
170 | { } | ||
162 | hp_sdc.ibf = 0; | 171 | hp_sdc.ibf = 0; |
163 | write_unlock_irqrestore(lock, flags); | 172 | write_unlock_irqrestore(lock, flags); |
164 | } | 173 | } |
165 | 174 | ||
166 | 175 | ||
167 | /************************ Interrupt context functions ************************/ | 176 | /************************ Interrupt context functions ************************/ |
168 | static void hp_sdc_take (int irq, void *dev_id, uint8_t status, uint8_t data) { | 177 | static void hp_sdc_take(int irq, void *dev_id, uint8_t status, uint8_t data) |
178 | { | ||
169 | hp_sdc_transaction *curr; | 179 | hp_sdc_transaction *curr; |
170 | 180 | ||
171 | read_lock(&hp_sdc.rtq_lock); | 181 | read_lock(&hp_sdc.rtq_lock); |
172 | if (hp_sdc.rcurr < 0) { | 182 | if (hp_sdc.rcurr < 0) { |
173 | read_unlock(&hp_sdc.rtq_lock); | 183 | read_unlock(&hp_sdc.rtq_lock); |
174 | return; | 184 | return; |
175 | } | 185 | } |
176 | curr = hp_sdc.tq[hp_sdc.rcurr]; | 186 | curr = hp_sdc.tq[hp_sdc.rcurr]; |
@@ -183,25 +193,27 @@ static void hp_sdc_take (int irq, void *dev_id, uint8_t status, uint8_t data) { | |||
183 | 193 | ||
184 | if (hp_sdc.rqty <= 0) { | 194 | if (hp_sdc.rqty <= 0) { |
185 | /* All data has been gathered. */ | 195 | /* All data has been gathered. */ |
186 | if(curr->seq[curr->actidx] & HP_SDC_ACT_SEMAPHORE) { | 196 | if (curr->seq[curr->actidx] & HP_SDC_ACT_SEMAPHORE) |
187 | if (curr->act.semaphore) up(curr->act.semaphore); | 197 | if (curr->act.semaphore) |
188 | } | 198 | up(curr->act.semaphore); |
189 | if(curr->seq[curr->actidx] & HP_SDC_ACT_CALLBACK) { | 199 | |
200 | if (curr->seq[curr->actidx] & HP_SDC_ACT_CALLBACK) | ||
190 | if (curr->act.irqhook) | 201 | if (curr->act.irqhook) |
191 | curr->act.irqhook(irq, dev_id, status, data); | 202 | curr->act.irqhook(irq, dev_id, status, data); |
192 | } | 203 | |
193 | curr->actidx = curr->idx; | 204 | curr->actidx = curr->idx; |
194 | curr->idx++; | 205 | curr->idx++; |
195 | /* Return control of this transaction */ | 206 | /* Return control of this transaction */ |
196 | write_lock(&hp_sdc.rtq_lock); | 207 | write_lock(&hp_sdc.rtq_lock); |
197 | hp_sdc.rcurr = -1; | 208 | hp_sdc.rcurr = -1; |
198 | hp_sdc.rqty = 0; | 209 | hp_sdc.rqty = 0; |
199 | write_unlock(&hp_sdc.rtq_lock); | 210 | write_unlock(&hp_sdc.rtq_lock); |
200 | tasklet_schedule(&hp_sdc.task); | 211 | tasklet_schedule(&hp_sdc.task); |
201 | } | 212 | } |
202 | } | 213 | } |
203 | 214 | ||
204 | static irqreturn_t hp_sdc_isr(int irq, void *dev_id) { | 215 | static irqreturn_t hp_sdc_isr(int irq, void *dev_id) |
216 | { | ||
205 | uint8_t status, data; | 217 | uint8_t status, data; |
206 | 218 | ||
207 | status = hp_sdc_status_in8(); | 219 | status = hp_sdc_status_in8(); |
@@ -209,67 +221,74 @@ static irqreturn_t hp_sdc_isr(int irq, void *dev_id) { | |||
209 | data = hp_sdc_data_in8(); | 221 | data = hp_sdc_data_in8(); |
210 | 222 | ||
211 | /* For now we are ignoring these until we get the SDC to behave. */ | 223 | /* For now we are ignoring these until we get the SDC to behave. */ |
212 | if (((status & 0xf1) == 0x51) && data == 0x82) { | 224 | if (((status & 0xf1) == 0x51) && data == 0x82) |
213 | return IRQ_HANDLED; | 225 | return IRQ_HANDLED; |
214 | } | ||
215 | 226 | ||
216 | switch(status & HP_SDC_STATUS_IRQMASK) { | 227 | switch (status & HP_SDC_STATUS_IRQMASK) { |
217 | case 0: /* This case is not documented. */ | 228 | case 0: /* This case is not documented. */ |
218 | break; | 229 | break; |
219 | case HP_SDC_STATUS_USERTIMER: | 230 | |
220 | case HP_SDC_STATUS_PERIODIC: | 231 | case HP_SDC_STATUS_USERTIMER: |
221 | case HP_SDC_STATUS_TIMER: | 232 | case HP_SDC_STATUS_PERIODIC: |
233 | case HP_SDC_STATUS_TIMER: | ||
222 | read_lock(&hp_sdc.hook_lock); | 234 | read_lock(&hp_sdc.hook_lock); |
223 | if (hp_sdc.timer != NULL) | 235 | if (hp_sdc.timer != NULL) |
224 | hp_sdc.timer(irq, dev_id, status, data); | 236 | hp_sdc.timer(irq, dev_id, status, data); |
225 | read_unlock(&hp_sdc.hook_lock); | 237 | read_unlock(&hp_sdc.hook_lock); |
226 | break; | 238 | break; |
227 | case HP_SDC_STATUS_REG: | 239 | |
240 | case HP_SDC_STATUS_REG: | ||
228 | hp_sdc_take(irq, dev_id, status, data); | 241 | hp_sdc_take(irq, dev_id, status, data); |
229 | break; | 242 | break; |
230 | case HP_SDC_STATUS_HILCMD: | 243 | |
231 | case HP_SDC_STATUS_HILDATA: | 244 | case HP_SDC_STATUS_HILCMD: |
245 | case HP_SDC_STATUS_HILDATA: | ||
232 | read_lock(&hp_sdc.hook_lock); | 246 | read_lock(&hp_sdc.hook_lock); |
233 | if (hp_sdc.hil != NULL) | 247 | if (hp_sdc.hil != NULL) |
234 | hp_sdc.hil(irq, dev_id, status, data); | 248 | hp_sdc.hil(irq, dev_id, status, data); |
235 | read_unlock(&hp_sdc.hook_lock); | 249 | read_unlock(&hp_sdc.hook_lock); |
236 | break; | 250 | break; |
237 | case HP_SDC_STATUS_PUP: | 251 | |
252 | case HP_SDC_STATUS_PUP: | ||
238 | read_lock(&hp_sdc.hook_lock); | 253 | read_lock(&hp_sdc.hook_lock); |
239 | if (hp_sdc.pup != NULL) | 254 | if (hp_sdc.pup != NULL) |
240 | hp_sdc.pup(irq, dev_id, status, data); | 255 | hp_sdc.pup(irq, dev_id, status, data); |
241 | else printk(KERN_INFO PREFIX "HP SDC reports successful PUP.\n"); | 256 | else |
257 | printk(KERN_INFO PREFIX "HP SDC reports successful PUP.\n"); | ||
242 | read_unlock(&hp_sdc.hook_lock); | 258 | read_unlock(&hp_sdc.hook_lock); |
243 | break; | 259 | break; |
244 | default: | 260 | |
261 | default: | ||
245 | read_lock(&hp_sdc.hook_lock); | 262 | read_lock(&hp_sdc.hook_lock); |
246 | if (hp_sdc.cooked != NULL) | 263 | if (hp_sdc.cooked != NULL) |
247 | hp_sdc.cooked(irq, dev_id, status, data); | 264 | hp_sdc.cooked(irq, dev_id, status, data); |
248 | read_unlock(&hp_sdc.hook_lock); | 265 | read_unlock(&hp_sdc.hook_lock); |
249 | break; | 266 | break; |
250 | } | 267 | } |
268 | |||
251 | return IRQ_HANDLED; | 269 | return IRQ_HANDLED; |
252 | } | 270 | } |
253 | 271 | ||
254 | 272 | ||
255 | static irqreturn_t hp_sdc_nmisr(int irq, void *dev_id) { | 273 | static irqreturn_t hp_sdc_nmisr(int irq, void *dev_id) |
274 | { | ||
256 | int status; | 275 | int status; |
257 | 276 | ||
258 | status = hp_sdc_status_in8(); | 277 | status = hp_sdc_status_in8(); |
259 | printk(KERN_WARNING PREFIX "NMI !\n"); | 278 | printk(KERN_WARNING PREFIX "NMI !\n"); |
260 | 279 | ||
261 | #if 0 | 280 | #if 0 |
262 | if (status & HP_SDC_NMISTATUS_FHS) { | 281 | if (status & HP_SDC_NMISTATUS_FHS) { |
263 | read_lock(&hp_sdc.hook_lock); | 282 | read_lock(&hp_sdc.hook_lock); |
264 | if (hp_sdc.timer != NULL) | 283 | if (hp_sdc.timer != NULL) |
265 | hp_sdc.timer(irq, dev_id, status, 0); | 284 | hp_sdc.timer(irq, dev_id, status, 0); |
266 | read_unlock(&hp_sdc.hook_lock); | 285 | read_unlock(&hp_sdc.hook_lock); |
267 | } | 286 | } else { |
268 | else { | ||
269 | /* TODO: pass this on to the HIL handler, or do SAK here? */ | 287 | /* TODO: pass this on to the HIL handler, or do SAK here? */ |
270 | printk(KERN_WARNING PREFIX "HIL NMI\n"); | 288 | printk(KERN_WARNING PREFIX "HIL NMI\n"); |
271 | } | 289 | } |
272 | #endif | 290 | #endif |
291 | |||
273 | return IRQ_HANDLED; | 292 | return IRQ_HANDLED; |
274 | } | 293 | } |
275 | 294 | ||
@@ -278,13 +297,17 @@ static irqreturn_t hp_sdc_nmisr(int irq, void *dev_id) { | |||
278 | 297 | ||
279 | unsigned long hp_sdc_put(void); | 298 | unsigned long hp_sdc_put(void); |
280 | 299 | ||
281 | static void hp_sdc_tasklet(unsigned long foo) { | 300 | static void hp_sdc_tasklet(unsigned long foo) |
282 | 301 | { | |
283 | write_lock_irq(&hp_sdc.rtq_lock); | 302 | write_lock_irq(&hp_sdc.rtq_lock); |
303 | |||
284 | if (hp_sdc.rcurr >= 0) { | 304 | if (hp_sdc.rcurr >= 0) { |
285 | struct timeval tv; | 305 | struct timeval tv; |
306 | |||
286 | do_gettimeofday(&tv); | 307 | do_gettimeofday(&tv); |
287 | if (tv.tv_sec > hp_sdc.rtv.tv_sec) tv.tv_usec += 1000000; | 308 | if (tv.tv_sec > hp_sdc.rtv.tv_sec) |
309 | tv.tv_usec += USEC_PER_SEC; | ||
310 | |||
288 | if (tv.tv_usec - hp_sdc.rtv.tv_usec > HP_SDC_MAX_REG_DELAY) { | 311 | if (tv.tv_usec - hp_sdc.rtv.tv_usec > HP_SDC_MAX_REG_DELAY) { |
289 | hp_sdc_transaction *curr; | 312 | hp_sdc_transaction *curr; |
290 | uint8_t tmp; | 313 | uint8_t tmp; |
@@ -300,27 +323,29 @@ static void hp_sdc_tasklet(unsigned long foo) { | |||
300 | hp_sdc.rqty = 0; | 323 | hp_sdc.rqty = 0; |
301 | tmp = curr->seq[curr->actidx]; | 324 | tmp = curr->seq[curr->actidx]; |
302 | curr->seq[curr->actidx] |= HP_SDC_ACT_DEAD; | 325 | curr->seq[curr->actidx] |= HP_SDC_ACT_DEAD; |
303 | if(tmp & HP_SDC_ACT_SEMAPHORE) { | 326 | if (tmp & HP_SDC_ACT_SEMAPHORE) |
304 | if (curr->act.semaphore) | 327 | if (curr->act.semaphore) |
305 | up(curr->act.semaphore); | 328 | up(curr->act.semaphore); |
306 | } | 329 | |
307 | if(tmp & HP_SDC_ACT_CALLBACK) { | 330 | if (tmp & HP_SDC_ACT_CALLBACK) { |
308 | /* Note this means that irqhooks may be called | 331 | /* Note this means that irqhooks may be called |
309 | * in tasklet/bh context. | 332 | * in tasklet/bh context. |
310 | */ | 333 | */ |
311 | if (curr->act.irqhook) | 334 | if (curr->act.irqhook) |
312 | curr->act.irqhook(0, NULL, 0, 0); | 335 | curr->act.irqhook(0, NULL, 0, 0); |
313 | } | 336 | } |
337 | |||
314 | curr->actidx = curr->idx; | 338 | curr->actidx = curr->idx; |
315 | curr->idx++; | 339 | curr->idx++; |
316 | hp_sdc.rcurr = -1; | 340 | hp_sdc.rcurr = -1; |
317 | } | 341 | } |
318 | } | 342 | } |
319 | write_unlock_irq(&hp_sdc.rtq_lock); | 343 | write_unlock_irq(&hp_sdc.rtq_lock); |
320 | hp_sdc_put(); | 344 | hp_sdc_put(); |
321 | } | 345 | } |
322 | 346 | ||
323 | unsigned long hp_sdc_put(void) { | 347 | unsigned long hp_sdc_put(void) |
348 | { | ||
324 | hp_sdc_transaction *curr; | 349 | hp_sdc_transaction *curr; |
325 | uint8_t act; | 350 | uint8_t act; |
326 | int idx, curridx; | 351 | int idx, curridx; |
@@ -333,19 +358,24 @@ unsigned long hp_sdc_put(void) { | |||
333 | requires output, so we skip to the administrativa. */ | 358 | requires output, so we skip to the administrativa. */ |
334 | if (hp_sdc.ibf) { | 359 | if (hp_sdc.ibf) { |
335 | hp_sdc_status_in8(); | 360 | hp_sdc_status_in8(); |
336 | if (hp_sdc.ibf) goto finish; | 361 | if (hp_sdc.ibf) |
362 | goto finish; | ||
337 | } | 363 | } |
338 | 364 | ||
339 | anew: | 365 | anew: |
340 | /* See if we are in the middle of a sequence. */ | 366 | /* See if we are in the middle of a sequence. */ |
341 | if (hp_sdc.wcurr < 0) hp_sdc.wcurr = 0; | 367 | if (hp_sdc.wcurr < 0) |
368 | hp_sdc.wcurr = 0; | ||
342 | read_lock_irq(&hp_sdc.rtq_lock); | 369 | read_lock_irq(&hp_sdc.rtq_lock); |
343 | if (hp_sdc.rcurr == hp_sdc.wcurr) hp_sdc.wcurr++; | 370 | if (hp_sdc.rcurr == hp_sdc.wcurr) |
371 | hp_sdc.wcurr++; | ||
344 | read_unlock_irq(&hp_sdc.rtq_lock); | 372 | read_unlock_irq(&hp_sdc.rtq_lock); |
345 | if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0; | 373 | if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) |
374 | hp_sdc.wcurr = 0; | ||
346 | curridx = hp_sdc.wcurr; | 375 | curridx = hp_sdc.wcurr; |
347 | 376 | ||
348 | if (hp_sdc.tq[curridx] != NULL) goto start; | 377 | if (hp_sdc.tq[curridx] != NULL) |
378 | goto start; | ||
349 | 379 | ||
350 | while (++curridx != hp_sdc.wcurr) { | 380 | while (++curridx != hp_sdc.wcurr) { |
351 | if (curridx >= HP_SDC_QUEUE_LEN) { | 381 | if (curridx >= HP_SDC_QUEUE_LEN) { |
@@ -358,7 +388,8 @@ unsigned long hp_sdc_put(void) { | |||
358 | continue; | 388 | continue; |
359 | } | 389 | } |
360 | read_unlock_irq(&hp_sdc.rtq_lock); | 390 | read_unlock_irq(&hp_sdc.rtq_lock); |
361 | if (hp_sdc.tq[curridx] != NULL) break; /* Found one. */ | 391 | if (hp_sdc.tq[curridx] != NULL) |
392 | break; /* Found one. */ | ||
362 | } | 393 | } |
363 | if (curridx == hp_sdc.wcurr) { /* There's nothing queued to do. */ | 394 | if (curridx == hp_sdc.wcurr) { /* There's nothing queued to do. */ |
364 | curridx = -1; | 395 | curridx = -1; |
@@ -374,7 +405,8 @@ unsigned long hp_sdc_put(void) { | |||
374 | goto finish; | 405 | goto finish; |
375 | } | 406 | } |
376 | 407 | ||
377 | if (hp_sdc.wcurr == -1) goto done; | 408 | if (hp_sdc.wcurr == -1) |
409 | goto done; | ||
378 | 410 | ||
379 | curr = hp_sdc.tq[curridx]; | 411 | curr = hp_sdc.tq[curridx]; |
380 | idx = curr->actidx; | 412 | idx = curr->actidx; |
@@ -383,20 +415,23 @@ unsigned long hp_sdc_put(void) { | |||
383 | hp_sdc.tq[curridx] = NULL; | 415 | hp_sdc.tq[curridx] = NULL; |
384 | /* Interleave outbound data between the transactions. */ | 416 | /* Interleave outbound data between the transactions. */ |
385 | hp_sdc.wcurr++; | 417 | hp_sdc.wcurr++; |
386 | if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0; | 418 | if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) |
387 | goto finish; | 419 | hp_sdc.wcurr = 0; |
420 | goto finish; | ||
388 | } | 421 | } |
389 | 422 | ||
390 | act = curr->seq[idx]; | 423 | act = curr->seq[idx]; |
391 | idx++; | 424 | idx++; |
392 | 425 | ||
393 | if (curr->idx >= curr->endidx) { | 426 | if (curr->idx >= curr->endidx) { |
394 | if (act & HP_SDC_ACT_DEALLOC) kfree(curr); | 427 | if (act & HP_SDC_ACT_DEALLOC) |
428 | kfree(curr); | ||
395 | hp_sdc.tq[curridx] = NULL; | 429 | hp_sdc.tq[curridx] = NULL; |
396 | /* Interleave outbound data between the transactions. */ | 430 | /* Interleave outbound data between the transactions. */ |
397 | hp_sdc.wcurr++; | 431 | hp_sdc.wcurr++; |
398 | if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0; | 432 | if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) |
399 | goto finish; | 433 | hp_sdc.wcurr = 0; |
434 | goto finish; | ||
400 | } | 435 | } |
401 | 436 | ||
402 | while (act & HP_SDC_ACT_PRECMD) { | 437 | while (act & HP_SDC_ACT_PRECMD) { |
@@ -409,9 +444,10 @@ unsigned long hp_sdc_put(void) { | |||
409 | curr->idx++; | 444 | curr->idx++; |
410 | /* act finished? */ | 445 | /* act finished? */ |
411 | if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_PRECMD) | 446 | if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_PRECMD) |
412 | goto actdone; | 447 | goto actdone; |
413 | /* skip quantity field if data-out sequence follows. */ | 448 | /* skip quantity field if data-out sequence follows. */ |
414 | if (act & HP_SDC_ACT_DATAOUT) curr->idx++; | 449 | if (act & HP_SDC_ACT_DATAOUT) |
450 | curr->idx++; | ||
415 | goto finish; | 451 | goto finish; |
416 | } | 452 | } |
417 | if (act & HP_SDC_ACT_DATAOUT) { | 453 | if (act & HP_SDC_ACT_DATAOUT) { |
@@ -423,15 +459,15 @@ unsigned long hp_sdc_put(void) { | |||
423 | hp_sdc_data_out8(curr->seq[curr->idx]); | 459 | hp_sdc_data_out8(curr->seq[curr->idx]); |
424 | curr->idx++; | 460 | curr->idx++; |
425 | /* act finished? */ | 461 | /* act finished? */ |
426 | if ((curr->idx - idx >= qty) && | 462 | if (curr->idx - idx >= qty && |
427 | ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAOUT)) | 463 | (act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAOUT) |
428 | goto actdone; | 464 | goto actdone; |
429 | goto finish; | 465 | goto finish; |
430 | } | 466 | } |
431 | idx += qty; | 467 | idx += qty; |
432 | act &= ~HP_SDC_ACT_DATAOUT; | 468 | act &= ~HP_SDC_ACT_DATAOUT; |
433 | } | 469 | } else |
434 | else while (act & HP_SDC_ACT_DATAREG) { | 470 | while (act & HP_SDC_ACT_DATAREG) { |
435 | int mask; | 471 | int mask; |
436 | uint8_t w7[4]; | 472 | uint8_t w7[4]; |
437 | 473 | ||
@@ -445,26 +481,30 @@ unsigned long hp_sdc_put(void) { | |||
445 | act &= ~HP_SDC_ACT_DATAREG; | 481 | act &= ~HP_SDC_ACT_DATAREG; |
446 | break; | 482 | break; |
447 | } | 483 | } |
448 | 484 | ||
449 | w7[0] = (mask & 1) ? curr->seq[++idx] : hp_sdc.r7[0]; | 485 | w7[0] = (mask & 1) ? curr->seq[++idx] : hp_sdc.r7[0]; |
450 | w7[1] = (mask & 2) ? curr->seq[++idx] : hp_sdc.r7[1]; | 486 | w7[1] = (mask & 2) ? curr->seq[++idx] : hp_sdc.r7[1]; |
451 | w7[2] = (mask & 4) ? curr->seq[++idx] : hp_sdc.r7[2]; | 487 | w7[2] = (mask & 4) ? curr->seq[++idx] : hp_sdc.r7[2]; |
452 | w7[3] = (mask & 8) ? curr->seq[++idx] : hp_sdc.r7[3]; | 488 | w7[3] = (mask & 8) ? curr->seq[++idx] : hp_sdc.r7[3]; |
453 | 489 | ||
454 | if (hp_sdc.wi > 0x73 || hp_sdc.wi < 0x70 || | 490 | if (hp_sdc.wi > 0x73 || hp_sdc.wi < 0x70 || |
455 | w7[hp_sdc.wi-0x70] == hp_sdc.r7[hp_sdc.wi-0x70]) { | 491 | w7[hp_sdc.wi - 0x70] == hp_sdc.r7[hp_sdc.wi - 0x70]) { |
456 | int i = 0; | 492 | int i = 0; |
457 | 493 | ||
458 | /* Need to point the write index register */ | 494 | /* Need to point the write index register */ |
459 | while ((i < 4) && w7[i] == hp_sdc.r7[i]) i++; | 495 | while (i < 4 && w7[i] == hp_sdc.r7[i]) |
496 | i++; | ||
497 | |||
460 | if (i < 4) { | 498 | if (i < 4) { |
461 | hp_sdc_status_out8(HP_SDC_CMD_SET_D0 + i); | 499 | hp_sdc_status_out8(HP_SDC_CMD_SET_D0 + i); |
462 | hp_sdc.wi = 0x70 + i; | 500 | hp_sdc.wi = 0x70 + i; |
463 | goto finish; | 501 | goto finish; |
464 | } | 502 | } |
503 | |||
465 | idx++; | 504 | idx++; |
466 | if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAREG) | 505 | if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAREG) |
467 | goto actdone; | 506 | goto actdone; |
507 | |||
468 | curr->idx = idx; | 508 | curr->idx = idx; |
469 | act &= ~HP_SDC_ACT_DATAREG; | 509 | act &= ~HP_SDC_ACT_DATAREG; |
470 | break; | 510 | break; |
@@ -476,12 +516,13 @@ unsigned long hp_sdc_put(void) { | |||
476 | { | 516 | { |
477 | int i = 0; | 517 | int i = 0; |
478 | 518 | ||
479 | while ((i < 4) && w7[i] == hp_sdc.r7[i]) i++; | 519 | while ((i < 4) && w7[i] == hp_sdc.r7[i]) |
520 | i++; | ||
480 | if (i >= 4) { | 521 | if (i >= 4) { |
481 | curr->idx = idx + 1; | 522 | curr->idx = idx + 1; |
482 | if ((act & HP_SDC_ACT_DURING) == | 523 | if ((act & HP_SDC_ACT_DURING) == |
483 | HP_SDC_ACT_DATAREG) | 524 | HP_SDC_ACT_DATAREG) |
484 | goto actdone; | 525 | goto actdone; |
485 | } | 526 | } |
486 | } | 527 | } |
487 | goto finish; | 528 | goto finish; |
@@ -497,7 +538,7 @@ unsigned long hp_sdc_put(void) { | |||
497 | 538 | ||
498 | 539 | ||
499 | if (act & HP_SDC_ACT_POSTCMD) { | 540 | if (act & HP_SDC_ACT_POSTCMD) { |
500 | uint8_t postcmd; | 541 | uint8_t postcmd; |
501 | 542 | ||
502 | /* curr->idx should == idx at this point. */ | 543 | /* curr->idx should == idx at this point. */ |
503 | postcmd = curr->seq[idx]; | 544 | postcmd = curr->seq[idx]; |
@@ -505,12 +546,12 @@ unsigned long hp_sdc_put(void) { | |||
505 | if (act & HP_SDC_ACT_DATAIN) { | 546 | if (act & HP_SDC_ACT_DATAIN) { |
506 | 547 | ||
507 | /* Start a new read */ | 548 | /* Start a new read */ |
508 | hp_sdc.rqty = curr->seq[curr->idx]; | 549 | hp_sdc.rqty = curr->seq[curr->idx]; |
509 | do_gettimeofday(&hp_sdc.rtv); | 550 | do_gettimeofday(&hp_sdc.rtv); |
510 | curr->idx++; | 551 | curr->idx++; |
511 | /* Still need to lock here in case of spurious irq. */ | 552 | /* Still need to lock here in case of spurious irq. */ |
512 | write_lock_irq(&hp_sdc.rtq_lock); | 553 | write_lock_irq(&hp_sdc.rtq_lock); |
513 | hp_sdc.rcurr = curridx; | 554 | hp_sdc.rcurr = curridx; |
514 | write_unlock_irq(&hp_sdc.rtq_lock); | 555 | write_unlock_irq(&hp_sdc.rtq_lock); |
515 | hp_sdc_status_out8(postcmd); | 556 | hp_sdc_status_out8(postcmd); |
516 | goto finish; | 557 | goto finish; |
@@ -519,75 +560,86 @@ unsigned long hp_sdc_put(void) { | |||
519 | goto actdone; | 560 | goto actdone; |
520 | } | 561 | } |
521 | 562 | ||
522 | actdone: | 563 | actdone: |
523 | if (act & HP_SDC_ACT_SEMAPHORE) { | 564 | if (act & HP_SDC_ACT_SEMAPHORE) |
524 | up(curr->act.semaphore); | 565 | up(curr->act.semaphore); |
525 | } | 566 | else if (act & HP_SDC_ACT_CALLBACK) |
526 | else if (act & HP_SDC_ACT_CALLBACK) { | ||
527 | curr->act.irqhook(0,NULL,0,0); | 567 | curr->act.irqhook(0,NULL,0,0); |
528 | } | 568 | |
529 | if (curr->idx >= curr->endidx) { /* This transaction is over. */ | 569 | if (curr->idx >= curr->endidx) { /* This transaction is over. */ |
530 | if (act & HP_SDC_ACT_DEALLOC) kfree(curr); | 570 | if (act & HP_SDC_ACT_DEALLOC) |
571 | kfree(curr); | ||
531 | hp_sdc.tq[curridx] = NULL; | 572 | hp_sdc.tq[curridx] = NULL; |
532 | } | 573 | } else { |
533 | else { | ||
534 | curr->actidx = idx + 1; | 574 | curr->actidx = idx + 1; |
535 | curr->idx = idx + 2; | 575 | curr->idx = idx + 2; |
536 | } | 576 | } |
537 | /* Interleave outbound data between the transactions. */ | 577 | /* Interleave outbound data between the transactions. */ |
538 | hp_sdc.wcurr++; | 578 | hp_sdc.wcurr++; |
539 | if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0; | 579 | if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) |
580 | hp_sdc.wcurr = 0; | ||
540 | 581 | ||
541 | finish: | 582 | finish: |
542 | /* If by some quirk IBF has cleared and our ISR has run to | 583 | /* If by some quirk IBF has cleared and our ISR has run to |
543 | see that that has happened, do it all again. */ | 584 | see that that has happened, do it all again. */ |
544 | if (!hp_sdc.ibf && limit++ < 20) goto anew; | 585 | if (!hp_sdc.ibf && limit++ < 20) |
586 | goto anew; | ||
545 | 587 | ||
546 | done: | 588 | done: |
547 | if (hp_sdc.wcurr >= 0) tasklet_schedule(&hp_sdc.task); | 589 | if (hp_sdc.wcurr >= 0) |
590 | tasklet_schedule(&hp_sdc.task); | ||
548 | write_unlock(&hp_sdc.lock); | 591 | write_unlock(&hp_sdc.lock); |
592 | |||
549 | return 0; | 593 | return 0; |
550 | } | 594 | } |
551 | 595 | ||
552 | /******* Functions called in either user or kernel context ****/ | 596 | /******* Functions called in either user or kernel context ****/ |
553 | int hp_sdc_enqueue_transaction(hp_sdc_transaction *this) { | 597 | int __hp_sdc_enqueue_transaction(hp_sdc_transaction *this) |
554 | unsigned long flags; | 598 | { |
555 | int i; | 599 | int i; |
556 | 600 | ||
557 | if (this == NULL) { | 601 | if (this == NULL) { |
558 | tasklet_schedule(&hp_sdc.task); | 602 | BUG(); |
559 | return -EINVAL; | 603 | return -EINVAL; |
560 | }; | 604 | } |
561 | |||
562 | write_lock_irqsave(&hp_sdc.lock, flags); | ||
563 | 605 | ||
564 | /* Can't have same transaction on queue twice */ | 606 | /* Can't have same transaction on queue twice */ |
565 | for (i=0; i < HP_SDC_QUEUE_LEN; i++) | 607 | for (i = 0; i < HP_SDC_QUEUE_LEN; i++) |
566 | if (hp_sdc.tq[i] == this) goto fail; | 608 | if (hp_sdc.tq[i] == this) |
609 | goto fail; | ||
567 | 610 | ||
568 | this->actidx = 0; | 611 | this->actidx = 0; |
569 | this->idx = 1; | 612 | this->idx = 1; |
570 | 613 | ||
571 | /* Search for empty slot */ | 614 | /* Search for empty slot */ |
572 | for (i=0; i < HP_SDC_QUEUE_LEN; i++) { | 615 | for (i = 0; i < HP_SDC_QUEUE_LEN; i++) |
573 | if (hp_sdc.tq[i] == NULL) { | 616 | if (hp_sdc.tq[i] == NULL) { |
574 | hp_sdc.tq[i] = this; | 617 | hp_sdc.tq[i] = this; |
575 | write_unlock_irqrestore(&hp_sdc.lock, flags); | ||
576 | tasklet_schedule(&hp_sdc.task); | 618 | tasklet_schedule(&hp_sdc.task); |
577 | return 0; | 619 | return 0; |
578 | } | 620 | } |
579 | } | 621 | |
580 | write_unlock_irqrestore(&hp_sdc.lock, flags); | ||
581 | printk(KERN_WARNING PREFIX "No free slot to add transaction.\n"); | 622 | printk(KERN_WARNING PREFIX "No free slot to add transaction.\n"); |
582 | return -EBUSY; | 623 | return -EBUSY; |
583 | 624 | ||
584 | fail: | 625 | fail: |
585 | write_unlock_irqrestore(&hp_sdc.lock,flags); | ||
586 | printk(KERN_WARNING PREFIX "Transaction add failed: transaction already queued?\n"); | 626 | printk(KERN_WARNING PREFIX "Transaction add failed: transaction already queued?\n"); |
587 | return -EINVAL; | 627 | return -EINVAL; |
588 | } | 628 | } |
589 | 629 | ||
590 | int hp_sdc_dequeue_transaction(hp_sdc_transaction *this) { | 630 | int hp_sdc_enqueue_transaction(hp_sdc_transaction *this) { |
631 | unsigned long flags; | ||
632 | int ret; | ||
633 | |||
634 | write_lock_irqsave(&hp_sdc.lock, flags); | ||
635 | ret = __hp_sdc_enqueue_transaction(this); | ||
636 | write_unlock_irqrestore(&hp_sdc.lock,flags); | ||
637 | |||
638 | return ret; | ||
639 | } | ||
640 | |||
641 | int hp_sdc_dequeue_transaction(hp_sdc_transaction *this) | ||
642 | { | ||
591 | unsigned long flags; | 643 | unsigned long flags; |
592 | int i; | 644 | int i; |
593 | 645 | ||
@@ -595,8 +647,9 @@ int hp_sdc_dequeue_transaction(hp_sdc_transaction *this) { | |||
595 | 647 | ||
596 | /* TODO: don't remove it if it's not done. */ | 648 | /* TODO: don't remove it if it's not done. */ |
597 | 649 | ||
598 | for (i=0; i < HP_SDC_QUEUE_LEN; i++) | 650 | for (i = 0; i < HP_SDC_QUEUE_LEN; i++) |
599 | if (hp_sdc.tq[i] == this) hp_sdc.tq[i] = NULL; | 651 | if (hp_sdc.tq[i] == this) |
652 | hp_sdc.tq[i] = NULL; | ||
600 | 653 | ||
601 | write_unlock_irqrestore(&hp_sdc.lock, flags); | 654 | write_unlock_irqrestore(&hp_sdc.lock, flags); |
602 | return 0; | 655 | return 0; |
@@ -605,11 +658,11 @@ int hp_sdc_dequeue_transaction(hp_sdc_transaction *this) { | |||
605 | 658 | ||
606 | 659 | ||
607 | /********************** User context functions **************************/ | 660 | /********************** User context functions **************************/ |
608 | int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback) { | 661 | int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback) |
609 | 662 | { | |
610 | if (callback == NULL || hp_sdc.dev == NULL) { | 663 | if (callback == NULL || hp_sdc.dev == NULL) |
611 | return -EINVAL; | 664 | return -EINVAL; |
612 | } | 665 | |
613 | write_lock_irq(&hp_sdc.hook_lock); | 666 | write_lock_irq(&hp_sdc.hook_lock); |
614 | if (hp_sdc.timer != NULL) { | 667 | if (hp_sdc.timer != NULL) { |
615 | write_unlock_irq(&hp_sdc.hook_lock); | 668 | write_unlock_irq(&hp_sdc.hook_lock); |
@@ -629,11 +682,11 @@ int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback) { | |||
629 | return 0; | 682 | return 0; |
630 | } | 683 | } |
631 | 684 | ||
632 | int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback) { | 685 | int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback) |
633 | 686 | { | |
634 | if (callback == NULL || hp_sdc.dev == NULL) { | 687 | if (callback == NULL || hp_sdc.dev == NULL) |
635 | return -EINVAL; | 688 | return -EINVAL; |
636 | } | 689 | |
637 | write_lock_irq(&hp_sdc.hook_lock); | 690 | write_lock_irq(&hp_sdc.hook_lock); |
638 | if (hp_sdc.hil != NULL) { | 691 | if (hp_sdc.hil != NULL) { |
639 | write_unlock_irq(&hp_sdc.hook_lock); | 692 | write_unlock_irq(&hp_sdc.hook_lock); |
@@ -650,11 +703,11 @@ int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback) { | |||
650 | return 0; | 703 | return 0; |
651 | } | 704 | } |
652 | 705 | ||
653 | int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback) { | 706 | int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback) |
654 | 707 | { | |
655 | if (callback == NULL || hp_sdc.dev == NULL) { | 708 | if (callback == NULL || hp_sdc.dev == NULL) |
656 | return -EINVAL; | 709 | return -EINVAL; |
657 | } | 710 | |
658 | write_lock_irq(&hp_sdc.hook_lock); | 711 | write_lock_irq(&hp_sdc.hook_lock); |
659 | if (hp_sdc.cooked != NULL) { | 712 | if (hp_sdc.cooked != NULL) { |
660 | write_unlock_irq(&hp_sdc.hook_lock); | 713 | write_unlock_irq(&hp_sdc.hook_lock); |
@@ -672,9 +725,8 @@ int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback) { | |||
672 | return 0; | 725 | return 0; |
673 | } | 726 | } |
674 | 727 | ||
675 | int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback) { | 728 | int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback) |
676 | 729 | { | |
677 | |||
678 | write_lock_irq(&hp_sdc.hook_lock); | 730 | write_lock_irq(&hp_sdc.hook_lock); |
679 | if ((callback != hp_sdc.timer) || | 731 | if ((callback != hp_sdc.timer) || |
680 | (hp_sdc.timer == NULL)) { | 732 | (hp_sdc.timer == NULL)) { |
@@ -694,8 +746,8 @@ int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback) { | |||
694 | return 0; | 746 | return 0; |
695 | } | 747 | } |
696 | 748 | ||
697 | int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback) { | 749 | int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback) |
698 | 750 | { | |
699 | write_lock_irq(&hp_sdc.hook_lock); | 751 | write_lock_irq(&hp_sdc.hook_lock); |
700 | if ((callback != hp_sdc.hil) || | 752 | if ((callback != hp_sdc.hil) || |
701 | (hp_sdc.hil == NULL)) { | 753 | (hp_sdc.hil == NULL)) { |
@@ -715,8 +767,8 @@ int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback) { | |||
715 | return 0; | 767 | return 0; |
716 | } | 768 | } |
717 | 769 | ||
718 | int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback) { | 770 | int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback) |
719 | 771 | { | |
720 | write_lock_irq(&hp_sdc.hook_lock); | 772 | write_lock_irq(&hp_sdc.hook_lock); |
721 | if ((callback != hp_sdc.cooked) || | 773 | if ((callback != hp_sdc.cooked) || |
722 | (hp_sdc.cooked == NULL)) { | 774 | (hp_sdc.cooked == NULL)) { |
@@ -738,7 +790,8 @@ int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback) { | |||
738 | 790 | ||
739 | /************************* Keepalive timer task *********************/ | 791 | /************************* Keepalive timer task *********************/ |
740 | 792 | ||
741 | void hp_sdc_kicker (unsigned long data) { | 793 | void hp_sdc_kicker (unsigned long data) |
794 | { | ||
742 | tasklet_schedule(&hp_sdc.task); | 795 | tasklet_schedule(&hp_sdc.task); |
743 | /* Re-insert the periodic task. */ | 796 | /* Re-insert the periodic task. */ |
744 | mod_timer(&hp_sdc.kicker, jiffies + HZ); | 797 | mod_timer(&hp_sdc.kicker, jiffies + HZ); |
@@ -748,12 +801,12 @@ void hp_sdc_kicker (unsigned long data) { | |||
748 | 801 | ||
749 | #if defined(__hppa__) | 802 | #if defined(__hppa__) |
750 | 803 | ||
751 | static struct parisc_device_id hp_sdc_tbl[] = { | 804 | static const struct parisc_device_id hp_sdc_tbl[] = { |
752 | { | 805 | { |
753 | .hw_type = HPHW_FIO, | 806 | .hw_type = HPHW_FIO, |
754 | .hversion_rev = HVERSION_REV_ANY_ID, | 807 | .hversion_rev = HVERSION_REV_ANY_ID, |
755 | .hversion = HVERSION_ANY_ID, | 808 | .hversion = HVERSION_ANY_ID, |
756 | .sversion = 0x73, | 809 | .sversion = 0x73, |
757 | }, | 810 | }, |
758 | { 0, } | 811 | { 0, } |
759 | }; | 812 | }; |
@@ -772,16 +825,15 @@ static struct parisc_driver hp_sdc_driver = { | |||
772 | 825 | ||
773 | static int __init hp_sdc_init(void) | 826 | static int __init hp_sdc_init(void) |
774 | { | 827 | { |
775 | int i; | ||
776 | char *errstr; | 828 | char *errstr; |
777 | hp_sdc_transaction t_sync; | 829 | hp_sdc_transaction t_sync; |
778 | uint8_t ts_sync[6]; | 830 | uint8_t ts_sync[6]; |
779 | struct semaphore s_sync; | 831 | struct semaphore s_sync; |
780 | 832 | ||
781 | rwlock_init(&hp_sdc.lock); | 833 | rwlock_init(&hp_sdc.lock); |
782 | rwlock_init(&hp_sdc.ibf_lock); | 834 | rwlock_init(&hp_sdc.ibf_lock); |
783 | rwlock_init(&hp_sdc.rtq_lock); | 835 | rwlock_init(&hp_sdc.rtq_lock); |
784 | rwlock_init(&hp_sdc.hook_lock); | 836 | rwlock_init(&hp_sdc.hook_lock); |
785 | 837 | ||
786 | hp_sdc.timer = NULL; | 838 | hp_sdc.timer = NULL; |
787 | hp_sdc.hil = NULL; | 839 | hp_sdc.hil = NULL; |
@@ -796,7 +848,8 @@ static int __init hp_sdc_init(void) | |||
796 | hp_sdc.r7[3] = 0xff; | 848 | hp_sdc.r7[3] = 0xff; |
797 | hp_sdc.ibf = 1; | 849 | hp_sdc.ibf = 1; |
798 | 850 | ||
799 | for (i = 0; i < HP_SDC_QUEUE_LEN; i++) hp_sdc.tq[i] = NULL; | 851 | memset(&hp_sdc.tq, 0, sizeof(hp_sdc.tq)); |
852 | |||
800 | hp_sdc.wcurr = -1; | 853 | hp_sdc.wcurr = -1; |
801 | hp_sdc.rcurr = -1; | 854 | hp_sdc.rcurr = -1; |
802 | hp_sdc.rqty = 0; | 855 | hp_sdc.rqty = 0; |
@@ -804,27 +857,32 @@ static int __init hp_sdc_init(void) | |||
804 | hp_sdc.dev_err = -ENODEV; | 857 | hp_sdc.dev_err = -ENODEV; |
805 | 858 | ||
806 | errstr = "IO not found for"; | 859 | errstr = "IO not found for"; |
807 | if (!hp_sdc.base_io) goto err0; | 860 | if (!hp_sdc.base_io) |
861 | goto err0; | ||
808 | 862 | ||
809 | errstr = "IRQ not found for"; | 863 | errstr = "IRQ not found for"; |
810 | if (!hp_sdc.irq) goto err0; | 864 | if (!hp_sdc.irq) |
865 | goto err0; | ||
811 | 866 | ||
812 | hp_sdc.dev_err = -EBUSY; | 867 | hp_sdc.dev_err = -EBUSY; |
813 | 868 | ||
814 | #if defined(__hppa__) | 869 | #if defined(__hppa__) |
815 | errstr = "IO not available for"; | 870 | errstr = "IO not available for"; |
816 | if (request_region(hp_sdc.data_io, 2, hp_sdc_driver.name)) goto err0; | 871 | if (request_region(hp_sdc.data_io, 2, hp_sdc_driver.name)) |
817 | #endif | 872 | goto err0; |
873 | #endif | ||
818 | 874 | ||
819 | errstr = "IRQ not available for"; | 875 | errstr = "IRQ not available for"; |
820 | if(request_irq(hp_sdc.irq, &hp_sdc_isr, 0, "HP SDC", | 876 | if (request_irq(hp_sdc.irq, &hp_sdc_isr, IRQF_SHARED|IRQF_SAMPLE_RANDOM, |
821 | (void *) hp_sdc.base_io)) goto err1; | 877 | "HP SDC", &hp_sdc)) |
878 | goto err1; | ||
822 | 879 | ||
823 | errstr = "NMI not available for"; | 880 | errstr = "NMI not available for"; |
824 | if (request_irq(hp_sdc.nmi, &hp_sdc_nmisr, 0, "HP SDC NMI", | 881 | if (request_irq(hp_sdc.nmi, &hp_sdc_nmisr, IRQF_SHARED, |
825 | (void *) hp_sdc.base_io)) goto err2; | 882 | "HP SDC NMI", &hp_sdc)) |
883 | goto err2; | ||
826 | 884 | ||
827 | printk(KERN_INFO PREFIX "HP SDC at 0x%p, IRQ %d (NMI IRQ %d)\n", | 885 | printk(KERN_INFO PREFIX "HP SDC at 0x%p, IRQ %d (NMI IRQ %d)\n", |
828 | (void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi); | 886 | (void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi); |
829 | 887 | ||
830 | hp_sdc_status_in8(); | 888 | hp_sdc_status_in8(); |
@@ -854,13 +912,14 @@ static int __init hp_sdc_init(void) | |||
854 | hp_sdc.dev_err = 0; | 912 | hp_sdc.dev_err = 0; |
855 | return 0; | 913 | return 0; |
856 | err2: | 914 | err2: |
857 | free_irq(hp_sdc.irq, NULL); | 915 | free_irq(hp_sdc.irq, &hp_sdc); |
858 | err1: | 916 | err1: |
859 | release_region(hp_sdc.data_io, 2); | 917 | release_region(hp_sdc.data_io, 2); |
860 | err0: | 918 | err0: |
861 | printk(KERN_WARNING PREFIX ": %s SDC IO=0x%p IRQ=0x%x NMI=0x%x\n", | 919 | printk(KERN_WARNING PREFIX ": %s SDC IO=0x%p IRQ=0x%x NMI=0x%x\n", |
862 | errstr, (void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi); | 920 | errstr, (void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi); |
863 | hp_sdc.dev = NULL; | 921 | hp_sdc.dev = NULL; |
922 | |||
864 | return hp_sdc.dev_err; | 923 | return hp_sdc.dev_err; |
865 | } | 924 | } |
866 | 925 | ||
@@ -868,8 +927,10 @@ static int __init hp_sdc_init(void) | |||
868 | 927 | ||
869 | static int __init hp_sdc_init_hppa(struct parisc_device *d) | 928 | static int __init hp_sdc_init_hppa(struct parisc_device *d) |
870 | { | 929 | { |
871 | if (!d) return 1; | 930 | if (!d) |
872 | if (hp_sdc.dev != NULL) return 1; /* We only expect one SDC */ | 931 | return 1; |
932 | if (hp_sdc.dev != NULL) | ||
933 | return 1; /* We only expect one SDC */ | ||
873 | 934 | ||
874 | hp_sdc.dev = d; | 935 | hp_sdc.dev = d; |
875 | hp_sdc.irq = d->irq; | 936 | hp_sdc.irq = d->irq; |
@@ -898,18 +959,16 @@ static void hp_sdc_exit(void) | |||
898 | /* Wait until we know this has been processed by the i8042 */ | 959 | /* Wait until we know this has been processed by the i8042 */ |
899 | hp_sdc_spin_ibf(); | 960 | hp_sdc_spin_ibf(); |
900 | 961 | ||
901 | free_irq(hp_sdc.nmi, NULL); | 962 | free_irq(hp_sdc.nmi, &hp_sdc); |
902 | free_irq(hp_sdc.irq, NULL); | 963 | free_irq(hp_sdc.irq, &hp_sdc); |
903 | write_unlock_irq(&hp_sdc.lock); | 964 | write_unlock_irq(&hp_sdc.lock); |
904 | 965 | ||
905 | del_timer(&hp_sdc.kicker); | 966 | del_timer(&hp_sdc.kicker); |
906 | 967 | ||
907 | tasklet_kill(&hp_sdc.task); | 968 | tasklet_kill(&hp_sdc.task); |
908 | 969 | ||
909 | /* release_region(hp_sdc.data_io, 2); */ | ||
910 | |||
911 | #if defined(__hppa__) | 970 | #if defined(__hppa__) |
912 | if (unregister_parisc_driver(&hp_sdc_driver)) | 971 | if (unregister_parisc_driver(&hp_sdc_driver)) |
913 | printk(KERN_WARNING PREFIX "Error unregistering HP SDC"); | 972 | printk(KERN_WARNING PREFIX "Error unregistering HP SDC"); |
914 | #endif | 973 | #endif |
915 | } | 974 | } |
@@ -923,7 +982,7 @@ static int __init hp_sdc_register(void) | |||
923 | mm_segment_t fs; | 982 | mm_segment_t fs; |
924 | unsigned char i; | 983 | unsigned char i; |
925 | #endif | 984 | #endif |
926 | 985 | ||
927 | hp_sdc.dev = NULL; | 986 | hp_sdc.dev = NULL; |
928 | hp_sdc.dev_err = 0; | 987 | hp_sdc.dev_err = 0; |
929 | #if defined(__hppa__) | 988 | #if defined(__hppa__) |
@@ -960,8 +1019,8 @@ static int __init hp_sdc_register(void) | |||
960 | tq_init.seq = tq_init_seq; | 1019 | tq_init.seq = tq_init_seq; |
961 | tq_init.act.semaphore = &tq_init_sem; | 1020 | tq_init.act.semaphore = &tq_init_sem; |
962 | 1021 | ||
963 | tq_init_seq[0] = | 1022 | tq_init_seq[0] = |
964 | HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN | HP_SDC_ACT_SEMAPHORE; | 1023 | HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN | HP_SDC_ACT_SEMAPHORE; |
965 | tq_init_seq[1] = HP_SDC_CMD_READ_KCC; | 1024 | tq_init_seq[1] = HP_SDC_CMD_READ_KCC; |
966 | tq_init_seq[2] = 1; | 1025 | tq_init_seq[2] = 1; |
967 | tq_init_seq[3] = 0; | 1026 | tq_init_seq[3] = 0; |
@@ -979,13 +1038,13 @@ static int __init hp_sdc_register(void) | |||
979 | } | 1038 | } |
980 | hp_sdc.r11 = tq_init_seq[4]; | 1039 | hp_sdc.r11 = tq_init_seq[4]; |
981 | if (hp_sdc.r11 & HP_SDC_CFG_NEW) { | 1040 | if (hp_sdc.r11 & HP_SDC_CFG_NEW) { |
982 | char *str; | 1041 | const char *str; |
983 | printk(KERN_INFO PREFIX "New style SDC\n"); | 1042 | printk(KERN_INFO PREFIX "New style SDC\n"); |
984 | tq_init_seq[1] = HP_SDC_CMD_READ_XTD; | 1043 | tq_init_seq[1] = HP_SDC_CMD_READ_XTD; |
985 | tq_init.actidx = 0; | 1044 | tq_init.actidx = 0; |
986 | tq_init.idx = 1; | 1045 | tq_init.idx = 1; |
987 | down(&tq_init_sem); | 1046 | down(&tq_init_sem); |
988 | hp_sdc_enqueue_transaction(&tq_init); | 1047 | hp_sdc_enqueue_transaction(&tq_init); |
989 | down(&tq_init_sem); | 1048 | down(&tq_init_sem); |
990 | up(&tq_init_sem); | 1049 | up(&tq_init_sem); |
991 | if ((tq_init_seq[0] & HP_SDC_ACT_DEAD) == HP_SDC_ACT_DEAD) { | 1050 | if ((tq_init_seq[0] & HP_SDC_ACT_DEAD) == HP_SDC_ACT_DEAD) { |
@@ -995,15 +1054,13 @@ static int __init hp_sdc_register(void) | |||
995 | hp_sdc.r7e = tq_init_seq[4]; | 1054 | hp_sdc.r7e = tq_init_seq[4]; |
996 | HP_SDC_XTD_REV_STRINGS(hp_sdc.r7e & HP_SDC_XTD_REV, str) | 1055 | HP_SDC_XTD_REV_STRINGS(hp_sdc.r7e & HP_SDC_XTD_REV, str) |
997 | printk(KERN_INFO PREFIX "Revision: %s\n", str); | 1056 | printk(KERN_INFO PREFIX "Revision: %s\n", str); |
998 | if (hp_sdc.r7e & HP_SDC_XTD_BEEPER) { | 1057 | if (hp_sdc.r7e & HP_SDC_XTD_BEEPER) |
999 | printk(KERN_INFO PREFIX "TI SN76494 beeper present\n"); | 1058 | printk(KERN_INFO PREFIX "TI SN76494 beeper present\n"); |
1000 | } | 1059 | if (hp_sdc.r7e & HP_SDC_XTD_BBRTC) |
1001 | if (hp_sdc.r7e & HP_SDC_XTD_BBRTC) { | ||
1002 | printk(KERN_INFO PREFIX "OKI MSM-58321 BBRTC present\n"); | 1060 | printk(KERN_INFO PREFIX "OKI MSM-58321 BBRTC present\n"); |
1003 | } | ||
1004 | printk(KERN_INFO PREFIX "Spunking the self test register to force PUP " | 1061 | printk(KERN_INFO PREFIX "Spunking the self test register to force PUP " |
1005 | "on next firmware reset.\n"); | 1062 | "on next firmware reset.\n"); |
1006 | tq_init_seq[0] = HP_SDC_ACT_PRECMD | | 1063 | tq_init_seq[0] = HP_SDC_ACT_PRECMD | |
1007 | HP_SDC_ACT_DATAOUT | HP_SDC_ACT_SEMAPHORE; | 1064 | HP_SDC_ACT_DATAOUT | HP_SDC_ACT_SEMAPHORE; |
1008 | tq_init_seq[1] = HP_SDC_CMD_SET_STR; | 1065 | tq_init_seq[1] = HP_SDC_CMD_SET_STR; |
1009 | tq_init_seq[2] = 1; | 1066 | tq_init_seq[2] = 1; |
@@ -1012,14 +1069,12 @@ static int __init hp_sdc_register(void) | |||
1012 | tq_init.idx = 1; | 1069 | tq_init.idx = 1; |
1013 | tq_init.endidx = 4; | 1070 | tq_init.endidx = 4; |
1014 | down(&tq_init_sem); | 1071 | down(&tq_init_sem); |
1015 | hp_sdc_enqueue_transaction(&tq_init); | 1072 | hp_sdc_enqueue_transaction(&tq_init); |
1016 | down(&tq_init_sem); | 1073 | down(&tq_init_sem); |
1017 | up(&tq_init_sem); | 1074 | up(&tq_init_sem); |
1018 | } | 1075 | } else |
1019 | else { | 1076 | printk(KERN_INFO PREFIX "Old style SDC (1820-%s).\n", |
1020 | printk(KERN_INFO PREFIX "Old style SDC (1820-%s).\n", | ||
1021 | (hp_sdc.r11 & HP_SDC_CFG_REV) ? "3300" : "2564/3087"); | 1077 | (hp_sdc.r11 & HP_SDC_CFG_REV) ? "3300" : "2564/3087"); |
1022 | } | ||
1023 | 1078 | ||
1024 | return 0; | 1079 | return 0; |
1025 | } | 1080 | } |
@@ -1027,13 +1082,13 @@ static int __init hp_sdc_register(void) | |||
1027 | module_init(hp_sdc_register); | 1082 | module_init(hp_sdc_register); |
1028 | module_exit(hp_sdc_exit); | 1083 | module_exit(hp_sdc_exit); |
1029 | 1084 | ||
1030 | /* Timing notes: These measurements taken on my 64MHz 7100-LC (715/64) | 1085 | /* Timing notes: These measurements taken on my 64MHz 7100-LC (715/64) |
1031 | * cycles cycles-adj time | 1086 | * cycles cycles-adj time |
1032 | * between two consecutive mfctl(16)'s: 4 n/a 63ns | 1087 | * between two consecutive mfctl(16)'s: 4 n/a 63ns |
1033 | * hp_sdc_spin_ibf when idle: 119 115 1.7us | 1088 | * hp_sdc_spin_ibf when idle: 119 115 1.7us |
1034 | * gsc_writeb status register: 83 79 1.2us | 1089 | * gsc_writeb status register: 83 79 1.2us |
1035 | * IBF to clear after sending SET_IM: 6204 6006 93us | 1090 | * IBF to clear after sending SET_IM: 6204 6006 93us |
1036 | * IBF to clear after sending LOAD_RT: 4467 4352 68us | 1091 | * IBF to clear after sending LOAD_RT: 4467 4352 68us |
1037 | * IBF to clear after sending two LOAD_RTs: 18974 18859 295us | 1092 | * IBF to clear after sending two LOAD_RTs: 18974 18859 295us |
1038 | * READ_T1, read status/data, IRQ, call handler: 35564 n/a 556us | 1093 | * READ_T1, read status/data, IRQ, call handler: 35564 n/a 556us |
1039 | * cmd to ~IBF READ_T1 2nd time right after: 5158403 n/a 81ms | 1094 | * cmd to ~IBF READ_T1 2nd time right after: 5158403 n/a 81ms |
diff --git a/drivers/input/serio/hp_sdc_mlc.c b/drivers/input/serio/hp_sdc_mlc.c index aa4a8a4ccfdb..c45ea74d53e4 100644 --- a/drivers/input/serio/hp_sdc_mlc.c +++ b/drivers/input/serio/hp_sdc_mlc.c | |||
@@ -58,12 +58,13 @@ struct hp_sdc_mlc_priv_s { | |||
58 | } hp_sdc_mlc_priv; | 58 | } hp_sdc_mlc_priv; |
59 | 59 | ||
60 | /************************* Interrupt context ******************************/ | 60 | /************************* Interrupt context ******************************/ |
61 | static void hp_sdc_mlc_isr (int irq, void *dev_id, | 61 | static void hp_sdc_mlc_isr (int irq, void *dev_id, |
62 | uint8_t status, uint8_t data) { | 62 | uint8_t status, uint8_t data) |
63 | int idx; | 63 | { |
64 | int idx; | ||
64 | hil_mlc *mlc = &hp_sdc_mlc; | 65 | hil_mlc *mlc = &hp_sdc_mlc; |
65 | 66 | ||
66 | write_lock(&(mlc->lock)); | 67 | write_lock(&mlc->lock); |
67 | if (mlc->icount < 0) { | 68 | if (mlc->icount < 0) { |
68 | printk(KERN_WARNING PREFIX "HIL Overflow!\n"); | 69 | printk(KERN_WARNING PREFIX "HIL Overflow!\n"); |
69 | up(&mlc->isem); | 70 | up(&mlc->isem); |
@@ -73,239 +74,232 @@ static void hp_sdc_mlc_isr (int irq, void *dev_id, | |||
73 | if ((status & HP_SDC_STATUS_IRQMASK) == HP_SDC_STATUS_HILDATA) { | 74 | if ((status & HP_SDC_STATUS_IRQMASK) == HP_SDC_STATUS_HILDATA) { |
74 | mlc->ipacket[idx] |= data | HIL_ERR_INT; | 75 | mlc->ipacket[idx] |= data | HIL_ERR_INT; |
75 | mlc->icount--; | 76 | mlc->icount--; |
76 | if (hp_sdc_mlc_priv.got5x) goto check; | 77 | if (hp_sdc_mlc_priv.got5x || !idx) |
77 | if (!idx) goto check; | 78 | goto check; |
78 | if ((mlc->ipacket[idx-1] & HIL_PKT_ADDR_MASK) != | 79 | if ((mlc->ipacket[idx - 1] & HIL_PKT_ADDR_MASK) != |
79 | (mlc->ipacket[idx] & HIL_PKT_ADDR_MASK)) { | 80 | (mlc->ipacket[idx] & HIL_PKT_ADDR_MASK)) { |
80 | mlc->ipacket[idx] &= ~HIL_PKT_ADDR_MASK; | 81 | mlc->ipacket[idx] &= ~HIL_PKT_ADDR_MASK; |
81 | mlc->ipacket[idx] |= (mlc->ipacket[idx-1] | 82 | mlc->ipacket[idx] |= (mlc->ipacket[idx - 1] |
82 | & HIL_PKT_ADDR_MASK); | 83 | & HIL_PKT_ADDR_MASK); |
83 | } | 84 | } |
84 | goto check; | 85 | goto check; |
85 | } | 86 | } |
86 | /* We know status is 5X */ | 87 | /* We know status is 5X */ |
87 | if (data & HP_SDC_HIL_ISERR) goto err; | 88 | if (data & HP_SDC_HIL_ISERR) |
88 | mlc->ipacket[idx] = | 89 | goto err; |
90 | mlc->ipacket[idx] = | ||
89 | (data & HP_SDC_HIL_R1MASK) << HIL_PKT_ADDR_SHIFT; | 91 | (data & HP_SDC_HIL_R1MASK) << HIL_PKT_ADDR_SHIFT; |
90 | hp_sdc_mlc_priv.got5x = 1; | 92 | hp_sdc_mlc_priv.got5x = 1; |
91 | goto out; | 93 | goto out; |
92 | 94 | ||
93 | check: | 95 | check: |
94 | hp_sdc_mlc_priv.got5x = 0; | 96 | hp_sdc_mlc_priv.got5x = 0; |
95 | if (mlc->imatch == 0) goto done; | 97 | if (mlc->imatch == 0) |
96 | if ((mlc->imatch == (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) | 98 | goto done; |
97 | && (mlc->ipacket[idx] == (mlc->imatch | idx))) goto done; | 99 | if ((mlc->imatch == (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) |
98 | if (mlc->ipacket[idx] == mlc->imatch) goto done; | 100 | && (mlc->ipacket[idx] == (mlc->imatch | idx))) |
101 | goto done; | ||
102 | if (mlc->ipacket[idx] == mlc->imatch) | ||
103 | goto done; | ||
99 | goto out; | 104 | goto out; |
100 | 105 | ||
101 | err: | 106 | err: |
102 | printk(KERN_DEBUG PREFIX "err code %x\n", data); | 107 | printk(KERN_DEBUG PREFIX "err code %x\n", data); |
108 | |||
103 | switch (data) { | 109 | switch (data) { |
104 | case HP_SDC_HIL_RC_DONE: | 110 | case HP_SDC_HIL_RC_DONE: |
105 | printk(KERN_WARNING PREFIX "Bastard SDC reconfigured loop!\n"); | 111 | printk(KERN_WARNING PREFIX "Bastard SDC reconfigured loop!\n"); |
106 | break; | 112 | break; |
113 | |||
107 | case HP_SDC_HIL_ERR: | 114 | case HP_SDC_HIL_ERR: |
108 | mlc->ipacket[idx] |= HIL_ERR_INT | HIL_ERR_PERR | | 115 | mlc->ipacket[idx] |= HIL_ERR_INT | HIL_ERR_PERR | |
109 | HIL_ERR_FERR | HIL_ERR_FOF; | 116 | HIL_ERR_FERR | HIL_ERR_FOF; |
110 | break; | 117 | break; |
118 | |||
111 | case HP_SDC_HIL_TO: | 119 | case HP_SDC_HIL_TO: |
112 | mlc->ipacket[idx] |= HIL_ERR_INT | HIL_ERR_LERR; | 120 | mlc->ipacket[idx] |= HIL_ERR_INT | HIL_ERR_LERR; |
113 | break; | 121 | break; |
122 | |||
114 | case HP_SDC_HIL_RC: | 123 | case HP_SDC_HIL_RC: |
115 | printk(KERN_WARNING PREFIX "Bastard SDC decided to reconfigure loop!\n"); | 124 | printk(KERN_WARNING PREFIX "Bastard SDC decided to reconfigure loop!\n"); |
116 | break; | 125 | break; |
126 | |||
117 | default: | 127 | default: |
118 | printk(KERN_WARNING PREFIX "Unkown HIL Error status (%x)!\n", data); | 128 | printk(KERN_WARNING PREFIX "Unkown HIL Error status (%x)!\n", data); |
119 | break; | 129 | break; |
120 | } | 130 | } |
131 | |||
121 | /* No more data will be coming due to an error. */ | 132 | /* No more data will be coming due to an error. */ |
122 | done: | 133 | done: |
123 | tasklet_schedule(mlc->tasklet); | 134 | tasklet_schedule(mlc->tasklet); |
124 | up(&(mlc->isem)); | 135 | up(&mlc->isem); |
125 | out: | 136 | out: |
126 | write_unlock(&(mlc->lock)); | 137 | write_unlock(&mlc->lock); |
127 | } | 138 | } |
128 | 139 | ||
129 | 140 | ||
130 | /******************** Tasklet or userspace context functions ****************/ | 141 | /******************** Tasklet or userspace context functions ****************/ |
131 | 142 | ||
132 | static int hp_sdc_mlc_in (hil_mlc *mlc, suseconds_t timeout) { | 143 | static int hp_sdc_mlc_in(hil_mlc *mlc, suseconds_t timeout) |
133 | unsigned long flags; | 144 | { |
134 | struct hp_sdc_mlc_priv_s *priv; | 145 | struct hp_sdc_mlc_priv_s *priv; |
135 | int rc = 2; | 146 | int rc = 2; |
136 | 147 | ||
137 | priv = mlc->priv; | 148 | priv = mlc->priv; |
138 | 149 | ||
139 | write_lock_irqsave(&(mlc->lock), flags); | ||
140 | |||
141 | /* Try to down the semaphore */ | 150 | /* Try to down the semaphore */ |
142 | if (down_trylock(&(mlc->isem))) { | 151 | if (down_trylock(&mlc->isem)) { |
143 | struct timeval tv; | 152 | struct timeval tv; |
144 | if (priv->emtestmode) { | 153 | if (priv->emtestmode) { |
145 | mlc->ipacket[0] = | 154 | mlc->ipacket[0] = |
146 | HIL_ERR_INT | (mlc->opacket & | 155 | HIL_ERR_INT | (mlc->opacket & |
147 | (HIL_PKT_CMD | | 156 | (HIL_PKT_CMD | |
148 | HIL_PKT_ADDR_MASK | | 157 | HIL_PKT_ADDR_MASK | |
149 | HIL_PKT_DATA_MASK)); | 158 | HIL_PKT_DATA_MASK)); |
150 | mlc->icount = 14; | 159 | mlc->icount = 14; |
151 | /* printk(KERN_DEBUG PREFIX ">[%x]\n", mlc->ipacket[0]); */ | 160 | /* printk(KERN_DEBUG PREFIX ">[%x]\n", mlc->ipacket[0]); */ |
152 | goto wasup; | 161 | goto wasup; |
153 | } | 162 | } |
154 | do_gettimeofday(&tv); | 163 | do_gettimeofday(&tv); |
155 | tv.tv_usec += 1000000 * (tv.tv_sec - mlc->instart.tv_sec); | 164 | tv.tv_usec += USEC_PER_SEC * (tv.tv_sec - mlc->instart.tv_sec); |
156 | if (tv.tv_usec - mlc->instart.tv_usec > mlc->intimeout) { | 165 | if (tv.tv_usec - mlc->instart.tv_usec > mlc->intimeout) { |
157 | /* printk("!%i %i", | 166 | /* printk("!%i %i", |
158 | tv.tv_usec - mlc->instart.tv_usec, | 167 | tv.tv_usec - mlc->instart.tv_usec, |
159 | mlc->intimeout); | 168 | mlc->intimeout); |
160 | */ | 169 | */ |
161 | rc = 1; | 170 | rc = 1; |
162 | up(&(mlc->isem)); | 171 | up(&mlc->isem); |
163 | } | 172 | } |
164 | goto done; | 173 | goto done; |
165 | } | 174 | } |
166 | wasup: | 175 | wasup: |
167 | up(&(mlc->isem)); | 176 | up(&mlc->isem); |
168 | rc = 0; | 177 | rc = 0; |
169 | goto done; | ||
170 | done: | 178 | done: |
171 | write_unlock_irqrestore(&(mlc->lock), flags); | ||
172 | return rc; | 179 | return rc; |
173 | } | 180 | } |
174 | 181 | ||
175 | static int hp_sdc_mlc_cts (hil_mlc *mlc) { | 182 | static int hp_sdc_mlc_cts(hil_mlc *mlc) |
183 | { | ||
176 | struct hp_sdc_mlc_priv_s *priv; | 184 | struct hp_sdc_mlc_priv_s *priv; |
177 | unsigned long flags; | ||
178 | 185 | ||
179 | priv = mlc->priv; | 186 | priv = mlc->priv; |
180 | |||
181 | write_lock_irqsave(&(mlc->lock), flags); | ||
182 | 187 | ||
183 | /* Try to down the semaphores -- they should be up. */ | 188 | /* Try to down the semaphores -- they should be up. */ |
184 | if (down_trylock(&(mlc->isem))) { | 189 | BUG_ON(down_trylock(&mlc->isem)); |
185 | BUG(); | 190 | BUG_ON(down_trylock(&mlc->osem)); |
186 | goto busy; | 191 | |
187 | } | 192 | up(&mlc->isem); |
188 | if (down_trylock(&(mlc->osem))) { | 193 | up(&mlc->osem); |
189 | BUG(); | ||
190 | up(&(mlc->isem)); | ||
191 | goto busy; | ||
192 | } | ||
193 | up(&(mlc->isem)); | ||
194 | up(&(mlc->osem)); | ||
195 | 194 | ||
196 | if (down_trylock(&(mlc->csem))) { | 195 | if (down_trylock(&mlc->csem)) { |
197 | if (priv->trans.act.semaphore != &(mlc->csem)) goto poll; | 196 | if (priv->trans.act.semaphore != &mlc->csem) |
198 | goto busy; | 197 | goto poll; |
198 | else | ||
199 | goto busy; | ||
199 | } | 200 | } |
200 | if (!(priv->tseq[4] & HP_SDC_USE_LOOP)) goto done; | 201 | |
202 | if (!(priv->tseq[4] & HP_SDC_USE_LOOP)) | ||
203 | goto done; | ||
201 | 204 | ||
202 | poll: | 205 | poll: |
203 | priv->trans.act.semaphore = &(mlc->csem); | 206 | priv->trans.act.semaphore = &mlc->csem; |
204 | priv->trans.actidx = 0; | 207 | priv->trans.actidx = 0; |
205 | priv->trans.idx = 1; | 208 | priv->trans.idx = 1; |
206 | priv->trans.endidx = 5; | 209 | priv->trans.endidx = 5; |
207 | priv->tseq[0] = | 210 | priv->tseq[0] = |
208 | HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN | HP_SDC_ACT_SEMAPHORE; | 211 | HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN | HP_SDC_ACT_SEMAPHORE; |
209 | priv->tseq[1] = HP_SDC_CMD_READ_USE; | 212 | priv->tseq[1] = HP_SDC_CMD_READ_USE; |
210 | priv->tseq[2] = 1; | 213 | priv->tseq[2] = 1; |
211 | priv->tseq[3] = 0; | 214 | priv->tseq[3] = 0; |
212 | priv->tseq[4] = 0; | 215 | priv->tseq[4] = 0; |
213 | hp_sdc_enqueue_transaction(&(priv->trans)); | 216 | __hp_sdc_enqueue_transaction(&priv->trans); |
214 | busy: | 217 | busy: |
215 | write_unlock_irqrestore(&(mlc->lock), flags); | ||
216 | return 1; | 218 | return 1; |
217 | done: | 219 | done: |
218 | priv->trans.act.semaphore = &(mlc->osem); | 220 | priv->trans.act.semaphore = &mlc->osem; |
219 | up(&(mlc->csem)); | 221 | up(&mlc->csem); |
220 | write_unlock_irqrestore(&(mlc->lock), flags); | ||
221 | return 0; | 222 | return 0; |
222 | } | 223 | } |
223 | 224 | ||
224 | static void hp_sdc_mlc_out (hil_mlc *mlc) { | 225 | static void hp_sdc_mlc_out(hil_mlc *mlc) |
226 | { | ||
225 | struct hp_sdc_mlc_priv_s *priv; | 227 | struct hp_sdc_mlc_priv_s *priv; |
226 | unsigned long flags; | ||
227 | 228 | ||
228 | priv = mlc->priv; | 229 | priv = mlc->priv; |
229 | 230 | ||
230 | write_lock_irqsave(&(mlc->lock), flags); | ||
231 | |||
232 | /* Try to down the semaphore -- it should be up. */ | 231 | /* Try to down the semaphore -- it should be up. */ |
233 | if (down_trylock(&(mlc->osem))) { | 232 | BUG_ON(down_trylock(&mlc->osem)); |
234 | BUG(); | ||
235 | goto done; | ||
236 | } | ||
237 | 233 | ||
238 | if (mlc->opacket & HIL_DO_ALTER_CTRL) goto do_control; | 234 | if (mlc->opacket & HIL_DO_ALTER_CTRL) |
235 | goto do_control; | ||
239 | 236 | ||
240 | do_data: | 237 | do_data: |
241 | if (priv->emtestmode) { | 238 | if (priv->emtestmode) { |
242 | up(&(mlc->osem)); | 239 | up(&mlc->osem); |
243 | goto done; | 240 | return; |
244 | } | 241 | } |
245 | /* Shouldn't be sending commands when loop may be busy */ | 242 | /* Shouldn't be sending commands when loop may be busy */ |
246 | if (down_trylock(&(mlc->csem))) { | 243 | BUG_ON(down_trylock(&mlc->csem)); |
247 | BUG(); | 244 | up(&mlc->csem); |
248 | goto done; | ||
249 | } | ||
250 | up(&(mlc->csem)); | ||
251 | 245 | ||
252 | priv->trans.actidx = 0; | 246 | priv->trans.actidx = 0; |
253 | priv->trans.idx = 1; | 247 | priv->trans.idx = 1; |
254 | priv->trans.act.semaphore = &(mlc->osem); | 248 | priv->trans.act.semaphore = &mlc->osem; |
255 | priv->trans.endidx = 6; | 249 | priv->trans.endidx = 6; |
256 | priv->tseq[0] = | 250 | priv->tseq[0] = |
257 | HP_SDC_ACT_DATAREG | HP_SDC_ACT_POSTCMD | HP_SDC_ACT_SEMAPHORE; | 251 | HP_SDC_ACT_DATAREG | HP_SDC_ACT_POSTCMD | HP_SDC_ACT_SEMAPHORE; |
258 | priv->tseq[1] = 0x7; | 252 | priv->tseq[1] = 0x7; |
259 | priv->tseq[2] = | 253 | priv->tseq[2] = |
260 | (mlc->opacket & | 254 | (mlc->opacket & |
261 | (HIL_PKT_ADDR_MASK | HIL_PKT_CMD)) | 255 | (HIL_PKT_ADDR_MASK | HIL_PKT_CMD)) |
262 | >> HIL_PKT_ADDR_SHIFT; | 256 | >> HIL_PKT_ADDR_SHIFT; |
263 | priv->tseq[3] = | 257 | priv->tseq[3] = |
264 | (mlc->opacket & HIL_PKT_DATA_MASK) | 258 | (mlc->opacket & HIL_PKT_DATA_MASK) |
265 | >> HIL_PKT_DATA_SHIFT; | 259 | >> HIL_PKT_DATA_SHIFT; |
266 | priv->tseq[4] = 0; /* No timeout */ | 260 | priv->tseq[4] = 0; /* No timeout */ |
267 | if (priv->tseq[3] == HIL_CMD_DHR) priv->tseq[4] = 1; | 261 | if (priv->tseq[3] == HIL_CMD_DHR) |
262 | priv->tseq[4] = 1; | ||
268 | priv->tseq[5] = HP_SDC_CMD_DO_HIL; | 263 | priv->tseq[5] = HP_SDC_CMD_DO_HIL; |
269 | goto enqueue; | 264 | goto enqueue; |
270 | 265 | ||
271 | do_control: | 266 | do_control: |
272 | priv->emtestmode = mlc->opacket & HIL_CTRL_TEST; | 267 | priv->emtestmode = mlc->opacket & HIL_CTRL_TEST; |
273 | 268 | ||
274 | /* we cannot emulate this, it should not be used. */ | 269 | /* we cannot emulate this, it should not be used. */ |
275 | BUG_ON((mlc->opacket & (HIL_CTRL_APE | HIL_CTRL_IPF)) == HIL_CTRL_APE); | 270 | BUG_ON((mlc->opacket & (HIL_CTRL_APE | HIL_CTRL_IPF)) == HIL_CTRL_APE); |
276 | 271 | ||
277 | if ((mlc->opacket & HIL_CTRL_ONLY) == HIL_CTRL_ONLY) goto control_only; | 272 | if ((mlc->opacket & HIL_CTRL_ONLY) == HIL_CTRL_ONLY) |
278 | if (mlc->opacket & HIL_CTRL_APE) { | 273 | goto control_only; |
279 | BUG(); /* Should not send command/data after engaging APE */ | 274 | |
280 | goto done; | 275 | /* Should not send command/data after engaging APE */ |
281 | } | 276 | BUG_ON(mlc->opacket & HIL_CTRL_APE); |
282 | /* Disengaging APE this way would not be valid either since | 277 | |
278 | /* Disengaging APE this way would not be valid either since | ||
283 | * the loop must be allowed to idle. | 279 | * the loop must be allowed to idle. |
284 | * | 280 | * |
285 | * So, it works out that we really never actually send control | 281 | * So, it works out that we really never actually send control |
286 | * and data when using SDC, we just send the data. | 282 | * and data when using SDC, we just send the data. |
287 | */ | 283 | */ |
288 | goto do_data; | 284 | goto do_data; |
289 | 285 | ||
290 | control_only: | 286 | control_only: |
291 | priv->trans.actidx = 0; | 287 | priv->trans.actidx = 0; |
292 | priv->trans.idx = 1; | 288 | priv->trans.idx = 1; |
293 | priv->trans.act.semaphore = &(mlc->osem); | 289 | priv->trans.act.semaphore = &mlc->osem; |
294 | priv->trans.endidx = 4; | 290 | priv->trans.endidx = 4; |
295 | priv->tseq[0] = | 291 | priv->tseq[0] = |
296 | HP_SDC_ACT_PRECMD | HP_SDC_ACT_DATAOUT | HP_SDC_ACT_SEMAPHORE; | 292 | HP_SDC_ACT_PRECMD | HP_SDC_ACT_DATAOUT | HP_SDC_ACT_SEMAPHORE; |
297 | priv->tseq[1] = HP_SDC_CMD_SET_LPC; | 293 | priv->tseq[1] = HP_SDC_CMD_SET_LPC; |
298 | priv->tseq[2] = 1; | 294 | priv->tseq[2] = 1; |
299 | // priv->tseq[3] = (mlc->ddc + 1) | HP_SDC_LPS_ACSUCC; | 295 | /* priv->tseq[3] = (mlc->ddc + 1) | HP_SDC_LPS_ACSUCC; */ |
300 | priv->tseq[3] = 0; | 296 | priv->tseq[3] = 0; |
301 | if (mlc->opacket & HIL_CTRL_APE) { | 297 | if (mlc->opacket & HIL_CTRL_APE) { |
302 | priv->tseq[3] |= HP_SDC_LPC_APE_IPF; | 298 | priv->tseq[3] |= HP_SDC_LPC_APE_IPF; |
303 | down_trylock(&(mlc->csem)); | 299 | down_trylock(&mlc->csem); |
304 | } | 300 | } |
305 | enqueue: | 301 | enqueue: |
306 | hp_sdc_enqueue_transaction(&(priv->trans)); | 302 | hp_sdc_enqueue_transaction(&priv->trans); |
307 | done: | ||
308 | write_unlock_irqrestore(&(mlc->lock), flags); | ||
309 | } | 303 | } |
310 | 304 | ||
311 | static int __init hp_sdc_mlc_init(void) | 305 | static int __init hp_sdc_mlc_init(void) |
@@ -316,18 +310,18 @@ static int __init hp_sdc_mlc_init(void) | |||
316 | 310 | ||
317 | hp_sdc_mlc_priv.emtestmode = 0; | 311 | hp_sdc_mlc_priv.emtestmode = 0; |
318 | hp_sdc_mlc_priv.trans.seq = hp_sdc_mlc_priv.tseq; | 312 | hp_sdc_mlc_priv.trans.seq = hp_sdc_mlc_priv.tseq; |
319 | hp_sdc_mlc_priv.trans.act.semaphore = &(mlc->osem); | 313 | hp_sdc_mlc_priv.trans.act.semaphore = &mlc->osem; |
320 | hp_sdc_mlc_priv.got5x = 0; | 314 | hp_sdc_mlc_priv.got5x = 0; |
321 | 315 | ||
322 | mlc->cts = &hp_sdc_mlc_cts; | 316 | mlc->cts = &hp_sdc_mlc_cts; |
323 | mlc->in = &hp_sdc_mlc_in; | 317 | mlc->in = &hp_sdc_mlc_in; |
324 | mlc->out = &hp_sdc_mlc_out; | 318 | mlc->out = &hp_sdc_mlc_out; |
319 | mlc->priv = &hp_sdc_mlc_priv; | ||
325 | 320 | ||
326 | if (hil_mlc_register(mlc)) { | 321 | if (hil_mlc_register(mlc)) { |
327 | printk(KERN_WARNING PREFIX "Failed to register MLC structure with hil_mlc\n"); | 322 | printk(KERN_WARNING PREFIX "Failed to register MLC structure with hil_mlc\n"); |
328 | goto err0; | 323 | goto err0; |
329 | } | 324 | } |
330 | mlc->priv = &hp_sdc_mlc_priv; | ||
331 | 325 | ||
332 | if (hp_sdc_request_hil_irq(&hp_sdc_mlc_isr)) { | 326 | if (hp_sdc_request_hil_irq(&hp_sdc_mlc_isr)) { |
333 | printk(KERN_WARNING PREFIX "Request for raw HIL ISR hook denied\n"); | 327 | printk(KERN_WARNING PREFIX "Request for raw HIL ISR hook denied\n"); |
@@ -335,10 +329,9 @@ static int __init hp_sdc_mlc_init(void) | |||
335 | } | 329 | } |
336 | return 0; | 330 | return 0; |
337 | err1: | 331 | err1: |
338 | if (hil_mlc_unregister(mlc)) { | 332 | if (hil_mlc_unregister(mlc)) |
339 | printk(KERN_ERR PREFIX "Failed to unregister MLC structure with hil_mlc.\n" | 333 | printk(KERN_ERR PREFIX "Failed to unregister MLC structure with hil_mlc.\n" |
340 | "This is bad. Could cause an oops.\n"); | 334 | "This is bad. Could cause an oops.\n"); |
341 | } | ||
342 | err0: | 335 | err0: |
343 | return -EBUSY; | 336 | return -EBUSY; |
344 | } | 337 | } |
@@ -346,14 +339,14 @@ static int __init hp_sdc_mlc_init(void) | |||
346 | static void __exit hp_sdc_mlc_exit(void) | 339 | static void __exit hp_sdc_mlc_exit(void) |
347 | { | 340 | { |
348 | hil_mlc *mlc = &hp_sdc_mlc; | 341 | hil_mlc *mlc = &hp_sdc_mlc; |
349 | if (hp_sdc_release_hil_irq(&hp_sdc_mlc_isr)) { | 342 | |
343 | if (hp_sdc_release_hil_irq(&hp_sdc_mlc_isr)) | ||
350 | printk(KERN_ERR PREFIX "Failed to release the raw HIL ISR hook.\n" | 344 | printk(KERN_ERR PREFIX "Failed to release the raw HIL ISR hook.\n" |
351 | "This is bad. Could cause an oops.\n"); | 345 | "This is bad. Could cause an oops.\n"); |
352 | } | 346 | |
353 | if (hil_mlc_unregister(mlc)) { | 347 | if (hil_mlc_unregister(mlc)) |
354 | printk(KERN_ERR PREFIX "Failed to unregister MLC structure with hil_mlc.\n" | 348 | printk(KERN_ERR PREFIX "Failed to unregister MLC structure with hil_mlc.\n" |
355 | "This is bad. Could cause an oops.\n"); | 349 | "This is bad. Could cause an oops.\n"); |
356 | } | ||
357 | } | 350 | } |
358 | 351 | ||
359 | module_init(hp_sdc_mlc_init); | 352 | module_init(hp_sdc_mlc_init); |
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index d36bd5475b6d..6858bc58f0fd 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -160,6 +160,28 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { | |||
160 | }, | 160 | }, |
161 | }, | 161 | }, |
162 | { | 162 | { |
163 | /* | ||
164 | * No data is coming from the touchscreen unless KBC | ||
165 | * is in legacy mode. | ||
166 | */ | ||
167 | .ident = "Panasonic CF-29", | ||
168 | .matches = { | ||
169 | DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), | ||
170 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"), | ||
171 | }, | ||
172 | }, | ||
173 | { | ||
174 | /* | ||
175 | * Errors on MUX ports are reported without raising AUXDATA | ||
176 | * causing "spurious NAK" messages. | ||
177 | */ | ||
178 | .ident = "HP Pavilion DV4017EA", | ||
179 | .matches = { | ||
180 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
181 | DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)"), | ||
182 | }, | ||
183 | }, | ||
184 | { | ||
163 | .ident = "Toshiba P10", | 185 | .ident = "Toshiba P10", |
164 | .matches = { | 186 | .matches = { |
165 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | 187 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), |
@@ -280,6 +302,8 @@ static struct pnp_driver i8042_pnp_kbd_driver = { | |||
280 | }; | 302 | }; |
281 | 303 | ||
282 | static struct pnp_device_id pnp_aux_devids[] = { | 304 | static struct pnp_device_id pnp_aux_devids[] = { |
305 | { .id = "FJC6000", .driver_data = 0 }, | ||
306 | { .id = "FJC6001", .driver_data = 0 }, | ||
283 | { .id = "PNP0f03", .driver_data = 0 }, | 307 | { .id = "PNP0f03", .driver_data = 0 }, |
284 | { .id = "PNP0f0b", .driver_data = 0 }, | 308 | { .id = "PNP0f0b", .driver_data = 0 }, |
285 | { .id = "PNP0f0e", .driver_data = 0 }, | 309 | { .id = "PNP0f0e", .driver_data = 0 }, |
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index db9cca3b65e0..7c17377a65b9 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -768,6 +768,13 @@ static void i8042_controller_reset(void) | |||
768 | i8042_flush(); | 768 | i8042_flush(); |
769 | 769 | ||
770 | /* | 770 | /* |
771 | * Disable both KBD and AUX interfaces so they don't get in the way | ||
772 | */ | ||
773 | |||
774 | i8042_ctr |= I8042_CTR_KBDDIS | I8042_CTR_AUXDIS; | ||
775 | i8042_ctr &= ~(I8042_CTR_KBDINT | I8042_CTR_AUXINT); | ||
776 | |||
777 | /* | ||
771 | * Disable MUX mode if present. | 778 | * Disable MUX mode if present. |
772 | */ | 779 | */ |
773 | 780 | ||
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 0a26e0663542..693e3b2a65a3 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
@@ -39,7 +39,8 @@ | |||
39 | /* | 39 | /* |
40 | * This code has been heavily tested on a Nokia 770, and lightly | 40 | * This code has been heavily tested on a Nokia 770, and lightly |
41 | * tested on other ads7846 devices (OSK/Mistral, Lubbock). | 41 | * tested on other ads7846 devices (OSK/Mistral, Lubbock). |
42 | * Support for ads7843 and ads7845 has only been stubbed in. | 42 | * Support for ads7843 tested on Atmel at91sam926x-EK. |
43 | * Support for ads7845 has only been stubbed in. | ||
43 | * | 44 | * |
44 | * IRQ handling needs a workaround because of a shortcoming in handling | 45 | * IRQ handling needs a workaround because of a shortcoming in handling |
45 | * edge triggered IRQs on some platforms like the OMAP1/2. These | 46 | * edge triggered IRQs on some platforms like the OMAP1/2. These |
@@ -246,18 +247,16 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) | |||
246 | 247 | ||
247 | /* REVISIT: take a few more samples, and compare ... */ | 248 | /* REVISIT: take a few more samples, and compare ... */ |
248 | 249 | ||
249 | /* maybe off internal vREF */ | 250 | /* converter in low power mode & enable PENIRQ */ |
250 | if (use_internal) { | 251 | req->ref_off = PWRDOWN; |
251 | req->ref_off = REF_OFF; | 252 | req->xfer[4].tx_buf = &req->ref_off; |
252 | req->xfer[4].tx_buf = &req->ref_off; | 253 | req->xfer[4].len = 1; |
253 | req->xfer[4].len = 1; | 254 | spi_message_add_tail(&req->xfer[4], &req->msg); |
254 | spi_message_add_tail(&req->xfer[4], &req->msg); | 255 | |
255 | 256 | req->xfer[5].rx_buf = &req->scratch; | |
256 | req->xfer[5].rx_buf = &req->scratch; | 257 | req->xfer[5].len = 2; |
257 | req->xfer[5].len = 2; | 258 | CS_CHANGE(req->xfer[5]); |
258 | CS_CHANGE(req->xfer[5]); | 259 | spi_message_add_tail(&req->xfer[5], &req->msg); |
259 | spi_message_add_tail(&req->xfer[5], &req->msg); | ||
260 | } | ||
261 | 260 | ||
262 | ts->irq_disabled = 1; | 261 | ts->irq_disabled = 1; |
263 | disable_irq(spi->irq); | 262 | disable_irq(spi->irq); |
@@ -536,6 +535,9 @@ static void ads7846_rx(void *ads) | |||
536 | } else | 535 | } else |
537 | Rt = 0; | 536 | Rt = 0; |
538 | 537 | ||
538 | if (ts->model == 7843) | ||
539 | Rt = ts->pressure_max / 2; | ||
540 | |||
539 | /* Sample found inconsistent by debouncing or pressure is beyond | 541 | /* Sample found inconsistent by debouncing or pressure is beyond |
540 | * the maximum. Don't report it to user space, repeat at least | 542 | * the maximum. Don't report it to user space, repeat at least |
541 | * once more the measurement | 543 | * once more the measurement |
@@ -897,7 +899,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
897 | 899 | ||
898 | input_dev->name = "ADS784x Touchscreen"; | 900 | input_dev->name = "ADS784x Touchscreen"; |
899 | input_dev->phys = ts->phys; | 901 | input_dev->phys = ts->phys; |
900 | input_dev->cdev.dev = &spi->dev; | 902 | input_dev->dev.parent = &spi->dev; |
901 | 903 | ||
902 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | 904 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); |
903 | input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); | 905 | input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); |
diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c index e2945582828e..e6a31d118786 100644 --- a/drivers/input/touchscreen/corgi_ts.c +++ b/drivers/input/touchscreen/corgi_ts.c | |||
@@ -300,8 +300,7 @@ static int __init corgits_probe(struct platform_device *pdev) | |||
300 | input_dev->id.vendor = 0x0001; | 300 | input_dev->id.vendor = 0x0001; |
301 | input_dev->id.product = 0x0002; | 301 | input_dev->id.product = 0x0002; |
302 | input_dev->id.version = 0x0100; | 302 | input_dev->id.version = 0x0100; |
303 | input_dev->cdev.dev = &pdev->dev; | 303 | input_dev->dev.parent = &pdev->dev; |
304 | input_dev->private = corgi_ts; | ||
305 | 304 | ||
306 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | 305 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); |
307 | input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); | 306 | input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); |
diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c index 9d61cd133d01..557d781719f1 100644 --- a/drivers/input/touchscreen/elo.c +++ b/drivers/input/touchscreen/elo.c | |||
@@ -312,14 +312,13 @@ static int elo_connect(struct serio *serio, struct serio_driver *drv) | |||
312 | init_completion(&elo->cmd_done); | 312 | init_completion(&elo->cmd_done); |
313 | snprintf(elo->phys, sizeof(elo->phys), "%s/input0", serio->phys); | 313 | snprintf(elo->phys, sizeof(elo->phys), "%s/input0", serio->phys); |
314 | 314 | ||
315 | input_dev->private = elo; | ||
316 | input_dev->name = "Elo Serial TouchScreen"; | 315 | input_dev->name = "Elo Serial TouchScreen"; |
317 | input_dev->phys = elo->phys; | 316 | input_dev->phys = elo->phys; |
318 | input_dev->id.bustype = BUS_RS232; | 317 | input_dev->id.bustype = BUS_RS232; |
319 | input_dev->id.vendor = SERIO_ELO; | 318 | input_dev->id.vendor = SERIO_ELO; |
320 | input_dev->id.product = elo->id; | 319 | input_dev->id.product = elo->id; |
321 | input_dev->id.version = 0x0100; | 320 | input_dev->id.version = 0x0100; |
322 | input_dev->cdev.dev = &serio->dev; | 321 | input_dev->dev.parent = &serio->dev; |
323 | 322 | ||
324 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | 323 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); |
325 | input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); | 324 | input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); |
diff --git a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c index 9157eb148e84..39d602600d7c 100644 --- a/drivers/input/touchscreen/gunze.c +++ b/drivers/input/touchscreen/gunze.c | |||
@@ -130,13 +130,13 @@ static int gunze_connect(struct serio *serio, struct serio_driver *drv) | |||
130 | gunze->dev = input_dev; | 130 | gunze->dev = input_dev; |
131 | snprintf(gunze->phys, sizeof(serio->phys), "%s/input0", serio->phys); | 131 | snprintf(gunze->phys, sizeof(serio->phys), "%s/input0", serio->phys); |
132 | 132 | ||
133 | input_dev->private = gunze; | ||
134 | input_dev->name = "Gunze AHL-51S TouchScreen"; | 133 | input_dev->name = "Gunze AHL-51S TouchScreen"; |
135 | input_dev->phys = gunze->phys; | 134 | input_dev->phys = gunze->phys; |
136 | input_dev->id.bustype = BUS_RS232; | 135 | input_dev->id.bustype = BUS_RS232; |
137 | input_dev->id.vendor = SERIO_GUNZE; | 136 | input_dev->id.vendor = SERIO_GUNZE; |
138 | input_dev->id.product = 0x0051; | 137 | input_dev->id.product = 0x0051; |
139 | input_dev->id.version = 0x0100; | 138 | input_dev->id.version = 0x0100; |
139 | input_dev->dev.parent = &serio->dev; | ||
140 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | 140 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); |
141 | input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); | 141 | input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); |
142 | input_set_abs_params(input_dev, ABS_X, 24, 1000, 0, 0); | 142 | input_set_abs_params(input_dev, ABS_X, 24, 1000, 0, 0); |
diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c index c4116d4f64e7..09ed7803cb8f 100644 --- a/drivers/input/touchscreen/h3600_ts_input.c +++ b/drivers/input/touchscreen/h3600_ts_input.c | |||
@@ -147,7 +147,7 @@ enum flite_pwr { | |||
147 | unsigned int h3600_flite_power(struct input_dev *dev, enum flite_pwr pwr) | 147 | unsigned int h3600_flite_power(struct input_dev *dev, enum flite_pwr pwr) |
148 | { | 148 | { |
149 | unsigned char brightness = (pwr == FLITE_PWR_OFF) ? 0 : flite_brightness; | 149 | unsigned char brightness = (pwr == FLITE_PWR_OFF) ? 0 : flite_brightness; |
150 | struct h3600_dev *ts = dev->private; | 150 | struct h3600_dev *ts = input_get_drvdata(dev); |
151 | 151 | ||
152 | /* Must be in this order */ | 152 | /* Must be in this order */ |
153 | ts->serio->write(ts->serio, 1); | 153 | ts->serio->write(ts->serio, 1); |
@@ -260,7 +260,7 @@ static int h3600ts_event(struct input_dev *dev, unsigned int type, | |||
260 | unsigned int code, int value) | 260 | unsigned int code, int value) |
261 | { | 261 | { |
262 | #if 0 | 262 | #if 0 |
263 | struct h3600_dev *ts = dev->private; | 263 | struct h3600_dev *ts = input_get_drvdata(dev); |
264 | 264 | ||
265 | switch (type) { | 265 | switch (type) { |
266 | case EV_LED: { | 266 | case EV_LED: { |
@@ -367,8 +367,9 @@ static int h3600ts_connect(struct serio *serio, struct serio_driver *drv) | |||
367 | input_dev->id.vendor = SERIO_H3600; | 367 | input_dev->id.vendor = SERIO_H3600; |
368 | input_dev->id.product = 0x0666; /* FIXME !!! We can ask the hardware */ | 368 | input_dev->id.product = 0x0666; /* FIXME !!! We can ask the hardware */ |
369 | input_dev->id.version = 0x0100; | 369 | input_dev->id.version = 0x0100; |
370 | input_dev->cdev.dev = &serio->dev; | 370 | input_dev->dev.parent = &serio->dev; |
371 | input_dev->private = ts; | 371 | |
372 | input_set_drvdata(input_dev, ts); | ||
372 | 373 | ||
373 | input_dev->event = h3600ts_event; | 374 | input_dev->event = h3600ts_event; |
374 | 375 | ||
diff --git a/drivers/input/touchscreen/hp680_ts_input.c b/drivers/input/touchscreen/hp680_ts_input.c index 249087472740..61c15024c2a0 100644 --- a/drivers/input/touchscreen/hp680_ts_input.c +++ b/drivers/input/touchscreen/hp680_ts_input.c | |||
@@ -21,7 +21,7 @@ | |||
21 | static void do_softint(void *data); | 21 | static void do_softint(void *data); |
22 | 22 | ||
23 | static struct input_dev *hp680_ts_dev; | 23 | static struct input_dev *hp680_ts_dev; |
24 | static DECLARE_WORK(work, do_softint, 0); | 24 | static DECLARE_WORK(work, do_softint); |
25 | 25 | ||
26 | static void do_softint(void *data) | 26 | static void do_softint(void *data) |
27 | { | 27 | { |
diff --git a/drivers/input/touchscreen/mtouch.c b/drivers/input/touchscreen/mtouch.c index c3c2d735d0ec..4ec3b1f940c8 100644 --- a/drivers/input/touchscreen/mtouch.c +++ b/drivers/input/touchscreen/mtouch.c | |||
@@ -144,13 +144,13 @@ static int mtouch_connect(struct serio *serio, struct serio_driver *drv) | |||
144 | mtouch->dev = input_dev; | 144 | mtouch->dev = input_dev; |
145 | snprintf(mtouch->phys, sizeof(mtouch->phys), "%s/input0", serio->phys); | 145 | snprintf(mtouch->phys, sizeof(mtouch->phys), "%s/input0", serio->phys); |
146 | 146 | ||
147 | input_dev->private = mtouch; | ||
148 | input_dev->name = "MicroTouch Serial TouchScreen"; | 147 | input_dev->name = "MicroTouch Serial TouchScreen"; |
149 | input_dev->phys = mtouch->phys; | 148 | input_dev->phys = mtouch->phys; |
150 | input_dev->id.bustype = BUS_RS232; | 149 | input_dev->id.bustype = BUS_RS232; |
151 | input_dev->id.vendor = SERIO_MICROTOUCH; | 150 | input_dev->id.vendor = SERIO_MICROTOUCH; |
152 | input_dev->id.product = 0; | 151 | input_dev->id.product = 0; |
153 | input_dev->id.version = 0x0100; | 152 | input_dev->id.version = 0x0100; |
153 | input_dev->dev.parent = &serio->dev; | ||
154 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | 154 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); |
155 | input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); | 155 | input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); |
156 | input_set_abs_params(mtouch->dev, ABS_X, MTOUCH_MIN_XC, MTOUCH_MAX_XC, 0, 0); | 156 | input_set_abs_params(mtouch->dev, ABS_X, MTOUCH_MIN_XC, MTOUCH_MAX_XC, 0, 0); |
diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c index bd2767991ae9..f2c0d3c7149c 100644 --- a/drivers/input/touchscreen/penmount.c +++ b/drivers/input/touchscreen/penmount.c | |||
@@ -105,14 +105,13 @@ static int pm_connect(struct serio *serio, struct serio_driver *drv) | |||
105 | pm->dev = input_dev; | 105 | pm->dev = input_dev; |
106 | snprintf(pm->phys, sizeof(pm->phys), "%s/input0", serio->phys); | 106 | snprintf(pm->phys, sizeof(pm->phys), "%s/input0", serio->phys); |
107 | 107 | ||
108 | input_dev->private = pm; | ||
109 | input_dev->name = "Penmount Serial TouchScreen"; | 108 | input_dev->name = "Penmount Serial TouchScreen"; |
110 | input_dev->phys = pm->phys; | 109 | input_dev->phys = pm->phys; |
111 | input_dev->id.bustype = BUS_RS232; | 110 | input_dev->id.bustype = BUS_RS232; |
112 | input_dev->id.vendor = SERIO_PENMOUNT; | 111 | input_dev->id.vendor = SERIO_PENMOUNT; |
113 | input_dev->id.product = 0; | 112 | input_dev->id.product = 0; |
114 | input_dev->id.version = 0x0100; | 113 | input_dev->id.version = 0x0100; |
115 | input_dev->cdev.dev = &serio->dev; | 114 | input_dev->dev.parent = &serio->dev; |
116 | 115 | ||
117 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | 116 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); |
118 | input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); | 117 | input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); |
diff --git a/drivers/input/touchscreen/touchright.c b/drivers/input/touchscreen/touchright.c index 35ba46c6ad2d..3def7bb1df44 100644 --- a/drivers/input/touchscreen/touchright.c +++ b/drivers/input/touchscreen/touchright.c | |||
@@ -118,13 +118,13 @@ static int tr_connect(struct serio *serio, struct serio_driver *drv) | |||
118 | tr->dev = input_dev; | 118 | tr->dev = input_dev; |
119 | snprintf(tr->phys, sizeof(tr->phys), "%s/input0", serio->phys); | 119 | snprintf(tr->phys, sizeof(tr->phys), "%s/input0", serio->phys); |
120 | 120 | ||
121 | input_dev->private = tr; | ||
122 | input_dev->name = "Touchright Serial TouchScreen"; | 121 | input_dev->name = "Touchright Serial TouchScreen"; |
123 | input_dev->phys = tr->phys; | 122 | input_dev->phys = tr->phys; |
124 | input_dev->id.bustype = BUS_RS232; | 123 | input_dev->id.bustype = BUS_RS232; |
125 | input_dev->id.vendor = SERIO_TOUCHRIGHT; | 124 | input_dev->id.vendor = SERIO_TOUCHRIGHT; |
126 | input_dev->id.product = 0; | 125 | input_dev->id.product = 0; |
127 | input_dev->id.version = 0x0100; | 126 | input_dev->id.version = 0x0100; |
127 | input_dev->dev.parent = &serio->dev; | ||
128 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | 128 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); |
129 | input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); | 129 | input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); |
130 | input_set_abs_params(tr->dev, ABS_X, TR_MIN_XC, TR_MAX_XC, 0, 0); | 130 | input_set_abs_params(tr->dev, ABS_X, TR_MIN_XC, TR_MAX_XC, 0, 0); |
diff --git a/drivers/input/touchscreen/touchwin.c b/drivers/input/touchscreen/touchwin.c index 4dc073dacabb..ac4bdcf18666 100644 --- a/drivers/input/touchscreen/touchwin.c +++ b/drivers/input/touchscreen/touchwin.c | |||
@@ -125,13 +125,13 @@ static int tw_connect(struct serio *serio, struct serio_driver *drv) | |||
125 | tw->dev = input_dev; | 125 | tw->dev = input_dev; |
126 | snprintf(tw->phys, sizeof(tw->phys), "%s/input0", serio->phys); | 126 | snprintf(tw->phys, sizeof(tw->phys), "%s/input0", serio->phys); |
127 | 127 | ||
128 | input_dev->private = tw; | ||
129 | input_dev->name = "Touchwindow Serial TouchScreen"; | 128 | input_dev->name = "Touchwindow Serial TouchScreen"; |
130 | input_dev->phys = tw->phys; | 129 | input_dev->phys = tw->phys; |
131 | input_dev->id.bustype = BUS_RS232; | 130 | input_dev->id.bustype = BUS_RS232; |
132 | input_dev->id.vendor = SERIO_TOUCHWIN; | 131 | input_dev->id.vendor = SERIO_TOUCHWIN; |
133 | input_dev->id.product = 0; | 132 | input_dev->id.product = 0; |
134 | input_dev->id.version = 0x0100; | 133 | input_dev->id.version = 0x0100; |
134 | input_dev->dev.parent = &serio->dev; | ||
135 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | 135 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); |
136 | input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); | 136 | input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); |
137 | input_set_abs_params(tw->dev, ABS_X, TW_MIN_XC, TW_MAX_XC, 0, 0); | 137 | input_set_abs_params(tw->dev, ABS_X, TW_MIN_XC, TW_MAX_XC, 0, 0); |
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c index e8606c48c9c3..6582816a0477 100644 --- a/drivers/input/touchscreen/ucb1400_ts.c +++ b/drivers/input/touchscreen/ucb1400_ts.c | |||
@@ -97,6 +97,8 @@ struct ucb1400 { | |||
97 | }; | 97 | }; |
98 | 98 | ||
99 | static int adcsync; | 99 | static int adcsync; |
100 | static int ts_delay = 55; /* us */ | ||
101 | static int ts_delay_pressure; /* us */ | ||
100 | 102 | ||
101 | static inline u16 ucb1400_reg_read(struct ucb1400 *ucb, u16 reg) | 103 | static inline u16 ucb1400_reg_read(struct ucb1400 *ucb, u16 reg) |
102 | { | 104 | { |
@@ -159,6 +161,7 @@ static inline unsigned int ucb1400_ts_read_pressure(struct ucb1400 *ucb) | |||
159 | UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW | | 161 | UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW | |
160 | UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND | | 162 | UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND | |
161 | UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); | 163 | UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); |
164 | udelay(ts_delay_pressure); | ||
162 | return ucb1400_adc_read(ucb, UCB_ADC_INP_TSPY); | 165 | return ucb1400_adc_read(ucb, UCB_ADC_INP_TSPY); |
163 | } | 166 | } |
164 | 167 | ||
@@ -180,7 +183,7 @@ static inline unsigned int ucb1400_ts_read_xpos(struct ucb1400 *ucb) | |||
180 | UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | | 183 | UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | |
181 | UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA); | 184 | UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA); |
182 | 185 | ||
183 | udelay(55); | 186 | udelay(ts_delay); |
184 | 187 | ||
185 | return ucb1400_adc_read(ucb, UCB_ADC_INP_TSPY); | 188 | return ucb1400_adc_read(ucb, UCB_ADC_INP_TSPY); |
186 | } | 189 | } |
@@ -203,7 +206,7 @@ static inline unsigned int ucb1400_ts_read_ypos(struct ucb1400 *ucb) | |||
203 | UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | | 206 | UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | |
204 | UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA); | 207 | UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA); |
205 | 208 | ||
206 | udelay(55); | 209 | udelay(ts_delay); |
207 | 210 | ||
208 | return ucb1400_adc_read(ucb, UCB_ADC_INP_TSPX); | 211 | return ucb1400_adc_read(ucb, UCB_ADC_INP_TSPX); |
209 | } | 212 | } |
@@ -369,7 +372,7 @@ static irqreturn_t ucb1400_hard_irq(int irqnr, void *devid) | |||
369 | 372 | ||
370 | static int ucb1400_ts_open(struct input_dev *idev) | 373 | static int ucb1400_ts_open(struct input_dev *idev) |
371 | { | 374 | { |
372 | struct ucb1400 *ucb = idev->private; | 375 | struct ucb1400 *ucb = input_get_drvdata(idev); |
373 | int ret = 0; | 376 | int ret = 0; |
374 | 377 | ||
375 | BUG_ON(ucb->ts_task); | 378 | BUG_ON(ucb->ts_task); |
@@ -385,7 +388,7 @@ static int ucb1400_ts_open(struct input_dev *idev) | |||
385 | 388 | ||
386 | static void ucb1400_ts_close(struct input_dev *idev) | 389 | static void ucb1400_ts_close(struct input_dev *idev) |
387 | { | 390 | { |
388 | struct ucb1400 *ucb = idev->private; | 391 | struct ucb1400 *ucb = input_get_drvdata(idev); |
389 | 392 | ||
390 | if (ucb->ts_task) | 393 | if (ucb->ts_task) |
391 | kthread_stop(ucb->ts_task); | 394 | kthread_stop(ucb->ts_task); |
@@ -507,8 +510,9 @@ static int ucb1400_ts_probe(struct device *dev) | |||
507 | } | 510 | } |
508 | printk(KERN_DEBUG "UCB1400: found IRQ %d\n", ucb->irq); | 511 | printk(KERN_DEBUG "UCB1400: found IRQ %d\n", ucb->irq); |
509 | 512 | ||
510 | idev->private = ucb; | 513 | input_set_drvdata(idev, ucb); |
511 | idev->cdev.dev = dev; | 514 | |
515 | idev->dev.parent = dev; | ||
512 | idev->name = "UCB1400 touchscreen interface"; | 516 | idev->name = "UCB1400 touchscreen interface"; |
513 | idev->id.vendor = ucb1400_reg_read(ucb, AC97_VENDOR_ID1); | 517 | idev->id.vendor = ucb1400_reg_read(ucb, AC97_VENDOR_ID1); |
514 | idev->id.product = id; | 518 | idev->id.product = id; |
@@ -571,7 +575,15 @@ static void __exit ucb1400_ts_exit(void) | |||
571 | driver_unregister(&ucb1400_ts_driver); | 575 | driver_unregister(&ucb1400_ts_driver); |
572 | } | 576 | } |
573 | 577 | ||
574 | module_param(adcsync, int, 0444); | 578 | module_param(adcsync, bool, 0444); |
579 | MODULE_PARM_DESC(adcsync, "Synchronize touch readings with ADCSYNC pin."); | ||
580 | |||
581 | module_param(ts_delay, int, 0444); | ||
582 | MODULE_PARM_DESC(ts_delay, "Delay between panel setup and position read. Default = 55us."); | ||
583 | |||
584 | module_param(ts_delay_pressure, int, 0444); | ||
585 | MODULE_PARM_DESC(ts_delay_pressure, | ||
586 | "delay between panel setup and pressure read. Default = 0us."); | ||
575 | 587 | ||
576 | module_init(ucb1400_ts_init); | 588 | module_init(ucb1400_ts_init); |
577 | module_exit(ucb1400_ts_exit); | 589 | module_exit(ucb1400_ts_exit); |
diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c index 0300dca8591d..5e5b5c91d75b 100644 --- a/drivers/input/tsdev.c +++ b/drivers/input/tsdev.c | |||
@@ -111,13 +111,13 @@ struct tsdev { | |||
111 | int minor; | 111 | int minor; |
112 | char name[8]; | 112 | char name[8]; |
113 | wait_queue_head_t wait; | 113 | wait_queue_head_t wait; |
114 | struct list_head list; | 114 | struct list_head client_list; |
115 | struct input_handle handle; | 115 | struct input_handle handle; |
116 | int x, y, pressure; | 116 | int x, y, pressure; |
117 | struct ts_calibration cal; | 117 | struct ts_calibration cal; |
118 | }; | 118 | }; |
119 | 119 | ||
120 | struct tsdev_list { | 120 | struct tsdev_client { |
121 | struct fasync_struct *fasync; | 121 | struct fasync_struct *fasync; |
122 | struct list_head node; | 122 | struct list_head node; |
123 | struct tsdev *tsdev; | 123 | struct tsdev *tsdev; |
@@ -139,38 +139,49 @@ static struct tsdev *tsdev_table[TSDEV_MINORS/2]; | |||
139 | 139 | ||
140 | static int tsdev_fasync(int fd, struct file *file, int on) | 140 | static int tsdev_fasync(int fd, struct file *file, int on) |
141 | { | 141 | { |
142 | struct tsdev_list *list = file->private_data; | 142 | struct tsdev_client *client = file->private_data; |
143 | int retval; | 143 | int retval; |
144 | 144 | ||
145 | retval = fasync_helper(fd, file, on, &list->fasync); | 145 | retval = fasync_helper(fd, file, on, &client->fasync); |
146 | return retval < 0 ? retval : 0; | 146 | return retval < 0 ? retval : 0; |
147 | } | 147 | } |
148 | 148 | ||
149 | static int tsdev_open(struct inode *inode, struct file *file) | 149 | static int tsdev_open(struct inode *inode, struct file *file) |
150 | { | 150 | { |
151 | int i = iminor(inode) - TSDEV_MINOR_BASE; | 151 | int i = iminor(inode) - TSDEV_MINOR_BASE; |
152 | struct tsdev_list *list; | 152 | struct tsdev_client *client; |
153 | struct tsdev *tsdev; | ||
154 | int error; | ||
153 | 155 | ||
154 | printk(KERN_WARNING "tsdev (compaq touchscreen emulation) is scheduled " | 156 | printk(KERN_WARNING "tsdev (compaq touchscreen emulation) is scheduled " |
155 | "for removal.\nSee Documentation/feature-removal-schedule.txt " | 157 | "for removal.\nSee Documentation/feature-removal-schedule.txt " |
156 | "for details.\n"); | 158 | "for details.\n"); |
157 | 159 | ||
158 | if (i >= TSDEV_MINORS || !tsdev_table[i & TSDEV_MINOR_MASK]) | 160 | if (i >= TSDEV_MINORS) |
161 | return -ENODEV; | ||
162 | |||
163 | tsdev = tsdev_table[i & TSDEV_MINOR_MASK]; | ||
164 | if (!tsdev || !tsdev->exist) | ||
159 | return -ENODEV; | 165 | return -ENODEV; |
160 | 166 | ||
161 | if (!(list = kzalloc(sizeof(struct tsdev_list), GFP_KERNEL))) | 167 | client = kzalloc(sizeof(struct tsdev_client), GFP_KERNEL); |
168 | if (!client) | ||
162 | return -ENOMEM; | 169 | return -ENOMEM; |
163 | 170 | ||
164 | list->raw = (i >= TSDEV_MINORS/2) ? 1 : 0; | 171 | client->tsdev = tsdev; |
172 | client->raw = (i >= TSDEV_MINORS / 2) ? 1 : 0; | ||
173 | list_add_tail(&client->node, &tsdev->client_list); | ||
165 | 174 | ||
166 | i &= TSDEV_MINOR_MASK; | 175 | if (!tsdev->open++ && tsdev->exist) { |
167 | list->tsdev = tsdev_table[i]; | 176 | error = input_open_device(&tsdev->handle); |
168 | list_add_tail(&list->node, &tsdev_table[i]->list); | 177 | if (error) { |
169 | file->private_data = list; | 178 | list_del(&client->node); |
179 | kfree(client); | ||
180 | return error; | ||
181 | } | ||
182 | } | ||
170 | 183 | ||
171 | if (!list->tsdev->open++) | 184 | file->private_data = client; |
172 | if (list->tsdev->exist) | ||
173 | input_open_device(&list->tsdev->handle); | ||
174 | return 0; | 185 | return 0; |
175 | } | 186 | } |
176 | 187 | ||
@@ -182,45 +193,48 @@ static void tsdev_free(struct tsdev *tsdev) | |||
182 | 193 | ||
183 | static int tsdev_release(struct inode *inode, struct file *file) | 194 | static int tsdev_release(struct inode *inode, struct file *file) |
184 | { | 195 | { |
185 | struct tsdev_list *list = file->private_data; | 196 | struct tsdev_client *client = file->private_data; |
197 | struct tsdev *tsdev = client->tsdev; | ||
186 | 198 | ||
187 | tsdev_fasync(-1, file, 0); | 199 | tsdev_fasync(-1, file, 0); |
188 | list_del(&list->node); | ||
189 | 200 | ||
190 | if (!--list->tsdev->open) { | 201 | list_del(&client->node); |
191 | if (list->tsdev->exist) | 202 | kfree(client); |
192 | input_close_device(&list->tsdev->handle); | 203 | |
204 | if (!--tsdev->open) { | ||
205 | if (tsdev->exist) | ||
206 | input_close_device(&tsdev->handle); | ||
193 | else | 207 | else |
194 | tsdev_free(list->tsdev); | 208 | tsdev_free(tsdev); |
195 | } | 209 | } |
196 | kfree(list); | 210 | |
197 | return 0; | 211 | return 0; |
198 | } | 212 | } |
199 | 213 | ||
200 | static ssize_t tsdev_read(struct file *file, char __user *buffer, size_t count, | 214 | static ssize_t tsdev_read(struct file *file, char __user *buffer, size_t count, |
201 | loff_t * ppos) | 215 | loff_t *ppos) |
202 | { | 216 | { |
203 | struct tsdev_list *list = file->private_data; | 217 | struct tsdev_client *client = file->private_data; |
218 | struct tsdev *tsdev = client->tsdev; | ||
204 | int retval = 0; | 219 | int retval = 0; |
205 | 220 | ||
206 | if (list->head == list->tail && list->tsdev->exist && (file->f_flags & O_NONBLOCK)) | 221 | if (client->head == client->tail && tsdev->exist && (file->f_flags & O_NONBLOCK)) |
207 | return -EAGAIN; | 222 | return -EAGAIN; |
208 | 223 | ||
209 | retval = wait_event_interruptible(list->tsdev->wait, | 224 | retval = wait_event_interruptible(tsdev->wait, |
210 | list->head != list->tail || !list->tsdev->exist); | 225 | client->head != client->tail || !tsdev->exist); |
211 | |||
212 | if (retval) | 226 | if (retval) |
213 | return retval; | 227 | return retval; |
214 | 228 | ||
215 | if (!list->tsdev->exist) | 229 | if (!tsdev->exist) |
216 | return -ENODEV; | 230 | return -ENODEV; |
217 | 231 | ||
218 | while (list->head != list->tail && | 232 | while (client->head != client->tail && |
219 | retval + sizeof (struct ts_event) <= count) { | 233 | retval + sizeof (struct ts_event) <= count) { |
220 | if (copy_to_user (buffer + retval, list->event + list->tail, | 234 | if (copy_to_user (buffer + retval, client->event + client->tail, |
221 | sizeof (struct ts_event))) | 235 | sizeof (struct ts_event))) |
222 | return -EFAULT; | 236 | return -EFAULT; |
223 | list->tail = (list->tail + 1) & (TSDEV_BUFFER_SIZE - 1); | 237 | client->tail = (client->tail + 1) & (TSDEV_BUFFER_SIZE - 1); |
224 | retval += sizeof (struct ts_event); | 238 | retval += sizeof (struct ts_event); |
225 | } | 239 | } |
226 | 240 | ||
@@ -228,32 +242,33 @@ static ssize_t tsdev_read(struct file *file, char __user *buffer, size_t count, | |||
228 | } | 242 | } |
229 | 243 | ||
230 | /* No kernel lock - fine */ | 244 | /* No kernel lock - fine */ |
231 | static unsigned int tsdev_poll(struct file *file, poll_table * wait) | 245 | static unsigned int tsdev_poll(struct file *file, poll_table *wait) |
232 | { | 246 | { |
233 | struct tsdev_list *list = file->private_data; | 247 | struct tsdev_client *client = file->private_data; |
248 | struct tsdev *tsdev = client->tsdev; | ||
234 | 249 | ||
235 | poll_wait(file, &list->tsdev->wait, wait); | 250 | poll_wait(file, &tsdev->wait, wait); |
236 | return ((list->head == list->tail) ? 0 : (POLLIN | POLLRDNORM)) | | 251 | return ((client->head == client->tail) ? 0 : (POLLIN | POLLRDNORM)) | |
237 | (list->tsdev->exist ? 0 : (POLLHUP | POLLERR)); | 252 | (tsdev->exist ? 0 : (POLLHUP | POLLERR)); |
238 | } | 253 | } |
239 | 254 | ||
240 | static int tsdev_ioctl(struct inode *inode, struct file *file, | 255 | static int tsdev_ioctl(struct inode *inode, struct file *file, |
241 | unsigned int cmd, unsigned long arg) | 256 | unsigned int cmd, unsigned long arg) |
242 | { | 257 | { |
243 | struct tsdev_list *list = file->private_data; | 258 | struct tsdev_client *client = file->private_data; |
244 | struct tsdev *tsdev = list->tsdev; | 259 | struct tsdev *tsdev = client->tsdev; |
245 | int retval = 0; | 260 | int retval = 0; |
246 | 261 | ||
247 | switch (cmd) { | 262 | switch (cmd) { |
248 | case TS_GET_CAL: | 263 | case TS_GET_CAL: |
249 | if (copy_to_user ((void __user *)arg, &tsdev->cal, | 264 | if (copy_to_user((void __user *)arg, &tsdev->cal, |
250 | sizeof (struct ts_calibration))) | 265 | sizeof (struct ts_calibration))) |
251 | retval = -EFAULT; | 266 | retval = -EFAULT; |
252 | break; | 267 | break; |
253 | 268 | ||
254 | case TS_SET_CAL: | 269 | case TS_SET_CAL: |
255 | if (copy_from_user (&tsdev->cal, (void __user *)arg, | 270 | if (copy_from_user(&tsdev->cal, (void __user *)arg, |
256 | sizeof (struct ts_calibration))) | 271 | sizeof (struct ts_calibration))) |
257 | retval = -EFAULT; | 272 | retval = -EFAULT; |
258 | break; | 273 | break; |
259 | 274 | ||
@@ -279,7 +294,7 @@ static void tsdev_event(struct input_handle *handle, unsigned int type, | |||
279 | unsigned int code, int value) | 294 | unsigned int code, int value) |
280 | { | 295 | { |
281 | struct tsdev *tsdev = handle->private; | 296 | struct tsdev *tsdev = handle->private; |
282 | struct tsdev_list *list; | 297 | struct tsdev_client *client; |
283 | struct timeval time; | 298 | struct timeval time; |
284 | 299 | ||
285 | switch (type) { | 300 | switch (type) { |
@@ -343,18 +358,18 @@ static void tsdev_event(struct input_handle *handle, unsigned int type, | |||
343 | if (type != EV_SYN || code != SYN_REPORT) | 358 | if (type != EV_SYN || code != SYN_REPORT) |
344 | return; | 359 | return; |
345 | 360 | ||
346 | list_for_each_entry(list, &tsdev->list, node) { | 361 | list_for_each_entry(client, &tsdev->client_list, node) { |
347 | int x, y, tmp; | 362 | int x, y, tmp; |
348 | 363 | ||
349 | do_gettimeofday(&time); | 364 | do_gettimeofday(&time); |
350 | list->event[list->head].millisecs = time.tv_usec / 100; | 365 | client->event[client->head].millisecs = time.tv_usec / 100; |
351 | list->event[list->head].pressure = tsdev->pressure; | 366 | client->event[client->head].pressure = tsdev->pressure; |
352 | 367 | ||
353 | x = tsdev->x; | 368 | x = tsdev->x; |
354 | y = tsdev->y; | 369 | y = tsdev->y; |
355 | 370 | ||
356 | /* Calibration */ | 371 | /* Calibration */ |
357 | if (!list->raw) { | 372 | if (!client->raw) { |
358 | x = ((x * tsdev->cal.xscale) >> 8) + tsdev->cal.xtrans; | 373 | x = ((x * tsdev->cal.xscale) >> 8) + tsdev->cal.xtrans; |
359 | y = ((y * tsdev->cal.yscale) >> 8) + tsdev->cal.ytrans; | 374 | y = ((y * tsdev->cal.yscale) >> 8) + tsdev->cal.ytrans; |
360 | if (tsdev->cal.xyswap) { | 375 | if (tsdev->cal.xyswap) { |
@@ -362,33 +377,35 @@ static void tsdev_event(struct input_handle *handle, unsigned int type, | |||
362 | } | 377 | } |
363 | } | 378 | } |
364 | 379 | ||
365 | list->event[list->head].x = x; | 380 | client->event[client->head].x = x; |
366 | list->event[list->head].y = y; | 381 | client->event[client->head].y = y; |
367 | list->head = (list->head + 1) & (TSDEV_BUFFER_SIZE - 1); | 382 | client->head = (client->head + 1) & (TSDEV_BUFFER_SIZE - 1); |
368 | kill_fasync(&list->fasync, SIGIO, POLL_IN); | 383 | kill_fasync(&client->fasync, SIGIO, POLL_IN); |
369 | } | 384 | } |
370 | wake_up_interruptible(&tsdev->wait); | 385 | wake_up_interruptible(&tsdev->wait); |
371 | } | 386 | } |
372 | 387 | ||
373 | static struct input_handle *tsdev_connect(struct input_handler *handler, | 388 | static int tsdev_connect(struct input_handler *handler, struct input_dev *dev, |
374 | struct input_dev *dev, | 389 | const struct input_device_id *id) |
375 | const struct input_device_id *id) | ||
376 | { | 390 | { |
377 | struct tsdev *tsdev; | 391 | struct tsdev *tsdev; |
378 | struct class_device *cdev; | 392 | struct class_device *cdev; |
393 | dev_t devt; | ||
379 | int minor, delta; | 394 | int minor, delta; |
395 | int error; | ||
380 | 396 | ||
381 | for (minor = 0; minor < TSDEV_MINORS / 2 && tsdev_table[minor]; minor++); | 397 | for (minor = 0; minor < TSDEV_MINORS / 2 && tsdev_table[minor]; minor++); |
382 | if (minor >= TSDEV_MINORS / 2) { | 398 | if (minor >= TSDEV_MINORS / 2) { |
383 | printk(KERN_ERR | 399 | printk(KERN_ERR |
384 | "tsdev: You have way too many touchscreens\n"); | 400 | "tsdev: You have way too many touchscreens\n"); |
385 | return NULL; | 401 | return -ENFILE; |
386 | } | 402 | } |
387 | 403 | ||
388 | if (!(tsdev = kzalloc(sizeof(struct tsdev), GFP_KERNEL))) | 404 | tsdev = kzalloc(sizeof(struct tsdev), GFP_KERNEL); |
389 | return NULL; | 405 | if (!tsdev) |
406 | return -ENOMEM; | ||
390 | 407 | ||
391 | INIT_LIST_HEAD(&tsdev->list); | 408 | INIT_LIST_HEAD(&tsdev->client_list); |
392 | init_waitqueue_head(&tsdev->wait); | 409 | init_waitqueue_head(&tsdev->wait); |
393 | 410 | ||
394 | sprintf(tsdev->name, "ts%d", minor); | 411 | sprintf(tsdev->name, "ts%d", minor); |
@@ -415,23 +432,45 @@ static struct input_handle *tsdev_connect(struct input_handler *handler, | |||
415 | 432 | ||
416 | tsdev_table[minor] = tsdev; | 433 | tsdev_table[minor] = tsdev; |
417 | 434 | ||
418 | cdev = class_device_create(&input_class, &dev->cdev, | 435 | devt = MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor), |
419 | MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor), | 436 | |
420 | dev->cdev.dev, tsdev->name); | 437 | cdev = class_device_create(&input_class, &dev->cdev, devt, |
438 | dev->cdev.dev, tsdev->name); | ||
439 | if (IS_ERR(cdev)) { | ||
440 | error = PTR_ERR(cdev); | ||
441 | goto err_free_tsdev; | ||
442 | } | ||
421 | 443 | ||
422 | /* temporary symlink to keep userspace happy */ | 444 | /* temporary symlink to keep userspace happy */ |
423 | sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj, | 445 | error = sysfs_create_link(&input_class.subsys.kobj, |
424 | tsdev->name); | 446 | &cdev->kobj, tsdev->name); |
447 | if (error) | ||
448 | goto err_cdev_destroy; | ||
449 | |||
450 | error = input_register_handle(&tsdev->handle); | ||
451 | if (error) | ||
452 | goto err_remove_link; | ||
425 | 453 | ||
426 | return &tsdev->handle; | 454 | return 0; |
455 | |||
456 | err_remove_link: | ||
457 | sysfs_remove_link(&input_class.subsys.kobj, tsdev->name); | ||
458 | err_cdev_destroy: | ||
459 | class_device_destroy(&input_class, devt); | ||
460 | err_free_tsdev: | ||
461 | tsdev_table[minor] = NULL; | ||
462 | kfree(tsdev); | ||
463 | return error; | ||
427 | } | 464 | } |
428 | 465 | ||
429 | static void tsdev_disconnect(struct input_handle *handle) | 466 | static void tsdev_disconnect(struct input_handle *handle) |
430 | { | 467 | { |
431 | struct tsdev *tsdev = handle->private; | 468 | struct tsdev *tsdev = handle->private; |
432 | struct tsdev_list *list; | 469 | struct tsdev_client *client; |
470 | |||
471 | input_unregister_handle(handle); | ||
433 | 472 | ||
434 | sysfs_remove_link(&input_class.subsys.kset.kobj, tsdev->name); | 473 | sysfs_remove_link(&input_class.subsys.kobj, tsdev->name); |
435 | class_device_destroy(&input_class, | 474 | class_device_destroy(&input_class, |
436 | MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor)); | 475 | MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor)); |
437 | tsdev->exist = 0; | 476 | tsdev->exist = 0; |
@@ -439,8 +478,8 @@ static void tsdev_disconnect(struct input_handle *handle) | |||
439 | if (tsdev->open) { | 478 | if (tsdev->open) { |
440 | input_close_device(handle); | 479 | input_close_device(handle); |
441 | wake_up_interruptible(&tsdev->wait); | 480 | wake_up_interruptible(&tsdev->wait); |
442 | list_for_each_entry(list, &tsdev->list, node) | 481 | list_for_each_entry(client, &tsdev->client_list, node) |
443 | kill_fasync(&list->fasync, SIGIO, POLL_HUP); | 482 | kill_fasync(&client->fasync, SIGIO, POLL_HUP); |
444 | } else | 483 | } else |
445 | tsdev_free(tsdev); | 484 | tsdev_free(tsdev); |
446 | } | 485 | } |