Blame view
drivers/input/mousedev.c
26.1 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 10 |
/* * Input driver to ExplorerPS/2 device driver module. * * Copyright (c) 1999-2002 Vojtech Pavlik * Copyright (c) 2004 Dmitry Torokhov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as published by * the Free Software Foundation. */ |
da0c49011 Input: use pr_fmt... |
11 |
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
4f00469c1 [PATCH] Input: ki... |
12 |
#define MOUSEDEV_MINOR_BASE 32 |
c91cb7a75 Input: mousedev -... |
13 14 |
#define MOUSEDEV_MINORS 31 #define MOUSEDEV_MIX 63 |
1da177e4c Linux-2.6.12-rc2 |
15 |
|
a99bbaf5e headers: remove s... |
16 |
#include <linux/sched.h> |
1da177e4c Linux-2.6.12-rc2 |
17 18 19 |
#include <linux/slab.h> #include <linux/poll.h> #include <linux/module.h> |
1da177e4c Linux-2.6.12-rc2 |
20 21 |
#include <linux/init.h> #include <linux/input.h> |
1da177e4c Linux-2.6.12-rc2 |
22 23 24 |
#include <linux/random.h> #include <linux/major.h> #include <linux/device.h> |
7f8d4cad1 Input: extend the... |
25 |
#include <linux/cdev.h> |
987a6c029 Input: switch to ... |
26 |
#include <linux/kernel.h> |
1da177e4c Linux-2.6.12-rc2 |
27 28 29 30 31 32 33 34 35 36 37 38 39 |
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); MODULE_DESCRIPTION("Mouse (ExplorerPS/2) device interfaces"); MODULE_LICENSE("GPL"); #ifndef CONFIG_INPUT_MOUSEDEV_SCREEN_X #define CONFIG_INPUT_MOUSEDEV_SCREEN_X 1024 #endif #ifndef CONFIG_INPUT_MOUSEDEV_SCREEN_Y #define CONFIG_INPUT_MOUSEDEV_SCREEN_Y 768 #endif static int xres = CONFIG_INPUT_MOUSEDEV_SCREEN_X; |
84c12b241 Input: mousedev -... |
40 |
module_param(xres, uint, 0644); |
1da177e4c Linux-2.6.12-rc2 |
41 42 43 |
MODULE_PARM_DESC(xres, "Horizontal screen resolution"); static int yres = CONFIG_INPUT_MOUSEDEV_SCREEN_Y; |
84c12b241 Input: mousedev -... |
44 |
module_param(yres, uint, 0644); |
1da177e4c Linux-2.6.12-rc2 |
45 46 47 |
MODULE_PARM_DESC(yres, "Vertical screen resolution"); static unsigned tap_time = 200; |
84c12b241 Input: mousedev -... |
48 |
module_param(tap_time, uint, 0644); |
1da177e4c Linux-2.6.12-rc2 |
49 50 51 52 53 54 55 56 57 58 |
MODULE_PARM_DESC(tap_time, "Tap time for touchpads in absolute mode (msecs)"); struct mousedev_hw_data { int dx, dy, dz; int x, y; int abs_event; unsigned long buttons; }; struct mousedev { |
1da177e4c Linux-2.6.12-rc2 |
59 |
int open; |
464b24157 Input: mousedev -... |
60 |
struct input_handle handle; |
1da177e4c Linux-2.6.12-rc2 |
61 |
wait_queue_head_t wait; |
d0ffb9be8 Input: handlers -... |
62 |
struct list_head client_list; |
464b24157 Input: mousedev -... |
63 64 |
spinlock_t client_lock; /* protects client_list */ struct mutex mutex; |
9657d75c5 Input: convert fr... |
65 |
struct device dev; |
7f8d4cad1 Input: extend the... |
66 |
struct cdev cdev; |
20da92de8 Input: change inp... |
67 |
bool exist; |
1da177e4c Linux-2.6.12-rc2 |
68 |
|
d542ed82f Input: handlers -... |
69 |
struct list_head mixdev_node; |
3376b8b75 Input: mousedev -... |
70 |
bool opened_by_mixdev; |
d542ed82f Input: handlers -... |
71 |
|
1da177e4c Linux-2.6.12-rc2 |
72 73 74 75 76 |
struct mousedev_hw_data packet; unsigned int pkt_count; int old_x[4], old_y[4]; int frac_dx, frac_dy; unsigned long touch; |
e4dbedc7e Input: mousedev -... |
77 78 79 |
int (*open_device)(struct mousedev *mousedev); void (*close_device)(struct mousedev *mousedev); |
1da177e4c Linux-2.6.12-rc2 |
80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
}; enum mousedev_emul { MOUSEDEV_EMUL_PS2, MOUSEDEV_EMUL_IMPS, MOUSEDEV_EMUL_EXPS }; struct mousedev_motion { int dx, dy, dz; unsigned long buttons; }; #define PACKET_QUEUE_LEN 16 |
d0ffb9be8 Input: handlers -... |
94 |
struct mousedev_client { |
1da177e4c Linux-2.6.12-rc2 |
95 96 97 98 99 100 101 102 103 104 105 106 107 |
struct fasync_struct *fasync; struct mousedev *mousedev; struct list_head node; struct mousedev_motion packets[PACKET_QUEUE_LEN]; unsigned int head, tail; spinlock_t packet_lock; int pos_x, pos_y; signed char ps2[6]; unsigned char ready, buffer, bufsiz; unsigned char imexseq, impsseq; enum mousedev_emul mode; |
c1e4c8d3e [PATCH] fix jumpy... |
108 |
unsigned long last_buttons; |
1da177e4c Linux-2.6.12-rc2 |
109 110 111 112 113 114 |
}; #define MOUSEDEV_SEQ_LEN 6 static unsigned char mousedev_imps_seq[] = { 0xf3, 200, 0xf3, 100, 0xf3, 80 }; static unsigned char mousedev_imex_seq[] = { 0xf3, 200, 0xf3, 200, 0xf3, 80 }; |
9657d75c5 Input: convert fr... |
115 |
static struct mousedev *mousedev_mix; |
d542ed82f Input: handlers -... |
116 |
static LIST_HEAD(mousedev_mix_list); |
1da177e4c Linux-2.6.12-rc2 |
117 118 119 |
#define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03]) #define fy(i) (mousedev->old_y[(mousedev->pkt_count - (i)) & 03]) |
464b24157 Input: mousedev -... |
120 121 122 |
static void mousedev_touchpad_event(struct input_dev *dev, struct mousedev *mousedev, unsigned int code, int value) |
1da177e4c Linux-2.6.12-rc2 |
123 124 125 |
{ int size, tmp; enum { FRACTION_DENOM = 128 }; |
0d9d93c41 Input: mousedev -... |
126 |
switch (code) { |
1da177e4c Linux-2.6.12-rc2 |
127 |
|
464b24157 Input: mousedev -... |
128 |
case ABS_X: |
987a6c029 Input: switch to ... |
129 |
|
464b24157 Input: mousedev -... |
130 131 |
fx(0) = value; if (mousedev->touch && mousedev->pkt_count >= 2) { |
268ba5c05 Input: mousedev -... |
132 133 |
size = input_abs_get_max(dev, ABS_X) - input_abs_get_min(dev, ABS_X); |
464b24157 Input: mousedev -... |
134 135 |
if (size == 0) size = 256 * 2; |
987a6c029 Input: switch to ... |
136 |
|
464b24157 Input: mousedev -... |
137 138 139 140 141 142 143 144 145 146 147 |
tmp = ((value - fx(2)) * 256 * FRACTION_DENOM) / size; tmp += mousedev->frac_dx; mousedev->packet.dx = tmp / FRACTION_DENOM; mousedev->frac_dx = tmp - mousedev->packet.dx * FRACTION_DENOM; } break; case ABS_Y: fy(0) = value; if (mousedev->touch && mousedev->pkt_count >= 2) { |
987a6c029 Input: switch to ... |
148 |
/* use X size for ABS_Y to keep the same scale */ |
268ba5c05 Input: mousedev -... |
149 150 |
size = input_abs_get_max(dev, ABS_X) - input_abs_get_min(dev, ABS_X); |
464b24157 Input: mousedev -... |
151 152 |
if (size == 0) size = 256 * 2; |
987a6c029 Input: switch to ... |
153 |
|
464b24157 Input: mousedev -... |
154 155 156 157 158 159 160 |
tmp = -((value - fy(2)) * 256 * FRACTION_DENOM) / size; tmp += mousedev->frac_dy; mousedev->packet.dy = tmp / FRACTION_DENOM; mousedev->frac_dy = tmp - mousedev->packet.dy * FRACTION_DENOM; } break; |
1da177e4c Linux-2.6.12-rc2 |
161 162 |
} } |
464b24157 Input: mousedev -... |
163 164 |
static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev, unsigned int code, int value) |
1da177e4c Linux-2.6.12-rc2 |
165 |
{ |
987a6c029 Input: switch to ... |
166 |
int min, max, size; |
1da177e4c Linux-2.6.12-rc2 |
167 168 |
switch (code) { |
1da177e4c Linux-2.6.12-rc2 |
169 |
|
464b24157 Input: mousedev -... |
170 |
case ABS_X: |
987a6c029 Input: switch to ... |
171 172 173 174 |
min = input_abs_get_min(dev, ABS_X); max = input_abs_get_max(dev, ABS_X); size = max - min; |
464b24157 Input: mousedev -... |
175 176 |
if (size == 0) size = xres ? : 1; |
987a6c029 Input: switch to ... |
177 |
|
8c127f071 Input: properly a... |
178 |
value = clamp(value, min, max); |
987a6c029 Input: switch to ... |
179 180 |
mousedev->packet.x = ((value - min) * xres) / size; |
464b24157 Input: mousedev -... |
181 182 183 184 |
mousedev->packet.abs_event = 1; break; case ABS_Y: |
987a6c029 Input: switch to ... |
185 186 187 188 |
min = input_abs_get_min(dev, ABS_Y); max = input_abs_get_max(dev, ABS_Y); size = max - min; |
464b24157 Input: mousedev -... |
189 190 |
if (size == 0) size = yres ? : 1; |
987a6c029 Input: switch to ... |
191 |
|
8c127f071 Input: properly a... |
192 |
value = clamp(value, min, max); |
987a6c029 Input: switch to ... |
193 194 |
mousedev->packet.y = yres - ((value - min) * yres) / size; |
464b24157 Input: mousedev -... |
195 196 |
mousedev->packet.abs_event = 1; break; |
1da177e4c Linux-2.6.12-rc2 |
197 198 |
} } |
464b24157 Input: mousedev -... |
199 200 |
static void mousedev_rel_event(struct mousedev *mousedev, unsigned int code, int value) |
1da177e4c Linux-2.6.12-rc2 |
201 202 |
{ switch (code) { |
464b24157 Input: mousedev -... |
203 204 205 206 207 208 209 210 211 212 213 |
case REL_X: mousedev->packet.dx += value; break; case REL_Y: mousedev->packet.dy -= value; break; case REL_WHEEL: mousedev->packet.dz -= value; break; |
1da177e4c Linux-2.6.12-rc2 |
214 215 |
} } |
464b24157 Input: mousedev -... |
216 217 |
static void mousedev_key_event(struct mousedev *mousedev, unsigned int code, int value) |
1da177e4c Linux-2.6.12-rc2 |
218 219 220 221 |
{ int index; switch (code) { |
464b24157 Input: mousedev -... |
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 |
case BTN_TOUCH: case BTN_0: case BTN_LEFT: index = 0; break; case BTN_STYLUS: case BTN_1: case BTN_RIGHT: index = 1; break; case BTN_2: case BTN_FORWARD: case BTN_STYLUS2: case BTN_MIDDLE: index = 2; break; case BTN_3: case BTN_BACK: case BTN_SIDE: index = 3; break; case BTN_4: case BTN_EXTRA: index = 4; break; default: return; |
1da177e4c Linux-2.6.12-rc2 |
244 245 246 247 |
} if (value) { set_bit(index, &mousedev->packet.buttons); |
9657d75c5 Input: convert fr... |
248 |
set_bit(index, &mousedev_mix->packet.buttons); |
1da177e4c Linux-2.6.12-rc2 |
249 250 |
} else { clear_bit(index, &mousedev->packet.buttons); |
9657d75c5 Input: convert fr... |
251 |
clear_bit(index, &mousedev_mix->packet.buttons); |
1da177e4c Linux-2.6.12-rc2 |
252 253 |
} } |
464b24157 Input: mousedev -... |
254 255 |
static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_hw_data *packet) |
1da177e4c Linux-2.6.12-rc2 |
256 |
{ |
d0ffb9be8 Input: handlers -... |
257 |
struct mousedev_client *client; |
1da177e4c Linux-2.6.12-rc2 |
258 |
struct mousedev_motion *p; |
464b24157 Input: mousedev -... |
259 |
unsigned int new_head; |
8121152c1 Input: mousedev -... |
260 |
int wake_readers = 0; |
1da177e4c Linux-2.6.12-rc2 |
261 |
|
82ba56c27 Input: use full R... |
262 |
rcu_read_lock(); |
464b24157 Input: mousedev -... |
263 264 265 266 |
list_for_each_entry_rcu(client, &mousedev->client_list, node) { /* Just acquire the lock, interrupts already disabled */ spin_lock(&client->packet_lock); |
1da177e4c Linux-2.6.12-rc2 |
267 |
|
d0ffb9be8 Input: handlers -... |
268 269 |
p = &client->packets[client->head]; if (client->ready && p->buttons != mousedev->packet.buttons) { |
464b24157 Input: mousedev -... |
270 |
new_head = (client->head + 1) % PACKET_QUEUE_LEN; |
d0ffb9be8 Input: handlers -... |
271 272 |
if (new_head != client->tail) { p = &client->packets[client->head = new_head]; |
1da177e4c Linux-2.6.12-rc2 |
273 274 275 276 277 |
memset(p, 0, sizeof(struct mousedev_motion)); } } if (packet->abs_event) { |
d0ffb9be8 Input: handlers -... |
278 279 280 281 |
p->dx += packet->x - client->pos_x; p->dy += packet->y - client->pos_y; client->pos_x = packet->x; client->pos_y = packet->y; |
1da177e4c Linux-2.6.12-rc2 |
282 |
} |
d0ffb9be8 Input: handlers -... |
283 |
client->pos_x += packet->dx; |
464b24157 Input: mousedev -... |
284 285 |
client->pos_x = client->pos_x < 0 ? 0 : (client->pos_x >= xres ? xres : client->pos_x); |
d0ffb9be8 Input: handlers -... |
286 |
client->pos_y += packet->dy; |
464b24157 Input: mousedev -... |
287 288 |
client->pos_y = client->pos_y < 0 ? 0 : (client->pos_y >= yres ? yres : client->pos_y); |
1da177e4c Linux-2.6.12-rc2 |
289 290 291 292 293 |
p->dx += packet->dx; p->dy += packet->dy; p->dz += packet->dz; p->buttons = mousedev->packet.buttons; |
464b24157 Input: mousedev -... |
294 295 |
if (p->dx || p->dy || p->dz || p->buttons != client->last_buttons) |
d0ffb9be8 Input: handlers -... |
296 |
client->ready = 1; |
1da177e4c Linux-2.6.12-rc2 |
297 |
|
464b24157 Input: mousedev -... |
298 |
spin_unlock(&client->packet_lock); |
c1e4c8d3e [PATCH] fix jumpy... |
299 |
|
d0ffb9be8 Input: handlers -... |
300 301 |
if (client->ready) { kill_fasync(&client->fasync, SIGIO, POLL_IN); |
8121152c1 Input: mousedev -... |
302 303 |
wake_readers = 1; } |
1da177e4c Linux-2.6.12-rc2 |
304 |
} |
82ba56c27 Input: use full R... |
305 |
rcu_read_unlock(); |
1da177e4c Linux-2.6.12-rc2 |
306 |
|
8121152c1 Input: mousedev -... |
307 308 |
if (wake_readers) wake_up_interruptible(&mousedev->wait); |
1da177e4c Linux-2.6.12-rc2 |
309 310 311 312 313 314 |
} static void mousedev_touchpad_touch(struct mousedev *mousedev, int value) { if (!value) { if (mousedev->touch && |
464b24157 Input: mousedev -... |
315 316 |
time_before(jiffies, mousedev->touch + msecs_to_jiffies(tap_time))) { |
1da177e4c Linux-2.6.12-rc2 |
317 318 319 320 321 322 |
/* * Toggle left button to emulate tap. * We rely on the fact that mousedev_mix always has 0 * motion packet so we won't mess current position. */ set_bit(0, &mousedev->packet.buttons); |
9657d75c5 Input: convert fr... |
323 324 |
set_bit(0, &mousedev_mix->packet.buttons); mousedev_notify_readers(mousedev, &mousedev_mix->packet); |
464b24157 Input: mousedev -... |
325 326 |
mousedev_notify_readers(mousedev_mix, &mousedev_mix->packet); |
1da177e4c Linux-2.6.12-rc2 |
327 |
clear_bit(0, &mousedev->packet.buttons); |
9657d75c5 Input: convert fr... |
328 |
clear_bit(0, &mousedev_mix->packet.buttons); |
1da177e4c Linux-2.6.12-rc2 |
329 330 331 332 |
} mousedev->touch = mousedev->pkt_count = 0; mousedev->frac_dx = 0; mousedev->frac_dy = 0; |
1e0afb288 Input: fix format... |
333 334 335 |
} else if (!mousedev->touch) mousedev->touch = jiffies; |
1da177e4c Linux-2.6.12-rc2 |
336 |
} |
464b24157 Input: mousedev -... |
337 338 |
static void mousedev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) |
1da177e4c Linux-2.6.12-rc2 |
339 340 341 342 |
{ struct mousedev *mousedev = handle->private; switch (type) { |
1da177e4c Linux-2.6.12-rc2 |
343 |
|
464b24157 Input: mousedev -... |
344 345 346 347 |
case EV_ABS: /* Ignore joysticks */ if (test_bit(BTN_TRIGGER, handle->dev->keybit)) return; |
1da177e4c Linux-2.6.12-rc2 |
348 |
|
464b24157 Input: mousedev -... |
349 350 351 352 353 |
if (test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) mousedev_touchpad_event(handle->dev, mousedev, code, value); else mousedev_abs_event(handle->dev, mousedev, code, value); |
1da177e4c Linux-2.6.12-rc2 |
354 |
|
464b24157 Input: mousedev -... |
355 |
break; |
1da177e4c Linux-2.6.12-rc2 |
356 |
|
464b24157 Input: mousedev -... |
357 358 359 |
case EV_REL: mousedev_rel_event(mousedev, code, value); break; |
1da177e4c Linux-2.6.12-rc2 |
360 |
|
464b24157 Input: mousedev -... |
361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 |
case EV_KEY: if (value != 2) { if (code == BTN_TOUCH && test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) mousedev_touchpad_touch(mousedev, value); else mousedev_key_event(mousedev, code, value); } break; case EV_SYN: if (code == SYN_REPORT) { if (mousedev->touch) { mousedev->pkt_count++; /* * Input system eats duplicate events, * but we need all of them to do correct * averaging so apply present one forward */ fx(0) = fx(1); fy(0) = fy(1); |
1da177e4c Linux-2.6.12-rc2 |
382 |
} |
464b24157 Input: mousedev -... |
383 384 385 386 387 388 389 390 391 |
mousedev_notify_readers(mousedev, &mousedev->packet); mousedev_notify_readers(mousedev_mix, &mousedev->packet); mousedev->packet.dx = mousedev->packet.dy = mousedev->packet.dz = 0; mousedev->packet.abs_event = 0; } break; |
1da177e4c Linux-2.6.12-rc2 |
392 393 394 395 396 |
} } static int mousedev_fasync(int fd, struct file *file, int on) { |
d0ffb9be8 Input: handlers -... |
397 |
struct mousedev_client *client = file->private_data; |
1e0afb288 Input: fix format... |
398 |
|
60aa49243 Rationalize fasyn... |
399 |
return fasync_helper(fd, file, on, &client->fasync); |
1da177e4c Linux-2.6.12-rc2 |
400 |
} |
9657d75c5 Input: convert fr... |
401 |
static void mousedev_free(struct device *dev) |
1da177e4c Linux-2.6.12-rc2 |
402 |
{ |
9657d75c5 Input: convert fr... |
403 |
struct mousedev *mousedev = container_of(dev, struct mousedev, dev); |
a7097ff89 Input: make sure ... |
404 |
input_put_device(mousedev->handle.dev); |
1da177e4c Linux-2.6.12-rc2 |
405 406 |
kfree(mousedev); } |
464b24157 Input: mousedev -... |
407 |
static int mousedev_open_device(struct mousedev *mousedev) |
1da177e4c Linux-2.6.12-rc2 |
408 |
{ |
464b24157 Input: mousedev -... |
409 |
int retval; |
1da177e4c Linux-2.6.12-rc2 |
410 |
|
464b24157 Input: mousedev -... |
411 412 413 |
retval = mutex_lock_interruptible(&mousedev->mutex); if (retval) return retval; |
d542ed82f Input: handlers -... |
414 |
|
e4dbedc7e Input: mousedev -... |
415 |
if (!mousedev->exist) |
464b24157 Input: mousedev -... |
416 |
retval = -ENODEV; |
064450140 Input: fix open c... |
417 |
else if (!mousedev->open++) { |
464b24157 Input: mousedev -... |
418 |
retval = input_open_device(&mousedev->handle); |
064450140 Input: fix open c... |
419 420 421 |
if (retval) mousedev->open--; } |
d542ed82f Input: handlers -... |
422 |
|
464b24157 Input: mousedev -... |
423 424 |
mutex_unlock(&mousedev->mutex); return retval; |
d542ed82f Input: handlers -... |
425 |
} |
464b24157 Input: mousedev -... |
426 |
static void mousedev_close_device(struct mousedev *mousedev) |
d542ed82f Input: handlers -... |
427 |
{ |
464b24157 Input: mousedev -... |
428 |
mutex_lock(&mousedev->mutex); |
d542ed82f Input: handlers -... |
429 |
|
e4dbedc7e Input: mousedev -... |
430 |
if (mousedev->exist && !--mousedev->open) |
464b24157 Input: mousedev -... |
431 432 433 |
input_close_device(&mousedev->handle); mutex_unlock(&mousedev->mutex); |
d542ed82f Input: handlers -... |
434 |
} |
464b24157 Input: mousedev -... |
435 436 437 438 439 |
/* * Open all available devices so they can all be multiplexed in one. * stream. Note that this function is called with mousedev_mix->mutex * held. */ |
e4dbedc7e Input: mousedev -... |
440 |
static int mixdev_open_devices(struct mousedev *mixdev) |
d542ed82f Input: handlers -... |
441 |
{ |
e4dbedc7e Input: mousedev -... |
442 443 444 445 446 |
int error; error = mutex_lock_interruptible(&mixdev->mutex); if (error) return error; |
d542ed82f Input: handlers -... |
447 |
|
e4dbedc7e Input: mousedev -... |
448 449 |
if (!mixdev->open++) { struct mousedev *mousedev; |
9657d75c5 Input: convert fr... |
450 |
|
e4dbedc7e Input: mousedev -... |
451 452 453 454 |
list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) { if (!mousedev->opened_by_mixdev) { if (mousedev_open_device(mousedev)) continue; |
d542ed82f Input: handlers -... |
455 |
|
e4dbedc7e Input: mousedev -... |
456 457 |
mousedev->opened_by_mixdev = true; } |
1da177e4c Linux-2.6.12-rc2 |
458 459 |
} } |
e4dbedc7e Input: mousedev -... |
460 461 462 |
mutex_unlock(&mixdev->mutex); return 0; |
1da177e4c Linux-2.6.12-rc2 |
463 |
} |
464b24157 Input: mousedev -... |
464 465 466 467 468 |
/* * Close all devices that were opened as part of multiplexed * device. Note that this function is called with mousedev_mix->mutex * held. */ |
e4dbedc7e Input: mousedev -... |
469 |
static void mixdev_close_devices(struct mousedev *mixdev) |
1da177e4c Linux-2.6.12-rc2 |
470 |
{ |
e4dbedc7e Input: mousedev -... |
471 |
mutex_lock(&mixdev->mutex); |
d542ed82f Input: handlers -... |
472 |
|
e4dbedc7e Input: mousedev -... |
473 474 |
if (!--mixdev->open) { struct mousedev *mousedev; |
9657d75c5 Input: convert fr... |
475 |
|
e4dbedc7e Input: mousedev -... |
476 477 478 479 480 |
list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) { if (mousedev->opened_by_mixdev) { mousedev->opened_by_mixdev = false; mousedev_close_device(mousedev); } |
1da177e4c Linux-2.6.12-rc2 |
481 482 |
} } |
e4dbedc7e Input: mousedev -... |
483 484 |
mutex_unlock(&mixdev->mutex); |
1da177e4c Linux-2.6.12-rc2 |
485 |
} |
464b24157 Input: mousedev -... |
486 487 488 489 490 491 492 |
static void mousedev_attach_client(struct mousedev *mousedev, struct mousedev_client *client) { spin_lock(&mousedev->client_lock); list_add_tail_rcu(&client->node, &mousedev->client_list); spin_unlock(&mousedev->client_lock); |
464b24157 Input: mousedev -... |
493 494 495 496 497 498 499 500 |
} static void mousedev_detach_client(struct mousedev *mousedev, struct mousedev_client *client) { spin_lock(&mousedev->client_lock); list_del_rcu(&client->node); spin_unlock(&mousedev->client_lock); |
82ba56c27 Input: use full R... |
501 |
synchronize_rcu(); |
464b24157 Input: mousedev -... |
502 |
} |
d0ffb9be8 Input: handlers -... |
503 |
static int mousedev_release(struct inode *inode, struct file *file) |
1da177e4c Linux-2.6.12-rc2 |
504 |
{ |
d0ffb9be8 Input: handlers -... |
505 506 |
struct mousedev_client *client = file->private_data; struct mousedev *mousedev = client->mousedev; |
1da177e4c Linux-2.6.12-rc2 |
507 |
|
464b24157 Input: mousedev -... |
508 |
mousedev_detach_client(mousedev, client); |
d0ffb9be8 Input: handlers -... |
509 |
kfree(client); |
1da177e4c Linux-2.6.12-rc2 |
510 |
|
e4dbedc7e Input: mousedev -... |
511 |
mousedev->close_device(mousedev); |
1da177e4c Linux-2.6.12-rc2 |
512 |
|
1da177e4c Linux-2.6.12-rc2 |
513 514 |
return 0; } |
d0ffb9be8 Input: handlers -... |
515 |
static int mousedev_open(struct inode *inode, struct file *file) |
1da177e4c Linux-2.6.12-rc2 |
516 |
{ |
d0ffb9be8 Input: handlers -... |
517 |
struct mousedev_client *client; |
1da177e4c Linux-2.6.12-rc2 |
518 |
struct mousedev *mousedev; |
d542ed82f Input: handlers -... |
519 |
int error; |
1da177e4c Linux-2.6.12-rc2 |
520 521 522 |
#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX if (imajor(inode) == MISC_MAJOR) |
7f8d4cad1 Input: extend the... |
523 |
mousedev = mousedev_mix; |
1da177e4c Linux-2.6.12-rc2 |
524 525 |
else #endif |
7f8d4cad1 Input: extend the... |
526 |
mousedev = container_of(inode->i_cdev, struct mousedev, cdev); |
1da177e4c Linux-2.6.12-rc2 |
527 |
|
d0ffb9be8 Input: handlers -... |
528 |
client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL); |
7f8d4cad1 Input: extend the... |
529 530 |
if (!client) return -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
531 |
|
d0ffb9be8 Input: handlers -... |
532 533 534 535 |
spin_lock_init(&client->packet_lock); client->pos_x = xres / 2; client->pos_y = yres / 2; client->mousedev = mousedev; |
464b24157 Input: mousedev -... |
536 |
mousedev_attach_client(mousedev, client); |
1da177e4c Linux-2.6.12-rc2 |
537 |
|
e4dbedc7e Input: mousedev -... |
538 |
error = mousedev->open_device(mousedev); |
464b24157 Input: mousedev -... |
539 540 |
if (error) goto err_free_client; |
1da177e4c Linux-2.6.12-rc2 |
541 |
|
d0ffb9be8 Input: handlers -... |
542 |
file->private_data = client; |
0124be497 Input: mousedev -... |
543 |
nonseekable_open(inode, file); |
7f8d4cad1 Input: extend the... |
544 |
|
1da177e4c Linux-2.6.12-rc2 |
545 |
return 0; |
9657d75c5 Input: convert fr... |
546 547 |
err_free_client: |
464b24157 Input: mousedev -... |
548 |
mousedev_detach_client(mousedev, client); |
9657d75c5 Input: convert fr... |
549 |
kfree(client); |
9657d75c5 Input: convert fr... |
550 |
return error; |
1da177e4c Linux-2.6.12-rc2 |
551 552 553 554 555 556 |
} static inline int mousedev_limit_delta(int delta, int limit) { return delta > limit ? limit : (delta < -limit ? -limit : delta); } |
464b24157 Input: mousedev -... |
557 558 |
static void mousedev_packet(struct mousedev_client *client, signed char *ps2_data) |
1da177e4c Linux-2.6.12-rc2 |
559 |
{ |
464b24157 Input: mousedev -... |
560 |
struct mousedev_motion *p = &client->packets[client->tail]; |
1da177e4c Linux-2.6.12-rc2 |
561 |
|
464b24157 Input: mousedev -... |
562 563 |
ps2_data[0] = 0x08 | ((p->dx < 0) << 4) | ((p->dy < 0) << 5) | (p->buttons & 0x07); |
1da177e4c Linux-2.6.12-rc2 |
564 565 566 567 |
ps2_data[1] = mousedev_limit_delta(p->dx, 127); ps2_data[2] = mousedev_limit_delta(p->dy, 127); p->dx -= ps2_data[1]; p->dy -= ps2_data[2]; |
d0ffb9be8 Input: handlers -... |
568 |
switch (client->mode) { |
464b24157 Input: mousedev -... |
569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 |
case MOUSEDEV_EMUL_EXPS: ps2_data[3] = mousedev_limit_delta(p->dz, 7); p->dz -= ps2_data[3]; ps2_data[3] = (ps2_data[3] & 0x0f) | ((p->buttons & 0x18) << 1); client->bufsiz = 4; break; case MOUSEDEV_EMUL_IMPS: ps2_data[0] |= ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1); ps2_data[3] = mousedev_limit_delta(p->dz, 127); p->dz -= ps2_data[3]; client->bufsiz = 4; break; case MOUSEDEV_EMUL_PS2: default: ps2_data[0] |= ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1); p->dz = 0; client->bufsiz = 3; break; |
1da177e4c Linux-2.6.12-rc2 |
591 592 593 |
} if (!p->dx && !p->dy && !p->dz) { |
d0ffb9be8 Input: handlers -... |
594 595 596 |
if (client->tail == client->head) { client->ready = 0; client->last_buttons = p->buttons; |
c1e4c8d3e [PATCH] fix jumpy... |
597 |
} else |
d0ffb9be8 Input: handlers -... |
598 |
client->tail = (client->tail + 1) % PACKET_QUEUE_LEN; |
1da177e4c Linux-2.6.12-rc2 |
599 |
} |
1da177e4c Linux-2.6.12-rc2 |
600 |
} |
464b24157 Input: mousedev -... |
601 602 603 604 |
static void mousedev_generate_response(struct mousedev_client *client, int command) { client->ps2[0] = 0xfa; /* ACK */ |
1da177e4c Linux-2.6.12-rc2 |
605 |
|
464b24157 Input: mousedev -... |
606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 |
switch (command) { case 0xeb: /* Poll */ mousedev_packet(client, &client->ps2[1]); client->bufsiz++; /* account for leading ACK */ break; case 0xf2: /* Get ID */ switch (client->mode) { case MOUSEDEV_EMUL_PS2: client->ps2[1] = 0; break; case MOUSEDEV_EMUL_IMPS: client->ps2[1] = 3; break; case MOUSEDEV_EMUL_EXPS: client->ps2[1] = 4; break; } client->bufsiz = 2; break; case 0xe9: /* Get info */ client->ps2[1] = 0x60; client->ps2[2] = 3; client->ps2[3] = 200; client->bufsiz = 4; break; case 0xff: /* Reset */ client->impsseq = client->imexseq = 0; client->mode = MOUSEDEV_EMUL_PS2; client->ps2[1] = 0xaa; client->ps2[2] = 0x00; client->bufsiz = 3; break; default: client->bufsiz = 1; break; } client->buffer = client->bufsiz; } static ssize_t mousedev_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) |
1da177e4c Linux-2.6.12-rc2 |
649 |
{ |
d0ffb9be8 Input: handlers -... |
650 |
struct mousedev_client *client = file->private_data; |
1da177e4c Linux-2.6.12-rc2 |
651 652 653 654 655 656 657 |
unsigned char c; unsigned int i; for (i = 0; i < count; i++) { if (get_user(c, buffer + i)) return -EFAULT; |
464b24157 Input: mousedev -... |
658 |
spin_lock_irq(&client->packet_lock); |
d0ffb9be8 Input: handlers -... |
659 660 661 662 |
if (c == mousedev_imex_seq[client->imexseq]) { if (++client->imexseq == MOUSEDEV_SEQ_LEN) { client->imexseq = 0; client->mode = MOUSEDEV_EMUL_EXPS; |
1da177e4c Linux-2.6.12-rc2 |
663 |
} |
1e0afb288 Input: fix format... |
664 |
} else |
d0ffb9be8 Input: handlers -... |
665 |
client->imexseq = 0; |
1da177e4c Linux-2.6.12-rc2 |
666 |
|
d0ffb9be8 Input: handlers -... |
667 668 669 670 |
if (c == mousedev_imps_seq[client->impsseq]) { if (++client->impsseq == MOUSEDEV_SEQ_LEN) { client->impsseq = 0; client->mode = MOUSEDEV_EMUL_IMPS; |
1da177e4c Linux-2.6.12-rc2 |
671 |
} |
1e0afb288 Input: fix format... |
672 |
} else |
d0ffb9be8 Input: handlers -... |
673 |
client->impsseq = 0; |
1da177e4c Linux-2.6.12-rc2 |
674 |
|
464b24157 Input: mousedev -... |
675 |
mousedev_generate_response(client, c); |
1da177e4c Linux-2.6.12-rc2 |
676 |
|
464b24157 Input: mousedev -... |
677 |
spin_unlock_irq(&client->packet_lock); |
1da177e4c Linux-2.6.12-rc2 |
678 |
} |
d0ffb9be8 Input: handlers -... |
679 |
kill_fasync(&client->fasync, SIGIO, POLL_IN); |
d0ffb9be8 Input: handlers -... |
680 |
wake_up_interruptible(&client->mousedev->wait); |
1da177e4c Linux-2.6.12-rc2 |
681 682 683 |
return count; } |
464b24157 Input: mousedev -... |
684 685 |
static ssize_t mousedev_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) |
1da177e4c Linux-2.6.12-rc2 |
686 |
{ |
d0ffb9be8 Input: handlers -... |
687 |
struct mousedev_client *client = file->private_data; |
464b24157 Input: mousedev -... |
688 689 |
struct mousedev *mousedev = client->mousedev; signed char data[sizeof(client->ps2)]; |
1da177e4c Linux-2.6.12-rc2 |
690 |
int retval = 0; |
464b24157 Input: mousedev -... |
691 692 |
if (!client->ready && !client->buffer && mousedev->exist && (file->f_flags & O_NONBLOCK)) |
1da177e4c Linux-2.6.12-rc2 |
693 |
return -EAGAIN; |
464b24157 Input: mousedev -... |
694 695 |
retval = wait_event_interruptible(mousedev->wait, !mousedev->exist || client->ready || client->buffer); |
1da177e4c Linux-2.6.12-rc2 |
696 697 |
if (retval) return retval; |
464b24157 Input: mousedev -... |
698 |
if (!mousedev->exist) |
1da177e4c Linux-2.6.12-rc2 |
699 |
return -ENODEV; |
464b24157 Input: mousedev -... |
700 |
spin_lock_irq(&client->packet_lock); |
d0ffb9be8 Input: handlers -... |
701 702 703 |
if (!client->buffer && client->ready) { mousedev_packet(client, client->ps2); client->buffer = client->bufsiz; |
1da177e4c Linux-2.6.12-rc2 |
704 |
} |
d0ffb9be8 Input: handlers -... |
705 706 |
if (count > client->buffer) count = client->buffer; |
1da177e4c Linux-2.6.12-rc2 |
707 |
|
464b24157 Input: mousedev -... |
708 |
memcpy(data, client->ps2 + client->bufsiz - client->buffer, count); |
d0ffb9be8 Input: handlers -... |
709 |
client->buffer -= count; |
1da177e4c Linux-2.6.12-rc2 |
710 |
|
464b24157 Input: mousedev -... |
711 712 713 |
spin_unlock_irq(&client->packet_lock); if (copy_to_user(buffer, data, count)) |
1da177e4c Linux-2.6.12-rc2 |
714 715 716 717 718 719 720 721 |
return -EFAULT; return count; } /* No kernel lock - fine */ static unsigned int mousedev_poll(struct file *file, poll_table *wait) { |
d0ffb9be8 Input: handlers -... |
722 723 |
struct mousedev_client *client = file->private_data; struct mousedev *mousedev = client->mousedev; |
4d4bf995e Input: mousedev -... |
724 |
unsigned int mask; |
1e0afb288 Input: fix format... |
725 |
|
d0ffb9be8 Input: handlers -... |
726 |
poll_wait(file, &mousedev->wait, wait); |
4d4bf995e Input: mousedev -... |
727 728 729 730 731 732 |
mask = mousedev->exist ? POLLOUT | POLLWRNORM : POLLHUP | POLLERR; if (client->ready || client->buffer) mask |= POLLIN | POLLRDNORM; return mask; |
1da177e4c Linux-2.6.12-rc2 |
733 |
} |
66e661188 Input: constify i... |
734 |
static const struct file_operations mousedev_fops = { |
1c74585ec Input: mousedev -... |
735 736 737 738 739 740 741 742 |
.owner = THIS_MODULE, .read = mousedev_read, .write = mousedev_write, .poll = mousedev_poll, .open = mousedev_open, .release = mousedev_release, .fasync = mousedev_fasync, .llseek = noop_llseek, |
1da177e4c Linux-2.6.12-rc2 |
743 |
}; |
464b24157 Input: mousedev -... |
744 745 746 747 748 749 750 751 |
/* * Mark device non-existent. This disables writes, ioctls and * prevents new users from opening the device. Already posted * blocking reads will stay, however new ones will fail. */ static void mousedev_mark_dead(struct mousedev *mousedev) { mutex_lock(&mousedev->mutex); |
20da92de8 Input: change inp... |
752 |
mousedev->exist = false; |
464b24157 Input: mousedev -... |
753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 |
mutex_unlock(&mousedev->mutex); } /* * Wake up users waiting for IO so they can disconnect from * dead device. */ static void mousedev_hangup(struct mousedev *mousedev) { struct mousedev_client *client; spin_lock(&mousedev->client_lock); list_for_each_entry(client, &mousedev->client_list, node) kill_fasync(&client->fasync, SIGIO, POLL_HUP); spin_unlock(&mousedev->client_lock); wake_up_interruptible(&mousedev->wait); } static void mousedev_cleanup(struct mousedev *mousedev) { struct input_handle *handle = &mousedev->handle; mousedev_mark_dead(mousedev); mousedev_hangup(mousedev); |
7f8d4cad1 Input: extend the... |
778 779 |
cdev_del(&mousedev->cdev); |
464b24157 Input: mousedev -... |
780 781 782 783 784 |
/* mousedev is marked dead so no one else accesses mousedev->open */ if (mousedev->open) input_close_device(handle); } |
7f8d4cad1 Input: extend the... |
785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 |
static int mousedev_reserve_minor(bool mixdev) { int minor; if (mixdev) { minor = input_get_new_minor(MOUSEDEV_MIX, 1, false); if (minor < 0) pr_err("failed to reserve mixdev minor: %d ", minor); } else { minor = input_get_new_minor(MOUSEDEV_MINOR_BASE, MOUSEDEV_MINORS, true); if (minor < 0) pr_err("failed to reserve new minor: %d ", minor); } return minor; } |
9657d75c5 Input: convert fr... |
804 805 |
static struct mousedev *mousedev_create(struct input_dev *dev, struct input_handler *handler, |
7f8d4cad1 Input: extend the... |
806 |
bool mixdev) |
1da177e4c Linux-2.6.12-rc2 |
807 808 |
{ struct mousedev *mousedev; |
7f8d4cad1 Input: extend the... |
809 |
int minor; |
5b2a08262 Input: rework han... |
810 |
int error; |
1da177e4c Linux-2.6.12-rc2 |
811 |
|
7f8d4cad1 Input: extend the... |
812 813 814 815 816 |
minor = mousedev_reserve_minor(mixdev); if (minor < 0) { error = minor; goto err_out; } |
5b2a08262 Input: rework han... |
817 |
mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL); |
9657d75c5 Input: convert fr... |
818 819 |
if (!mousedev) { error = -ENOMEM; |
7f8d4cad1 Input: extend the... |
820 |
goto err_free_minor; |
9657d75c5 Input: convert fr... |
821 |
} |
1da177e4c Linux-2.6.12-rc2 |
822 |
|
d0ffb9be8 Input: handlers -... |
823 |
INIT_LIST_HEAD(&mousedev->client_list); |
5b2a08262 Input: rework han... |
824 |
INIT_LIST_HEAD(&mousedev->mixdev_node); |
464b24157 Input: mousedev -... |
825 826 827 |
spin_lock_init(&mousedev->client_lock); mutex_init(&mousedev->mutex); lockdep_set_subclass(&mousedev->mutex, |
7f8d4cad1 Input: extend the... |
828 |
mixdev ? SINGLE_DEPTH_NESTING : 0); |
1da177e4c Linux-2.6.12-rc2 |
829 |
init_waitqueue_head(&mousedev->wait); |
7f8d4cad1 Input: extend the... |
830 |
if (mixdev) { |
3d5cb60ef Input: simplify n... |
831 |
dev_set_name(&mousedev->dev, "mice"); |
e4dbedc7e Input: mousedev -... |
832 833 834 |
mousedev->open_device = mixdev_open_devices; mousedev->close_device = mixdev_close_devices; |
7f8d4cad1 Input: extend the... |
835 836 837 838 839 840 |
} else { int dev_no = minor; /* Normalize device number if it falls into legacy range */ if (dev_no < MOUSEDEV_MINOR_BASE + MOUSEDEV_MINORS) dev_no -= MOUSEDEV_MINOR_BASE; dev_set_name(&mousedev->dev, "mouse%d", dev_no); |
e4dbedc7e Input: mousedev -... |
841 842 843 |
mousedev->open_device = mousedev_open_device; mousedev->close_device = mousedev_close_device; |
7f8d4cad1 Input: extend the... |
844 |
} |
9657d75c5 Input: convert fr... |
845 |
|
20da92de8 Input: change inp... |
846 |
mousedev->exist = true; |
a7097ff89 Input: make sure ... |
847 |
mousedev->handle.dev = input_get_device(dev); |
3d5cb60ef Input: simplify n... |
848 |
mousedev->handle.name = dev_name(&mousedev->dev); |
1da177e4c Linux-2.6.12-rc2 |
849 850 |
mousedev->handle.handler = handler; mousedev->handle.private = mousedev; |
1da177e4c Linux-2.6.12-rc2 |
851 |
|
9657d75c5 Input: convert fr... |
852 853 854 |
mousedev->dev.class = &input_class; if (dev) mousedev->dev.parent = &dev->dev; |
7f8d4cad1 Input: extend the... |
855 |
mousedev->dev.devt = MKDEV(INPUT_MAJOR, minor); |
9657d75c5 Input: convert fr... |
856 857 |
mousedev->dev.release = mousedev_free; device_initialize(&mousedev->dev); |
1da177e4c Linux-2.6.12-rc2 |
858 |
|
7f8d4cad1 Input: extend the... |
859 |
if (!mixdev) { |
464b24157 Input: mousedev -... |
860 861 862 863 |
error = input_register_handle(&mousedev->handle); if (error) goto err_free_mousedev; } |
7f8d4cad1 Input: extend the... |
864 |
cdev_init(&mousedev->cdev, &mousedev_fops); |
4a215aade Input: fix use-af... |
865 |
mousedev->cdev.kobj.parent = &mousedev->dev.kobj; |
7f8d4cad1 Input: extend the... |
866 |
error = cdev_add(&mousedev->cdev, mousedev->dev.devt, 1); |
464b24157 Input: mousedev -... |
867 868 |
if (error) goto err_unregister_handle; |
5b2a08262 Input: rework han... |
869 |
|
9657d75c5 Input: convert fr... |
870 871 |
error = device_add(&mousedev->dev); if (error) |
464b24157 Input: mousedev -... |
872 |
goto err_cleanup_mousedev; |
9657d75c5 Input: convert fr... |
873 874 |
return mousedev; |
464b24157 Input: mousedev -... |
875 876 877 |
err_cleanup_mousedev: mousedev_cleanup(mousedev); err_unregister_handle: |
7f8d4cad1 Input: extend the... |
878 |
if (!mixdev) |
464b24157 Input: mousedev -... |
879 |
input_unregister_handle(&mousedev->handle); |
9657d75c5 Input: convert fr... |
880 881 |
err_free_mousedev: put_device(&mousedev->dev); |
7f8d4cad1 Input: extend the... |
882 883 |
err_free_minor: input_free_minor(minor); |
9657d75c5 Input: convert fr... |
884 885 886 887 888 889 |
err_out: return ERR_PTR(error); } static void mousedev_destroy(struct mousedev *mousedev) { |
9657d75c5 Input: convert fr... |
890 |
device_del(&mousedev->dev); |
464b24157 Input: mousedev -... |
891 |
mousedev_cleanup(mousedev); |
7f8d4cad1 Input: extend the... |
892 |
input_free_minor(MINOR(mousedev->dev.devt)); |
e4dbedc7e Input: mousedev -... |
893 |
if (mousedev != mousedev_mix) |
464b24157 Input: mousedev -... |
894 895 896 |
input_unregister_handle(&mousedev->handle); put_device(&mousedev->dev); } |
9657d75c5 Input: convert fr... |
897 |
|
464b24157 Input: mousedev -... |
898 899 900 901 902 903 904 905 906 907 908 909 |
static int mixdev_add_device(struct mousedev *mousedev) { int retval; retval = mutex_lock_interruptible(&mousedev_mix->mutex); if (retval) return retval; if (mousedev_mix->open) { retval = mousedev_open_device(mousedev); if (retval) goto out; |
3376b8b75 Input: mousedev -... |
910 |
mousedev->opened_by_mixdev = true; |
5b2a08262 Input: rework han... |
911 |
} |
c9bcd582d [PATCH] INPUT: Cr... |
912 |
|
464b24157 Input: mousedev -... |
913 914 915 916 917 918 919 920 921 922 923 |
get_device(&mousedev->dev); list_add_tail(&mousedev->mixdev_node, &mousedev_mix_list); out: mutex_unlock(&mousedev_mix->mutex); return retval; } static void mixdev_remove_device(struct mousedev *mousedev) { mutex_lock(&mousedev_mix->mutex); |
3376b8b75 Input: mousedev -... |
924 925 |
if (mousedev->opened_by_mixdev) { mousedev->opened_by_mixdev = false; |
464b24157 Input: mousedev -... |
926 927 928 929 930 |
mousedev_close_device(mousedev); } list_del_init(&mousedev->mixdev_node); mutex_unlock(&mousedev_mix->mutex); |
9657d75c5 Input: convert fr... |
931 932 |
put_device(&mousedev->dev); } |
464b24157 Input: mousedev -... |
933 934 |
static int mousedev_connect(struct input_handler *handler, struct input_dev *dev, |
9657d75c5 Input: convert fr... |
935 936 937 |
const struct input_device_id *id) { struct mousedev *mousedev; |
9657d75c5 Input: convert fr... |
938 |
int error; |
7f8d4cad1 Input: extend the... |
939 |
mousedev = mousedev_create(dev, handler, false); |
9657d75c5 Input: convert fr... |
940 941 |
if (IS_ERR(mousedev)) return PTR_ERR(mousedev); |
5b2a08262 Input: rework han... |
942 |
|
d542ed82f Input: handlers -... |
943 |
error = mixdev_add_device(mousedev); |
464b24157 Input: mousedev -... |
944 945 946 947 |
if (error) { mousedev_destroy(mousedev); return error; } |
1da177e4c Linux-2.6.12-rc2 |
948 |
|
5b2a08262 Input: rework han... |
949 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
950 951 952 953 954 |
} static void mousedev_disconnect(struct input_handle *handle) { struct mousedev *mousedev = handle->private; |
1da177e4c Linux-2.6.12-rc2 |
955 |
|
d542ed82f Input: handlers -... |
956 |
mixdev_remove_device(mousedev); |
9657d75c5 Input: convert fr... |
957 |
mousedev_destroy(mousedev); |
1da177e4c Linux-2.6.12-rc2 |
958 |
} |
66e661188 Input: constify i... |
959 |
static const struct input_device_id mousedev_ids[] = { |
1da177e4c Linux-2.6.12-rc2 |
960 |
{ |
464b24157 Input: mousedev -... |
961 962 963 |
.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_RELBIT, |
7b19ada2e get rid of input ... |
964 965 966 |
.evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) }, .keybit = { [BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) }, .relbit = { BIT_MASK(REL_X) | BIT_MASK(REL_Y) }, |
464b24157 Input: mousedev -... |
967 968 |
}, /* A mouse like device, at least one button, two relative axes */ |
1da177e4c Linux-2.6.12-rc2 |
969 |
{ |
464b24157 Input: mousedev -... |
970 971 |
.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_RELBIT, |
7b19ada2e get rid of input ... |
972 973 |
.evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) }, .relbit = { BIT_MASK(REL_WHEEL) }, |
1da177e4c Linux-2.6.12-rc2 |
974 975 |
}, /* A separate scrollwheel */ { |
464b24157 Input: mousedev -... |
976 977 978 |
.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_ABSBIT, |
7b19ada2e get rid of input ... |
979 980 981 |
.evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) }, .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) }, .absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) }, |
464b24157 Input: mousedev -... |
982 983 |
}, /* A tablet like device, at least touch detection, two absolute axes */ |
1da177e4c Linux-2.6.12-rc2 |
984 |
{ |
464b24157 Input: mousedev -... |
985 986 987 |
.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_ABSBIT, |
7b19ada2e get rid of input ... |
988 989 990 991 992 993 |
.evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) }, .keybit = { [BIT_WORD(BTN_TOOL_FINGER)] = BIT_MASK(BTN_TOOL_FINGER) }, .absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | BIT_MASK(ABS_PRESSURE) | BIT_MASK(ABS_TOOL_WIDTH) }, |
1da177e4c Linux-2.6.12-rc2 |
994 |
}, /* A touchpad */ |
6724f9346 Input: mousedev -... |
995 996 997 998 |
{ .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_ABSBIT, |
d182c10c8 Input: mousedev -... |
999 |
.evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) }, |
6724f9346 Input: mousedev -... |
1000 1001 1002 1003 |
.keybit = { [BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) }, .absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) }, }, /* Mouse-like device with absolute X and Y but ordinary clicks, like hp ILO2 High Performance mouse */ |
1da177e4c Linux-2.6.12-rc2 |
1004 |
|
d0ffb9be8 Input: handlers -... |
1005 |
{ }, /* Terminating entry */ |
1da177e4c Linux-2.6.12-rc2 |
1006 1007 1008 1009 1010 |
}; MODULE_DEVICE_TABLE(input, mousedev_ids); static struct input_handler mousedev_handler = { |
1c74585ec Input: mousedev -... |
1011 1012 1013 |
.event = mousedev_event, .connect = mousedev_connect, .disconnect = mousedev_disconnect, |
7f8d4cad1 Input: extend the... |
1014 |
.legacy_minors = true, |
1c74585ec Input: mousedev -... |
1015 1016 1017 |
.minor = MOUSEDEV_MINOR_BASE, .name = "mousedev", .id_table = mousedev_ids, |
1da177e4c Linux-2.6.12-rc2 |
1018 1019 1020 |
}; #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX |
a2cb1191f Input: mousedev -... |
1021 |
#include <linux/miscdevice.h> |
1da177e4c Linux-2.6.12-rc2 |
1022 |
static struct miscdevice psaux_mouse = { |
a2cb1191f Input: mousedev -... |
1023 1024 1025 |
.minor = PSMOUSE_MINOR, .name = "psaux", .fops = &mousedev_fops, |
1da177e4c Linux-2.6.12-rc2 |
1026 |
}; |
a2cb1191f Input: mousedev -... |
1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 |
static bool psaux_registered; static void __init mousedev_psaux_register(void) { int error; error = misc_register(&psaux_mouse); if (error) pr_warn("could not register psaux device, error: %d ", error); else psaux_registered = true; } static void __exit mousedev_psaux_unregister(void) { if (psaux_registered) misc_deregister(&psaux_mouse); } #else static inline void mousedev_psaux_register(void) { } static inline void mousedev_psaux_unregister(void) { } |
1da177e4c Linux-2.6.12-rc2 |
1051 1052 1053 1054 |
#endif static int __init mousedev_init(void) { |
4263cf0fa Input: make input... |
1055 |
int error; |
7f8d4cad1 Input: extend the... |
1056 |
mousedev_mix = mousedev_create(NULL, &mousedev_handler, true); |
9657d75c5 Input: convert fr... |
1057 1058 |
if (IS_ERR(mousedev_mix)) return PTR_ERR(mousedev_mix); |
4263cf0fa Input: make input... |
1059 |
error = input_register_handler(&mousedev_handler); |
9657d75c5 Input: convert fr... |
1060 1061 |
if (error) { mousedev_destroy(mousedev_mix); |
4263cf0fa Input: make input... |
1062 |
return error; |
4263cf0fa Input: make input... |
1063 |
} |
1da177e4c Linux-2.6.12-rc2 |
1064 |
|
a2cb1191f Input: mousedev -... |
1065 |
mousedev_psaux_register(); |
1da177e4c Linux-2.6.12-rc2 |
1066 |
|
da0c49011 Input: use pr_fmt... |
1067 1068 |
pr_info("PS/2 mouse device common for all mice "); |
1da177e4c Linux-2.6.12-rc2 |
1069 1070 1071 1072 1073 1074 |
return 0; } static void __exit mousedev_exit(void) { |
a2cb1191f Input: mousedev -... |
1075 |
mousedev_psaux_unregister(); |
1da177e4c Linux-2.6.12-rc2 |
1076 |
input_unregister_handler(&mousedev_handler); |
9657d75c5 Input: convert fr... |
1077 |
mousedev_destroy(mousedev_mix); |
1da177e4c Linux-2.6.12-rc2 |
1078 1079 1080 1081 |
} module_init(mousedev_init); module_exit(mousedev_exit); |