diff options
44 files changed, 1943 insertions, 317 deletions
diff --git a/Documentation/devicetree/bindings/gpio/gpio_keys.txt b/Documentation/devicetree/bindings/gpio/gpio_keys.txt new file mode 100644 index 000000000000..7190c99d7611 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/gpio_keys.txt | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | Device-Tree bindings for input/gpio_keys.c keyboard driver | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible = "gpio-keys"; | ||
| 5 | |||
| 6 | Optional properties: | ||
| 7 | - autorepeat: Boolean, Enable auto repeat feature of Linux input | ||
| 8 | subsystem. | ||
| 9 | |||
| 10 | Each button (key) is represented as a sub-node of "gpio-keys": | ||
| 11 | Subnode properties: | ||
| 12 | |||
| 13 | - gpios: OF devcie-tree gpio specificatin. | ||
| 14 | - label: Descriptive name of the key. | ||
| 15 | - linux,code: Keycode to emit. | ||
| 16 | |||
| 17 | Optional subnode-properties: | ||
| 18 | - linux,input-type: Specify event type this button/key generates. | ||
| 19 | If not specified defaults to <1> == EV_KEY. | ||
| 20 | - debounce-interval: Debouncing interval time in milliseconds. | ||
| 21 | If not specified defaults to 5. | ||
| 22 | - gpio-key,wakeup: Boolean, button can wake-up the system. | ||
| 23 | |||
| 24 | Example nodes: | ||
| 25 | |||
| 26 | gpio_keys { | ||
| 27 | compatible = "gpio-keys"; | ||
| 28 | #address-cells = <1>; | ||
| 29 | #size-cells = <0>; | ||
| 30 | autorepeat; | ||
| 31 | button@21 { | ||
| 32 | label = "GPIO Key UP"; | ||
| 33 | linux,code = <103>; | ||
| 34 | gpios = <&gpio1 0 1>; | ||
| 35 | }; | ||
| 36 | ... | ||
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 56abf3d0e911..d72887585a14 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
| @@ -154,10 +154,13 @@ static const struct xpad_device { | |||
| 154 | { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", 0, XTYPE_XBOX }, | 154 | { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", 0, XTYPE_XBOX }, |
| 155 | { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", 0, XTYPE_XBOX }, | 155 | { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", 0, XTYPE_XBOX }, |
| 156 | { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 156 | { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
| 157 | { 0x12ab, 0x0004, "Honey Bee Xbox360 dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, | ||
| 158 | { 0x0e6f, 0x0105, "HSM3 Xbox360 dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, | ||
| 157 | { 0x1430, 0x4748, "RedOctane Guitar Hero X-plorer", 0, XTYPE_XBOX360 }, | 159 | { 0x1430, 0x4748, "RedOctane Guitar Hero X-plorer", 0, XTYPE_XBOX360 }, |
| 158 | { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 160 | { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
| 159 | { 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 }, | 161 | { 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 }, |
| 160 | { 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 }, | 162 | { 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 }, |
| 163 | { 0x1bad, 0x0002, "Harmonix Rock Band Guitar", 0, XTYPE_XBOX360 }, | ||
| 161 | { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, | 164 | { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, |
| 162 | { 0x0f0d, 0x0016, "Hori Real Arcade Pro.EX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, | 165 | { 0x0f0d, 0x0016, "Hori Real Arcade Pro.EX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, |
| 163 | { 0x0f0d, 0x000d, "Hori Fighting Stick EX2", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, | 166 | { 0x0f0d, 0x000d, "Hori Fighting Stick EX2", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, |
| @@ -236,9 +239,10 @@ static struct usb_device_id xpad_table [] = { | |||
| 236 | XPAD_XBOX360_VENDOR(0x046d), /* Logitech X-Box 360 style controllers */ | 239 | XPAD_XBOX360_VENDOR(0x046d), /* Logitech X-Box 360 style controllers */ |
| 237 | XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz X-Box 360 controllers */ | 240 | XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz X-Box 360 controllers */ |
| 238 | XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f X-Box 360 controllers */ | 241 | XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f X-Box 360 controllers */ |
| 242 | XPAD_XBOX360_VENDOR(0x12ab), /* X-Box 360 dance pads */ | ||
| 239 | XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */ | 243 | XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */ |
| 240 | XPAD_XBOX360_VENDOR(0x146b), /* BigBen Interactive Controllers */ | 244 | XPAD_XBOX360_VENDOR(0x146b), /* BigBen Interactive Controllers */ |
| 241 | XPAD_XBOX360_VENDOR(0x1bad), /* Rock Band Drums */ | 245 | XPAD_XBOX360_VENDOR(0x1bad), /* Harminix Rock Band Guitar and Drums */ |
| 242 | XPAD_XBOX360_VENDOR(0x0f0d), /* Hori Controllers */ | 246 | XPAD_XBOX360_VENDOR(0x0f0d), /* Hori Controllers */ |
| 243 | { } | 247 | { } |
| 244 | }; | 248 | }; |
| @@ -545,7 +549,7 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) | |||
| 545 | struct usb_endpoint_descriptor *ep_irq_out; | 549 | struct usb_endpoint_descriptor *ep_irq_out; |
| 546 | int error; | 550 | int error; |
| 547 | 551 | ||
| 548 | if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX) | 552 | if (xpad->xtype == XTYPE_UNKNOWN) |
| 549 | return 0; | 553 | return 0; |
| 550 | 554 | ||
| 551 | xpad->odata = usb_alloc_coherent(xpad->udev, XPAD_PKT_LEN, | 555 | xpad->odata = usb_alloc_coherent(xpad->udev, XPAD_PKT_LEN, |
| @@ -579,13 +583,13 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) | |||
| 579 | 583 | ||
| 580 | static void xpad_stop_output(struct usb_xpad *xpad) | 584 | static void xpad_stop_output(struct usb_xpad *xpad) |
| 581 | { | 585 | { |
| 582 | if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX) | 586 | if (xpad->xtype != XTYPE_UNKNOWN) |
| 583 | usb_kill_urb(xpad->irq_out); | 587 | usb_kill_urb(xpad->irq_out); |
| 584 | } | 588 | } |
| 585 | 589 | ||
| 586 | static void xpad_deinit_output(struct usb_xpad *xpad) | 590 | static void xpad_deinit_output(struct usb_xpad *xpad) |
| 587 | { | 591 | { |
| 588 | if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX) { | 592 | if (xpad->xtype != XTYPE_UNKNOWN) { |
| 589 | usb_free_urb(xpad->irq_out); | 593 | usb_free_urb(xpad->irq_out); |
| 590 | usb_free_coherent(xpad->udev, XPAD_PKT_LEN, | 594 | usb_free_coherent(xpad->udev, XPAD_PKT_LEN, |
| 591 | xpad->odata, xpad->odata_dma); | 595 | xpad->odata, xpad->odata_dma); |
| @@ -632,6 +636,23 @@ static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect | |||
| 632 | 636 | ||
| 633 | return usb_submit_urb(xpad->irq_out, GFP_ATOMIC); | 637 | return usb_submit_urb(xpad->irq_out, GFP_ATOMIC); |
| 634 | 638 | ||
| 639 | case XTYPE_XBOX360W: | ||
| 640 | xpad->odata[0] = 0x00; | ||
| 641 | xpad->odata[1] = 0x01; | ||
| 642 | xpad->odata[2] = 0x0F; | ||
| 643 | xpad->odata[3] = 0xC0; | ||
| 644 | xpad->odata[4] = 0x00; | ||
| 645 | xpad->odata[5] = strong / 256; | ||
| 646 | xpad->odata[6] = weak / 256; | ||
| 647 | xpad->odata[7] = 0x00; | ||
| 648 | xpad->odata[8] = 0x00; | ||
| 649 | xpad->odata[9] = 0x00; | ||
| 650 | xpad->odata[10] = 0x00; | ||
| 651 | xpad->odata[11] = 0x00; | ||
| 652 | xpad->irq_out->transfer_buffer_length = 12; | ||
| 653 | |||
| 654 | return usb_submit_urb(xpad->irq_out, GFP_ATOMIC); | ||
| 655 | |||
| 635 | default: | 656 | default: |
| 636 | dbg("%s - rumble command sent to unsupported xpad type: %d", | 657 | dbg("%s - rumble command sent to unsupported xpad type: %d", |
| 637 | __func__, xpad->xtype); | 658 | __func__, xpad->xtype); |
| @@ -644,7 +665,7 @@ static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect | |||
| 644 | 665 | ||
| 645 | static int xpad_init_ff(struct usb_xpad *xpad) | 666 | static int xpad_init_ff(struct usb_xpad *xpad) |
| 646 | { | 667 | { |
| 647 | if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX) | 668 | if (xpad->xtype == XTYPE_UNKNOWN) |
| 648 | return 0; | 669 | return 0; |
| 649 | 670 | ||
| 650 | input_set_capability(xpad->dev, EV_FF, FF_RUMBLE); | 671 | input_set_capability(xpad->dev, EV_FF, FF_RUMBLE); |
diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index af45d275f686..7b404e5443ed 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c | |||
| @@ -9,7 +9,6 @@ | |||
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
| 12 | #include <linux/version.h> | ||
| 13 | #include <linux/init.h> | 12 | #include <linux/init.h> |
| 14 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
| 15 | #include <linux/irq.h> | 14 | #include <linux/irq.h> |
diff --git a/drivers/input/keyboard/adp5589-keys.c b/drivers/input/keyboard/adp5589-keys.c index 631598663aab..c7708263051b 100644 --- a/drivers/input/keyboard/adp5589-keys.c +++ b/drivers/input/keyboard/adp5589-keys.c | |||
| @@ -8,7 +8,6 @@ | |||
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
| 11 | #include <linux/version.h> | ||
| 12 | #include <linux/init.h> | 11 | #include <linux/init.h> |
| 13 | #include <linux/interrupt.h> | 12 | #include <linux/interrupt.h> |
| 14 | #include <linux/irq.h> | 13 | #include <linux/irq.h> |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 11478eb2c27d..19cfc0cf558c 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
| @@ -1578,14 +1578,14 @@ static int __init atkbd_setup_forced_release(const struct dmi_system_id *id) | |||
| 1578 | atkbd_platform_fixup = atkbd_apply_forced_release_keylist; | 1578 | atkbd_platform_fixup = atkbd_apply_forced_release_keylist; |
| 1579 | atkbd_platform_fixup_data = id->driver_data; | 1579 | atkbd_platform_fixup_data = id->driver_data; |
| 1580 | 1580 | ||
| 1581 | return 0; | 1581 | return 1; |
| 1582 | } | 1582 | } |
| 1583 | 1583 | ||
| 1584 | static int __init atkbd_setup_scancode_fixup(const struct dmi_system_id *id) | 1584 | static int __init atkbd_setup_scancode_fixup(const struct dmi_system_id *id) |
| 1585 | { | 1585 | { |
| 1586 | atkbd_platform_scancode_fixup = id->driver_data; | 1586 | atkbd_platform_scancode_fixup = id->driver_data; |
| 1587 | 1587 | ||
| 1588 | return 0; | 1588 | return 1; |
| 1589 | } | 1589 | } |
| 1590 | 1590 | ||
| 1591 | static const struct dmi_system_id atkbd_dmi_quirk_table[] __initconst = { | 1591 | static const struct dmi_system_id atkbd_dmi_quirk_table[] __initconst = { |
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 6e6145b9a4c1..ce281d152275 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | * Driver for keys on GPIO lines capable of generating interrupts. | 2 | * Driver for keys on GPIO lines capable of generating interrupts. |
| 3 | * | 3 | * |
| 4 | * Copyright 2005 Phil Blundell | 4 | * Copyright 2005 Phil Blundell |
| 5 | * Copyright 2010, 2011 David Jander <david@protonic.nl> | ||
| 5 | * | 6 | * |
| 6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
| @@ -25,6 +26,8 @@ | |||
| 25 | #include <linux/gpio_keys.h> | 26 | #include <linux/gpio_keys.h> |
| 26 | #include <linux/workqueue.h> | 27 | #include <linux/workqueue.h> |
| 27 | #include <linux/gpio.h> | 28 | #include <linux/gpio.h> |
| 29 | #include <linux/of_platform.h> | ||
| 30 | #include <linux/of_gpio.h> | ||
| 28 | 31 | ||
| 29 | struct gpio_button_data { | 32 | struct gpio_button_data { |
| 30 | struct gpio_keys_button *button; | 33 | struct gpio_keys_button *button; |
| @@ -415,7 +418,7 @@ static int __devinit gpio_keys_setup_key(struct platform_device *pdev, | |||
| 415 | if (!button->can_disable) | 418 | if (!button->can_disable) |
| 416 | irqflags |= IRQF_SHARED; | 419 | irqflags |= IRQF_SHARED; |
| 417 | 420 | ||
| 418 | error = request_any_context_irq(irq, gpio_keys_isr, irqflags, desc, bdata); | 421 | error = request_threaded_irq(irq, NULL, gpio_keys_isr, irqflags, desc, bdata); |
| 419 | if (error < 0) { | 422 | if (error < 0) { |
| 420 | dev_err(dev, "Unable to claim irq %d; error %d\n", | 423 | dev_err(dev, "Unable to claim irq %d; error %d\n", |
| 421 | irq, error); | 424 | irq, error); |
| @@ -445,15 +448,120 @@ static void gpio_keys_close(struct input_dev *input) | |||
| 445 | ddata->disable(input->dev.parent); | 448 | ddata->disable(input->dev.parent); |
| 446 | } | 449 | } |
| 447 | 450 | ||
| 451 | /* | ||
| 452 | * Handlers for alternative sources of platform_data | ||
| 453 | */ | ||
| 454 | #ifdef CONFIG_OF | ||
| 455 | /* | ||
| 456 | * Translate OpenFirmware node properties into platform_data | ||
| 457 | */ | ||
| 458 | static int gpio_keys_get_devtree_pdata(struct device *dev, | ||
| 459 | struct gpio_keys_platform_data *pdata) | ||
| 460 | { | ||
| 461 | struct device_node *node, *pp; | ||
| 462 | int i; | ||
| 463 | struct gpio_keys_button *buttons; | ||
| 464 | const u32 *reg; | ||
| 465 | int len; | ||
| 466 | |||
| 467 | node = dev->of_node; | ||
| 468 | if (node == NULL) | ||
| 469 | return -ENODEV; | ||
| 470 | |||
| 471 | memset(pdata, 0, sizeof *pdata); | ||
| 472 | |||
| 473 | pdata->rep = !!of_get_property(node, "autorepeat", &len); | ||
| 474 | |||
| 475 | /* First count the subnodes */ | ||
| 476 | pdata->nbuttons = 0; | ||
| 477 | pp = NULL; | ||
| 478 | while ((pp = of_get_next_child(node, pp))) | ||
| 479 | pdata->nbuttons++; | ||
| 480 | |||
| 481 | if (pdata->nbuttons == 0) | ||
| 482 | return -ENODEV; | ||
| 483 | |||
| 484 | buttons = kzalloc(pdata->nbuttons * (sizeof *buttons), GFP_KERNEL); | ||
| 485 | if (!buttons) | ||
| 486 | return -ENODEV; | ||
| 487 | |||
| 488 | pp = NULL; | ||
| 489 | i = 0; | ||
| 490 | while ((pp = of_get_next_child(node, pp))) { | ||
| 491 | enum of_gpio_flags flags; | ||
| 492 | |||
| 493 | if (!of_find_property(pp, "gpios", NULL)) { | ||
| 494 | pdata->nbuttons--; | ||
| 495 | dev_warn(dev, "Found button without gpios\n"); | ||
| 496 | continue; | ||
| 497 | } | ||
| 498 | buttons[i].gpio = of_get_gpio_flags(pp, 0, &flags); | ||
| 499 | buttons[i].active_low = flags & OF_GPIO_ACTIVE_LOW; | ||
| 500 | |||
| 501 | reg = of_get_property(pp, "linux,code", &len); | ||
| 502 | if (!reg) { | ||
| 503 | dev_err(dev, "Button without keycode: 0x%x\n", buttons[i].gpio); | ||
| 504 | goto out_fail; | ||
| 505 | } | ||
| 506 | buttons[i].code = be32_to_cpup(reg); | ||
| 507 | |||
| 508 | buttons[i].desc = of_get_property(pp, "label", &len); | ||
| 509 | |||
| 510 | reg = of_get_property(pp, "linux,input-type", &len); | ||
| 511 | buttons[i].type = reg ? be32_to_cpup(reg) : EV_KEY; | ||
| 512 | |||
| 513 | buttons[i].wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL); | ||
| 514 | |||
| 515 | reg = of_get_property(pp, "debounce-interval", &len); | ||
| 516 | buttons[i].debounce_interval = reg ? be32_to_cpup(reg) : 5; | ||
| 517 | |||
| 518 | i++; | ||
| 519 | } | ||
| 520 | |||
| 521 | pdata->buttons = buttons; | ||
| 522 | |||
| 523 | return 0; | ||
| 524 | |||
| 525 | out_fail: | ||
| 526 | kfree(buttons); | ||
| 527 | return -ENODEV; | ||
| 528 | } | ||
| 529 | |||
| 530 | static struct of_device_id gpio_keys_of_match[] = { | ||
| 531 | { .compatible = "gpio-keys", }, | ||
| 532 | { }, | ||
| 533 | }; | ||
| 534 | MODULE_DEVICE_TABLE(of, gpio_keys_of_match); | ||
| 535 | |||
| 536 | #else | ||
| 537 | |||
| 538 | static int gpio_keys_get_devtree_pdata(struct device *dev, | ||
| 539 | struct gpio_keys_platform_data *altp) | ||
| 540 | { | ||
| 541 | return -ENODEV; | ||
| 542 | } | ||
| 543 | |||
| 544 | #define gpio_keys_of_match NULL | ||
| 545 | |||
| 546 | #endif | ||
| 547 | |||
| 448 | static int __devinit gpio_keys_probe(struct platform_device *pdev) | 548 | static int __devinit gpio_keys_probe(struct platform_device *pdev) |
| 449 | { | 549 | { |
| 450 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | 550 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; |
| 451 | struct gpio_keys_drvdata *ddata; | 551 | struct gpio_keys_drvdata *ddata; |
| 452 | struct device *dev = &pdev->dev; | 552 | struct device *dev = &pdev->dev; |
| 553 | struct gpio_keys_platform_data alt_pdata; | ||
| 453 | struct input_dev *input; | 554 | struct input_dev *input; |
| 454 | int i, error; | 555 | int i, error; |
| 455 | int wakeup = 0; | 556 | int wakeup = 0; |
| 456 | 557 | ||
| 558 | if (!pdata) { | ||
| 559 | error = gpio_keys_get_devtree_pdata(dev, &alt_pdata); | ||
| 560 | if (error) | ||
| 561 | return error; | ||
| 562 | pdata = &alt_pdata; | ||
| 563 | } | ||
| 564 | |||
| 457 | ddata = kzalloc(sizeof(struct gpio_keys_drvdata) + | 565 | ddata = kzalloc(sizeof(struct gpio_keys_drvdata) + |
| 458 | pdata->nbuttons * sizeof(struct gpio_button_data), | 566 | pdata->nbuttons * sizeof(struct gpio_button_data), |
| 459 | GFP_KERNEL); | 567 | GFP_KERNEL); |
| @@ -544,13 +652,15 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
| 544 | fail1: | 652 | fail1: |
| 545 | input_free_device(input); | 653 | input_free_device(input); |
| 546 | kfree(ddata); | 654 | kfree(ddata); |
| 655 | /* If we have no platform_data, we allocated buttons dynamically. */ | ||
| 656 | if (!pdev->dev.platform_data) | ||
| 657 | kfree(pdata->buttons); | ||
| 547 | 658 | ||
| 548 | return error; | 659 | return error; |
| 549 | } | 660 | } |
| 550 | 661 | ||
| 551 | static int __devexit gpio_keys_remove(struct platform_device *pdev) | 662 | static int __devexit gpio_keys_remove(struct platform_device *pdev) |
| 552 | { | 663 | { |
| 553 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | ||
| 554 | struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); | 664 | struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); |
| 555 | struct input_dev *input = ddata->input; | 665 | struct input_dev *input = ddata->input; |
| 556 | int i; | 666 | int i; |
| @@ -559,31 +669,39 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev) | |||
| 559 | 669 | ||
| 560 | device_init_wakeup(&pdev->dev, 0); | 670 | device_init_wakeup(&pdev->dev, 0); |
| 561 | 671 | ||
| 562 | for (i = 0; i < pdata->nbuttons; i++) { | 672 | for (i = 0; i < ddata->n_buttons; i++) { |
| 563 | int irq = gpio_to_irq(pdata->buttons[i].gpio); | 673 | int irq = gpio_to_irq(ddata->data[i].button->gpio); |
| 564 | free_irq(irq, &ddata->data[i]); | 674 | free_irq(irq, &ddata->data[i]); |
| 565 | if (ddata->data[i].timer_debounce) | 675 | if (ddata->data[i].timer_debounce) |
| 566 | del_timer_sync(&ddata->data[i].timer); | 676 | del_timer_sync(&ddata->data[i].timer); |
| 567 | cancel_work_sync(&ddata->data[i].work); | 677 | cancel_work_sync(&ddata->data[i].work); |
| 568 | gpio_free(pdata->buttons[i].gpio); | 678 | gpio_free(ddata->data[i].button->gpio); |
| 569 | } | 679 | } |
| 570 | 680 | ||
| 571 | input_unregister_device(input); | 681 | input_unregister_device(input); |
| 572 | 682 | ||
| 683 | /* | ||
| 684 | * If we had no platform_data, we allocated buttons dynamically, and | ||
| 685 | * must free them here. ddata->data[0].button is the pointer to the | ||
| 686 | * beginning of the allocated array. | ||
| 687 | */ | ||
| 688 | if (!pdev->dev.platform_data) | ||
| 689 | kfree(ddata->data[0].button); | ||
| 690 | |||
| 691 | kfree(ddata); | ||
| 692 | |||
| 573 | return 0; | 693 | return 0; |
| 574 | } | 694 | } |
| 575 | 695 | ||
| 576 | 696 | #ifdef CONFIG_PM_SLEEP | |
| 577 | #ifdef CONFIG_PM | ||
| 578 | static int gpio_keys_suspend(struct device *dev) | 697 | static int gpio_keys_suspend(struct device *dev) |
| 579 | { | 698 | { |
| 580 | struct platform_device *pdev = to_platform_device(dev); | 699 | struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev); |
| 581 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | ||
| 582 | int i; | 700 | int i; |
| 583 | 701 | ||
| 584 | if (device_may_wakeup(&pdev->dev)) { | 702 | if (device_may_wakeup(dev)) { |
| 585 | for (i = 0; i < pdata->nbuttons; i++) { | 703 | for (i = 0; i < ddata->n_buttons; i++) { |
| 586 | struct gpio_keys_button *button = &pdata->buttons[i]; | 704 | struct gpio_keys_button *button = ddata->data[i].button; |
| 587 | if (button->wakeup) { | 705 | if (button->wakeup) { |
| 588 | int irq = gpio_to_irq(button->gpio); | 706 | int irq = gpio_to_irq(button->gpio); |
| 589 | enable_irq_wake(irq); | 707 | enable_irq_wake(irq); |
| @@ -596,15 +714,13 @@ static int gpio_keys_suspend(struct device *dev) | |||
| 596 | 714 | ||
| 597 | static int gpio_keys_resume(struct device *dev) | 715 | static int gpio_keys_resume(struct device *dev) |
| 598 | { | 716 | { |
| 599 | struct platform_device *pdev = to_platform_device(dev); | 717 | struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev); |
| 600 | struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); | ||
| 601 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | ||
| 602 | int i; | 718 | int i; |
| 603 | 719 | ||
| 604 | for (i = 0; i < pdata->nbuttons; i++) { | 720 | for (i = 0; i < ddata->n_buttons; i++) { |
| 605 | 721 | ||
| 606 | struct gpio_keys_button *button = &pdata->buttons[i]; | 722 | struct gpio_keys_button *button = ddata->data[i].button; |
| 607 | if (button->wakeup && device_may_wakeup(&pdev->dev)) { | 723 | if (button->wakeup && device_may_wakeup(dev)) { |
| 608 | int irq = gpio_to_irq(button->gpio); | 724 | int irq = gpio_to_irq(button->gpio); |
| 609 | disable_irq_wake(irq); | 725 | disable_irq_wake(irq); |
| 610 | } | 726 | } |
| @@ -615,22 +731,18 @@ static int gpio_keys_resume(struct device *dev) | |||
| 615 | 731 | ||
| 616 | return 0; | 732 | return 0; |
| 617 | } | 733 | } |
| 618 | |||
| 619 | static const struct dev_pm_ops gpio_keys_pm_ops = { | ||
| 620 | .suspend = gpio_keys_suspend, | ||
| 621 | .resume = gpio_keys_resume, | ||
| 622 | }; | ||
| 623 | #endif | 734 | #endif |
| 624 | 735 | ||
| 736 | static SIMPLE_DEV_PM_OPS(gpio_keys_pm_ops, gpio_keys_suspend, gpio_keys_resume); | ||
| 737 | |||
| 625 | static struct platform_driver gpio_keys_device_driver = { | 738 | static struct platform_driver gpio_keys_device_driver = { |
| 626 | .probe = gpio_keys_probe, | 739 | .probe = gpio_keys_probe, |
| 627 | .remove = __devexit_p(gpio_keys_remove), | 740 | .remove = __devexit_p(gpio_keys_remove), |
| 628 | .driver = { | 741 | .driver = { |
| 629 | .name = "gpio-keys", | 742 | .name = "gpio-keys", |
| 630 | .owner = THIS_MODULE, | 743 | .owner = THIS_MODULE, |
| 631 | #ifdef CONFIG_PM | ||
| 632 | .pm = &gpio_keys_pm_ops, | 744 | .pm = &gpio_keys_pm_ops, |
| 633 | #endif | 745 | .of_match_table = gpio_keys_of_match, |
| 634 | } | 746 | } |
| 635 | }; | 747 | }; |
| 636 | 748 | ||
| @@ -644,10 +756,10 @@ static void __exit gpio_keys_exit(void) | |||
| 644 | platform_driver_unregister(&gpio_keys_device_driver); | 756 | platform_driver_unregister(&gpio_keys_device_driver); |
| 645 | } | 757 | } |
| 646 | 758 | ||
| 647 | module_init(gpio_keys_init); | 759 | late_initcall(gpio_keys_init); |
| 648 | module_exit(gpio_keys_exit); | 760 | module_exit(gpio_keys_exit); |
| 649 | 761 | ||
| 650 | MODULE_LICENSE("GPL"); | 762 | MODULE_LICENSE("GPL"); |
| 651 | MODULE_AUTHOR("Phil Blundell <pb@handhelds.org>"); | 763 | MODULE_AUTHOR("Phil Blundell <pb@handhelds.org>"); |
| 652 | MODULE_DESCRIPTION("Keyboard driver for CPU GPIOs"); | 764 | MODULE_DESCRIPTION("Keyboard driver for GPIOs"); |
| 653 | MODULE_ALIAS("platform:gpio-keys"); | 765 | MODULE_ALIAS("platform:gpio-keys"); |
diff --git a/drivers/input/keyboard/lm8323.c b/drivers/input/keyboard/lm8323.c index 71f744a8e686..ab0acaf7fe8f 100644 --- a/drivers/input/keyboard/lm8323.c +++ b/drivers/input/keyboard/lm8323.c | |||
| @@ -146,7 +146,6 @@ struct lm8323_chip { | |||
| 146 | /* device lock */ | 146 | /* device lock */ |
| 147 | struct mutex lock; | 147 | struct mutex lock; |
| 148 | struct i2c_client *client; | 148 | struct i2c_client *client; |
| 149 | struct work_struct work; | ||
| 150 | struct input_dev *idev; | 149 | struct input_dev *idev; |
| 151 | bool kp_enabled; | 150 | bool kp_enabled; |
| 152 | bool pm_suspend; | 151 | bool pm_suspend; |
| @@ -162,7 +161,6 @@ struct lm8323_chip { | |||
| 162 | 161 | ||
| 163 | #define client_to_lm8323(c) container_of(c, struct lm8323_chip, client) | 162 | #define client_to_lm8323(c) container_of(c, struct lm8323_chip, client) |
| 164 | #define dev_to_lm8323(d) container_of(d, struct lm8323_chip, client->dev) | 163 | #define dev_to_lm8323(d) container_of(d, struct lm8323_chip, client->dev) |
| 165 | #define work_to_lm8323(w) container_of(w, struct lm8323_chip, work) | ||
| 166 | #define cdev_to_pwm(c) container_of(c, struct lm8323_pwm, cdev) | 164 | #define cdev_to_pwm(c) container_of(c, struct lm8323_pwm, cdev) |
| 167 | #define work_to_pwm(w) container_of(w, struct lm8323_pwm, work) | 165 | #define work_to_pwm(w) container_of(w, struct lm8323_pwm, work) |
| 168 | 166 | ||
| @@ -375,9 +373,9 @@ static void pwm_done(struct lm8323_pwm *pwm) | |||
| 375 | * Bottom half: handle the interrupt by posting key events, or dealing with | 373 | * Bottom half: handle the interrupt by posting key events, or dealing with |
| 376 | * errors appropriately. | 374 | * errors appropriately. |
| 377 | */ | 375 | */ |
| 378 | static void lm8323_work(struct work_struct *work) | 376 | static irqreturn_t lm8323_irq(int irq, void *_lm) |
| 379 | { | 377 | { |
| 380 | struct lm8323_chip *lm = work_to_lm8323(work); | 378 | struct lm8323_chip *lm = _lm; |
| 381 | u8 ints; | 379 | u8 ints; |
| 382 | int i; | 380 | int i; |
| 383 | 381 | ||
| @@ -409,16 +407,6 @@ static void lm8323_work(struct work_struct *work) | |||
| 409 | } | 407 | } |
| 410 | 408 | ||
| 411 | mutex_unlock(&lm->lock); | 409 | mutex_unlock(&lm->lock); |
| 412 | } | ||
| 413 | |||
| 414 | /* | ||
| 415 | * We cannot use I2C in interrupt context, so we just schedule work. | ||
| 416 | */ | ||
| 417 | static irqreturn_t lm8323_irq(int irq, void *data) | ||
| 418 | { | ||
| 419 | struct lm8323_chip *lm = data; | ||
| 420 | |||
| 421 | schedule_work(&lm->work); | ||
| 422 | 410 | ||
| 423 | return IRQ_HANDLED; | 411 | return IRQ_HANDLED; |
| 424 | } | 412 | } |
| @@ -675,7 +663,6 @@ static int __devinit lm8323_probe(struct i2c_client *client, | |||
| 675 | lm->client = client; | 663 | lm->client = client; |
| 676 | lm->idev = idev; | 664 | lm->idev = idev; |
| 677 | mutex_init(&lm->lock); | 665 | mutex_init(&lm->lock); |
| 678 | INIT_WORK(&lm->work, lm8323_work); | ||
| 679 | 666 | ||
| 680 | lm->size_x = pdata->size_x; | 667 | lm->size_x = pdata->size_x; |
| 681 | lm->size_y = pdata->size_y; | 668 | lm->size_y = pdata->size_y; |
| @@ -746,9 +733,8 @@ static int __devinit lm8323_probe(struct i2c_client *client, | |||
| 746 | goto fail3; | 733 | goto fail3; |
| 747 | } | 734 | } |
| 748 | 735 | ||
| 749 | err = request_irq(client->irq, lm8323_irq, | 736 | err = request_threaded_irq(client->irq, NULL, lm8323_irq, |
| 750 | IRQF_TRIGGER_FALLING | IRQF_DISABLED, | 737 | IRQF_TRIGGER_LOW|IRQF_ONESHOT, "lm8323", lm); |
| 751 | "lm8323", lm); | ||
| 752 | if (err) { | 738 | if (err) { |
| 753 | dev_err(&client->dev, "could not get IRQ %d\n", client->irq); | 739 | dev_err(&client->dev, "could not get IRQ %d\n", client->irq); |
| 754 | goto fail4; | 740 | goto fail4; |
| @@ -783,7 +769,6 @@ static int __devexit lm8323_remove(struct i2c_client *client) | |||
| 783 | 769 | ||
| 784 | disable_irq_wake(client->irq); | 770 | disable_irq_wake(client->irq); |
| 785 | free_irq(client->irq, lm); | 771 | free_irq(client->irq, lm); |
| 786 | cancel_work_sync(&lm->work); | ||
| 787 | 772 | ||
| 788 | input_unregister_device(lm->idev); | 773 | input_unregister_device(lm->idev); |
| 789 | 774 | ||
diff --git a/drivers/input/keyboard/mpr121_touchkey.c b/drivers/input/keyboard/mpr121_touchkey.c index 0a9e81194888..1c1615d9a7f9 100644 --- a/drivers/input/keyboard/mpr121_touchkey.c +++ b/drivers/input/keyboard/mpr121_touchkey.c | |||
| @@ -43,14 +43,15 @@ | |||
| 43 | * enabled capacitance sensing inputs and its run/suspend mode. | 43 | * enabled capacitance sensing inputs and its run/suspend mode. |
| 44 | */ | 44 | */ |
| 45 | #define ELECTRODE_CONF_ADDR 0x5e | 45 | #define ELECTRODE_CONF_ADDR 0x5e |
| 46 | #define ELECTRODE_CONF_QUICK_CHARGE 0x80 | ||
| 46 | #define AUTO_CONFIG_CTRL_ADDR 0x7b | 47 | #define AUTO_CONFIG_CTRL_ADDR 0x7b |
| 47 | #define AUTO_CONFIG_USL_ADDR 0x7d | 48 | #define AUTO_CONFIG_USL_ADDR 0x7d |
| 48 | #define AUTO_CONFIG_LSL_ADDR 0x7e | 49 | #define AUTO_CONFIG_LSL_ADDR 0x7e |
| 49 | #define AUTO_CONFIG_TL_ADDR 0x7f | 50 | #define AUTO_CONFIG_TL_ADDR 0x7f |
| 50 | 51 | ||
| 51 | /* Threshold of touch/release trigger */ | 52 | /* Threshold of touch/release trigger */ |
| 52 | #define TOUCH_THRESHOLD 0x0f | 53 | #define TOUCH_THRESHOLD 0x08 |
| 53 | #define RELEASE_THRESHOLD 0x0a | 54 | #define RELEASE_THRESHOLD 0x05 |
| 54 | /* Masks for touch and release triggers */ | 55 | /* Masks for touch and release triggers */ |
| 55 | #define TOUCH_STATUS_MASK 0xfff | 56 | #define TOUCH_STATUS_MASK 0xfff |
| 56 | /* MPR121 has 12 keys */ | 57 | /* MPR121 has 12 keys */ |
| @@ -127,7 +128,7 @@ static int __devinit mpr121_phys_init(const struct mpr121_platform_data *pdata, | |||
| 127 | struct i2c_client *client) | 128 | struct i2c_client *client) |
| 128 | { | 129 | { |
| 129 | const struct mpr121_init_register *reg; | 130 | const struct mpr121_init_register *reg; |
| 130 | unsigned char usl, lsl, tl; | 131 | unsigned char usl, lsl, tl, eleconf; |
| 131 | int i, t, vdd, ret; | 132 | int i, t, vdd, ret; |
| 132 | 133 | ||
| 133 | /* Set up touch/release threshold for ele0-ele11 */ | 134 | /* Set up touch/release threshold for ele0-ele11 */ |
| @@ -163,8 +164,15 @@ static int __devinit mpr121_phys_init(const struct mpr121_platform_data *pdata, | |||
| 163 | ret = i2c_smbus_write_byte_data(client, AUTO_CONFIG_USL_ADDR, usl); | 164 | ret = i2c_smbus_write_byte_data(client, AUTO_CONFIG_USL_ADDR, usl); |
| 164 | ret |= i2c_smbus_write_byte_data(client, AUTO_CONFIG_LSL_ADDR, lsl); | 165 | ret |= i2c_smbus_write_byte_data(client, AUTO_CONFIG_LSL_ADDR, lsl); |
| 165 | ret |= i2c_smbus_write_byte_data(client, AUTO_CONFIG_TL_ADDR, tl); | 166 | ret |= i2c_smbus_write_byte_data(client, AUTO_CONFIG_TL_ADDR, tl); |
| 167 | |||
| 168 | /* | ||
| 169 | * Quick charge bit will let the capacitive charge to ready | ||
| 170 | * state quickly, or the buttons may not function after system | ||
| 171 | * boot. | ||
| 172 | */ | ||
| 173 | eleconf = mpr121->keycount | ELECTRODE_CONF_QUICK_CHARGE; | ||
| 166 | ret |= i2c_smbus_write_byte_data(client, ELECTRODE_CONF_ADDR, | 174 | ret |= i2c_smbus_write_byte_data(client, ELECTRODE_CONF_ADDR, |
| 167 | mpr121->keycount); | 175 | eleconf); |
| 168 | if (ret != 0) | 176 | if (ret != 0) |
| 169 | goto err_i2c_write; | 177 | goto err_i2c_write; |
| 170 | 178 | ||
diff --git a/drivers/input/keyboard/pmic8xxx-keypad.c b/drivers/input/keyboard/pmic8xxx-keypad.c index 6229c3e8e78b..e7cc51d0fb34 100644 --- a/drivers/input/keyboard/pmic8xxx-keypad.c +++ b/drivers/input/keyboard/pmic8xxx-keypad.c | |||
| @@ -700,9 +700,9 @@ static int __devinit pmic8xxx_kp_probe(struct platform_device *pdev) | |||
| 700 | return 0; | 700 | return 0; |
| 701 | 701 | ||
| 702 | err_pmic_reg_read: | 702 | err_pmic_reg_read: |
| 703 | free_irq(kp->key_stuck_irq, NULL); | 703 | free_irq(kp->key_stuck_irq, kp); |
| 704 | err_req_stuck_irq: | 704 | err_req_stuck_irq: |
| 705 | free_irq(kp->key_sense_irq, NULL); | 705 | free_irq(kp->key_sense_irq, kp); |
| 706 | err_gpio_config: | 706 | err_gpio_config: |
| 707 | err_get_irq: | 707 | err_get_irq: |
| 708 | input_free_device(kp->input); | 708 | input_free_device(kp->input); |
| @@ -717,8 +717,8 @@ static int __devexit pmic8xxx_kp_remove(struct platform_device *pdev) | |||
| 717 | struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); | 717 | struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); |
| 718 | 718 | ||
| 719 | device_init_wakeup(&pdev->dev, 0); | 719 | device_init_wakeup(&pdev->dev, 0); |
| 720 | free_irq(kp->key_stuck_irq, NULL); | 720 | free_irq(kp->key_stuck_irq, kp); |
| 721 | free_irq(kp->key_sense_irq, NULL); | 721 | free_irq(kp->key_sense_irq, kp); |
| 722 | input_unregister_device(kp->input); | 722 | input_unregister_device(kp->input); |
| 723 | kfree(kp); | 723 | kfree(kp); |
| 724 | 724 | ||
diff --git a/drivers/input/keyboard/qt1070.c b/drivers/input/keyboard/qt1070.c index ca7b89196ab7..b21bf5b876bb 100644 --- a/drivers/input/keyboard/qt1070.c +++ b/drivers/input/keyboard/qt1070.c | |||
| @@ -239,8 +239,6 @@ static int __devexit qt1070_remove(struct i2c_client *client) | |||
| 239 | input_unregister_device(data->input); | 239 | input_unregister_device(data->input); |
| 240 | kfree(data); | 240 | kfree(data); |
| 241 | 241 | ||
| 242 | i2c_set_clientdata(client, NULL); | ||
| 243 | |||
| 244 | return 0; | 242 | return 0; |
| 245 | } | 243 | } |
| 246 | 244 | ||
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c index 6876700a4469..934aeb583b30 100644 --- a/drivers/input/keyboard/sh_keysc.c +++ b/drivers/input/keyboard/sh_keysc.c | |||
| @@ -291,7 +291,7 @@ static int __devexit sh_keysc_remove(struct platform_device *pdev) | |||
| 291 | return 0; | 291 | return 0; |
| 292 | } | 292 | } |
| 293 | 293 | ||
| 294 | #if CONFIG_PM_SLEEP | 294 | #ifdef CONFIG_PM_SLEEP |
| 295 | static int sh_keysc_suspend(struct device *dev) | 295 | static int sh_keysc_suspend(struct device *dev) |
| 296 | { | 296 | { |
| 297 | struct platform_device *pdev = to_platform_device(dev); | 297 | struct platform_device *pdev = to_platform_device(dev); |
diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index 2b3b73ec6689..da3828fc2c09 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c | |||
| @@ -657,7 +657,7 @@ static int __devinit tegra_kbc_probe(struct platform_device *pdev) | |||
| 657 | 657 | ||
| 658 | input_set_drvdata(input_dev, kbc); | 658 | input_set_drvdata(input_dev, kbc); |
| 659 | 659 | ||
| 660 | input_dev->evbit[0] = BIT_MASK(EV_KEY); | 660 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); |
| 661 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | 661 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); |
| 662 | 662 | ||
| 663 | input_dev->keycode = kbc->keycode; | 663 | input_dev->keycode = kbc->keycode; |
diff --git a/drivers/input/keyboard/tnetv107x-keypad.c b/drivers/input/keyboard/tnetv107x-keypad.c index c8f097a15d89..1c58681de81f 100644 --- a/drivers/input/keyboard/tnetv107x-keypad.c +++ b/drivers/input/keyboard/tnetv107x-keypad.c | |||
| @@ -337,5 +337,5 @@ module_exit(keypad_exit); | |||
| 337 | 337 | ||
| 338 | MODULE_AUTHOR("Cyril Chemparathy"); | 338 | MODULE_AUTHOR("Cyril Chemparathy"); |
| 339 | MODULE_DESCRIPTION("TNETV107X Keypad Driver"); | 339 | MODULE_DESCRIPTION("TNETV107X Keypad Driver"); |
| 340 | MODULE_ALIAS("platform: tnetv107x-keypad"); | 340 | MODULE_ALIAS("platform:tnetv107x-keypad"); |
| 341 | MODULE_LICENSE("GPL"); | 341 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index d1bf8724b58f..c9104bb4db06 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig | |||
| @@ -100,6 +100,27 @@ config INPUT_MAX8925_ONKEY | |||
| 100 | To compile this driver as a module, choose M here: the module | 100 | To compile this driver as a module, choose M here: the module |
| 101 | will be called max8925_onkey. | 101 | will be called max8925_onkey. |
| 102 | 102 | ||
| 103 | config INPUT_MMA8450 | ||
| 104 | tristate "MMA8450 - Freescale's 3-Axis, 8/12-bit Digital Accelerometer" | ||
| 105 | depends on I2C | ||
| 106 | select INPUT_POLLDEV | ||
| 107 | help | ||
| 108 | Say Y here if you want to support Freescale's MMA8450 Accelerometer | ||
| 109 | through I2C interface. | ||
| 110 | |||
| 111 | To compile this driver as a module, choose M here: the | ||
| 112 | module will be called mma8450. | ||
| 113 | |||
| 114 | config INPUT_MPU3050 | ||
| 115 | tristate "MPU3050 Triaxial gyroscope sensor" | ||
| 116 | depends on I2C | ||
| 117 | help | ||
| 118 | Say Y here if you want to support InvenSense MPU3050 | ||
| 119 | connected via an I2C bus. | ||
| 120 | |||
| 121 | To compile this driver as a module, choose M here: the | ||
| 122 | module will be called mpu3050. | ||
| 123 | |||
| 103 | config INPUT_APANEL | 124 | config INPUT_APANEL |
| 104 | tristate "Fujitsu Lifebook Application Panel buttons" | 125 | tristate "Fujitsu Lifebook Application Panel buttons" |
| 105 | depends on X86 && I2C && LEDS_CLASS | 126 | depends on X86 && I2C && LEDS_CLASS |
| @@ -209,6 +230,23 @@ config INPUT_KEYSPAN_REMOTE | |||
| 209 | To compile this driver as a module, choose M here: the module will | 230 | To compile this driver as a module, choose M here: the module will |
| 210 | be called keyspan_remote. | 231 | be called keyspan_remote. |
| 211 | 232 | ||
| 233 | config INPUT_KXTJ9 | ||
| 234 | tristate "Kionix KXTJ9 tri-axis digital accelerometer" | ||
| 235 | depends on I2C | ||
| 236 | help | ||
| 237 | Say Y here to enable support for the Kionix KXTJ9 digital tri-axis | ||
| 238 | accelerometer. | ||
| 239 | |||
| 240 | To compile this driver as a module, choose M here: the module will | ||
| 241 | be called kxtj9. | ||
| 242 | |||
| 243 | config INPUT_KXTJ9_POLLED_MODE | ||
| 244 | bool "Enable polling mode support" | ||
| 245 | depends on INPUT_KXTJ9 | ||
| 246 | select INPUT_POLLDEV | ||
| 247 | help | ||
| 248 | Say Y here if you need accelerometer to work in polling mode. | ||
| 249 | |||
| 212 | config INPUT_POWERMATE | 250 | config INPUT_POWERMATE |
| 213 | tristate "Griffin PowerMate and Contour Jog support" | 251 | tristate "Griffin PowerMate and Contour Jog support" |
| 214 | depends on USB_ARCH_HAS_HCD | 252 | depends on USB_ARCH_HAS_HCD |
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 4da7c3a60e04..299ad5edba84 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile | |||
| @@ -25,8 +25,11 @@ obj-$(CONFIG_INPUT_DM355EVM) += dm355evm_keys.o | |||
| 25 | obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o | 25 | obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o |
| 26 | obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o | 26 | obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o |
| 27 | obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o | 27 | obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o |
| 28 | obj-$(CONFIG_INPUT_KXTJ9) += kxtj9.o | ||
| 28 | obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o | 29 | obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o |
| 29 | obj-$(CONFIG_INPUT_MAX8925_ONKEY) += max8925_onkey.o | 30 | obj-$(CONFIG_INPUT_MAX8925_ONKEY) += max8925_onkey.o |
| 31 | obj-$(CONFIG_INPUT_MMA8450) += mma8450.o | ||
| 32 | obj-$(CONFIG_INPUT_MPU3050) += mpu3050.o | ||
| 30 | obj-$(CONFIG_INPUT_PCAP) += pcap_keys.o | 33 | obj-$(CONFIG_INPUT_PCAP) += pcap_keys.o |
| 31 | obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o | 34 | obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o |
| 32 | obj-$(CONFIG_INPUT_PCF8574) += pcf8574_keypad.o | 35 | obj-$(CONFIG_INPUT_PCF8574) += pcf8574_keypad.o |
| @@ -46,4 +49,3 @@ obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o | |||
| 46 | obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o | 49 | obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o |
| 47 | obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o | 50 | obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o |
| 48 | obj-$(CONFIG_INPUT_YEALINK) += yealink.o | 51 | obj-$(CONFIG_INPUT_YEALINK) += yealink.o |
| 49 | |||
diff --git a/drivers/input/misc/bfin_rotary.c b/drivers/input/misc/bfin_rotary.c index 4f72bdd69410..d00edc9f39d1 100644 --- a/drivers/input/misc/bfin_rotary.c +++ b/drivers/input/misc/bfin_rotary.c | |||
| @@ -6,7 +6,6 @@ | |||
| 6 | */ | 6 | */ |
| 7 | 7 | ||
| 8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
| 9 | #include <linux/version.h> | ||
| 10 | #include <linux/init.h> | 9 | #include <linux/init.h> |
| 11 | #include <linux/interrupt.h> | 10 | #include <linux/interrupt.h> |
| 12 | #include <linux/irq.h> | 11 | #include <linux/irq.h> |
diff --git a/drivers/input/misc/kxtj9.c b/drivers/input/misc/kxtj9.c new file mode 100644 index 000000000000..c456f63b6bae --- /dev/null +++ b/drivers/input/misc/kxtj9.c | |||
| @@ -0,0 +1,671 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 Kionix, Inc. | ||
| 3 | * Written by Chris Hudson <chudson@kionix.com> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License version 2 as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program; if not, write to the Free Software | ||
| 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
| 17 | * 02111-1307, USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <linux/delay.h> | ||
| 21 | #include <linux/i2c.h> | ||
| 22 | #include <linux/input.h> | ||
| 23 | #include <linux/interrupt.h> | ||
| 24 | #include <linux/slab.h> | ||
| 25 | #include <linux/input/kxtj9.h> | ||
| 26 | #include <linux/input-polldev.h> | ||
| 27 | |||
| 28 | #define NAME "kxtj9" | ||
| 29 | #define G_MAX 8000 | ||
| 30 | /* OUTPUT REGISTERS */ | ||
| 31 | #define XOUT_L 0x06 | ||
| 32 | #define WHO_AM_I 0x0F | ||
| 33 | /* CONTROL REGISTERS */ | ||
| 34 | #define INT_REL 0x1A | ||
| 35 | #define CTRL_REG1 0x1B | ||
| 36 | #define INT_CTRL1 0x1E | ||
| 37 | #define DATA_CTRL 0x21 | ||
| 38 | /* CONTROL REGISTER 1 BITS */ | ||
| 39 | #define PC1_OFF 0x7F | ||
| 40 | #define PC1_ON (1 << 7) | ||
| 41 | /* Data ready funtion enable bit: set during probe if using irq mode */ | ||
| 42 | #define DRDYE (1 << 5) | ||
| 43 | /* INTERRUPT CONTROL REGISTER 1 BITS */ | ||
| 44 | /* Set these during probe if using irq mode */ | ||
| 45 | #define KXTJ9_IEL (1 << 3) | ||
| 46 | #define KXTJ9_IEA (1 << 4) | ||
| 47 | #define KXTJ9_IEN (1 << 5) | ||
| 48 | /* INPUT_ABS CONSTANTS */ | ||
| 49 | #define FUZZ 3 | ||
| 50 | #define FLAT 3 | ||
| 51 | /* RESUME STATE INDICES */ | ||
| 52 | #define RES_DATA_CTRL 0 | ||
| 53 | #define RES_CTRL_REG1 1 | ||
| 54 | #define RES_INT_CTRL1 2 | ||
| 55 | #define RESUME_ENTRIES 3 | ||
| 56 | |||
| 57 | /* | ||
| 58 | * The following table lists the maximum appropriate poll interval for each | ||
| 59 | * available output data rate. | ||
| 60 | */ | ||
| 61 | static const struct { | ||
| 62 | unsigned int cutoff; | ||
| 63 | u8 mask; | ||
| 64 | } kxtj9_odr_table[] = { | ||
| 65 | { 3, ODR800F }, | ||
| 66 | { 5, ODR400F }, | ||
| 67 | { 10, ODR200F }, | ||
| 68 | { 20, ODR100F }, | ||
| 69 | { 40, ODR50F }, | ||
| 70 | { 80, ODR25F }, | ||
| 71 | { 0, ODR12_5F}, | ||
| 72 | }; | ||
| 73 | |||
| 74 | struct kxtj9_data { | ||
| 75 | struct i2c_client *client; | ||
| 76 | struct kxtj9_platform_data pdata; | ||
| 77 | struct input_dev *input_dev; | ||
| 78 | #ifdef CONFIG_INPUT_KXTJ9_POLLED_MODE | ||
| 79 | struct input_polled_dev *poll_dev; | ||
| 80 | #endif | ||
| 81 | unsigned int last_poll_interval; | ||
| 82 | u8 shift; | ||
| 83 | u8 ctrl_reg1; | ||
| 84 | u8 data_ctrl; | ||
| 85 | u8 int_ctrl; | ||
| 86 | }; | ||
| 87 | |||
| 88 | static int kxtj9_i2c_read(struct kxtj9_data *tj9, u8 addr, u8 *data, int len) | ||
| 89 | { | ||
| 90 | struct i2c_msg msgs[] = { | ||
| 91 | { | ||
| 92 | .addr = tj9->client->addr, | ||
| 93 | .flags = tj9->client->flags, | ||
| 94 | .len = 1, | ||
| 95 | .buf = &addr, | ||
| 96 | }, | ||
| 97 | { | ||
| 98 | .addr = tj9->client->addr, | ||
| 99 | .flags = tj9->client->flags | I2C_M_RD, | ||
| 100 | .len = len, | ||
| 101 | .buf = data, | ||
| 102 | }, | ||
| 103 | }; | ||
| 104 | |||
| 105 | return i2c_transfer(tj9->client->adapter, msgs, 2); | ||
| 106 | } | ||
| 107 | |||
| 108 | static void kxtj9_report_acceleration_data(struct kxtj9_data *tj9) | ||
| 109 | { | ||
| 110 | s16 acc_data[3]; /* Data bytes from hardware xL, xH, yL, yH, zL, zH */ | ||
| 111 | s16 x, y, z; | ||
| 112 | int err; | ||
| 113 | |||
| 114 | err = kxtj9_i2c_read(tj9, XOUT_L, (u8 *)acc_data, 6); | ||
| 115 | if (err < 0) | ||
| 116 | dev_err(&tj9->client->dev, "accelerometer data read failed\n"); | ||
| 117 | |||
| 118 | x = le16_to_cpu(acc_data[tj9->pdata.axis_map_x]) >> tj9->shift; | ||
| 119 | y = le16_to_cpu(acc_data[tj9->pdata.axis_map_y]) >> tj9->shift; | ||
| 120 | z = le16_to_cpu(acc_data[tj9->pdata.axis_map_z]) >> tj9->shift; | ||
| 121 | |||
| 122 | input_report_abs(tj9->input_dev, ABS_X, tj9->pdata.negate_x ? -x : x); | ||
| 123 | input_report_abs(tj9->input_dev, ABS_Y, tj9->pdata.negate_y ? -y : y); | ||
| 124 | input_report_abs(tj9->input_dev, ABS_Z, tj9->pdata.negate_z ? -z : z); | ||
| 125 | input_sync(tj9->input_dev); | ||
| 126 | } | ||
| 127 | |||
| 128 | static irqreturn_t kxtj9_isr(int irq, void *dev) | ||
| 129 | { | ||
| 130 | struct kxtj9_data *tj9 = dev; | ||
| 131 | int err; | ||
| 132 | |||
| 133 | /* data ready is the only possible interrupt type */ | ||
| 134 | kxtj9_report_acceleration_data(tj9); | ||
| 135 | |||
| 136 | err = i2c_smbus_read_byte_data(tj9->client, INT_REL); | ||
| 137 | if (err < 0) | ||
| 138 | dev_err(&tj9->client->dev, | ||
| 139 | "error clearing interrupt status: %d\n", err); | ||
| 140 | |||
| 141 | return IRQ_HANDLED; | ||
| 142 | } | ||
| 143 | |||
| 144 | static int kxtj9_update_g_range(struct kxtj9_data *tj9, u8 new_g_range) | ||
| 145 | { | ||
| 146 | switch (new_g_range) { | ||
| 147 | case KXTJ9_G_2G: | ||
| 148 | tj9->shift = 4; | ||
| 149 | break; | ||
| 150 | case KXTJ9_G_4G: | ||
| 151 | tj9->shift = 3; | ||
| 152 | break; | ||
| 153 | case KXTJ9_G_8G: | ||
| 154 | tj9->shift = 2; | ||
| 155 | break; | ||
| 156 | default: | ||
| 157 | return -EINVAL; | ||
| 158 | } | ||
| 159 | |||
| 160 | tj9->ctrl_reg1 &= 0xe7; | ||
| 161 | tj9->ctrl_reg1 |= new_g_range; | ||
| 162 | |||
| 163 | return 0; | ||
| 164 | } | ||
| 165 | |||
| 166 | static int kxtj9_update_odr(struct kxtj9_data *tj9, unsigned int poll_interval) | ||
| 167 | { | ||
| 168 | int err; | ||
| 169 | int i; | ||
| 170 | |||
| 171 | /* Use the lowest ODR that can support the requested poll interval */ | ||
| 172 | for (i = 0; i < ARRAY_SIZE(kxtj9_odr_table); i++) { | ||
| 173 | tj9->data_ctrl = kxtj9_odr_table[i].mask; | ||
| 174 | if (poll_interval < kxtj9_odr_table[i].cutoff) | ||
| 175 | break; | ||
| 176 | } | ||
| 177 | |||
| 178 | err = i2c_smbus_write_byte_data(tj9->client, CTRL_REG1, 0); | ||
| 179 | if (err < 0) | ||
| 180 | return err; | ||
| 181 | |||
| 182 | err = i2c_smbus_write_byte_data(tj9->client, DATA_CTRL, tj9->data_ctrl); | ||
| 183 | if (err < 0) | ||
| 184 | return err; | ||
| 185 | |||
| 186 | err = i2c_smbus_write_byte_data(tj9->client, CTRL_REG1, tj9->ctrl_reg1); | ||
| 187 | if (err < 0) | ||
| 188 | return err; | ||
| 189 | |||
| 190 | return 0; | ||
| 191 | } | ||
| 192 | |||
| 193 | static int kxtj9_device_power_on(struct kxtj9_data *tj9) | ||
| 194 | { | ||
| 195 | if (tj9->pdata.power_on) | ||
| 196 | return tj9->pdata.power_on(); | ||
| 197 | |||
| 198 | return 0; | ||
| 199 | } | ||
| 200 | |||
| 201 | static void kxtj9_device_power_off(struct kxtj9_data *tj9) | ||
| 202 | { | ||
| 203 | int err; | ||
| 204 | |||
| 205 | tj9->ctrl_reg1 &= PC1_OFF; | ||
| 206 | err = i2c_smbus_write_byte_data(tj9->client, CTRL_REG1, tj9->ctrl_reg1); | ||
| 207 | if (err < 0) | ||
| 208 | dev_err(&tj9->client->dev, "soft power off failed\n"); | ||
| 209 | |||
| 210 | if (tj9->pdata.power_off) | ||
| 211 | tj9->pdata.power_off(); | ||
| 212 | } | ||
| 213 | |||
| 214 | static int kxtj9_enable(struct kxtj9_data *tj9) | ||
| 215 | { | ||
| 216 | int err; | ||
| 217 | |||
| 218 | err = kxtj9_device_power_on(tj9); | ||
| 219 | if (err < 0) | ||
| 220 | return err; | ||
| 221 | |||
| 222 | /* ensure that PC1 is cleared before updating control registers */ | ||
| 223 | err = i2c_smbus_write_byte_data(tj9->client, CTRL_REG1, 0); | ||
| 224 | if (err < 0) | ||
| 225 | return err; | ||
| 226 | |||
| 227 | /* only write INT_CTRL_REG1 if in irq mode */ | ||
| 228 | if (tj9->client->irq) { | ||
| 229 | err = i2c_smbus_write_byte_data(tj9->client, | ||
| 230 | INT_CTRL1, tj9->int_ctrl); | ||
| 231 | if (err < 0) | ||
| 232 | return err; | ||
| 233 | } | ||
| 234 | |||
| 235 | err = kxtj9_update_g_range(tj9, tj9->pdata.g_range); | ||
| 236 | if (err < 0) | ||
| 237 | return err; | ||
| 238 | |||
| 239 | /* turn on outputs */ | ||
| 240 | tj9->ctrl_reg1 |= PC1_ON; | ||
| 241 | err = i2c_smbus_write_byte_data(tj9->client, CTRL_REG1, tj9->ctrl_reg1); | ||
| 242 | if (err < 0) | ||
| 243 | return err; | ||
| 244 | |||
| 245 | err = kxtj9_update_odr(tj9, tj9->last_poll_interval); | ||
| 246 | if (err < 0) | ||
| 247 | return err; | ||
| 248 | |||
| 249 | /* clear initial interrupt if in irq mode */ | ||
| 250 | if (tj9->client->irq) { | ||
| 251 | err = i2c_smbus_read_byte_data(tj9->client, INT_REL); | ||
| 252 | if (err < 0) { | ||
| 253 | dev_err(&tj9->client->dev, | ||
| 254 | "error clearing interrupt: %d\n", err); | ||
| 255 | goto fail; | ||
| 256 | } | ||
| 257 | } | ||
| 258 | |||
| 259 | return 0; | ||
| 260 | |||
| 261 | fail: | ||
| 262 | kxtj9_device_power_off(tj9); | ||
| 263 | return err; | ||
| 264 | } | ||
| 265 | |||
| 266 | static void kxtj9_disable(struct kxtj9_data *tj9) | ||
| 267 | { | ||
| 268 | kxtj9_device_power_off(tj9); | ||
| 269 | } | ||
| 270 | |||
| 271 | static int kxtj9_input_open(struct input_dev *input) | ||
| 272 | { | ||
| 273 | struct kxtj9_data *tj9 = input_get_drvdata(input); | ||
| 274 | |||
| 275 | return kxtj9_enable(tj9); | ||
| 276 | } | ||
| 277 | |||
| 278 | static void kxtj9_input_close(struct input_dev *dev) | ||
| 279 | { | ||
| 280 | struct kxtj9_data *tj9 = input_get_drvdata(dev); | ||
| 281 | |||
| 282 | kxtj9_disable(tj9); | ||
| 283 | } | ||
| 284 | |||
| 285 | static void __devinit kxtj9_init_input_device(struct kxtj9_data *tj9, | ||
| 286 | struct input_dev *input_dev) | ||
| 287 | { | ||
| 288 | __set_bit(EV_ABS, input_dev->evbit); | ||
| 289 | input_set_abs_params(input_dev, ABS_X, -G_MAX, G_MAX, FUZZ, FLAT); | ||
| 290 | input_set_abs_params(input_dev, ABS_Y, -G_MAX, G_MAX, FUZZ, FLAT); | ||
| 291 | input_set_abs_params(input_dev, ABS_Z, -G_MAX, G_MAX, FUZZ, FLAT); | ||
| 292 | |||
| 293 | input_dev->name = "kxtj9_accel"; | ||
| 294 | input_dev->id.bustype = BUS_I2C; | ||
| 295 | input_dev->dev.parent = &tj9->client->dev; | ||
| 296 | } | ||
| 297 | |||
| 298 | static int __devinit kxtj9_setup_input_device(struct kxtj9_data *tj9) | ||
| 299 | { | ||
| 300 | struct input_dev *input_dev; | ||
| 301 | int err; | ||
| 302 | |||
| 303 | input_dev = input_allocate_device(); | ||
| 304 | if (!input_dev) { | ||
| 305 | dev_err(&tj9->client->dev, "input device allocate failed\n"); | ||
| 306 | return -ENOMEM; | ||
| 307 | } | ||
| 308 | |||
| 309 | tj9->input_dev = input_dev; | ||
| 310 | |||
| 311 | input_dev->open = kxtj9_input_open; | ||
| 312 | input_dev->close = kxtj9_input_close; | ||
| 313 | input_set_drvdata(input_dev, tj9); | ||
| 314 | |||
| 315 | kxtj9_init_input_device(tj9, input_dev); | ||
| 316 | |||
| 317 | err = input_register_device(tj9->input_dev); | ||
| 318 | if (err) { | ||
| 319 | dev_err(&tj9->client->dev, | ||
| 320 | "unable to register input polled device %s: %d\n", | ||
| 321 | tj9->input_dev->name, err); | ||
| 322 | input_free_device(tj9->input_dev); | ||
| 323 | return err; | ||
| 324 | } | ||
| 325 | |||
| 326 | return 0; | ||
| 327 | } | ||
| 328 | |||
| 329 | /* | ||
| 330 | * When IRQ mode is selected, we need to provide an interface to allow the user | ||
| 331 | * to change the output data rate of the part. For consistency, we are using | ||
| 332 | * the set_poll method, which accepts a poll interval in milliseconds, and then | ||
| 333 | * calls update_odr() while passing this value as an argument. In IRQ mode, the | ||
| 334 | * data outputs will not be read AT the requested poll interval, rather, the | ||
| 335 | * lowest ODR that can support the requested interval. The client application | ||
| 336 | * will be responsible for retrieving data from the input node at the desired | ||
| 337 | * interval. | ||
| 338 | */ | ||
| 339 | |||
| 340 | /* Returns currently selected poll interval (in ms) */ | ||
| 341 | static ssize_t kxtj9_get_poll(struct device *dev, | ||
| 342 | struct device_attribute *attr, char *buf) | ||
| 343 | { | ||
| 344 | struct i2c_client *client = to_i2c_client(dev); | ||
| 345 | struct kxtj9_data *tj9 = i2c_get_clientdata(client); | ||
| 346 | |||
| 347 | return sprintf(buf, "%d\n", tj9->last_poll_interval); | ||
| 348 | } | ||
| 349 | |||
| 350 | /* Allow users to select a new poll interval (in ms) */ | ||
| 351 | static ssize_t kxtj9_set_poll(struct device *dev, struct device_attribute *attr, | ||
| 352 | const char *buf, size_t count) | ||
| 353 | { | ||
| 354 | struct i2c_client *client = to_i2c_client(dev); | ||
| 355 | struct kxtj9_data *tj9 = i2c_get_clientdata(client); | ||
| 356 | struct input_dev *input_dev = tj9->input_dev; | ||
| 357 | unsigned int interval; | ||
| 358 | int error; | ||
| 359 | |||
| 360 | error = kstrtouint(buf, 10, &interval); | ||
| 361 | if (error < 0) | ||
| 362 | return error; | ||
| 363 | |||
| 364 | /* Lock the device to prevent races with open/close (and itself) */ | ||
| 365 | mutex_lock(&input_dev->mutex); | ||
| 366 | |||
| 367 | disable_irq(client->irq); | ||
| 368 | |||
| 369 | /* | ||
| 370 | * Set current interval to the greater of the minimum interval or | ||
| 371 | * the requested interval | ||
| 372 | */ | ||
| 373 | tj9->last_poll_interval = max(interval, tj9->pdata.min_interval); | ||
| 374 | |||
| 375 | kxtj9_update_odr(tj9, tj9->last_poll_interval); | ||
| 376 | |||
| 377 | enable_irq(client->irq); | ||
| 378 | mutex_unlock(&input_dev->mutex); | ||
| 379 | |||
| 380 | return count; | ||
| 381 | } | ||
| 382 | |||
| 383 | static DEVICE_ATTR(poll, S_IRUGO|S_IWUSR, kxtj9_get_poll, kxtj9_set_poll); | ||
| 384 | |||
| 385 | static struct attribute *kxtj9_attributes[] = { | ||
| 386 | &dev_attr_poll.attr, | ||
| 387 | NULL | ||
| 388 | }; | ||
| 389 | |||
| 390 | static struct attribute_group kxtj9_attribute_group = { | ||
| 391 | .attrs = kxtj9_attributes | ||
| 392 | }; | ||
| 393 | |||
| 394 | |||
| 395 | #ifdef CONFIG_INPUT_KXTJ9_POLLED_MODE | ||
| 396 | static void kxtj9_poll(struct input_polled_dev *dev) | ||
| 397 | { | ||
| 398 | struct kxtj9_data *tj9 = dev->private; | ||
| 399 | unsigned int poll_interval = dev->poll_interval; | ||
| 400 | |||
| 401 | kxtj9_report_acceleration_data(tj9); | ||
| 402 | |||
| 403 | if (poll_interval != tj9->last_poll_interval) { | ||
| 404 | kxtj9_update_odr(tj9, poll_interval); | ||
| 405 | tj9->last_poll_interval = poll_interval; | ||
| 406 | } | ||
| 407 | } | ||
| 408 | |||
| 409 | static void kxtj9_polled_input_open(struct input_polled_dev *dev) | ||
| 410 | { | ||
| 411 | struct kxtj9_data *tj9 = dev->private; | ||
| 412 | |||
| 413 | kxtj9_enable(tj9); | ||
| 414 | } | ||
| 415 | |||
| 416 | static void kxtj9_polled_input_close(struct input_polled_dev *dev) | ||
| 417 | { | ||
| 418 | struct kxtj9_data *tj9 = dev->private; | ||
| 419 | |||
| 420 | kxtj9_disable(tj9); | ||
| 421 | } | ||
| 422 | |||
| 423 | static int __devinit kxtj9_setup_polled_device(struct kxtj9_data *tj9) | ||
| 424 | { | ||
| 425 | int err; | ||
| 426 | struct input_polled_dev *poll_dev; | ||
| 427 | poll_dev = input_allocate_polled_device(); | ||
| 428 | |||
| 429 | if (!poll_dev) { | ||
| 430 | dev_err(&tj9->client->dev, | ||
| 431 | "Failed to allocate polled device\n"); | ||
| 432 | return -ENOMEM; | ||
| 433 | } | ||
| 434 | |||
| 435 | tj9->poll_dev = poll_dev; | ||
| 436 | tj9->input_dev = poll_dev->input; | ||
| 437 | |||
| 438 | poll_dev->private = tj9; | ||
| 439 | poll_dev->poll = kxtj9_poll; | ||
| 440 | poll_dev->open = kxtj9_polled_input_open; | ||
| 441 | poll_dev->close = kxtj9_polled_input_close; | ||
| 442 | |||
| 443 | kxtj9_init_input_device(tj9, poll_dev->input); | ||
| 444 | |||
| 445 | err = input_register_polled_device(poll_dev); | ||
| 446 | if (err) { | ||
| 447 | dev_err(&tj9->client->dev, | ||
| 448 | "Unable to register polled device, err=%d\n", err); | ||
| 449 | input_free_polled_device(poll_dev); | ||
| 450 | return err; | ||
| 451 | } | ||
| 452 | |||
| 453 | return 0; | ||
| 454 | } | ||
| 455 | |||
| 456 | static void __devexit kxtj9_teardown_polled_device(struct kxtj9_data *tj9) | ||
| 457 | { | ||
| 458 | input_unregister_polled_device(tj9->poll_dev); | ||
| 459 | input_free_polled_device(tj9->poll_dev); | ||
| 460 | } | ||
| 461 | |||
| 462 | #else | ||
| 463 | |||
| 464 | static inline int kxtj9_setup_polled_device(struct kxtj9_data *tj9) | ||
| 465 | { | ||
| 466 | return -ENOSYS; | ||
| 467 | } | ||
| 468 | |||
| 469 | static inline void kxtj9_teardown_polled_device(struct kxtj9_data *tj9) | ||
| 470 | { | ||
| 471 | } | ||
| 472 | |||
| 473 | #endif | ||
| 474 | |||
| 475 | static int __devinit kxtj9_verify(struct kxtj9_data *tj9) | ||
| 476 | { | ||
| 477 | int retval; | ||
| 478 | |||
| 479 | retval = kxtj9_device_power_on(tj9); | ||
| 480 | if (retval < 0) | ||
| 481 | return retval; | ||
| 482 | |||
| 483 | retval = i2c_smbus_read_byte_data(tj9->client, WHO_AM_I); | ||
| 484 | if (retval < 0) { | ||
| 485 | dev_err(&tj9->client->dev, "read err int source\n"); | ||
| 486 | goto out; | ||
| 487 | } | ||
| 488 | |||
| 489 | retval = retval != 0x06 ? -EIO : 0; | ||
| 490 | |||
| 491 | out: | ||
| 492 | kxtj9_device_power_off(tj9); | ||
| 493 | return retval; | ||
| 494 | } | ||
| 495 | |||
| 496 | static int __devinit kxtj9_probe(struct i2c_client *client, | ||
| 497 | const struct i2c_device_id *id) | ||
| 498 | { | ||
| 499 | const struct kxtj9_platform_data *pdata = client->dev.platform_data; | ||
| 500 | struct kxtj9_data *tj9; | ||
| 501 | int err; | ||
| 502 | |||
| 503 | if (!i2c_check_functionality(client->adapter, | ||
| 504 | I2C_FUNC_I2C | I2C_FUNC_SMBUS_BYTE_DATA)) { | ||
| 505 | dev_err(&client->dev, "client is not i2c capable\n"); | ||
| 506 | return -ENXIO; | ||
| 507 | } | ||
| 508 | |||
| 509 | if (!pdata) { | ||
| 510 | dev_err(&client->dev, "platform data is NULL; exiting\n"); | ||
| 511 | return -EINVAL; | ||
| 512 | } | ||
| 513 | |||
| 514 | tj9 = kzalloc(sizeof(*tj9), GFP_KERNEL); | ||
| 515 | if (!tj9) { | ||
| 516 | dev_err(&client->dev, | ||
| 517 | "failed to allocate memory for module data\n"); | ||
| 518 | return -ENOMEM; | ||
| 519 | } | ||
| 520 | |||
| 521 | tj9->client = client; | ||
| 522 | tj9->pdata = *pdata; | ||
| 523 | |||
| 524 | if (pdata->init) { | ||
| 525 | err = pdata->init(); | ||
| 526 | if (err < 0) | ||
| 527 | goto err_free_mem; | ||
| 528 | } | ||
| 529 | |||
| 530 | err = kxtj9_verify(tj9); | ||
| 531 | if (err < 0) { | ||
| 532 | dev_err(&client->dev, "device not recognized\n"); | ||
| 533 | goto err_pdata_exit; | ||
| 534 | } | ||
| 535 | |||
| 536 | i2c_set_clientdata(client, tj9); | ||
| 537 | |||
| 538 | tj9->ctrl_reg1 = tj9->pdata.res_12bit | tj9->pdata.g_range; | ||
| 539 | tj9->data_ctrl = tj9->pdata.data_odr_init; | ||
| 540 | |||
| 541 | if (client->irq) { | ||
| 542 | /* If in irq mode, populate INT_CTRL_REG1 and enable DRDY. */ | ||
| 543 | tj9->int_ctrl |= KXTJ9_IEN | KXTJ9_IEA | KXTJ9_IEL; | ||
| 544 | tj9->ctrl_reg1 |= DRDYE; | ||
| 545 | |||
| 546 | err = kxtj9_setup_input_device(tj9); | ||
| 547 | if (err) | ||
| 548 | goto err_pdata_exit; | ||
| 549 | |||
| 550 | err = request_threaded_irq(client->irq, NULL, kxtj9_isr, | ||
| 551 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, | ||
| 552 | "kxtj9-irq", tj9); | ||
| 553 | if (err) { | ||
| 554 | dev_err(&client->dev, "request irq failed: %d\n", err); | ||
| 555 | goto err_destroy_input; | ||
| 556 | } | ||
| 557 | |||
| 558 | err = sysfs_create_group(&client->dev.kobj, &kxtj9_attribute_group); | ||
| 559 | if (err) { | ||
| 560 | dev_err(&client->dev, "sysfs create failed: %d\n", err); | ||
| 561 | goto err_free_irq; | ||
| 562 | } | ||
| 563 | |||
| 564 | } else { | ||
| 565 | err = kxtj9_setup_polled_device(tj9); | ||
| 566 | if (err) | ||
| 567 | goto err_pdata_exit; | ||
| 568 | } | ||
| 569 | |||
| 570 | return 0; | ||
| 571 | |||
| 572 | err_free_irq: | ||
| 573 | free_irq(client->irq, tj9); | ||
| 574 | err_destroy_input: | ||
| 575 | input_unregister_device(tj9->input_dev); | ||
| 576 | err_pdata_exit: | ||
| 577 | if (tj9->pdata.exit) | ||
| 578 | tj9->pdata.exit(); | ||
| 579 | err_free_mem: | ||
| 580 | kfree(tj9); | ||
| 581 | return err; | ||
| 582 | } | ||
| 583 | |||
| 584 | static int __devexit kxtj9_remove(struct i2c_client *client) | ||
| 585 | { | ||
| 586 | struct kxtj9_data *tj9 = i2c_get_clientdata(client); | ||
| 587 | |||
| 588 | if (client->irq) { | ||
| 589 | sysfs_remove_group(&client->dev.kobj, &kxtj9_attribute_group); | ||
| 590 | free_irq(client->irq, tj9); | ||
| 591 | input_unregister_device(tj9->input_dev); | ||
| 592 | } else { | ||
| 593 | kxtj9_teardown_polled_device(tj9); | ||
| 594 | } | ||
| 595 | |||
| 596 | if (tj9->pdata.exit) | ||
| 597 | tj9->pdata.exit(); | ||
| 598 | |||
| 599 | kfree(tj9); | ||
| 600 | |||
| 601 | return 0; | ||
| 602 | } | ||
| 603 | |||
| 604 | #ifdef CONFIG_PM_SLEEP | ||
| 605 | static int kxtj9_suspend(struct device *dev) | ||
| 606 | { | ||
| 607 | struct i2c_client *client = to_i2c_client(dev); | ||
| 608 | struct kxtj9_data *tj9 = i2c_get_clientdata(client); | ||
| 609 | struct input_dev *input_dev = tj9->input_dev; | ||
| 610 | |||
| 611 | mutex_lock(&input_dev->mutex); | ||
| 612 | |||
| 613 | if (input_dev->users) | ||
| 614 | kxtj9_disable(tj9); | ||
| 615 | |||
| 616 | mutex_unlock(&input_dev->mutex); | ||
| 617 | return 0; | ||
| 618 | } | ||
| 619 | |||
| 620 | static int kxtj9_resume(struct device *dev) | ||
| 621 | { | ||
| 622 | struct i2c_client *client = to_i2c_client(dev); | ||
| 623 | struct kxtj9_data *tj9 = i2c_get_clientdata(client); | ||
| 624 | struct input_dev *input_dev = tj9->input_dev; | ||
| 625 | int retval = 0; | ||
| 626 | |||
| 627 | mutex_lock(&input_dev->mutex); | ||
| 628 | |||
| 629 | if (input_dev->users) | ||
| 630 | kxtj9_enable(tj9); | ||
| 631 | |||
| 632 | mutex_unlock(&input_dev->mutex); | ||
| 633 | return retval; | ||
| 634 | } | ||
| 635 | #endif | ||
| 636 | |||
| 637 | static SIMPLE_DEV_PM_OPS(kxtj9_pm_ops, kxtj9_suspend, kxtj9_resume); | ||
| 638 | |||
| 639 | static const struct i2c_device_id kxtj9_id[] = { | ||
| 640 | { NAME, 0 }, | ||
| 641 | { }, | ||
| 642 | }; | ||
| 643 | |||
| 644 | MODULE_DEVICE_TABLE(i2c, kxtj9_id); | ||
| 645 | |||
| 646 | static struct i2c_driver kxtj9_driver = { | ||
| 647 | .driver = { | ||
| 648 | .name = NAME, | ||
| 649 | .owner = THIS_MODULE, | ||
| 650 | .pm = &kxtj9_pm_ops, | ||
| 651 | }, | ||
| 652 | .probe = kxtj9_probe, | ||
| 653 | .remove = __devexit_p(kxtj9_remove), | ||
| 654 | .id_table = kxtj9_id, | ||
| 655 | }; | ||
| 656 | |||
| 657 | static int __init kxtj9_init(void) | ||
| 658 | { | ||
| 659 | return i2c_add_driver(&kxtj9_driver); | ||
| 660 | } | ||
| 661 | module_init(kxtj9_init); | ||
| 662 | |||
| 663 | static void __exit kxtj9_exit(void) | ||
| 664 | { | ||
| 665 | i2c_del_driver(&kxtj9_driver); | ||
| 666 | } | ||
| 667 | module_exit(kxtj9_exit); | ||
| 668 | |||
| 669 | MODULE_DESCRIPTION("KXTJ9 accelerometer driver"); | ||
| 670 | MODULE_AUTHOR("Chris Hudson <chudson@kionix.com>"); | ||
| 671 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/misc/mma8450.c b/drivers/input/misc/mma8450.c new file mode 100644 index 000000000000..20f8f9284f02 --- /dev/null +++ b/drivers/input/misc/mma8450.c | |||
| @@ -0,0 +1,256 @@ | |||
| 1 | /* | ||
| 2 | * Driver for Freescale's 3-Axis Accelerometer MMA8450 | ||
| 3 | * | ||
| 4 | * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/kernel.h> | ||
| 22 | #include <linux/module.h> | ||
| 23 | #include <linux/slab.h> | ||
| 24 | #include <linux/delay.h> | ||
| 25 | #include <linux/i2c.h> | ||
| 26 | #include <linux/input-polldev.h> | ||
| 27 | |||
| 28 | #define MMA8450_DRV_NAME "mma8450" | ||
| 29 | |||
| 30 | #define MODE_CHANGE_DELAY_MS 100 | ||
| 31 | #define POLL_INTERVAL 100 | ||
| 32 | #define POLL_INTERVAL_MAX 500 | ||
| 33 | |||
| 34 | /* register definitions */ | ||
| 35 | #define MMA8450_STATUS 0x00 | ||
| 36 | #define MMA8450_STATUS_ZXYDR 0x08 | ||
| 37 | |||
| 38 | #define MMA8450_OUT_X8 0x01 | ||
| 39 | #define MMA8450_OUT_Y8 0x02 | ||
| 40 | #define MMA8450_OUT_Z8 0x03 | ||
| 41 | |||
| 42 | #define MMA8450_OUT_X_LSB 0x05 | ||
| 43 | #define MMA8450_OUT_X_MSB 0x06 | ||
| 44 | #define MMA8450_OUT_Y_LSB 0x07 | ||
| 45 | #define MMA8450_OUT_Y_MSB 0x08 | ||
| 46 | #define MMA8450_OUT_Z_LSB 0x09 | ||
| 47 | #define MMA8450_OUT_Z_MSB 0x0a | ||
| 48 | |||
| 49 | #define MMA8450_XYZ_DATA_CFG 0x16 | ||
| 50 | |||
| 51 | #define MMA8450_CTRL_REG1 0x38 | ||
| 52 | #define MMA8450_CTRL_REG2 0x39 | ||
| 53 | |||
| 54 | /* mma8450 status */ | ||
| 55 | struct mma8450 { | ||
| 56 | struct i2c_client *client; | ||
| 57 | struct input_polled_dev *idev; | ||
| 58 | }; | ||
| 59 | |||
| 60 | static int mma8450_read(struct mma8450 *m, unsigned off) | ||
| 61 | { | ||
| 62 | struct i2c_client *c = m->client; | ||
| 63 | int ret; | ||
| 64 | |||
| 65 | ret = i2c_smbus_read_byte_data(c, off); | ||
| 66 | if (ret < 0) | ||
| 67 | dev_err(&c->dev, | ||
| 68 | "failed to read register 0x%02x, error %d\n", | ||
| 69 | off, ret); | ||
| 70 | |||
| 71 | return ret; | ||
| 72 | } | ||
| 73 | |||
| 74 | static int mma8450_write(struct mma8450 *m, unsigned off, u8 v) | ||
| 75 | { | ||
| 76 | struct i2c_client *c = m->client; | ||
| 77 | int error; | ||
| 78 | |||
| 79 | error = i2c_smbus_write_byte_data(c, off, v); | ||
| 80 | if (error < 0) { | ||
| 81 | dev_err(&c->dev, | ||
| 82 | "failed to write to register 0x%02x, error %d\n", | ||
| 83 | off, error); | ||
| 84 | return error; | ||
| 85 | } | ||
| 86 | |||
| 87 | return 0; | ||
| 88 | } | ||
| 89 | |||
| 90 | static int mma8450_read_xyz(struct mma8450 *m, int *x, int *y, int *z) | ||
| 91 | { | ||
| 92 | struct i2c_client *c = m->client; | ||
| 93 | u8 buff[6]; | ||
| 94 | int err; | ||
| 95 | |||
| 96 | err = i2c_smbus_read_i2c_block_data(c, MMA8450_OUT_X_LSB, 6, buff); | ||
| 97 | if (err < 0) { | ||
| 98 | dev_err(&c->dev, | ||
| 99 | "failed to read block data at 0x%02x, error %d\n", | ||
| 100 | MMA8450_OUT_X_LSB, err); | ||
| 101 | return err; | ||
| 102 | } | ||
| 103 | |||
| 104 | *x = ((buff[1] << 4) & 0xff0) | (buff[0] & 0xf); | ||
| 105 | *y = ((buff[3] << 4) & 0xff0) | (buff[2] & 0xf); | ||
| 106 | *z = ((buff[5] << 4) & 0xff0) | (buff[4] & 0xf); | ||
| 107 | |||
| 108 | return 0; | ||
| 109 | } | ||
| 110 | |||
| 111 | static void mma8450_poll(struct input_polled_dev *dev) | ||
| 112 | { | ||
| 113 | struct mma8450 *m = dev->private; | ||
| 114 | int x, y, z; | ||
| 115 | int ret; | ||
| 116 | int err; | ||
| 117 | |||
| 118 | ret = mma8450_read(m, MMA8450_STATUS); | ||
| 119 | if (ret < 0) | ||
| 120 | return; | ||
| 121 | |||
| 122 | if (!(ret & MMA8450_STATUS_ZXYDR)) | ||
| 123 | return; | ||
| 124 | |||
| 125 | err = mma8450_read_xyz(m, &x, &y, &z); | ||
| 126 | if (err) | ||
| 127 | return; | ||
| 128 | |||
| 129 | input_report_abs(dev->input, ABS_X, x); | ||
| 130 | input_report_abs(dev->input, ABS_Y, y); | ||
| 131 | input_report_abs(dev->input, ABS_Z, z); | ||
| 132 | input_sync(dev->input); | ||
| 133 | } | ||
| 134 | |||
| 135 | /* Initialize the MMA8450 chip */ | ||
| 136 | static void mma8450_open(struct input_polled_dev *dev) | ||
| 137 | { | ||
| 138 | struct mma8450 *m = dev->private; | ||
| 139 | int err; | ||
| 140 | |||
| 141 | /* enable all events from X/Y/Z, no FIFO */ | ||
| 142 | err = mma8450_write(m, MMA8450_XYZ_DATA_CFG, 0x07); | ||
| 143 | if (err) | ||
| 144 | return; | ||
| 145 | |||
| 146 | /* | ||
| 147 | * Sleep mode poll rate - 50Hz | ||
| 148 | * System output data rate - 400Hz | ||
| 149 | * Full scale selection - Active, +/- 2G | ||
| 150 | */ | ||
| 151 | err = mma8450_write(m, MMA8450_CTRL_REG1, 0x01); | ||
| 152 | if (err < 0) | ||
| 153 | return; | ||
| 154 | |||
| 155 | msleep(MODE_CHANGE_DELAY_MS); | ||
| 156 | } | ||
| 157 | |||
| 158 | static void mma8450_close(struct input_polled_dev *dev) | ||
| 159 | { | ||
| 160 | struct mma8450 *m = dev->private; | ||
| 161 | |||
| 162 | mma8450_write(m, MMA8450_CTRL_REG1, 0x00); | ||
| 163 | mma8450_write(m, MMA8450_CTRL_REG2, 0x01); | ||
| 164 | } | ||
| 165 | |||
| 166 | /* | ||
| 167 | * I2C init/probing/exit functions | ||
| 168 | */ | ||
| 169 | static int __devinit mma8450_probe(struct i2c_client *c, | ||
| 170 | const struct i2c_device_id *id) | ||
| 171 | { | ||
| 172 | struct input_polled_dev *idev; | ||
| 173 | struct mma8450 *m; | ||
| 174 | int err; | ||
| 175 | |||
| 176 | m = kzalloc(sizeof(struct mma8450), GFP_KERNEL); | ||
| 177 | idev = input_allocate_polled_device(); | ||
| 178 | if (!m || !idev) { | ||
| 179 | err = -ENOMEM; | ||
| 180 | goto err_free_mem; | ||
| 181 | } | ||
| 182 | |||
| 183 | m->client = c; | ||
| 184 | m->idev = idev; | ||
| 185 | |||
| 186 | idev->private = m; | ||
| 187 | idev->input->name = MMA8450_DRV_NAME; | ||
| 188 | idev->input->id.bustype = BUS_I2C; | ||
| 189 | idev->poll = mma8450_poll; | ||
| 190 | idev->poll_interval = POLL_INTERVAL; | ||
| 191 | idev->poll_interval_max = POLL_INTERVAL_MAX; | ||
| 192 | idev->open = mma8450_open; | ||
| 193 | idev->close = mma8450_close; | ||
| 194 | |||
| 195 | __set_bit(EV_ABS, idev->input->evbit); | ||
| 196 | input_set_abs_params(idev->input, ABS_X, -2048, 2047, 32, 32); | ||
| 197 | input_set_abs_params(idev->input, ABS_Y, -2048, 2047, 32, 32); | ||
| 198 | input_set_abs_params(idev->input, ABS_Z, -2048, 2047, 32, 32); | ||
| 199 | |||
| 200 | err = input_register_polled_device(idev); | ||
| 201 | if (err) { | ||
| 202 | dev_err(&c->dev, "failed to register polled input device\n"); | ||
| 203 | goto err_free_mem; | ||
| 204 | } | ||
| 205 | |||
| 206 | return 0; | ||
| 207 | |||
| 208 | err_free_mem: | ||
| 209 | input_free_polled_device(idev); | ||
| 210 | kfree(m); | ||
| 211 | return err; | ||
| 212 | } | ||
| 213 | |||
| 214 | static int __devexit mma8450_remove(struct i2c_client *c) | ||
| 215 | { | ||
| 216 | struct mma8450 *m = i2c_get_clientdata(c); | ||
| 217 | struct input_polled_dev *idev = m->idev; | ||
| 218 | |||
| 219 | input_unregister_polled_device(idev); | ||
| 220 | input_free_polled_device(idev); | ||
| 221 | kfree(m); | ||
| 222 | |||
| 223 | return 0; | ||
| 224 | } | ||
| 225 | |||
| 226 | static const struct i2c_device_id mma8450_id[] = { | ||
| 227 | { MMA8450_DRV_NAME, 0 }, | ||
| 228 | { }, | ||
| 229 | }; | ||
| 230 | MODULE_DEVICE_TABLE(i2c, mma8450_id); | ||
| 231 | |||
| 232 | static struct i2c_driver mma8450_driver = { | ||
| 233 | .driver = { | ||
| 234 | .name = MMA8450_DRV_NAME, | ||
| 235 | .owner = THIS_MODULE, | ||
| 236 | }, | ||
| 237 | .probe = mma8450_probe, | ||
| 238 | .remove = __devexit_p(mma8450_remove), | ||
| 239 | .id_table = mma8450_id, | ||
| 240 | }; | ||
| 241 | |||
| 242 | static int __init mma8450_init(void) | ||
| 243 | { | ||
| 244 | return i2c_add_driver(&mma8450_driver); | ||
| 245 | } | ||
| 246 | module_init(mma8450_init); | ||
| 247 | |||
| 248 | static void __exit mma8450_exit(void) | ||
| 249 | { | ||
| 250 | i2c_del_driver(&mma8450_driver); | ||
| 251 | } | ||
| 252 | module_exit(mma8450_exit); | ||
| 253 | |||
| 254 | MODULE_AUTHOR("Freescale Semiconductor, Inc."); | ||
| 255 | MODULE_DESCRIPTION("MMA8450 3-Axis Accelerometer Driver"); | ||
| 256 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/misc/mpu3050.c b/drivers/input/misc/mpu3050.c new file mode 100644 index 000000000000..b95fac15b2ea --- /dev/null +++ b/drivers/input/misc/mpu3050.c | |||
| @@ -0,0 +1,376 @@ | |||
| 1 | /* | ||
| 2 | * MPU3050 Tri-axis gyroscope driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2011 Wistron Co.Ltd | ||
| 5 | * Joseph Lai <joseph_lai@wistron.com> | ||
| 6 | * | ||
| 7 | * Trimmed down by Alan Cox <alan@linux.intel.com> to produce this version | ||
| 8 | * | ||
| 9 | * This is a 'lite' version of the driver, while we consider the right way | ||
| 10 | * to present the other features to user space. In particular it requires the | ||
| 11 | * device has an IRQ, and it only provides an input interface, so is not much | ||
| 12 | * use for device orientation. A fuller version is available from the Meego | ||
| 13 | * tree. | ||
| 14 | * | ||
| 15 | * This program is based on bma023.c. | ||
| 16 | * | ||
| 17 | * This program is free software; you can redistribute it and/or modify | ||
| 18 | * it under the terms of the GNU General Public License as published by | ||
| 19 | * the Free Software Foundation; version 2 of the License. | ||
| 20 | * | ||
| 21 | * This program is distributed in the hope that it will be useful, but | ||
| 22 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 24 | * General Public License for more details. | ||
| 25 | * | ||
| 26 | * You should have received a copy of the GNU General Public License along | ||
| 27 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 28 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
| 29 | * | ||
| 30 | */ | ||
| 31 | |||
| 32 | #include <linux/module.h> | ||
| 33 | #include <linux/init.h> | ||
| 34 | #include <linux/interrupt.h> | ||
| 35 | #include <linux/platform_device.h> | ||
| 36 | #include <linux/mutex.h> | ||
| 37 | #include <linux/err.h> | ||
| 38 | #include <linux/i2c.h> | ||
| 39 | #include <linux/input.h> | ||
| 40 | #include <linux/delay.h> | ||
| 41 | #include <linux/slab.h> | ||
| 42 | #include <linux/pm_runtime.h> | ||
| 43 | |||
| 44 | #define MPU3050_CHIP_ID_REG 0x00 | ||
| 45 | #define MPU3050_CHIP_ID 0x69 | ||
| 46 | #define MPU3050_XOUT_H 0x1D | ||
| 47 | #define MPU3050_PWR_MGM 0x3E | ||
| 48 | #define MPU3050_PWR_MGM_POS 6 | ||
| 49 | #define MPU3050_PWR_MGM_MASK 0x40 | ||
| 50 | |||
| 51 | #define MPU3050_AUTO_DELAY 1000 | ||
| 52 | |||
| 53 | #define MPU3050_MIN_VALUE -32768 | ||
| 54 | #define MPU3050_MAX_VALUE 32767 | ||
| 55 | |||
| 56 | struct axis_data { | ||
| 57 | s16 x; | ||
| 58 | s16 y; | ||
| 59 | s16 z; | ||
| 60 | }; | ||
| 61 | |||
| 62 | struct mpu3050_sensor { | ||
| 63 | struct i2c_client *client; | ||
| 64 | struct device *dev; | ||
| 65 | struct input_dev *idev; | ||
| 66 | }; | ||
| 67 | |||
| 68 | /** | ||
| 69 | * mpu3050_xyz_read_reg - read the axes values | ||
| 70 | * @buffer: provide register addr and get register | ||
| 71 | * @length: length of register | ||
| 72 | * | ||
| 73 | * Reads the register values in one transaction or returns a negative | ||
| 74 | * error code on failure. | ||
| 75 | */ | ||
| 76 | static int mpu3050_xyz_read_reg(struct i2c_client *client, | ||
| 77 | u8 *buffer, int length) | ||
| 78 | { | ||
| 79 | /* | ||
| 80 | * Annoying we can't make this const because the i2c layer doesn't | ||
| 81 | * declare input buffers const. | ||
| 82 | */ | ||
| 83 | char cmd = MPU3050_XOUT_H; | ||
| 84 | struct i2c_msg msg[] = { | ||
| 85 | { | ||
| 86 | .addr = client->addr, | ||
| 87 | .flags = 0, | ||
| 88 | .len = 1, | ||
| 89 | .buf = &cmd, | ||
| 90 | }, | ||
| 91 | { | ||
| 92 | .addr = client->addr, | ||
| 93 | .flags = I2C_M_RD, | ||
| 94 | .len = length, | ||
| 95 | .buf = buffer, | ||
| 96 | }, | ||
| 97 | }; | ||
| 98 | |||
| 99 | return i2c_transfer(client->adapter, msg, 2); | ||
| 100 | } | ||
| 101 | |||
| 102 | /** | ||
| 103 | * mpu3050_read_xyz - get co-ordinates from device | ||
| 104 | * @client: i2c address of sensor | ||
| 105 | * @coords: co-ordinates to update | ||
| 106 | * | ||
| 107 | * Return the converted X Y and Z co-ordinates from the sensor device | ||
| 108 | */ | ||
| 109 | static void mpu3050_read_xyz(struct i2c_client *client, | ||
| 110 | struct axis_data *coords) | ||
| 111 | { | ||
| 112 | u16 buffer[3]; | ||
| 113 | |||
| 114 | mpu3050_xyz_read_reg(client, (u8 *)buffer, 6); | ||
| 115 | coords->x = be16_to_cpu(buffer[0]); | ||
| 116 | coords->y = be16_to_cpu(buffer[1]); | ||
| 117 | coords->z = be16_to_cpu(buffer[2]); | ||
| 118 | dev_dbg(&client->dev, "%s: x %d, y %d, z %d\n", __func__, | ||
| 119 | coords->x, coords->y, coords->z); | ||
| 120 | } | ||
| 121 | |||
| 122 | /** | ||
| 123 | * mpu3050_set_power_mode - set the power mode | ||
| 124 | * @client: i2c client for the sensor | ||
| 125 | * @val: value to switch on/off of power, 1: normal power, 0: low power | ||
| 126 | * | ||
| 127 | * Put device to normal-power mode or low-power mode. | ||
| 128 | */ | ||
| 129 | static void mpu3050_set_power_mode(struct i2c_client *client, u8 val) | ||
| 130 | { | ||
| 131 | u8 value; | ||
| 132 | |||
| 133 | value = i2c_smbus_read_byte_data(client, MPU3050_PWR_MGM); | ||
| 134 | value = (value & ~MPU3050_PWR_MGM_MASK) | | ||
| 135 | (((val << MPU3050_PWR_MGM_POS) & MPU3050_PWR_MGM_MASK) ^ | ||
| 136 | MPU3050_PWR_MGM_MASK); | ||
| 137 | i2c_smbus_write_byte_data(client, MPU3050_PWR_MGM, value); | ||
| 138 | } | ||
| 139 | |||
| 140 | /** | ||
| 141 | * mpu3050_input_open - called on input event open | ||
| 142 | * @input: input dev of opened device | ||
| 143 | * | ||
| 144 | * The input layer calls this function when input event is opened. The | ||
| 145 | * function will push the device to resume. Then, the device is ready | ||
| 146 | * to provide data. | ||
| 147 | */ | ||
| 148 | static int mpu3050_input_open(struct input_dev *input) | ||
| 149 | { | ||
| 150 | struct mpu3050_sensor *sensor = input_get_drvdata(input); | ||
| 151 | |||
| 152 | pm_runtime_get(sensor->dev); | ||
| 153 | |||
| 154 | return 0; | ||
| 155 | } | ||
| 156 | |||
| 157 | /** | ||
| 158 | * mpu3050_input_close - called on input event close | ||
| 159 | * @input: input dev of closed device | ||
| 160 | * | ||
| 161 | * The input layer calls this function when input event is closed. The | ||
| 162 | * function will push the device to suspend. | ||
| 163 | */ | ||
| 164 | static void mpu3050_input_close(struct input_dev *input) | ||
| 165 | { | ||
| 166 | struct mpu3050_sensor *sensor = input_get_drvdata(input); | ||
| 167 | |||
| 168 | pm_runtime_put(sensor->dev); | ||
| 169 | } | ||
| 170 | |||
| 171 | /** | ||
| 172 | * mpu3050_interrupt_thread - handle an IRQ | ||
| 173 | * @irq: interrupt numner | ||
| 174 | * @data: the sensor | ||
| 175 | * | ||
| 176 | * Called by the kernel single threaded after an interrupt occurs. Read | ||
| 177 | * the sensor data and generate an input event for it. | ||
| 178 | */ | ||
| 179 | static irqreturn_t mpu3050_interrupt_thread(int irq, void *data) | ||
| 180 | { | ||
| 181 | struct mpu3050_sensor *sensor = data; | ||
| 182 | struct axis_data axis; | ||
| 183 | |||
| 184 | mpu3050_read_xyz(sensor->client, &axis); | ||
| 185 | |||
| 186 | input_report_abs(sensor->idev, ABS_X, axis.x); | ||
| 187 | input_report_abs(sensor->idev, ABS_Y, axis.y); | ||
| 188 | input_report_abs(sensor->idev, ABS_Z, axis.z); | ||
| 189 | input_sync(sensor->idev); | ||
| 190 | |||
| 191 | return IRQ_HANDLED; | ||
| 192 | } | ||
| 193 | |||
| 194 | /** | ||
| 195 | * mpu3050_probe - device detection callback | ||
| 196 | * @client: i2c client of found device | ||
| 197 | * @id: id match information | ||
| 198 | * | ||
| 199 | * The I2C layer calls us when it believes a sensor is present at this | ||
| 200 | * address. Probe to see if this is correct and to validate the device. | ||
| 201 | * | ||
| 202 | * If present install the relevant sysfs interfaces and input device. | ||
| 203 | */ | ||
| 204 | static int __devinit mpu3050_probe(struct i2c_client *client, | ||
| 205 | const struct i2c_device_id *id) | ||
| 206 | { | ||
| 207 | struct mpu3050_sensor *sensor; | ||
| 208 | struct input_dev *idev; | ||
| 209 | int ret; | ||
| 210 | int error; | ||
| 211 | |||
| 212 | sensor = kzalloc(sizeof(struct mpu3050_sensor), GFP_KERNEL); | ||
| 213 | idev = input_allocate_device(); | ||
| 214 | if (!sensor || !idev) { | ||
| 215 | dev_err(&client->dev, "failed to allocate driver data\n"); | ||
| 216 | error = -ENOMEM; | ||
| 217 | goto err_free_mem; | ||
| 218 | } | ||
| 219 | |||
| 220 | sensor->client = client; | ||
| 221 | sensor->dev = &client->dev; | ||
| 222 | sensor->idev = idev; | ||
| 223 | |||
| 224 | mpu3050_set_power_mode(client, 1); | ||
| 225 | msleep(10); | ||
| 226 | |||
| 227 | ret = i2c_smbus_read_byte_data(client, MPU3050_CHIP_ID_REG); | ||
| 228 | if (ret < 0) { | ||
| 229 | dev_err(&client->dev, "failed to detect device\n"); | ||
| 230 | error = -ENXIO; | ||
| 231 | goto err_free_mem; | ||
| 232 | } | ||
| 233 | |||
| 234 | if (ret != MPU3050_CHIP_ID) { | ||
| 235 | dev_err(&client->dev, "unsupported chip id\n"); | ||
| 236 | error = -ENXIO; | ||
| 237 | goto err_free_mem; | ||
| 238 | } | ||
| 239 | |||
| 240 | idev->name = "MPU3050"; | ||
| 241 | idev->id.bustype = BUS_I2C; | ||
| 242 | idev->dev.parent = &client->dev; | ||
| 243 | |||
| 244 | idev->open = mpu3050_input_open; | ||
| 245 | idev->close = mpu3050_input_close; | ||
| 246 | |||
| 247 | __set_bit(EV_ABS, idev->evbit); | ||
| 248 | input_set_abs_params(idev, ABS_X, | ||
| 249 | MPU3050_MIN_VALUE, MPU3050_MAX_VALUE, 0, 0); | ||
| 250 | input_set_abs_params(idev, ABS_Y, | ||
| 251 | MPU3050_MIN_VALUE, MPU3050_MAX_VALUE, 0, 0); | ||
| 252 | input_set_abs_params(idev, ABS_Z, | ||
| 253 | MPU3050_MIN_VALUE, MPU3050_MAX_VALUE, 0, 0); | ||
| 254 | |||
| 255 | input_set_drvdata(idev, sensor); | ||
| 256 | |||
| 257 | pm_runtime_set_active(&client->dev); | ||
| 258 | |||
| 259 | error = request_threaded_irq(client->irq, | ||
| 260 | NULL, mpu3050_interrupt_thread, | ||
| 261 | IRQF_TRIGGER_RISING, | ||
| 262 | "mpu_int", sensor); | ||
| 263 | if (error) { | ||
| 264 | dev_err(&client->dev, | ||
| 265 | "can't get IRQ %d, error %d\n", client->irq, error); | ||
| 266 | goto err_pm_set_suspended; | ||
| 267 | } | ||
| 268 | |||
| 269 | error = input_register_device(idev); | ||
| 270 | if (error) { | ||
| 271 | dev_err(&client->dev, "failed to register input device\n"); | ||
| 272 | goto err_free_irq; | ||
| 273 | } | ||
| 274 | |||
| 275 | pm_runtime_enable(&client->dev); | ||
| 276 | pm_runtime_set_autosuspend_delay(&client->dev, MPU3050_AUTO_DELAY); | ||
| 277 | |||
| 278 | return 0; | ||
| 279 | |||
| 280 | err_free_irq: | ||
| 281 | free_irq(client->irq, sensor); | ||
| 282 | err_pm_set_suspended: | ||
| 283 | pm_runtime_set_suspended(&client->dev); | ||
| 284 | err_free_mem: | ||
| 285 | input_unregister_device(idev); | ||
| 286 | kfree(sensor); | ||
| 287 | return error; | ||
| 288 | } | ||
| 289 | |||
| 290 | /** | ||
| 291 | * mpu3050_remove - remove a sensor | ||
| 292 | * @client: i2c client of sensor being removed | ||
| 293 | * | ||
| 294 | * Our sensor is going away, clean up the resources. | ||
| 295 | */ | ||
| 296 | static int __devexit mpu3050_remove(struct i2c_client *client) | ||
| 297 | { | ||
| 298 | struct mpu3050_sensor *sensor = i2c_get_clientdata(client); | ||
| 299 | |||
| 300 | pm_runtime_disable(&client->dev); | ||
| 301 | pm_runtime_set_suspended(&client->dev); | ||
| 302 | |||
| 303 | free_irq(client->irq, sensor); | ||
| 304 | input_unregister_device(sensor->idev); | ||
| 305 | kfree(sensor); | ||
| 306 | |||
| 307 | return 0; | ||
| 308 | } | ||
| 309 | |||
| 310 | #ifdef CONFIG_PM | ||
| 311 | /** | ||
| 312 | * mpu3050_suspend - called on device suspend | ||
| 313 | * @dev: device being suspended | ||
| 314 | * | ||
| 315 | * Put the device into sleep mode before we suspend the machine. | ||
| 316 | */ | ||
| 317 | static int mpu3050_suspend(struct device *dev) | ||
| 318 | { | ||
| 319 | struct i2c_client *client = to_i2c_client(dev); | ||
| 320 | |||
| 321 | mpu3050_set_power_mode(client, 0); | ||
| 322 | |||
| 323 | return 0; | ||
| 324 | } | ||
| 325 | |||
| 326 | /** | ||
| 327 | * mpu3050_resume - called on device resume | ||
| 328 | * @dev: device being resumed | ||
| 329 | * | ||
| 330 | * Put the device into powered mode on resume. | ||
| 331 | */ | ||
| 332 | static int mpu3050_resume(struct device *dev) | ||
| 333 | { | ||
| 334 | struct i2c_client *client = to_i2c_client(dev); | ||
| 335 | |||
| 336 | mpu3050_set_power_mode(client, 1); | ||
| 337 | msleep(100); /* wait for gyro chip resume */ | ||
| 338 | |||
| 339 | return 0; | ||
| 340 | } | ||
| 341 | #endif | ||
| 342 | |||
| 343 | static UNIVERSAL_DEV_PM_OPS(mpu3050_pm, mpu3050_suspend, mpu3050_resume, NULL); | ||
| 344 | |||
| 345 | static const struct i2c_device_id mpu3050_ids[] = { | ||
| 346 | { "mpu3050", 0 }, | ||
| 347 | { } | ||
| 348 | }; | ||
| 349 | MODULE_DEVICE_TABLE(i2c, mpu3050_ids); | ||
| 350 | |||
| 351 | static struct i2c_driver mpu3050_i2c_driver = { | ||
| 352 | .driver = { | ||
| 353 | .name = "mpu3050", | ||
| 354 | .owner = THIS_MODULE, | ||
| 355 | .pm = &mpu3050_pm, | ||
| 356 | }, | ||
| 357 | .probe = mpu3050_probe, | ||
| 358 | .remove = __devexit_p(mpu3050_remove), | ||
| 359 | .id_table = mpu3050_ids, | ||
| 360 | }; | ||
| 361 | |||
| 362 | static int __init mpu3050_init(void) | ||
| 363 | { | ||
| 364 | return i2c_add_driver(&mpu3050_i2c_driver); | ||
| 365 | } | ||
| 366 | module_init(mpu3050_init); | ||
| 367 | |||
| 368 | static void __exit mpu3050_exit(void) | ||
| 369 | { | ||
| 370 | i2c_del_driver(&mpu3050_i2c_driver); | ||
| 371 | } | ||
| 372 | module_exit(mpu3050_exit); | ||
| 373 | |||
| 374 | MODULE_AUTHOR("Wistron Corp."); | ||
| 375 | MODULE_DESCRIPTION("MPU3050 Tri-axis gyroscope driver"); | ||
| 376 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/misc/xen-kbdfront.c b/drivers/input/misc/xen-kbdfront.c index 62bae99424e6..ad2e51c04db8 100644 --- a/drivers/input/misc/xen-kbdfront.c +++ b/drivers/input/misc/xen-kbdfront.c | |||
| @@ -373,7 +373,7 @@ static struct xenbus_driver xenkbd_driver = { | |||
| 373 | 373 | ||
| 374 | static int __init xenkbd_init(void) | 374 | static int __init xenkbd_init(void) |
| 375 | { | 375 | { |
| 376 | if (!xen_pv_domain()) | 376 | if (!xen_domain()) |
| 377 | return -ENODEV; | 377 | return -ENODEV; |
| 378 | 378 | ||
| 379 | /* Nothing to do if running in dom0. */ | 379 | /* Nothing to do if running in dom0. */ |
diff --git a/drivers/input/mouse/gpio_mouse.c b/drivers/input/mouse/gpio_mouse.c index 7b6ce178f1b6..58902fbb9896 100644 --- a/drivers/input/mouse/gpio_mouse.c +++ b/drivers/input/mouse/gpio_mouse.c | |||
| @@ -191,7 +191,7 @@ static void __exit gpio_mouse_exit(void) | |||
| 191 | } | 191 | } |
| 192 | module_exit(gpio_mouse_exit); | 192 | module_exit(gpio_mouse_exit); |
| 193 | 193 | ||
| 194 | MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>"); | 194 | MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>"); |
| 195 | MODULE_DESCRIPTION("GPIO mouse driver"); | 195 | MODULE_DESCRIPTION("GPIO mouse driver"); |
| 196 | MODULE_LICENSE("GPL"); | 196 | MODULE_LICENSE("GPL"); |
| 197 | MODULE_ALIAS("platform:gpio_mouse"); /* work with hotplug and coldplug */ | 197 | MODULE_ALIAS("platform:gpio_mouse"); /* work with hotplug and coldplug */ |
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index c31ad11df6bb..83bcaba96b89 100644 --- a/drivers/input/mouse/lifebook.c +++ b/drivers/input/mouse/lifebook.c | |||
| @@ -33,7 +33,7 @@ static const char *desired_serio_phys; | |||
| 33 | static int lifebook_limit_serio3(const struct dmi_system_id *d) | 33 | static int lifebook_limit_serio3(const struct dmi_system_id *d) |
| 34 | { | 34 | { |
| 35 | desired_serio_phys = "isa0060/serio3"; | 35 | desired_serio_phys = "isa0060/serio3"; |
| 36 | return 0; | 36 | return 1; |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | static bool lifebook_use_6byte_proto; | 39 | static bool lifebook_use_6byte_proto; |
| @@ -41,7 +41,7 @@ static bool lifebook_use_6byte_proto; | |||
| 41 | static int lifebook_set_6byte_proto(const struct dmi_system_id *d) | 41 | static int lifebook_set_6byte_proto(const struct dmi_system_id *d) |
| 42 | { | 42 | { |
| 43 | lifebook_use_6byte_proto = true; | 43 | lifebook_use_6byte_proto = true; |
| 44 | return 0; | 44 | return 1; |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | static const struct dmi_system_id __initconst lifebook_dmi_table[] = { | 47 | static const struct dmi_system_id __initconst lifebook_dmi_table[] = { |
diff --git a/drivers/input/mouse/pxa930_trkball.c b/drivers/input/mouse/pxa930_trkball.c index 943cfec15665..6c5d84fcdea1 100644 --- a/drivers/input/mouse/pxa930_trkball.c +++ b/drivers/input/mouse/pxa930_trkball.c | |||
| @@ -12,7 +12,6 @@ | |||
| 12 | 12 | ||
| 13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
| 14 | #include <linux/input.h> | 14 | #include <linux/input.h> |
| 15 | #include <linux/version.h> | ||
| 16 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
| 17 | #include <linux/module.h> | 16 | #include <linux/module.h> |
| 18 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c index 1242775fee19..2fc887a51066 100644 --- a/drivers/input/mouse/sentelic.c +++ b/drivers/input/mouse/sentelic.c | |||
| @@ -20,7 +20,6 @@ | |||
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
| 23 | #include <linux/version.h> | ||
| 24 | #include <linux/input.h> | 23 | #include <linux/input.h> |
| 25 | #include <linux/ctype.h> | 24 | #include <linux/ctype.h> |
| 26 | #include <linux/libps2.h> | 25 | #include <linux/libps2.h> |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index e06e045bf907..5538fc657af1 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
| @@ -207,27 +207,37 @@ static int synaptics_identify(struct psmouse *psmouse) | |||
| 207 | static int synaptics_resolution(struct psmouse *psmouse) | 207 | static int synaptics_resolution(struct psmouse *psmouse) |
| 208 | { | 208 | { |
| 209 | struct synaptics_data *priv = psmouse->private; | 209 | struct synaptics_data *priv = psmouse->private; |
| 210 | unsigned char res[3]; | 210 | unsigned char resp[3]; |
| 211 | unsigned char max[3]; | ||
| 212 | 211 | ||
| 213 | if (SYN_ID_MAJOR(priv->identity) < 4) | 212 | if (SYN_ID_MAJOR(priv->identity) < 4) |
| 214 | return 0; | 213 | return 0; |
| 215 | 214 | ||
| 216 | if (synaptics_send_cmd(psmouse, SYN_QUE_RESOLUTION, res) == 0) { | 215 | if (synaptics_send_cmd(psmouse, SYN_QUE_RESOLUTION, resp) == 0) { |
| 217 | if (res[0] != 0 && (res[1] & 0x80) && res[2] != 0) { | 216 | if (resp[0] != 0 && (resp[1] & 0x80) && resp[2] != 0) { |
| 218 | priv->x_res = res[0]; /* x resolution in units/mm */ | 217 | priv->x_res = resp[0]; /* x resolution in units/mm */ |
| 219 | priv->y_res = res[2]; /* y resolution in units/mm */ | 218 | priv->y_res = resp[2]; /* y resolution in units/mm */ |
| 220 | } | 219 | } |
| 221 | } | 220 | } |
| 222 | 221 | ||
| 223 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 5 && | 222 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 5 && |
| 224 | SYN_CAP_MAX_DIMENSIONS(priv->ext_cap_0c)) { | 223 | SYN_CAP_MAX_DIMENSIONS(priv->ext_cap_0c)) { |
| 225 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_DIMENSIONS, max)) { | 224 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MAX_COORDS, resp)) { |
| 226 | printk(KERN_ERR "Synaptics claims to have dimensions query," | 225 | printk(KERN_ERR "Synaptics claims to have max coordinates" |
| 227 | " but I'm not able to read it.\n"); | 226 | " query, but I'm not able to read it.\n"); |
| 227 | } else { | ||
| 228 | priv->x_max = (resp[0] << 5) | ((resp[1] & 0x0f) << 1); | ||
| 229 | priv->y_max = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3); | ||
| 230 | } | ||
| 231 | } | ||
| 232 | |||
| 233 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 7 && | ||
| 234 | SYN_CAP_MIN_DIMENSIONS(priv->ext_cap_0c)) { | ||
| 235 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MIN_COORDS, resp)) { | ||
| 236 | printk(KERN_ERR "Synaptics claims to have min coordinates" | ||
| 237 | " query, but I'm not able to read it.\n"); | ||
| 228 | } else { | 238 | } else { |
| 229 | priv->x_max = (max[0] << 5) | ((max[1] & 0x0f) << 1); | 239 | priv->x_min = (resp[0] << 5) | ((resp[1] & 0x0f) << 1); |
| 230 | priv->y_max = (max[2] << 5) | ((max[1] & 0xf0) >> 3); | 240 | priv->y_min = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3); |
| 231 | } | 241 | } |
| 232 | } | 242 | } |
| 233 | 243 | ||
| @@ -406,26 +416,10 @@ static int synaptics_parse_hw_state(const unsigned char buf[], | |||
| 406 | memset(hw, 0, sizeof(struct synaptics_hw_state)); | 416 | memset(hw, 0, sizeof(struct synaptics_hw_state)); |
| 407 | 417 | ||
| 408 | if (SYN_MODEL_NEWABS(priv->model_id)) { | 418 | if (SYN_MODEL_NEWABS(priv->model_id)) { |
| 409 | hw->x = (((buf[3] & 0x10) << 8) | | ||
| 410 | ((buf[1] & 0x0f) << 8) | | ||
| 411 | buf[4]); | ||
| 412 | hw->y = (((buf[3] & 0x20) << 7) | | ||
| 413 | ((buf[1] & 0xf0) << 4) | | ||
| 414 | buf[5]); | ||
| 415 | |||
| 416 | hw->z = buf[2]; | ||
| 417 | hw->w = (((buf[0] & 0x30) >> 2) | | 419 | hw->w = (((buf[0] & 0x30) >> 2) | |
| 418 | ((buf[0] & 0x04) >> 1) | | 420 | ((buf[0] & 0x04) >> 1) | |
| 419 | ((buf[3] & 0x04) >> 2)); | 421 | ((buf[3] & 0x04) >> 2)); |
| 420 | 422 | ||
| 421 | if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) && hw->w == 2) { | ||
| 422 | /* Gesture packet: (x, y, z) at half resolution */ | ||
| 423 | priv->mt.x = (((buf[4] & 0x0f) << 8) | buf[1]) << 1; | ||
| 424 | priv->mt.y = (((buf[4] & 0xf0) << 4) | buf[2]) << 1; | ||
| 425 | priv->mt.z = ((buf[3] & 0x30) | (buf[5] & 0x0f)) << 1; | ||
| 426 | return 1; | ||
| 427 | } | ||
| 428 | |||
| 429 | hw->left = (buf[0] & 0x01) ? 1 : 0; | 423 | hw->left = (buf[0] & 0x01) ? 1 : 0; |
| 430 | hw->right = (buf[0] & 0x02) ? 1 : 0; | 424 | hw->right = (buf[0] & 0x02) ? 1 : 0; |
| 431 | 425 | ||
| @@ -448,6 +442,22 @@ static int synaptics_parse_hw_state(const unsigned char buf[], | |||
| 448 | hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0; | 442 | hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0; |
| 449 | } | 443 | } |
| 450 | 444 | ||
| 445 | if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) && hw->w == 2) { | ||
| 446 | /* Gesture packet: (x, y, z) at half resolution */ | ||
| 447 | priv->mt.x = (((buf[4] & 0x0f) << 8) | buf[1]) << 1; | ||
| 448 | priv->mt.y = (((buf[4] & 0xf0) << 4) | buf[2]) << 1; | ||
| 449 | priv->mt.z = ((buf[3] & 0x30) | (buf[5] & 0x0f)) << 1; | ||
| 450 | return 1; | ||
| 451 | } | ||
| 452 | |||
| 453 | hw->x = (((buf[3] & 0x10) << 8) | | ||
| 454 | ((buf[1] & 0x0f) << 8) | | ||
| 455 | buf[4]); | ||
| 456 | hw->y = (((buf[3] & 0x20) << 7) | | ||
| 457 | ((buf[1] & 0xf0) << 4) | | ||
| 458 | buf[5]); | ||
| 459 | hw->z = buf[2]; | ||
| 460 | |||
| 451 | if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) && | 461 | if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) && |
| 452 | ((buf[0] ^ buf[3]) & 0x02)) { | 462 | ((buf[0] ^ buf[3]) & 0x02)) { |
| 453 | switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) { | 463 | switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) { |
| @@ -485,7 +495,8 @@ static int synaptics_parse_hw_state(const unsigned char buf[], | |||
| 485 | return 0; | 495 | return 0; |
| 486 | } | 496 | } |
| 487 | 497 | ||
| 488 | static void set_slot(struct input_dev *dev, int slot, bool active, int x, int y) | 498 | static void synaptics_report_semi_mt_slot(struct input_dev *dev, int slot, |
| 499 | bool active, int x, int y) | ||
| 489 | { | 500 | { |
| 490 | input_mt_slot(dev, slot); | 501 | input_mt_slot(dev, slot); |
| 491 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, active); | 502 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, active); |
| @@ -502,14 +513,16 @@ static void synaptics_report_semi_mt_data(struct input_dev *dev, | |||
| 502 | int num_fingers) | 513 | int num_fingers) |
| 503 | { | 514 | { |
| 504 | if (num_fingers >= 2) { | 515 | if (num_fingers >= 2) { |
| 505 | set_slot(dev, 0, true, min(a->x, b->x), min(a->y, b->y)); | 516 | synaptics_report_semi_mt_slot(dev, 0, true, min(a->x, b->x), |
| 506 | set_slot(dev, 1, true, max(a->x, b->x), max(a->y, b->y)); | 517 | min(a->y, b->y)); |
| 518 | synaptics_report_semi_mt_slot(dev, 1, true, max(a->x, b->x), | ||
| 519 | max(a->y, b->y)); | ||
| 507 | } else if (num_fingers == 1) { | 520 | } else if (num_fingers == 1) { |
| 508 | set_slot(dev, 0, true, a->x, a->y); | 521 | synaptics_report_semi_mt_slot(dev, 0, true, a->x, a->y); |
| 509 | set_slot(dev, 1, false, 0, 0); | 522 | synaptics_report_semi_mt_slot(dev, 1, false, 0, 0); |
| 510 | } else { | 523 | } else { |
| 511 | set_slot(dev, 0, false, 0, 0); | 524 | synaptics_report_semi_mt_slot(dev, 0, false, 0, 0); |
| 512 | set_slot(dev, 1, false, 0, 0); | 525 | synaptics_report_semi_mt_slot(dev, 1, false, 0, 0); |
| 513 | } | 526 | } |
| 514 | } | 527 | } |
| 515 | 528 | ||
| @@ -684,23 +697,36 @@ static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse) | |||
| 684 | static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | 697 | static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) |
| 685 | { | 698 | { |
| 686 | int i; | 699 | int i; |
| 700 | int fuzz = SYN_CAP_REDUCED_FILTERING(priv->ext_cap_0c) ? | ||
| 701 | SYN_REDUCED_FILTER_FUZZ : 0; | ||
| 687 | 702 | ||
| 688 | __set_bit(INPUT_PROP_POINTER, dev->propbit); | 703 | __set_bit(INPUT_PROP_POINTER, dev->propbit); |
| 689 | 704 | ||
| 690 | __set_bit(EV_ABS, dev->evbit); | 705 | __set_bit(EV_ABS, dev->evbit); |
| 691 | input_set_abs_params(dev, ABS_X, | 706 | input_set_abs_params(dev, ABS_X, |
| 692 | XMIN_NOMINAL, priv->x_max ?: XMAX_NOMINAL, 0, 0); | 707 | priv->x_min ?: XMIN_NOMINAL, |
| 708 | priv->x_max ?: XMAX_NOMINAL, | ||
| 709 | fuzz, 0); | ||
| 693 | input_set_abs_params(dev, ABS_Y, | 710 | input_set_abs_params(dev, ABS_Y, |
| 694 | YMIN_NOMINAL, priv->y_max ?: YMAX_NOMINAL, 0, 0); | 711 | priv->y_min ?: YMIN_NOMINAL, |
| 712 | priv->y_max ?: YMAX_NOMINAL, | ||
| 713 | fuzz, 0); | ||
| 695 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); | 714 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); |
| 696 | 715 | ||
| 697 | if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) { | 716 | if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) { |
| 698 | __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); | 717 | __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); |
| 699 | input_mt_init_slots(dev, 2); | 718 | input_mt_init_slots(dev, 2); |
| 700 | input_set_abs_params(dev, ABS_MT_POSITION_X, XMIN_NOMINAL, | 719 | input_set_abs_params(dev, ABS_MT_POSITION_X, |
| 701 | priv->x_max ?: XMAX_NOMINAL, 0, 0); | 720 | priv->x_min ?: XMIN_NOMINAL, |
| 702 | input_set_abs_params(dev, ABS_MT_POSITION_Y, YMIN_NOMINAL, | 721 | priv->x_max ?: XMAX_NOMINAL, |
| 703 | priv->y_max ?: YMAX_NOMINAL, 0, 0); | 722 | fuzz, 0); |
| 723 | input_set_abs_params(dev, ABS_MT_POSITION_Y, | ||
| 724 | priv->y_min ?: YMIN_NOMINAL, | ||
| 725 | priv->y_max ?: YMAX_NOMINAL, | ||
| 726 | fuzz, 0); | ||
| 727 | |||
| 728 | input_abs_set_res(dev, ABS_MT_POSITION_X, priv->x_res); | ||
| 729 | input_abs_set_res(dev, ABS_MT_POSITION_Y, priv->y_res); | ||
| 704 | } | 730 | } |
| 705 | 731 | ||
| 706 | if (SYN_CAP_PALMDETECT(priv->capabilities)) | 732 | if (SYN_CAP_PALMDETECT(priv->capabilities)) |
| @@ -971,4 +997,3 @@ bool synaptics_supported(void) | |||
| 971 | } | 997 | } |
| 972 | 998 | ||
| 973 | #endif /* CONFIG_MOUSE_PS2_SYNAPTICS */ | 999 | #endif /* CONFIG_MOUSE_PS2_SYNAPTICS */ |
| 974 | |||
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index 7453938bf5ef..ca040aa80fa7 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h | |||
| @@ -19,7 +19,8 @@ | |||
| 19 | #define SYN_QUE_RESOLUTION 0x08 | 19 | #define SYN_QUE_RESOLUTION 0x08 |
| 20 | #define SYN_QUE_EXT_CAPAB 0x09 | 20 | #define SYN_QUE_EXT_CAPAB 0x09 |
| 21 | #define SYN_QUE_EXT_CAPAB_0C 0x0c | 21 | #define SYN_QUE_EXT_CAPAB_0C 0x0c |
| 22 | #define SYN_QUE_EXT_DIMENSIONS 0x0d | 22 | #define SYN_QUE_EXT_MAX_COORDS 0x0d |
| 23 | #define SYN_QUE_EXT_MIN_COORDS 0x0f | ||
| 23 | 24 | ||
| 24 | /* synatics modes */ | 25 | /* synatics modes */ |
| 25 | #define SYN_BIT_ABSOLUTE_MODE (1 << 7) | 26 | #define SYN_BIT_ABSOLUTE_MODE (1 << 7) |
| @@ -66,18 +67,21 @@ | |||
| 66 | * 1 0x60 multifinger mode identifies firmware finger counting | 67 | * 1 0x60 multifinger mode identifies firmware finger counting |
| 67 | * (not reporting!) algorithm. | 68 | * (not reporting!) algorithm. |
| 68 | * Not particularly meaningful | 69 | * Not particularly meaningful |
| 69 | * 1 0x80 covered pad W clipped to 14, 15 == pad mostly covered | 70 | * 1 0x80 covered pad W clipped to 14, 15 == pad mostly covered |
| 70 | * 2 0x01 clickpad bit 1 2-button ClickPad | 71 | * 2 0x01 clickpad bit 1 2-button ClickPad |
| 71 | * 2 0x02 deluxe LED controls touchpad support LED commands | 72 | * 2 0x02 deluxe LED controls touchpad support LED commands |
| 72 | * ala multimedia control bar | 73 | * ala multimedia control bar |
| 73 | * 2 0x04 reduced filtering firmware does less filtering on | 74 | * 2 0x04 reduced filtering firmware does less filtering on |
| 74 | * position data, driver should watch | 75 | * position data, driver should watch |
| 75 | * for noise. | 76 | * for noise. |
| 77 | * 2 0x20 report min query 0x0f gives min coord reported | ||
| 76 | */ | 78 | */ |
| 77 | #define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */ | 79 | #define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */ |
| 78 | #define SYN_CAP_CLICKPAD2BTN(ex0c) ((ex0c) & 0x000100) /* 2-button ClickPad */ | 80 | #define SYN_CAP_CLICKPAD2BTN(ex0c) ((ex0c) & 0x000100) /* 2-button ClickPad */ |
| 79 | #define SYN_CAP_MAX_DIMENSIONS(ex0c) ((ex0c) & 0x020000) | 81 | #define SYN_CAP_MAX_DIMENSIONS(ex0c) ((ex0c) & 0x020000) |
| 82 | #define SYN_CAP_MIN_DIMENSIONS(ex0c) ((ex0c) & 0x002000) | ||
| 80 | #define SYN_CAP_ADV_GESTURE(ex0c) ((ex0c) & 0x080000) | 83 | #define SYN_CAP_ADV_GESTURE(ex0c) ((ex0c) & 0x080000) |
| 84 | #define SYN_CAP_REDUCED_FILTERING(ex0c) ((ex0c) & 0x000400) | ||
| 81 | 85 | ||
| 82 | /* synaptics modes query bits */ | 86 | /* synaptics modes query bits */ |
| 83 | #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) | 87 | #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) |
| @@ -104,6 +108,9 @@ | |||
| 104 | #define SYN_NEWABS_RELAXED 2 | 108 | #define SYN_NEWABS_RELAXED 2 |
| 105 | #define SYN_OLDABS 3 | 109 | #define SYN_OLDABS 3 |
| 106 | 110 | ||
| 111 | /* amount to fuzz position data when touchpad reports reduced filtering */ | ||
| 112 | #define SYN_REDUCED_FILTER_FUZZ 8 | ||
| 113 | |||
| 107 | /* | 114 | /* |
| 108 | * A structure to describe the state of the touchpad hardware (buttons and pad) | 115 | * A structure to describe the state of the touchpad hardware (buttons and pad) |
| 109 | */ | 116 | */ |
| @@ -130,7 +137,8 @@ struct synaptics_data { | |||
| 130 | unsigned long int ext_cap_0c; /* Ext Caps from 0x0c query */ | 137 | unsigned long int ext_cap_0c; /* Ext Caps from 0x0c query */ |
| 131 | unsigned long int identity; /* Identification */ | 138 | unsigned long int identity; /* Identification */ |
| 132 | unsigned int x_res, y_res; /* X/Y resolution in units/mm */ | 139 | unsigned int x_res, y_res; /* X/Y resolution in units/mm */ |
| 133 | unsigned int x_max, y_max; /* Max dimensions (from FW) */ | 140 | unsigned int x_max, y_max; /* Max coordinates (from FW) */ |
| 141 | unsigned int x_min, y_min; /* Min coordinates (from FW) */ | ||
| 134 | 142 | ||
| 135 | unsigned char pkt_type; /* packet type - old, new, etc */ | 143 | unsigned char pkt_type; /* packet type - old, new, etc */ |
| 136 | unsigned char mode; /* current mode byte */ | 144 | unsigned char mode; /* current mode byte */ |
diff --git a/drivers/input/serio/at32psif.c b/drivers/input/serio/at32psif.c index 6ee8f0ddad51..95280f9207e1 100644 --- a/drivers/input/serio/at32psif.c +++ b/drivers/input/serio/at32psif.c | |||
| @@ -372,6 +372,6 @@ static void __exit psif_exit(void) | |||
| 372 | module_init(psif_init); | 372 | module_init(psif_init); |
| 373 | module_exit(psif_exit); | 373 | module_exit(psif_exit); |
| 374 | 374 | ||
| 375 | MODULE_AUTHOR("Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com>"); | 375 | MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>"); |
| 376 | MODULE_DESCRIPTION("Atmel AVR32 PSIF PS/2 driver"); | 376 | MODULE_DESCRIPTION("Atmel AVR32 PSIF PS/2 driver"); |
| 377 | MODULE_LICENSE("GPL"); | 377 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c index 42206205e4f5..979c443bf1ef 100644 --- a/drivers/input/serio/hp_sdc.c +++ b/drivers/input/serio/hp_sdc.c | |||
| @@ -795,7 +795,7 @@ int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback) | |||
| 795 | 795 | ||
| 796 | /************************* Keepalive timer task *********************/ | 796 | /************************* Keepalive timer task *********************/ |
| 797 | 797 | ||
| 798 | void hp_sdc_kicker (unsigned long data) | 798 | static void hp_sdc_kicker(unsigned long data) |
| 799 | { | 799 | { |
| 800 | tasklet_schedule(&hp_sdc.task); | 800 | tasklet_schedule(&hp_sdc.task); |
| 801 | /* Re-insert the periodic task. */ | 801 | /* Re-insert the periodic task. */ |
diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 0a619c558bfb..6d89fd1842c3 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c | |||
| @@ -225,7 +225,6 @@ | |||
| 225 | /* toolMode codes | 225 | /* toolMode codes |
| 226 | */ | 226 | */ |
| 227 | #define AIPTEK_TOOL_BUTTON_PEN_MODE BTN_TOOL_PEN | 227 | #define AIPTEK_TOOL_BUTTON_PEN_MODE BTN_TOOL_PEN |
| 228 | #define AIPTEK_TOOL_BUTTON_PEN_MODE BTN_TOOL_PEN | ||
| 229 | #define AIPTEK_TOOL_BUTTON_PENCIL_MODE BTN_TOOL_PENCIL | 228 | #define AIPTEK_TOOL_BUTTON_PENCIL_MODE BTN_TOOL_PENCIL |
| 230 | #define AIPTEK_TOOL_BUTTON_BRUSH_MODE BTN_TOOL_BRUSH | 229 | #define AIPTEK_TOOL_BUTTON_BRUSH_MODE BTN_TOOL_BRUSH |
| 231 | #define AIPTEK_TOOL_BUTTON_AIRBRUSH_MODE BTN_TOOL_AIRBRUSH | 230 | #define AIPTEK_TOOL_BUTTON_AIRBRUSH_MODE BTN_TOOL_AIRBRUSH |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 08ba5ad9c9be..03ebcc8b24b5 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include "wacom_wac.h" | 15 | #include "wacom_wac.h" |
| 16 | #include "wacom.h" | 16 | #include "wacom.h" |
| 17 | #include <linux/input/mt.h> | 17 | #include <linux/input/mt.h> |
| 18 | #include <linux/hid.h> | ||
| 18 | 19 | ||
| 19 | /* resolution for penabled devices */ | 20 | /* resolution for penabled devices */ |
| 20 | #define WACOM_PL_RES 20 | 21 | #define WACOM_PL_RES 20 |
| @@ -264,6 +265,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom) | |||
| 264 | wacom->id[0] = 0; | 265 | wacom->id[0] = 0; |
| 265 | input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */ | 266 | input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */ |
| 266 | input_report_key(input, wacom->tool[0], prox); | 267 | input_report_key(input, wacom->tool[0], prox); |
| 268 | input_event(input, EV_MSC, MSC_SERIAL, 1); | ||
| 267 | input_sync(input); /* sync last event */ | 269 | input_sync(input); /* sync last event */ |
| 268 | } | 270 | } |
| 269 | 271 | ||
| @@ -273,11 +275,10 @@ static int wacom_graphire_irq(struct wacom_wac *wacom) | |||
| 273 | prox = data[7] & 0xf8; | 275 | prox = data[7] & 0xf8; |
| 274 | if (prox || wacom->id[1]) { | 276 | if (prox || wacom->id[1]) { |
| 275 | wacom->id[1] = PAD_DEVICE_ID; | 277 | wacom->id[1] = PAD_DEVICE_ID; |
| 276 | input_report_key(input, BTN_0, (data[7] & 0x40)); | 278 | input_report_key(input, BTN_BACK, (data[7] & 0x40)); |
| 277 | input_report_key(input, BTN_4, (data[7] & 0x80)); | 279 | input_report_key(input, BTN_FORWARD, (data[7] & 0x80)); |
| 278 | rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3); | 280 | rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3); |
| 279 | input_report_rel(input, REL_WHEEL, rw); | 281 | input_report_rel(input, REL_WHEEL, rw); |
| 280 | input_report_key(input, BTN_TOOL_FINGER, 0xf0); | ||
| 281 | if (!prox) | 282 | if (!prox) |
| 282 | wacom->id[1] = 0; | 283 | wacom->id[1] = 0; |
| 283 | input_report_abs(input, ABS_MISC, wacom->id[1]); | 284 | input_report_abs(input, ABS_MISC, wacom->id[1]); |
| @@ -290,18 +291,17 @@ static int wacom_graphire_irq(struct wacom_wac *wacom) | |||
| 290 | prox = (data[7] & 0xf8) || data[8]; | 291 | prox = (data[7] & 0xf8) || data[8]; |
| 291 | if (prox || wacom->id[1]) { | 292 | if (prox || wacom->id[1]) { |
| 292 | wacom->id[1] = PAD_DEVICE_ID; | 293 | wacom->id[1] = PAD_DEVICE_ID; |
| 293 | input_report_key(input, BTN_0, (data[7] & 0x08)); | 294 | input_report_key(input, BTN_BACK, (data[7] & 0x08)); |
| 294 | input_report_key(input, BTN_1, (data[7] & 0x20)); | 295 | input_report_key(input, BTN_LEFT, (data[7] & 0x20)); |
| 295 | input_report_key(input, BTN_4, (data[7] & 0x10)); | 296 | input_report_key(input, BTN_FORWARD, (data[7] & 0x10)); |
| 296 | input_report_key(input, BTN_5, (data[7] & 0x40)); | 297 | input_report_key(input, BTN_RIGHT, (data[7] & 0x40)); |
| 297 | input_report_abs(input, ABS_WHEEL, (data[8] & 0x7f)); | 298 | input_report_abs(input, ABS_WHEEL, (data[8] & 0x7f)); |
| 298 | input_report_key(input, BTN_TOOL_FINGER, 0xf0); | ||
| 299 | if (!prox) | 299 | if (!prox) |
| 300 | wacom->id[1] = 0; | 300 | wacom->id[1] = 0; |
| 301 | input_report_abs(input, ABS_MISC, wacom->id[1]); | 301 | input_report_abs(input, ABS_MISC, wacom->id[1]); |
| 302 | input_event(input, EV_MSC, MSC_SERIAL, 0xf0); | 302 | input_event(input, EV_MSC, MSC_SERIAL, 0xf0); |
| 303 | retval = 1; | ||
| 303 | } | 304 | } |
| 304 | retval = 1; | ||
| 305 | break; | 305 | break; |
| 306 | } | 306 | } |
| 307 | exit: | 307 | exit: |
| @@ -494,10 +494,6 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
| 494 | 494 | ||
| 495 | /* pad packets. Works as a second tool and is always in prox */ | 495 | /* pad packets. Works as a second tool and is always in prox */ |
| 496 | if (data[0] == WACOM_REPORT_INTUOSPAD) { | 496 | if (data[0] == WACOM_REPORT_INTUOSPAD) { |
| 497 | /* initiate the pad as a device */ | ||
| 498 | if (wacom->tool[1] != BTN_TOOL_FINGER) | ||
| 499 | wacom->tool[1] = BTN_TOOL_FINGER; | ||
| 500 | |||
| 501 | if (features->type >= INTUOS4S && features->type <= INTUOS4L) { | 497 | if (features->type >= INTUOS4S && features->type <= INTUOS4L) { |
| 502 | input_report_key(input, BTN_0, (data[2] & 0x01)); | 498 | input_report_key(input, BTN_0, (data[2] & 0x01)); |
| 503 | input_report_key(input, BTN_1, (data[3] & 0x01)); | 499 | input_report_key(input, BTN_1, (data[3] & 0x01)); |
| @@ -1080,18 +1076,14 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
| 1080 | 1076 | ||
| 1081 | switch (wacom_wac->features.type) { | 1077 | switch (wacom_wac->features.type) { |
| 1082 | case WACOM_MO: | 1078 | case WACOM_MO: |
| 1083 | __set_bit(BTN_1, input_dev->keybit); | ||
| 1084 | __set_bit(BTN_5, input_dev->keybit); | ||
| 1085 | |||
| 1086 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); | 1079 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); |
| 1087 | /* fall through */ | 1080 | /* fall through */ |
| 1088 | 1081 | ||
| 1089 | case WACOM_G4: | 1082 | case WACOM_G4: |
| 1090 | input_set_capability(input_dev, EV_MSC, MSC_SERIAL); | 1083 | input_set_capability(input_dev, EV_MSC, MSC_SERIAL); |
| 1091 | 1084 | ||
| 1092 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | 1085 | __set_bit(BTN_BACK, input_dev->keybit); |
| 1093 | __set_bit(BTN_0, input_dev->keybit); | 1086 | __set_bit(BTN_FORWARD, input_dev->keybit); |
| 1094 | __set_bit(BTN_4, input_dev->keybit); | ||
| 1095 | /* fall through */ | 1087 | /* fall through */ |
| 1096 | 1088 | ||
| 1097 | case GRAPHIRE: | 1089 | case GRAPHIRE: |
| @@ -1127,10 +1119,12 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
| 1127 | case CINTIQ: | 1119 | case CINTIQ: |
| 1128 | for (i = 0; i < 8; i++) | 1120 | for (i = 0; i < 8; i++) |
| 1129 | __set_bit(BTN_0 + i, input_dev->keybit); | 1121 | __set_bit(BTN_0 + i, input_dev->keybit); |
| 1130 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | ||
| 1131 | 1122 | ||
| 1132 | input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); | 1123 | if (wacom_wac->features.type != WACOM_21UX2) { |
| 1133 | input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); | 1124 | input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); |
| 1125 | input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); | ||
| 1126 | } | ||
| 1127 | |||
| 1134 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | 1128 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); |
| 1135 | wacom_setup_cintiq(wacom_wac); | 1129 | wacom_setup_cintiq(wacom_wac); |
| 1136 | break; | 1130 | break; |
| @@ -1151,8 +1145,6 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
| 1151 | __set_bit(BTN_2, input_dev->keybit); | 1145 | __set_bit(BTN_2, input_dev->keybit); |
| 1152 | __set_bit(BTN_3, input_dev->keybit); | 1146 | __set_bit(BTN_3, input_dev->keybit); |
| 1153 | 1147 | ||
| 1154 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | ||
| 1155 | |||
| 1156 | input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); | 1148 | input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); |
| 1157 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | 1149 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); |
| 1158 | /* fall through */ | 1150 | /* fall through */ |
| @@ -1170,7 +1162,6 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
| 1170 | case INTUOS4S: | 1162 | case INTUOS4S: |
| 1171 | for (i = 0; i < 7; i++) | 1163 | for (i = 0; i < 7; i++) |
| 1172 | __set_bit(BTN_0 + i, input_dev->keybit); | 1164 | __set_bit(BTN_0 + i, input_dev->keybit); |
| 1173 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | ||
| 1174 | 1165 | ||
| 1175 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | 1166 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); |
| 1176 | wacom_setup_intuos(wacom_wac); | 1167 | wacom_setup_intuos(wacom_wac); |
| @@ -1295,6 +1286,12 @@ static const struct wacom_features wacom_features_0x65 = | |||
| 1295 | static const struct wacom_features wacom_features_0x69 = | 1286 | static const struct wacom_features wacom_features_0x69 = |
| 1296 | { "Wacom Bamboo1", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, | 1287 | { "Wacom Bamboo1", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, |
| 1297 | 63, GRAPHIRE, WACOM_PENPRTN_RES, WACOM_PENPRTN_RES }; | 1288 | 63, GRAPHIRE, WACOM_PENPRTN_RES, WACOM_PENPRTN_RES }; |
| 1289 | static const struct wacom_features wacom_features_0x6A = | ||
| 1290 | { "Wacom Bamboo1 4x6", WACOM_PKGLEN_GRAPHIRE, 14760, 9225, 1023, | ||
| 1291 | 63, GRAPHIRE, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
| 1292 | static const struct wacom_features wacom_features_0x6B = | ||
| 1293 | { "Wacom Bamboo1 5x8", WACOM_PKGLEN_GRAPHIRE, 21648, 13530, 1023, | ||
| 1294 | 63, GRAPHIRE, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
| 1298 | static const struct wacom_features wacom_features_0x20 = | 1295 | static const struct wacom_features wacom_features_0x20 = |
| 1299 | { "Wacom Intuos 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, | 1296 | { "Wacom Intuos 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, |
| 1300 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1297 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
| @@ -1427,6 +1424,9 @@ static const struct wacom_features wacom_features_0x90 = | |||
| 1427 | static const struct wacom_features wacom_features_0x93 = | 1424 | static const struct wacom_features wacom_features_0x93 = |
| 1428 | { "Wacom ISDv4 93", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, | 1425 | { "Wacom ISDv4 93", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, |
| 1429 | 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1426 | 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
| 1427 | static const struct wacom_features wacom_features_0x97 = | ||
| 1428 | { "Wacom ISDv4 97", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 511, | ||
| 1429 | 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
| 1430 | static const struct wacom_features wacom_features_0x9A = | 1430 | static const struct wacom_features wacom_features_0x9A = |
| 1431 | { "Wacom ISDv4 9A", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, | 1431 | { "Wacom ISDv4 9A", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, |
| 1432 | 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1432 | 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
| @@ -1458,7 +1458,7 @@ static const struct wacom_features wacom_features_0xD3 = | |||
| 1458 | { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, | 1458 | { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, |
| 1459 | 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1459 | 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
| 1460 | static const struct wacom_features wacom_features_0xD4 = | 1460 | static const struct wacom_features wacom_features_0xD4 = |
| 1461 | { "Wacom Bamboo Pen", WACOM_PKGLEN_BBFUN, 14720, 9200, 255, | 1461 | { "Wacom Bamboo Pen", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, |
| 1462 | 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1462 | 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
| 1463 | static const struct wacom_features wacom_features_0xD6 = | 1463 | static const struct wacom_features wacom_features_0xD6 = |
| 1464 | { "Wacom BambooPT 2FG 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, | 1464 | { "Wacom BambooPT 2FG 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, |
| @@ -1483,6 +1483,11 @@ static const struct wacom_features wacom_features_0x6004 = | |||
| 1483 | USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \ | 1483 | USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \ |
| 1484 | .driver_info = (kernel_ulong_t)&wacom_features_##prod | 1484 | .driver_info = (kernel_ulong_t)&wacom_features_##prod |
| 1485 | 1485 | ||
| 1486 | #define USB_DEVICE_DETAILED(prod, class, sub, proto) \ | ||
| 1487 | USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_WACOM, prod, class, \ | ||
| 1488 | sub, proto), \ | ||
| 1489 | .driver_info = (kernel_ulong_t)&wacom_features_##prod | ||
| 1490 | |||
| 1486 | #define USB_DEVICE_LENOVO(prod) \ | 1491 | #define USB_DEVICE_LENOVO(prod) \ |
| 1487 | USB_DEVICE(USB_VENDOR_ID_LENOVO, prod), \ | 1492 | USB_DEVICE(USB_VENDOR_ID_LENOVO, prod), \ |
| 1488 | .driver_info = (kernel_ulong_t)&wacom_features_##prod | 1493 | .driver_info = (kernel_ulong_t)&wacom_features_##prod |
| @@ -1506,6 +1511,8 @@ const struct usb_device_id wacom_ids[] = { | |||
| 1506 | { USB_DEVICE_WACOM(0x64) }, | 1511 | { USB_DEVICE_WACOM(0x64) }, |
| 1507 | { USB_DEVICE_WACOM(0x65) }, | 1512 | { USB_DEVICE_WACOM(0x65) }, |
| 1508 | { USB_DEVICE_WACOM(0x69) }, | 1513 | { USB_DEVICE_WACOM(0x69) }, |
| 1514 | { USB_DEVICE_WACOM(0x6A) }, | ||
| 1515 | { USB_DEVICE_WACOM(0x6B) }, | ||
| 1509 | { USB_DEVICE_WACOM(0x20) }, | 1516 | { USB_DEVICE_WACOM(0x20) }, |
| 1510 | { USB_DEVICE_WACOM(0x21) }, | 1517 | { USB_DEVICE_WACOM(0x21) }, |
| 1511 | { USB_DEVICE_WACOM(0x22) }, | 1518 | { USB_DEVICE_WACOM(0x22) }, |
| @@ -1545,7 +1552,13 @@ const struct usb_device_id wacom_ids[] = { | |||
| 1545 | { USB_DEVICE_WACOM(0xC5) }, | 1552 | { USB_DEVICE_WACOM(0xC5) }, |
| 1546 | { USB_DEVICE_WACOM(0xC6) }, | 1553 | { USB_DEVICE_WACOM(0xC6) }, |
| 1547 | { USB_DEVICE_WACOM(0xC7) }, | 1554 | { USB_DEVICE_WACOM(0xC7) }, |
| 1548 | { USB_DEVICE_WACOM(0xCE) }, | 1555 | /* |
| 1556 | * DTU-2231 has two interfaces on the same configuration, | ||
| 1557 | * only one is used. | ||
| 1558 | */ | ||
| 1559 | { USB_DEVICE_DETAILED(0xCE, USB_CLASS_HID, | ||
| 1560 | USB_INTERFACE_SUBCLASS_BOOT, | ||
| 1561 | USB_INTERFACE_PROTOCOL_MOUSE) }, | ||
| 1549 | { USB_DEVICE_WACOM(0xD0) }, | 1562 | { USB_DEVICE_WACOM(0xD0) }, |
| 1550 | { USB_DEVICE_WACOM(0xD1) }, | 1563 | { USB_DEVICE_WACOM(0xD1) }, |
| 1551 | { USB_DEVICE_WACOM(0xD2) }, | 1564 | { USB_DEVICE_WACOM(0xD2) }, |
| @@ -1560,6 +1573,7 @@ const struct usb_device_id wacom_ids[] = { | |||
| 1560 | { USB_DEVICE_WACOM(0xCC) }, | 1573 | { USB_DEVICE_WACOM(0xCC) }, |
| 1561 | { USB_DEVICE_WACOM(0x90) }, | 1574 | { USB_DEVICE_WACOM(0x90) }, |
| 1562 | { USB_DEVICE_WACOM(0x93) }, | 1575 | { USB_DEVICE_WACOM(0x93) }, |
| 1576 | { USB_DEVICE_WACOM(0x97) }, | ||
| 1563 | { USB_DEVICE_WACOM(0x9A) }, | 1577 | { USB_DEVICE_WACOM(0x9A) }, |
| 1564 | { USB_DEVICE_WACOM(0x9F) }, | 1578 | { USB_DEVICE_WACOM(0x9F) }, |
| 1565 | { USB_DEVICE_WACOM(0xE2) }, | 1579 | { USB_DEVICE_WACOM(0xE2) }, |
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 5196861b86ef..d507b9b67806 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
| @@ -967,17 +967,12 @@ static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads784 | |||
| 967 | ts->get_pendown_state = pdata->get_pendown_state; | 967 | ts->get_pendown_state = pdata->get_pendown_state; |
| 968 | } else if (gpio_is_valid(pdata->gpio_pendown)) { | 968 | } else if (gpio_is_valid(pdata->gpio_pendown)) { |
| 969 | 969 | ||
| 970 | err = gpio_request(pdata->gpio_pendown, "ads7846_pendown"); | 970 | err = gpio_request_one(pdata->gpio_pendown, GPIOF_IN, |
| 971 | "ads7846_pendown"); | ||
| 971 | if (err) { | 972 | if (err) { |
| 972 | dev_err(&spi->dev, "failed to request pendown GPIO%d\n", | 973 | dev_err(&spi->dev, |
| 973 | pdata->gpio_pendown); | 974 | "failed to request/setup pendown GPIO%d: %d\n", |
| 974 | return err; | 975 | pdata->gpio_pendown, err); |
| 975 | } | ||
| 976 | err = gpio_direction_input(pdata->gpio_pendown); | ||
| 977 | if (err) { | ||
| 978 | dev_err(&spi->dev, "failed to setup pendown GPIO%d\n", | ||
| 979 | pdata->gpio_pendown); | ||
| 980 | gpio_free(pdata->gpio_pendown); | ||
| 981 | return err; | 976 | return err; |
| 982 | } | 977 | } |
| 983 | 978 | ||
diff --git a/drivers/input/touchscreen/atmel-wm97xx.c b/drivers/input/touchscreen/atmel-wm97xx.c index fa8e56bd9094..8034cbb20f74 100644 --- a/drivers/input/touchscreen/atmel-wm97xx.c +++ b/drivers/input/touchscreen/atmel-wm97xx.c | |||
| @@ -164,7 +164,7 @@ static irqreturn_t atmel_wm97xx_channel_b_interrupt(int irq, void *dev_id) | |||
| 164 | 164 | ||
| 165 | data = ac97c_readl(atmel_wm97xx, CBRHR); | 165 | data = ac97c_readl(atmel_wm97xx, CBRHR); |
| 166 | value = data & 0x0fff; | 166 | value = data & 0x0fff; |
| 167 | source = data & WM97XX_ADCSRC_MASK; | 167 | source = data & WM97XX_ADCSEL_MASK; |
| 168 | pen_down = (data & WM97XX_PEN_DOWN) >> 8; | 168 | pen_down = (data & WM97XX_PEN_DOWN) >> 8; |
| 169 | 169 | ||
| 170 | if (source == WM97XX_ADCSEL_X) | 170 | if (source == WM97XX_ADCSEL_X) |
| @@ -442,6 +442,6 @@ static void __exit atmel_wm97xx_exit(void) | |||
| 442 | } | 442 | } |
| 443 | module_exit(atmel_wm97xx_exit); | 443 | module_exit(atmel_wm97xx_exit); |
| 444 | 444 | ||
| 445 | MODULE_AUTHOR("Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com>"); | 445 | MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>"); |
| 446 | MODULE_DESCRIPTION("wm97xx continuous touch driver for Atmel AT91 and AVR32"); | 446 | MODULE_DESCRIPTION("wm97xx continuous touch driver for Atmel AT91 and AVR32"); |
| 447 | MODULE_LICENSE("GPL"); | 447 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 1e61387c73ca..ae00604a6a81 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c | |||
| @@ -48,41 +48,47 @@ | |||
| 48 | #define MXT_OBJECT_SIZE 6 | 48 | #define MXT_OBJECT_SIZE 6 |
| 49 | 49 | ||
| 50 | /* Object types */ | 50 | /* Object types */ |
| 51 | #define MXT_DEBUG_DIAGNOSTIC 37 | 51 | #define MXT_DEBUG_DIAGNOSTIC_T37 37 |
| 52 | #define MXT_GEN_MESSAGE 5 | 52 | #define MXT_GEN_MESSAGE_T5 5 |
| 53 | #define MXT_GEN_COMMAND 6 | 53 | #define MXT_GEN_COMMAND_T6 6 |
| 54 | #define MXT_GEN_POWER 7 | 54 | #define MXT_GEN_POWER_T7 7 |
| 55 | #define MXT_GEN_ACQUIRE 8 | 55 | #define MXT_GEN_ACQUIRE_T8 8 |
| 56 | #define MXT_TOUCH_MULTI 9 | 56 | #define MXT_GEN_DATASOURCE_T53 53 |
| 57 | #define MXT_TOUCH_KEYARRAY 15 | 57 | #define MXT_TOUCH_MULTI_T9 9 |
| 58 | #define MXT_TOUCH_PROXIMITY 23 | 58 | #define MXT_TOUCH_KEYARRAY_T15 15 |
| 59 | #define MXT_PROCI_GRIPFACE 20 | 59 | #define MXT_TOUCH_PROXIMITY_T23 23 |
| 60 | #define MXT_PROCG_NOISE 22 | 60 | #define MXT_TOUCH_PROXKEY_T52 52 |
| 61 | #define MXT_PROCI_ONETOUCH 24 | 61 | #define MXT_PROCI_GRIPFACE_T20 20 |
| 62 | #define MXT_PROCI_TWOTOUCH 27 | 62 | #define MXT_PROCG_NOISE_T22 22 |
| 63 | #define MXT_PROCI_GRIP 40 | 63 | #define MXT_PROCI_ONETOUCH_T24 24 |
| 64 | #define MXT_PROCI_PALM 41 | 64 | #define MXT_PROCI_TWOTOUCH_T27 27 |
| 65 | #define MXT_SPT_COMMSCONFIG 18 | 65 | #define MXT_PROCI_GRIP_T40 40 |
| 66 | #define MXT_SPT_GPIOPWM 19 | 66 | #define MXT_PROCI_PALM_T41 41 |
| 67 | #define MXT_SPT_SELFTEST 25 | 67 | #define MXT_PROCI_TOUCHSUPPRESSION_T42 42 |
| 68 | #define MXT_SPT_CTECONFIG 28 | 68 | #define MXT_PROCI_STYLUS_T47 47 |
| 69 | #define MXT_SPT_USERDATA 38 | 69 | #define MXT_PROCG_NOISESUPPRESSION_T48 48 |
| 70 | #define MXT_SPT_DIGITIZER 43 | 70 | #define MXT_SPT_COMMSCONFIG_T18 18 |
| 71 | #define MXT_SPT_MESSAGECOUNT 44 | 71 | #define MXT_SPT_GPIOPWM_T19 19 |
| 72 | 72 | #define MXT_SPT_SELFTEST_T25 25 | |
| 73 | /* MXT_GEN_COMMAND field */ | 73 | #define MXT_SPT_CTECONFIG_T28 28 |
| 74 | #define MXT_SPT_USERDATA_T38 38 | ||
| 75 | #define MXT_SPT_DIGITIZER_T43 43 | ||
| 76 | #define MXT_SPT_MESSAGECOUNT_T44 44 | ||
| 77 | #define MXT_SPT_CTECONFIG_T46 46 | ||
| 78 | |||
| 79 | /* MXT_GEN_COMMAND_T6 field */ | ||
| 74 | #define MXT_COMMAND_RESET 0 | 80 | #define MXT_COMMAND_RESET 0 |
| 75 | #define MXT_COMMAND_BACKUPNV 1 | 81 | #define MXT_COMMAND_BACKUPNV 1 |
| 76 | #define MXT_COMMAND_CALIBRATE 2 | 82 | #define MXT_COMMAND_CALIBRATE 2 |
| 77 | #define MXT_COMMAND_REPORTALL 3 | 83 | #define MXT_COMMAND_REPORTALL 3 |
| 78 | #define MXT_COMMAND_DIAGNOSTIC 5 | 84 | #define MXT_COMMAND_DIAGNOSTIC 5 |
| 79 | 85 | ||
| 80 | /* MXT_GEN_POWER field */ | 86 | /* MXT_GEN_POWER_T7 field */ |
| 81 | #define MXT_POWER_IDLEACQINT 0 | 87 | #define MXT_POWER_IDLEACQINT 0 |
| 82 | #define MXT_POWER_ACTVACQINT 1 | 88 | #define MXT_POWER_ACTVACQINT 1 |
| 83 | #define MXT_POWER_ACTV2IDLETO 2 | 89 | #define MXT_POWER_ACTV2IDLETO 2 |
| 84 | 90 | ||
| 85 | /* MXT_GEN_ACQUIRE field */ | 91 | /* MXT_GEN_ACQUIRE_T8 field */ |
| 86 | #define MXT_ACQUIRE_CHRGTIME 0 | 92 | #define MXT_ACQUIRE_CHRGTIME 0 |
| 87 | #define MXT_ACQUIRE_TCHDRIFT 2 | 93 | #define MXT_ACQUIRE_TCHDRIFT 2 |
| 88 | #define MXT_ACQUIRE_DRIFTST 3 | 94 | #define MXT_ACQUIRE_DRIFTST 3 |
| @@ -91,7 +97,7 @@ | |||
| 91 | #define MXT_ACQUIRE_ATCHCALST 6 | 97 | #define MXT_ACQUIRE_ATCHCALST 6 |
| 92 | #define MXT_ACQUIRE_ATCHCALSTHR 7 | 98 | #define MXT_ACQUIRE_ATCHCALSTHR 7 |
| 93 | 99 | ||
| 94 | /* MXT_TOUCH_MULTI field */ | 100 | /* MXT_TOUCH_MULTI_T9 field */ |
| 95 | #define MXT_TOUCH_CTRL 0 | 101 | #define MXT_TOUCH_CTRL 0 |
| 96 | #define MXT_TOUCH_XORIGIN 1 | 102 | #define MXT_TOUCH_XORIGIN 1 |
| 97 | #define MXT_TOUCH_YORIGIN 2 | 103 | #define MXT_TOUCH_YORIGIN 2 |
| @@ -121,7 +127,7 @@ | |||
| 121 | #define MXT_TOUCH_YEDGEDIST 29 | 127 | #define MXT_TOUCH_YEDGEDIST 29 |
| 122 | #define MXT_TOUCH_JUMPLIMIT 30 | 128 | #define MXT_TOUCH_JUMPLIMIT 30 |
| 123 | 129 | ||
| 124 | /* MXT_PROCI_GRIPFACE field */ | 130 | /* MXT_PROCI_GRIPFACE_T20 field */ |
| 125 | #define MXT_GRIPFACE_CTRL 0 | 131 | #define MXT_GRIPFACE_CTRL 0 |
| 126 | #define MXT_GRIPFACE_XLOGRIP 1 | 132 | #define MXT_GRIPFACE_XLOGRIP 1 |
| 127 | #define MXT_GRIPFACE_XHIGRIP 2 | 133 | #define MXT_GRIPFACE_XHIGRIP 2 |
| @@ -151,11 +157,11 @@ | |||
| 151 | #define MXT_NOISE_FREQ4 15 | 157 | #define MXT_NOISE_FREQ4 15 |
| 152 | #define MXT_NOISE_IDLEGCAFVALID 16 | 158 | #define MXT_NOISE_IDLEGCAFVALID 16 |
| 153 | 159 | ||
| 154 | /* MXT_SPT_COMMSCONFIG */ | 160 | /* MXT_SPT_COMMSCONFIG_T18 */ |
| 155 | #define MXT_COMMS_CTRL 0 | 161 | #define MXT_COMMS_CTRL 0 |
| 156 | #define MXT_COMMS_CMD 1 | 162 | #define MXT_COMMS_CMD 1 |
| 157 | 163 | ||
| 158 | /* MXT_SPT_CTECONFIG field */ | 164 | /* MXT_SPT_CTECONFIG_T28 field */ |
| 159 | #define MXT_CTE_CTRL 0 | 165 | #define MXT_CTE_CTRL 0 |
| 160 | #define MXT_CTE_CMD 1 | 166 | #define MXT_CTE_CMD 1 |
| 161 | #define MXT_CTE_MODE 2 | 167 | #define MXT_CTE_MODE 2 |
| @@ -166,7 +172,7 @@ | |||
| 166 | #define MXT_VOLTAGE_DEFAULT 2700000 | 172 | #define MXT_VOLTAGE_DEFAULT 2700000 |
| 167 | #define MXT_VOLTAGE_STEP 10000 | 173 | #define MXT_VOLTAGE_STEP 10000 |
| 168 | 174 | ||
| 169 | /* Define for MXT_GEN_COMMAND */ | 175 | /* Define for MXT_GEN_COMMAND_T6 */ |
| 170 | #define MXT_BOOT_VALUE 0xa5 | 176 | #define MXT_BOOT_VALUE 0xa5 |
| 171 | #define MXT_BACKUP_VALUE 0x55 | 177 | #define MXT_BACKUP_VALUE 0x55 |
| 172 | #define MXT_BACKUP_TIME 25 /* msec */ | 178 | #define MXT_BACKUP_TIME 25 /* msec */ |
| @@ -256,24 +262,31 @@ struct mxt_data { | |||
| 256 | static bool mxt_object_readable(unsigned int type) | 262 | static bool mxt_object_readable(unsigned int type) |
| 257 | { | 263 | { |
| 258 | switch (type) { | 264 | switch (type) { |
| 259 | case MXT_GEN_MESSAGE: | 265 | case MXT_GEN_MESSAGE_T5: |
| 260 | case MXT_GEN_COMMAND: | 266 | case MXT_GEN_COMMAND_T6: |
| 261 | case MXT_GEN_POWER: | 267 | case MXT_GEN_POWER_T7: |
| 262 | case MXT_GEN_ACQUIRE: | 268 | case MXT_GEN_ACQUIRE_T8: |
| 263 | case MXT_TOUCH_MULTI: | 269 | case MXT_GEN_DATASOURCE_T53: |
| 264 | case MXT_TOUCH_KEYARRAY: | 270 | case MXT_TOUCH_MULTI_T9: |
| 265 | case MXT_TOUCH_PROXIMITY: | 271 | case MXT_TOUCH_KEYARRAY_T15: |
| 266 | case MXT_PROCI_GRIPFACE: | 272 | case MXT_TOUCH_PROXIMITY_T23: |
| 267 | case MXT_PROCG_NOISE: | 273 | case MXT_TOUCH_PROXKEY_T52: |
| 268 | case MXT_PROCI_ONETOUCH: | 274 | case MXT_PROCI_GRIPFACE_T20: |
| 269 | case MXT_PROCI_TWOTOUCH: | 275 | case MXT_PROCG_NOISE_T22: |
| 270 | case MXT_PROCI_GRIP: | 276 | case MXT_PROCI_ONETOUCH_T24: |
| 271 | case MXT_PROCI_PALM: | 277 | case MXT_PROCI_TWOTOUCH_T27: |
| 272 | case MXT_SPT_COMMSCONFIG: | 278 | case MXT_PROCI_GRIP_T40: |
| 273 | case MXT_SPT_GPIOPWM: | 279 | case MXT_PROCI_PALM_T41: |
| 274 | case MXT_SPT_SELFTEST: | 280 | case MXT_PROCI_TOUCHSUPPRESSION_T42: |
| 275 | case MXT_SPT_CTECONFIG: | 281 | case MXT_PROCI_STYLUS_T47: |
| 276 | case MXT_SPT_USERDATA: | 282 | case MXT_PROCG_NOISESUPPRESSION_T48: |
| 283 | case MXT_SPT_COMMSCONFIG_T18: | ||
| 284 | case MXT_SPT_GPIOPWM_T19: | ||
| 285 | case MXT_SPT_SELFTEST_T25: | ||
| 286 | case MXT_SPT_CTECONFIG_T28: | ||
| 287 | case MXT_SPT_USERDATA_T38: | ||
| 288 | case MXT_SPT_DIGITIZER_T43: | ||
| 289 | case MXT_SPT_CTECONFIG_T46: | ||
| 277 | return true; | 290 | return true; |
| 278 | default: | 291 | default: |
| 279 | return false; | 292 | return false; |
| @@ -283,21 +296,28 @@ static bool mxt_object_readable(unsigned int type) | |||
| 283 | static bool mxt_object_writable(unsigned int type) | 296 | static bool mxt_object_writable(unsigned int type) |
| 284 | { | 297 | { |
| 285 | switch (type) { | 298 | switch (type) { |
| 286 | case MXT_GEN_COMMAND: | 299 | case MXT_GEN_COMMAND_T6: |
| 287 | case MXT_GEN_POWER: | 300 | case MXT_GEN_POWER_T7: |
| 288 | case MXT_GEN_ACQUIRE: | 301 | case MXT_GEN_ACQUIRE_T8: |
| 289 | case MXT_TOUCH_MULTI: | 302 | case MXT_TOUCH_MULTI_T9: |
| 290 | case MXT_TOUCH_KEYARRAY: | 303 | case MXT_TOUCH_KEYARRAY_T15: |
| 291 | case MXT_TOUCH_PROXIMITY: | 304 | case MXT_TOUCH_PROXIMITY_T23: |
| 292 | case MXT_PROCI_GRIPFACE: | 305 | case MXT_TOUCH_PROXKEY_T52: |
| 293 | case MXT_PROCG_NOISE: | 306 | case MXT_PROCI_GRIPFACE_T20: |
| 294 | case MXT_PROCI_ONETOUCH: | 307 | case MXT_PROCG_NOISE_T22: |
| 295 | case MXT_PROCI_TWOTOUCH: | 308 | case MXT_PROCI_ONETOUCH_T24: |
| 296 | case MXT_PROCI_GRIP: | 309 | case MXT_PROCI_TWOTOUCH_T27: |
| 297 | case MXT_PROCI_PALM: | 310 | case MXT_PROCI_GRIP_T40: |
| 298 | case MXT_SPT_GPIOPWM: | 311 | case MXT_PROCI_PALM_T41: |
| 299 | case MXT_SPT_SELFTEST: | 312 | case MXT_PROCI_TOUCHSUPPRESSION_T42: |
| 300 | case MXT_SPT_CTECONFIG: | 313 | case MXT_PROCI_STYLUS_T47: |
| 314 | case MXT_PROCG_NOISESUPPRESSION_T48: | ||
| 315 | case MXT_SPT_COMMSCONFIG_T18: | ||
| 316 | case MXT_SPT_GPIOPWM_T19: | ||
| 317 | case MXT_SPT_SELFTEST_T25: | ||
| 318 | case MXT_SPT_CTECONFIG_T28: | ||
| 319 | case MXT_SPT_DIGITIZER_T43: | ||
| 320 | case MXT_SPT_CTECONFIG_T46: | ||
| 301 | return true; | 321 | return true; |
| 302 | default: | 322 | default: |
| 303 | return false; | 323 | return false; |
| @@ -455,7 +475,7 @@ static int mxt_read_message(struct mxt_data *data, | |||
| 455 | struct mxt_object *object; | 475 | struct mxt_object *object; |
| 456 | u16 reg; | 476 | u16 reg; |
| 457 | 477 | ||
| 458 | object = mxt_get_object(data, MXT_GEN_MESSAGE); | 478 | object = mxt_get_object(data, MXT_GEN_MESSAGE_T5); |
| 459 | if (!object) | 479 | if (!object) |
| 460 | return -EINVAL; | 480 | return -EINVAL; |
| 461 | 481 | ||
| @@ -597,8 +617,8 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id) | |||
| 597 | 617 | ||
| 598 | reportid = message.reportid; | 618 | reportid = message.reportid; |
| 599 | 619 | ||
| 600 | /* whether reportid is thing of MXT_TOUCH_MULTI */ | 620 | /* whether reportid is thing of MXT_TOUCH_MULTI_T9 */ |
| 601 | object = mxt_get_object(data, MXT_TOUCH_MULTI); | 621 | object = mxt_get_object(data, MXT_TOUCH_MULTI_T9); |
| 602 | if (!object) | 622 | if (!object) |
| 603 | goto end; | 623 | goto end; |
| 604 | 624 | ||
| @@ -635,7 +655,9 @@ static int mxt_check_reg_init(struct mxt_data *data) | |||
| 635 | if (!mxt_object_writable(object->type)) | 655 | if (!mxt_object_writable(object->type)) |
| 636 | continue; | 656 | continue; |
| 637 | 657 | ||
| 638 | for (j = 0; j < object->size + 1; j++) { | 658 | for (j = 0; |
| 659 | j < (object->size + 1) * (object->instances + 1); | ||
| 660 | j++) { | ||
| 639 | config_offset = index + j; | 661 | config_offset = index + j; |
| 640 | if (config_offset > pdata->config_length) { | 662 | if (config_offset > pdata->config_length) { |
| 641 | dev_err(dev, "Not enough config data!\n"); | 663 | dev_err(dev, "Not enough config data!\n"); |
| @@ -644,7 +666,7 @@ static int mxt_check_reg_init(struct mxt_data *data) | |||
| 644 | mxt_write_object(data, object->type, j, | 666 | mxt_write_object(data, object->type, j, |
| 645 | pdata->config[config_offset]); | 667 | pdata->config[config_offset]); |
| 646 | } | 668 | } |
| 647 | index += object->size + 1; | 669 | index += (object->size + 1) * (object->instances + 1); |
| 648 | } | 670 | } |
| 649 | 671 | ||
| 650 | return 0; | 672 | return 0; |
| @@ -678,31 +700,31 @@ static void mxt_handle_pdata(struct mxt_data *data) | |||
| 678 | u8 voltage; | 700 | u8 voltage; |
| 679 | 701 | ||
| 680 | /* Set touchscreen lines */ | 702 | /* Set touchscreen lines */ |
| 681 | mxt_write_object(data, MXT_TOUCH_MULTI, MXT_TOUCH_XSIZE, | 703 | mxt_write_object(data, MXT_TOUCH_MULTI_T9, MXT_TOUCH_XSIZE, |
| 682 | pdata->x_line); | 704 | pdata->x_line); |
| 683 | mxt_write_object(data, MXT_TOUCH_MULTI, MXT_TOUCH_YSIZE, | 705 | mxt_write_object(data, MXT_TOUCH_MULTI_T9, MXT_TOUCH_YSIZE, |
| 684 | pdata->y_line); | 706 | pdata->y_line); |
| 685 | 707 | ||
| 686 | /* Set touchscreen orient */ | 708 | /* Set touchscreen orient */ |
| 687 | mxt_write_object(data, MXT_TOUCH_MULTI, MXT_TOUCH_ORIENT, | 709 | mxt_write_object(data, MXT_TOUCH_MULTI_T9, MXT_TOUCH_ORIENT, |
| 688 | pdata->orient); | 710 | pdata->orient); |
| 689 | 711 | ||
| 690 | /* Set touchscreen burst length */ | 712 | /* Set touchscreen burst length */ |
| 691 | mxt_write_object(data, MXT_TOUCH_MULTI, | 713 | mxt_write_object(data, MXT_TOUCH_MULTI_T9, |
| 692 | MXT_TOUCH_BLEN, pdata->blen); | 714 | MXT_TOUCH_BLEN, pdata->blen); |
| 693 | 715 | ||
| 694 | /* Set touchscreen threshold */ | 716 | /* Set touchscreen threshold */ |
| 695 | mxt_write_object(data, MXT_TOUCH_MULTI, | 717 | mxt_write_object(data, MXT_TOUCH_MULTI_T9, |
| 696 | MXT_TOUCH_TCHTHR, pdata->threshold); | 718 | MXT_TOUCH_TCHTHR, pdata->threshold); |
| 697 | 719 | ||
| 698 | /* Set touchscreen resolution */ | 720 | /* Set touchscreen resolution */ |
| 699 | mxt_write_object(data, MXT_TOUCH_MULTI, | 721 | mxt_write_object(data, MXT_TOUCH_MULTI_T9, |
| 700 | MXT_TOUCH_XRANGE_LSB, (pdata->x_size - 1) & 0xff); | 722 | MXT_TOUCH_XRANGE_LSB, (pdata->x_size - 1) & 0xff); |
| 701 | mxt_write_object(data, MXT_TOUCH_MULTI, | 723 | mxt_write_object(data, MXT_TOUCH_MULTI_T9, |
| 702 | MXT_TOUCH_XRANGE_MSB, (pdata->x_size - 1) >> 8); | 724 | MXT_TOUCH_XRANGE_MSB, (pdata->x_size - 1) >> 8); |
| 703 | mxt_write_object(data, MXT_TOUCH_MULTI, | 725 | mxt_write_object(data, MXT_TOUCH_MULTI_T9, |
| 704 | MXT_TOUCH_YRANGE_LSB, (pdata->y_size - 1) & 0xff); | 726 | MXT_TOUCH_YRANGE_LSB, (pdata->y_size - 1) & 0xff); |
| 705 | mxt_write_object(data, MXT_TOUCH_MULTI, | 727 | mxt_write_object(data, MXT_TOUCH_MULTI_T9, |
| 706 | MXT_TOUCH_YRANGE_MSB, (pdata->y_size - 1) >> 8); | 728 | MXT_TOUCH_YRANGE_MSB, (pdata->y_size - 1) >> 8); |
| 707 | 729 | ||
| 708 | /* Set touchscreen voltage */ | 730 | /* Set touchscreen voltage */ |
| @@ -715,7 +737,7 @@ static void mxt_handle_pdata(struct mxt_data *data) | |||
| 715 | voltage = (pdata->voltage - MXT_VOLTAGE_DEFAULT) / | 737 | voltage = (pdata->voltage - MXT_VOLTAGE_DEFAULT) / |
| 716 | MXT_VOLTAGE_STEP; | 738 | MXT_VOLTAGE_STEP; |
| 717 | 739 | ||
| 718 | mxt_write_object(data, MXT_SPT_CTECONFIG, | 740 | mxt_write_object(data, MXT_SPT_CTECONFIG_T28, |
| 719 | MXT_CTE_VOLTAGE, voltage); | 741 | MXT_CTE_VOLTAGE, voltage); |
| 720 | } | 742 | } |
| 721 | } | 743 | } |
| @@ -819,13 +841,13 @@ static int mxt_initialize(struct mxt_data *data) | |||
| 819 | mxt_handle_pdata(data); | 841 | mxt_handle_pdata(data); |
| 820 | 842 | ||
| 821 | /* Backup to memory */ | 843 | /* Backup to memory */ |
| 822 | mxt_write_object(data, MXT_GEN_COMMAND, | 844 | mxt_write_object(data, MXT_GEN_COMMAND_T6, |
| 823 | MXT_COMMAND_BACKUPNV, | 845 | MXT_COMMAND_BACKUPNV, |
| 824 | MXT_BACKUP_VALUE); | 846 | MXT_BACKUP_VALUE); |
| 825 | msleep(MXT_BACKUP_TIME); | 847 | msleep(MXT_BACKUP_TIME); |
| 826 | 848 | ||
| 827 | /* Soft reset */ | 849 | /* Soft reset */ |
| 828 | mxt_write_object(data, MXT_GEN_COMMAND, | 850 | mxt_write_object(data, MXT_GEN_COMMAND_T6, |
| 829 | MXT_COMMAND_RESET, 1); | 851 | MXT_COMMAND_RESET, 1); |
| 830 | msleep(MXT_RESET_TIME); | 852 | msleep(MXT_RESET_TIME); |
| 831 | 853 | ||
| @@ -921,7 +943,7 @@ static int mxt_load_fw(struct device *dev, const char *fn) | |||
| 921 | } | 943 | } |
| 922 | 944 | ||
| 923 | /* Change to the bootloader mode */ | 945 | /* Change to the bootloader mode */ |
| 924 | mxt_write_object(data, MXT_GEN_COMMAND, | 946 | mxt_write_object(data, MXT_GEN_COMMAND_T6, |
| 925 | MXT_COMMAND_RESET, MXT_BOOT_VALUE); | 947 | MXT_COMMAND_RESET, MXT_BOOT_VALUE); |
| 926 | msleep(MXT_RESET_TIME); | 948 | msleep(MXT_RESET_TIME); |
| 927 | 949 | ||
| @@ -1027,14 +1049,14 @@ static void mxt_start(struct mxt_data *data) | |||
| 1027 | { | 1049 | { |
| 1028 | /* Touch enable */ | 1050 | /* Touch enable */ |
| 1029 | mxt_write_object(data, | 1051 | mxt_write_object(data, |
| 1030 | MXT_TOUCH_MULTI, MXT_TOUCH_CTRL, 0x83); | 1052 | MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0x83); |
| 1031 | } | 1053 | } |
| 1032 | 1054 | ||
| 1033 | static void mxt_stop(struct mxt_data *data) | 1055 | static void mxt_stop(struct mxt_data *data) |
| 1034 | { | 1056 | { |
| 1035 | /* Touch disable */ | 1057 | /* Touch disable */ |
| 1036 | mxt_write_object(data, | 1058 | mxt_write_object(data, |
| 1037 | MXT_TOUCH_MULTI, MXT_TOUCH_CTRL, 0); | 1059 | MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0); |
| 1038 | } | 1060 | } |
| 1039 | 1061 | ||
| 1040 | static int mxt_input_open(struct input_dev *dev) | 1062 | static int mxt_input_open(struct input_dev *dev) |
| @@ -1182,7 +1204,7 @@ static int mxt_resume(struct device *dev) | |||
| 1182 | struct input_dev *input_dev = data->input_dev; | 1204 | struct input_dev *input_dev = data->input_dev; |
| 1183 | 1205 | ||
| 1184 | /* Soft reset */ | 1206 | /* Soft reset */ |
| 1185 | mxt_write_object(data, MXT_GEN_COMMAND, | 1207 | mxt_write_object(data, MXT_GEN_COMMAND_T6, |
| 1186 | MXT_COMMAND_RESET, 1); | 1208 | MXT_COMMAND_RESET, 1); |
| 1187 | 1209 | ||
| 1188 | msleep(MXT_RESET_TIME); | 1210 | msleep(MXT_RESET_TIME); |
diff --git a/drivers/input/touchscreen/cy8ctmg110_ts.c b/drivers/input/touchscreen/cy8ctmg110_ts.c index a93c5c26ab3f..d8815c5d54ad 100644 --- a/drivers/input/touchscreen/cy8ctmg110_ts.c +++ b/drivers/input/touchscreen/cy8ctmg110_ts.c | |||
| @@ -84,9 +84,9 @@ static int cy8ctmg110_write_regs(struct cy8ctmg110 *tsc, unsigned char reg, | |||
| 84 | memcpy(i2c_data + 1, value, len); | 84 | memcpy(i2c_data + 1, value, len); |
| 85 | 85 | ||
| 86 | ret = i2c_master_send(client, i2c_data, len + 1); | 86 | ret = i2c_master_send(client, i2c_data, len + 1); |
| 87 | if (ret != 1) { | 87 | if (ret != len + 1) { |
| 88 | dev_err(&client->dev, "i2c write data cmd failed\n"); | 88 | dev_err(&client->dev, "i2c write data cmd failed\n"); |
| 89 | return ret ? ret : -EIO; | 89 | return ret < 0 ? ret : -EIO; |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | return 0; | 92 | return 0; |
| @@ -193,6 +193,8 @@ static int __devinit cy8ctmg110_probe(struct i2c_client *client, | |||
| 193 | 193 | ||
| 194 | ts->client = client; | 194 | ts->client = client; |
| 195 | ts->input = input_dev; | 195 | ts->input = input_dev; |
| 196 | ts->reset_pin = pdata->reset_pin; | ||
| 197 | ts->irq_pin = pdata->irq_pin; | ||
| 196 | 198 | ||
| 197 | snprintf(ts->phys, sizeof(ts->phys), | 199 | snprintf(ts->phys, sizeof(ts->phys), |
| 198 | "%s/input0", dev_name(&client->dev)); | 200 | "%s/input0", dev_name(&client->dev)); |
| @@ -328,7 +330,7 @@ static int __devexit cy8ctmg110_remove(struct i2c_client *client) | |||
| 328 | return 0; | 330 | return 0; |
| 329 | } | 331 | } |
| 330 | 332 | ||
| 331 | static struct i2c_device_id cy8ctmg110_idtable[] = { | 333 | static const struct i2c_device_id cy8ctmg110_idtable[] = { |
| 332 | { CY8CTMG110_DRIVER_NAME, 1 }, | 334 | { CY8CTMG110_DRIVER_NAME, 1 }, |
| 333 | { } | 335 | { } |
| 334 | }; | 336 | }; |
diff --git a/drivers/input/touchscreen/intel-mid-touch.c b/drivers/input/touchscreen/intel-mid-touch.c index 66c96bfc5522..327695268e06 100644 --- a/drivers/input/touchscreen/intel-mid-touch.c +++ b/drivers/input/touchscreen/intel-mid-touch.c | |||
| @@ -448,15 +448,11 @@ static int __devinit mrstouch_read_pmic_id(uint *vendor, uint *rev) | |||
| 448 | */ | 448 | */ |
| 449 | static int __devinit mrstouch_chan_parse(struct mrstouch_dev *tsdev) | 449 | static int __devinit mrstouch_chan_parse(struct mrstouch_dev *tsdev) |
| 450 | { | 450 | { |
| 451 | int err, i, found; | 451 | int found = 0; |
| 452 | int err, i; | ||
| 452 | u8 r8; | 453 | u8 r8; |
| 453 | 454 | ||
| 454 | found = -1; | ||
| 455 | |||
| 456 | for (i = 0; i < MRSTOUCH_MAX_CHANNELS; i++) { | 455 | for (i = 0; i < MRSTOUCH_MAX_CHANNELS; i++) { |
| 457 | if (found >= 0) | ||
| 458 | break; | ||
| 459 | |||
| 460 | err = intel_scu_ipc_ioread8(PMICADDR0 + i, &r8); | 456 | err = intel_scu_ipc_ioread8(PMICADDR0 + i, &r8); |
| 461 | if (err) | 457 | if (err) |
| 462 | return err; | 458 | return err; |
| @@ -466,16 +462,15 @@ static int __devinit mrstouch_chan_parse(struct mrstouch_dev *tsdev) | |||
| 466 | break; | 462 | break; |
| 467 | } | 463 | } |
| 468 | } | 464 | } |
| 469 | if (found < 0) | ||
| 470 | return 0; | ||
| 471 | 465 | ||
| 472 | if (tsdev->vendor == PMIC_VENDOR_FS) { | 466 | if (tsdev->vendor == PMIC_VENDOR_FS) { |
| 473 | if (found && found > (MRSTOUCH_MAX_CHANNELS - 18)) | 467 | if (found > MRSTOUCH_MAX_CHANNELS - 18) |
| 474 | return -ENOSPC; | 468 | return -ENOSPC; |
| 475 | } else { | 469 | } else { |
| 476 | if (found && found > (MRSTOUCH_MAX_CHANNELS - 4)) | 470 | if (found > MRSTOUCH_MAX_CHANNELS - 4) |
| 477 | return -ENOSPC; | 471 | return -ENOSPC; |
| 478 | } | 472 | } |
| 473 | |||
| 479 | return found; | 474 | return found; |
| 480 | } | 475 | } |
| 481 | 476 | ||
diff --git a/drivers/input/touchscreen/mainstone-wm97xx.c b/drivers/input/touchscreen/mainstone-wm97xx.c index 3242e7076258..e966c29ff1bb 100644 --- a/drivers/input/touchscreen/mainstone-wm97xx.c +++ b/drivers/input/touchscreen/mainstone-wm97xx.c | |||
| @@ -157,9 +157,9 @@ static int wm97xx_acc_pen_down(struct wm97xx *wm) | |||
| 157 | x, y, p); | 157 | x, y, p); |
| 158 | 158 | ||
| 159 | /* are samples valid */ | 159 | /* are samples valid */ |
| 160 | if ((x & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_X || | 160 | if ((x & WM97XX_ADCSEL_MASK) != WM97XX_ADCSEL_X || |
| 161 | (y & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_Y || | 161 | (y & WM97XX_ADCSEL_MASK) != WM97XX_ADCSEL_Y || |
| 162 | (p & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_PRES) | 162 | (p & WM97XX_ADCSEL_MASK) != WM97XX_ADCSEL_PRES) |
| 163 | goto up; | 163 | goto up; |
| 164 | 164 | ||
| 165 | /* coordinate is good */ | 165 | /* coordinate is good */ |
diff --git a/drivers/input/touchscreen/tnetv107x-ts.c b/drivers/input/touchscreen/tnetv107x-ts.c index 22a3411e93c5..089b0a0f3d8c 100644 --- a/drivers/input/touchscreen/tnetv107x-ts.c +++ b/drivers/input/touchscreen/tnetv107x-ts.c | |||
| @@ -393,5 +393,5 @@ module_exit(tsc_exit); | |||
| 393 | 393 | ||
| 394 | MODULE_AUTHOR("Cyril Chemparathy"); | 394 | MODULE_AUTHOR("Cyril Chemparathy"); |
| 395 | MODULE_DESCRIPTION("TNETV107X Touchscreen Driver"); | 395 | MODULE_DESCRIPTION("TNETV107X Touchscreen Driver"); |
| 396 | MODULE_ALIAS("platform: tnetv107x-ts"); | 396 | MODULE_ALIAS("platform:tnetv107x-ts"); |
| 397 | MODULE_LICENSE("GPL"); | 397 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/input/touchscreen/wm9705.c b/drivers/input/touchscreen/wm9705.c index 98e61175d3f5..adc13a523ab5 100644 --- a/drivers/input/touchscreen/wm9705.c +++ b/drivers/input/touchscreen/wm9705.c | |||
| @@ -215,8 +215,9 @@ static inline int is_pden(struct wm97xx *wm) | |||
| 215 | static int wm9705_poll_sample(struct wm97xx *wm, int adcsel, int *sample) | 215 | static int wm9705_poll_sample(struct wm97xx *wm, int adcsel, int *sample) |
| 216 | { | 216 | { |
| 217 | int timeout = 5 * delay; | 217 | int timeout = 5 * delay; |
| 218 | bool wants_pen = adcsel & WM97XX_PEN_DOWN; | ||
| 218 | 219 | ||
| 219 | if (!wm->pen_probably_down) { | 220 | if (wants_pen && !wm->pen_probably_down) { |
| 220 | u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); | 221 | u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); |
| 221 | if (!(data & WM97XX_PEN_DOWN)) | 222 | if (!(data & WM97XX_PEN_DOWN)) |
| 222 | return RC_PENUP; | 223 | return RC_PENUP; |
| @@ -224,13 +225,10 @@ static int wm9705_poll_sample(struct wm97xx *wm, int adcsel, int *sample) | |||
| 224 | } | 225 | } |
| 225 | 226 | ||
| 226 | /* set up digitiser */ | 227 | /* set up digitiser */ |
| 227 | if (adcsel & 0x8000) | ||
| 228 | adcsel = ((adcsel & 0x7fff) + 3) << 12; | ||
| 229 | |||
| 230 | if (wm->mach_ops && wm->mach_ops->pre_sample) | 228 | if (wm->mach_ops && wm->mach_ops->pre_sample) |
| 231 | wm->mach_ops->pre_sample(adcsel); | 229 | wm->mach_ops->pre_sample(adcsel); |
| 232 | wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, | 230 | wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, (adcsel & WM97XX_ADCSEL_MASK) |
| 233 | adcsel | WM97XX_POLL | WM97XX_DELAY(delay)); | 231 | | WM97XX_POLL | WM97XX_DELAY(delay)); |
| 234 | 232 | ||
| 235 | /* wait 3 AC97 time slots + delay for conversion */ | 233 | /* wait 3 AC97 time slots + delay for conversion */ |
| 236 | poll_delay(delay); | 234 | poll_delay(delay); |
| @@ -256,13 +254,14 @@ static int wm9705_poll_sample(struct wm97xx *wm, int adcsel, int *sample) | |||
| 256 | wm->mach_ops->post_sample(adcsel); | 254 | wm->mach_ops->post_sample(adcsel); |
| 257 | 255 | ||
| 258 | /* check we have correct sample */ | 256 | /* check we have correct sample */ |
| 259 | if ((*sample & WM97XX_ADCSEL_MASK) != adcsel) { | 257 | if ((*sample ^ adcsel) & WM97XX_ADCSEL_MASK) { |
| 260 | dev_dbg(wm->dev, "adc wrong sample, read %x got %x", adcsel, | 258 | dev_dbg(wm->dev, "adc wrong sample, wanted %x got %x", |
| 261 | *sample & WM97XX_ADCSEL_MASK); | 259 | adcsel & WM97XX_ADCSEL_MASK, |
| 260 | *sample & WM97XX_ADCSEL_MASK); | ||
| 262 | return RC_PENUP; | 261 | return RC_PENUP; |
| 263 | } | 262 | } |
| 264 | 263 | ||
| 265 | if (!(*sample & WM97XX_PEN_DOWN)) { | 264 | if (wants_pen && !(*sample & WM97XX_PEN_DOWN)) { |
| 266 | wm->pen_probably_down = 0; | 265 | wm->pen_probably_down = 0; |
| 267 | return RC_PENUP; | 266 | return RC_PENUP; |
| 268 | } | 267 | } |
| @@ -277,14 +276,14 @@ static int wm9705_poll_touch(struct wm97xx *wm, struct wm97xx_data *data) | |||
| 277 | { | 276 | { |
| 278 | int rc; | 277 | int rc; |
| 279 | 278 | ||
| 280 | rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_X, &data->x); | 279 | rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_X | WM97XX_PEN_DOWN, &data->x); |
| 281 | if (rc != RC_VALID) | 280 | if (rc != RC_VALID) |
| 282 | return rc; | 281 | return rc; |
| 283 | rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_Y, &data->y); | 282 | rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_Y | WM97XX_PEN_DOWN, &data->y); |
| 284 | if (rc != RC_VALID) | 283 | if (rc != RC_VALID) |
| 285 | return rc; | 284 | return rc; |
| 286 | if (pil) { | 285 | if (pil) { |
| 287 | rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_PRES, &data->p); | 286 | rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_PRES | WM97XX_PEN_DOWN, &data->p); |
| 288 | if (rc != RC_VALID) | 287 | if (rc != RC_VALID) |
| 289 | return rc; | 288 | return rc; |
| 290 | } else | 289 | } else |
diff --git a/drivers/input/touchscreen/wm9712.c b/drivers/input/touchscreen/wm9712.c index 2bc2fb801009..6e743e3dfda4 100644 --- a/drivers/input/touchscreen/wm9712.c +++ b/drivers/input/touchscreen/wm9712.c | |||
| @@ -255,8 +255,9 @@ static inline int is_pden(struct wm97xx *wm) | |||
| 255 | static int wm9712_poll_sample(struct wm97xx *wm, int adcsel, int *sample) | 255 | static int wm9712_poll_sample(struct wm97xx *wm, int adcsel, int *sample) |
| 256 | { | 256 | { |
| 257 | int timeout = 5 * delay; | 257 | int timeout = 5 * delay; |
| 258 | bool wants_pen = adcsel & WM97XX_PEN_DOWN; | ||
| 258 | 259 | ||
| 259 | if (!wm->pen_probably_down) { | 260 | if (wants_pen && !wm->pen_probably_down) { |
| 260 | u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); | 261 | u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); |
| 261 | if (!(data & WM97XX_PEN_DOWN)) | 262 | if (!(data & WM97XX_PEN_DOWN)) |
| 262 | return RC_PENUP; | 263 | return RC_PENUP; |
| @@ -264,13 +265,10 @@ static int wm9712_poll_sample(struct wm97xx *wm, int adcsel, int *sample) | |||
| 264 | } | 265 | } |
| 265 | 266 | ||
| 266 | /* set up digitiser */ | 267 | /* set up digitiser */ |
| 267 | if (adcsel & 0x8000) | ||
| 268 | adcsel = ((adcsel & 0x7fff) + 3) << 12; | ||
| 269 | |||
| 270 | if (wm->mach_ops && wm->mach_ops->pre_sample) | 268 | if (wm->mach_ops && wm->mach_ops->pre_sample) |
| 271 | wm->mach_ops->pre_sample(adcsel); | 269 | wm->mach_ops->pre_sample(adcsel); |
| 272 | wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, | 270 | wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, (adcsel & WM97XX_ADCSEL_MASK) |
| 273 | adcsel | WM97XX_POLL | WM97XX_DELAY(delay)); | 271 | | WM97XX_POLL | WM97XX_DELAY(delay)); |
| 274 | 272 | ||
| 275 | /* wait 3 AC97 time slots + delay for conversion */ | 273 | /* wait 3 AC97 time slots + delay for conversion */ |
| 276 | poll_delay(delay); | 274 | poll_delay(delay); |
| @@ -296,13 +294,14 @@ static int wm9712_poll_sample(struct wm97xx *wm, int adcsel, int *sample) | |||
| 296 | wm->mach_ops->post_sample(adcsel); | 294 | wm->mach_ops->post_sample(adcsel); |
| 297 | 295 | ||
| 298 | /* check we have correct sample */ | 296 | /* check we have correct sample */ |
| 299 | if ((*sample & WM97XX_ADCSEL_MASK) != adcsel) { | 297 | if ((*sample ^ adcsel) & WM97XX_ADCSEL_MASK) { |
| 300 | dev_dbg(wm->dev, "adc wrong sample, read %x got %x", adcsel, | 298 | dev_dbg(wm->dev, "adc wrong sample, wanted %x got %x", |
| 301 | *sample & WM97XX_ADCSEL_MASK); | 299 | adcsel & WM97XX_ADCSEL_MASK, |
| 300 | *sample & WM97XX_ADCSEL_MASK); | ||
| 302 | return RC_PENUP; | 301 | return RC_PENUP; |
| 303 | } | 302 | } |
| 304 | 303 | ||
| 305 | if (!(*sample & WM97XX_PEN_DOWN)) { | 304 | if (wants_pen && !(*sample & WM97XX_PEN_DOWN)) { |
| 306 | wm->pen_probably_down = 0; | 305 | wm->pen_probably_down = 0; |
| 307 | return RC_PENUP; | 306 | return RC_PENUP; |
| 308 | } | 307 | } |
| @@ -387,16 +386,18 @@ static int wm9712_poll_touch(struct wm97xx *wm, struct wm97xx_data *data) | |||
| 387 | if (rc != RC_VALID) | 386 | if (rc != RC_VALID) |
| 388 | return rc; | 387 | return rc; |
| 389 | } else { | 388 | } else { |
| 390 | rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_X, &data->x); | 389 | rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_X | WM97XX_PEN_DOWN, |
| 390 | &data->x); | ||
| 391 | if (rc != RC_VALID) | 391 | if (rc != RC_VALID) |
| 392 | return rc; | 392 | return rc; |
| 393 | 393 | ||
| 394 | rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_Y, &data->y); | 394 | rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_Y | WM97XX_PEN_DOWN, |
| 395 | &data->y); | ||
| 395 | if (rc != RC_VALID) | 396 | if (rc != RC_VALID) |
| 396 | return rc; | 397 | return rc; |
| 397 | 398 | ||
| 398 | if (pil && !five_wire) { | 399 | if (pil && !five_wire) { |
| 399 | rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_PRES, | 400 | rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_PRES | WM97XX_PEN_DOWN, |
| 400 | &data->p); | 401 | &data->p); |
| 401 | if (rc != RC_VALID) | 402 | if (rc != RC_VALID) |
| 402 | return rc; | 403 | return rc; |
diff --git a/drivers/input/touchscreen/wm9713.c b/drivers/input/touchscreen/wm9713.c index 73ec99568f12..7405353199d7 100644 --- a/drivers/input/touchscreen/wm9713.c +++ b/drivers/input/touchscreen/wm9713.c | |||
| @@ -261,8 +261,9 @@ static int wm9713_poll_sample(struct wm97xx *wm, int adcsel, int *sample) | |||
| 261 | { | 261 | { |
| 262 | u16 dig1; | 262 | u16 dig1; |
| 263 | int timeout = 5 * delay; | 263 | int timeout = 5 * delay; |
| 264 | bool wants_pen = adcsel & WM97XX_PEN_DOWN; | ||
| 264 | 265 | ||
| 265 | if (!wm->pen_probably_down) { | 266 | if (wants_pen && !wm->pen_probably_down) { |
| 266 | u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); | 267 | u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); |
| 267 | if (!(data & WM97XX_PEN_DOWN)) | 268 | if (!(data & WM97XX_PEN_DOWN)) |
| 268 | return RC_PENUP; | 269 | return RC_PENUP; |
| @@ -270,15 +271,14 @@ static int wm9713_poll_sample(struct wm97xx *wm, int adcsel, int *sample) | |||
| 270 | } | 271 | } |
| 271 | 272 | ||
| 272 | /* set up digitiser */ | 273 | /* set up digitiser */ |
| 273 | if (adcsel & 0x8000) | ||
| 274 | adcsel = 1 << ((adcsel & 0x7fff) + 3); | ||
| 275 | |||
| 276 | dig1 = wm97xx_reg_read(wm, AC97_WM9713_DIG1); | 274 | dig1 = wm97xx_reg_read(wm, AC97_WM9713_DIG1); |
| 277 | dig1 &= ~WM9713_ADCSEL_MASK; | 275 | dig1 &= ~WM9713_ADCSEL_MASK; |
| 276 | /* WM97XX_ADCSEL_* channels need to be converted to WM9713 format */ | ||
| 277 | dig1 |= 1 << ((adcsel & WM97XX_ADCSEL_MASK) >> 12); | ||
| 278 | 278 | ||
| 279 | if (wm->mach_ops && wm->mach_ops->pre_sample) | 279 | if (wm->mach_ops && wm->mach_ops->pre_sample) |
| 280 | wm->mach_ops->pre_sample(adcsel); | 280 | wm->mach_ops->pre_sample(adcsel); |
| 281 | wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1 | adcsel | WM9713_POLL); | 281 | wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1 | WM9713_POLL); |
| 282 | 282 | ||
| 283 | /* wait 3 AC97 time slots + delay for conversion */ | 283 | /* wait 3 AC97 time slots + delay for conversion */ |
| 284 | poll_delay(delay); | 284 | poll_delay(delay); |
| @@ -304,13 +304,14 @@ static int wm9713_poll_sample(struct wm97xx *wm, int adcsel, int *sample) | |||
| 304 | wm->mach_ops->post_sample(adcsel); | 304 | wm->mach_ops->post_sample(adcsel); |
| 305 | 305 | ||
| 306 | /* check we have correct sample */ | 306 | /* check we have correct sample */ |
| 307 | if ((*sample & WM97XX_ADCSRC_MASK) != ffs(adcsel >> 1) << 12) { | 307 | if ((*sample ^ adcsel) & WM97XX_ADCSEL_MASK) { |
| 308 | dev_dbg(wm->dev, "adc wrong sample, read %x got %x", adcsel, | 308 | dev_dbg(wm->dev, "adc wrong sample, wanted %x got %x", |
| 309 | *sample & WM97XX_ADCSRC_MASK); | 309 | adcsel & WM97XX_ADCSEL_MASK, |
| 310 | *sample & WM97XX_ADCSEL_MASK); | ||
| 310 | return RC_PENUP; | 311 | return RC_PENUP; |
| 311 | } | 312 | } |
| 312 | 313 | ||
| 313 | if (!(*sample & WM97XX_PEN_DOWN)) { | 314 | if (wants_pen && !(*sample & WM97XX_PEN_DOWN)) { |
| 314 | wm->pen_probably_down = 0; | 315 | wm->pen_probably_down = 0; |
| 315 | return RC_PENUP; | 316 | return RC_PENUP; |
| 316 | } | 317 | } |
| @@ -400,14 +401,14 @@ static int wm9713_poll_touch(struct wm97xx *wm, struct wm97xx_data *data) | |||
| 400 | if (rc != RC_VALID) | 401 | if (rc != RC_VALID) |
| 401 | return rc; | 402 | return rc; |
| 402 | } else { | 403 | } else { |
| 403 | rc = wm9713_poll_sample(wm, WM9713_ADCSEL_X, &data->x); | 404 | rc = wm9713_poll_sample(wm, WM97XX_ADCSEL_X | WM97XX_PEN_DOWN, &data->x); |
| 404 | if (rc != RC_VALID) | 405 | if (rc != RC_VALID) |
| 405 | return rc; | 406 | return rc; |
| 406 | rc = wm9713_poll_sample(wm, WM9713_ADCSEL_Y, &data->y); | 407 | rc = wm9713_poll_sample(wm, WM97XX_ADCSEL_Y | WM97XX_PEN_DOWN, &data->y); |
| 407 | if (rc != RC_VALID) | 408 | if (rc != RC_VALID) |
| 408 | return rc; | 409 | return rc; |
| 409 | if (pil) { | 410 | if (pil) { |
| 410 | rc = wm9713_poll_sample(wm, WM9713_ADCSEL_PRES, | 411 | rc = wm9713_poll_sample(wm, WM97XX_ADCSEL_PRES | WM97XX_PEN_DOWN, |
| 411 | &data->p); | 412 | &data->p); |
| 412 | if (rc != RC_VALID) | 413 | if (rc != RC_VALID) |
| 413 | return rc; | 414 | return rc; |
diff --git a/drivers/input/touchscreen/zylonite-wm97xx.c b/drivers/input/touchscreen/zylonite-wm97xx.c index 5b0f15ec874a..f6328c0cded6 100644 --- a/drivers/input/touchscreen/zylonite-wm97xx.c +++ b/drivers/input/touchscreen/zylonite-wm97xx.c | |||
| @@ -122,9 +122,9 @@ static int wm97xx_acc_pen_down(struct wm97xx *wm) | |||
| 122 | x, y, p); | 122 | x, y, p); |
| 123 | 123 | ||
| 124 | /* are samples valid */ | 124 | /* are samples valid */ |
| 125 | if ((x & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_X || | 125 | if ((x & WM97XX_ADCSEL_MASK) != WM97XX_ADCSEL_X || |
| 126 | (y & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_Y || | 126 | (y & WM97XX_ADCSEL_MASK) != WM97XX_ADCSEL_Y || |
| 127 | (p & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_PRES) | 127 | (p & WM97XX_ADCSEL_MASK) != WM97XX_ADCSEL_PRES) |
| 128 | goto up; | 128 | goto up; |
| 129 | 129 | ||
| 130 | /* coordinate is good */ | 130 | /* coordinate is good */ |
diff --git a/include/linux/input.h b/include/linux/input.h index 771d6d85667d..068784e17972 100644 --- a/include/linux/input.h +++ b/include/linux/input.h | |||
| @@ -119,9 +119,9 @@ struct input_keymap_entry { | |||
| 119 | #define EVIOCGSND(len) _IOC(_IOC_READ, 'E', 0x1a, len) /* get all sounds status */ | 119 | #define EVIOCGSND(len) _IOC(_IOC_READ, 'E', 0x1a, len) /* get all sounds status */ |
| 120 | #define EVIOCGSW(len) _IOC(_IOC_READ, 'E', 0x1b, len) /* get all switch states */ | 120 | #define EVIOCGSW(len) _IOC(_IOC_READ, 'E', 0x1b, len) /* get all switch states */ |
| 121 | 121 | ||
| 122 | #define EVIOCGBIT(ev,len) _IOC(_IOC_READ, 'E', 0x20 + ev, len) /* get event bits */ | 122 | #define EVIOCGBIT(ev,len) _IOC(_IOC_READ, 'E', 0x20 + (ev), len) /* get event bits */ |
| 123 | #define EVIOCGABS(abs) _IOR('E', 0x40 + abs, struct input_absinfo) /* get abs value/limits */ | 123 | #define EVIOCGABS(abs) _IOR('E', 0x40 + (abs), struct input_absinfo) /* get abs value/limits */ |
| 124 | #define EVIOCSABS(abs) _IOW('E', 0xc0 + abs, struct input_absinfo) /* set abs value/limits */ | 124 | #define EVIOCSABS(abs) _IOW('E', 0xc0 + (abs), struct input_absinfo) /* set abs value/limits */ |
| 125 | 125 | ||
| 126 | #define EVIOCSFF _IOC(_IOC_WRITE, 'E', 0x80, sizeof(struct ff_effect)) /* send a force effect to a force feedback device */ | 126 | #define EVIOCSFF _IOC(_IOC_WRITE, 'E', 0x80, sizeof(struct ff_effect)) /* send a force effect to a force feedback device */ |
| 127 | #define EVIOCRMFF _IOW('E', 0x81, int) /* Erase a force effect */ | 127 | #define EVIOCRMFF _IOW('E', 0x81, int) /* Erase a force effect */ |
diff --git a/include/linux/input/kxtj9.h b/include/linux/input/kxtj9.h new file mode 100644 index 000000000000..f6bac89537b8 --- /dev/null +++ b/include/linux/input/kxtj9.h | |||
| @@ -0,0 +1,70 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 Kionix, Inc. | ||
| 3 | * Written by Chris Hudson <chudson@kionix.com> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License version 2 as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program; if not, write to the Free Software | ||
| 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
| 17 | * 02111-1307, USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef __KXTJ9_H__ | ||
| 21 | #define __KXTJ9_H__ | ||
| 22 | |||
| 23 | #define KXTJ9_I2C_ADDR 0x0F | ||
| 24 | |||
| 25 | struct kxtj9_platform_data { | ||
| 26 | unsigned int min_interval; /* minimum poll interval (in milli-seconds) */ | ||
| 27 | |||
| 28 | /* | ||
| 29 | * By default, x is axis 0, y is axis 1, z is axis 2; these can be | ||
| 30 | * changed to account for sensor orientation within the host device. | ||
| 31 | */ | ||
| 32 | u8 axis_map_x; | ||
| 33 | u8 axis_map_y; | ||
| 34 | u8 axis_map_z; | ||
| 35 | |||
| 36 | /* | ||
| 37 | * Each axis can be negated to account for sensor orientation within | ||
| 38 | * the host device. | ||
| 39 | */ | ||
| 40 | bool negate_x; | ||
| 41 | bool negate_y; | ||
| 42 | bool negate_z; | ||
| 43 | |||
| 44 | /* CTRL_REG1: set resolution, g-range, data ready enable */ | ||
| 45 | /* Output resolution: 8-bit valid or 12-bit valid */ | ||
| 46 | #define RES_8BIT 0 | ||
| 47 | #define RES_12BIT (1 << 6) | ||
| 48 | u8 res_12bit; | ||
| 49 | /* Output g-range: +/-2g, 4g, or 8g */ | ||
| 50 | #define KXTJ9_G_2G 0 | ||
| 51 | #define KXTJ9_G_4G (1 << 3) | ||
| 52 | #define KXTJ9_G_8G (1 << 4) | ||
| 53 | u8 g_range; | ||
| 54 | |||
| 55 | /* DATA_CTRL_REG: controls the output data rate of the part */ | ||
| 56 | #define ODR12_5F 0 | ||
| 57 | #define ODR25F 1 | ||
| 58 | #define ODR50F 2 | ||
| 59 | #define ODR100F 3 | ||
| 60 | #define ODR200F 4 | ||
| 61 | #define ODR400F 5 | ||
| 62 | #define ODR800F 6 | ||
| 63 | u8 data_odr_init; | ||
| 64 | |||
| 65 | int (*init)(void); | ||
| 66 | void (*exit)(void); | ||
| 67 | int (*power_on)(void); | ||
| 68 | int (*power_off)(void); | ||
| 69 | }; | ||
| 70 | #endif /* __KXTJ9_H__ */ | ||
diff --git a/include/linux/wm97xx.h b/include/linux/wm97xx.h index 38e8c4d9289e..fd98bb968219 100644 --- a/include/linux/wm97xx.h +++ b/include/linux/wm97xx.h | |||
| @@ -38,7 +38,11 @@ | |||
| 38 | #define WM97XX_ADCSEL_X 0x1000 /* x coord measurement */ | 38 | #define WM97XX_ADCSEL_X 0x1000 /* x coord measurement */ |
| 39 | #define WM97XX_ADCSEL_Y 0x2000 /* y coord measurement */ | 39 | #define WM97XX_ADCSEL_Y 0x2000 /* y coord measurement */ |
| 40 | #define WM97XX_ADCSEL_PRES 0x3000 /* pressure measurement */ | 40 | #define WM97XX_ADCSEL_PRES 0x3000 /* pressure measurement */ |
| 41 | #define WM97XX_ADCSEL_MASK 0x7000 | 41 | #define WM97XX_AUX_ID1 0x4000 |
| 42 | #define WM97XX_AUX_ID2 0x5000 | ||
| 43 | #define WM97XX_AUX_ID3 0x6000 | ||
| 44 | #define WM97XX_AUX_ID4 0x7000 | ||
| 45 | #define WM97XX_ADCSEL_MASK 0x7000 /* ADC selection mask */ | ||
| 42 | #define WM97XX_COO 0x0800 /* enable coordinate mode */ | 46 | #define WM97XX_COO 0x0800 /* enable coordinate mode */ |
| 43 | #define WM97XX_CTC 0x0400 /* enable continuous mode */ | 47 | #define WM97XX_CTC 0x0400 /* enable continuous mode */ |
| 44 | #define WM97XX_CM_RATE_93 0x0000 /* 93.75Hz continuous rate */ | 48 | #define WM97XX_CM_RATE_93 0x0000 /* 93.75Hz continuous rate */ |
| @@ -61,13 +65,6 @@ | |||
| 61 | #define WM97XX_PRP_DET_DIG 0xc000 /* setect on, digitise on */ | 65 | #define WM97XX_PRP_DET_DIG 0xc000 /* setect on, digitise on */ |
| 62 | #define WM97XX_RPR 0x2000 /* wake up on pen down */ | 66 | #define WM97XX_RPR 0x2000 /* wake up on pen down */ |
| 63 | #define WM97XX_PEN_DOWN 0x8000 /* pen is down */ | 67 | #define WM97XX_PEN_DOWN 0x8000 /* pen is down */ |
| 64 | #define WM97XX_ADCSRC_MASK 0x7000 /* ADC source mask */ | ||
| 65 | |||
| 66 | #define WM97XX_AUX_ID1 0x8001 | ||
| 67 | #define WM97XX_AUX_ID2 0x8002 | ||
| 68 | #define WM97XX_AUX_ID3 0x8003 | ||
| 69 | #define WM97XX_AUX_ID4 0x8004 | ||
| 70 | |||
| 71 | 68 | ||
| 72 | /* WM9712 Bits */ | 69 | /* WM9712 Bits */ |
| 73 | #define WM9712_45W 0x1000 /* set for 5-wire touchscreen */ | 70 | #define WM9712_45W 0x1000 /* set for 5-wire touchscreen */ |
