diff options
Diffstat (limited to 'drivers/input/mouse')
26 files changed, 1219 insertions, 608 deletions
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index 8a2c5b14c8d8..3feeb3af8abd 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig | |||
| @@ -107,6 +107,14 @@ config MOUSE_PS2_ELANTECH | |||
| 107 | entries. For further information, | 107 | entries. For further information, |
| 108 | see <file:Documentation/input/elantech.txt>. | 108 | see <file:Documentation/input/elantech.txt>. |
| 109 | 109 | ||
| 110 | config MOUSE_PS2_SENTELIC | ||
| 111 | bool "Sentelic Finger Sensing Pad PS/2 protocol extension" | ||
| 112 | depends on MOUSE_PS2 | ||
| 113 | help | ||
| 114 | Say Y here if you have a laptop (such as MSI WIND Netbook) | ||
| 115 | with Sentelic Finger Sensing Pad touchpad. | ||
| 116 | |||
| 117 | If unsure, say N. | ||
| 110 | 118 | ||
| 111 | config MOUSE_PS2_TOUCHKIT | 119 | config MOUSE_PS2_TOUCHKIT |
| 112 | bool "eGalax TouchKit PS/2 protocol extension" | 120 | bool "eGalax TouchKit PS/2 protocol extension" |
| @@ -262,14 +270,6 @@ config MOUSE_VSXXXAA | |||
| 262 | described in the source file). This driver also works with the | 270 | described in the source file). This driver also works with the |
| 263 | digitizer (VSXXX-AB) DEC produced. | 271 | digitizer (VSXXX-AB) DEC produced. |
| 264 | 272 | ||
| 265 | config MOUSE_HIL | ||
| 266 | tristate "HIL pointers (mice etc)." | ||
| 267 | depends on GSC || HP300 | ||
| 268 | select HP_SDC | ||
| 269 | select HIL_MLC | ||
| 270 | help | ||
| 271 | Say Y here to support HIL pointers. | ||
| 272 | |||
| 273 | config MOUSE_GPIO | 273 | config MOUSE_GPIO |
| 274 | tristate "GPIO mouse" | 274 | tristate "GPIO mouse" |
| 275 | depends on GENERIC_GPIO | 275 | depends on GENERIC_GPIO |
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile index 010f265ec152..570c84a4a654 100644 --- a/drivers/input/mouse/Makefile +++ b/drivers/input/mouse/Makefile | |||
| @@ -9,7 +9,6 @@ obj-$(CONFIG_MOUSE_APPLETOUCH) += appletouch.o | |||
| 9 | obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o | 9 | obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o |
| 10 | obj-$(CONFIG_MOUSE_BCM5974) += bcm5974.o | 10 | obj-$(CONFIG_MOUSE_BCM5974) += bcm5974.o |
| 11 | obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o | 11 | obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o |
| 12 | obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o | ||
| 13 | obj-$(CONFIG_MOUSE_INPORT) += inport.o | 12 | obj-$(CONFIG_MOUSE_INPORT) += inport.o |
| 14 | obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o | 13 | obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o |
| 15 | obj-$(CONFIG_MOUSE_MAPLE) += maplemouse.o | 14 | obj-$(CONFIG_MOUSE_MAPLE) += maplemouse.o |
| @@ -28,5 +27,6 @@ psmouse-$(CONFIG_MOUSE_PS2_ELANTECH) += elantech.o | |||
| 28 | psmouse-$(CONFIG_MOUSE_PS2_OLPC) += hgpk.o | 27 | psmouse-$(CONFIG_MOUSE_PS2_OLPC) += hgpk.o |
| 29 | psmouse-$(CONFIG_MOUSE_PS2_LOGIPS2PP) += logips2pp.o | 28 | psmouse-$(CONFIG_MOUSE_PS2_LOGIPS2PP) += logips2pp.o |
| 30 | psmouse-$(CONFIG_MOUSE_PS2_LIFEBOOK) += lifebook.o | 29 | psmouse-$(CONFIG_MOUSE_PS2_LIFEBOOK) += lifebook.o |
| 30 | psmouse-$(CONFIG_MOUSE_PS2_SENTELIC) += sentelic.o | ||
| 31 | psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o | 31 | psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o |
| 32 | psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT) += touchkit_ps2.o | 32 | psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT) += touchkit_ps2.o |
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 5547e2429fbe..f36110689aae 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
| @@ -279,7 +279,7 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int | |||
| 279 | * subsequent commands. It looks like glidepad is behind stickpointer, | 279 | * subsequent commands. It looks like glidepad is behind stickpointer, |
| 280 | * I'd thought it would be other way around... | 280 | * I'd thought it would be other way around... |
| 281 | */ | 281 | */ |
| 282 | static int alps_passthrough_mode(struct psmouse *psmouse, int enable) | 282 | static int alps_passthrough_mode(struct psmouse *psmouse, bool enable) |
| 283 | { | 283 | { |
| 284 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 284 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
| 285 | int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11; | 285 | int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11; |
| @@ -367,16 +367,16 @@ static int alps_poll(struct psmouse *psmouse) | |||
| 367 | { | 367 | { |
| 368 | struct alps_data *priv = psmouse->private; | 368 | struct alps_data *priv = psmouse->private; |
| 369 | unsigned char buf[6]; | 369 | unsigned char buf[6]; |
| 370 | int poll_failed; | 370 | bool poll_failed; |
| 371 | 371 | ||
| 372 | if (priv->i->flags & ALPS_PASS) | 372 | if (priv->i->flags & ALPS_PASS) |
| 373 | alps_passthrough_mode(psmouse, 1); | 373 | alps_passthrough_mode(psmouse, true); |
| 374 | 374 | ||
| 375 | poll_failed = ps2_command(&psmouse->ps2dev, buf, | 375 | poll_failed = ps2_command(&psmouse->ps2dev, buf, |
| 376 | PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)) < 0; | 376 | PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)) < 0; |
| 377 | 377 | ||
| 378 | if (priv->i->flags & ALPS_PASS) | 378 | if (priv->i->flags & ALPS_PASS) |
| 379 | alps_passthrough_mode(psmouse, 0); | 379 | alps_passthrough_mode(psmouse, false); |
| 380 | 380 | ||
| 381 | if (poll_failed || (buf[0] & priv->i->mask0) != priv->i->byte0) | 381 | if (poll_failed || (buf[0] & priv->i->mask0) != priv->i->byte0) |
| 382 | return -1; | 382 | return -1; |
| @@ -401,10 +401,12 @@ static int alps_hw_init(struct psmouse *psmouse, int *version) | |||
| 401 | if (!priv->i) | 401 | if (!priv->i) |
| 402 | return -1; | 402 | return -1; |
| 403 | 403 | ||
| 404 | if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1)) | 404 | if ((priv->i->flags & ALPS_PASS) && |
| 405 | alps_passthrough_mode(psmouse, true)) { | ||
| 405 | return -1; | 406 | return -1; |
| 407 | } | ||
| 406 | 408 | ||
| 407 | if (alps_tap_mode(psmouse, 1)) { | 409 | if (alps_tap_mode(psmouse, true)) { |
| 408 | printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n"); | 410 | printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n"); |
| 409 | return -1; | 411 | return -1; |
| 410 | } | 412 | } |
| @@ -414,8 +416,10 @@ static int alps_hw_init(struct psmouse *psmouse, int *version) | |||
| 414 | return -1; | 416 | return -1; |
| 415 | } | 417 | } |
| 416 | 418 | ||
| 417 | if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 0)) | 419 | if ((priv->i->flags & ALPS_PASS) && |
| 420 | alps_passthrough_mode(psmouse, false)) { | ||
| 418 | return -1; | 421 | return -1; |
| 422 | } | ||
| 419 | 423 | ||
| 420 | /* ALPS needs stream mode, otherwise it won't report any data */ | 424 | /* ALPS needs stream mode, otherwise it won't report any data */ |
| 421 | if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM)) { | 425 | if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM)) { |
| @@ -519,7 +523,7 @@ init_fail: | |||
| 519 | return -1; | 523 | return -1; |
| 520 | } | 524 | } |
| 521 | 525 | ||
| 522 | int alps_detect(struct psmouse *psmouse, int set_properties) | 526 | int alps_detect(struct psmouse *psmouse, bool set_properties) |
| 523 | { | 527 | { |
| 524 | int version; | 528 | int version; |
| 525 | const struct alps_model_info *model; | 529 | const struct alps_model_info *model; |
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h index 4bbddc99962b..bc87936fee1a 100644 --- a/drivers/input/mouse/alps.h +++ b/drivers/input/mouse/alps.h | |||
| @@ -26,10 +26,10 @@ struct alps_data { | |||
| 26 | }; | 26 | }; |
| 27 | 27 | ||
| 28 | #ifdef CONFIG_MOUSE_PS2_ALPS | 28 | #ifdef CONFIG_MOUSE_PS2_ALPS |
| 29 | int alps_detect(struct psmouse *psmouse, int set_properties); | 29 | int alps_detect(struct psmouse *psmouse, bool set_properties); |
| 30 | int alps_init(struct psmouse *psmouse); | 30 | int alps_init(struct psmouse *psmouse); |
| 31 | #else | 31 | #else |
| 32 | inline int alps_detect(struct psmouse *psmouse, int set_properties) | 32 | inline int alps_detect(struct psmouse *psmouse, bool set_properties) |
| 33 | { | 33 | { |
| 34 | return -ENOSYS; | 34 | return -ENOSYS; |
| 35 | } | 35 | } |
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index 2d8fc0bf6923..0d1d33468b43 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c | |||
| @@ -317,7 +317,7 @@ static int report_tp_state(struct bcm5974 *dev, int size) | |||
| 317 | const struct tp_finger *f; | 317 | const struct tp_finger *f; |
| 318 | struct input_dev *input = dev->input; | 318 | struct input_dev *input = dev->input; |
| 319 | int raw_p, raw_w, raw_x, raw_y, raw_n; | 319 | int raw_p, raw_w, raw_x, raw_y, raw_n; |
| 320 | int ptest = 0, origin = 0, ibt = 0, nmin = 0, nmax = 0; | 320 | int ptest, origin, ibt = 0, nmin = 0, nmax = 0; |
| 321 | int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0; | 321 | int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0; |
| 322 | 322 | ||
| 323 | if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0) | 323 | if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0) |
| @@ -345,21 +345,22 @@ static int report_tp_state(struct bcm5974 *dev, int size) | |||
| 345 | /* set the integrated button if applicable */ | 345 | /* set the integrated button if applicable */ |
| 346 | if (c->tp_type == TYPE2) | 346 | if (c->tp_type == TYPE2) |
| 347 | ibt = raw2int(dev->tp_data[BUTTON_TYPE2]); | 347 | ibt = raw2int(dev->tp_data[BUTTON_TYPE2]); |
| 348 | } | ||
| 349 | 348 | ||
| 350 | /* while tracking finger still valid, count all fingers */ | 349 | /* while tracking finger still valid, count all fingers */ |
| 351 | if (ptest > PRESSURE_LOW && origin) { | 350 | if (ptest > PRESSURE_LOW && origin) { |
| 352 | abs_p = ptest; | 351 | abs_p = ptest; |
| 353 | abs_w = int2bound(&c->w, raw_w); | 352 | abs_w = int2bound(&c->w, raw_w); |
| 354 | abs_x = int2bound(&c->x, raw_x - c->x.devmin); | 353 | abs_x = int2bound(&c->x, raw_x - c->x.devmin); |
| 355 | abs_y = int2bound(&c->y, c->y.devmax - raw_y); | 354 | abs_y = int2bound(&c->y, c->y.devmax - raw_y); |
| 356 | while (raw_n--) { | 355 | while (raw_n--) { |
| 357 | ptest = int2bound(&c->p, raw2int(f->force_major)); | 356 | ptest = int2bound(&c->p, |
| 358 | if (ptest > PRESSURE_LOW) | 357 | raw2int(f->force_major)); |
| 359 | nmax++; | 358 | if (ptest > PRESSURE_LOW) |
| 360 | if (ptest > PRESSURE_HIGH) | 359 | nmax++; |
| 361 | nmin++; | 360 | if (ptest > PRESSURE_HIGH) |
| 362 | f++; | 361 | nmin++; |
| 362 | f++; | ||
| 363 | } | ||
| 363 | } | 364 | } |
| 364 | } | 365 | } |
| 365 | 366 | ||
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 4bc78892ba91..fda35e615abf 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
| @@ -553,7 +553,7 @@ static struct attribute_group elantech_attr_group = { | |||
| 553 | /* | 553 | /* |
| 554 | * Use magic knock to detect Elantech touchpad | 554 | * Use magic knock to detect Elantech touchpad |
| 555 | */ | 555 | */ |
| 556 | int elantech_detect(struct psmouse *psmouse, int set_properties) | 556 | int elantech_detect(struct psmouse *psmouse, bool set_properties) |
| 557 | { | 557 | { |
| 558 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 558 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
| 559 | unsigned char param[3]; | 559 | unsigned char param[3]; |
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h index ed848cc80814..feac5f7af966 100644 --- a/drivers/input/mouse/elantech.h +++ b/drivers/input/mouse/elantech.h | |||
| @@ -109,10 +109,10 @@ struct elantech_data { | |||
| 109 | }; | 109 | }; |
| 110 | 110 | ||
| 111 | #ifdef CONFIG_MOUSE_PS2_ELANTECH | 111 | #ifdef CONFIG_MOUSE_PS2_ELANTECH |
| 112 | int elantech_detect(struct psmouse *psmouse, int set_properties); | 112 | int elantech_detect(struct psmouse *psmouse, bool set_properties); |
| 113 | int elantech_init(struct psmouse *psmouse); | 113 | int elantech_init(struct psmouse *psmouse); |
| 114 | #else | 114 | #else |
| 115 | static inline int elantech_detect(struct psmouse *psmouse, int set_properties) | 115 | static inline int elantech_detect(struct psmouse *psmouse, bool set_properties) |
| 116 | { | 116 | { |
| 117 | return -ENOSYS; | 117 | return -ENOSYS; |
| 118 | } | 118 | } |
diff --git a/drivers/input/mouse/gpio_mouse.c b/drivers/input/mouse/gpio_mouse.c index 5e5eb88d8d1e..7b6ce178f1b6 100644 --- a/drivers/input/mouse/gpio_mouse.c +++ b/drivers/input/mouse/gpio_mouse.c | |||
| @@ -46,7 +46,7 @@ static void gpio_mouse_scan(struct input_polled_dev *dev) | |||
| 46 | input_sync(input); | 46 | input_sync(input); |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | static int __init gpio_mouse_probe(struct platform_device *pdev) | 49 | static int __devinit gpio_mouse_probe(struct platform_device *pdev) |
| 50 | { | 50 | { |
| 51 | struct gpio_mouse_platform_data *pdata = pdev->dev.platform_data; | 51 | struct gpio_mouse_platform_data *pdata = pdev->dev.platform_data; |
| 52 | struct input_polled_dev *input_poll; | 52 | struct input_polled_dev *input_poll; |
| @@ -170,10 +170,8 @@ static int __devexit gpio_mouse_remove(struct platform_device *pdev) | |||
| 170 | return 0; | 170 | return 0; |
| 171 | } | 171 | } |
| 172 | 172 | ||
| 173 | /* work with hotplug and coldplug */ | ||
| 174 | MODULE_ALIAS("platform:gpio_mouse"); | ||
| 175 | |||
| 176 | static struct platform_driver gpio_mouse_device_driver = { | 173 | static struct platform_driver gpio_mouse_device_driver = { |
| 174 | .probe = gpio_mouse_probe, | ||
| 177 | .remove = __devexit_p(gpio_mouse_remove), | 175 | .remove = __devexit_p(gpio_mouse_remove), |
| 178 | .driver = { | 176 | .driver = { |
| 179 | .name = "gpio_mouse", | 177 | .name = "gpio_mouse", |
| @@ -183,8 +181,7 @@ static struct platform_driver gpio_mouse_device_driver = { | |||
| 183 | 181 | ||
| 184 | static int __init gpio_mouse_init(void) | 182 | static int __init gpio_mouse_init(void) |
| 185 | { | 183 | { |
| 186 | return platform_driver_probe(&gpio_mouse_device_driver, | 184 | return platform_driver_register(&gpio_mouse_device_driver); |
| 187 | gpio_mouse_probe); | ||
| 188 | } | 185 | } |
| 189 | module_init(gpio_mouse_init); | 186 | module_init(gpio_mouse_init); |
| 190 | 187 | ||
| @@ -197,3 +194,5 @@ module_exit(gpio_mouse_exit); | |||
| 197 | MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>"); | 194 | MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>"); |
| 198 | MODULE_DESCRIPTION("GPIO mouse driver"); | 195 | MODULE_DESCRIPTION("GPIO mouse driver"); |
| 199 | MODULE_LICENSE("GPL"); | 196 | MODULE_LICENSE("GPL"); |
| 197 | MODULE_ALIAS("platform:gpio_mouse"); /* work with hotplug and coldplug */ | ||
| 198 | |||
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c index a1ad2f1a7bb3..de1e553028b7 100644 --- a/drivers/input/mouse/hgpk.c +++ b/drivers/input/mouse/hgpk.c | |||
| @@ -367,7 +367,36 @@ static ssize_t hgpk_set_powered(struct psmouse *psmouse, void *data, | |||
| 367 | } | 367 | } |
| 368 | 368 | ||
| 369 | __PSMOUSE_DEFINE_ATTR(powered, S_IWUSR | S_IRUGO, NULL, | 369 | __PSMOUSE_DEFINE_ATTR(powered, S_IWUSR | S_IRUGO, NULL, |
| 370 | hgpk_show_powered, hgpk_set_powered, 0); | 370 | hgpk_show_powered, hgpk_set_powered, false); |
| 371 | |||
| 372 | static ssize_t hgpk_trigger_recal_show(struct psmouse *psmouse, | ||
| 373 | void *data, char *buf) | ||
| 374 | { | ||
| 375 | return -EINVAL; | ||
| 376 | } | ||
| 377 | |||
| 378 | static ssize_t hgpk_trigger_recal(struct psmouse *psmouse, void *data, | ||
| 379 | const char *buf, size_t count) | ||
| 380 | { | ||
| 381 | struct hgpk_data *priv = psmouse->private; | ||
| 382 | unsigned long value; | ||
| 383 | int err; | ||
| 384 | |||
| 385 | err = strict_strtoul(buf, 10, &value); | ||
| 386 | if (err || value != 1) | ||
| 387 | return -EINVAL; | ||
| 388 | |||
| 389 | /* | ||
| 390 | * We queue work instead of doing recalibration right here | ||
| 391 | * to avoid adding locking to to hgpk_force_recalibrate() | ||
| 392 | * since workqueue provides serialization. | ||
| 393 | */ | ||
| 394 | psmouse_queue_work(psmouse, &priv->recalib_wq, 0); | ||
| 395 | return count; | ||
| 396 | } | ||
| 397 | |||
| 398 | __PSMOUSE_DEFINE_ATTR(recalibrate, S_IWUSR | S_IRUGO, NULL, | ||
| 399 | hgpk_trigger_recal_show, hgpk_trigger_recal, false); | ||
| 371 | 400 | ||
| 372 | static void hgpk_disconnect(struct psmouse *psmouse) | 401 | static void hgpk_disconnect(struct psmouse *psmouse) |
| 373 | { | 402 | { |
| @@ -375,6 +404,11 @@ static void hgpk_disconnect(struct psmouse *psmouse) | |||
| 375 | 404 | ||
| 376 | device_remove_file(&psmouse->ps2dev.serio->dev, | 405 | device_remove_file(&psmouse->ps2dev.serio->dev, |
| 377 | &psmouse_attr_powered.dattr); | 406 | &psmouse_attr_powered.dattr); |
| 407 | |||
| 408 | if (psmouse->model >= HGPK_MODEL_C) | ||
| 409 | device_remove_file(&psmouse->ps2dev.serio->dev, | ||
| 410 | &psmouse_attr_recalibrate.dattr); | ||
| 411 | |||
| 378 | psmouse_reset(psmouse); | 412 | psmouse_reset(psmouse); |
| 379 | kfree(priv); | 413 | kfree(priv); |
| 380 | } | 414 | } |
| @@ -423,10 +457,25 @@ static int hgpk_register(struct psmouse *psmouse) | |||
| 423 | 457 | ||
| 424 | err = device_create_file(&psmouse->ps2dev.serio->dev, | 458 | err = device_create_file(&psmouse->ps2dev.serio->dev, |
| 425 | &psmouse_attr_powered.dattr); | 459 | &psmouse_attr_powered.dattr); |
| 426 | if (err) | 460 | if (err) { |
| 427 | hgpk_err(psmouse, "Failed to create sysfs attribute\n"); | 461 | hgpk_err(psmouse, "Failed creating 'powered' sysfs node\n"); |
| 462 | return err; | ||
| 463 | } | ||
| 428 | 464 | ||
| 429 | return err; | 465 | /* C-series touchpads added the recalibrate command */ |
| 466 | if (psmouse->model >= HGPK_MODEL_C) { | ||
| 467 | err = device_create_file(&psmouse->ps2dev.serio->dev, | ||
| 468 | &psmouse_attr_recalibrate.dattr); | ||
| 469 | if (err) { | ||
| 470 | hgpk_err(psmouse, | ||
| 471 | "Failed creating 'recalibrate' sysfs node\n"); | ||
| 472 | device_remove_file(&psmouse->ps2dev.serio->dev, | ||
| 473 | &psmouse_attr_powered.dattr); | ||
| 474 | return err; | ||
| 475 | } | ||
| 476 | } | ||
| 477 | |||
| 478 | return 0; | ||
| 430 | } | 479 | } |
| 431 | 480 | ||
| 432 | int hgpk_init(struct psmouse *psmouse) | 481 | int hgpk_init(struct psmouse *psmouse) |
| @@ -440,7 +489,7 @@ int hgpk_init(struct psmouse *psmouse) | |||
| 440 | 489 | ||
| 441 | psmouse->private = priv; | 490 | psmouse->private = priv; |
| 442 | priv->psmouse = psmouse; | 491 | priv->psmouse = psmouse; |
| 443 | priv->powered = 1; | 492 | priv->powered = true; |
| 444 | INIT_DELAYED_WORK(&priv->recalib_wq, hgpk_recalib_work); | 493 | INIT_DELAYED_WORK(&priv->recalib_wq, hgpk_recalib_work); |
| 445 | 494 | ||
| 446 | err = psmouse_reset(psmouse); | 495 | err = psmouse_reset(psmouse); |
| @@ -483,7 +532,7 @@ static enum hgpk_model_t hgpk_get_model(struct psmouse *psmouse) | |||
| 483 | return param[2]; | 532 | return param[2]; |
| 484 | } | 533 | } |
| 485 | 534 | ||
| 486 | int hgpk_detect(struct psmouse *psmouse, int set_properties) | 535 | int hgpk_detect(struct psmouse *psmouse, bool set_properties) |
| 487 | { | 536 | { |
| 488 | int version; | 537 | int version; |
| 489 | 538 | ||
diff --git a/drivers/input/mouse/hgpk.h b/drivers/input/mouse/hgpk.h index a4b2a96f5f54..d61cfd3ee9cb 100644 --- a/drivers/input/mouse/hgpk.h +++ b/drivers/input/mouse/hgpk.h | |||
| @@ -15,7 +15,7 @@ enum hgpk_model_t { | |||
| 15 | 15 | ||
| 16 | struct hgpk_data { | 16 | struct hgpk_data { |
| 17 | struct psmouse *psmouse; | 17 | struct psmouse *psmouse; |
| 18 | int powered; | 18 | bool powered; |
| 19 | int count, x_tally, y_tally; /* hardware workaround stuff */ | 19 | int count, x_tally, y_tally; /* hardware workaround stuff */ |
| 20 | unsigned long recalib_window; | 20 | unsigned long recalib_window; |
| 21 | struct delayed_work recalib_wq; | 21 | struct delayed_work recalib_wq; |
| @@ -33,10 +33,10 @@ struct hgpk_data { | |||
| 33 | dev_notice(&(psmouse)->ps2dev.serio->dev, format, ## arg) | 33 | dev_notice(&(psmouse)->ps2dev.serio->dev, format, ## arg) |
| 34 | 34 | ||
| 35 | #ifdef CONFIG_MOUSE_PS2_OLPC | 35 | #ifdef CONFIG_MOUSE_PS2_OLPC |
| 36 | int hgpk_detect(struct psmouse *psmouse, int set_properties); | 36 | int hgpk_detect(struct psmouse *psmouse, bool set_properties); |
| 37 | int hgpk_init(struct psmouse *psmouse); | 37 | int hgpk_init(struct psmouse *psmouse); |
| 38 | #else | 38 | #else |
| 39 | static inline int hgpk_detect(struct psmouse *psmouse, int set_properties) | 39 | static inline int hgpk_detect(struct psmouse *psmouse, bool set_properties) |
| 40 | { | 40 | { |
| 41 | return -ENODEV; | 41 | return -ENODEV; |
| 42 | } | 42 | } |
diff --git a/drivers/input/mouse/hil_ptr.c b/drivers/input/mouse/hil_ptr.c deleted file mode 100644 index 3263ce083bf0..000000000000 --- a/drivers/input/mouse/hil_ptr.c +++ /dev/null | |||
| @@ -1,447 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Generic linux-input device driver for axis-bearing devices | ||
| 3 | * | ||
| 4 | * Copyright (c) 2001 Brian S. Julin | ||
| 5 | * All rights reserved. | ||
| 6 | * | ||
| 7 | * Redistribution and use in source and binary forms, with or without | ||
| 8 | * modification, are permitted provided that the following conditions | ||
| 9 | * are met: | ||
| 10 | * 1. Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions, and the following disclaimer, | ||
| 12 | * without modification. | ||
| 13 | * 2. The name of the author may not be used to endorse or promote products | ||
| 14 | * derived from this software without specific prior written permission. | ||
| 15 | * | ||
| 16 | * Alternatively, this software may be distributed under the terms of the | ||
| 17 | * GNU General Public License ("GPL"). | ||
| 18 | * | ||
| 19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
| 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR | ||
| 23 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 28 | * | ||
| 29 | * References: | ||
| 30 | * HP-HIL Technical Reference Manual. Hewlett Packard Product No. 45918A | ||
| 31 | * | ||
| 32 | */ | ||
| 33 | |||
| 34 | #include <linux/hil.h> | ||
| 35 | #include <linux/input.h> | ||
| 36 | #include <linux/serio.h> | ||
| 37 | #include <linux/kernel.h> | ||
| 38 | #include <linux/module.h> | ||
| 39 | #include <linux/init.h> | ||
| 40 | #include <linux/slab.h> | ||
| 41 | #include <linux/pci_ids.h> | ||
| 42 | |||
| 43 | #define PREFIX "HIL PTR: " | ||
| 44 | #define HIL_GENERIC_NAME "HIL pointer device" | ||
| 45 | |||
| 46 | MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>"); | ||
| 47 | MODULE_DESCRIPTION(HIL_GENERIC_NAME " driver"); | ||
| 48 | MODULE_LICENSE("Dual BSD/GPL"); | ||
| 49 | MODULE_ALIAS("serio:ty03pr25id0Fex*"); | ||
| 50 | |||
| 51 | #define TABLET_SIMULATES_MOUSE /* allow tablet to be used as mouse */ | ||
| 52 | #undef TABLET_AUTOADJUST /* auto-adjust valid tablet ranges */ | ||
| 53 | |||
| 54 | |||
| 55 | #define HIL_PTR_MAX_LENGTH 16 | ||
| 56 | |||
| 57 | struct hil_ptr { | ||
| 58 | struct input_dev *dev; | ||
| 59 | struct serio *serio; | ||
| 60 | |||
| 61 | /* Input buffer and index for packets from HIL bus. */ | ||
| 62 | hil_packet data[HIL_PTR_MAX_LENGTH]; | ||
| 63 | int idx4; /* four counts per packet */ | ||
| 64 | |||
| 65 | /* Raw device info records from HIL bus, see hil.h for fields. */ | ||
| 66 | char idd[HIL_PTR_MAX_LENGTH]; /* DID byte and IDD record */ | ||
| 67 | char rsc[HIL_PTR_MAX_LENGTH]; /* RSC record */ | ||
| 68 | char exd[HIL_PTR_MAX_LENGTH]; /* EXD record */ | ||
| 69 | char rnm[HIL_PTR_MAX_LENGTH + 1]; /* RNM record + NULL term. */ | ||
| 70 | |||
| 71 | /* Extra device details not contained in struct input_dev. */ | ||
| 72 | unsigned int nbtn, naxes; | ||
| 73 | unsigned int btnmap[7]; | ||
| 74 | |||
| 75 | /* Something to sleep around with. */ | ||
| 76 | struct semaphore sem; | ||
| 77 | }; | ||
| 78 | |||
| 79 | /* Process a complete packet after transfer from the HIL */ | ||
| 80 | static void hil_ptr_process_record(struct hil_ptr *ptr) | ||
| 81 | { | ||
| 82 | struct input_dev *dev = ptr->dev; | ||
| 83 | hil_packet *data = ptr->data; | ||
| 84 | hil_packet p; | ||
| 85 | int idx, i, cnt, laxis; | ||
| 86 | int ax16, absdev; | ||
| 87 | |||
| 88 | idx = ptr->idx4/4; | ||
| 89 | p = data[idx - 1]; | ||
| 90 | |||
| 91 | if ((p & ~HIL_CMDCT_POL) == | ||
| 92 | (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) | ||
| 93 | goto report; | ||
| 94 | if ((p & ~HIL_CMDCT_RPL) == | ||
| 95 | (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL)) | ||
| 96 | goto report; | ||
| 97 | |||
| 98 | /* Not a poll response. See if we are loading config records. */ | ||
| 99 | switch (p & HIL_PKT_DATA_MASK) { | ||
| 100 | case HIL_CMD_IDD: | ||
| 101 | for (i = 0; i < idx; i++) | ||
| 102 | ptr->idd[i] = ptr->data[i] & HIL_PKT_DATA_MASK; | ||
| 103 | for (; i < HIL_PTR_MAX_LENGTH; i++) | ||
| 104 | ptr->idd[i] = 0; | ||
| 105 | break; | ||
| 106 | |||
| 107 | case HIL_CMD_RSC: | ||
| 108 | for (i = 0; i < idx; i++) | ||
| 109 | ptr->rsc[i] = ptr->data[i] & HIL_PKT_DATA_MASK; | ||
| 110 | for (; i < HIL_PTR_MAX_LENGTH; i++) | ||
| 111 | ptr->rsc[i] = 0; | ||
| 112 | break; | ||
| 113 | |||
| 114 | case HIL_CMD_EXD: | ||
| 115 | for (i = 0; i < idx; i++) | ||
| 116 | ptr->exd[i] = ptr->data[i] & HIL_PKT_DATA_MASK; | ||
| 117 | for (; i < HIL_PTR_MAX_LENGTH; i++) | ||
| 118 | ptr->exd[i] = 0; | ||
| 119 | break; | ||
| 120 | |||
| 121 | case HIL_CMD_RNM: | ||
| 122 | for (i = 0; i < idx; i++) | ||
| 123 | ptr->rnm[i] = ptr->data[i] & HIL_PKT_DATA_MASK; | ||
| 124 | for (; i < HIL_PTR_MAX_LENGTH + 1; i++) | ||
| 125 | ptr->rnm[i] = 0; | ||
| 126 | break; | ||
| 127 | |||
| 128 | default: | ||
| 129 | /* These occur when device isn't present */ | ||
| 130 | if (p == (HIL_ERR_INT | HIL_PKT_CMD)) | ||
| 131 | break; | ||
| 132 | /* Anything else we'd like to know about. */ | ||
| 133 | printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p); | ||
| 134 | break; | ||
| 135 | } | ||
| 136 | goto out; | ||
| 137 | |||
| 138 | report: | ||
| 139 | if ((p & HIL_CMDCT_POL) != idx - 1) { | ||
| 140 | printk(KERN_WARNING PREFIX | ||
| 141 | "Malformed poll packet %x (idx = %i)\n", p, idx); | ||
| 142 | goto out; | ||
| 143 | } | ||
| 144 | |||
| 145 | i = (ptr->data[0] & HIL_POL_AXIS_ALT) ? 3 : 0; | ||
| 146 | laxis = ptr->data[0] & HIL_POL_NUM_AXES_MASK; | ||
| 147 | laxis += i; | ||
| 148 | |||
| 149 | ax16 = ptr->idd[1] & HIL_IDD_HEADER_16BIT; /* 8 or 16bit resolution */ | ||
| 150 | absdev = ptr->idd[1] & HIL_IDD_HEADER_ABS; | ||
| 151 | |||
| 152 | for (cnt = 1; i < laxis; i++) { | ||
| 153 | unsigned int lo,hi,val; | ||
| 154 | lo = ptr->data[cnt++] & HIL_PKT_DATA_MASK; | ||
| 155 | hi = ax16 ? (ptr->data[cnt++] & HIL_PKT_DATA_MASK) : 0; | ||
| 156 | if (absdev) { | ||
| 157 | val = lo + (hi<<8); | ||
| 158 | #ifdef TABLET_AUTOADJUST | ||
| 159 | if (val < dev->absmin[ABS_X + i]) | ||
| 160 | dev->absmin[ABS_X + i] = val; | ||
| 161 | if (val > dev->absmax[ABS_X + i]) | ||
| 162 | dev->absmax[ABS_X + i] = val; | ||
| 163 | #endif | ||
| 164 | if (i%3) val = dev->absmax[ABS_X + i] - val; | ||
| 165 | input_report_abs(dev, ABS_X + i, val); | ||
| 166 | } else { | ||
| 167 | val = (int) (((int8_t)lo) | ((int8_t)hi<<8)); | ||
| 168 | if (i%3) | ||
| 169 | val *= -1; | ||
| 170 | input_report_rel(dev, REL_X + i, val); | ||
| 171 | } | ||
| 172 | } | ||
| 173 | |||
| 174 | while (cnt < idx - 1) { | ||
| 175 | unsigned int btn; | ||
| 176 | int up; | ||
| 177 | btn = ptr->data[cnt++]; | ||
| 178 | up = btn & 1; | ||
| 179 | btn &= 0xfe; | ||
| 180 | if (btn == 0x8e) | ||
| 181 | continue; /* TODO: proximity == touch? */ | ||
| 182 | else | ||
| 183 | if ((btn > 0x8c) || (btn < 0x80)) | ||
| 184 | continue; | ||
| 185 | btn = (btn - 0x80) >> 1; | ||
| 186 | btn = ptr->btnmap[btn]; | ||
| 187 | input_report_key(dev, btn, !up); | ||
| 188 | } | ||
| 189 | input_sync(dev); | ||
| 190 | out: | ||
| 191 | ptr->idx4 = 0; | ||
| 192 | up(&ptr->sem); | ||
| 193 | } | ||
| 194 | |||
| 195 | static void hil_ptr_process_err(struct hil_ptr *ptr) | ||
| 196 | { | ||
| 197 | printk(KERN_WARNING PREFIX "errored HIL packet\n"); | ||
| 198 | ptr->idx4 = 0; | ||
| 199 | up(&ptr->sem); | ||
| 200 | } | ||
| 201 | |||
| 202 | static irqreturn_t hil_ptr_interrupt(struct serio *serio, | ||
| 203 | unsigned char data, unsigned int flags) | ||
| 204 | { | ||
| 205 | struct hil_ptr *ptr; | ||
| 206 | hil_packet packet; | ||
| 207 | int idx; | ||
| 208 | |||
| 209 | ptr = serio_get_drvdata(serio); | ||
| 210 | BUG_ON(ptr == NULL); | ||
| 211 | |||
| 212 | if (ptr->idx4 >= (HIL_PTR_MAX_LENGTH * sizeof(hil_packet))) { | ||
| 213 | hil_ptr_process_err(ptr); | ||
| 214 | return IRQ_HANDLED; | ||
| 215 | } | ||
| 216 | idx = ptr->idx4/4; | ||
| 217 | if (!(ptr->idx4 % 4)) | ||
| 218 | ptr->data[idx] = 0; | ||
| 219 | packet = ptr->data[idx]; | ||
| 220 | packet |= ((hil_packet)data) << ((3 - (ptr->idx4 % 4)) * 8); | ||
| 221 | ptr->data[idx] = packet; | ||
| 222 | |||
| 223 | /* Records of N 4-byte hil_packets must terminate with a command. */ | ||
| 224 | if ((++(ptr->idx4)) % 4) | ||
| 225 | return IRQ_HANDLED; | ||
| 226 | if ((packet & 0xffff0000) != HIL_ERR_INT) { | ||
| 227 | hil_ptr_process_err(ptr); | ||
| 228 | return IRQ_HANDLED; | ||
| 229 | } | ||
| 230 | if (packet & HIL_PKT_CMD) | ||
| 231 | hil_ptr_process_record(ptr); | ||
| 232 | |||
| 233 | return IRQ_HANDLED; | ||
| 234 | } | ||
| 235 | |||
| 236 | static void hil_ptr_disconnect(struct serio *serio) | ||
| 237 | { | ||
| 238 | struct hil_ptr *ptr; | ||
| 239 | |||
| 240 | ptr = serio_get_drvdata(serio); | ||
| 241 | BUG_ON(ptr == NULL); | ||
| 242 | |||
| 243 | serio_close(serio); | ||
| 244 | input_unregister_device(ptr->dev); | ||
| 245 | kfree(ptr); | ||
| 246 | } | ||
| 247 | |||
| 248 | static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) | ||
| 249 | { | ||
| 250 | struct hil_ptr *ptr; | ||
| 251 | const char *txt; | ||
| 252 | unsigned int i, naxsets, btntype; | ||
| 253 | uint8_t did, *idd; | ||
| 254 | int error; | ||
| 255 | |||
| 256 | ptr = kzalloc(sizeof(struct hil_ptr), GFP_KERNEL); | ||
| 257 | if (!ptr) | ||
| 258 | return -ENOMEM; | ||
| 259 | |||
| 260 | ptr->dev = input_allocate_device(); | ||
| 261 | if (!ptr->dev) { | ||
| 262 | error = -ENOMEM; | ||
| 263 | goto bail0; | ||
| 264 | } | ||
| 265 | |||
| 266 | error = serio_open(serio, driver); | ||
| 267 | if (error) | ||
| 268 | goto bail1; | ||
| 269 | |||
| 270 | serio_set_drvdata(serio, ptr); | ||
| 271 | ptr->serio = serio; | ||
| 272 | |||
| 273 | init_MUTEX_LOCKED(&ptr->sem); | ||
| 274 | |||
| 275 | /* Get device info. MLC driver supplies devid/status/etc. */ | ||
| 276 | serio->write(serio, 0); | ||
| 277 | serio->write(serio, 0); | ||
| 278 | serio->write(serio, HIL_PKT_CMD >> 8); | ||
| 279 | serio->write(serio, HIL_CMD_IDD); | ||
| 280 | down(&ptr->sem); | ||
| 281 | |||
| 282 | serio->write(serio, 0); | ||
| 283 | serio->write(serio, 0); | ||
| 284 | serio->write(serio, HIL_PKT_CMD >> 8); | ||
| 285 | serio->write(serio, HIL_CMD_RSC); | ||
| 286 | down(&ptr->sem); | ||
| 287 | |||
| 288 | serio->write(serio, 0); | ||
| 289 | serio->write(serio, 0); | ||
| 290 | serio->write(serio, HIL_PKT_CMD >> 8); | ||
| 291 | serio->write(serio, HIL_CMD_RNM); | ||
| 292 | down(&ptr->sem); | ||
| 293 | |||
| 294 | serio->write(serio, 0); | ||
| 295 | serio->write(serio, 0); | ||
| 296 | serio->write(serio, HIL_PKT_CMD >> 8); | ||
| 297 | serio->write(serio, HIL_CMD_EXD); | ||
| 298 | down(&ptr->sem); | ||
| 299 | |||
| 300 | up(&ptr->sem); | ||
| 301 | |||
| 302 | did = ptr->idd[0]; | ||
| 303 | idd = ptr->idd + 1; | ||
| 304 | txt = "unknown"; | ||
| 305 | |||
| 306 | if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) { | ||
| 307 | ptr->dev->evbit[0] = BIT_MASK(EV_REL); | ||
| 308 | txt = "relative"; | ||
| 309 | } | ||
| 310 | |||
| 311 | if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_ABS) { | ||
| 312 | ptr->dev->evbit[0] = BIT_MASK(EV_ABS); | ||
| 313 | txt = "absolute"; | ||
| 314 | } | ||
| 315 | |||
| 316 | if (!ptr->dev->evbit[0]) { | ||
| 317 | error = -ENODEV; | ||
| 318 | goto bail2; | ||
| 319 | } | ||
| 320 | |||
| 321 | ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd); | ||
| 322 | if (ptr->nbtn) | ||
| 323 | ptr->dev->evbit[0] |= BIT_MASK(EV_KEY); | ||
| 324 | |||
| 325 | naxsets = HIL_IDD_NUM_AXSETS(*idd); | ||
| 326 | ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd); | ||
| 327 | |||
| 328 | printk(KERN_INFO PREFIX "HIL pointer device found (did: 0x%02x, axis: %s)\n", | ||
| 329 | did, txt); | ||
| 330 | printk(KERN_INFO PREFIX "HIL pointer has %i buttons and %i sets of %i axes\n", | ||
| 331 | ptr->nbtn, naxsets, ptr->naxes); | ||
| 332 | |||
| 333 | btntype = BTN_MISC; | ||
| 334 | if ((did & HIL_IDD_DID_ABS_TABLET_MASK) == HIL_IDD_DID_ABS_TABLET) | ||
| 335 | #ifdef TABLET_SIMULATES_MOUSE | ||
| 336 | btntype = BTN_TOUCH; | ||
| 337 | #else | ||
| 338 | btntype = BTN_DIGI; | ||
| 339 | #endif | ||
| 340 | if ((did & HIL_IDD_DID_ABS_TSCREEN_MASK) == HIL_IDD_DID_ABS_TSCREEN) | ||
| 341 | btntype = BTN_TOUCH; | ||
| 342 | |||
| 343 | if ((did & HIL_IDD_DID_REL_MOUSE_MASK) == HIL_IDD_DID_REL_MOUSE) | ||
| 344 | btntype = BTN_MOUSE; | ||
| 345 | |||
| 346 | for (i = 0; i < ptr->nbtn; i++) { | ||
| 347 | set_bit(btntype | i, ptr->dev->keybit); | ||
| 348 | ptr->btnmap[i] = btntype | i; | ||
| 349 | } | ||
| 350 | |||
| 351 | if (btntype == BTN_MOUSE) { | ||
| 352 | /* Swap buttons 2 and 3 */ | ||
| 353 | ptr->btnmap[1] = BTN_MIDDLE; | ||
| 354 | ptr->btnmap[2] = BTN_RIGHT; | ||
| 355 | } | ||
| 356 | |||
| 357 | if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) { | ||
| 358 | for (i = 0; i < ptr->naxes; i++) | ||
| 359 | set_bit(REL_X + i, ptr->dev->relbit); | ||
| 360 | for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) | ||
| 361 | set_bit(REL_X + i, ptr->dev->relbit); | ||
| 362 | } else { | ||
| 363 | for (i = 0; i < ptr->naxes; i++) { | ||
| 364 | set_bit(ABS_X + i, ptr->dev->absbit); | ||
| 365 | ptr->dev->absmin[ABS_X + i] = 0; | ||
| 366 | ptr->dev->absmax[ABS_X + i] = | ||
| 367 | HIL_IDD_AXIS_MAX((ptr->idd + 1), i); | ||
| 368 | } | ||
| 369 | for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) { | ||
| 370 | set_bit(ABS_X + i, ptr->dev->absbit); | ||
| 371 | ptr->dev->absmin[ABS_X + i] = 0; | ||
| 372 | ptr->dev->absmax[ABS_X + i] = | ||
| 373 | HIL_IDD_AXIS_MAX((ptr->idd + 1), (i - 3)); | ||
| 374 | } | ||
| 375 | #ifdef TABLET_AUTOADJUST | ||
| 376 | for (i = 0; i < ABS_MAX; i++) { | ||
| 377 | int diff = ptr->dev->absmax[ABS_X + i] / 10; | ||
| 378 | ptr->dev->absmin[ABS_X + i] += diff; | ||
| 379 | ptr->dev->absmax[ABS_X + i] -= diff; | ||
| 380 | } | ||
| 381 | #endif | ||
| 382 | } | ||
| 383 | |||
| 384 | ptr->dev->name = strlen(ptr->rnm) ? ptr->rnm : HIL_GENERIC_NAME; | ||
| 385 | |||
| 386 | ptr->dev->id.bustype = BUS_HIL; | ||
| 387 | ptr->dev->id.vendor = PCI_VENDOR_ID_HP; | ||
| 388 | ptr->dev->id.product = 0x0001; /* TODO: get from ptr->rsc */ | ||
| 389 | ptr->dev->id.version = 0x0100; /* TODO: get from ptr->rsc */ | ||
| 390 | ptr->dev->dev.parent = &serio->dev; | ||
| 391 | |||
| 392 | error = input_register_device(ptr->dev); | ||
| 393 | if (error) { | ||
| 394 | printk(KERN_INFO PREFIX "Unable to register input device\n"); | ||
| 395 | goto bail2; | ||
| 396 | } | ||
| 397 | |||
| 398 | printk(KERN_INFO "input: %s (%s), ID: %d\n", | ||
| 399 | ptr->dev->name, | ||
| 400 | (btntype == BTN_MOUSE) ? "HIL mouse":"HIL tablet or touchpad", | ||
| 401 | did); | ||
| 402 | |||
| 403 | return 0; | ||
| 404 | |||
| 405 | bail2: | ||
| 406 | serio_close(serio); | ||
| 407 | bail1: | ||
| 408 | input_free_device(ptr->dev); | ||
| 409 | bail0: | ||
| 410 | kfree(ptr); | ||
| 411 | serio_set_drvdata(serio, NULL); | ||
| 412 | return error; | ||
| 413 | } | ||
| 414 | |||
| 415 | static struct serio_device_id hil_ptr_ids[] = { | ||
| 416 | { | ||
| 417 | .type = SERIO_HIL_MLC, | ||
| 418 | .proto = SERIO_HIL, | ||
| 419 | .id = SERIO_ANY, | ||
| 420 | .extra = SERIO_ANY, | ||
| 421 | }, | ||
| 422 | { 0 } | ||
| 423 | }; | ||
| 424 | |||
| 425 | static struct serio_driver hil_ptr_serio_driver = { | ||
| 426 | .driver = { | ||
| 427 | .name = "hil_ptr", | ||
| 428 | }, | ||
| 429 | .description = "HP HIL mouse/tablet driver", | ||
| 430 | .id_table = hil_ptr_ids, | ||
| 431 | .connect = hil_ptr_connect, | ||
| 432 | .disconnect = hil_ptr_disconnect, | ||
| 433 | .interrupt = hil_ptr_interrupt | ||
| 434 | }; | ||
| 435 | |||
| 436 | static int __init hil_ptr_init(void) | ||
| 437 | { | ||
| 438 | return serio_register_driver(&hil_ptr_serio_driver); | ||
| 439 | } | ||
| 440 | |||
| 441 | static void __exit hil_ptr_exit(void) | ||
| 442 | { | ||
| 443 | serio_unregister_driver(&hil_ptr_serio_driver); | ||
| 444 | } | ||
| 445 | |||
| 446 | module_init(hil_ptr_init); | ||
| 447 | module_exit(hil_ptr_exit); | ||
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index dcd4236af1e3..5e6308694408 100644 --- a/drivers/input/mouse/lifebook.c +++ b/drivers/input/mouse/lifebook.c | |||
| @@ -33,11 +33,11 @@ static int lifebook_set_serio_phys(const struct dmi_system_id *d) | |||
| 33 | return 0; | 33 | return 0; |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | static unsigned char lifebook_use_6byte_proto; | 36 | static bool lifebook_use_6byte_proto; |
| 37 | 37 | ||
| 38 | static int lifebook_set_6byte_proto(const struct dmi_system_id *d) | 38 | static int lifebook_set_6byte_proto(const struct dmi_system_id *d) |
| 39 | { | 39 | { |
| 40 | lifebook_use_6byte_proto = 1; | 40 | lifebook_use_6byte_proto = true; |
| 41 | return 0; | 41 | return 0; |
| 42 | } | 42 | } |
| 43 | 43 | ||
| @@ -125,7 +125,7 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) | |||
| 125 | struct input_dev *dev1 = psmouse->dev; | 125 | struct input_dev *dev1 = psmouse->dev; |
| 126 | struct input_dev *dev2 = priv ? priv->dev2 : NULL; | 126 | struct input_dev *dev2 = priv ? priv->dev2 : NULL; |
| 127 | unsigned char *packet = psmouse->packet; | 127 | unsigned char *packet = psmouse->packet; |
| 128 | int relative_packet = packet[0] & 0x08; | 128 | bool relative_packet = packet[0] & 0x08; |
| 129 | 129 | ||
| 130 | if (relative_packet || !lifebook_use_6byte_proto) { | 130 | if (relative_packet || !lifebook_use_6byte_proto) { |
| 131 | if (psmouse->pktcnt != 3) | 131 | if (psmouse->pktcnt != 3) |
| @@ -242,7 +242,7 @@ static void lifebook_disconnect(struct psmouse *psmouse) | |||
| 242 | psmouse->private = NULL; | 242 | psmouse->private = NULL; |
| 243 | } | 243 | } |
| 244 | 244 | ||
| 245 | int lifebook_detect(struct psmouse *psmouse, int set_properties) | 245 | int lifebook_detect(struct psmouse *psmouse, bool set_properties) |
| 246 | { | 246 | { |
| 247 | if (!dmi_check_system(lifebook_dmi_table)) | 247 | if (!dmi_check_system(lifebook_dmi_table)) |
| 248 | return -1; | 248 | return -1; |
diff --git a/drivers/input/mouse/lifebook.h b/drivers/input/mouse/lifebook.h index c1647cf036c2..407cb226bc0a 100644 --- a/drivers/input/mouse/lifebook.h +++ b/drivers/input/mouse/lifebook.h | |||
| @@ -12,10 +12,10 @@ | |||
| 12 | #define _LIFEBOOK_H | 12 | #define _LIFEBOOK_H |
| 13 | 13 | ||
| 14 | #ifdef CONFIG_MOUSE_PS2_LIFEBOOK | 14 | #ifdef CONFIG_MOUSE_PS2_LIFEBOOK |
| 15 | int lifebook_detect(struct psmouse *psmouse, int set_properties); | 15 | int lifebook_detect(struct psmouse *psmouse, bool set_properties); |
| 16 | int lifebook_init(struct psmouse *psmouse); | 16 | int lifebook_init(struct psmouse *psmouse); |
| 17 | #else | 17 | #else |
| 18 | inline int lifebook_detect(struct psmouse *psmouse, int set_properties) | 18 | inline int lifebook_detect(struct psmouse *psmouse, bool set_properties) |
| 19 | { | 19 | { |
| 20 | return -ENOSYS; | 20 | return -ENOSYS; |
| 21 | } | 21 | } |
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index 390f1dbb98a4..de745d751162 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c | |||
| @@ -130,14 +130,11 @@ static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned cha | |||
| 130 | * 0 - disabled | 130 | * 0 - disabled |
| 131 | */ | 131 | */ |
| 132 | 132 | ||
| 133 | static void ps2pp_set_smartscroll(struct psmouse *psmouse, unsigned int smartscroll) | 133 | static void ps2pp_set_smartscroll(struct psmouse *psmouse, bool smartscroll) |
| 134 | { | 134 | { |
| 135 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 135 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
| 136 | unsigned char param[4]; | 136 | unsigned char param[4]; |
| 137 | 137 | ||
| 138 | if (smartscroll > 1) | ||
| 139 | smartscroll = 1; | ||
| 140 | |||
| 141 | ps2pp_cmd(psmouse, param, 0x32); | 138 | ps2pp_cmd(psmouse, param, 0x32); |
| 142 | 139 | ||
| 143 | param[0] = 0; | 140 | param[0] = 0; |
| @@ -149,12 +146,14 @@ static void ps2pp_set_smartscroll(struct psmouse *psmouse, unsigned int smartscr | |||
| 149 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); | 146 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); |
| 150 | } | 147 | } |
| 151 | 148 | ||
| 152 | static ssize_t ps2pp_attr_show_smartscroll(struct psmouse *psmouse, void *data, char *buf) | 149 | static ssize_t ps2pp_attr_show_smartscroll(struct psmouse *psmouse, |
| 150 | void *data, char *buf) | ||
| 153 | { | 151 | { |
| 154 | return sprintf(buf, "%d\n", psmouse->smartscroll ? 1 : 0); | 152 | return sprintf(buf, "%d\n", psmouse->smartscroll); |
| 155 | } | 153 | } |
| 156 | 154 | ||
| 157 | static ssize_t ps2pp_attr_set_smartscroll(struct psmouse *psmouse, void *data, const char *buf, size_t count) | 155 | static ssize_t ps2pp_attr_set_smartscroll(struct psmouse *psmouse, void *data, |
| 156 | const char *buf, size_t count) | ||
| 158 | { | 157 | { |
| 159 | unsigned long value; | 158 | unsigned long value; |
| 160 | 159 | ||
| @@ -261,29 +260,29 @@ static const struct ps2pp_info *get_model_info(unsigned char model) | |||
| 261 | 260 | ||
| 262 | static void ps2pp_set_model_properties(struct psmouse *psmouse, | 261 | static void ps2pp_set_model_properties(struct psmouse *psmouse, |
| 263 | const struct ps2pp_info *model_info, | 262 | const struct ps2pp_info *model_info, |
| 264 | int using_ps2pp) | 263 | bool using_ps2pp) |
| 265 | { | 264 | { |
| 266 | struct input_dev *input_dev = psmouse->dev; | 265 | struct input_dev *input_dev = psmouse->dev; |
| 267 | 266 | ||
| 268 | if (model_info->features & PS2PP_SIDE_BTN) | 267 | if (model_info->features & PS2PP_SIDE_BTN) |
| 269 | set_bit(BTN_SIDE, input_dev->keybit); | 268 | __set_bit(BTN_SIDE, input_dev->keybit); |
| 270 | 269 | ||
| 271 | if (model_info->features & PS2PP_EXTRA_BTN) | 270 | if (model_info->features & PS2PP_EXTRA_BTN) |
| 272 | set_bit(BTN_EXTRA, input_dev->keybit); | 271 | __set_bit(BTN_EXTRA, input_dev->keybit); |
| 273 | 272 | ||
| 274 | if (model_info->features & PS2PP_TASK_BTN) | 273 | if (model_info->features & PS2PP_TASK_BTN) |
| 275 | set_bit(BTN_TASK, input_dev->keybit); | 274 | __set_bit(BTN_TASK, input_dev->keybit); |
| 276 | 275 | ||
| 277 | if (model_info->features & PS2PP_NAV_BTN) { | 276 | if (model_info->features & PS2PP_NAV_BTN) { |
| 278 | set_bit(BTN_FORWARD, input_dev->keybit); | 277 | __set_bit(BTN_FORWARD, input_dev->keybit); |
| 279 | set_bit(BTN_BACK, input_dev->keybit); | 278 | __set_bit(BTN_BACK, input_dev->keybit); |
| 280 | } | 279 | } |
| 281 | 280 | ||
| 282 | if (model_info->features & PS2PP_WHEEL) | 281 | if (model_info->features & PS2PP_WHEEL) |
| 283 | set_bit(REL_WHEEL, input_dev->relbit); | 282 | __set_bit(REL_WHEEL, input_dev->relbit); |
| 284 | 283 | ||
| 285 | if (model_info->features & PS2PP_HWHEEL) | 284 | if (model_info->features & PS2PP_HWHEEL) |
| 286 | set_bit(REL_HWHEEL, input_dev->relbit); | 285 | __set_bit(REL_HWHEEL, input_dev->relbit); |
| 287 | 286 | ||
| 288 | switch (model_info->kind) { | 287 | switch (model_info->kind) { |
| 289 | case PS2PP_KIND_WHEEL: | 288 | case PS2PP_KIND_WHEEL: |
| @@ -321,13 +320,13 @@ static void ps2pp_set_model_properties(struct psmouse *psmouse, | |||
| 321 | * that support it. | 320 | * that support it. |
| 322 | */ | 321 | */ |
| 323 | 322 | ||
| 324 | int ps2pp_init(struct psmouse *psmouse, int set_properties) | 323 | int ps2pp_init(struct psmouse *psmouse, bool set_properties) |
| 325 | { | 324 | { |
| 326 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 325 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
| 327 | unsigned char param[4]; | 326 | unsigned char param[4]; |
| 328 | unsigned char model, buttons; | 327 | unsigned char model, buttons; |
| 329 | const struct ps2pp_info *model_info; | 328 | const struct ps2pp_info *model_info; |
| 330 | int use_ps2pp = 0; | 329 | bool use_ps2pp = false; |
| 331 | int error; | 330 | int error; |
| 332 | 331 | ||
| 333 | param[0] = 0; | 332 | param[0] = 0; |
| @@ -364,7 +363,7 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties) | |||
| 364 | param[0] = 0; | 363 | param[0] = 0; |
| 365 | if (!ps2_command(ps2dev, param, 0x13d1) && | 364 | if (!ps2_command(ps2dev, param, 0x13d1) && |
| 366 | param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) { | 365 | param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) { |
| 367 | use_ps2pp = 1; | 366 | use_ps2pp = true; |
| 368 | } | 367 | } |
| 369 | 368 | ||
| 370 | } else { | 369 | } else { |
| @@ -376,8 +375,8 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties) | |||
| 376 | if ((param[0] & 0x78) == 0x48 && | 375 | if ((param[0] & 0x78) == 0x48 && |
| 377 | (param[1] & 0xf3) == 0xc2 && | 376 | (param[1] & 0xf3) == 0xc2 && |
| 378 | (param[2] & 0x03) == ((param[1] >> 2) & 3)) { | 377 | (param[2] & 0x03) == ((param[1] >> 2) & 3)) { |
| 379 | ps2pp_set_smartscroll(psmouse, psmouse->smartscroll); | 378 | ps2pp_set_smartscroll(psmouse, false); |
| 380 | use_ps2pp = 1; | 379 | use_ps2pp = true; |
| 381 | } | 380 | } |
| 382 | } | 381 | } |
| 383 | } | 382 | } |
| @@ -406,7 +405,7 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties) | |||
| 406 | } | 405 | } |
| 407 | 406 | ||
| 408 | if (buttons < 3) | 407 | if (buttons < 3) |
| 409 | clear_bit(BTN_MIDDLE, psmouse->dev->keybit); | 408 | __clear_bit(BTN_MIDDLE, psmouse->dev->keybit); |
| 410 | 409 | ||
| 411 | if (model_info) | 410 | if (model_info) |
| 412 | ps2pp_set_model_properties(psmouse, model_info, use_ps2pp); | 411 | ps2pp_set_model_properties(psmouse, model_info, use_ps2pp); |
diff --git a/drivers/input/mouse/logips2pp.h b/drivers/input/mouse/logips2pp.h index 6e5712525fd6..0c186f0282d9 100644 --- a/drivers/input/mouse/logips2pp.h +++ b/drivers/input/mouse/logips2pp.h | |||
| @@ -12,9 +12,9 @@ | |||
| 12 | #define _LOGIPS2PP_H | 12 | #define _LOGIPS2PP_H |
| 13 | 13 | ||
| 14 | #ifdef CONFIG_MOUSE_PS2_LOGIPS2PP | 14 | #ifdef CONFIG_MOUSE_PS2_LOGIPS2PP |
| 15 | int ps2pp_init(struct psmouse *psmouse, int set_properties); | 15 | int ps2pp_init(struct psmouse *psmouse, bool set_properties); |
| 16 | #else | 16 | #else |
| 17 | inline int ps2pp_init(struct psmouse *psmouse, int set_properties) | 17 | inline int ps2pp_init(struct psmouse *psmouse, bool set_properties) |
| 18 | { | 18 | { |
| 19 | return -ENOSYS; | 19 | return -ENOSYS; |
| 20 | } | 20 | } |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index b407b355dceb..690aed905436 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include "trackpoint.h" | 30 | #include "trackpoint.h" |
| 31 | #include "touchkit_ps2.h" | 31 | #include "touchkit_ps2.h" |
| 32 | #include "elantech.h" | 32 | #include "elantech.h" |
| 33 | #include "sentelic.h" | ||
| 33 | 34 | ||
| 34 | #define DRIVER_DESC "PS/2 mouse driver" | 35 | #define DRIVER_DESC "PS/2 mouse driver" |
| 35 | 36 | ||
| @@ -108,10 +109,10 @@ static struct workqueue_struct *kpsmoused_wq; | |||
| 108 | 109 | ||
| 109 | struct psmouse_protocol { | 110 | struct psmouse_protocol { |
| 110 | enum psmouse_type type; | 111 | enum psmouse_type type; |
| 112 | bool maxproto; | ||
| 111 | const char *name; | 113 | const char *name; |
| 112 | const char *alias; | 114 | const char *alias; |
| 113 | int maxproto; | 115 | int (*detect)(struct psmouse *, bool); |
| 114 | int (*detect)(struct psmouse *, int); | ||
| 115 | int (*init)(struct psmouse *); | 116 | int (*init)(struct psmouse *); |
| 116 | }; | 117 | }; |
| 117 | 118 | ||
| @@ -216,7 +217,7 @@ void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work, | |||
| 216 | static inline void __psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state) | 217 | static inline void __psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state) |
| 217 | { | 218 | { |
| 218 | psmouse->state = new_state; | 219 | psmouse->state = new_state; |
| 219 | psmouse->pktcnt = psmouse->out_of_sync = 0; | 220 | psmouse->pktcnt = psmouse->out_of_sync_cnt = 0; |
| 220 | psmouse->ps2dev.flags = 0; | 221 | psmouse->ps2dev.flags = 0; |
| 221 | psmouse->last = jiffies; | 222 | psmouse->last = jiffies; |
| 222 | } | 223 | } |
| @@ -249,7 +250,7 @@ static int psmouse_handle_byte(struct psmouse *psmouse) | |||
| 249 | if (psmouse->state == PSMOUSE_ACTIVATED) { | 250 | if (psmouse->state == PSMOUSE_ACTIVATED) { |
| 250 | printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n", | 251 | printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n", |
| 251 | psmouse->name, psmouse->phys, psmouse->pktcnt); | 252 | psmouse->name, psmouse->phys, psmouse->pktcnt); |
| 252 | if (++psmouse->out_of_sync == psmouse->resetafter) { | 253 | if (++psmouse->out_of_sync_cnt == psmouse->resetafter) { |
| 253 | __psmouse_set_state(psmouse, PSMOUSE_IGNORE); | 254 | __psmouse_set_state(psmouse, PSMOUSE_IGNORE); |
| 254 | printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n"); | 255 | printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n"); |
| 255 | serio_reconnect(psmouse->ps2dev.serio); | 256 | serio_reconnect(psmouse->ps2dev.serio); |
| @@ -261,8 +262,8 @@ static int psmouse_handle_byte(struct psmouse *psmouse) | |||
| 261 | 262 | ||
| 262 | case PSMOUSE_FULL_PACKET: | 263 | case PSMOUSE_FULL_PACKET: |
| 263 | psmouse->pktcnt = 0; | 264 | psmouse->pktcnt = 0; |
| 264 | if (psmouse->out_of_sync) { | 265 | if (psmouse->out_of_sync_cnt) { |
| 265 | psmouse->out_of_sync = 0; | 266 | psmouse->out_of_sync_cnt = 0; |
| 266 | printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n", | 267 | printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n", |
| 267 | psmouse->name, psmouse->phys); | 268 | psmouse->name, psmouse->phys); |
| 268 | } | 269 | } |
| @@ -408,7 +409,7 @@ int psmouse_reset(struct psmouse *psmouse) | |||
| 408 | /* | 409 | /* |
| 409 | * Genius NetMouse magic init. | 410 | * Genius NetMouse magic init. |
| 410 | */ | 411 | */ |
| 411 | static int genius_detect(struct psmouse *psmouse, int set_properties) | 412 | static int genius_detect(struct psmouse *psmouse, bool set_properties) |
| 412 | { | 413 | { |
| 413 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 414 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
| 414 | unsigned char param[4]; | 415 | unsigned char param[4]; |
| @@ -424,9 +425,9 @@ static int genius_detect(struct psmouse *psmouse, int set_properties) | |||
| 424 | return -1; | 425 | return -1; |
| 425 | 426 | ||
| 426 | if (set_properties) { | 427 | if (set_properties) { |
| 427 | set_bit(BTN_EXTRA, psmouse->dev->keybit); | 428 | __set_bit(BTN_EXTRA, psmouse->dev->keybit); |
| 428 | set_bit(BTN_SIDE, psmouse->dev->keybit); | 429 | __set_bit(BTN_SIDE, psmouse->dev->keybit); |
| 429 | set_bit(REL_WHEEL, psmouse->dev->relbit); | 430 | __set_bit(REL_WHEEL, psmouse->dev->relbit); |
| 430 | 431 | ||
| 431 | psmouse->vendor = "Genius"; | 432 | psmouse->vendor = "Genius"; |
| 432 | psmouse->name = "Mouse"; | 433 | psmouse->name = "Mouse"; |
| @@ -439,7 +440,7 @@ static int genius_detect(struct psmouse *psmouse, int set_properties) | |||
| 439 | /* | 440 | /* |
| 440 | * IntelliMouse magic init. | 441 | * IntelliMouse magic init. |
| 441 | */ | 442 | */ |
| 442 | static int intellimouse_detect(struct psmouse *psmouse, int set_properties) | 443 | static int intellimouse_detect(struct psmouse *psmouse, bool set_properties) |
| 443 | { | 444 | { |
| 444 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 445 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
| 445 | unsigned char param[2]; | 446 | unsigned char param[2]; |
| @@ -456,8 +457,8 @@ static int intellimouse_detect(struct psmouse *psmouse, int set_properties) | |||
| 456 | return -1; | 457 | return -1; |
| 457 | 458 | ||
| 458 | if (set_properties) { | 459 | if (set_properties) { |
| 459 | set_bit(BTN_MIDDLE, psmouse->dev->keybit); | 460 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); |
| 460 | set_bit(REL_WHEEL, psmouse->dev->relbit); | 461 | __set_bit(REL_WHEEL, psmouse->dev->relbit); |
| 461 | 462 | ||
| 462 | if (!psmouse->vendor) psmouse->vendor = "Generic"; | 463 | if (!psmouse->vendor) psmouse->vendor = "Generic"; |
| 463 | if (!psmouse->name) psmouse->name = "Wheel Mouse"; | 464 | if (!psmouse->name) psmouse->name = "Wheel Mouse"; |
| @@ -470,7 +471,7 @@ static int intellimouse_detect(struct psmouse *psmouse, int set_properties) | |||
| 470 | /* | 471 | /* |
| 471 | * Try IntelliMouse/Explorer magic init. | 472 | * Try IntelliMouse/Explorer magic init. |
| 472 | */ | 473 | */ |
| 473 | static int im_explorer_detect(struct psmouse *psmouse, int set_properties) | 474 | static int im_explorer_detect(struct psmouse *psmouse, bool set_properties) |
| 474 | { | 475 | { |
| 475 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 476 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
| 476 | unsigned char param[2]; | 477 | unsigned char param[2]; |
| @@ -497,11 +498,11 @@ static int im_explorer_detect(struct psmouse *psmouse, int set_properties) | |||
| 497 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); | 498 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); |
| 498 | 499 | ||
| 499 | if (set_properties) { | 500 | if (set_properties) { |
| 500 | set_bit(BTN_MIDDLE, psmouse->dev->keybit); | 501 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); |
| 501 | set_bit(REL_WHEEL, psmouse->dev->relbit); | 502 | __set_bit(REL_WHEEL, psmouse->dev->relbit); |
| 502 | set_bit(REL_HWHEEL, psmouse->dev->relbit); | 503 | __set_bit(REL_HWHEEL, psmouse->dev->relbit); |
| 503 | set_bit(BTN_SIDE, psmouse->dev->keybit); | 504 | __set_bit(BTN_SIDE, psmouse->dev->keybit); |
| 504 | set_bit(BTN_EXTRA, psmouse->dev->keybit); | 505 | __set_bit(BTN_EXTRA, psmouse->dev->keybit); |
| 505 | 506 | ||
| 506 | if (!psmouse->vendor) psmouse->vendor = "Generic"; | 507 | if (!psmouse->vendor) psmouse->vendor = "Generic"; |
| 507 | if (!psmouse->name) psmouse->name = "Explorer Mouse"; | 508 | if (!psmouse->name) psmouse->name = "Explorer Mouse"; |
| @@ -514,7 +515,7 @@ static int im_explorer_detect(struct psmouse *psmouse, int set_properties) | |||
| 514 | /* | 515 | /* |
| 515 | * Kensington ThinkingMouse / ExpertMouse magic init. | 516 | * Kensington ThinkingMouse / ExpertMouse magic init. |
| 516 | */ | 517 | */ |
| 517 | static int thinking_detect(struct psmouse *psmouse, int set_properties) | 518 | static int thinking_detect(struct psmouse *psmouse, bool set_properties) |
| 518 | { | 519 | { |
| 519 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 520 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
| 520 | unsigned char param[2]; | 521 | unsigned char param[2]; |
| @@ -535,7 +536,7 @@ static int thinking_detect(struct psmouse *psmouse, int set_properties) | |||
| 535 | return -1; | 536 | return -1; |
| 536 | 537 | ||
| 537 | if (set_properties) { | 538 | if (set_properties) { |
| 538 | set_bit(BTN_EXTRA, psmouse->dev->keybit); | 539 | __set_bit(BTN_EXTRA, psmouse->dev->keybit); |
| 539 | 540 | ||
| 540 | psmouse->vendor = "Kensington"; | 541 | psmouse->vendor = "Kensington"; |
| 541 | psmouse->name = "ThinkingMouse"; | 542 | psmouse->name = "ThinkingMouse"; |
| @@ -547,7 +548,7 @@ static int thinking_detect(struct psmouse *psmouse, int set_properties) | |||
| 547 | /* | 548 | /* |
| 548 | * Bare PS/2 protocol "detection". Always succeeds. | 549 | * Bare PS/2 protocol "detection". Always succeeds. |
| 549 | */ | 550 | */ |
| 550 | static int ps2bare_detect(struct psmouse *psmouse, int set_properties) | 551 | static int ps2bare_detect(struct psmouse *psmouse, bool set_properties) |
| 551 | { | 552 | { |
| 552 | if (set_properties) { | 553 | if (set_properties) { |
| 553 | if (!psmouse->vendor) psmouse->vendor = "Generic"; | 554 | if (!psmouse->vendor) psmouse->vendor = "Generic"; |
| @@ -561,12 +562,12 @@ static int ps2bare_detect(struct psmouse *psmouse, int set_properties) | |||
| 561 | * Cortron PS/2 protocol detection. There's no special way to detect it, so it | 562 | * Cortron PS/2 protocol detection. There's no special way to detect it, so it |
| 562 | * must be forced by sysfs protocol writing. | 563 | * must be forced by sysfs protocol writing. |
| 563 | */ | 564 | */ |
| 564 | static int cortron_detect(struct psmouse *psmouse, int set_properties) | 565 | static int cortron_detect(struct psmouse *psmouse, bool set_properties) |
| 565 | { | 566 | { |
| 566 | if (set_properties) { | 567 | if (set_properties) { |
| 567 | psmouse->vendor = "Cortron"; | 568 | psmouse->vendor = "Cortron"; |
| 568 | psmouse->name = "PS/2 Trackball"; | 569 | psmouse->name = "PS/2 Trackball"; |
| 569 | set_bit(BTN_SIDE, psmouse->dev->keybit); | 570 | __set_bit(BTN_SIDE, psmouse->dev->keybit); |
| 570 | } | 571 | } |
| 571 | 572 | ||
| 572 | return 0; | 573 | return 0; |
| @@ -578,9 +579,9 @@ static int cortron_detect(struct psmouse *psmouse, int set_properties) | |||
| 578 | */ | 579 | */ |
| 579 | 580 | ||
| 580 | static int psmouse_extensions(struct psmouse *psmouse, | 581 | static int psmouse_extensions(struct psmouse *psmouse, |
| 581 | unsigned int max_proto, int set_properties) | 582 | unsigned int max_proto, bool set_properties) |
| 582 | { | 583 | { |
| 583 | int synaptics_hardware = 0; | 584 | bool synaptics_hardware = true; |
| 584 | 585 | ||
| 585 | /* | 586 | /* |
| 586 | * We always check for lifebook because it does not disturb mouse | 587 | * We always check for lifebook because it does not disturb mouse |
| @@ -607,7 +608,7 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
| 607 | * can reset it properly after probing for intellimouse. | 608 | * can reset it properly after probing for intellimouse. |
| 608 | */ | 609 | */ |
| 609 | if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse, set_properties) == 0) { | 610 | if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse, set_properties) == 0) { |
| 610 | synaptics_hardware = 1; | 611 | synaptics_hardware = true; |
| 611 | 612 | ||
| 612 | if (max_proto > PSMOUSE_IMEX) { | 613 | if (max_proto > PSMOUSE_IMEX) { |
| 613 | if (!set_properties || synaptics_init(psmouse) == 0) | 614 | if (!set_properties || synaptics_init(psmouse) == 0) |
| @@ -666,6 +667,20 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
| 666 | max_proto = PSMOUSE_IMEX; | 667 | max_proto = PSMOUSE_IMEX; |
| 667 | } | 668 | } |
| 668 | 669 | ||
| 670 | /* | ||
| 671 | * Try Finger Sensing Pad | ||
| 672 | */ | ||
| 673 | if (max_proto > PSMOUSE_IMEX) { | ||
| 674 | if (fsp_detect(psmouse, set_properties) == 0) { | ||
| 675 | if (!set_properties || fsp_init(psmouse) == 0) | ||
| 676 | return PSMOUSE_FSP; | ||
| 677 | /* | ||
| 678 | * Init failed, try basic relative protocols | ||
| 679 | */ | ||
| 680 | max_proto = PSMOUSE_IMEX; | ||
| 681 | } | ||
| 682 | } | ||
| 683 | |||
| 669 | if (max_proto > PSMOUSE_IMEX) { | 684 | if (max_proto > PSMOUSE_IMEX) { |
| 670 | if (genius_detect(psmouse, set_properties) == 0) | 685 | if (genius_detect(psmouse, set_properties) == 0) |
| 671 | return PSMOUSE_GENPS; | 686 | return PSMOUSE_GENPS; |
| @@ -718,7 +733,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
| 718 | .type = PSMOUSE_PS2, | 733 | .type = PSMOUSE_PS2, |
| 719 | .name = "PS/2", | 734 | .name = "PS/2", |
| 720 | .alias = "bare", | 735 | .alias = "bare", |
| 721 | .maxproto = 1, | 736 | .maxproto = true, |
| 722 | .detect = ps2bare_detect, | 737 | .detect = ps2bare_detect, |
| 723 | }, | 738 | }, |
| 724 | #ifdef CONFIG_MOUSE_PS2_LOGIPS2PP | 739 | #ifdef CONFIG_MOUSE_PS2_LOGIPS2PP |
| @@ -745,14 +760,14 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
| 745 | .type = PSMOUSE_IMPS, | 760 | .type = PSMOUSE_IMPS, |
| 746 | .name = "ImPS/2", | 761 | .name = "ImPS/2", |
| 747 | .alias = "imps", | 762 | .alias = "imps", |
| 748 | .maxproto = 1, | 763 | .maxproto = true, |
| 749 | .detect = intellimouse_detect, | 764 | .detect = intellimouse_detect, |
| 750 | }, | 765 | }, |
| 751 | { | 766 | { |
| 752 | .type = PSMOUSE_IMEX, | 767 | .type = PSMOUSE_IMEX, |
| 753 | .name = "ImExPS/2", | 768 | .name = "ImExPS/2", |
| 754 | .alias = "exps", | 769 | .alias = "exps", |
| 755 | .maxproto = 1, | 770 | .maxproto = true, |
| 756 | .detect = im_explorer_detect, | 771 | .detect = im_explorer_detect, |
| 757 | }, | 772 | }, |
| 758 | #ifdef CONFIG_MOUSE_PS2_SYNAPTICS | 773 | #ifdef CONFIG_MOUSE_PS2_SYNAPTICS |
| @@ -813,7 +828,16 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
| 813 | .detect = elantech_detect, | 828 | .detect = elantech_detect, |
| 814 | .init = elantech_init, | 829 | .init = elantech_init, |
| 815 | }, | 830 | }, |
| 816 | #endif | 831 | #endif |
| 832 | #ifdef CONFIG_MOUSE_PS2_SENTELIC | ||
| 833 | { | ||
| 834 | .type = PSMOUSE_FSP, | ||
| 835 | .name = "FSPPS/2", | ||
| 836 | .alias = "fsp", | ||
| 837 | .detect = fsp_detect, | ||
| 838 | .init = fsp_init, | ||
| 839 | }, | ||
| 840 | #endif | ||
| 817 | { | 841 | { |
| 818 | .type = PSMOUSE_CORTRON, | 842 | .type = PSMOUSE_CORTRON, |
| 819 | .name = "CortronPS/2", | 843 | .name = "CortronPS/2", |
| @@ -824,7 +848,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
| 824 | .type = PSMOUSE_AUTO, | 848 | .type = PSMOUSE_AUTO, |
| 825 | .name = "auto", | 849 | .name = "auto", |
| 826 | .alias = "any", | 850 | .alias = "any", |
| 827 | .maxproto = 1, | 851 | .maxproto = true, |
| 828 | }, | 852 | }, |
| 829 | }; | 853 | }; |
| 830 | 854 | ||
| @@ -990,7 +1014,7 @@ static void psmouse_resync(struct work_struct *work) | |||
| 990 | container_of(work, struct psmouse, resync_work.work); | 1014 | container_of(work, struct psmouse, resync_work.work); |
| 991 | struct serio *serio = psmouse->ps2dev.serio; | 1015 | struct serio *serio = psmouse->ps2dev.serio; |
| 992 | psmouse_ret_t rc = PSMOUSE_GOOD_DATA; | 1016 | psmouse_ret_t rc = PSMOUSE_GOOD_DATA; |
| 993 | int failed = 0, enabled = 0; | 1017 | bool failed = false, enabled = false; |
| 994 | int i; | 1018 | int i; |
| 995 | 1019 | ||
| 996 | mutex_lock(&psmouse_mutex); | 1020 | mutex_lock(&psmouse_mutex); |
| @@ -1017,9 +1041,9 @@ static void psmouse_resync(struct work_struct *work) | |||
| 1017 | 1041 | ||
| 1018 | if (ps2_sendbyte(&psmouse->ps2dev, PSMOUSE_CMD_DISABLE, 20)) { | 1042 | if (ps2_sendbyte(&psmouse->ps2dev, PSMOUSE_CMD_DISABLE, 20)) { |
| 1019 | if (psmouse->num_resyncs < 3 || psmouse->acks_disable_command) | 1043 | if (psmouse->num_resyncs < 3 || psmouse->acks_disable_command) |
| 1020 | failed = 1; | 1044 | failed = true; |
| 1021 | } else | 1045 | } else |
| 1022 | psmouse->acks_disable_command = 1; | 1046 | psmouse->acks_disable_command = true; |
| 1023 | 1047 | ||
| 1024 | /* | 1048 | /* |
| 1025 | * Poll the mouse. If it was reset the packet will be shorter than | 1049 | * Poll the mouse. If it was reset the packet will be shorter than |
| @@ -1030,7 +1054,7 @@ static void psmouse_resync(struct work_struct *work) | |||
| 1030 | */ | 1054 | */ |
| 1031 | if (!failed) { | 1055 | if (!failed) { |
| 1032 | if (psmouse->poll(psmouse)) | 1056 | if (psmouse->poll(psmouse)) |
| 1033 | failed = 1; | 1057 | failed = true; |
| 1034 | else { | 1058 | else { |
| 1035 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); | 1059 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); |
| 1036 | for (i = 0; i < psmouse->pktsize; i++) { | 1060 | for (i = 0; i < psmouse->pktsize; i++) { |
| @@ -1040,7 +1064,7 @@ static void psmouse_resync(struct work_struct *work) | |||
| 1040 | break; | 1064 | break; |
| 1041 | } | 1065 | } |
| 1042 | if (rc != PSMOUSE_FULL_PACKET) | 1066 | if (rc != PSMOUSE_FULL_PACKET) |
| 1043 | failed = 1; | 1067 | failed = true; |
| 1044 | psmouse_set_state(psmouse, PSMOUSE_RESYNCING); | 1068 | psmouse_set_state(psmouse, PSMOUSE_RESYNCING); |
| 1045 | } | 1069 | } |
| 1046 | } | 1070 | } |
| @@ -1051,7 +1075,7 @@ static void psmouse_resync(struct work_struct *work) | |||
| 1051 | */ | 1075 | */ |
| 1052 | for (i = 0; i < 5; i++) { | 1076 | for (i = 0; i < 5; i++) { |
| 1053 | if (!ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE)) { | 1077 | if (!ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE)) { |
| 1054 | enabled = 1; | 1078 | enabled = true; |
| 1055 | break; | 1079 | break; |
| 1056 | } | 1080 | } |
| 1057 | msleep(200); | 1081 | msleep(200); |
| @@ -1060,7 +1084,7 @@ static void psmouse_resync(struct work_struct *work) | |||
| 1060 | if (!enabled) { | 1084 | if (!enabled) { |
| 1061 | printk(KERN_WARNING "psmouse.c: failed to re-enable mouse on %s\n", | 1085 | printk(KERN_WARNING "psmouse.c: failed to re-enable mouse on %s\n", |
| 1062 | psmouse->ps2dev.serio->phys); | 1086 | psmouse->ps2dev.serio->phys); |
| 1063 | failed = 1; | 1087 | failed = true; |
| 1064 | } | 1088 | } |
| 1065 | 1089 | ||
| 1066 | if (failed) { | 1090 | if (failed) { |
| @@ -1187,7 +1211,8 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, const struct psmouse | |||
| 1187 | psmouse->type = proto->type; | 1211 | psmouse->type = proto->type; |
| 1188 | } | 1212 | } |
| 1189 | else | 1213 | else |
| 1190 | psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1); | 1214 | psmouse->type = psmouse_extensions(psmouse, |
| 1215 | psmouse_max_proto, true); | ||
| 1191 | 1216 | ||
| 1192 | /* | 1217 | /* |
| 1193 | * If mouse's packet size is 3 there is no point in polling the | 1218 | * If mouse's packet size is 3 there is no point in polling the |
| @@ -1342,8 +1367,10 @@ static int psmouse_reconnect(struct serio *serio) | |||
| 1342 | if (psmouse->reconnect(psmouse)) | 1367 | if (psmouse->reconnect(psmouse)) |
| 1343 | goto out; | 1368 | goto out; |
| 1344 | } else if (psmouse_probe(psmouse) < 0 || | 1369 | } else if (psmouse_probe(psmouse) < 0 || |
| 1345 | psmouse->type != psmouse_extensions(psmouse, psmouse_max_proto, 0)) | 1370 | psmouse->type != psmouse_extensions(psmouse, |
| 1371 | psmouse_max_proto, false)) { | ||
| 1346 | goto out; | 1372 | goto out; |
| 1373 | } | ||
| 1347 | 1374 | ||
| 1348 | /* ok, the device type (and capabilities) match the old one, | 1375 | /* ok, the device type (and capabilities) match the old one, |
| 1349 | * we can continue using it, complete intialization | 1376 | * we can continue using it, complete intialization |
| @@ -1528,7 +1555,9 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co | |||
| 1528 | 1555 | ||
| 1529 | while (serio->child) { | 1556 | while (serio->child) { |
| 1530 | if (++retry > 3) { | 1557 | if (++retry > 3) { |
| 1531 | printk(KERN_WARNING "psmouse: failed to destroy child port, protocol change aborted.\n"); | 1558 | printk(KERN_WARNING |
| 1559 | "psmouse: failed to destroy child port, " | ||
| 1560 | "protocol change aborted.\n"); | ||
| 1532 | input_free_device(new_dev); | 1561 | input_free_device(new_dev); |
| 1533 | return -EIO; | 1562 | return -EIO; |
| 1534 | } | 1563 | } |
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h index 54ed267894bd..e053bdd137ff 100644 --- a/drivers/input/mouse/psmouse.h +++ b/drivers/input/mouse/psmouse.h | |||
| @@ -47,10 +47,10 @@ struct psmouse { | |||
| 47 | unsigned char pktcnt; | 47 | unsigned char pktcnt; |
| 48 | unsigned char pktsize; | 48 | unsigned char pktsize; |
| 49 | unsigned char type; | 49 | unsigned char type; |
| 50 | unsigned char acks_disable_command; | 50 | bool acks_disable_command; |
| 51 | unsigned int model; | 51 | unsigned int model; |
| 52 | unsigned long last; | 52 | unsigned long last; |
| 53 | unsigned long out_of_sync; | 53 | unsigned long out_of_sync_cnt; |
| 54 | unsigned long num_resyncs; | 54 | unsigned long num_resyncs; |
| 55 | enum psmouse_state state; | 55 | enum psmouse_state state; |
| 56 | char devname[64]; | 56 | char devname[64]; |
| @@ -60,7 +60,7 @@ struct psmouse { | |||
| 60 | unsigned int resolution; | 60 | unsigned int resolution; |
| 61 | unsigned int resetafter; | 61 | unsigned int resetafter; |
| 62 | unsigned int resync_time; | 62 | unsigned int resync_time; |
| 63 | unsigned int smartscroll; /* Logitech only */ | 63 | bool smartscroll; /* Logitech only */ |
| 64 | 64 | ||
| 65 | psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse); | 65 | psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse); |
| 66 | void (*set_rate)(struct psmouse *psmouse, unsigned int rate); | 66 | void (*set_rate)(struct psmouse *psmouse, unsigned int rate); |
| @@ -91,6 +91,7 @@ enum psmouse_type { | |||
| 91 | PSMOUSE_CORTRON, | 91 | PSMOUSE_CORTRON, |
| 92 | PSMOUSE_HGPK, | 92 | PSMOUSE_HGPK, |
| 93 | PSMOUSE_ELANTECH, | 93 | PSMOUSE_ELANTECH, |
| 94 | PSMOUSE_FSP, | ||
| 94 | PSMOUSE_AUTO /* This one should always be last */ | 95 | PSMOUSE_AUTO /* This one should always be last */ |
| 95 | }; | 96 | }; |
| 96 | 97 | ||
| @@ -107,7 +108,7 @@ struct psmouse_attribute { | |||
| 107 | ssize_t (*show)(struct psmouse *psmouse, void *data, char *buf); | 108 | ssize_t (*show)(struct psmouse *psmouse, void *data, char *buf); |
| 108 | ssize_t (*set)(struct psmouse *psmouse, void *data, | 109 | ssize_t (*set)(struct psmouse *psmouse, void *data, |
| 109 | const char *buf, size_t count); | 110 | const char *buf, size_t count); |
| 110 | int protect; | 111 | bool protect; |
| 111 | }; | 112 | }; |
| 112 | #define to_psmouse_attr(a) container_of((a), struct psmouse_attribute, dattr) | 113 | #define to_psmouse_attr(a) container_of((a), struct psmouse_attribute, dattr) |
| 113 | 114 | ||
| @@ -116,9 +117,7 @@ ssize_t psmouse_attr_show_helper(struct device *dev, struct device_attribute *at | |||
| 116 | ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *attr, | 117 | ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *attr, |
| 117 | const char *buf, size_t count); | 118 | const char *buf, size_t count); |
| 118 | 119 | ||
| 119 | #define __PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, _protect) \ | 120 | #define __PSMOUSE_DEFINE_ATTR_VAR(_name, _mode, _data, _show, _set, _protect) \ |
| 120 | static ssize_t _show(struct psmouse *, void *data, char *); \ | ||
| 121 | static ssize_t _set(struct psmouse *, void *data, const char *, size_t); \ | ||
| 122 | static struct psmouse_attribute psmouse_attr_##_name = { \ | 121 | static struct psmouse_attribute psmouse_attr_##_name = { \ |
| 123 | .dattr = { \ | 122 | .dattr = { \ |
| 124 | .attr = { \ | 123 | .attr = { \ |
| @@ -134,7 +133,20 @@ static struct psmouse_attribute psmouse_attr_##_name = { \ | |||
| 134 | .protect = _protect, \ | 133 | .protect = _protect, \ |
| 135 | } | 134 | } |
| 136 | 135 | ||
| 137 | #define PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set) \ | 136 | #define __PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, _protect) \ |
| 138 | __PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, 1) | 137 | static ssize_t _show(struct psmouse *, void *, char *); \ |
| 138 | static ssize_t _set(struct psmouse *, void *, const char *, size_t); \ | ||
| 139 | __PSMOUSE_DEFINE_ATTR_VAR(_name, _mode, _data, _show, _set, _protect) | ||
| 140 | |||
| 141 | #define PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set) \ | ||
| 142 | __PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, true) | ||
| 143 | |||
| 144 | #define PSMOUSE_DEFINE_RO_ATTR(_name, _mode, _data, _show) \ | ||
| 145 | static ssize_t _show(struct psmouse *, void *, char *); \ | ||
| 146 | __PSMOUSE_DEFINE_ATTR_VAR(_name, _mode, _data, _show, NULL, true) | ||
| 147 | |||
| 148 | #define PSMOUSE_DEFINE_WO_ATTR(_name, _mode, _data, _set) \ | ||
| 149 | static ssize_t _set(struct psmouse *, void *, const char *, size_t); \ | ||
| 150 | __PSMOUSE_DEFINE_ATTR_VAR(_name, _mode, _data, NULL, _set, true) | ||
| 139 | 151 | ||
| 140 | #endif /* _PSMOUSE_H */ | 152 | #endif /* _PSMOUSE_H */ |
diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c new file mode 100644 index 000000000000..84e2fc04d11b --- /dev/null +++ b/drivers/input/mouse/sentelic.c | |||
| @@ -0,0 +1,867 @@ | |||
| 1 | /*- | ||
| 2 | * Finger Sensing Pad PS/2 mouse driver. | ||
| 3 | * | ||
| 4 | * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd. | ||
| 5 | * Copyright (C) 2005-2009 Tai-hwa Liang, Sentelic Corporation. | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License | ||
| 9 | * as published by the Free Software Foundation; either version 2 | ||
| 10 | * of the License, or (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include <linux/module.h> | ||
| 23 | #include <linux/version.h> | ||
| 24 | #include <linux/input.h> | ||
| 25 | #include <linux/ctype.h> | ||
| 26 | #include <linux/libps2.h> | ||
| 27 | #include <linux/serio.h> | ||
| 28 | #include <linux/jiffies.h> | ||
| 29 | |||
| 30 | #include "psmouse.h" | ||
| 31 | #include "sentelic.h" | ||
| 32 | |||
| 33 | /* | ||
| 34 | * Timeout for FSP PS/2 command only (in milliseconds). | ||
| 35 | */ | ||
| 36 | #define FSP_CMD_TIMEOUT 200 | ||
| 37 | #define FSP_CMD_TIMEOUT2 30 | ||
| 38 | |||
| 39 | /** Driver version. */ | ||
| 40 | static const char fsp_drv_ver[] = "1.0.0-K"; | ||
| 41 | |||
| 42 | /* | ||
| 43 | * Make sure that the value being sent to FSP will not conflict with | ||
| 44 | * possible sample rate values. | ||
| 45 | */ | ||
| 46 | static unsigned char fsp_test_swap_cmd(unsigned char reg_val) | ||
| 47 | { | ||
| 48 | switch (reg_val) { | ||
| 49 | case 10: case 20: case 40: case 60: case 80: case 100: case 200: | ||
| 50 | /* | ||
| 51 | * The requested value being sent to FSP matched to possible | ||
| 52 | * sample rates, swap the given value such that the hardware | ||
| 53 | * wouldn't get confused. | ||
| 54 | */ | ||
| 55 | return (reg_val >> 4) | (reg_val << 4); | ||
| 56 | default: | ||
| 57 | return reg_val; /* swap isn't necessary */ | ||
| 58 | } | ||
| 59 | } | ||
| 60 | |||
| 61 | /* | ||
| 62 | * Make sure that the value being sent to FSP will not conflict with certain | ||
| 63 | * commands. | ||
| 64 | */ | ||
| 65 | static unsigned char fsp_test_invert_cmd(unsigned char reg_val) | ||
| 66 | { | ||
| 67 | switch (reg_val) { | ||
| 68 | case 0xe9: case 0xee: case 0xf2: case 0xff: | ||
| 69 | /* | ||
| 70 | * The requested value being sent to FSP matched to certain | ||
| 71 | * commands, inverse the given value such that the hardware | ||
| 72 | * wouldn't get confused. | ||
| 73 | */ | ||
| 74 | return ~reg_val; | ||
| 75 | default: | ||
| 76 | return reg_val; /* inversion isn't necessary */ | ||
| 77 | } | ||
| 78 | } | ||
| 79 | |||
| 80 | static int fsp_reg_read(struct psmouse *psmouse, int reg_addr, int *reg_val) | ||
| 81 | { | ||
| 82 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
| 83 | unsigned char param[3]; | ||
| 84 | unsigned char addr; | ||
| 85 | int rc = -1; | ||
| 86 | |||
| 87 | /* | ||
| 88 | * We need to shut off the device and switch it into command | ||
| 89 | * mode so we don't confuse our protocol handler. We don't need | ||
| 90 | * to do that for writes because sysfs set helper does this for | ||
| 91 | * us. | ||
| 92 | */ | ||
| 93 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE); | ||
| 94 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); | ||
| 95 | mutex_lock(&ps2dev->cmd_mutex); | ||
| 96 | |||
| 97 | if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) | ||
| 98 | goto out; | ||
| 99 | |||
| 100 | /* should return 0xfe(request for resending) */ | ||
| 101 | ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2); | ||
| 102 | /* should return 0xfc(failed) */ | ||
| 103 | ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2); | ||
| 104 | |||
| 105 | if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) | ||
| 106 | goto out; | ||
| 107 | |||
| 108 | if ((addr = fsp_test_invert_cmd(reg_addr)) != reg_addr) { | ||
| 109 | ps2_sendbyte(ps2dev, 0x68, FSP_CMD_TIMEOUT2); | ||
| 110 | } else if ((addr = fsp_test_swap_cmd(reg_addr)) != reg_addr) { | ||
| 111 | /* swapping is required */ | ||
| 112 | ps2_sendbyte(ps2dev, 0xcc, FSP_CMD_TIMEOUT2); | ||
| 113 | /* expect 0xfe */ | ||
| 114 | } else { | ||
| 115 | /* swapping isn't necessary */ | ||
| 116 | ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2); | ||
| 117 | /* expect 0xfe */ | ||
| 118 | } | ||
| 119 | /* should return 0xfc(failed) */ | ||
| 120 | ps2_sendbyte(ps2dev, addr, FSP_CMD_TIMEOUT); | ||
| 121 | |||
| 122 | if (__ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO) < 0) | ||
| 123 | goto out; | ||
| 124 | |||
| 125 | *reg_val = param[2]; | ||
| 126 | rc = 0; | ||
| 127 | |||
| 128 | out: | ||
| 129 | mutex_unlock(&ps2dev->cmd_mutex); | ||
| 130 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE); | ||
| 131 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); | ||
| 132 | dev_dbg(&ps2dev->serio->dev, "READ REG: 0x%02x is 0x%02x (rc = %d)\n", | ||
| 133 | reg_addr, *reg_val, rc); | ||
| 134 | return rc; | ||
| 135 | } | ||
| 136 | |||
| 137 | static int fsp_reg_write(struct psmouse *psmouse, int reg_addr, int reg_val) | ||
| 138 | { | ||
| 139 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
| 140 | unsigned char v; | ||
| 141 | int rc = -1; | ||
| 142 | |||
| 143 | mutex_lock(&ps2dev->cmd_mutex); | ||
| 144 | |||
| 145 | if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) | ||
| 146 | goto out; | ||
| 147 | |||
| 148 | if ((v = fsp_test_invert_cmd(reg_addr)) != reg_addr) { | ||
| 149 | /* inversion is required */ | ||
| 150 | ps2_sendbyte(ps2dev, 0x74, FSP_CMD_TIMEOUT2); | ||
| 151 | } else { | ||
| 152 | if ((v = fsp_test_swap_cmd(reg_addr)) != reg_addr) { | ||
| 153 | /* swapping is required */ | ||
| 154 | ps2_sendbyte(ps2dev, 0x77, FSP_CMD_TIMEOUT2); | ||
| 155 | } else { | ||
| 156 | /* swapping isn't necessary */ | ||
| 157 | ps2_sendbyte(ps2dev, 0x55, FSP_CMD_TIMEOUT2); | ||
| 158 | } | ||
| 159 | } | ||
| 160 | /* write the register address in correct order */ | ||
| 161 | ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2); | ||
| 162 | |||
| 163 | if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) | ||
| 164 | return -1; | ||
| 165 | |||
| 166 | if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) { | ||
| 167 | /* inversion is required */ | ||
| 168 | ps2_sendbyte(ps2dev, 0x47, FSP_CMD_TIMEOUT2); | ||
| 169 | } else if ((v = fsp_test_swap_cmd(reg_val)) != reg_val) { | ||
| 170 | /* swapping is required */ | ||
| 171 | ps2_sendbyte(ps2dev, 0x44, FSP_CMD_TIMEOUT2); | ||
| 172 | } else { | ||
| 173 | /* swapping isn't necessary */ | ||
| 174 | ps2_sendbyte(ps2dev, 0x33, FSP_CMD_TIMEOUT2); | ||
| 175 | } | ||
| 176 | |||
| 177 | /* write the register value in correct order */ | ||
| 178 | ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2); | ||
| 179 | rc = 0; | ||
| 180 | |||
| 181 | out: | ||
| 182 | mutex_unlock(&ps2dev->cmd_mutex); | ||
| 183 | dev_dbg(&ps2dev->serio->dev, "WRITE REG: 0x%02x to 0x%02x (rc = %d)\n", | ||
| 184 | reg_addr, reg_val, rc); | ||
| 185 | return rc; | ||
| 186 | } | ||
| 187 | |||
| 188 | /* Enable register clock gating for writing certain registers */ | ||
| 189 | static int fsp_reg_write_enable(struct psmouse *psmouse, bool enable) | ||
| 190 | { | ||
| 191 | int v, nv; | ||
| 192 | |||
| 193 | if (fsp_reg_read(psmouse, FSP_REG_SYSCTL1, &v) == -1) | ||
| 194 | return -1; | ||
| 195 | |||
| 196 | if (enable) | ||
| 197 | nv = v | FSP_BIT_EN_REG_CLK; | ||
| 198 | else | ||
| 199 | nv = v & ~FSP_BIT_EN_REG_CLK; | ||
| 200 | |||
| 201 | /* only write if necessary */ | ||
| 202 | if (nv != v) | ||
| 203 | if (fsp_reg_write(psmouse, FSP_REG_SYSCTL1, nv) == -1) | ||
| 204 | return -1; | ||
| 205 | |||
| 206 | return 0; | ||
| 207 | } | ||
| 208 | |||
| 209 | static int fsp_page_reg_read(struct psmouse *psmouse, int *reg_val) | ||
| 210 | { | ||
| 211 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
| 212 | unsigned char param[3]; | ||
| 213 | int rc = -1; | ||
| 214 | |||
| 215 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE); | ||
| 216 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); | ||
| 217 | mutex_lock(&ps2dev->cmd_mutex); | ||
| 218 | |||
| 219 | if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) | ||
| 220 | goto out; | ||
| 221 | |||
| 222 | ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2); | ||
| 223 | ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2); | ||
| 224 | |||
| 225 | if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) | ||
| 226 | goto out; | ||
| 227 | |||
| 228 | ps2_sendbyte(ps2dev, 0x83, FSP_CMD_TIMEOUT2); | ||
| 229 | ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2); | ||
| 230 | |||
| 231 | /* get the returned result */ | ||
| 232 | if (__ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) | ||
| 233 | goto out; | ||
| 234 | |||
| 235 | *reg_val = param[2]; | ||
| 236 | rc = 0; | ||
| 237 | |||
| 238 | out: | ||
| 239 | mutex_unlock(&ps2dev->cmd_mutex); | ||
| 240 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE); | ||
| 241 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); | ||
| 242 | dev_dbg(&ps2dev->serio->dev, "READ PAGE REG: 0x%02x (rc = %d)\n", | ||
| 243 | *reg_val, rc); | ||
| 244 | return rc; | ||
| 245 | } | ||
| 246 | |||
| 247 | static int fsp_page_reg_write(struct psmouse *psmouse, int reg_val) | ||
| 248 | { | ||
| 249 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
| 250 | unsigned char v; | ||
| 251 | int rc = -1; | ||
| 252 | |||
| 253 | mutex_lock(&ps2dev->cmd_mutex); | ||
| 254 | |||
| 255 | if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) | ||
| 256 | goto out; | ||
| 257 | |||
| 258 | ps2_sendbyte(ps2dev, 0x38, FSP_CMD_TIMEOUT2); | ||
| 259 | ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2); | ||
| 260 | |||
| 261 | if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) | ||
| 262 | return -1; | ||
| 263 | |||
| 264 | if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) { | ||
| 265 | ps2_sendbyte(ps2dev, 0x47, FSP_CMD_TIMEOUT2); | ||
| 266 | } else if ((v = fsp_test_swap_cmd(reg_val)) != reg_val) { | ||
| 267 | /* swapping is required */ | ||
| 268 | ps2_sendbyte(ps2dev, 0x44, FSP_CMD_TIMEOUT2); | ||
| 269 | } else { | ||
| 270 | /* swapping isn't necessary */ | ||
| 271 | ps2_sendbyte(ps2dev, 0x33, FSP_CMD_TIMEOUT2); | ||
| 272 | } | ||
| 273 | |||
| 274 | ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2); | ||
| 275 | rc = 0; | ||
| 276 | |||
| 277 | out: | ||
| 278 | mutex_unlock(&ps2dev->cmd_mutex); | ||
| 279 | dev_dbg(&ps2dev->serio->dev, "WRITE PAGE REG: to 0x%02x (rc = %d)\n", | ||
| 280 | reg_val, rc); | ||
| 281 | return rc; | ||
| 282 | } | ||
| 283 | |||
| 284 | static int fsp_get_version(struct psmouse *psmouse, int *version) | ||
| 285 | { | ||
| 286 | if (fsp_reg_read(psmouse, FSP_REG_VERSION, version)) | ||
| 287 | return -EIO; | ||
| 288 | |||
| 289 | return 0; | ||
| 290 | } | ||
| 291 | |||
| 292 | static int fsp_get_revision(struct psmouse *psmouse, int *rev) | ||
| 293 | { | ||
| 294 | if (fsp_reg_read(psmouse, FSP_REG_REVISION, rev)) | ||
| 295 | return -EIO; | ||
| 296 | |||
| 297 | return 0; | ||
| 298 | } | ||
| 299 | |||
| 300 | static int fsp_get_buttons(struct psmouse *psmouse, int *btn) | ||
| 301 | { | ||
| 302 | static const int buttons[] = { | ||
| 303 | 0x16, /* Left/Middle/Right/Forward/Backward & Scroll Up/Down */ | ||
| 304 | 0x06, /* Left/Middle/Right & Scroll Up/Down/Right/Left */ | ||
| 305 | 0x04, /* Left/Middle/Right & Scroll Up/Down */ | ||
| 306 | 0x02, /* Left/Middle/Right */ | ||
| 307 | }; | ||
| 308 | int val; | ||
| 309 | |||
| 310 | if (fsp_reg_read(psmouse, FSP_REG_TMOD_STATUS1, &val) == -1) | ||
| 311 | return -EIO; | ||
| 312 | |||
| 313 | *btn = buttons[(val & 0x30) >> 4]; | ||
| 314 | return 0; | ||
| 315 | } | ||
| 316 | |||
| 317 | /* Enable on-pad command tag output */ | ||
| 318 | static int fsp_opc_tag_enable(struct psmouse *psmouse, bool enable) | ||
| 319 | { | ||
| 320 | int v, nv; | ||
| 321 | int res = 0; | ||
| 322 | |||
| 323 | if (fsp_reg_read(psmouse, FSP_REG_OPC_QDOWN, &v) == -1) { | ||
| 324 | dev_err(&psmouse->ps2dev.serio->dev, "Unable get OPC state.\n"); | ||
| 325 | return -EIO; | ||
| 326 | } | ||
| 327 | |||
| 328 | if (enable) | ||
| 329 | nv = v | FSP_BIT_EN_OPC_TAG; | ||
| 330 | else | ||
| 331 | nv = v & ~FSP_BIT_EN_OPC_TAG; | ||
| 332 | |||
| 333 | /* only write if necessary */ | ||
| 334 | if (nv != v) { | ||
| 335 | fsp_reg_write_enable(psmouse, true); | ||
| 336 | res = fsp_reg_write(psmouse, FSP_REG_OPC_QDOWN, nv); | ||
| 337 | fsp_reg_write_enable(psmouse, false); | ||
| 338 | } | ||
| 339 | |||
| 340 | if (res != 0) { | ||
| 341 | dev_err(&psmouse->ps2dev.serio->dev, | ||
| 342 | "Unable to enable OPC tag.\n"); | ||
| 343 | res = -EIO; | ||
| 344 | } | ||
| 345 | |||
| 346 | return res; | ||
| 347 | } | ||
| 348 | |||
| 349 | static int fsp_onpad_vscr(struct psmouse *psmouse, bool enable) | ||
| 350 | { | ||
| 351 | struct fsp_data *pad = psmouse->private; | ||
| 352 | int val; | ||
| 353 | |||
| 354 | if (fsp_reg_read(psmouse, FSP_REG_ONPAD_CTL, &val)) | ||
| 355 | return -EIO; | ||
| 356 | |||
| 357 | pad->vscroll = enable; | ||
| 358 | |||
| 359 | if (enable) | ||
| 360 | val |= (FSP_BIT_FIX_VSCR | FSP_BIT_ONPAD_ENABLE); | ||
| 361 | else | ||
| 362 | val &= ~FSP_BIT_FIX_VSCR; | ||
| 363 | |||
| 364 | if (fsp_reg_write(psmouse, FSP_REG_ONPAD_CTL, val)) | ||
| 365 | return -EIO; | ||
| 366 | |||
| 367 | return 0; | ||
| 368 | } | ||
| 369 | |||
| 370 | static int fsp_onpad_hscr(struct psmouse *psmouse, bool enable) | ||
| 371 | { | ||
| 372 | struct fsp_data *pad = psmouse->private; | ||
| 373 | int val, v2; | ||
| 374 | |||
| 375 | if (fsp_reg_read(psmouse, FSP_REG_ONPAD_CTL, &val)) | ||
| 376 | return -EIO; | ||
| 377 | |||
| 378 | if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &v2)) | ||
| 379 | return -EIO; | ||
| 380 | |||
| 381 | pad->hscroll = enable; | ||
| 382 | |||
| 383 | if (enable) { | ||
| 384 | val |= (FSP_BIT_FIX_HSCR | FSP_BIT_ONPAD_ENABLE); | ||
| 385 | v2 |= FSP_BIT_EN_MSID6; | ||
| 386 | } else { | ||
| 387 | val &= ~FSP_BIT_FIX_HSCR; | ||
| 388 | v2 &= ~(FSP_BIT_EN_MSID6 | FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8); | ||
| 389 | } | ||
| 390 | |||
| 391 | if (fsp_reg_write(psmouse, FSP_REG_ONPAD_CTL, val)) | ||
| 392 | return -EIO; | ||
| 393 | |||
| 394 | /* reconfigure horizontal scrolling packet output */ | ||
| 395 | if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, v2)) | ||
| 396 | return -EIO; | ||
| 397 | |||
| 398 | return 0; | ||
| 399 | } | ||
| 400 | |||
| 401 | /* | ||
| 402 | * Write device specific initial parameters. | ||
| 403 | * | ||
| 404 | * ex: 0xab 0xcd - write oxcd into register 0xab | ||
| 405 | */ | ||
| 406 | static ssize_t fsp_attr_set_setreg(struct psmouse *psmouse, void *data, | ||
| 407 | const char *buf, size_t count) | ||
| 408 | { | ||
| 409 | unsigned long reg, val; | ||
| 410 | char *rest; | ||
| 411 | ssize_t retval; | ||
| 412 | |||
| 413 | reg = simple_strtoul(buf, &rest, 16); | ||
| 414 | if (rest == buf || *rest != ' ' || reg > 0xff) | ||
| 415 | return -EINVAL; | ||
| 416 | |||
| 417 | if (strict_strtoul(rest + 1, 16, &val) || val > 0xff) | ||
| 418 | return -EINVAL; | ||
| 419 | |||
| 420 | if (fsp_reg_write_enable(psmouse, true)) | ||
| 421 | return -EIO; | ||
| 422 | |||
| 423 | retval = fsp_reg_write(psmouse, reg, val) < 0 ? -EIO : count; | ||
| 424 | |||
| 425 | fsp_reg_write_enable(psmouse, false); | ||
| 426 | |||
| 427 | return count; | ||
| 428 | } | ||
| 429 | |||
| 430 | PSMOUSE_DEFINE_WO_ATTR(setreg, S_IWUSR, NULL, fsp_attr_set_setreg); | ||
| 431 | |||
| 432 | static ssize_t fsp_attr_show_getreg(struct psmouse *psmouse, | ||
| 433 | void *data, char *buf) | ||
| 434 | { | ||
| 435 | struct fsp_data *pad = psmouse->private; | ||
| 436 | |||
| 437 | return sprintf(buf, "%02x%02x\n", pad->last_reg, pad->last_val); | ||
| 438 | } | ||
| 439 | |||
| 440 | /* | ||
| 441 | * Read a register from device. | ||
| 442 | * | ||
| 443 | * ex: 0xab -- read content from register 0xab | ||
| 444 | */ | ||
| 445 | static ssize_t fsp_attr_set_getreg(struct psmouse *psmouse, void *data, | ||
| 446 | const char *buf, size_t count) | ||
| 447 | { | ||
| 448 | struct fsp_data *pad = psmouse->private; | ||
| 449 | unsigned long reg; | ||
| 450 | int val; | ||
| 451 | |||
| 452 | if (strict_strtoul(buf, 16, ®) || reg > 0xff) | ||
| 453 | return -EINVAL; | ||
| 454 | |||
| 455 | if (fsp_reg_read(psmouse, reg, &val)) | ||
| 456 | return -EIO; | ||
| 457 | |||
| 458 | pad->last_reg = reg; | ||
| 459 | pad->last_val = val; | ||
| 460 | |||
| 461 | return count; | ||
| 462 | } | ||
| 463 | |||
| 464 | PSMOUSE_DEFINE_ATTR(getreg, S_IWUSR | S_IRUGO, NULL, | ||
| 465 | fsp_attr_show_getreg, fsp_attr_set_getreg); | ||
| 466 | |||
| 467 | static ssize_t fsp_attr_show_pagereg(struct psmouse *psmouse, | ||
| 468 | void *data, char *buf) | ||
| 469 | { | ||
| 470 | int val = 0; | ||
| 471 | |||
| 472 | if (fsp_page_reg_read(psmouse, &val)) | ||
| 473 | return -EIO; | ||
| 474 | |||
| 475 | return sprintf(buf, "%02x\n", val); | ||
| 476 | } | ||
| 477 | |||
| 478 | static ssize_t fsp_attr_set_pagereg(struct psmouse *psmouse, void *data, | ||
| 479 | const char *buf, size_t count) | ||
| 480 | { | ||
| 481 | unsigned long val; | ||
| 482 | |||
| 483 | if (strict_strtoul(buf, 16, &val) || val > 0xff) | ||
| 484 | return -EINVAL; | ||
| 485 | |||
| 486 | if (fsp_page_reg_write(psmouse, val)) | ||
| 487 | return -EIO; | ||
| 488 | |||
| 489 | return count; | ||
| 490 | } | ||
| 491 | |||
| 492 | PSMOUSE_DEFINE_ATTR(page, S_IWUSR | S_IRUGO, NULL, | ||
| 493 | fsp_attr_show_pagereg, fsp_attr_set_pagereg); | ||
| 494 | |||
| 495 | static ssize_t fsp_attr_show_vscroll(struct psmouse *psmouse, | ||
| 496 | void *data, char *buf) | ||
| 497 | { | ||
| 498 | struct fsp_data *pad = psmouse->private; | ||
| 499 | |||
| 500 | return sprintf(buf, "%d\n", pad->vscroll); | ||
| 501 | } | ||
| 502 | |||
| 503 | static ssize_t fsp_attr_set_vscroll(struct psmouse *psmouse, void *data, | ||
| 504 | const char *buf, size_t count) | ||
| 505 | { | ||
| 506 | unsigned long val; | ||
| 507 | |||
| 508 | if (strict_strtoul(buf, 10, &val) || val > 1) | ||
| 509 | return -EINVAL; | ||
| 510 | |||
| 511 | fsp_onpad_vscr(psmouse, val); | ||
| 512 | |||
| 513 | return count; | ||
| 514 | } | ||
| 515 | |||
| 516 | PSMOUSE_DEFINE_ATTR(vscroll, S_IWUSR | S_IRUGO, NULL, | ||
| 517 | fsp_attr_show_vscroll, fsp_attr_set_vscroll); | ||
| 518 | |||
| 519 | static ssize_t fsp_attr_show_hscroll(struct psmouse *psmouse, | ||
| 520 | void *data, char *buf) | ||
| 521 | { | ||
| 522 | struct fsp_data *pad = psmouse->private; | ||
| 523 | |||
| 524 | return sprintf(buf, "%d\n", pad->hscroll); | ||
| 525 | } | ||
| 526 | |||
| 527 | static ssize_t fsp_attr_set_hscroll(struct psmouse *psmouse, void *data, | ||
| 528 | const char *buf, size_t count) | ||
| 529 | { | ||
| 530 | unsigned long val; | ||
| 531 | |||
| 532 | if (strict_strtoul(buf, 10, &val) || val > 1) | ||
| 533 | return -EINVAL; | ||
| 534 | |||
| 535 | fsp_onpad_hscr(psmouse, val); | ||
| 536 | |||
| 537 | return count; | ||
| 538 | } | ||
| 539 | |||
| 540 | PSMOUSE_DEFINE_ATTR(hscroll, S_IWUSR | S_IRUGO, NULL, | ||
| 541 | fsp_attr_show_hscroll, fsp_attr_set_hscroll); | ||
| 542 | |||
| 543 | static ssize_t fsp_attr_show_flags(struct psmouse *psmouse, | ||
| 544 | void *data, char *buf) | ||
| 545 | { | ||
| 546 | struct fsp_data *pad = psmouse->private; | ||
| 547 | |||
| 548 | return sprintf(buf, "%c\n", | ||
| 549 | pad->flags & FSPDRV_FLAG_EN_OPC ? 'C' : 'c'); | ||
| 550 | } | ||
| 551 | |||
| 552 | static ssize_t fsp_attr_set_flags(struct psmouse *psmouse, void *data, | ||
| 553 | const char *buf, size_t count) | ||
| 554 | { | ||
| 555 | struct fsp_data *pad = psmouse->private; | ||
| 556 | size_t i; | ||
| 557 | |||
| 558 | for (i = 0; i < count; i++) { | ||
| 559 | switch (buf[i]) { | ||
| 560 | case 'C': | ||
| 561 | pad->flags |= FSPDRV_FLAG_EN_OPC; | ||
| 562 | break; | ||
| 563 | case 'c': | ||
| 564 | pad->flags &= ~FSPDRV_FLAG_EN_OPC; | ||
| 565 | break; | ||
| 566 | default: | ||
| 567 | return -EINVAL; | ||
| 568 | } | ||
| 569 | } | ||
| 570 | return count; | ||
| 571 | } | ||
| 572 | |||
| 573 | PSMOUSE_DEFINE_ATTR(flags, S_IWUSR | S_IRUGO, NULL, | ||
| 574 | fsp_attr_show_flags, fsp_attr_set_flags); | ||
| 575 | |||
| 576 | static ssize_t fsp_attr_show_ver(struct psmouse *psmouse, | ||
| 577 | void *data, char *buf) | ||
| 578 | { | ||
| 579 | return sprintf(buf, "Sentelic FSP kernel module %s\n", fsp_drv_ver); | ||
| 580 | } | ||
| 581 | |||
| 582 | PSMOUSE_DEFINE_RO_ATTR(ver, S_IRUGO, NULL, fsp_attr_show_ver); | ||
| 583 | |||
| 584 | static struct attribute *fsp_attributes[] = { | ||
| 585 | &psmouse_attr_setreg.dattr.attr, | ||
| 586 | &psmouse_attr_getreg.dattr.attr, | ||
| 587 | &psmouse_attr_page.dattr.attr, | ||
| 588 | &psmouse_attr_vscroll.dattr.attr, | ||
| 589 | &psmouse_attr_hscroll.dattr.attr, | ||
| 590 | &psmouse_attr_flags.dattr.attr, | ||
| 591 | &psmouse_attr_ver.dattr.attr, | ||
| 592 | NULL | ||
| 593 | }; | ||
| 594 | |||
| 595 | static struct attribute_group fsp_attribute_group = { | ||
| 596 | .attrs = fsp_attributes, | ||
| 597 | }; | ||
| 598 | |||
| 599 | #ifdef FSP_DEBUG | ||
| 600 | static void fsp_packet_debug(unsigned char packet[]) | ||
| 601 | { | ||
| 602 | static unsigned int ps2_packet_cnt; | ||
| 603 | static unsigned int ps2_last_second; | ||
| 604 | unsigned int jiffies_msec; | ||
| 605 | |||
| 606 | ps2_packet_cnt++; | ||
| 607 | jiffies_msec = jiffies_to_msecs(jiffies); | ||
| 608 | printk(KERN_DEBUG "%08dms PS/2 packets: %02x, %02x, %02x, %02x\n", | ||
| 609 | jiffies_msec, packet[0], packet[1], packet[2], packet[3]); | ||
| 610 | |||
| 611 | if (jiffies_msec - ps2_last_second > 1000) { | ||
| 612 | printk(KERN_DEBUG "PS/2 packets/sec = %d\n", ps2_packet_cnt); | ||
| 613 | ps2_packet_cnt = 0; | ||
| 614 | ps2_last_second = jiffies_msec; | ||
| 615 | } | ||
| 616 | } | ||
| 617 | #else | ||
| 618 | static void fsp_packet_debug(unsigned char packet[]) | ||
| 619 | { | ||
| 620 | } | ||
| 621 | #endif | ||
| 622 | |||
| 623 | static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse) | ||
| 624 | { | ||
| 625 | struct input_dev *dev = psmouse->dev; | ||
| 626 | struct fsp_data *ad = psmouse->private; | ||
| 627 | unsigned char *packet = psmouse->packet; | ||
| 628 | unsigned char button_status = 0, lscroll = 0, rscroll = 0; | ||
| 629 | int rel_x, rel_y; | ||
| 630 | |||
| 631 | if (psmouse->pktcnt < 4) | ||
| 632 | return PSMOUSE_GOOD_DATA; | ||
| 633 | |||
| 634 | /* | ||
| 635 | * Full packet accumulated, process it | ||
| 636 | */ | ||
| 637 | |||
| 638 | switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) { | ||
| 639 | case FSP_PKT_TYPE_ABS: | ||
| 640 | dev_warn(&psmouse->ps2dev.serio->dev, | ||
| 641 | "Unexpected absolute mode packet, ignored.\n"); | ||
| 642 | break; | ||
| 643 | |||
| 644 | case FSP_PKT_TYPE_NORMAL_OPC: | ||
| 645 | /* on-pad click, filter it if necessary */ | ||
| 646 | if ((ad->flags & FSPDRV_FLAG_EN_OPC) != FSPDRV_FLAG_EN_OPC) | ||
| 647 | packet[0] &= ~BIT(0); | ||
| 648 | /* fall through */ | ||
| 649 | |||
| 650 | case FSP_PKT_TYPE_NORMAL: | ||
| 651 | /* normal packet */ | ||
| 652 | /* special packet data translation from on-pad packets */ | ||
| 653 | if (packet[3] != 0) { | ||
| 654 | if (packet[3] & BIT(0)) | ||
| 655 | button_status |= 0x01; /* wheel down */ | ||
| 656 | if (packet[3] & BIT(1)) | ||
| 657 | button_status |= 0x0f; /* wheel up */ | ||
| 658 | if (packet[3] & BIT(2)) | ||
| 659 | button_status |= BIT(5);/* horizontal left */ | ||
| 660 | if (packet[3] & BIT(3)) | ||
| 661 | button_status |= BIT(4);/* horizontal right */ | ||
| 662 | /* push back to packet queue */ | ||
| 663 | if (button_status != 0) | ||
| 664 | packet[3] = button_status; | ||
| 665 | rscroll = (packet[3] >> 4) & 1; | ||
| 666 | lscroll = (packet[3] >> 5) & 1; | ||
| 667 | } | ||
| 668 | /* | ||
| 669 | * Processing wheel up/down and extra button events | ||
| 670 | */ | ||
| 671 | input_report_rel(dev, REL_WHEEL, | ||
| 672 | (int)(packet[3] & 8) - (int)(packet[3] & 7)); | ||
| 673 | input_report_rel(dev, REL_HWHEEL, lscroll - rscroll); | ||
| 674 | input_report_key(dev, BTN_BACK, lscroll); | ||
| 675 | input_report_key(dev, BTN_FORWARD, rscroll); | ||
| 676 | |||
| 677 | /* | ||
| 678 | * Standard PS/2 Mouse | ||
| 679 | */ | ||
| 680 | input_report_key(dev, BTN_LEFT, packet[0] & 1); | ||
| 681 | input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1); | ||
| 682 | input_report_key(dev, BTN_RIGHT, (packet[0] >> 1) & 1); | ||
| 683 | |||
| 684 | rel_x = packet[1] ? (int)packet[1] - (int)((packet[0] << 4) & 0x100) : 0; | ||
| 685 | rel_y = packet[2] ? (int)((packet[0] << 3) & 0x100) - (int)packet[2] : 0; | ||
| 686 | |||
| 687 | input_report_rel(dev, REL_X, rel_x); | ||
| 688 | input_report_rel(dev, REL_Y, rel_y); | ||
| 689 | break; | ||
| 690 | } | ||
| 691 | |||
| 692 | input_sync(dev); | ||
| 693 | |||
| 694 | fsp_packet_debug(packet); | ||
| 695 | |||
| 696 | return PSMOUSE_FULL_PACKET; | ||
| 697 | } | ||
| 698 | |||
| 699 | static int fsp_activate_protocol(struct psmouse *psmouse) | ||
| 700 | { | ||
| 701 | struct fsp_data *pad = psmouse->private; | ||
| 702 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
| 703 | unsigned char param[2]; | ||
| 704 | int val; | ||
| 705 | |||
| 706 | /* | ||
| 707 | * Standard procedure to enter FSP Intellimouse mode | ||
| 708 | * (scrolling wheel, 4th and 5th buttons) | ||
| 709 | */ | ||
| 710 | param[0] = 200; | ||
| 711 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); | ||
| 712 | param[0] = 200; | ||
| 713 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); | ||
| 714 | param[0] = 80; | ||
| 715 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); | ||
| 716 | |||
| 717 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETID); | ||
| 718 | if (param[0] != 0x04) { | ||
| 719 | dev_err(&psmouse->ps2dev.serio->dev, | ||
| 720 | "Unable to enable 4 bytes packet format.\n"); | ||
| 721 | return -EIO; | ||
| 722 | } | ||
| 723 | |||
| 724 | if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &val)) { | ||
| 725 | dev_err(&psmouse->ps2dev.serio->dev, | ||
| 726 | "Unable to read SYSCTL5 register.\n"); | ||
| 727 | return -EIO; | ||
| 728 | } | ||
| 729 | |||
| 730 | val &= ~(FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8 | FSP_BIT_EN_AUTO_MSID8); | ||
| 731 | /* Ensure we are not in absolute mode */ | ||
| 732 | val &= ~FSP_BIT_EN_PKT_G0; | ||
| 733 | if (pad->buttons == 0x06) { | ||
| 734 | /* Left/Middle/Right & Scroll Up/Down/Right/Left */ | ||
| 735 | val |= FSP_BIT_EN_MSID6; | ||
| 736 | } | ||
| 737 | |||
| 738 | if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, val)) { | ||
| 739 | dev_err(&psmouse->ps2dev.serio->dev, | ||
| 740 | "Unable to set up required mode bits.\n"); | ||
| 741 | return -EIO; | ||
| 742 | } | ||
| 743 | |||
| 744 | /* | ||
| 745 | * Enable OPC tags such that driver can tell the difference between | ||
| 746 | * on-pad and real button click | ||
| 747 | */ | ||
| 748 | if (fsp_opc_tag_enable(psmouse, true)) | ||
| 749 | dev_warn(&psmouse->ps2dev.serio->dev, | ||
| 750 | "Failed to enable OPC tag mode.\n"); | ||
| 751 | |||
| 752 | /* Enable on-pad vertical and horizontal scrolling */ | ||
| 753 | fsp_onpad_vscr(psmouse, true); | ||
| 754 | fsp_onpad_hscr(psmouse, true); | ||
| 755 | |||
| 756 | return 0; | ||
| 757 | } | ||
| 758 | |||
| 759 | int fsp_detect(struct psmouse *psmouse, bool set_properties) | ||
| 760 | { | ||
| 761 | int id; | ||
| 762 | |||
| 763 | if (fsp_reg_read(psmouse, FSP_REG_DEVICE_ID, &id)) | ||
| 764 | return -EIO; | ||
| 765 | |||
| 766 | if (id != 0x01) | ||
| 767 | return -ENODEV; | ||
| 768 | |||
| 769 | if (set_properties) { | ||
| 770 | psmouse->vendor = "Sentelic"; | ||
| 771 | psmouse->name = "FingerSensingPad"; | ||
| 772 | } | ||
| 773 | |||
| 774 | return 0; | ||
| 775 | } | ||
| 776 | |||
| 777 | static void fsp_reset(struct psmouse *psmouse) | ||
| 778 | { | ||
| 779 | fsp_opc_tag_enable(psmouse, false); | ||
| 780 | fsp_onpad_vscr(psmouse, false); | ||
| 781 | fsp_onpad_hscr(psmouse, false); | ||
| 782 | } | ||
| 783 | |||
| 784 | static void fsp_disconnect(struct psmouse *psmouse) | ||
| 785 | { | ||
| 786 | sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj, | ||
| 787 | &fsp_attribute_group); | ||
| 788 | |||
| 789 | fsp_reset(psmouse); | ||
| 790 | kfree(psmouse->private); | ||
| 791 | } | ||
| 792 | |||
| 793 | static int fsp_reconnect(struct psmouse *psmouse) | ||
| 794 | { | ||
| 795 | int version; | ||
| 796 | |||
| 797 | if (fsp_detect(psmouse, 0)) | ||
| 798 | return -ENODEV; | ||
| 799 | |||
| 800 | if (fsp_get_version(psmouse, &version)) | ||
| 801 | return -ENODEV; | ||
| 802 | |||
| 803 | if (fsp_activate_protocol(psmouse)) | ||
| 804 | return -EIO; | ||
| 805 | |||
| 806 | return 0; | ||
| 807 | } | ||
| 808 | |||
| 809 | int fsp_init(struct psmouse *psmouse) | ||
| 810 | { | ||
| 811 | struct fsp_data *priv; | ||
| 812 | int ver, rev, buttons; | ||
| 813 | int error; | ||
| 814 | |||
| 815 | if (fsp_get_version(psmouse, &ver) || | ||
| 816 | fsp_get_revision(psmouse, &rev) || | ||
| 817 | fsp_get_buttons(psmouse, &buttons)) { | ||
| 818 | return -ENODEV; | ||
| 819 | } | ||
| 820 | |||
| 821 | printk(KERN_INFO | ||
| 822 | "Finger Sensing Pad, hw: %d.%d.%d, sw: %s, buttons: %d\n", | ||
| 823 | ver >> 4, ver & 0x0F, rev, fsp_drv_ver, buttons & 7); | ||
| 824 | |||
| 825 | psmouse->private = priv = kzalloc(sizeof(struct fsp_data), GFP_KERNEL); | ||
| 826 | if (!priv) | ||
| 827 | return -ENOMEM; | ||
| 828 | |||
| 829 | priv->ver = ver; | ||
| 830 | priv->rev = rev; | ||
| 831 | priv->buttons = buttons; | ||
| 832 | |||
| 833 | /* enable on-pad click by default */ | ||
| 834 | priv->flags |= FSPDRV_FLAG_EN_OPC; | ||
| 835 | |||
| 836 | /* Set up various supported input event bits */ | ||
| 837 | __set_bit(BTN_BACK, psmouse->dev->keybit); | ||
| 838 | __set_bit(BTN_FORWARD, psmouse->dev->keybit); | ||
| 839 | __set_bit(REL_WHEEL, psmouse->dev->relbit); | ||
| 840 | __set_bit(REL_HWHEEL, psmouse->dev->relbit); | ||
| 841 | |||
| 842 | psmouse->protocol_handler = fsp_process_byte; | ||
| 843 | psmouse->disconnect = fsp_disconnect; | ||
| 844 | psmouse->reconnect = fsp_reconnect; | ||
| 845 | psmouse->cleanup = fsp_reset; | ||
| 846 | psmouse->pktsize = 4; | ||
| 847 | |||
| 848 | /* set default packet output based on number of buttons we found */ | ||
| 849 | error = fsp_activate_protocol(psmouse); | ||
| 850 | if (error) | ||
| 851 | goto err_out; | ||
| 852 | |||
| 853 | error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj, | ||
| 854 | &fsp_attribute_group); | ||
| 855 | if (error) { | ||
| 856 | dev_err(&psmouse->ps2dev.serio->dev, | ||
| 857 | "Failed to create sysfs attributes (%d)", error); | ||
| 858 | goto err_out; | ||
| 859 | } | ||
| 860 | |||
| 861 | return 0; | ||
| 862 | |||
| 863 | err_out: | ||
| 864 | kfree(psmouse->private); | ||
| 865 | psmouse->private = NULL; | ||
| 866 | return error; | ||
| 867 | } | ||
diff --git a/drivers/input/mouse/sentelic.h b/drivers/input/mouse/sentelic.h new file mode 100644 index 000000000000..ed1395ac7b8b --- /dev/null +++ b/drivers/input/mouse/sentelic.h | |||
| @@ -0,0 +1,98 @@ | |||
| 1 | /*- | ||
| 2 | * Finger Sensing Pad PS/2 mouse driver. | ||
| 3 | * | ||
| 4 | * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd. | ||
| 5 | * Copyright (C) 2005-2009 Tai-hwa Liang, Sentelic Corporation. | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License | ||
| 9 | * as published by the Free Software Foundation; either version 2 | ||
| 10 | * of the License, or (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 20 | */ | ||
| 21 | |||
| 22 | #ifndef __SENTELIC_H | ||
| 23 | #define __SENTELIC_H | ||
| 24 | |||
| 25 | /* Finger-sensing Pad information registers */ | ||
| 26 | #define FSP_REG_DEVICE_ID 0x00 | ||
| 27 | #define FSP_REG_VERSION 0x01 | ||
| 28 | #define FSP_REG_REVISION 0x04 | ||
| 29 | #define FSP_REG_TMOD_STATUS1 0x0B | ||
| 30 | #define FSP_BIT_NO_ROTATION BIT(3) | ||
| 31 | #define FSP_REG_PAGE_CTRL 0x0F | ||
| 32 | |||
| 33 | /* Finger-sensing Pad control registers */ | ||
| 34 | #define FSP_REG_SYSCTL1 0x10 | ||
| 35 | #define FSP_BIT_EN_REG_CLK BIT(5) | ||
| 36 | #define FSP_REG_OPC_QDOWN 0x31 | ||
| 37 | #define FSP_BIT_EN_OPC_TAG BIT(7) | ||
| 38 | #define FSP_REG_OPTZ_XLO 0x34 | ||
| 39 | #define FSP_REG_OPTZ_XHI 0x35 | ||
| 40 | #define FSP_REG_OPTZ_YLO 0x36 | ||
| 41 | #define FSP_REG_OPTZ_YHI 0x37 | ||
| 42 | #define FSP_REG_SYSCTL5 0x40 | ||
| 43 | #define FSP_BIT_90_DEGREE BIT(0) | ||
| 44 | #define FSP_BIT_EN_MSID6 BIT(1) | ||
| 45 | #define FSP_BIT_EN_MSID7 BIT(2) | ||
| 46 | #define FSP_BIT_EN_MSID8 BIT(3) | ||
| 47 | #define FSP_BIT_EN_AUTO_MSID8 BIT(5) | ||
| 48 | #define FSP_BIT_EN_PKT_G0 BIT(6) | ||
| 49 | |||
| 50 | #define FSP_REG_ONPAD_CTL 0x43 | ||
| 51 | #define FSP_BIT_ONPAD_ENABLE BIT(0) | ||
| 52 | #define FSP_BIT_ONPAD_FBBB BIT(1) | ||
| 53 | #define FSP_BIT_FIX_VSCR BIT(3) | ||
| 54 | #define FSP_BIT_FIX_HSCR BIT(5) | ||
| 55 | #define FSP_BIT_DRAG_LOCK BIT(6) | ||
| 56 | |||
| 57 | /* Finger-sensing Pad packet formating related definitions */ | ||
| 58 | |||
| 59 | /* absolute packet type */ | ||
| 60 | #define FSP_PKT_TYPE_NORMAL (0x00) | ||
| 61 | #define FSP_PKT_TYPE_ABS (0x01) | ||
| 62 | #define FSP_PKT_TYPE_NOTIFY (0x02) | ||
| 63 | #define FSP_PKT_TYPE_NORMAL_OPC (0x03) | ||
| 64 | #define FSP_PKT_TYPE_SHIFT (6) | ||
| 65 | |||
| 66 | #ifdef __KERNEL__ | ||
| 67 | |||
| 68 | struct fsp_data { | ||
| 69 | unsigned char ver; /* hardware version */ | ||
| 70 | unsigned char rev; /* hardware revison */ | ||
| 71 | unsigned char buttons; /* Number of buttons */ | ||
| 72 | unsigned int flags; | ||
| 73 | #define FSPDRV_FLAG_EN_OPC (0x001) /* enable on-pad clicking */ | ||
| 74 | |||
| 75 | bool vscroll; /* Vertical scroll zone enabled */ | ||
| 76 | bool hscroll; /* Horizontal scroll zone enabled */ | ||
| 77 | |||
| 78 | unsigned char last_reg; /* Last register we requested read from */ | ||
| 79 | unsigned char last_val; | ||
| 80 | }; | ||
| 81 | |||
| 82 | #ifdef CONFIG_MOUSE_PS2_SENTELIC | ||
| 83 | extern int fsp_detect(struct psmouse *psmouse, bool set_properties); | ||
| 84 | extern int fsp_init(struct psmouse *psmouse); | ||
| 85 | #else | ||
| 86 | inline int fsp_detect(struct psmouse *psmouse, bool set_properties) | ||
| 87 | { | ||
| 88 | return -ENOSYS; | ||
| 89 | } | ||
| 90 | inline int fsp_init(struct psmouse *psmouse) | ||
| 91 | { | ||
| 92 | return -ENOSYS; | ||
| 93 | } | ||
| 94 | #endif | ||
| 95 | |||
| 96 | #endif /* __KERNEL__ */ | ||
| 97 | |||
| 98 | #endif /* !__SENTELIC_H */ | ||
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 19984bf06cad..b66ff1ac7dea 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
| @@ -60,7 +60,7 @@ static int synaptics_mode_cmd(struct psmouse *psmouse, unsigned char mode) | |||
| 60 | return 0; | 60 | return 0; |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | int synaptics_detect(struct psmouse *psmouse, int set_properties) | 63 | int synaptics_detect(struct psmouse *psmouse, bool set_properties) |
| 64 | { | 64 | { |
| 65 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 65 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
| 66 | unsigned char param[4]; | 66 | unsigned char param[4]; |
| @@ -556,38 +556,38 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | |||
| 556 | { | 556 | { |
| 557 | int i; | 557 | int i; |
| 558 | 558 | ||
| 559 | set_bit(EV_ABS, dev->evbit); | 559 | __set_bit(EV_ABS, dev->evbit); |
| 560 | input_set_abs_params(dev, ABS_X, XMIN_NOMINAL, XMAX_NOMINAL, 0, 0); | 560 | input_set_abs_params(dev, ABS_X, XMIN_NOMINAL, XMAX_NOMINAL, 0, 0); |
| 561 | input_set_abs_params(dev, ABS_Y, YMIN_NOMINAL, YMAX_NOMINAL, 0, 0); | 561 | input_set_abs_params(dev, ABS_Y, YMIN_NOMINAL, YMAX_NOMINAL, 0, 0); |
| 562 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); | 562 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); |
| 563 | set_bit(ABS_TOOL_WIDTH, dev->absbit); | 563 | __set_bit(ABS_TOOL_WIDTH, dev->absbit); |
| 564 | 564 | ||
| 565 | set_bit(EV_KEY, dev->evbit); | 565 | __set_bit(EV_KEY, dev->evbit); |
| 566 | set_bit(BTN_TOUCH, dev->keybit); | 566 | __set_bit(BTN_TOUCH, dev->keybit); |
| 567 | set_bit(BTN_TOOL_FINGER, dev->keybit); | 567 | __set_bit(BTN_TOOL_FINGER, dev->keybit); |
| 568 | set_bit(BTN_LEFT, dev->keybit); | 568 | __set_bit(BTN_LEFT, dev->keybit); |
| 569 | set_bit(BTN_RIGHT, dev->keybit); | 569 | __set_bit(BTN_RIGHT, dev->keybit); |
| 570 | 570 | ||
| 571 | if (SYN_CAP_MULTIFINGER(priv->capabilities)) { | 571 | if (SYN_CAP_MULTIFINGER(priv->capabilities)) { |
| 572 | set_bit(BTN_TOOL_DOUBLETAP, dev->keybit); | 572 | __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit); |
| 573 | set_bit(BTN_TOOL_TRIPLETAP, dev->keybit); | 573 | __set_bit(BTN_TOOL_TRIPLETAP, dev->keybit); |
| 574 | } | 574 | } |
| 575 | 575 | ||
| 576 | if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) | 576 | if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) |
| 577 | set_bit(BTN_MIDDLE, dev->keybit); | 577 | __set_bit(BTN_MIDDLE, dev->keybit); |
| 578 | 578 | ||
| 579 | if (SYN_CAP_FOUR_BUTTON(priv->capabilities) || | 579 | if (SYN_CAP_FOUR_BUTTON(priv->capabilities) || |
| 580 | SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) { | 580 | SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) { |
| 581 | set_bit(BTN_FORWARD, dev->keybit); | 581 | __set_bit(BTN_FORWARD, dev->keybit); |
| 582 | set_bit(BTN_BACK, dev->keybit); | 582 | __set_bit(BTN_BACK, dev->keybit); |
| 583 | } | 583 | } |
| 584 | 584 | ||
| 585 | for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++) | 585 | for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++) |
| 586 | set_bit(BTN_0 + i, dev->keybit); | 586 | __set_bit(BTN_0 + i, dev->keybit); |
| 587 | 587 | ||
| 588 | clear_bit(EV_REL, dev->evbit); | 588 | __clear_bit(EV_REL, dev->evbit); |
| 589 | clear_bit(REL_X, dev->relbit); | 589 | __clear_bit(REL_X, dev->relbit); |
| 590 | clear_bit(REL_Y, dev->relbit); | 590 | __clear_bit(REL_Y, dev->relbit); |
| 591 | 591 | ||
| 592 | dev->absres[ABS_X] = priv->x_res; | 592 | dev->absres[ABS_X] = priv->x_res; |
| 593 | dev->absres[ABS_Y] = priv->y_res; | 593 | dev->absres[ABS_Y] = priv->y_res; |
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index 302382151752..871f6fe377f9 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h | |||
| @@ -105,7 +105,7 @@ struct synaptics_data { | |||
| 105 | int scroll; | 105 | int scroll; |
| 106 | }; | 106 | }; |
| 107 | 107 | ||
| 108 | int synaptics_detect(struct psmouse *psmouse, int set_properties); | 108 | int synaptics_detect(struct psmouse *psmouse, bool set_properties); |
| 109 | int synaptics_init(struct psmouse *psmouse); | 109 | int synaptics_init(struct psmouse *psmouse); |
| 110 | void synaptics_reset(struct psmouse *psmouse); | 110 | void synaptics_reset(struct psmouse *psmouse); |
| 111 | 111 | ||
diff --git a/drivers/input/mouse/touchkit_ps2.c b/drivers/input/mouse/touchkit_ps2.c index 3fadb2accac0..0308a0faa94d 100644 --- a/drivers/input/mouse/touchkit_ps2.c +++ b/drivers/input/mouse/touchkit_ps2.c | |||
| @@ -67,7 +67,7 @@ static psmouse_ret_t touchkit_ps2_process_byte(struct psmouse *psmouse) | |||
| 67 | return PSMOUSE_FULL_PACKET; | 67 | return PSMOUSE_FULL_PACKET; |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties) | 70 | int touchkit_ps2_detect(struct psmouse *psmouse, bool set_properties) |
| 71 | { | 71 | { |
| 72 | struct input_dev *dev = psmouse->dev; | 72 | struct input_dev *dev = psmouse->dev; |
| 73 | unsigned char param[3]; | 73 | unsigned char param[3]; |
| @@ -86,7 +86,7 @@ int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties) | |||
| 86 | 86 | ||
| 87 | if (set_properties) { | 87 | if (set_properties) { |
| 88 | dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 88 | dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
| 89 | set_bit(BTN_TOUCH, dev->keybit); | 89 | __set_bit(BTN_TOUCH, dev->keybit); |
| 90 | input_set_abs_params(dev, ABS_X, 0, TOUCHKIT_MAX_XC, 0, 0); | 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); | 91 | input_set_abs_params(dev, ABS_Y, 0, TOUCHKIT_MAX_YC, 0, 0); |
| 92 | 92 | ||
diff --git a/drivers/input/mouse/touchkit_ps2.h b/drivers/input/mouse/touchkit_ps2.h index 8a0dd3574aef..2efe9ea29d0c 100644 --- a/drivers/input/mouse/touchkit_ps2.h +++ b/drivers/input/mouse/touchkit_ps2.h | |||
| @@ -13,10 +13,10 @@ | |||
| 13 | #define _TOUCHKIT_PS2_H | 13 | #define _TOUCHKIT_PS2_H |
| 14 | 14 | ||
| 15 | #ifdef CONFIG_MOUSE_PS2_TOUCHKIT | 15 | #ifdef CONFIG_MOUSE_PS2_TOUCHKIT |
| 16 | int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties); | 16 | int touchkit_ps2_detect(struct psmouse *psmouse, bool set_properties); |
| 17 | #else | 17 | #else |
| 18 | static inline int touchkit_ps2_detect(struct psmouse *psmouse, | 18 | static inline int touchkit_ps2_detect(struct psmouse *psmouse, |
| 19 | int set_properties) | 19 | bool set_properties) |
| 20 | { | 20 | { |
| 21 | return -ENOSYS; | 21 | return -ENOSYS; |
| 22 | } | 22 | } |
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c index e68c814c4361..e354362f2971 100644 --- a/drivers/input/mouse/trackpoint.c +++ b/drivers/input/mouse/trackpoint.c | |||
| @@ -282,7 +282,7 @@ static int trackpoint_reconnect(struct psmouse *psmouse) | |||
| 282 | return 0; | 282 | return 0; |
| 283 | } | 283 | } |
| 284 | 284 | ||
| 285 | int trackpoint_detect(struct psmouse *psmouse, int set_properties) | 285 | int trackpoint_detect(struct psmouse *psmouse, bool set_properties) |
| 286 | { | 286 | { |
| 287 | struct trackpoint_data *priv; | 287 | struct trackpoint_data *priv; |
| 288 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 288 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
diff --git a/drivers/input/mouse/trackpoint.h b/drivers/input/mouse/trackpoint.h index c10a6e7d0101..e558a7096618 100644 --- a/drivers/input/mouse/trackpoint.h +++ b/drivers/input/mouse/trackpoint.h | |||
| @@ -143,9 +143,9 @@ struct trackpoint_data | |||
| 143 | }; | 143 | }; |
| 144 | 144 | ||
| 145 | #ifdef CONFIG_MOUSE_PS2_TRACKPOINT | 145 | #ifdef CONFIG_MOUSE_PS2_TRACKPOINT |
| 146 | int trackpoint_detect(struct psmouse *psmouse, int set_properties); | 146 | int trackpoint_detect(struct psmouse *psmouse, bool set_properties); |
| 147 | #else | 147 | #else |
| 148 | inline int trackpoint_detect(struct psmouse *psmouse, int set_properties) | 148 | inline int trackpoint_detect(struct psmouse *psmouse, bool set_properties) |
| 149 | { | 149 | { |
| 150 | return -ENOSYS; | 150 | return -ENOSYS; |
| 151 | } | 151 | } |
diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c index 404eedd5ffa2..70111443678e 100644 --- a/drivers/input/mouse/vsxxxaa.c +++ b/drivers/input/mouse/vsxxxaa.c | |||
| @@ -384,11 +384,11 @@ vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse) | |||
| 384 | printk (KERN_NOTICE "%s on %s: Forceing standard packet format, " | 384 | printk (KERN_NOTICE "%s on %s: Forceing standard packet format, " |
| 385 | "incremental streaming mode and 72 samples/sec\n", | 385 | "incremental streaming mode and 72 samples/sec\n", |
| 386 | mouse->name, mouse->phys); | 386 | mouse->name, mouse->phys); |
| 387 | mouse->serio->write (mouse->serio, 'S'); /* Standard format */ | 387 | serio_write (mouse->serio, 'S'); /* Standard format */ |
| 388 | mdelay (50); | 388 | mdelay (50); |
| 389 | mouse->serio->write (mouse->serio, 'R'); /* Incremental */ | 389 | serio_write (mouse->serio, 'R'); /* Incremental */ |
| 390 | mdelay (50); | 390 | mdelay (50); |
| 391 | mouse->serio->write (mouse->serio, 'L'); /* 72 samples/sec */ | 391 | serio_write (mouse->serio, 'L'); /* 72 samples/sec */ |
| 392 | } | 392 | } |
| 393 | 393 | ||
| 394 | static void | 394 | static void |
| @@ -532,7 +532,7 @@ vsxxxaa_connect (struct serio *serio, struct serio_driver *drv) | |||
| 532 | * Request selftest. Standard packet format and differential | 532 | * Request selftest. Standard packet format and differential |
| 533 | * mode will be requested after the device ID'ed successfully. | 533 | * mode will be requested after the device ID'ed successfully. |
| 534 | */ | 534 | */ |
| 535 | serio->write (serio, 'T'); /* Test */ | 535 | serio_write (serio, 'T'); /* Test */ |
| 536 | 536 | ||
| 537 | err = input_register_device (input_dev); | 537 | err = input_register_device (input_dev); |
| 538 | if (err) | 538 | if (err) |
