diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-17 13:06:02 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-17 13:06:02 -0500 |
| commit | d797da41b2aceed5daa8cd2eee92cd74b2a0c652 (patch) | |
| tree | f4de7daf5a81f425c057dd5a65a0e1b8056de5a9 | |
| parent | d6666be6f0c43efb9475d1d35fbef9f8be61b7b1 (diff) | |
| parent | f20c86cd75f1c8c728dafd0218645ff3c5e8545d (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input subsystem updates from Dmitry Torokhov:
"Two new drivers for Elan hardware (for I2C touchpad and touchscreen
found in several Chromebooks and other devices), a driver for Goodix
touch panel, and small fixes to Cypress I2C trackpad and other input
drivers.
Also we switched to use __maybe_unused instead of gating suspend/
resume code with #ifdef guards to get better compile coverage"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (27 commits)
Input: gpio_keys - fix warning regarding uninitialized 'button' variable
Input: add support for Elan eKTH I2C touchscreens
Input: gpio_keys - fix warning regarding uninitialized 'irq' variable
Input: cyapa - use 'error' for error codes
Input: cyapa - fix resuming the device
Input: gpio_keys - add device tree support for interrupt only keys
Input: amikbd - allocate temporary keymap buffer on the stack
Input: amikbd - fix build if !CONFIG_HW_CONSOLE
Input: lm8323 - missing error check in lm8323_set_disable()
Input: initialize device counter variables with -1
Input: initialize input_no to -1 to avoid subtraction
Input: i8042 - do not try to load on Intel NUC D54250WYK
Input: atkbd - correct MSC_SCAN events for force_release keys
Input: cyapa - switch to using managed resources
Input: lifebook - use "static inline" instead of "inline" in lifebook.h
Input: touchscreen - use __maybe_unused instead of ifdef around suspend/resume
Input: mouse - use __maybe_unused instead of ifdef around suspend/resume
Input: misc - use __maybe_unused instead of ifdef around suspend/resume
Input: cap11xx - support for irq-active-high option
Input: cap11xx - add support for various cap11xx devices
...
77 files changed, 4949 insertions, 922 deletions
diff --git a/Documentation/devicetree/bindings/input/cap1106.txt b/Documentation/devicetree/bindings/input/cap11xx.txt index 4b463904cba0..7d0a3009771b 100644 --- a/Documentation/devicetree/bindings/input/cap1106.txt +++ b/Documentation/devicetree/bindings/input/cap11xx.txt | |||
| @@ -1,14 +1,16 @@ | |||
| 1 | Device tree bindings for Microchip CAP1106, 6 channel capacitive touch sensor | 1 | Device tree bindings for Microchip CAP11xx based capacitive touch sensors |
| 2 | 2 | ||
| 3 | The node for this driver must be a child of a I2C controller node, as the | 3 | The node for this device must be a child of a I2C controller node, as the |
| 4 | device communication via I2C only. | 4 | device communication via I2C only. |
| 5 | 5 | ||
| 6 | Required properties: | 6 | Required properties: |
| 7 | 7 | ||
| 8 | compatible: Must be "microchip,cap1106" | 8 | compatible: Must contain one of: |
| 9 | "microchip,cap1106" | ||
| 10 | "microchip,cap1126" | ||
| 11 | "microchip,cap1188" | ||
| 9 | 12 | ||
| 10 | reg: The I2C slave address of the device. | 13 | reg: The I2C slave address of the device. |
| 11 | Only 0x28 is valid. | ||
| 12 | 14 | ||
| 13 | interrupts: Property describing the interrupt line the | 15 | interrupts: Property describing the interrupt line the |
| 14 | device's ALERT#/CM_IRQ# pin is connected to. | 16 | device's ALERT#/CM_IRQ# pin is connected to. |
| @@ -26,6 +28,10 @@ Optional properties: | |||
| 26 | Valid values are 1, 2, 4, and 8. | 28 | Valid values are 1, 2, 4, and 8. |
| 27 | By default, a gain of 1 is set. | 29 | By default, a gain of 1 is set. |
| 28 | 30 | ||
| 31 | microchip,irq-active-high: By default the interrupt pin is active low | ||
| 32 | open drain. This property allows using the active | ||
| 33 | high push-pull output. | ||
| 34 | |||
| 29 | linux,keycodes: Specifies an array of numeric keycode values to | 35 | linux,keycodes: Specifies an array of numeric keycode values to |
| 30 | be used for the channels. If this property is | 36 | be used for the channels. If this property is |
| 31 | omitted, KEY_A, KEY_B, etc are used as | 37 | omitted, KEY_A, KEY_B, etc are used as |
| @@ -43,11 +49,11 @@ i2c_controller { | |||
| 43 | autorepeat; | 49 | autorepeat; |
| 44 | microchip,sensor-gain = <2>; | 50 | microchip,sensor-gain = <2>; |
| 45 | 51 | ||
| 46 | linux,keycodes = <103 /* KEY_UP */ | 52 | linux,keycodes = <103>, /* KEY_UP */ |
| 47 | 106 /* KEY_RIGHT */ | 53 | <106>, /* KEY_RIGHT */ |
| 48 | 108 /* KEY_DOWN */ | 54 | <108>, /* KEY_DOWN */ |
| 49 | 105 /* KEY_LEFT */ | 55 | <105>, /* KEY_LEFT */ |
| 50 | 109 /* KEY_PAGEDOWN */ | 56 | <109>, /* KEY_PAGEDOWN */ |
| 51 | 104>; /* KEY_PAGEUP */ | 57 | <104>; /* KEY_PAGEUP */ |
| 52 | }; | 58 | }; |
| 53 | } | 59 | } |
diff --git a/Documentation/devicetree/bindings/input/elan_i2c.txt b/Documentation/devicetree/bindings/input/elan_i2c.txt new file mode 100644 index 000000000000..ee3242c4ba67 --- /dev/null +++ b/Documentation/devicetree/bindings/input/elan_i2c.txt | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | Elantech I2C Touchpad | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible: must be "elan,ekth3000". | ||
| 5 | - reg: I2C address of the chip. | ||
| 6 | - interrupt-parent: a phandle for the interrupt controller (see interrupt | ||
| 7 | binding[0]). | ||
| 8 | - interrupts: interrupt to which the chip is connected (see interrupt | ||
| 9 | binding[0]). | ||
| 10 | |||
| 11 | Optional properties: | ||
| 12 | - wakeup-source: touchpad can be used as a wakeup source. | ||
| 13 | - pinctrl-names: should be "default" (see pinctrl binding [1]). | ||
| 14 | - pinctrl-0: a phandle pointing to the pin settings for the device (see | ||
| 15 | pinctrl binding [1]). | ||
| 16 | - vcc-supply: a phandle for the regulator supplying 3.3V power. | ||
| 17 | |||
| 18 | [0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt | ||
| 19 | [1]: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt | ||
| 20 | |||
| 21 | Example: | ||
| 22 | &i2c1 { | ||
| 23 | /* ... */ | ||
| 24 | |||
| 25 | touchpad@15 { | ||
| 26 | compatible = "elan,ekth3000"; | ||
| 27 | reg = <0x15>; | ||
| 28 | interrupt-parent = <&gpio4>; | ||
| 29 | interrupts = <0x0 IRQ_TYPE_EDGE_FALLING>; | ||
| 30 | wakeup-source; | ||
| 31 | }; | ||
| 32 | |||
| 33 | /* ... */ | ||
| 34 | }; | ||
diff --git a/Documentation/devicetree/bindings/input/elants_i2c.txt b/Documentation/devicetree/bindings/input/elants_i2c.txt new file mode 100644 index 000000000000..a765232e6446 --- /dev/null +++ b/Documentation/devicetree/bindings/input/elants_i2c.txt | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | Elantech I2C Touchscreen | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible: must be "elan,ekth3500". | ||
| 5 | - reg: I2C address of the chip. | ||
| 6 | - interrupt-parent: a phandle for the interrupt controller (see interrupt | ||
| 7 | binding[0]). | ||
| 8 | - interrupts: interrupt to which the chip is connected (see interrupt | ||
| 9 | binding[0]). | ||
| 10 | |||
| 11 | Optional properties: | ||
| 12 | - wakeup-source: touchscreen can be used as a wakeup source. | ||
| 13 | - pinctrl-names: should be "default" (see pinctrl binding [1]). | ||
| 14 | - pinctrl-0: a phandle pointing to the pin settings for the device (see | ||
| 15 | pinctrl binding [1]). | ||
| 16 | |||
| 17 | [0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt | ||
| 18 | [1]: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt | ||
| 19 | |||
| 20 | Example: | ||
| 21 | &i2c1 { | ||
| 22 | /* ... */ | ||
| 23 | |||
| 24 | touchscreen@10 { | ||
| 25 | compatible = "elan,ekth3500"; | ||
| 26 | reg = <0x10>; | ||
| 27 | interrupt-parent = <&gpio4>; | ||
| 28 | interrupts = <0x0 IRQ_TYPE_EDGE_FALLING>; | ||
| 29 | wakeup-source; | ||
| 30 | }; | ||
| 31 | |||
| 32 | /* ... */ | ||
| 33 | }; | ||
diff --git a/Documentation/devicetree/bindings/input/gpio-keys.txt b/Documentation/devicetree/bindings/input/gpio-keys.txt index 5c2c02140a62..a4a38fcf2ed6 100644 --- a/Documentation/devicetree/bindings/input/gpio-keys.txt +++ b/Documentation/devicetree/bindings/input/gpio-keys.txt | |||
| @@ -10,10 +10,13 @@ Optional properties: | |||
| 10 | Each button (key) is represented as a sub-node of "gpio-keys": | 10 | Each button (key) is represented as a sub-node of "gpio-keys": |
| 11 | Subnode properties: | 11 | Subnode properties: |
| 12 | 12 | ||
| 13 | - gpios: OF device-tree gpio specification. | ||
| 14 | - label: Descriptive name of the key. | 13 | - label: Descriptive name of the key. |
| 15 | - linux,code: Keycode to emit. | 14 | - linux,code: Keycode to emit. |
| 16 | 15 | ||
| 16 | Required mutual exclusive subnode-properties: | ||
| 17 | - gpios: OF device-tree gpio specification. | ||
| 18 | - interrupts: the interrupt line for that input | ||
| 19 | |||
| 17 | Optional subnode-properties: | 20 | Optional subnode-properties: |
| 18 | - linux,input-type: Specify event type this button/key generates. | 21 | - linux,input-type: Specify event type this button/key generates. |
| 19 | If not specified defaults to <1> == EV_KEY. | 22 | If not specified defaults to <1> == EV_KEY. |
| @@ -33,4 +36,9 @@ Example nodes: | |||
| 33 | linux,code = <103>; | 36 | linux,code = <103>; |
| 34 | gpios = <&gpio1 0 1>; | 37 | gpios = <&gpio1 0 1>; |
| 35 | }; | 38 | }; |
| 39 | button@22 { | ||
| 40 | label = "GPIO Key DOWN"; | ||
| 41 | linux,code = <108>; | ||
| 42 | interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; | ||
| 43 | }; | ||
| 36 | ... | 44 | ... |
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 423d47418e72..b1df0ad1306c 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt | |||
| @@ -47,6 +47,7 @@ dlink D-Link Corporation | |||
| 47 | dmo Data Modul AG | 47 | dmo Data Modul AG |
| 48 | ebv EBV Elektronik | 48 | ebv EBV Elektronik |
| 49 | edt Emerging Display Technologies | 49 | edt Emerging Display Technologies |
| 50 | elan Elan Microelectronic Corp. | ||
| 50 | emmicro EM Microelectronic | 51 | emmicro EM Microelectronic |
| 51 | energymicro Silicon Laboratories (formerly Energy Micro AS) | 52 | energymicro Silicon Laboratories (formerly Energy Micro AS) |
| 52 | epcos EPCOS AG | 53 | epcos EPCOS AG |
diff --git a/MAINTAINERS b/MAINTAINERS index 4aac6c8dce72..68e79dac352f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -4255,6 +4255,12 @@ L: linux-media@vger.kernel.org | |||
| 4255 | S: Maintained | 4255 | S: Maintained |
| 4256 | F: drivers/media/usb/go7007/ | 4256 | F: drivers/media/usb/go7007/ |
| 4257 | 4257 | ||
| 4258 | GOODIX TOUCHSCREEN | ||
| 4259 | M: Bastien Nocera <hadess@hadess.net> | ||
| 4260 | L: linux-input@vger.kernel.org | ||
| 4261 | S: Maintained | ||
| 4262 | F: drivers/input/touchscreen/goodix.c | ||
| 4263 | |||
| 4258 | GPIO SUBSYSTEM | 4264 | GPIO SUBSYSTEM |
| 4259 | M: Linus Walleij <linus.walleij@linaro.org> | 4265 | M: Linus Walleij <linus.walleij@linaro.org> |
| 4260 | M: Alexandre Courbot <gnurou@gmail.com> | 4266 | M: Alexandre Courbot <gnurou@gmail.com> |
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index e29c04e2aff4..e853a2134680 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c | |||
| @@ -527,14 +527,14 @@ EXPORT_SYMBOL(gameport_set_phys); | |||
| 527 | */ | 527 | */ |
| 528 | static void gameport_init_port(struct gameport *gameport) | 528 | static void gameport_init_port(struct gameport *gameport) |
| 529 | { | 529 | { |
| 530 | static atomic_t gameport_no = ATOMIC_INIT(0); | 530 | static atomic_t gameport_no = ATOMIC_INIT(-1); |
| 531 | 531 | ||
| 532 | __module_get(THIS_MODULE); | 532 | __module_get(THIS_MODULE); |
| 533 | 533 | ||
| 534 | mutex_init(&gameport->drv_mutex); | 534 | mutex_init(&gameport->drv_mutex); |
| 535 | device_initialize(&gameport->dev); | 535 | device_initialize(&gameport->dev); |
| 536 | dev_set_name(&gameport->dev, "gameport%lu", | 536 | dev_set_name(&gameport->dev, "gameport%lu", |
| 537 | (unsigned long)atomic_inc_return(&gameport_no) - 1); | 537 | (unsigned long)atomic_inc_return(&gameport_no)); |
| 538 | gameport->dev.bus = &gameport_bus; | 538 | gameport->dev.bus = &gameport_bus; |
| 539 | gameport->dev.release = gameport_release_port; | 539 | gameport->dev.release = gameport_release_port; |
| 540 | if (gameport->parent) | 540 | if (gameport->parent) |
diff --git a/drivers/input/input.c b/drivers/input/input.c index 0f175f55782b..04217c2e345c 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
| @@ -1775,7 +1775,7 @@ EXPORT_SYMBOL_GPL(input_class); | |||
| 1775 | */ | 1775 | */ |
| 1776 | struct input_dev *input_allocate_device(void) | 1776 | struct input_dev *input_allocate_device(void) |
| 1777 | { | 1777 | { |
| 1778 | static atomic_t input_no = ATOMIC_INIT(0); | 1778 | static atomic_t input_no = ATOMIC_INIT(-1); |
| 1779 | struct input_dev *dev; | 1779 | struct input_dev *dev; |
| 1780 | 1780 | ||
| 1781 | dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL); | 1781 | dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL); |
| @@ -1790,7 +1790,7 @@ struct input_dev *input_allocate_device(void) | |||
| 1790 | INIT_LIST_HEAD(&dev->node); | 1790 | INIT_LIST_HEAD(&dev->node); |
| 1791 | 1791 | ||
| 1792 | dev_set_name(&dev->dev, "input%lu", | 1792 | dev_set_name(&dev->dev, "input%lu", |
| 1793 | (unsigned long) atomic_inc_return(&input_no) - 1); | 1793 | (unsigned long)atomic_inc_return(&input_no)); |
| 1794 | 1794 | ||
| 1795 | __module_get(THIS_MODULE); | 1795 | __module_get(THIS_MODULE); |
| 1796 | } | 1796 | } |
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index fc55f0d15b70..3aa2f3f3da5b 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
| @@ -886,8 +886,8 @@ static void xpad_led_set(struct led_classdev *led_cdev, | |||
| 886 | 886 | ||
| 887 | static int xpad_led_probe(struct usb_xpad *xpad) | 887 | static int xpad_led_probe(struct usb_xpad *xpad) |
| 888 | { | 888 | { |
| 889 | static atomic_t led_seq = ATOMIC_INIT(0); | 889 | static atomic_t led_seq = ATOMIC_INIT(-1); |
| 890 | long led_no; | 890 | unsigned long led_no; |
| 891 | struct xpad_led *led; | 891 | struct xpad_led *led; |
| 892 | struct led_classdev *led_cdev; | 892 | struct led_classdev *led_cdev; |
| 893 | int error; | 893 | int error; |
| @@ -899,9 +899,9 @@ static int xpad_led_probe(struct usb_xpad *xpad) | |||
| 899 | if (!led) | 899 | if (!led) |
| 900 | return -ENOMEM; | 900 | return -ENOMEM; |
| 901 | 901 | ||
| 902 | led_no = (long)atomic_inc_return(&led_seq) - 1; | 902 | led_no = atomic_inc_return(&led_seq); |
| 903 | 903 | ||
| 904 | snprintf(led->name, sizeof(led->name), "xpad%ld", led_no); | 904 | snprintf(led->name, sizeof(led->name), "xpad%lu", led_no); |
| 905 | led->xpad = xpad; | 905 | led->xpad = xpad; |
| 906 | 906 | ||
| 907 | led_cdev = &led->led_cdev; | 907 | led_cdev = &led->led_cdev; |
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index a3958c63d7d5..96ee26c555e0 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
| @@ -665,14 +665,14 @@ config KEYBOARD_CROS_EC | |||
| 665 | To compile this driver as a module, choose M here: the | 665 | To compile this driver as a module, choose M here: the |
| 666 | module will be called cros_ec_keyb. | 666 | module will be called cros_ec_keyb. |
| 667 | 667 | ||
| 668 | config KEYBOARD_CAP1106 | 668 | config KEYBOARD_CAP11XX |
| 669 | tristate "Microchip CAP1106 touch sensor" | 669 | tristate "Microchip CAP11XX based touch sensors" |
| 670 | depends on OF && I2C | 670 | depends on OF && I2C |
| 671 | select REGMAP_I2C | 671 | select REGMAP_I2C |
| 672 | help | 672 | help |
| 673 | Say Y here to enable the CAP1106 touch sensor driver. | 673 | Say Y here to enable the CAP11XX touch sensor driver. |
| 674 | 674 | ||
| 675 | To compile this driver as a module, choose M here: the | 675 | To compile this driver as a module, choose M here: the |
| 676 | module will be called cap1106. | 676 | module will be called cap11xx. |
| 677 | 677 | ||
| 678 | endif | 678 | endif |
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 0a3345634d79..febafa527eb6 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
| @@ -11,7 +11,7 @@ obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o | |||
| 11 | obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o | 11 | obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o |
| 12 | obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o | 12 | obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o |
| 13 | obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o | 13 | obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o |
| 14 | obj-$(CONFIG_KEYBOARD_CAP1106) += cap1106.o | 14 | obj-$(CONFIG_KEYBOARD_CAP11XX) += cap11xx.o |
| 15 | obj-$(CONFIG_KEYBOARD_CLPS711X) += clps711x-keypad.o | 15 | obj-$(CONFIG_KEYBOARD_CLPS711X) += clps711x-keypad.o |
| 16 | obj-$(CONFIG_KEYBOARD_CROS_EC) += cros_ec_keyb.o | 16 | obj-$(CONFIG_KEYBOARD_CROS_EC) += cros_ec_keyb.o |
| 17 | obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o | 17 | obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o |
diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c index d3b8c58fcfdb..e04a3b4e55d6 100644 --- a/drivers/input/keyboard/amikbd.c +++ b/drivers/input/keyboard/amikbd.c | |||
| @@ -45,6 +45,7 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); | |||
| 45 | MODULE_DESCRIPTION("Amiga keyboard driver"); | 45 | MODULE_DESCRIPTION("Amiga keyboard driver"); |
| 46 | MODULE_LICENSE("GPL"); | 46 | MODULE_LICENSE("GPL"); |
| 47 | 47 | ||
| 48 | #ifdef CONFIG_HW_CONSOLE | ||
| 48 | static unsigned char amikbd_keycode[0x78] __initdata = { | 49 | static unsigned char amikbd_keycode[0x78] __initdata = { |
| 49 | [0] = KEY_GRAVE, | 50 | [0] = KEY_GRAVE, |
| 50 | [1] = KEY_1, | 51 | [1] = KEY_1, |
| @@ -144,6 +145,32 @@ static unsigned char amikbd_keycode[0x78] __initdata = { | |||
| 144 | [103] = KEY_RIGHTMETA | 145 | [103] = KEY_RIGHTMETA |
| 145 | }; | 146 | }; |
| 146 | 147 | ||
| 148 | static void __init amikbd_init_console_keymaps(void) | ||
| 149 | { | ||
| 150 | /* We can spare 512 bytes on stack for temp_map in init path. */ | ||
| 151 | unsigned short temp_map[NR_KEYS]; | ||
| 152 | int i, j; | ||
| 153 | |||
| 154 | for (i = 0; i < MAX_NR_KEYMAPS; i++) { | ||
| 155 | if (!key_maps[i]) | ||
| 156 | continue; | ||
| 157 | memset(temp_map, 0, sizeof(temp_map)); | ||
| 158 | for (j = 0; j < 0x78; j++) { | ||
| 159 | if (!amikbd_keycode[j]) | ||
| 160 | continue; | ||
| 161 | temp_map[j] = key_maps[i][amikbd_keycode[j]]; | ||
| 162 | } | ||
| 163 | for (j = 0; j < NR_KEYS; j++) { | ||
| 164 | if (!temp_map[j]) | ||
| 165 | temp_map[j] = 0xf200; | ||
| 166 | } | ||
| 167 | memcpy(key_maps[i], temp_map, sizeof(temp_map)); | ||
| 168 | } | ||
| 169 | } | ||
| 170 | #else /* !CONFIG_HW_CONSOLE */ | ||
| 171 | static inline void amikbd_init_console_keymaps(void) {} | ||
| 172 | #endif /* !CONFIG_HW_CONSOLE */ | ||
| 173 | |||
| 147 | static const char *amikbd_messages[8] = { | 174 | static const char *amikbd_messages[8] = { |
| 148 | [0] = KERN_ALERT "amikbd: Ctrl-Amiga-Amiga reset warning!!\n", | 175 | [0] = KERN_ALERT "amikbd: Ctrl-Amiga-Amiga reset warning!!\n", |
| 149 | [1] = KERN_WARNING "amikbd: keyboard lost sync\n", | 176 | [1] = KERN_WARNING "amikbd: keyboard lost sync\n", |
| @@ -186,7 +213,7 @@ static irqreturn_t amikbd_interrupt(int irq, void *data) | |||
| 186 | static int __init amikbd_probe(struct platform_device *pdev) | 213 | static int __init amikbd_probe(struct platform_device *pdev) |
| 187 | { | 214 | { |
| 188 | struct input_dev *dev; | 215 | struct input_dev *dev; |
| 189 | int i, j, err; | 216 | int i, err; |
| 190 | 217 | ||
| 191 | dev = input_allocate_device(); | 218 | dev = input_allocate_device(); |
| 192 | if (!dev) { | 219 | if (!dev) { |
| @@ -207,22 +234,8 @@ static int __init amikbd_probe(struct platform_device *pdev) | |||
| 207 | for (i = 0; i < 0x78; i++) | 234 | for (i = 0; i < 0x78; i++) |
| 208 | set_bit(i, dev->keybit); | 235 | set_bit(i, dev->keybit); |
| 209 | 236 | ||
| 210 | for (i = 0; i < MAX_NR_KEYMAPS; i++) { | 237 | amikbd_init_console_keymaps(); |
| 211 | static u_short temp_map[NR_KEYS] __initdata; | 238 | |
| 212 | if (!key_maps[i]) | ||
| 213 | continue; | ||
| 214 | memset(temp_map, 0, sizeof(temp_map)); | ||
| 215 | for (j = 0; j < 0x78; j++) { | ||
| 216 | if (!amikbd_keycode[j]) | ||
| 217 | continue; | ||
| 218 | temp_map[j] = key_maps[i][amikbd_keycode[j]]; | ||
| 219 | } | ||
| 220 | for (j = 0; j < NR_KEYS; j++) { | ||
| 221 | if (!temp_map[j]) | ||
| 222 | temp_map[j] = 0xf200; | ||
| 223 | } | ||
| 224 | memcpy(key_maps[i], temp_map, sizeof(temp_map)); | ||
| 225 | } | ||
| 226 | ciaa.cra &= ~0x41; /* serial data in, turn off TA */ | 239 | ciaa.cra &= ~0x41; /* serial data in, turn off TA */ |
| 227 | err = request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd", | 240 | err = request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd", |
| 228 | dev); | 241 | dev); |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 6f5d79569136..e27a25892db4 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
| @@ -456,8 +456,9 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, | |||
| 456 | 456 | ||
| 457 | keycode = atkbd->keycode[code]; | 457 | keycode = atkbd->keycode[code]; |
| 458 | 458 | ||
| 459 | if (keycode != ATKBD_KEY_NULL) | 459 | if (!(atkbd->release && test_bit(code, atkbd->force_release_mask))) |
| 460 | input_event(dev, EV_MSC, MSC_SCAN, code); | 460 | if (keycode != ATKBD_KEY_NULL) |
| 461 | input_event(dev, EV_MSC, MSC_SCAN, code); | ||
| 461 | 462 | ||
| 462 | switch (keycode) { | 463 | switch (keycode) { |
| 463 | case ATKBD_KEY_NULL: | 464 | case ATKBD_KEY_NULL: |
| @@ -511,6 +512,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, | |||
| 511 | input_sync(dev); | 512 | input_sync(dev); |
| 512 | 513 | ||
| 513 | if (value && test_bit(code, atkbd->force_release_mask)) { | 514 | if (value && test_bit(code, atkbd->force_release_mask)) { |
| 515 | input_event(dev, EV_MSC, MSC_SCAN, code); | ||
| 514 | input_report_key(dev, keycode, 0); | 516 | input_report_key(dev, keycode, 0); |
| 515 | input_sync(dev); | 517 | input_sync(dev); |
| 516 | } | 518 | } |
diff --git a/drivers/input/keyboard/cap1106.c b/drivers/input/keyboard/cap1106.c deleted file mode 100644 index d70b65a14ced..000000000000 --- a/drivers/input/keyboard/cap1106.c +++ /dev/null | |||
| @@ -1,341 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Input driver for Microchip CAP1106, 6 channel capacitive touch sensor | ||
| 3 | * | ||
| 4 | * http://www.microchip.com/wwwproducts/Devices.aspx?product=CAP1106 | ||
| 5 | * | ||
| 6 | * (c) 2014 Daniel Mack <linux@zonque.org> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/kernel.h> | ||
| 14 | #include <linux/module.h> | ||
| 15 | #include <linux/interrupt.h> | ||
| 16 | #include <linux/input.h> | ||
| 17 | #include <linux/of_irq.h> | ||
| 18 | #include <linux/regmap.h> | ||
| 19 | #include <linux/i2c.h> | ||
| 20 | #include <linux/gpio/consumer.h> | ||
| 21 | |||
| 22 | #define CAP1106_REG_MAIN_CONTROL 0x00 | ||
| 23 | #define CAP1106_REG_MAIN_CONTROL_GAIN_SHIFT (6) | ||
| 24 | #define CAP1106_REG_MAIN_CONTROL_GAIN_MASK (0xc0) | ||
| 25 | #define CAP1106_REG_MAIN_CONTROL_DLSEEP BIT(4) | ||
| 26 | #define CAP1106_REG_GENERAL_STATUS 0x02 | ||
| 27 | #define CAP1106_REG_SENSOR_INPUT 0x03 | ||
| 28 | #define CAP1106_REG_NOISE_FLAG_STATUS 0x0a | ||
| 29 | #define CAP1106_REG_SENOR_DELTA(X) (0x10 + (X)) | ||
| 30 | #define CAP1106_REG_SENSITIVITY_CONTROL 0x1f | ||
| 31 | #define CAP1106_REG_CONFIG 0x20 | ||
| 32 | #define CAP1106_REG_SENSOR_ENABLE 0x21 | ||
| 33 | #define CAP1106_REG_SENSOR_CONFIG 0x22 | ||
| 34 | #define CAP1106_REG_SENSOR_CONFIG2 0x23 | ||
| 35 | #define CAP1106_REG_SAMPLING_CONFIG 0x24 | ||
| 36 | #define CAP1106_REG_CALIBRATION 0x26 | ||
| 37 | #define CAP1106_REG_INT_ENABLE 0x27 | ||
| 38 | #define CAP1106_REG_REPEAT_RATE 0x28 | ||
| 39 | #define CAP1106_REG_MT_CONFIG 0x2a | ||
| 40 | #define CAP1106_REG_MT_PATTERN_CONFIG 0x2b | ||
| 41 | #define CAP1106_REG_MT_PATTERN 0x2d | ||
| 42 | #define CAP1106_REG_RECALIB_CONFIG 0x2f | ||
| 43 | #define CAP1106_REG_SENSOR_THRESH(X) (0x30 + (X)) | ||
| 44 | #define CAP1106_REG_SENSOR_NOISE_THRESH 0x38 | ||
| 45 | #define CAP1106_REG_STANDBY_CHANNEL 0x40 | ||
| 46 | #define CAP1106_REG_STANDBY_CONFIG 0x41 | ||
| 47 | #define CAP1106_REG_STANDBY_SENSITIVITY 0x42 | ||
| 48 | #define CAP1106_REG_STANDBY_THRESH 0x43 | ||
| 49 | #define CAP1106_REG_CONFIG2 0x44 | ||
| 50 | #define CAP1106_REG_SENSOR_BASE_CNT(X) (0x50 + (X)) | ||
| 51 | #define CAP1106_REG_SENSOR_CALIB (0xb1 + (X)) | ||
| 52 | #define CAP1106_REG_SENSOR_CALIB_LSB1 0xb9 | ||
| 53 | #define CAP1106_REG_SENSOR_CALIB_LSB2 0xba | ||
| 54 | #define CAP1106_REG_PRODUCT_ID 0xfd | ||
| 55 | #define CAP1106_REG_MANUFACTURER_ID 0xfe | ||
| 56 | #define CAP1106_REG_REVISION 0xff | ||
| 57 | |||
| 58 | #define CAP1106_NUM_CHN 6 | ||
| 59 | #define CAP1106_PRODUCT_ID 0x55 | ||
| 60 | #define CAP1106_MANUFACTURER_ID 0x5d | ||
| 61 | |||
| 62 | struct cap1106_priv { | ||
| 63 | struct regmap *regmap; | ||
| 64 | struct input_dev *idev; | ||
| 65 | |||
| 66 | /* config */ | ||
| 67 | unsigned short keycodes[CAP1106_NUM_CHN]; | ||
| 68 | }; | ||
| 69 | |||
| 70 | static const struct reg_default cap1106_reg_defaults[] = { | ||
| 71 | { CAP1106_REG_MAIN_CONTROL, 0x00 }, | ||
| 72 | { CAP1106_REG_GENERAL_STATUS, 0x00 }, | ||
| 73 | { CAP1106_REG_SENSOR_INPUT, 0x00 }, | ||
| 74 | { CAP1106_REG_NOISE_FLAG_STATUS, 0x00 }, | ||
| 75 | { CAP1106_REG_SENSITIVITY_CONTROL, 0x2f }, | ||
| 76 | { CAP1106_REG_CONFIG, 0x20 }, | ||
| 77 | { CAP1106_REG_SENSOR_ENABLE, 0x3f }, | ||
| 78 | { CAP1106_REG_SENSOR_CONFIG, 0xa4 }, | ||
| 79 | { CAP1106_REG_SENSOR_CONFIG2, 0x07 }, | ||
| 80 | { CAP1106_REG_SAMPLING_CONFIG, 0x39 }, | ||
| 81 | { CAP1106_REG_CALIBRATION, 0x00 }, | ||
| 82 | { CAP1106_REG_INT_ENABLE, 0x3f }, | ||
| 83 | { CAP1106_REG_REPEAT_RATE, 0x3f }, | ||
| 84 | { CAP1106_REG_MT_CONFIG, 0x80 }, | ||
| 85 | { CAP1106_REG_MT_PATTERN_CONFIG, 0x00 }, | ||
| 86 | { CAP1106_REG_MT_PATTERN, 0x3f }, | ||
| 87 | { CAP1106_REG_RECALIB_CONFIG, 0x8a }, | ||
| 88 | { CAP1106_REG_SENSOR_THRESH(0), 0x40 }, | ||
| 89 | { CAP1106_REG_SENSOR_THRESH(1), 0x40 }, | ||
| 90 | { CAP1106_REG_SENSOR_THRESH(2), 0x40 }, | ||
| 91 | { CAP1106_REG_SENSOR_THRESH(3), 0x40 }, | ||
| 92 | { CAP1106_REG_SENSOR_THRESH(4), 0x40 }, | ||
| 93 | { CAP1106_REG_SENSOR_THRESH(5), 0x40 }, | ||
| 94 | { CAP1106_REG_SENSOR_NOISE_THRESH, 0x01 }, | ||
| 95 | { CAP1106_REG_STANDBY_CHANNEL, 0x00 }, | ||
| 96 | { CAP1106_REG_STANDBY_CONFIG, 0x39 }, | ||
| 97 | { CAP1106_REG_STANDBY_SENSITIVITY, 0x02 }, | ||
| 98 | { CAP1106_REG_STANDBY_THRESH, 0x40 }, | ||
| 99 | { CAP1106_REG_CONFIG2, 0x40 }, | ||
| 100 | { CAP1106_REG_SENSOR_CALIB_LSB1, 0x00 }, | ||
| 101 | { CAP1106_REG_SENSOR_CALIB_LSB2, 0x00 }, | ||
| 102 | }; | ||
| 103 | |||
| 104 | static bool cap1106_volatile_reg(struct device *dev, unsigned int reg) | ||
| 105 | { | ||
| 106 | switch (reg) { | ||
| 107 | case CAP1106_REG_MAIN_CONTROL: | ||
| 108 | case CAP1106_REG_SENSOR_INPUT: | ||
| 109 | case CAP1106_REG_SENOR_DELTA(0): | ||
| 110 | case CAP1106_REG_SENOR_DELTA(1): | ||
| 111 | case CAP1106_REG_SENOR_DELTA(2): | ||
| 112 | case CAP1106_REG_SENOR_DELTA(3): | ||
| 113 | case CAP1106_REG_SENOR_DELTA(4): | ||
| 114 | case CAP1106_REG_SENOR_DELTA(5): | ||
| 115 | case CAP1106_REG_PRODUCT_ID: | ||
| 116 | case CAP1106_REG_MANUFACTURER_ID: | ||
| 117 | case CAP1106_REG_REVISION: | ||
| 118 | return true; | ||
| 119 | } | ||
| 120 | |||
| 121 | return false; | ||
| 122 | } | ||
| 123 | |||
| 124 | static const struct regmap_config cap1106_regmap_config = { | ||
| 125 | .reg_bits = 8, | ||
| 126 | .val_bits = 8, | ||
| 127 | |||
| 128 | .max_register = CAP1106_REG_REVISION, | ||
| 129 | .reg_defaults = cap1106_reg_defaults, | ||
| 130 | |||
| 131 | .num_reg_defaults = ARRAY_SIZE(cap1106_reg_defaults), | ||
| 132 | .cache_type = REGCACHE_RBTREE, | ||
| 133 | .volatile_reg = cap1106_volatile_reg, | ||
| 134 | }; | ||
| 135 | |||
| 136 | static irqreturn_t cap1106_thread_func(int irq_num, void *data) | ||
| 137 | { | ||
| 138 | struct cap1106_priv *priv = data; | ||
| 139 | unsigned int status; | ||
| 140 | int ret, i; | ||
| 141 | |||
| 142 | /* | ||
| 143 | * Deassert interrupt. This needs to be done before reading the status | ||
| 144 | * registers, which will not carry valid values otherwise. | ||
| 145 | */ | ||
| 146 | ret = regmap_update_bits(priv->regmap, CAP1106_REG_MAIN_CONTROL, 1, 0); | ||
| 147 | if (ret < 0) | ||
| 148 | goto out; | ||
| 149 | |||
| 150 | ret = regmap_read(priv->regmap, CAP1106_REG_SENSOR_INPUT, &status); | ||
| 151 | if (ret < 0) | ||
| 152 | goto out; | ||
| 153 | |||
| 154 | for (i = 0; i < CAP1106_NUM_CHN; i++) | ||
| 155 | input_report_key(priv->idev, priv->keycodes[i], | ||
| 156 | status & (1 << i)); | ||
| 157 | |||
| 158 | input_sync(priv->idev); | ||
| 159 | |||
| 160 | out: | ||
| 161 | return IRQ_HANDLED; | ||
| 162 | } | ||
| 163 | |||
| 164 | static int cap1106_set_sleep(struct cap1106_priv *priv, bool sleep) | ||
| 165 | { | ||
| 166 | return regmap_update_bits(priv->regmap, CAP1106_REG_MAIN_CONTROL, | ||
| 167 | CAP1106_REG_MAIN_CONTROL_DLSEEP, | ||
| 168 | sleep ? CAP1106_REG_MAIN_CONTROL_DLSEEP : 0); | ||
| 169 | } | ||
| 170 | |||
| 171 | static int cap1106_input_open(struct input_dev *idev) | ||
| 172 | { | ||
| 173 | struct cap1106_priv *priv = input_get_drvdata(idev); | ||
| 174 | |||
| 175 | return cap1106_set_sleep(priv, false); | ||
| 176 | } | ||
| 177 | |||
| 178 | static void cap1106_input_close(struct input_dev *idev) | ||
| 179 | { | ||
| 180 | struct cap1106_priv *priv = input_get_drvdata(idev); | ||
| 181 | |||
| 182 | cap1106_set_sleep(priv, true); | ||
| 183 | } | ||
| 184 | |||
| 185 | static int cap1106_i2c_probe(struct i2c_client *i2c_client, | ||
| 186 | const struct i2c_device_id *id) | ||
| 187 | { | ||
| 188 | struct device *dev = &i2c_client->dev; | ||
| 189 | struct cap1106_priv *priv; | ||
| 190 | struct device_node *node; | ||
| 191 | int i, error, irq, gain = 0; | ||
| 192 | unsigned int val, rev; | ||
| 193 | u32 gain32, keycodes[CAP1106_NUM_CHN]; | ||
| 194 | |||
| 195 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
| 196 | if (!priv) | ||
| 197 | return -ENOMEM; | ||
| 198 | |||
| 199 | priv->regmap = devm_regmap_init_i2c(i2c_client, &cap1106_regmap_config); | ||
| 200 | if (IS_ERR(priv->regmap)) | ||
| 201 | return PTR_ERR(priv->regmap); | ||
| 202 | |||
| 203 | error = regmap_read(priv->regmap, CAP1106_REG_PRODUCT_ID, &val); | ||
| 204 | if (error) | ||
| 205 | return error; | ||
| 206 | |||
| 207 | if (val != CAP1106_PRODUCT_ID) { | ||
| 208 | dev_err(dev, "Product ID: Got 0x%02x, expected 0x%02x\n", | ||
| 209 | val, CAP1106_PRODUCT_ID); | ||
| 210 | return -ENODEV; | ||
| 211 | } | ||
| 212 | |||
| 213 | error = regmap_read(priv->regmap, CAP1106_REG_MANUFACTURER_ID, &val); | ||
| 214 | if (error) | ||
| 215 | return error; | ||
| 216 | |||
| 217 | if (val != CAP1106_MANUFACTURER_ID) { | ||
| 218 | dev_err(dev, "Manufacturer ID: Got 0x%02x, expected 0x%02x\n", | ||
| 219 | val, CAP1106_MANUFACTURER_ID); | ||
| 220 | return -ENODEV; | ||
| 221 | } | ||
| 222 | |||
| 223 | error = regmap_read(priv->regmap, CAP1106_REG_REVISION, &rev); | ||
| 224 | if (error < 0) | ||
| 225 | return error; | ||
| 226 | |||
| 227 | dev_info(dev, "CAP1106 detected, revision 0x%02x\n", rev); | ||
| 228 | i2c_set_clientdata(i2c_client, priv); | ||
| 229 | node = dev->of_node; | ||
| 230 | |||
| 231 | if (!of_property_read_u32(node, "microchip,sensor-gain", &gain32)) { | ||
| 232 | if (is_power_of_2(gain32) && gain32 <= 8) | ||
| 233 | gain = ilog2(gain32); | ||
| 234 | else | ||
| 235 | dev_err(dev, "Invalid sensor-gain value %d\n", gain32); | ||
| 236 | } | ||
| 237 | |||
| 238 | BUILD_BUG_ON(ARRAY_SIZE(keycodes) != ARRAY_SIZE(priv->keycodes)); | ||
| 239 | |||
| 240 | /* Provide some useful defaults */ | ||
| 241 | for (i = 0; i < ARRAY_SIZE(keycodes); i++) | ||
| 242 | keycodes[i] = KEY_A + i; | ||
| 243 | |||
| 244 | of_property_read_u32_array(node, "linux,keycodes", | ||
| 245 | keycodes, ARRAY_SIZE(keycodes)); | ||
| 246 | |||
| 247 | for (i = 0; i < ARRAY_SIZE(keycodes); i++) | ||
| 248 | priv->keycodes[i] = keycodes[i]; | ||
| 249 | |||
| 250 | error = regmap_update_bits(priv->regmap, CAP1106_REG_MAIN_CONTROL, | ||
| 251 | CAP1106_REG_MAIN_CONTROL_GAIN_MASK, | ||
| 252 | gain << CAP1106_REG_MAIN_CONTROL_GAIN_SHIFT); | ||
| 253 | if (error) | ||
| 254 | return error; | ||
| 255 | |||
| 256 | /* Disable autorepeat. The Linux input system has its own handling. */ | ||
| 257 | error = regmap_write(priv->regmap, CAP1106_REG_REPEAT_RATE, 0); | ||
| 258 | if (error) | ||
| 259 | return error; | ||
| 260 | |||
| 261 | priv->idev = devm_input_allocate_device(dev); | ||
| 262 | if (!priv->idev) | ||
| 263 | return -ENOMEM; | ||
| 264 | |||
| 265 | priv->idev->name = "CAP1106 capacitive touch sensor"; | ||
| 266 | priv->idev->id.bustype = BUS_I2C; | ||
| 267 | priv->idev->evbit[0] = BIT_MASK(EV_KEY); | ||
| 268 | |||
| 269 | if (of_property_read_bool(node, "autorepeat")) | ||
| 270 | __set_bit(EV_REP, priv->idev->evbit); | ||
| 271 | |||
| 272 | for (i = 0; i < CAP1106_NUM_CHN; i++) | ||
| 273 | __set_bit(priv->keycodes[i], priv->idev->keybit); | ||
| 274 | |||
| 275 | __clear_bit(KEY_RESERVED, priv->idev->keybit); | ||
| 276 | |||
| 277 | priv->idev->keycode = priv->keycodes; | ||
| 278 | priv->idev->keycodesize = sizeof(priv->keycodes[0]); | ||
| 279 | priv->idev->keycodemax = ARRAY_SIZE(priv->keycodes); | ||
| 280 | |||
| 281 | priv->idev->id.vendor = CAP1106_MANUFACTURER_ID; | ||
| 282 | priv->idev->id.product = CAP1106_PRODUCT_ID; | ||
| 283 | priv->idev->id.version = rev; | ||
| 284 | |||
| 285 | priv->idev->open = cap1106_input_open; | ||
| 286 | priv->idev->close = cap1106_input_close; | ||
| 287 | |||
| 288 | input_set_drvdata(priv->idev, priv); | ||
| 289 | |||
| 290 | /* | ||
| 291 | * Put the device in deep sleep mode for now. | ||
| 292 | * ->open() will bring it back once the it is actually needed. | ||
| 293 | */ | ||
| 294 | cap1106_set_sleep(priv, true); | ||
| 295 | |||
| 296 | error = input_register_device(priv->idev); | ||
| 297 | if (error) | ||
| 298 | return error; | ||
| 299 | |||
| 300 | irq = irq_of_parse_and_map(node, 0); | ||
| 301 | if (!irq) { | ||
| 302 | dev_err(dev, "Unable to parse or map IRQ\n"); | ||
| 303 | return -ENXIO; | ||
| 304 | } | ||
| 305 | |||
| 306 | error = devm_request_threaded_irq(dev, irq, NULL, cap1106_thread_func, | ||
| 307 | IRQF_ONESHOT, dev_name(dev), priv); | ||
| 308 | if (error) | ||
| 309 | return error; | ||
| 310 | |||
| 311 | return 0; | ||
| 312 | } | ||
| 313 | |||
| 314 | static const struct of_device_id cap1106_dt_ids[] = { | ||
| 315 | { .compatible = "microchip,cap1106", }, | ||
| 316 | {} | ||
| 317 | }; | ||
| 318 | MODULE_DEVICE_TABLE(of, cap1106_dt_ids); | ||
| 319 | |||
| 320 | static const struct i2c_device_id cap1106_i2c_ids[] = { | ||
| 321 | { "cap1106", 0 }, | ||
| 322 | {} | ||
| 323 | }; | ||
| 324 | MODULE_DEVICE_TABLE(i2c, cap1106_i2c_ids); | ||
| 325 | |||
| 326 | static struct i2c_driver cap1106_i2c_driver = { | ||
| 327 | .driver = { | ||
| 328 | .name = "cap1106", | ||
| 329 | .owner = THIS_MODULE, | ||
| 330 | .of_match_table = cap1106_dt_ids, | ||
| 331 | }, | ||
| 332 | .id_table = cap1106_i2c_ids, | ||
| 333 | .probe = cap1106_i2c_probe, | ||
| 334 | }; | ||
| 335 | |||
| 336 | module_i2c_driver(cap1106_i2c_driver); | ||
| 337 | |||
| 338 | MODULE_ALIAS("platform:cap1106"); | ||
| 339 | MODULE_DESCRIPTION("Microchip CAP1106 driver"); | ||
| 340 | MODULE_AUTHOR("Daniel Mack <linux@zonque.org>"); | ||
| 341 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/input/keyboard/cap11xx.c b/drivers/input/keyboard/cap11xx.c new file mode 100644 index 000000000000..4f59f0bab28f --- /dev/null +++ b/drivers/input/keyboard/cap11xx.c | |||
| @@ -0,0 +1,376 @@ | |||
| 1 | /* | ||
| 2 | * Input driver for Microchip CAP11xx based capacitive touch sensors | ||
| 3 | * | ||
| 4 | * (c) 2014 Daniel Mack <linux@zonque.org> | ||
| 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 version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/kernel.h> | ||
| 12 | #include <linux/module.h> | ||
| 13 | #include <linux/interrupt.h> | ||
| 14 | #include <linux/input.h> | ||
| 15 | #include <linux/of_irq.h> | ||
| 16 | #include <linux/regmap.h> | ||
| 17 | #include <linux/i2c.h> | ||
| 18 | #include <linux/gpio/consumer.h> | ||
| 19 | |||
| 20 | #define CAP11XX_REG_MAIN_CONTROL 0x00 | ||
| 21 | #define CAP11XX_REG_MAIN_CONTROL_GAIN_SHIFT (6) | ||
| 22 | #define CAP11XX_REG_MAIN_CONTROL_GAIN_MASK (0xc0) | ||
| 23 | #define CAP11XX_REG_MAIN_CONTROL_DLSEEP BIT(4) | ||
| 24 | #define CAP11XX_REG_GENERAL_STATUS 0x02 | ||
| 25 | #define CAP11XX_REG_SENSOR_INPUT 0x03 | ||
| 26 | #define CAP11XX_REG_NOISE_FLAG_STATUS 0x0a | ||
| 27 | #define CAP11XX_REG_SENOR_DELTA(X) (0x10 + (X)) | ||
| 28 | #define CAP11XX_REG_SENSITIVITY_CONTROL 0x1f | ||
| 29 | #define CAP11XX_REG_CONFIG 0x20 | ||
| 30 | #define CAP11XX_REG_SENSOR_ENABLE 0x21 | ||
| 31 | #define CAP11XX_REG_SENSOR_CONFIG 0x22 | ||
| 32 | #define CAP11XX_REG_SENSOR_CONFIG2 0x23 | ||
| 33 | #define CAP11XX_REG_SAMPLING_CONFIG 0x24 | ||
| 34 | #define CAP11XX_REG_CALIBRATION 0x26 | ||
| 35 | #define CAP11XX_REG_INT_ENABLE 0x27 | ||
| 36 | #define CAP11XX_REG_REPEAT_RATE 0x28 | ||
| 37 | #define CAP11XX_REG_MT_CONFIG 0x2a | ||
| 38 | #define CAP11XX_REG_MT_PATTERN_CONFIG 0x2b | ||
| 39 | #define CAP11XX_REG_MT_PATTERN 0x2d | ||
| 40 | #define CAP11XX_REG_RECALIB_CONFIG 0x2f | ||
| 41 | #define CAP11XX_REG_SENSOR_THRESH(X) (0x30 + (X)) | ||
| 42 | #define CAP11XX_REG_SENSOR_NOISE_THRESH 0x38 | ||
| 43 | #define CAP11XX_REG_STANDBY_CHANNEL 0x40 | ||
| 44 | #define CAP11XX_REG_STANDBY_CONFIG 0x41 | ||
| 45 | #define CAP11XX_REG_STANDBY_SENSITIVITY 0x42 | ||
| 46 | #define CAP11XX_REG_STANDBY_THRESH 0x43 | ||
| 47 | #define CAP11XX_REG_CONFIG2 0x44 | ||
| 48 | #define CAP11XX_REG_CONFIG2_ALT_POL BIT(6) | ||
| 49 | #define CAP11XX_REG_SENSOR_BASE_CNT(X) (0x50 + (X)) | ||
| 50 | #define CAP11XX_REG_SENSOR_CALIB (0xb1 + (X)) | ||
| 51 | #define CAP11XX_REG_SENSOR_CALIB_LSB1 0xb9 | ||
| 52 | #define CAP11XX_REG_SENSOR_CALIB_LSB2 0xba | ||
| 53 | #define CAP11XX_REG_PRODUCT_ID 0xfd | ||
| 54 | #define CAP11XX_REG_MANUFACTURER_ID 0xfe | ||
| 55 | #define CAP11XX_REG_REVISION 0xff | ||
| 56 | |||
| 57 | #define CAP11XX_MANUFACTURER_ID 0x5d | ||
| 58 | |||
| 59 | struct cap11xx_priv { | ||
| 60 | struct regmap *regmap; | ||
| 61 | struct input_dev *idev; | ||
| 62 | |||
| 63 | /* config */ | ||
| 64 | u32 keycodes[]; | ||
| 65 | }; | ||
| 66 | |||
| 67 | struct cap11xx_hw_model { | ||
| 68 | u8 product_id; | ||
| 69 | unsigned int num_channels; | ||
| 70 | }; | ||
| 71 | |||
| 72 | enum { | ||
| 73 | CAP1106, | ||
| 74 | CAP1126, | ||
| 75 | CAP1188, | ||
| 76 | }; | ||
| 77 | |||
| 78 | static const struct cap11xx_hw_model cap11xx_devices[] = { | ||
| 79 | [CAP1106] = { .product_id = 0x55, .num_channels = 6 }, | ||
| 80 | [CAP1126] = { .product_id = 0x53, .num_channels = 6 }, | ||
| 81 | [CAP1188] = { .product_id = 0x50, .num_channels = 8 }, | ||
| 82 | }; | ||
| 83 | |||
| 84 | static const struct reg_default cap11xx_reg_defaults[] = { | ||
| 85 | { CAP11XX_REG_MAIN_CONTROL, 0x00 }, | ||
| 86 | { CAP11XX_REG_GENERAL_STATUS, 0x00 }, | ||
| 87 | { CAP11XX_REG_SENSOR_INPUT, 0x00 }, | ||
| 88 | { CAP11XX_REG_NOISE_FLAG_STATUS, 0x00 }, | ||
| 89 | { CAP11XX_REG_SENSITIVITY_CONTROL, 0x2f }, | ||
| 90 | { CAP11XX_REG_CONFIG, 0x20 }, | ||
| 91 | { CAP11XX_REG_SENSOR_ENABLE, 0x3f }, | ||
| 92 | { CAP11XX_REG_SENSOR_CONFIG, 0xa4 }, | ||
| 93 | { CAP11XX_REG_SENSOR_CONFIG2, 0x07 }, | ||
| 94 | { CAP11XX_REG_SAMPLING_CONFIG, 0x39 }, | ||
| 95 | { CAP11XX_REG_CALIBRATION, 0x00 }, | ||
| 96 | { CAP11XX_REG_INT_ENABLE, 0x3f }, | ||
| 97 | { CAP11XX_REG_REPEAT_RATE, 0x3f }, | ||
| 98 | { CAP11XX_REG_MT_CONFIG, 0x80 }, | ||
| 99 | { CAP11XX_REG_MT_PATTERN_CONFIG, 0x00 }, | ||
| 100 | { CAP11XX_REG_MT_PATTERN, 0x3f }, | ||
| 101 | { CAP11XX_REG_RECALIB_CONFIG, 0x8a }, | ||
| 102 | { CAP11XX_REG_SENSOR_THRESH(0), 0x40 }, | ||
| 103 | { CAP11XX_REG_SENSOR_THRESH(1), 0x40 }, | ||
| 104 | { CAP11XX_REG_SENSOR_THRESH(2), 0x40 }, | ||
| 105 | { CAP11XX_REG_SENSOR_THRESH(3), 0x40 }, | ||
| 106 | { CAP11XX_REG_SENSOR_THRESH(4), 0x40 }, | ||
| 107 | { CAP11XX_REG_SENSOR_THRESH(5), 0x40 }, | ||
| 108 | { CAP11XX_REG_SENSOR_NOISE_THRESH, 0x01 }, | ||
| 109 | { CAP11XX_REG_STANDBY_CHANNEL, 0x00 }, | ||
| 110 | { CAP11XX_REG_STANDBY_CONFIG, 0x39 }, | ||
| 111 | { CAP11XX_REG_STANDBY_SENSITIVITY, 0x02 }, | ||
| 112 | { CAP11XX_REG_STANDBY_THRESH, 0x40 }, | ||
| 113 | { CAP11XX_REG_CONFIG2, 0x40 }, | ||
| 114 | { CAP11XX_REG_SENSOR_CALIB_LSB1, 0x00 }, | ||
| 115 | { CAP11XX_REG_SENSOR_CALIB_LSB2, 0x00 }, | ||
| 116 | }; | ||
| 117 | |||
| 118 | static bool cap11xx_volatile_reg(struct device *dev, unsigned int reg) | ||
| 119 | { | ||
| 120 | switch (reg) { | ||
| 121 | case CAP11XX_REG_MAIN_CONTROL: | ||
| 122 | case CAP11XX_REG_SENSOR_INPUT: | ||
| 123 | case CAP11XX_REG_SENOR_DELTA(0): | ||
| 124 | case CAP11XX_REG_SENOR_DELTA(1): | ||
| 125 | case CAP11XX_REG_SENOR_DELTA(2): | ||
| 126 | case CAP11XX_REG_SENOR_DELTA(3): | ||
| 127 | case CAP11XX_REG_SENOR_DELTA(4): | ||
| 128 | case CAP11XX_REG_SENOR_DELTA(5): | ||
| 129 | case CAP11XX_REG_PRODUCT_ID: | ||
| 130 | case CAP11XX_REG_MANUFACTURER_ID: | ||
| 131 | case CAP11XX_REG_REVISION: | ||
| 132 | return true; | ||
| 133 | } | ||
| 134 | |||
| 135 | return false; | ||
| 136 | } | ||
| 137 | |||
| 138 | static const struct regmap_config cap11xx_regmap_config = { | ||
| 139 | .reg_bits = 8, | ||
| 140 | .val_bits = 8, | ||
| 141 | |||
| 142 | .max_register = CAP11XX_REG_REVISION, | ||
| 143 | .reg_defaults = cap11xx_reg_defaults, | ||
| 144 | |||
| 145 | .num_reg_defaults = ARRAY_SIZE(cap11xx_reg_defaults), | ||
| 146 | .cache_type = REGCACHE_RBTREE, | ||
| 147 | .volatile_reg = cap11xx_volatile_reg, | ||
| 148 | }; | ||
| 149 | |||
| 150 | static irqreturn_t cap11xx_thread_func(int irq_num, void *data) | ||
| 151 | { | ||
| 152 | struct cap11xx_priv *priv = data; | ||
| 153 | unsigned int status; | ||
| 154 | int ret, i; | ||
| 155 | |||
| 156 | /* | ||
| 157 | * Deassert interrupt. This needs to be done before reading the status | ||
| 158 | * registers, which will not carry valid values otherwise. | ||
| 159 | */ | ||
| 160 | ret = regmap_update_bits(priv->regmap, CAP11XX_REG_MAIN_CONTROL, 1, 0); | ||
| 161 | if (ret < 0) | ||
| 162 | goto out; | ||
| 163 | |||
| 164 | ret = regmap_read(priv->regmap, CAP11XX_REG_SENSOR_INPUT, &status); | ||
| 165 | if (ret < 0) | ||
| 166 | goto out; | ||
| 167 | |||
| 168 | for (i = 0; i < priv->idev->keycodemax; i++) | ||
| 169 | input_report_key(priv->idev, priv->keycodes[i], | ||
| 170 | status & (1 << i)); | ||
| 171 | |||
| 172 | input_sync(priv->idev); | ||
| 173 | |||
| 174 | out: | ||
| 175 | return IRQ_HANDLED; | ||
| 176 | } | ||
| 177 | |||
| 178 | static int cap11xx_set_sleep(struct cap11xx_priv *priv, bool sleep) | ||
| 179 | { | ||
| 180 | return regmap_update_bits(priv->regmap, CAP11XX_REG_MAIN_CONTROL, | ||
| 181 | CAP11XX_REG_MAIN_CONTROL_DLSEEP, | ||
| 182 | sleep ? CAP11XX_REG_MAIN_CONTROL_DLSEEP : 0); | ||
| 183 | } | ||
| 184 | |||
| 185 | static int cap11xx_input_open(struct input_dev *idev) | ||
| 186 | { | ||
| 187 | struct cap11xx_priv *priv = input_get_drvdata(idev); | ||
| 188 | |||
| 189 | return cap11xx_set_sleep(priv, false); | ||
| 190 | } | ||
| 191 | |||
| 192 | static void cap11xx_input_close(struct input_dev *idev) | ||
| 193 | { | ||
| 194 | struct cap11xx_priv *priv = input_get_drvdata(idev); | ||
| 195 | |||
| 196 | cap11xx_set_sleep(priv, true); | ||
| 197 | } | ||
| 198 | |||
| 199 | static int cap11xx_i2c_probe(struct i2c_client *i2c_client, | ||
| 200 | const struct i2c_device_id *id) | ||
| 201 | { | ||
| 202 | struct device *dev = &i2c_client->dev; | ||
| 203 | struct cap11xx_priv *priv; | ||
| 204 | struct device_node *node; | ||
| 205 | const struct cap11xx_hw_model *cap; | ||
| 206 | int i, error, irq, gain = 0; | ||
| 207 | unsigned int val, rev; | ||
| 208 | u32 gain32; | ||
| 209 | |||
| 210 | if (id->driver_data >= ARRAY_SIZE(cap11xx_devices)) { | ||
| 211 | dev_err(dev, "Invalid device ID %lu\n", id->driver_data); | ||
| 212 | return -EINVAL; | ||
| 213 | } | ||
| 214 | |||
| 215 | cap = &cap11xx_devices[id->driver_data]; | ||
| 216 | if (!cap || !cap->num_channels) { | ||
| 217 | dev_err(dev, "Invalid device configuration\n"); | ||
| 218 | return -EINVAL; | ||
| 219 | } | ||
| 220 | |||
| 221 | priv = devm_kzalloc(dev, | ||
| 222 | sizeof(*priv) + | ||
| 223 | cap->num_channels * sizeof(priv->keycodes[0]), | ||
| 224 | GFP_KERNEL); | ||
| 225 | if (!priv) | ||
| 226 | return -ENOMEM; | ||
| 227 | |||
| 228 | priv->regmap = devm_regmap_init_i2c(i2c_client, &cap11xx_regmap_config); | ||
| 229 | if (IS_ERR(priv->regmap)) | ||
| 230 | return PTR_ERR(priv->regmap); | ||
| 231 | |||
| 232 | error = regmap_read(priv->regmap, CAP11XX_REG_PRODUCT_ID, &val); | ||
| 233 | if (error) | ||
| 234 | return error; | ||
| 235 | |||
| 236 | if (val != cap->product_id) { | ||
| 237 | dev_err(dev, "Product ID: Got 0x%02x, expected 0x%02x\n", | ||
| 238 | val, cap->product_id); | ||
| 239 | return -ENXIO; | ||
| 240 | } | ||
| 241 | |||
| 242 | error = regmap_read(priv->regmap, CAP11XX_REG_MANUFACTURER_ID, &val); | ||
| 243 | if (error) | ||
| 244 | return error; | ||
| 245 | |||
| 246 | if (val != CAP11XX_MANUFACTURER_ID) { | ||
| 247 | dev_err(dev, "Manufacturer ID: Got 0x%02x, expected 0x%02x\n", | ||
| 248 | val, CAP11XX_MANUFACTURER_ID); | ||
| 249 | return -ENXIO; | ||
| 250 | } | ||
| 251 | |||
| 252 | error = regmap_read(priv->regmap, CAP11XX_REG_REVISION, &rev); | ||
| 253 | if (error < 0) | ||
| 254 | return error; | ||
| 255 | |||
| 256 | dev_info(dev, "CAP11XX detected, revision 0x%02x\n", rev); | ||
| 257 | i2c_set_clientdata(i2c_client, priv); | ||
| 258 | node = dev->of_node; | ||
| 259 | |||
| 260 | if (!of_property_read_u32(node, "microchip,sensor-gain", &gain32)) { | ||
| 261 | if (is_power_of_2(gain32) && gain32 <= 8) | ||
| 262 | gain = ilog2(gain32); | ||
| 263 | else | ||
| 264 | dev_err(dev, "Invalid sensor-gain value %d\n", gain32); | ||
| 265 | } | ||
| 266 | |||
| 267 | if (of_property_read_bool(node, "microchip,irq-active-high")) { | ||
| 268 | error = regmap_update_bits(priv->regmap, CAP11XX_REG_CONFIG2, | ||
| 269 | CAP11XX_REG_CONFIG2_ALT_POL, 0); | ||
| 270 | if (error) | ||
| 271 | return error; | ||
| 272 | } | ||
| 273 | |||
| 274 | /* Provide some useful defaults */ | ||
| 275 | for (i = 0; i < cap->num_channels; i++) | ||
| 276 | priv->keycodes[i] = KEY_A + i; | ||
| 277 | |||
| 278 | of_property_read_u32_array(node, "linux,keycodes", | ||
| 279 | priv->keycodes, cap->num_channels); | ||
| 280 | |||
| 281 | error = regmap_update_bits(priv->regmap, CAP11XX_REG_MAIN_CONTROL, | ||
| 282 | CAP11XX_REG_MAIN_CONTROL_GAIN_MASK, | ||
| 283 | gain << CAP11XX_REG_MAIN_CONTROL_GAIN_SHIFT); | ||
| 284 | if (error) | ||
| 285 | return error; | ||
| 286 | |||
| 287 | /* Disable autorepeat. The Linux input system has its own handling. */ | ||
| 288 | error = regmap_write(priv->regmap, CAP11XX_REG_REPEAT_RATE, 0); | ||
| 289 | if (error) | ||
| 290 | return error; | ||
| 291 | |||
| 292 | priv->idev = devm_input_allocate_device(dev); | ||
| 293 | if (!priv->idev) | ||
| 294 | return -ENOMEM; | ||
| 295 | |||
| 296 | priv->idev->name = "CAP11XX capacitive touch sensor"; | ||
| 297 | priv->idev->id.bustype = BUS_I2C; | ||
| 298 | priv->idev->evbit[0] = BIT_MASK(EV_KEY); | ||
| 299 | |||
| 300 | if (of_property_read_bool(node, "autorepeat")) | ||
| 301 | __set_bit(EV_REP, priv->idev->evbit); | ||
| 302 | |||
| 303 | for (i = 0; i < cap->num_channels; i++) | ||
| 304 | __set_bit(priv->keycodes[i], priv->idev->keybit); | ||
| 305 | |||
| 306 | __clear_bit(KEY_RESERVED, priv->idev->keybit); | ||
| 307 | |||
| 308 | priv->idev->keycode = priv->keycodes; | ||
| 309 | priv->idev->keycodesize = sizeof(priv->keycodes[0]); | ||
| 310 | priv->idev->keycodemax = cap->num_channels; | ||
| 311 | |||
| 312 | priv->idev->id.vendor = CAP11XX_MANUFACTURER_ID; | ||
| 313 | priv->idev->id.product = cap->product_id; | ||
| 314 | priv->idev->id.version = rev; | ||
| 315 | |||
| 316 | priv->idev->open = cap11xx_input_open; | ||
| 317 | priv->idev->close = cap11xx_input_close; | ||
| 318 | |||
| 319 | input_set_drvdata(priv->idev, priv); | ||
| 320 | |||
| 321 | /* | ||
| 322 | * Put the device in deep sleep mode for now. | ||
| 323 | * ->open() will bring it back once the it is actually needed. | ||
| 324 | */ | ||
| 325 | cap11xx_set_sleep(priv, true); | ||
| 326 | |||
| 327 | error = input_register_device(priv->idev); | ||
| 328 | if (error) | ||
| 329 | return error; | ||
| 330 | |||
| 331 | irq = irq_of_parse_and_map(node, 0); | ||
| 332 | if (!irq) { | ||
| 333 | dev_err(dev, "Unable to parse or map IRQ\n"); | ||
| 334 | return -ENXIO; | ||
| 335 | } | ||
| 336 | |||
| 337 | error = devm_request_threaded_irq(dev, irq, NULL, cap11xx_thread_func, | ||
| 338 | IRQF_ONESHOT, dev_name(dev), priv); | ||
| 339 | if (error) | ||
| 340 | return error; | ||
| 341 | |||
| 342 | return 0; | ||
| 343 | } | ||
| 344 | |||
| 345 | static const struct of_device_id cap11xx_dt_ids[] = { | ||
| 346 | { .compatible = "microchip,cap1106", }, | ||
| 347 | { .compatible = "microchip,cap1126", }, | ||
| 348 | { .compatible = "microchip,cap1188", }, | ||
| 349 | {} | ||
| 350 | }; | ||
| 351 | MODULE_DEVICE_TABLE(of, cap11xx_dt_ids); | ||
| 352 | |||
| 353 | static const struct i2c_device_id cap11xx_i2c_ids[] = { | ||
| 354 | { "cap1106", CAP1106 }, | ||
| 355 | { "cap1126", CAP1126 }, | ||
| 356 | { "cap1188", CAP1188 }, | ||
| 357 | {} | ||
| 358 | }; | ||
| 359 | MODULE_DEVICE_TABLE(i2c, cap11xx_i2c_ids); | ||
| 360 | |||
| 361 | static struct i2c_driver cap11xx_i2c_driver = { | ||
| 362 | .driver = { | ||
| 363 | .name = "cap11xx", | ||
| 364 | .owner = THIS_MODULE, | ||
| 365 | .of_match_table = cap11xx_dt_ids, | ||
| 366 | }, | ||
| 367 | .id_table = cap11xx_i2c_ids, | ||
| 368 | .probe = cap11xx_i2c_probe, | ||
| 369 | }; | ||
| 370 | |||
| 371 | module_i2c_driver(cap11xx_i2c_driver); | ||
| 372 | |||
| 373 | MODULE_ALIAS("platform:cap11xx"); | ||
| 374 | MODULE_DESCRIPTION("Microchip CAP11XX driver"); | ||
| 375 | MODULE_AUTHOR("Daniel Mack <linux@zonque.org>"); | ||
| 376 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 8f3a24e15402..d4dd78a7d56b 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <linux/of.h> | 29 | #include <linux/of.h> |
| 30 | #include <linux/of_platform.h> | 30 | #include <linux/of_platform.h> |
| 31 | #include <linux/of_gpio.h> | 31 | #include <linux/of_gpio.h> |
| 32 | #include <linux/of_irq.h> | ||
| 32 | #include <linux/spinlock.h> | 33 | #include <linux/spinlock.h> |
| 33 | 34 | ||
| 34 | struct gpio_button_data { | 35 | struct gpio_button_data { |
| @@ -617,27 +618,31 @@ gpio_keys_get_devtree_pdata(struct device *dev) | |||
| 617 | 618 | ||
| 618 | i = 0; | 619 | i = 0; |
| 619 | for_each_child_of_node(node, pp) { | 620 | for_each_child_of_node(node, pp) { |
| 620 | int gpio; | 621 | int gpio = -1; |
| 621 | enum of_gpio_flags flags; | 622 | enum of_gpio_flags flags; |
| 622 | 623 | ||
| 623 | if (!of_find_property(pp, "gpios", NULL)) { | 624 | button = &pdata->buttons[i++]; |
| 624 | pdata->nbuttons--; | ||
| 625 | dev_warn(dev, "Found button without gpios\n"); | ||
| 626 | continue; | ||
| 627 | } | ||
| 628 | 625 | ||
| 629 | gpio = of_get_gpio_flags(pp, 0, &flags); | 626 | if (!of_find_property(pp, "gpios", NULL)) { |
| 630 | if (gpio < 0) { | 627 | button->irq = irq_of_parse_and_map(pp, 0); |
| 631 | error = gpio; | 628 | if (button->irq == 0) { |
| 632 | if (error != -EPROBE_DEFER) | 629 | i--; |
| 633 | dev_err(dev, | 630 | pdata->nbuttons--; |
| 634 | "Failed to get gpio flags, error: %d\n", | 631 | dev_warn(dev, "Found button without gpios or irqs\n"); |
| 635 | error); | 632 | continue; |
| 636 | return ERR_PTR(error); | 633 | } |
| 634 | } else { | ||
| 635 | gpio = of_get_gpio_flags(pp, 0, &flags); | ||
| 636 | if (gpio < 0) { | ||
| 637 | error = gpio; | ||
| 638 | if (error != -EPROBE_DEFER) | ||
| 639 | dev_err(dev, | ||
| 640 | "Failed to get gpio flags, error: %d\n", | ||
| 641 | error); | ||
| 642 | return ERR_PTR(error); | ||
| 643 | } | ||
| 637 | } | 644 | } |
| 638 | 645 | ||
| 639 | button = &pdata->buttons[i++]; | ||
| 640 | |||
| 641 | button->gpio = gpio; | 646 | button->gpio = gpio; |
| 642 | button->active_low = flags & OF_GPIO_ACTIVE_LOW; | 647 | button->active_low = flags & OF_GPIO_ACTIVE_LOW; |
| 643 | 648 | ||
diff --git a/drivers/input/keyboard/lm8323.c b/drivers/input/keyboard/lm8323.c index cb32e2b506b7..21bea52d4365 100644 --- a/drivers/input/keyboard/lm8323.c +++ b/drivers/input/keyboard/lm8323.c | |||
| @@ -616,6 +616,8 @@ static ssize_t lm8323_set_disable(struct device *dev, | |||
| 616 | unsigned int i; | 616 | unsigned int i; |
| 617 | 617 | ||
| 618 | ret = kstrtouint(buf, 10, &i); | 618 | ret = kstrtouint(buf, 10, &i); |
| 619 | if (ret) | ||
| 620 | return ret; | ||
| 619 | 621 | ||
| 620 | mutex_lock(&lm->lock); | 622 | mutex_lock(&lm->lock); |
| 621 | lm->kp_enabled = !i; | 623 | lm->kp_enabled = !i; |
diff --git a/drivers/input/keyboard/lpc32xx-keys.c b/drivers/input/keyboard/lpc32xx-keys.c index 8c079371c2e7..265d641c40e2 100644 --- a/drivers/input/keyboard/lpc32xx-keys.c +++ b/drivers/input/keyboard/lpc32xx-keys.c | |||
| @@ -66,7 +66,6 @@ | |||
| 66 | struct lpc32xx_kscan_drv { | 66 | struct lpc32xx_kscan_drv { |
| 67 | struct input_dev *input; | 67 | struct input_dev *input; |
| 68 | struct clk *clk; | 68 | struct clk *clk; |
| 69 | struct resource *iores; | ||
| 70 | void __iomem *kscan_base; | 69 | void __iomem *kscan_base; |
| 71 | unsigned int irq; | 70 | unsigned int irq; |
| 72 | 71 | ||
| @@ -188,32 +187,27 @@ static int lpc32xx_kscan_probe(struct platform_device *pdev) | |||
| 188 | return -EINVAL; | 187 | return -EINVAL; |
| 189 | } | 188 | } |
| 190 | 189 | ||
| 191 | kscandat = kzalloc(sizeof(struct lpc32xx_kscan_drv), GFP_KERNEL); | 190 | kscandat = devm_kzalloc(&pdev->dev, sizeof(*kscandat), |
| 192 | if (!kscandat) { | 191 | GFP_KERNEL); |
| 193 | dev_err(&pdev->dev, "failed to allocate memory\n"); | 192 | if (!kscandat) |
| 194 | return -ENOMEM; | 193 | return -ENOMEM; |
| 195 | } | ||
| 196 | 194 | ||
| 197 | error = lpc32xx_parse_dt(&pdev->dev, kscandat); | 195 | error = lpc32xx_parse_dt(&pdev->dev, kscandat); |
| 198 | if (error) { | 196 | if (error) { |
| 199 | dev_err(&pdev->dev, "failed to parse device tree\n"); | 197 | dev_err(&pdev->dev, "failed to parse device tree\n"); |
| 200 | goto err_free_mem; | 198 | return error; |
| 201 | } | 199 | } |
| 202 | 200 | ||
| 203 | keymap_size = sizeof(kscandat->keymap[0]) * | 201 | keymap_size = sizeof(kscandat->keymap[0]) * |
| 204 | (kscandat->matrix_sz << kscandat->row_shift); | 202 | (kscandat->matrix_sz << kscandat->row_shift); |
| 205 | kscandat->keymap = kzalloc(keymap_size, GFP_KERNEL); | 203 | kscandat->keymap = devm_kzalloc(&pdev->dev, keymap_size, GFP_KERNEL); |
| 206 | if (!kscandat->keymap) { | 204 | if (!kscandat->keymap) |
| 207 | dev_err(&pdev->dev, "could not allocate memory for keymap\n"); | 205 | return -ENOMEM; |
| 208 | error = -ENOMEM; | ||
| 209 | goto err_free_mem; | ||
| 210 | } | ||
| 211 | 206 | ||
| 212 | kscandat->input = input = input_allocate_device(); | 207 | kscandat->input = input = devm_input_allocate_device(&pdev->dev); |
| 213 | if (!input) { | 208 | if (!input) { |
| 214 | dev_err(&pdev->dev, "failed to allocate input device\n"); | 209 | dev_err(&pdev->dev, "failed to allocate input device\n"); |
| 215 | error = -ENOMEM; | 210 | return -ENOMEM; |
| 216 | goto err_free_keymap; | ||
| 217 | } | 211 | } |
| 218 | 212 | ||
| 219 | /* Setup key input */ | 213 | /* Setup key input */ |
| @@ -234,39 +228,26 @@ static int lpc32xx_kscan_probe(struct platform_device *pdev) | |||
| 234 | kscandat->keymap, kscandat->input); | 228 | kscandat->keymap, kscandat->input); |
| 235 | if (error) { | 229 | if (error) { |
| 236 | dev_err(&pdev->dev, "failed to build keymap\n"); | 230 | dev_err(&pdev->dev, "failed to build keymap\n"); |
| 237 | goto err_free_input; | 231 | return error; |
| 238 | } | 232 | } |
| 239 | 233 | ||
| 240 | input_set_drvdata(kscandat->input, kscandat); | 234 | input_set_drvdata(kscandat->input, kscandat); |
| 241 | 235 | ||
| 242 | kscandat->iores = request_mem_region(res->start, resource_size(res), | 236 | kscandat->kscan_base = devm_ioremap_resource(&pdev->dev, res); |
| 243 | pdev->name); | 237 | if (IS_ERR(kscandat->kscan_base)) |
| 244 | if (!kscandat->iores) { | 238 | return PTR_ERR(kscandat->kscan_base); |
| 245 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | ||
| 246 | error = -EBUSY; | ||
| 247 | goto err_free_input; | ||
| 248 | } | ||
| 249 | |||
| 250 | kscandat->kscan_base = ioremap(kscandat->iores->start, | ||
| 251 | resource_size(kscandat->iores)); | ||
| 252 | if (!kscandat->kscan_base) { | ||
| 253 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | ||
| 254 | error = -EBUSY; | ||
| 255 | goto err_release_memregion; | ||
| 256 | } | ||
| 257 | 239 | ||
| 258 | /* Get the key scanner clock */ | 240 | /* Get the key scanner clock */ |
| 259 | kscandat->clk = clk_get(&pdev->dev, NULL); | 241 | kscandat->clk = devm_clk_get(&pdev->dev, NULL); |
| 260 | if (IS_ERR(kscandat->clk)) { | 242 | if (IS_ERR(kscandat->clk)) { |
| 261 | dev_err(&pdev->dev, "failed to get clock\n"); | 243 | dev_err(&pdev->dev, "failed to get clock\n"); |
| 262 | error = PTR_ERR(kscandat->clk); | 244 | return PTR_ERR(kscandat->clk); |
| 263 | goto err_unmap; | ||
| 264 | } | 245 | } |
| 265 | 246 | ||
| 266 | /* Configure the key scanner */ | 247 | /* Configure the key scanner */ |
| 267 | error = clk_prepare_enable(kscandat->clk); | 248 | error = clk_prepare_enable(kscandat->clk); |
| 268 | if (error) | 249 | if (error) |
| 269 | goto err_clk_put; | 250 | return error; |
| 270 | 251 | ||
| 271 | writel(kscandat->deb_clks, LPC32XX_KS_DEB(kscandat->kscan_base)); | 252 | writel(kscandat->deb_clks, LPC32XX_KS_DEB(kscandat->kscan_base)); |
| 272 | writel(kscandat->scan_delay, LPC32XX_KS_SCAN_CTL(kscandat->kscan_base)); | 253 | writel(kscandat->scan_delay, LPC32XX_KS_SCAN_CTL(kscandat->kscan_base)); |
| @@ -277,52 +258,20 @@ static int lpc32xx_kscan_probe(struct platform_device *pdev) | |||
| 277 | writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); | 258 | writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); |
| 278 | clk_disable_unprepare(kscandat->clk); | 259 | clk_disable_unprepare(kscandat->clk); |
| 279 | 260 | ||
| 280 | error = request_irq(irq, lpc32xx_kscan_irq, 0, pdev->name, kscandat); | 261 | error = devm_request_irq(&pdev->dev, irq, lpc32xx_kscan_irq, 0, |
| 262 | pdev->name, kscandat); | ||
| 281 | if (error) { | 263 | if (error) { |
| 282 | dev_err(&pdev->dev, "failed to request irq\n"); | 264 | dev_err(&pdev->dev, "failed to request irq\n"); |
| 283 | goto err_clk_put; | 265 | return error; |
| 284 | } | 266 | } |
| 285 | 267 | ||
| 286 | error = input_register_device(kscandat->input); | 268 | error = input_register_device(kscandat->input); |
| 287 | if (error) { | 269 | if (error) { |
| 288 | dev_err(&pdev->dev, "failed to register input device\n"); | 270 | dev_err(&pdev->dev, "failed to register input device\n"); |
| 289 | goto err_free_irq; | 271 | return error; |
| 290 | } | 272 | } |
| 291 | 273 | ||
| 292 | platform_set_drvdata(pdev, kscandat); | 274 | platform_set_drvdata(pdev, kscandat); |
| 293 | return 0; | ||
| 294 | |||
| 295 | err_free_irq: | ||
| 296 | free_irq(irq, kscandat); | ||
| 297 | err_clk_put: | ||
| 298 | clk_put(kscandat->clk); | ||
| 299 | err_unmap: | ||
| 300 | iounmap(kscandat->kscan_base); | ||
| 301 | err_release_memregion: | ||
| 302 | release_mem_region(kscandat->iores->start, | ||
| 303 | resource_size(kscandat->iores)); | ||
| 304 | err_free_input: | ||
| 305 | input_free_device(kscandat->input); | ||
| 306 | err_free_keymap: | ||
| 307 | kfree(kscandat->keymap); | ||
| 308 | err_free_mem: | ||
| 309 | kfree(kscandat); | ||
| 310 | |||
| 311 | return error; | ||
| 312 | } | ||
| 313 | |||
| 314 | static int lpc32xx_kscan_remove(struct platform_device *pdev) | ||
| 315 | { | ||
| 316 | struct lpc32xx_kscan_drv *kscandat = platform_get_drvdata(pdev); | ||
| 317 | |||
| 318 | free_irq(platform_get_irq(pdev, 0), kscandat); | ||
| 319 | clk_put(kscandat->clk); | ||
| 320 | iounmap(kscandat->kscan_base); | ||
| 321 | release_mem_region(kscandat->iores->start, | ||
| 322 | resource_size(kscandat->iores)); | ||
| 323 | input_unregister_device(kscandat->input); | ||
| 324 | kfree(kscandat->keymap); | ||
| 325 | kfree(kscandat); | ||
| 326 | 275 | ||
| 327 | return 0; | 276 | return 0; |
| 328 | } | 277 | } |
| @@ -378,7 +327,6 @@ MODULE_DEVICE_TABLE(of, lpc32xx_kscan_match); | |||
| 378 | 327 | ||
| 379 | static struct platform_driver lpc32xx_kscan_driver = { | 328 | static struct platform_driver lpc32xx_kscan_driver = { |
| 380 | .probe = lpc32xx_kscan_probe, | 329 | .probe = lpc32xx_kscan_probe, |
| 381 | .remove = lpc32xx_kscan_remove, | ||
| 382 | .driver = { | 330 | .driver = { |
| 383 | .name = DRV_NAME, | 331 | .name = DRV_NAME, |
| 384 | .pm = &lpc32xx_kscan_pm_ops, | 332 | .pm = &lpc32xx_kscan_pm_ops, |
diff --git a/drivers/input/keyboard/mpr121_touchkey.c b/drivers/input/keyboard/mpr121_touchkey.c index 009c82256e89..3aa2ec45bcab 100644 --- a/drivers/input/keyboard/mpr121_touchkey.c +++ b/drivers/input/keyboard/mpr121_touchkey.c | |||
| @@ -214,13 +214,14 @@ static int mpr_touchkey_probe(struct i2c_client *client, | |||
| 214 | return -EINVAL; | 214 | return -EINVAL; |
| 215 | } | 215 | } |
| 216 | 216 | ||
| 217 | mpr121 = kzalloc(sizeof(struct mpr121_touchkey), GFP_KERNEL); | 217 | mpr121 = devm_kzalloc(&client->dev, sizeof(*mpr121), |
| 218 | input_dev = input_allocate_device(); | 218 | GFP_KERNEL); |
| 219 | if (!mpr121 || !input_dev) { | 219 | if (!mpr121) |
| 220 | dev_err(&client->dev, "Failed to allocate memory\n"); | 220 | return -ENOMEM; |
| 221 | error = -ENOMEM; | 221 | |
| 222 | goto err_free_mem; | 222 | input_dev = devm_input_allocate_device(&client->dev); |
| 223 | } | 223 | if (!input_dev) |
| 224 | return -ENOMEM; | ||
| 224 | 225 | ||
| 225 | mpr121->client = client; | 226 | mpr121->client = client; |
| 226 | mpr121->input_dev = input_dev; | 227 | mpr121->input_dev = input_dev; |
| @@ -243,44 +244,26 @@ static int mpr_touchkey_probe(struct i2c_client *client, | |||
| 243 | error = mpr121_phys_init(pdata, mpr121, client); | 244 | error = mpr121_phys_init(pdata, mpr121, client); |
| 244 | if (error) { | 245 | if (error) { |
| 245 | dev_err(&client->dev, "Failed to init register\n"); | 246 | dev_err(&client->dev, "Failed to init register\n"); |
| 246 | goto err_free_mem; | 247 | return error; |
| 247 | } | 248 | } |
| 248 | 249 | ||
| 249 | error = request_threaded_irq(client->irq, NULL, | 250 | error = devm_request_threaded_irq(&client->dev, client->irq, NULL, |
| 250 | mpr_touchkey_interrupt, | 251 | mpr_touchkey_interrupt, |
| 251 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | 252 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, |
| 252 | client->dev.driver->name, mpr121); | 253 | client->dev.driver->name, mpr121); |
| 253 | if (error) { | 254 | if (error) { |
| 254 | dev_err(&client->dev, "Failed to register interrupt\n"); | 255 | dev_err(&client->dev, "Failed to register interrupt\n"); |
| 255 | goto err_free_mem; | 256 | return error; |
| 256 | } | 257 | } |
| 257 | 258 | ||
| 258 | error = input_register_device(input_dev); | 259 | error = input_register_device(input_dev); |
| 259 | if (error) | 260 | if (error) |
| 260 | goto err_free_irq; | 261 | return error; |
| 261 | 262 | ||
| 262 | i2c_set_clientdata(client, mpr121); | 263 | i2c_set_clientdata(client, mpr121); |
| 263 | device_init_wakeup(&client->dev, pdata->wakeup); | 264 | device_init_wakeup(&client->dev, pdata->wakeup); |
| 264 | 265 | ||
| 265 | return 0; | 266 | return 0; |
| 266 | |||
| 267 | err_free_irq: | ||
| 268 | free_irq(client->irq, mpr121); | ||
| 269 | err_free_mem: | ||
| 270 | input_free_device(input_dev); | ||
| 271 | kfree(mpr121); | ||
| 272 | return error; | ||
| 273 | } | ||
| 274 | |||
| 275 | static int mpr_touchkey_remove(struct i2c_client *client) | ||
| 276 | { | ||
| 277 | struct mpr121_touchkey *mpr121 = i2c_get_clientdata(client); | ||
| 278 | |||
| 279 | free_irq(client->irq, mpr121); | ||
| 280 | input_unregister_device(mpr121->input_dev); | ||
| 281 | kfree(mpr121); | ||
| 282 | |||
| 283 | return 0; | ||
| 284 | } | 267 | } |
| 285 | 268 | ||
| 286 | #ifdef CONFIG_PM_SLEEP | 269 | #ifdef CONFIG_PM_SLEEP |
| @@ -327,7 +310,6 @@ static struct i2c_driver mpr_touchkey_driver = { | |||
| 327 | }, | 310 | }, |
| 328 | .id_table = mpr121_id, | 311 | .id_table = mpr121_id, |
| 329 | .probe = mpr_touchkey_probe, | 312 | .probe = mpr_touchkey_probe, |
| 330 | .remove = mpr_touchkey_remove, | ||
| 331 | }; | 313 | }; |
| 332 | 314 | ||
| 333 | module_i2c_driver(mpr_touchkey_driver); | 315 | module_i2c_driver(mpr_touchkey_driver); |
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index 6ab3e7c96329..a90d6bdc499e 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c | |||
| @@ -741,37 +741,27 @@ static int pxa27x_keypad_probe(struct platform_device *pdev) | |||
| 741 | return -ENXIO; | 741 | return -ENXIO; |
| 742 | } | 742 | } |
| 743 | 743 | ||
| 744 | keypad = kzalloc(sizeof(struct pxa27x_keypad), GFP_KERNEL); | 744 | keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), |
| 745 | input_dev = input_allocate_device(); | 745 | GFP_KERNEL); |
| 746 | if (!keypad || !input_dev) { | 746 | if (!keypad) |
| 747 | dev_err(&pdev->dev, "failed to allocate memory\n"); | 747 | return -ENOMEM; |
| 748 | error = -ENOMEM; | 748 | |
| 749 | goto failed_free; | 749 | input_dev = devm_input_allocate_device(&pdev->dev); |
| 750 | } | 750 | if (!input_dev) |
| 751 | return -ENOMEM; | ||
| 751 | 752 | ||
| 752 | keypad->pdata = pdata; | 753 | keypad->pdata = pdata; |
| 753 | keypad->input_dev = input_dev; | 754 | keypad->input_dev = input_dev; |
| 754 | keypad->irq = irq; | 755 | keypad->irq = irq; |
| 755 | 756 | ||
| 756 | res = request_mem_region(res->start, resource_size(res), pdev->name); | 757 | keypad->mmio_base = devm_ioremap_resource(&pdev->dev, res); |
| 757 | if (res == NULL) { | 758 | if (IS_ERR(keypad->mmio_base)) |
| 758 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | 759 | return PTR_ERR(keypad->mmio_base); |
| 759 | error = -EBUSY; | ||
| 760 | goto failed_free; | ||
| 761 | } | ||
| 762 | |||
| 763 | keypad->mmio_base = ioremap(res->start, resource_size(res)); | ||
| 764 | if (keypad->mmio_base == NULL) { | ||
| 765 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | ||
| 766 | error = -ENXIO; | ||
| 767 | goto failed_free_mem; | ||
| 768 | } | ||
| 769 | 760 | ||
| 770 | keypad->clk = clk_get(&pdev->dev, NULL); | 761 | keypad->clk = devm_clk_get(&pdev->dev, NULL); |
| 771 | if (IS_ERR(keypad->clk)) { | 762 | if (IS_ERR(keypad->clk)) { |
| 772 | dev_err(&pdev->dev, "failed to get keypad clock\n"); | 763 | dev_err(&pdev->dev, "failed to get keypad clock\n"); |
| 773 | error = PTR_ERR(keypad->clk); | 764 | return PTR_ERR(keypad->clk); |
| 774 | goto failed_free_io; | ||
| 775 | } | 765 | } |
| 776 | 766 | ||
| 777 | input_dev->name = pdev->name; | 767 | input_dev->name = pdev->name; |
| @@ -802,7 +792,7 @@ static int pxa27x_keypad_probe(struct platform_device *pdev) | |||
| 802 | } | 792 | } |
| 803 | if (error) { | 793 | if (error) { |
| 804 | dev_err(&pdev->dev, "failed to build keycode\n"); | 794 | dev_err(&pdev->dev, "failed to build keycode\n"); |
| 805 | goto failed_put_clk; | 795 | return error; |
| 806 | } | 796 | } |
| 807 | 797 | ||
| 808 | keypad->row_shift = get_count_order(pdata->matrix_key_cols); | 798 | keypad->row_shift = get_count_order(pdata->matrix_key_cols); |
| @@ -812,61 +802,26 @@ static int pxa27x_keypad_probe(struct platform_device *pdev) | |||
| 812 | input_dev->evbit[0] |= BIT_MASK(EV_REL); | 802 | input_dev->evbit[0] |= BIT_MASK(EV_REL); |
| 813 | } | 803 | } |
| 814 | 804 | ||
| 815 | error = request_irq(irq, pxa27x_keypad_irq_handler, 0, | 805 | error = devm_request_irq(&pdev->dev, irq, pxa27x_keypad_irq_handler, |
| 816 | pdev->name, keypad); | 806 | 0, pdev->name, keypad); |
| 817 | if (error) { | 807 | if (error) { |
| 818 | dev_err(&pdev->dev, "failed to request IRQ\n"); | 808 | dev_err(&pdev->dev, "failed to request IRQ\n"); |
| 819 | goto failed_put_clk; | 809 | return error; |
| 820 | } | 810 | } |
| 821 | 811 | ||
| 822 | /* Register the input device */ | 812 | /* Register the input device */ |
| 823 | error = input_register_device(input_dev); | 813 | error = input_register_device(input_dev); |
| 824 | if (error) { | 814 | if (error) { |
| 825 | dev_err(&pdev->dev, "failed to register input device\n"); | 815 | dev_err(&pdev->dev, "failed to register input device\n"); |
| 826 | goto failed_free_irq; | 816 | return error; |
| 827 | } | 817 | } |
| 828 | 818 | ||
| 829 | platform_set_drvdata(pdev, keypad); | 819 | platform_set_drvdata(pdev, keypad); |
| 830 | device_init_wakeup(&pdev->dev, 1); | 820 | device_init_wakeup(&pdev->dev, 1); |
| 831 | 821 | ||
| 832 | return 0; | 822 | return 0; |
| 833 | |||
| 834 | failed_free_irq: | ||
| 835 | free_irq(irq, keypad); | ||
| 836 | failed_put_clk: | ||
| 837 | clk_put(keypad->clk); | ||
| 838 | failed_free_io: | ||
| 839 | iounmap(keypad->mmio_base); | ||
| 840 | failed_free_mem: | ||
| 841 | release_mem_region(res->start, resource_size(res)); | ||
| 842 | failed_free: | ||
| 843 | input_free_device(input_dev); | ||
| 844 | kfree(keypad); | ||
| 845 | return error; | ||
| 846 | } | 823 | } |
| 847 | 824 | ||
| 848 | static int pxa27x_keypad_remove(struct platform_device *pdev) | ||
| 849 | { | ||
| 850 | struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); | ||
| 851 | struct resource *res; | ||
| 852 | |||
| 853 | free_irq(keypad->irq, keypad); | ||
| 854 | clk_put(keypad->clk); | ||
| 855 | |||
| 856 | input_unregister_device(keypad->input_dev); | ||
| 857 | iounmap(keypad->mmio_base); | ||
| 858 | |||
| 859 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 860 | release_mem_region(res->start, resource_size(res)); | ||
| 861 | |||
| 862 | kfree(keypad); | ||
| 863 | |||
| 864 | return 0; | ||
| 865 | } | ||
| 866 | |||
| 867 | /* work with hotplug and coldplug */ | ||
| 868 | MODULE_ALIAS("platform:pxa27x-keypad"); | ||
| 869 | |||
| 870 | #ifdef CONFIG_OF | 825 | #ifdef CONFIG_OF |
| 871 | static const struct of_device_id pxa27x_keypad_dt_match[] = { | 826 | static const struct of_device_id pxa27x_keypad_dt_match[] = { |
| 872 | { .compatible = "marvell,pxa27x-keypad" }, | 827 | { .compatible = "marvell,pxa27x-keypad" }, |
| @@ -877,7 +832,6 @@ MODULE_DEVICE_TABLE(of, pxa27x_keypad_dt_match); | |||
| 877 | 832 | ||
| 878 | static struct platform_driver pxa27x_keypad_driver = { | 833 | static struct platform_driver pxa27x_keypad_driver = { |
| 879 | .probe = pxa27x_keypad_probe, | 834 | .probe = pxa27x_keypad_probe, |
| 880 | .remove = pxa27x_keypad_remove, | ||
| 881 | .driver = { | 835 | .driver = { |
| 882 | .name = "pxa27x-keypad", | 836 | .name = "pxa27x-keypad", |
| 883 | .of_match_table = of_match_ptr(pxa27x_keypad_dt_match), | 837 | .of_match_table = of_match_ptr(pxa27x_keypad_dt_match), |
| @@ -888,3 +842,5 @@ module_platform_driver(pxa27x_keypad_driver); | |||
| 888 | 842 | ||
| 889 | MODULE_DESCRIPTION("PXA27x Keypad Controller Driver"); | 843 | MODULE_DESCRIPTION("PXA27x Keypad Controller Driver"); |
| 890 | MODULE_LICENSE("GPL"); | 844 | MODULE_LICENSE("GPL"); |
| 845 | /* work with hotplug and coldplug */ | ||
| 846 | MODULE_ALIAS("platform:pxa27x-keypad"); | ||
diff --git a/drivers/input/misc/88pm860x_onkey.c b/drivers/input/misc/88pm860x_onkey.c index cfdca6e99779..cc87443aa2ee 100644 --- a/drivers/input/misc/88pm860x_onkey.c +++ b/drivers/input/misc/88pm860x_onkey.c | |||
| @@ -112,8 +112,7 @@ static int pm860x_onkey_probe(struct platform_device *pdev) | |||
| 112 | return 0; | 112 | return 0; |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | #ifdef CONFIG_PM_SLEEP | 115 | static int __maybe_unused pm860x_onkey_suspend(struct device *dev) |
| 116 | static int pm860x_onkey_suspend(struct device *dev) | ||
| 117 | { | 116 | { |
| 118 | struct platform_device *pdev = to_platform_device(dev); | 117 | struct platform_device *pdev = to_platform_device(dev); |
| 119 | struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); | 118 | struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); |
| @@ -122,7 +121,7 @@ static int pm860x_onkey_suspend(struct device *dev) | |||
| 122 | chip->wakeup_flag |= 1 << PM8607_IRQ_ONKEY; | 121 | chip->wakeup_flag |= 1 << PM8607_IRQ_ONKEY; |
| 123 | return 0; | 122 | return 0; |
| 124 | } | 123 | } |
| 125 | static int pm860x_onkey_resume(struct device *dev) | 124 | static int __maybe_unused pm860x_onkey_resume(struct device *dev) |
| 126 | { | 125 | { |
| 127 | struct platform_device *pdev = to_platform_device(dev); | 126 | struct platform_device *pdev = to_platform_device(dev); |
| 128 | struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); | 127 | struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); |
| @@ -131,7 +130,6 @@ static int pm860x_onkey_resume(struct device *dev) | |||
| 131 | chip->wakeup_flag &= ~(1 << PM8607_IRQ_ONKEY); | 130 | chip->wakeup_flag &= ~(1 << PM8607_IRQ_ONKEY); |
| 132 | return 0; | 131 | return 0; |
| 133 | } | 132 | } |
| 134 | #endif | ||
| 135 | 133 | ||
| 136 | static SIMPLE_DEV_PM_OPS(pm860x_onkey_pm_ops, pm860x_onkey_suspend, pm860x_onkey_resume); | 134 | static SIMPLE_DEV_PM_OPS(pm860x_onkey_pm_ops, pm860x_onkey_suspend, pm860x_onkey_resume); |
| 137 | 135 | ||
diff --git a/drivers/input/misc/ad714x-i2c.c b/drivers/input/misc/ad714x-i2c.c index e0f522516ef5..189bdc8e91a5 100644 --- a/drivers/input/misc/ad714x-i2c.c +++ b/drivers/input/misc/ad714x-i2c.c | |||
| @@ -13,17 +13,15 @@ | |||
| 13 | #include <linux/pm.h> | 13 | #include <linux/pm.h> |
| 14 | #include "ad714x.h" | 14 | #include "ad714x.h" |
| 15 | 15 | ||
| 16 | #ifdef CONFIG_PM_SLEEP | 16 | static int __maybe_unused ad714x_i2c_suspend(struct device *dev) |
| 17 | static int ad714x_i2c_suspend(struct device *dev) | ||
| 18 | { | 17 | { |
| 19 | return ad714x_disable(i2c_get_clientdata(to_i2c_client(dev))); | 18 | return ad714x_disable(i2c_get_clientdata(to_i2c_client(dev))); |
| 20 | } | 19 | } |
| 21 | 20 | ||
| 22 | static int ad714x_i2c_resume(struct device *dev) | 21 | static int __maybe_unused ad714x_i2c_resume(struct device *dev) |
| 23 | { | 22 | { |
| 24 | return ad714x_enable(i2c_get_clientdata(to_i2c_client(dev))); | 23 | return ad714x_enable(i2c_get_clientdata(to_i2c_client(dev))); |
| 25 | } | 24 | } |
| 26 | #endif | ||
| 27 | 25 | ||
| 28 | static SIMPLE_DEV_PM_OPS(ad714x_i2c_pm, ad714x_i2c_suspend, ad714x_i2c_resume); | 26 | static SIMPLE_DEV_PM_OPS(ad714x_i2c_pm, ad714x_i2c_suspend, ad714x_i2c_resume); |
| 29 | 27 | ||
diff --git a/drivers/input/misc/ad714x-spi.c b/drivers/input/misc/ad714x-spi.c index 3a90b710e309..a79e50b58bf5 100644 --- a/drivers/input/misc/ad714x-spi.c +++ b/drivers/input/misc/ad714x-spi.c | |||
| @@ -16,17 +16,15 @@ | |||
| 16 | #define AD714x_SPI_CMD_PREFIX 0xE000 /* bits 15:11 */ | 16 | #define AD714x_SPI_CMD_PREFIX 0xE000 /* bits 15:11 */ |
| 17 | #define AD714x_SPI_READ BIT(10) | 17 | #define AD714x_SPI_READ BIT(10) |
| 18 | 18 | ||
| 19 | #ifdef CONFIG_PM_SLEEP | 19 | static int __maybe_unused ad714x_spi_suspend(struct device *dev) |
| 20 | static int ad714x_spi_suspend(struct device *dev) | ||
| 21 | { | 20 | { |
| 22 | return ad714x_disable(spi_get_drvdata(to_spi_device(dev))); | 21 | return ad714x_disable(spi_get_drvdata(to_spi_device(dev))); |
| 23 | } | 22 | } |
| 24 | 23 | ||
| 25 | static int ad714x_spi_resume(struct device *dev) | 24 | static int __maybe_unused ad714x_spi_resume(struct device *dev) |
| 26 | { | 25 | { |
| 27 | return ad714x_enable(spi_get_drvdata(to_spi_device(dev))); | 26 | return ad714x_enable(spi_get_drvdata(to_spi_device(dev))); |
| 28 | } | 27 | } |
| 29 | #endif | ||
| 30 | 28 | ||
| 31 | static SIMPLE_DEV_PM_OPS(ad714x_spi_pm, ad714x_spi_suspend, ad714x_spi_resume); | 29 | static SIMPLE_DEV_PM_OPS(ad714x_spi_pm, ad714x_spi_suspend, ad714x_spi_resume); |
| 32 | 30 | ||
diff --git a/drivers/input/misc/adxl34x-i2c.c b/drivers/input/misc/adxl34x-i2c.c index 416f47ddcc90..470bfd6f0830 100644 --- a/drivers/input/misc/adxl34x-i2c.c +++ b/drivers/input/misc/adxl34x-i2c.c | |||
| @@ -105,8 +105,7 @@ static int adxl34x_i2c_remove(struct i2c_client *client) | |||
| 105 | return adxl34x_remove(ac); | 105 | return adxl34x_remove(ac); |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | #ifdef CONFIG_PM_SLEEP | 108 | static int __maybe_unused adxl34x_i2c_suspend(struct device *dev) |
| 109 | static int adxl34x_i2c_suspend(struct device *dev) | ||
| 110 | { | 109 | { |
| 111 | struct i2c_client *client = to_i2c_client(dev); | 110 | struct i2c_client *client = to_i2c_client(dev); |
| 112 | struct adxl34x *ac = i2c_get_clientdata(client); | 111 | struct adxl34x *ac = i2c_get_clientdata(client); |
| @@ -116,7 +115,7 @@ static int adxl34x_i2c_suspend(struct device *dev) | |||
| 116 | return 0; | 115 | return 0; |
| 117 | } | 116 | } |
| 118 | 117 | ||
| 119 | static int adxl34x_i2c_resume(struct device *dev) | 118 | static int __maybe_unused adxl34x_i2c_resume(struct device *dev) |
| 120 | { | 119 | { |
| 121 | struct i2c_client *client = to_i2c_client(dev); | 120 | struct i2c_client *client = to_i2c_client(dev); |
| 122 | struct adxl34x *ac = i2c_get_clientdata(client); | 121 | struct adxl34x *ac = i2c_get_clientdata(client); |
| @@ -125,7 +124,6 @@ static int adxl34x_i2c_resume(struct device *dev) | |||
| 125 | 124 | ||
| 126 | return 0; | 125 | return 0; |
| 127 | } | 126 | } |
| 128 | #endif | ||
| 129 | 127 | ||
| 130 | static SIMPLE_DEV_PM_OPS(adxl34x_i2c_pm, adxl34x_i2c_suspend, | 128 | static SIMPLE_DEV_PM_OPS(adxl34x_i2c_pm, adxl34x_i2c_suspend, |
| 131 | adxl34x_i2c_resume); | 129 | adxl34x_i2c_resume); |
diff --git a/drivers/input/misc/adxl34x-spi.c b/drivers/input/misc/adxl34x-spi.c index 76dc0679d3b1..da6e76b58dab 100644 --- a/drivers/input/misc/adxl34x-spi.c +++ b/drivers/input/misc/adxl34x-spi.c | |||
| @@ -94,8 +94,7 @@ static int adxl34x_spi_remove(struct spi_device *spi) | |||
| 94 | return adxl34x_remove(ac); | 94 | return adxl34x_remove(ac); |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | #ifdef CONFIG_PM_SLEEP | 97 | static int __maybe_unused adxl34x_spi_suspend(struct device *dev) |
| 98 | static int adxl34x_spi_suspend(struct device *dev) | ||
| 99 | { | 98 | { |
| 100 | struct spi_device *spi = to_spi_device(dev); | 99 | struct spi_device *spi = to_spi_device(dev); |
| 101 | struct adxl34x *ac = spi_get_drvdata(spi); | 100 | struct adxl34x *ac = spi_get_drvdata(spi); |
| @@ -105,7 +104,7 @@ static int adxl34x_spi_suspend(struct device *dev) | |||
| 105 | return 0; | 104 | return 0; |
| 106 | } | 105 | } |
| 107 | 106 | ||
| 108 | static int adxl34x_spi_resume(struct device *dev) | 107 | static int __maybe_unused adxl34x_spi_resume(struct device *dev) |
| 109 | { | 108 | { |
| 110 | struct spi_device *spi = to_spi_device(dev); | 109 | struct spi_device *spi = to_spi_device(dev); |
| 111 | struct adxl34x *ac = spi_get_drvdata(spi); | 110 | struct adxl34x *ac = spi_get_drvdata(spi); |
| @@ -114,7 +113,6 @@ static int adxl34x_spi_resume(struct device *dev) | |||
| 114 | 113 | ||
| 115 | return 0; | 114 | return 0; |
| 116 | } | 115 | } |
| 117 | #endif | ||
| 118 | 116 | ||
| 119 | static SIMPLE_DEV_PM_OPS(adxl34x_spi_pm, adxl34x_spi_suspend, | 117 | static SIMPLE_DEV_PM_OPS(adxl34x_spi_pm, adxl34x_spi_suspend, |
| 120 | adxl34x_spi_resume); | 118 | adxl34x_spi_resume); |
diff --git a/drivers/input/misc/drv260x.c b/drivers/input/misc/drv260x.c index cab87f5ce6d3..a364e109ca7c 100644 --- a/drivers/input/misc/drv260x.c +++ b/drivers/input/misc/drv260x.c | |||
| @@ -639,8 +639,7 @@ static int drv260x_probe(struct i2c_client *client, | |||
| 639 | return 0; | 639 | return 0; |
| 640 | } | 640 | } |
| 641 | 641 | ||
| 642 | #ifdef CONFIG_PM_SLEEP | 642 | static int __maybe_unused drv260x_suspend(struct device *dev) |
| 643 | static int drv260x_suspend(struct device *dev) | ||
| 644 | { | 643 | { |
| 645 | struct drv260x_data *haptics = dev_get_drvdata(dev); | 644 | struct drv260x_data *haptics = dev_get_drvdata(dev); |
| 646 | int ret = 0; | 645 | int ret = 0; |
| @@ -672,7 +671,7 @@ out: | |||
| 672 | return ret; | 671 | return ret; |
| 673 | } | 672 | } |
| 674 | 673 | ||
| 675 | static int drv260x_resume(struct device *dev) | 674 | static int __maybe_unused drv260x_resume(struct device *dev) |
| 676 | { | 675 | { |
| 677 | struct drv260x_data *haptics = dev_get_drvdata(dev); | 676 | struct drv260x_data *haptics = dev_get_drvdata(dev); |
| 678 | int ret = 0; | 677 | int ret = 0; |
| @@ -702,7 +701,6 @@ out: | |||
| 702 | mutex_unlock(&haptics->input_dev->mutex); | 701 | mutex_unlock(&haptics->input_dev->mutex); |
| 703 | return ret; | 702 | return ret; |
| 704 | } | 703 | } |
| 705 | #endif | ||
| 706 | 704 | ||
| 707 | static SIMPLE_DEV_PM_OPS(drv260x_pm_ops, drv260x_suspend, drv260x_resume); | 705 | static SIMPLE_DEV_PM_OPS(drv260x_pm_ops, drv260x_suspend, drv260x_resume); |
| 708 | 706 | ||
diff --git a/drivers/input/misc/drv2667.c b/drivers/input/misc/drv2667.c index 0f437581cc04..a021744e608c 100644 --- a/drivers/input/misc/drv2667.c +++ b/drivers/input/misc/drv2667.c | |||
| @@ -406,8 +406,7 @@ static int drv2667_probe(struct i2c_client *client, | |||
| 406 | return 0; | 406 | return 0; |
| 407 | } | 407 | } |
| 408 | 408 | ||
| 409 | #ifdef CONFIG_PM_SLEEP | 409 | static int __maybe_unused drv2667_suspend(struct device *dev) |
| 410 | static int drv2667_suspend(struct device *dev) | ||
| 411 | { | 410 | { |
| 412 | struct drv2667_data *haptics = dev_get_drvdata(dev); | 411 | struct drv2667_data *haptics = dev_get_drvdata(dev); |
| 413 | int ret = 0; | 412 | int ret = 0; |
| @@ -436,7 +435,7 @@ out: | |||
| 436 | return ret; | 435 | return ret; |
| 437 | } | 436 | } |
| 438 | 437 | ||
| 439 | static int drv2667_resume(struct device *dev) | 438 | static int __maybe_unused drv2667_resume(struct device *dev) |
| 440 | { | 439 | { |
| 441 | struct drv2667_data *haptics = dev_get_drvdata(dev); | 440 | struct drv2667_data *haptics = dev_get_drvdata(dev); |
| 442 | int ret = 0; | 441 | int ret = 0; |
| @@ -464,7 +463,6 @@ out: | |||
| 464 | mutex_unlock(&haptics->input_dev->mutex); | 463 | mutex_unlock(&haptics->input_dev->mutex); |
| 465 | return ret; | 464 | return ret; |
| 466 | } | 465 | } |
| 467 | #endif | ||
| 468 | 466 | ||
| 469 | static SIMPLE_DEV_PM_OPS(drv2667_pm_ops, drv2667_suspend, drv2667_resume); | 467 | static SIMPLE_DEV_PM_OPS(drv2667_pm_ops, drv2667_suspend, drv2667_resume); |
| 470 | 468 | ||
diff --git a/drivers/input/misc/gp2ap002a00f.c b/drivers/input/misc/gp2ap002a00f.c index de21e317da32..0ac176d66a6f 100644 --- a/drivers/input/misc/gp2ap002a00f.c +++ b/drivers/input/misc/gp2ap002a00f.c | |||
| @@ -225,8 +225,7 @@ static int gp2a_remove(struct i2c_client *client) | |||
| 225 | return 0; | 225 | return 0; |
| 226 | } | 226 | } |
| 227 | 227 | ||
| 228 | #ifdef CONFIG_PM_SLEEP | 228 | static int __maybe_unused gp2a_suspend(struct device *dev) |
| 229 | static int gp2a_suspend(struct device *dev) | ||
| 230 | { | 229 | { |
| 231 | struct i2c_client *client = to_i2c_client(dev); | 230 | struct i2c_client *client = to_i2c_client(dev); |
| 232 | struct gp2a_data *dt = i2c_get_clientdata(client); | 231 | struct gp2a_data *dt = i2c_get_clientdata(client); |
| @@ -244,7 +243,7 @@ static int gp2a_suspend(struct device *dev) | |||
| 244 | return retval; | 243 | return retval; |
| 245 | } | 244 | } |
| 246 | 245 | ||
| 247 | static int gp2a_resume(struct device *dev) | 246 | static int __maybe_unused gp2a_resume(struct device *dev) |
| 248 | { | 247 | { |
| 249 | struct i2c_client *client = to_i2c_client(dev); | 248 | struct i2c_client *client = to_i2c_client(dev); |
| 250 | struct gp2a_data *dt = i2c_get_clientdata(client); | 249 | struct gp2a_data *dt = i2c_get_clientdata(client); |
| @@ -261,7 +260,6 @@ static int gp2a_resume(struct device *dev) | |||
| 261 | 260 | ||
| 262 | return retval; | 261 | return retval; |
| 263 | } | 262 | } |
| 264 | #endif | ||
| 265 | 263 | ||
| 266 | static SIMPLE_DEV_PM_OPS(gp2a_pm, gp2a_suspend, gp2a_resume); | 264 | static SIMPLE_DEV_PM_OPS(gp2a_pm, gp2a_suspend, gp2a_resume); |
| 267 | 265 | ||
diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c index afed8e2b2f94..ac1fa5f44580 100644 --- a/drivers/input/misc/ims-pcu.c +++ b/drivers/input/misc/ims-pcu.c | |||
| @@ -1851,7 +1851,7 @@ static int ims_pcu_identify_type(struct ims_pcu *pcu, u8 *device_id) | |||
| 1851 | 1851 | ||
| 1852 | static int ims_pcu_init_application_mode(struct ims_pcu *pcu) | 1852 | static int ims_pcu_init_application_mode(struct ims_pcu *pcu) |
| 1853 | { | 1853 | { |
| 1854 | static atomic_t device_no = ATOMIC_INIT(0); | 1854 | static atomic_t device_no = ATOMIC_INIT(-1); |
| 1855 | 1855 | ||
| 1856 | const struct ims_pcu_device_info *info; | 1856 | const struct ims_pcu_device_info *info; |
| 1857 | int error; | 1857 | int error; |
| @@ -1882,7 +1882,7 @@ static int ims_pcu_init_application_mode(struct ims_pcu *pcu) | |||
| 1882 | } | 1882 | } |
| 1883 | 1883 | ||
| 1884 | /* Device appears to be operable, complete initialization */ | 1884 | /* Device appears to be operable, complete initialization */ |
| 1885 | pcu->device_no = atomic_inc_return(&device_no) - 1; | 1885 | pcu->device_no = atomic_inc_return(&device_no); |
| 1886 | 1886 | ||
| 1887 | /* | 1887 | /* |
| 1888 | * PCU-B devices, both GEN_1 and GEN_2 do not have OFN sensor | 1888 | * PCU-B devices, both GEN_1 and GEN_2 do not have OFN sensor |
diff --git a/drivers/input/misc/kxtj9.c b/drivers/input/misc/kxtj9.c index d708478bc5b5..6e29349da537 100644 --- a/drivers/input/misc/kxtj9.c +++ b/drivers/input/misc/kxtj9.c | |||
| @@ -615,8 +615,7 @@ static int kxtj9_remove(struct i2c_client *client) | |||
| 615 | return 0; | 615 | return 0; |
| 616 | } | 616 | } |
| 617 | 617 | ||
| 618 | #ifdef CONFIG_PM_SLEEP | 618 | static int __maybe_unused kxtj9_suspend(struct device *dev) |
| 619 | static int kxtj9_suspend(struct device *dev) | ||
| 620 | { | 619 | { |
| 621 | struct i2c_client *client = to_i2c_client(dev); | 620 | struct i2c_client *client = to_i2c_client(dev); |
| 622 | struct kxtj9_data *tj9 = i2c_get_clientdata(client); | 621 | struct kxtj9_data *tj9 = i2c_get_clientdata(client); |
| @@ -631,7 +630,7 @@ static int kxtj9_suspend(struct device *dev) | |||
| 631 | return 0; | 630 | return 0; |
| 632 | } | 631 | } |
| 633 | 632 | ||
| 634 | static int kxtj9_resume(struct device *dev) | 633 | static int __maybe_unused kxtj9_resume(struct device *dev) |
| 635 | { | 634 | { |
| 636 | struct i2c_client *client = to_i2c_client(dev); | 635 | struct i2c_client *client = to_i2c_client(dev); |
| 637 | struct kxtj9_data *tj9 = i2c_get_clientdata(client); | 636 | struct kxtj9_data *tj9 = i2c_get_clientdata(client); |
| @@ -646,7 +645,6 @@ static int kxtj9_resume(struct device *dev) | |||
| 646 | mutex_unlock(&input_dev->mutex); | 645 | mutex_unlock(&input_dev->mutex); |
| 647 | return retval; | 646 | return retval; |
| 648 | } | 647 | } |
| 649 | #endif | ||
| 650 | 648 | ||
| 651 | static SIMPLE_DEV_PM_OPS(kxtj9_pm_ops, kxtj9_suspend, kxtj9_resume); | 649 | static SIMPLE_DEV_PM_OPS(kxtj9_pm_ops, kxtj9_suspend, kxtj9_resume); |
| 652 | 650 | ||
diff --git a/drivers/input/misc/max77693-haptic.c b/drivers/input/misc/max77693-haptic.c index 034093ee63bc..39e930c10ebb 100644 --- a/drivers/input/misc/max77693-haptic.c +++ b/drivers/input/misc/max77693-haptic.c | |||
| @@ -309,8 +309,7 @@ static int max77693_haptic_probe(struct platform_device *pdev) | |||
| 309 | return 0; | 309 | return 0; |
| 310 | } | 310 | } |
| 311 | 311 | ||
| 312 | #ifdef CONFIG_PM_SLEEP | 312 | static int __maybe_unused max77693_haptic_suspend(struct device *dev) |
| 313 | static int max77693_haptic_suspend(struct device *dev) | ||
| 314 | { | 313 | { |
| 315 | struct platform_device *pdev = to_platform_device(dev); | 314 | struct platform_device *pdev = to_platform_device(dev); |
| 316 | struct max77693_haptic *haptic = platform_get_drvdata(pdev); | 315 | struct max77693_haptic *haptic = platform_get_drvdata(pdev); |
| @@ -323,7 +322,7 @@ static int max77693_haptic_suspend(struct device *dev) | |||
| 323 | return 0; | 322 | return 0; |
| 324 | } | 323 | } |
| 325 | 324 | ||
| 326 | static int max77693_haptic_resume(struct device *dev) | 325 | static int __maybe_unused max77693_haptic_resume(struct device *dev) |
| 327 | { | 326 | { |
| 328 | struct platform_device *pdev = to_platform_device(dev); | 327 | struct platform_device *pdev = to_platform_device(dev); |
| 329 | struct max77693_haptic *haptic = platform_get_drvdata(pdev); | 328 | struct max77693_haptic *haptic = platform_get_drvdata(pdev); |
| @@ -335,7 +334,6 @@ static int max77693_haptic_resume(struct device *dev) | |||
| 335 | 334 | ||
| 336 | return 0; | 335 | return 0; |
| 337 | } | 336 | } |
| 338 | #endif | ||
| 339 | 337 | ||
| 340 | static SIMPLE_DEV_PM_OPS(max77693_haptic_pm_ops, | 338 | static SIMPLE_DEV_PM_OPS(max77693_haptic_pm_ops, |
| 341 | max77693_haptic_suspend, max77693_haptic_resume); | 339 | max77693_haptic_suspend, max77693_haptic_resume); |
diff --git a/drivers/input/misc/max8925_onkey.c b/drivers/input/misc/max8925_onkey.c index 297e2a9169d5..7c49b8d23894 100644 --- a/drivers/input/misc/max8925_onkey.c +++ b/drivers/input/misc/max8925_onkey.c | |||
| @@ -133,8 +133,7 @@ static int max8925_onkey_probe(struct platform_device *pdev) | |||
| 133 | return 0; | 133 | return 0; |
| 134 | } | 134 | } |
| 135 | 135 | ||
| 136 | #ifdef CONFIG_PM_SLEEP | 136 | static int __maybe_unused max8925_onkey_suspend(struct device *dev) |
| 137 | static int max8925_onkey_suspend(struct device *dev) | ||
| 138 | { | 137 | { |
| 139 | struct platform_device *pdev = to_platform_device(dev); | 138 | struct platform_device *pdev = to_platform_device(dev); |
| 140 | struct max8925_onkey_info *info = platform_get_drvdata(pdev); | 139 | struct max8925_onkey_info *info = platform_get_drvdata(pdev); |
| @@ -148,7 +147,7 @@ static int max8925_onkey_suspend(struct device *dev) | |||
| 148 | return 0; | 147 | return 0; |
| 149 | } | 148 | } |
| 150 | 149 | ||
| 151 | static int max8925_onkey_resume(struct device *dev) | 150 | static int __maybe_unused max8925_onkey_resume(struct device *dev) |
| 152 | { | 151 | { |
| 153 | struct platform_device *pdev = to_platform_device(dev); | 152 | struct platform_device *pdev = to_platform_device(dev); |
| 154 | struct max8925_onkey_info *info = platform_get_drvdata(pdev); | 153 | struct max8925_onkey_info *info = platform_get_drvdata(pdev); |
| @@ -161,7 +160,6 @@ static int max8925_onkey_resume(struct device *dev) | |||
| 161 | 160 | ||
| 162 | return 0; | 161 | return 0; |
| 163 | } | 162 | } |
| 164 | #endif | ||
| 165 | 163 | ||
| 166 | static SIMPLE_DEV_PM_OPS(max8925_onkey_pm_ops, max8925_onkey_suspend, max8925_onkey_resume); | 164 | static SIMPLE_DEV_PM_OPS(max8925_onkey_pm_ops, max8925_onkey_suspend, max8925_onkey_resume); |
| 167 | 165 | ||
diff --git a/drivers/input/misc/max8997_haptic.c b/drivers/input/misc/max8997_haptic.c index 5b3154edf822..d0f687281339 100644 --- a/drivers/input/misc/max8997_haptic.c +++ b/drivers/input/misc/max8997_haptic.c | |||
| @@ -378,8 +378,7 @@ static int max8997_haptic_remove(struct platform_device *pdev) | |||
| 378 | return 0; | 378 | return 0; |
| 379 | } | 379 | } |
| 380 | 380 | ||
| 381 | #ifdef CONFIG_PM_SLEEP | 381 | static int __maybe_unused max8997_haptic_suspend(struct device *dev) |
| 382 | static int max8997_haptic_suspend(struct device *dev) | ||
| 383 | { | 382 | { |
| 384 | struct platform_device *pdev = to_platform_device(dev); | 383 | struct platform_device *pdev = to_platform_device(dev); |
| 385 | struct max8997_haptic *chip = platform_get_drvdata(pdev); | 384 | struct max8997_haptic *chip = platform_get_drvdata(pdev); |
| @@ -388,7 +387,6 @@ static int max8997_haptic_suspend(struct device *dev) | |||
| 388 | 387 | ||
| 389 | return 0; | 388 | return 0; |
| 390 | } | 389 | } |
| 391 | #endif | ||
| 392 | 390 | ||
| 393 | static SIMPLE_DEV_PM_OPS(max8997_haptic_pm_ops, max8997_haptic_suspend, NULL); | 391 | static SIMPLE_DEV_PM_OPS(max8997_haptic_pm_ops, max8997_haptic_suspend, NULL); |
| 394 | 392 | ||
diff --git a/drivers/input/misc/palmas-pwrbutton.c b/drivers/input/misc/palmas-pwrbutton.c index 066c5ab632c8..1f9b5ee92746 100644 --- a/drivers/input/misc/palmas-pwrbutton.c +++ b/drivers/input/misc/palmas-pwrbutton.c | |||
| @@ -260,7 +260,6 @@ static int palmas_pwron_remove(struct platform_device *pdev) | |||
| 260 | return 0; | 260 | return 0; |
| 261 | } | 261 | } |
| 262 | 262 | ||
| 263 | #ifdef CONFIG_PM_SLEEP | ||
| 264 | /** | 263 | /** |
| 265 | * palmas_pwron_suspend() - suspend handler | 264 | * palmas_pwron_suspend() - suspend handler |
| 266 | * @dev: power button device | 265 | * @dev: power button device |
| @@ -269,7 +268,7 @@ static int palmas_pwron_remove(struct platform_device *pdev) | |||
| 269 | * | 268 | * |
| 270 | * Return: 0 | 269 | * Return: 0 |
| 271 | */ | 270 | */ |
| 272 | static int palmas_pwron_suspend(struct device *dev) | 271 | static int __maybe_unused palmas_pwron_suspend(struct device *dev) |
| 273 | { | 272 | { |
| 274 | struct platform_device *pdev = to_platform_device(dev); | 273 | struct platform_device *pdev = to_platform_device(dev); |
| 275 | struct palmas_pwron *pwron = platform_get_drvdata(pdev); | 274 | struct palmas_pwron *pwron = platform_get_drvdata(pdev); |
| @@ -290,7 +289,7 @@ static int palmas_pwron_suspend(struct device *dev) | |||
| 290 | * | 289 | * |
| 291 | * Return: 0 | 290 | * Return: 0 |
| 292 | */ | 291 | */ |
| 293 | static int palmas_pwron_resume(struct device *dev) | 292 | static int __maybe_unused palmas_pwron_resume(struct device *dev) |
| 294 | { | 293 | { |
| 295 | struct platform_device *pdev = to_platform_device(dev); | 294 | struct platform_device *pdev = to_platform_device(dev); |
| 296 | struct palmas_pwron *pwron = platform_get_drvdata(pdev); | 295 | struct palmas_pwron *pwron = platform_get_drvdata(pdev); |
| @@ -300,7 +299,6 @@ static int palmas_pwron_resume(struct device *dev) | |||
| 300 | 299 | ||
| 301 | return 0; | 300 | return 0; |
| 302 | } | 301 | } |
| 303 | #endif | ||
| 304 | 302 | ||
| 305 | static SIMPLE_DEV_PM_OPS(palmas_pwron_pm, | 303 | static SIMPLE_DEV_PM_OPS(palmas_pwron_pm, |
| 306 | palmas_pwron_suspend, palmas_pwron_resume); | 304 | palmas_pwron_suspend, palmas_pwron_resume); |
diff --git a/drivers/input/misc/pm8xxx-vibrator.c b/drivers/input/misc/pm8xxx-vibrator.c index e9c77a95717e..5113877153d7 100644 --- a/drivers/input/misc/pm8xxx-vibrator.c +++ b/drivers/input/misc/pm8xxx-vibrator.c | |||
| @@ -199,8 +199,7 @@ static int pm8xxx_vib_probe(struct platform_device *pdev) | |||
| 199 | return 0; | 199 | return 0; |
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | #ifdef CONFIG_PM_SLEEP | 202 | static int __maybe_unused pm8xxx_vib_suspend(struct device *dev) |
| 203 | static int pm8xxx_vib_suspend(struct device *dev) | ||
| 204 | { | 203 | { |
| 205 | struct pm8xxx_vib *vib = dev_get_drvdata(dev); | 204 | struct pm8xxx_vib *vib = dev_get_drvdata(dev); |
| 206 | 205 | ||
| @@ -209,7 +208,6 @@ static int pm8xxx_vib_suspend(struct device *dev) | |||
| 209 | 208 | ||
| 210 | return 0; | 209 | return 0; |
| 211 | } | 210 | } |
| 212 | #endif | ||
| 213 | 211 | ||
| 214 | static SIMPLE_DEV_PM_OPS(pm8xxx_vib_pm_ops, pm8xxx_vib_suspend, NULL); | 212 | static SIMPLE_DEV_PM_OPS(pm8xxx_vib_pm_ops, pm8xxx_vib_suspend, NULL); |
| 215 | 213 | ||
diff --git a/drivers/input/misc/pmic8xxx-pwrkey.c b/drivers/input/misc/pmic8xxx-pwrkey.c index cb799177cbd5..c4ca20e63221 100644 --- a/drivers/input/misc/pmic8xxx-pwrkey.c +++ b/drivers/input/misc/pmic8xxx-pwrkey.c | |||
| @@ -53,8 +53,7 @@ static irqreturn_t pwrkey_release_irq(int irq, void *_pwr) | |||
| 53 | return IRQ_HANDLED; | 53 | return IRQ_HANDLED; |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | #ifdef CONFIG_PM_SLEEP | 56 | static int __maybe_unused pmic8xxx_pwrkey_suspend(struct device *dev) |
| 57 | static int pmic8xxx_pwrkey_suspend(struct device *dev) | ||
| 58 | { | 57 | { |
| 59 | struct pmic8xxx_pwrkey *pwrkey = dev_get_drvdata(dev); | 58 | struct pmic8xxx_pwrkey *pwrkey = dev_get_drvdata(dev); |
| 60 | 59 | ||
| @@ -64,7 +63,7 @@ static int pmic8xxx_pwrkey_suspend(struct device *dev) | |||
| 64 | return 0; | 63 | return 0; |
| 65 | } | 64 | } |
| 66 | 65 | ||
| 67 | static int pmic8xxx_pwrkey_resume(struct device *dev) | 66 | static int __maybe_unused pmic8xxx_pwrkey_resume(struct device *dev) |
| 68 | { | 67 | { |
| 69 | struct pmic8xxx_pwrkey *pwrkey = dev_get_drvdata(dev); | 68 | struct pmic8xxx_pwrkey *pwrkey = dev_get_drvdata(dev); |
| 70 | 69 | ||
| @@ -73,7 +72,6 @@ static int pmic8xxx_pwrkey_resume(struct device *dev) | |||
| 73 | 72 | ||
| 74 | return 0; | 73 | return 0; |
| 75 | } | 74 | } |
| 76 | #endif | ||
| 77 | 75 | ||
| 78 | static SIMPLE_DEV_PM_OPS(pm8xxx_pwr_key_pm_ops, | 76 | static SIMPLE_DEV_PM_OPS(pm8xxx_pwr_key_pm_ops, |
| 79 | pmic8xxx_pwrkey_suspend, pmic8xxx_pwrkey_resume); | 77 | pmic8xxx_pwrkey_suspend, pmic8xxx_pwrkey_resume); |
diff --git a/drivers/input/misc/pwm-beeper.c b/drivers/input/misc/pwm-beeper.c index 294aa48bad50..a28ee70ff158 100644 --- a/drivers/input/misc/pwm-beeper.c +++ b/drivers/input/misc/pwm-beeper.c | |||
| @@ -144,8 +144,7 @@ static int pwm_beeper_remove(struct platform_device *pdev) | |||
| 144 | return 0; | 144 | return 0; |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | #ifdef CONFIG_PM_SLEEP | 147 | static int __maybe_unused pwm_beeper_suspend(struct device *dev) |
| 148 | static int pwm_beeper_suspend(struct device *dev) | ||
| 149 | { | 148 | { |
| 150 | struct pwm_beeper *beeper = dev_get_drvdata(dev); | 149 | struct pwm_beeper *beeper = dev_get_drvdata(dev); |
| 151 | 150 | ||
| @@ -155,7 +154,7 @@ static int pwm_beeper_suspend(struct device *dev) | |||
| 155 | return 0; | 154 | return 0; |
| 156 | } | 155 | } |
| 157 | 156 | ||
| 158 | static int pwm_beeper_resume(struct device *dev) | 157 | static int __maybe_unused pwm_beeper_resume(struct device *dev) |
| 159 | { | 158 | { |
| 160 | struct pwm_beeper *beeper = dev_get_drvdata(dev); | 159 | struct pwm_beeper *beeper = dev_get_drvdata(dev); |
| 161 | 160 | ||
| @@ -170,6 +169,7 @@ static int pwm_beeper_resume(struct device *dev) | |||
| 170 | static SIMPLE_DEV_PM_OPS(pwm_beeper_pm_ops, | 169 | static SIMPLE_DEV_PM_OPS(pwm_beeper_pm_ops, |
| 171 | pwm_beeper_suspend, pwm_beeper_resume); | 170 | pwm_beeper_suspend, pwm_beeper_resume); |
| 172 | 171 | ||
| 172 | #ifdef CONFIG_PM_SLEEP | ||
| 173 | #define PWM_BEEPER_PM_OPS (&pwm_beeper_pm_ops) | 173 | #define PWM_BEEPER_PM_OPS (&pwm_beeper_pm_ops) |
| 174 | #else | 174 | #else |
| 175 | #define PWM_BEEPER_PM_OPS NULL | 175 | #define PWM_BEEPER_PM_OPS NULL |
diff --git a/drivers/input/misc/sirfsoc-onkey.c b/drivers/input/misc/sirfsoc-onkey.c index 4faf9f8d1240..9d5b89befe6f 100644 --- a/drivers/input/misc/sirfsoc-onkey.c +++ b/drivers/input/misc/sirfsoc-onkey.c | |||
| @@ -179,8 +179,7 @@ static int sirfsoc_pwrc_remove(struct platform_device *pdev) | |||
| 179 | return 0; | 179 | return 0; |
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | #ifdef CONFIG_PM_SLEEP | 182 | static int __maybe_unused sirfsoc_pwrc_resume(struct device *dev) |
| 183 | static int sirfsoc_pwrc_resume(struct device *dev) | ||
| 184 | { | 183 | { |
| 185 | struct sirfsoc_pwrc_drvdata *pwrcdrv = dev_get_drvdata(dev); | 184 | struct sirfsoc_pwrc_drvdata *pwrcdrv = dev_get_drvdata(dev); |
| 186 | struct input_dev *input = pwrcdrv->input; | 185 | struct input_dev *input = pwrcdrv->input; |
| @@ -196,7 +195,6 @@ static int sirfsoc_pwrc_resume(struct device *dev) | |||
| 196 | 195 | ||
| 197 | return 0; | 196 | return 0; |
| 198 | } | 197 | } |
| 199 | #endif | ||
| 200 | 198 | ||
| 201 | static SIMPLE_DEV_PM_OPS(sirfsoc_pwrc_pm_ops, NULL, sirfsoc_pwrc_resume); | 199 | static SIMPLE_DEV_PM_OPS(sirfsoc_pwrc_pm_ops, NULL, sirfsoc_pwrc_resume); |
| 202 | 200 | ||
diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c index ccd6dd18f8f6..fc17b9592f54 100644 --- a/drivers/input/misc/twl4030-vibra.c +++ b/drivers/input/misc/twl4030-vibra.c | |||
| @@ -157,8 +157,7 @@ static void twl4030_vibra_close(struct input_dev *input) | |||
| 157 | } | 157 | } |
| 158 | 158 | ||
| 159 | /*** Module ***/ | 159 | /*** Module ***/ |
| 160 | #ifdef CONFIG_PM_SLEEP | 160 | static int __maybe_unused twl4030_vibra_suspend(struct device *dev) |
| 161 | static int twl4030_vibra_suspend(struct device *dev) | ||
| 162 | { | 161 | { |
| 163 | struct platform_device *pdev = to_platform_device(dev); | 162 | struct platform_device *pdev = to_platform_device(dev); |
| 164 | struct vibra_info *info = platform_get_drvdata(pdev); | 163 | struct vibra_info *info = platform_get_drvdata(pdev); |
| @@ -169,12 +168,11 @@ static int twl4030_vibra_suspend(struct device *dev) | |||
| 169 | return 0; | 168 | return 0; |
| 170 | } | 169 | } |
| 171 | 170 | ||
| 172 | static int twl4030_vibra_resume(struct device *dev) | 171 | static int __maybe_unused twl4030_vibra_resume(struct device *dev) |
| 173 | { | 172 | { |
| 174 | vibra_disable_leds(); | 173 | vibra_disable_leds(); |
| 175 | return 0; | 174 | return 0; |
| 176 | } | 175 | } |
| 177 | #endif | ||
| 178 | 176 | ||
| 179 | static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops, | 177 | static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops, |
| 180 | twl4030_vibra_suspend, twl4030_vibra_resume); | 178 | twl4030_vibra_suspend, twl4030_vibra_resume); |
diff --git a/drivers/input/misc/twl6040-vibra.c b/drivers/input/misc/twl6040-vibra.c index 96e0e0c0ccb1..0e0d094df2e6 100644 --- a/drivers/input/misc/twl6040-vibra.c +++ b/drivers/input/misc/twl6040-vibra.c | |||
| @@ -236,8 +236,7 @@ static void twl6040_vibra_close(struct input_dev *input) | |||
| 236 | mutex_unlock(&info->mutex); | 236 | mutex_unlock(&info->mutex); |
| 237 | } | 237 | } |
| 238 | 238 | ||
| 239 | #ifdef CONFIG_PM_SLEEP | 239 | static int __maybe_unused twl6040_vibra_suspend(struct device *dev) |
| 240 | static int twl6040_vibra_suspend(struct device *dev) | ||
| 241 | { | 240 | { |
| 242 | struct platform_device *pdev = to_platform_device(dev); | 241 | struct platform_device *pdev = to_platform_device(dev); |
| 243 | struct vibra_info *info = platform_get_drvdata(pdev); | 242 | struct vibra_info *info = platform_get_drvdata(pdev); |
| @@ -251,7 +250,6 @@ static int twl6040_vibra_suspend(struct device *dev) | |||
| 251 | 250 | ||
| 252 | return 0; | 251 | return 0; |
| 253 | } | 252 | } |
| 254 | #endif | ||
| 255 | 253 | ||
| 256 | static SIMPLE_DEV_PM_OPS(twl6040_vibra_pm_ops, twl6040_vibra_suspend, NULL); | 254 | static SIMPLE_DEV_PM_OPS(twl6040_vibra_pm_ops, twl6040_vibra_suspend, NULL); |
| 257 | 255 | ||
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index 366fc7ad5eb6..d8b46b0f2dbe 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig | |||
| @@ -215,6 +215,36 @@ config MOUSE_CYAPA | |||
| 215 | To compile this driver as a module, choose M here: the module will be | 215 | To compile this driver as a module, choose M here: the module will be |
| 216 | called cyapa. | 216 | called cyapa. |
| 217 | 217 | ||
| 218 | config MOUSE_ELAN_I2C | ||
| 219 | tristate "ELAN I2C Touchpad support" | ||
| 220 | depends on I2C | ||
| 221 | help | ||
| 222 | This driver adds support for Elan I2C/SMbus Trackpads. | ||
| 223 | |||
| 224 | Say Y here if you have a ELAN I2C/SMbus Touchpad. | ||
| 225 | |||
| 226 | To compile this driver as a module, choose M here: the module will be | ||
| 227 | called elan_i2c. | ||
| 228 | |||
| 229 | config MOUSE_ELAN_I2C_I2C | ||
| 230 | bool "Enable I2C support" | ||
| 231 | depends on MOUSE_ELAN_I2C | ||
| 232 | default y | ||
| 233 | help | ||
| 234 | Say Y here if Elan Touchpad in your system is connected to | ||
| 235 | a standard I2C controller. | ||
| 236 | |||
| 237 | If unsure, say Y. | ||
| 238 | |||
| 239 | config MOUSE_ELAN_I2C_SMBUS | ||
| 240 | bool "Enable SMbus support" | ||
| 241 | depends on MOUSE_ELAN_I2C | ||
| 242 | help | ||
| 243 | Say Y here if Elan Touchpad in your system is connected to | ||
| 244 | a SMbus adapter. | ||
| 245 | |||
| 246 | If unsure, say Y. | ||
| 247 | |||
| 218 | config MOUSE_INPORT | 248 | config MOUSE_INPORT |
| 219 | tristate "InPort/MS/ATIXL busmouse" | 249 | tristate "InPort/MS/ATIXL busmouse" |
| 220 | depends on ISA | 250 | depends on ISA |
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile index dda507f8b3a2..560003dcac37 100644 --- a/drivers/input/mouse/Makefile +++ b/drivers/input/mouse/Makefile | |||
| @@ -9,6 +9,7 @@ obj-$(CONFIG_MOUSE_APPLETOUCH) += appletouch.o | |||
| 9 | obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o | 9 | obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o |
| 10 | obj-$(CONFIG_MOUSE_BCM5974) += bcm5974.o | 10 | obj-$(CONFIG_MOUSE_BCM5974) += bcm5974.o |
| 11 | obj-$(CONFIG_MOUSE_CYAPA) += cyapa.o | 11 | obj-$(CONFIG_MOUSE_CYAPA) += cyapa.o |
| 12 | obj-$(CONFIG_MOUSE_ELAN_I2C) += elan_i2c.o | ||
| 12 | obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o | 13 | obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o |
| 13 | obj-$(CONFIG_MOUSE_INPORT) += inport.o | 14 | obj-$(CONFIG_MOUSE_INPORT) += inport.o |
| 14 | obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o | 15 | obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o |
| @@ -34,3 +35,7 @@ psmouse-$(CONFIG_MOUSE_PS2_SENTELIC) += sentelic.o | |||
| 34 | psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o | 35 | psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o |
| 35 | psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT) += touchkit_ps2.o | 36 | psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT) += touchkit_ps2.o |
| 36 | psmouse-$(CONFIG_MOUSE_PS2_CYPRESS) += cypress_ps2.o | 37 | psmouse-$(CONFIG_MOUSE_PS2_CYPRESS) += cypress_ps2.o |
| 38 | |||
| 39 | elan_i2c-objs := elan_i2c_core.o | ||
| 40 | elan_i2c-$(CONFIG_MOUSE_ELAN_I2C_I2C) += elan_i2c_i2c.o | ||
| 41 | elan_i2c-$(CONFIG_MOUSE_ELAN_I2C_SMBUS) += elan_i2c_smbus.o | ||
diff --git a/drivers/input/mouse/cyapa.c b/drivers/input/mouse/cyapa.c index b409c3d7d4fb..1bece8cad46f 100644 --- a/drivers/input/mouse/cyapa.c +++ b/drivers/input/mouse/cyapa.c | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | * Daniel Kurtz <djkurtz@chromium.org> | 6 | * Daniel Kurtz <djkurtz@chromium.org> |
| 7 | * Benson Leung <bleung@chromium.org> | 7 | * Benson Leung <bleung@chromium.org> |
| 8 | * | 8 | * |
| 9 | * Copyright (C) 2011-2012 Cypress Semiconductor, Inc. | 9 | * Copyright (C) 2011-2014 Cypress Semiconductor, Inc. |
| 10 | * Copyright (C) 2011-2012 Google, Inc. | 10 | * Copyright (C) 2011-2012 Google, Inc. |
| 11 | * | 11 | * |
| 12 | * This file is subject to the terms and conditions of the GNU General Public | 12 | * This file is subject to the terms and conditions of the GNU General Public |
| @@ -206,7 +206,6 @@ struct cyapa { | |||
| 206 | struct i2c_client *client; | 206 | struct i2c_client *client; |
| 207 | struct input_dev *input; | 207 | struct input_dev *input; |
| 208 | char phys[32]; /* device physical location */ | 208 | char phys[32]; /* device physical location */ |
| 209 | int irq; | ||
| 210 | bool irq_wake; /* irq wake is enabled */ | 209 | bool irq_wake; /* irq wake is enabled */ |
| 211 | bool smbus; | 210 | bool smbus; |
| 212 | 211 | ||
| @@ -422,8 +421,8 @@ static ssize_t cyapa_read_block(struct cyapa *cyapa, u8 cmd_idx, u8 *values) | |||
| 422 | */ | 421 | */ |
| 423 | static int cyapa_get_state(struct cyapa *cyapa) | 422 | static int cyapa_get_state(struct cyapa *cyapa) |
| 424 | { | 423 | { |
| 425 | int ret; | ||
| 426 | u8 status[BL_STATUS_SIZE]; | 424 | u8 status[BL_STATUS_SIZE]; |
| 425 | int error; | ||
| 427 | 426 | ||
| 428 | cyapa->state = CYAPA_STATE_NO_DEVICE; | 427 | cyapa->state = CYAPA_STATE_NO_DEVICE; |
| 429 | 428 | ||
| @@ -433,18 +432,18 @@ static int cyapa_get_state(struct cyapa *cyapa) | |||
| 433 | * If the device is in operation mode, this will be the DATA regs. | 432 | * If the device is in operation mode, this will be the DATA regs. |
| 434 | * | 433 | * |
| 435 | */ | 434 | */ |
| 436 | ret = cyapa_i2c_reg_read_block(cyapa, BL_HEAD_OFFSET, BL_STATUS_SIZE, | 435 | error = cyapa_i2c_reg_read_block(cyapa, BL_HEAD_OFFSET, BL_STATUS_SIZE, |
| 437 | status); | 436 | status); |
| 438 | 437 | ||
| 439 | /* | 438 | /* |
| 440 | * On smbus systems in OP mode, the i2c_reg_read will fail with | 439 | * On smbus systems in OP mode, the i2c_reg_read will fail with |
| 441 | * -ETIMEDOUT. In this case, try again using the smbus equivalent | 440 | * -ETIMEDOUT. In this case, try again using the smbus equivalent |
| 442 | * command. This should return a BL_HEAD indicating CYAPA_STATE_OP. | 441 | * command. This should return a BL_HEAD indicating CYAPA_STATE_OP. |
| 443 | */ | 442 | */ |
| 444 | if (cyapa->smbus && (ret == -ETIMEDOUT || ret == -ENXIO)) | 443 | if (cyapa->smbus && (error == -ETIMEDOUT || error == -ENXIO)) |
| 445 | ret = cyapa_read_block(cyapa, CYAPA_CMD_BL_STATUS, status); | 444 | error = cyapa_read_block(cyapa, CYAPA_CMD_BL_STATUS, status); |
| 446 | 445 | ||
| 447 | if (ret != BL_STATUS_SIZE) | 446 | if (error != BL_STATUS_SIZE) |
| 448 | goto error; | 447 | goto error; |
| 449 | 448 | ||
| 450 | if ((status[REG_OP_STATUS] & OP_STATUS_SRC) == OP_STATUS_SRC) { | 449 | if ((status[REG_OP_STATUS] & OP_STATUS_SRC) == OP_STATUS_SRC) { |
| @@ -454,7 +453,7 @@ static int cyapa_get_state(struct cyapa *cyapa) | |||
| 454 | cyapa->state = CYAPA_STATE_OP; | 453 | cyapa->state = CYAPA_STATE_OP; |
| 455 | break; | 454 | break; |
| 456 | default: | 455 | default: |
| 457 | ret = -EAGAIN; | 456 | error = -EAGAIN; |
| 458 | goto error; | 457 | goto error; |
| 459 | } | 458 | } |
| 460 | } else { | 459 | } else { |
| @@ -468,7 +467,7 @@ static int cyapa_get_state(struct cyapa *cyapa) | |||
| 468 | 467 | ||
| 469 | return 0; | 468 | return 0; |
| 470 | error: | 469 | error: |
| 471 | return (ret < 0) ? ret : -EAGAIN; | 470 | return (error < 0) ? error : -EAGAIN; |
| 472 | } | 471 | } |
| 473 | 472 | ||
| 474 | /* | 473 | /* |
| @@ -487,31 +486,31 @@ error: | |||
| 487 | */ | 486 | */ |
| 488 | static int cyapa_poll_state(struct cyapa *cyapa, unsigned int timeout) | 487 | static int cyapa_poll_state(struct cyapa *cyapa, unsigned int timeout) |
| 489 | { | 488 | { |
| 490 | int ret; | 489 | int error; |
| 491 | int tries = timeout / 100; | 490 | int tries = timeout / 100; |
| 492 | 491 | ||
| 493 | ret = cyapa_get_state(cyapa); | 492 | error = cyapa_get_state(cyapa); |
| 494 | while ((ret || cyapa->state >= CYAPA_STATE_BL_BUSY) && tries--) { | 493 | while ((error || cyapa->state >= CYAPA_STATE_BL_BUSY) && tries--) { |
| 495 | msleep(100); | 494 | msleep(100); |
| 496 | ret = cyapa_get_state(cyapa); | 495 | error = cyapa_get_state(cyapa); |
| 497 | } | 496 | } |
| 498 | return (ret == -EAGAIN || ret == -ETIMEDOUT) ? -ETIMEDOUT : ret; | 497 | return (error == -EAGAIN || error == -ETIMEDOUT) ? -ETIMEDOUT : error; |
| 499 | } | 498 | } |
| 500 | 499 | ||
| 501 | static int cyapa_bl_deactivate(struct cyapa *cyapa) | 500 | static int cyapa_bl_deactivate(struct cyapa *cyapa) |
| 502 | { | 501 | { |
| 503 | int ret; | 502 | int error; |
| 504 | 503 | ||
| 505 | ret = cyapa_i2c_reg_write_block(cyapa, 0, sizeof(bl_deactivate), | 504 | error = cyapa_i2c_reg_write_block(cyapa, 0, sizeof(bl_deactivate), |
| 506 | bl_deactivate); | 505 | bl_deactivate); |
| 507 | if (ret < 0) | 506 | if (error) |
| 508 | return ret; | 507 | return error; |
| 509 | 508 | ||
| 510 | /* wait for bootloader to switch to idle state; should take < 100ms */ | 509 | /* wait for bootloader to switch to idle state; should take < 100ms */ |
| 511 | msleep(100); | 510 | msleep(100); |
| 512 | ret = cyapa_poll_state(cyapa, 500); | 511 | error = cyapa_poll_state(cyapa, 500); |
| 513 | if (ret < 0) | 512 | if (error) |
| 514 | return ret; | 513 | return error; |
| 515 | if (cyapa->state != CYAPA_STATE_BL_IDLE) | 514 | if (cyapa->state != CYAPA_STATE_BL_IDLE) |
| 516 | return -EAGAIN; | 515 | return -EAGAIN; |
| 517 | return 0; | 516 | return 0; |
| @@ -532,11 +531,11 @@ static int cyapa_bl_deactivate(struct cyapa *cyapa) | |||
| 532 | */ | 531 | */ |
| 533 | static int cyapa_bl_exit(struct cyapa *cyapa) | 532 | static int cyapa_bl_exit(struct cyapa *cyapa) |
| 534 | { | 533 | { |
| 535 | int ret; | 534 | int error; |
| 536 | 535 | ||
| 537 | ret = cyapa_i2c_reg_write_block(cyapa, 0, sizeof(bl_exit), bl_exit); | 536 | error = cyapa_i2c_reg_write_block(cyapa, 0, sizeof(bl_exit), bl_exit); |
| 538 | if (ret < 0) | 537 | if (error) |
| 539 | return ret; | 538 | return error; |
| 540 | 539 | ||
| 541 | /* | 540 | /* |
| 542 | * Wait for bootloader to exit, and operation mode to start. | 541 | * Wait for bootloader to exit, and operation mode to start. |
| @@ -548,9 +547,9 @@ static int cyapa_bl_exit(struct cyapa *cyapa) | |||
| 548 | * updated to new firmware, it must first calibrate its sensors, which | 547 | * updated to new firmware, it must first calibrate its sensors, which |
| 549 | * can take up to an additional 2 seconds. | 548 | * can take up to an additional 2 seconds. |
| 550 | */ | 549 | */ |
| 551 | ret = cyapa_poll_state(cyapa, 2000); | 550 | error = cyapa_poll_state(cyapa, 2000); |
| 552 | if (ret < 0) | 551 | if (error < 0) |
| 553 | return ret; | 552 | return error; |
| 554 | if (cyapa->state != CYAPA_STATE_OP) | 553 | if (cyapa->state != CYAPA_STATE_OP) |
| 555 | return -EAGAIN; | 554 | return -EAGAIN; |
| 556 | 555 | ||
| @@ -577,10 +576,13 @@ static int cyapa_set_power_mode(struct cyapa *cyapa, u8 power_mode) | |||
| 577 | power = ret & ~PWR_MODE_MASK; | 576 | power = ret & ~PWR_MODE_MASK; |
| 578 | power |= power_mode & PWR_MODE_MASK; | 577 | power |= power_mode & PWR_MODE_MASK; |
| 579 | ret = cyapa_write_byte(cyapa, CYAPA_CMD_POWER_MODE, power); | 578 | ret = cyapa_write_byte(cyapa, CYAPA_CMD_POWER_MODE, power); |
| 580 | if (ret < 0) | 579 | if (ret < 0) { |
| 581 | dev_err(dev, "failed to set power_mode 0x%02x err = %d\n", | 580 | dev_err(dev, "failed to set power_mode 0x%02x err = %d\n", |
| 582 | power_mode, ret); | 581 | power_mode, ret); |
| 583 | return ret; | 582 | return ret; |
| 583 | } | ||
| 584 | |||
| 585 | return 0; | ||
| 584 | } | 586 | } |
| 585 | 587 | ||
| 586 | static int cyapa_get_query_data(struct cyapa *cyapa) | 588 | static int cyapa_get_query_data(struct cyapa *cyapa) |
| @@ -637,28 +639,28 @@ static int cyapa_check_is_operational(struct cyapa *cyapa) | |||
| 637 | { | 639 | { |
| 638 | struct device *dev = &cyapa->client->dev; | 640 | struct device *dev = &cyapa->client->dev; |
| 639 | static const char unique_str[] = "CYTRA"; | 641 | static const char unique_str[] = "CYTRA"; |
| 640 | int ret; | 642 | int error; |
| 641 | 643 | ||
| 642 | ret = cyapa_poll_state(cyapa, 2000); | 644 | error = cyapa_poll_state(cyapa, 2000); |
| 643 | if (ret < 0) | 645 | if (error) |
| 644 | return ret; | 646 | return error; |
| 645 | switch (cyapa->state) { | 647 | switch (cyapa->state) { |
| 646 | case CYAPA_STATE_BL_ACTIVE: | 648 | case CYAPA_STATE_BL_ACTIVE: |
| 647 | ret = cyapa_bl_deactivate(cyapa); | 649 | error = cyapa_bl_deactivate(cyapa); |
| 648 | if (ret) | 650 | if (error) |
| 649 | return ret; | 651 | return error; |
| 650 | 652 | ||
| 651 | /* Fallthrough state */ | 653 | /* Fallthrough state */ |
| 652 | case CYAPA_STATE_BL_IDLE: | 654 | case CYAPA_STATE_BL_IDLE: |
| 653 | ret = cyapa_bl_exit(cyapa); | 655 | error = cyapa_bl_exit(cyapa); |
| 654 | if (ret) | 656 | if (error) |
| 655 | return ret; | 657 | return error; |
| 656 | 658 | ||
| 657 | /* Fallthrough state */ | 659 | /* Fallthrough state */ |
| 658 | case CYAPA_STATE_OP: | 660 | case CYAPA_STATE_OP: |
| 659 | ret = cyapa_get_query_data(cyapa); | 661 | error = cyapa_get_query_data(cyapa); |
| 660 | if (ret < 0) | 662 | if (error) |
| 661 | return ret; | 663 | return error; |
| 662 | 664 | ||
| 663 | /* only support firmware protocol gen3 */ | 665 | /* only support firmware protocol gen3 */ |
| 664 | if (cyapa->gen != CYAPA_GEN3) { | 666 | if (cyapa->gen != CYAPA_GEN3) { |
| @@ -753,18 +755,42 @@ static u8 cyapa_check_adapter_functionality(struct i2c_client *client) | |||
| 753 | return ret; | 755 | return ret; |
| 754 | } | 756 | } |
| 755 | 757 | ||
| 758 | static int cyapa_open(struct input_dev *input) | ||
| 759 | { | ||
| 760 | struct cyapa *cyapa = input_get_drvdata(input); | ||
| 761 | struct i2c_client *client = cyapa->client; | ||
| 762 | int error; | ||
| 763 | |||
| 764 | error = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE); | ||
| 765 | if (error) { | ||
| 766 | dev_err(&client->dev, "set active power failed: %d\n", error); | ||
| 767 | return error; | ||
| 768 | } | ||
| 769 | |||
| 770 | enable_irq(client->irq); | ||
| 771 | return 0; | ||
| 772 | } | ||
| 773 | |||
| 774 | static void cyapa_close(struct input_dev *input) | ||
| 775 | { | ||
| 776 | struct cyapa *cyapa = input_get_drvdata(input); | ||
| 777 | |||
| 778 | disable_irq(cyapa->client->irq); | ||
| 779 | cyapa_set_power_mode(cyapa, PWR_MODE_OFF); | ||
| 780 | } | ||
| 781 | |||
| 756 | static int cyapa_create_input_dev(struct cyapa *cyapa) | 782 | static int cyapa_create_input_dev(struct cyapa *cyapa) |
| 757 | { | 783 | { |
| 758 | struct device *dev = &cyapa->client->dev; | 784 | struct device *dev = &cyapa->client->dev; |
| 759 | int ret; | ||
| 760 | struct input_dev *input; | 785 | struct input_dev *input; |
| 786 | int error; | ||
| 761 | 787 | ||
| 762 | if (!cyapa->physical_size_x || !cyapa->physical_size_y) | 788 | if (!cyapa->physical_size_x || !cyapa->physical_size_y) |
| 763 | return -EINVAL; | 789 | return -EINVAL; |
| 764 | 790 | ||
| 765 | input = cyapa->input = input_allocate_device(); | 791 | input = devm_input_allocate_device(dev); |
| 766 | if (!input) { | 792 | if (!input) { |
| 767 | dev_err(dev, "allocate memory for input device failed\n"); | 793 | dev_err(dev, "failed to allocate memory for input device.\n"); |
| 768 | return -ENOMEM; | 794 | return -ENOMEM; |
| 769 | } | 795 | } |
| 770 | 796 | ||
| @@ -772,14 +798,17 @@ static int cyapa_create_input_dev(struct cyapa *cyapa) | |||
| 772 | input->phys = cyapa->phys; | 798 | input->phys = cyapa->phys; |
| 773 | input->id.bustype = BUS_I2C; | 799 | input->id.bustype = BUS_I2C; |
| 774 | input->id.version = 1; | 800 | input->id.version = 1; |
| 775 | input->id.product = 0; /* means any product in eventcomm. */ | 801 | input->id.product = 0; /* Means any product in eventcomm. */ |
| 776 | input->dev.parent = &cyapa->client->dev; | 802 | input->dev.parent = &cyapa->client->dev; |
| 777 | 803 | ||
| 804 | input->open = cyapa_open; | ||
| 805 | input->close = cyapa_close; | ||
| 806 | |||
| 778 | input_set_drvdata(input, cyapa); | 807 | input_set_drvdata(input, cyapa); |
| 779 | 808 | ||
| 780 | __set_bit(EV_ABS, input->evbit); | 809 | __set_bit(EV_ABS, input->evbit); |
| 781 | 810 | ||
| 782 | /* finger position */ | 811 | /* Finger position */ |
| 783 | input_set_abs_params(input, ABS_MT_POSITION_X, 0, cyapa->max_abs_x, 0, | 812 | input_set_abs_params(input, ABS_MT_POSITION_X, 0, cyapa->max_abs_x, 0, |
| 784 | 0); | 813 | 0); |
| 785 | input_set_abs_params(input, ABS_MT_POSITION_Y, 0, cyapa->max_abs_y, 0, | 814 | input_set_abs_params(input, ABS_MT_POSITION_Y, 0, cyapa->max_abs_y, 0, |
| @@ -801,35 +830,25 @@ static int cyapa_create_input_dev(struct cyapa *cyapa) | |||
| 801 | if (cyapa->btn_capability == CAPABILITY_LEFT_BTN_MASK) | 830 | if (cyapa->btn_capability == CAPABILITY_LEFT_BTN_MASK) |
| 802 | __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); | 831 | __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); |
| 803 | 832 | ||
| 804 | /* handle pointer emulation and unused slots in core */ | 833 | /* Handle pointer emulation and unused slots in core */ |
| 805 | ret = input_mt_init_slots(input, CYAPA_MAX_MT_SLOTS, | 834 | error = input_mt_init_slots(input, CYAPA_MAX_MT_SLOTS, |
| 806 | INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED); | 835 | INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED); |
| 807 | if (ret) { | 836 | if (error) { |
| 808 | dev_err(dev, "allocate memory for MT slots failed, %d\n", ret); | 837 | dev_err(dev, "failed to initialize MT slots: %d\n", error); |
| 809 | goto err_free_device; | 838 | return error; |
| 810 | } | 839 | } |
| 811 | 840 | ||
| 812 | /* Register the device in input subsystem */ | 841 | cyapa->input = input; |
| 813 | ret = input_register_device(input); | ||
| 814 | if (ret) { | ||
| 815 | dev_err(dev, "input device register failed, %d\n", ret); | ||
| 816 | goto err_free_device; | ||
| 817 | } | ||
| 818 | return 0; | 842 | return 0; |
| 819 | |||
| 820 | err_free_device: | ||
| 821 | input_free_device(input); | ||
| 822 | cyapa->input = NULL; | ||
| 823 | return ret; | ||
| 824 | } | 843 | } |
| 825 | 844 | ||
| 826 | static int cyapa_probe(struct i2c_client *client, | 845 | static int cyapa_probe(struct i2c_client *client, |
| 827 | const struct i2c_device_id *dev_id) | 846 | const struct i2c_device_id *dev_id) |
| 828 | { | 847 | { |
| 829 | int ret; | ||
| 830 | u8 adapter_func; | ||
| 831 | struct cyapa *cyapa; | ||
| 832 | struct device *dev = &client->dev; | 848 | struct device *dev = &client->dev; |
| 849 | struct cyapa *cyapa; | ||
| 850 | u8 adapter_func; | ||
| 851 | int error; | ||
| 833 | 852 | ||
| 834 | adapter_func = cyapa_check_adapter_functionality(client); | 853 | adapter_func = cyapa_check_adapter_functionality(client); |
| 835 | if (adapter_func == CYAPA_ADAPTER_FUNC_NONE) { | 854 | if (adapter_func == CYAPA_ADAPTER_FUNC_NONE) { |
| @@ -837,11 +856,9 @@ static int cyapa_probe(struct i2c_client *client, | |||
| 837 | return -EIO; | 856 | return -EIO; |
| 838 | } | 857 | } |
| 839 | 858 | ||
| 840 | cyapa = kzalloc(sizeof(struct cyapa), GFP_KERNEL); | 859 | cyapa = devm_kzalloc(dev, sizeof(struct cyapa), GFP_KERNEL); |
| 841 | if (!cyapa) { | 860 | if (!cyapa) |
| 842 | dev_err(dev, "allocate memory for cyapa failed\n"); | ||
| 843 | return -ENOMEM; | 861 | return -ENOMEM; |
| 844 | } | ||
| 845 | 862 | ||
| 846 | cyapa->gen = CYAPA_GEN3; | 863 | cyapa->gen = CYAPA_GEN3; |
| 847 | cyapa->client = client; | 864 | cyapa->client = client; |
| @@ -852,67 +869,61 @@ static int cyapa_probe(struct i2c_client *client, | |||
| 852 | /* i2c isn't supported, use smbus */ | 869 | /* i2c isn't supported, use smbus */ |
| 853 | if (adapter_func == CYAPA_ADAPTER_FUNC_SMBUS) | 870 | if (adapter_func == CYAPA_ADAPTER_FUNC_SMBUS) |
| 854 | cyapa->smbus = true; | 871 | cyapa->smbus = true; |
| 872 | |||
| 855 | cyapa->state = CYAPA_STATE_NO_DEVICE; | 873 | cyapa->state = CYAPA_STATE_NO_DEVICE; |
| 856 | ret = cyapa_check_is_operational(cyapa); | ||
| 857 | if (ret) { | ||
| 858 | dev_err(dev, "device not operational, %d\n", ret); | ||
| 859 | goto err_mem_free; | ||
| 860 | } | ||
| 861 | 874 | ||
| 862 | ret = cyapa_create_input_dev(cyapa); | 875 | error = cyapa_check_is_operational(cyapa); |
| 863 | if (ret) { | 876 | if (error) { |
| 864 | dev_err(dev, "create input_dev instance failed, %d\n", ret); | 877 | dev_err(dev, "device not operational, %d\n", error); |
| 865 | goto err_mem_free; | 878 | return error; |
| 866 | } | 879 | } |
| 867 | 880 | ||
| 868 | ret = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE); | 881 | /* Power down the device until we need it */ |
| 869 | if (ret) { | 882 | error = cyapa_set_power_mode(cyapa, PWR_MODE_OFF); |
| 870 | dev_err(dev, "set active power failed, %d\n", ret); | 883 | if (error) { |
| 871 | goto err_unregister_device; | 884 | dev_err(dev, "failed to quiesce the device: %d\n", error); |
| 885 | return error; | ||
| 872 | } | 886 | } |
| 873 | 887 | ||
| 874 | cyapa->irq = client->irq; | 888 | error = cyapa_create_input_dev(cyapa); |
| 875 | ret = request_threaded_irq(cyapa->irq, | 889 | if (error) |
| 876 | NULL, | 890 | return error; |
| 877 | cyapa_irq, | 891 | |
| 878 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | 892 | error = devm_request_threaded_irq(dev, client->irq, |
| 879 | "cyapa", | 893 | NULL, cyapa_irq, |
| 880 | cyapa); | 894 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, |
| 881 | if (ret) { | 895 | "cyapa", cyapa); |
| 882 | dev_err(dev, "IRQ request failed: %d\n, ", ret); | 896 | if (error) { |
| 883 | goto err_unregister_device; | 897 | dev_err(dev, "failed to request threaded irq: %d\n", error); |
| 898 | return error; | ||
| 884 | } | 899 | } |
| 885 | 900 | ||
| 886 | return 0; | 901 | /* Disable IRQ until the device is opened */ |
| 902 | disable_irq(client->irq); | ||
| 887 | 903 | ||
| 888 | err_unregister_device: | 904 | /* Register the device in input subsystem */ |
| 889 | input_unregister_device(cyapa->input); | 905 | error = input_register_device(cyapa->input); |
| 890 | err_mem_free: | 906 | if (error) { |
| 891 | kfree(cyapa); | 907 | dev_err(dev, "failed to register input device: %d\n", error); |
| 892 | 908 | return error; | |
| 893 | return ret; | 909 | } |
| 894 | } | ||
| 895 | |||
| 896 | static int cyapa_remove(struct i2c_client *client) | ||
| 897 | { | ||
| 898 | struct cyapa *cyapa = i2c_get_clientdata(client); | ||
| 899 | |||
| 900 | free_irq(cyapa->irq, cyapa); | ||
| 901 | input_unregister_device(cyapa->input); | ||
| 902 | cyapa_set_power_mode(cyapa, PWR_MODE_OFF); | ||
| 903 | kfree(cyapa); | ||
| 904 | 910 | ||
| 905 | return 0; | 911 | return 0; |
| 906 | } | 912 | } |
| 907 | 913 | ||
| 908 | #ifdef CONFIG_PM_SLEEP | 914 | static int __maybe_unused cyapa_suspend(struct device *dev) |
| 909 | static int cyapa_suspend(struct device *dev) | ||
| 910 | { | 915 | { |
| 911 | int ret; | 916 | struct i2c_client *client = to_i2c_client(dev); |
| 917 | struct cyapa *cyapa = i2c_get_clientdata(client); | ||
| 918 | struct input_dev *input = cyapa->input; | ||
| 912 | u8 power_mode; | 919 | u8 power_mode; |
| 913 | struct cyapa *cyapa = dev_get_drvdata(dev); | 920 | int error; |
| 914 | 921 | ||
| 915 | disable_irq(cyapa->irq); | 922 | error = mutex_lock_interruptible(&input->mutex); |
| 923 | if (error) | ||
| 924 | return error; | ||
| 925 | |||
| 926 | disable_irq(client->irq); | ||
| 916 | 927 | ||
| 917 | /* | 928 | /* |
| 918 | * Set trackpad device to idle mode if wakeup is allowed, | 929 | * Set trackpad device to idle mode if wakeup is allowed, |
| @@ -920,31 +931,44 @@ static int cyapa_suspend(struct device *dev) | |||
| 920 | */ | 931 | */ |
| 921 | power_mode = device_may_wakeup(dev) ? PWR_MODE_IDLE | 932 | power_mode = device_may_wakeup(dev) ? PWR_MODE_IDLE |
| 922 | : PWR_MODE_OFF; | 933 | : PWR_MODE_OFF; |
| 923 | ret = cyapa_set_power_mode(cyapa, power_mode); | 934 | error = cyapa_set_power_mode(cyapa, power_mode); |
| 924 | if (ret < 0) | 935 | if (error) |
| 925 | dev_err(dev, "set power mode failed, %d\n", ret); | 936 | dev_err(dev, "resume: set power mode to %d failed: %d\n", |
| 937 | power_mode, error); | ||
| 926 | 938 | ||
| 927 | if (device_may_wakeup(dev)) | 939 | if (device_may_wakeup(dev)) |
| 928 | cyapa->irq_wake = (enable_irq_wake(cyapa->irq) == 0); | 940 | cyapa->irq_wake = (enable_irq_wake(client->irq) == 0); |
| 941 | |||
| 942 | mutex_unlock(&input->mutex); | ||
| 943 | |||
| 929 | return 0; | 944 | return 0; |
| 930 | } | 945 | } |
| 931 | 946 | ||
| 932 | static int cyapa_resume(struct device *dev) | 947 | static int __maybe_unused cyapa_resume(struct device *dev) |
| 933 | { | 948 | { |
| 934 | int ret; | 949 | struct i2c_client *client = to_i2c_client(dev); |
| 935 | struct cyapa *cyapa = dev_get_drvdata(dev); | 950 | struct cyapa *cyapa = i2c_get_clientdata(client); |
| 951 | struct input_dev *input = cyapa->input; | ||
| 952 | u8 power_mode; | ||
| 953 | int error; | ||
| 954 | |||
| 955 | mutex_lock(&input->mutex); | ||
| 936 | 956 | ||
| 937 | if (device_may_wakeup(dev) && cyapa->irq_wake) | 957 | if (device_may_wakeup(dev) && cyapa->irq_wake) |
| 938 | disable_irq_wake(cyapa->irq); | 958 | disable_irq_wake(client->irq); |
| 959 | |||
| 960 | power_mode = input->users ? PWR_MODE_FULL_ACTIVE : PWR_MODE_OFF; | ||
| 961 | error = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE); | ||
| 962 | if (error) | ||
| 963 | dev_warn(dev, "resume: set power mode to %d failed: %d\n", | ||
| 964 | power_mode, error); | ||
| 965 | |||
| 966 | enable_irq(client->irq); | ||
| 939 | 967 | ||
| 940 | ret = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE); | 968 | mutex_unlock(&input->mutex); |
| 941 | if (ret) | ||
| 942 | dev_warn(dev, "resume active power failed, %d\n", ret); | ||
| 943 | 969 | ||
| 944 | enable_irq(cyapa->irq); | ||
| 945 | return 0; | 970 | return 0; |
| 946 | } | 971 | } |
| 947 | #endif /* CONFIG_PM_SLEEP */ | ||
| 948 | 972 | ||
| 949 | static SIMPLE_DEV_PM_OPS(cyapa_pm_ops, cyapa_suspend, cyapa_resume); | 973 | static SIMPLE_DEV_PM_OPS(cyapa_pm_ops, cyapa_suspend, cyapa_resume); |
| 950 | 974 | ||
| @@ -962,7 +986,6 @@ static struct i2c_driver cyapa_driver = { | |||
| 962 | }, | 986 | }, |
| 963 | 987 | ||
| 964 | .probe = cyapa_probe, | 988 | .probe = cyapa_probe, |
| 965 | .remove = cyapa_remove, | ||
| 966 | .id_table = cyapa_id_table, | 989 | .id_table = cyapa_id_table, |
| 967 | }; | 990 | }; |
| 968 | 991 | ||
diff --git a/drivers/input/mouse/elan_i2c.h b/drivers/input/mouse/elan_i2c.h new file mode 100644 index 000000000000..2e838626205f --- /dev/null +++ b/drivers/input/mouse/elan_i2c.h | |||
| @@ -0,0 +1,86 @@ | |||
| 1 | /* | ||
| 2 | * Elan I2C/SMBus Touchpad driver | ||
| 3 | * | ||
| 4 | * Copyright (c) 2013 ELAN Microelectronics Corp. | ||
| 5 | * | ||
| 6 | * Author: æž—æ”¿ç¶ (Duson Lin) <dusonlin@emc.com.tw> | ||
| 7 | * Version: 1.5.5 | ||
| 8 | * | ||
| 9 | * Based on cyapa driver: | ||
| 10 | * copyright (c) 2011-2012 Cypress Semiconductor, Inc. | ||
| 11 | * copyright (c) 2011-2012 Google, Inc. | ||
| 12 | * | ||
| 13 | * This program is free software; you can redistribute it and/or modify it | ||
| 14 | * under the terms of the GNU General Public License version 2 as published | ||
| 15 | * by the Free Software Foundation. | ||
| 16 | * | ||
| 17 | * Trademarks are the property of their respective owners. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef _ELAN_I2C_H | ||
| 21 | #define _ELAN_i2C_H | ||
| 22 | |||
| 23 | #include <linux/types.h> | ||
| 24 | |||
| 25 | #define ETP_ENABLE_ABS 0x0001 | ||
| 26 | #define ETP_ENABLE_CALIBRATE 0x0002 | ||
| 27 | #define ETP_DISABLE_CALIBRATE 0x0000 | ||
| 28 | #define ETP_DISABLE_POWER 0x0001 | ||
| 29 | |||
| 30 | /* IAP Firmware handling */ | ||
| 31 | #define ETP_FW_NAME "elan_i2c.bin" | ||
| 32 | #define ETP_IAP_START_ADDR 0x0083 | ||
| 33 | #define ETP_FW_IAP_PAGE_ERR (1 << 5) | ||
| 34 | #define ETP_FW_IAP_INTF_ERR (1 << 4) | ||
| 35 | #define ETP_FW_PAGE_SIZE 64 | ||
| 36 | #define ETP_FW_PAGE_COUNT 768 | ||
| 37 | #define ETP_FW_SIZE (ETP_FW_PAGE_SIZE * ETP_FW_PAGE_COUNT) | ||
| 38 | |||
| 39 | struct i2c_client; | ||
| 40 | struct completion; | ||
| 41 | |||
| 42 | enum tp_mode { | ||
| 43 | IAP_MODE = 1, | ||
| 44 | MAIN_MODE | ||
| 45 | }; | ||
| 46 | |||
| 47 | struct elan_transport_ops { | ||
| 48 | int (*initialize)(struct i2c_client *client); | ||
| 49 | int (*sleep_control)(struct i2c_client *, bool sleep); | ||
| 50 | int (*power_control)(struct i2c_client *, bool enable); | ||
| 51 | int (*set_mode)(struct i2c_client *client, u8 mode); | ||
| 52 | |||
| 53 | int (*calibrate)(struct i2c_client *client); | ||
| 54 | int (*calibrate_result)(struct i2c_client *client, u8 *val); | ||
| 55 | |||
| 56 | int (*get_baseline_data)(struct i2c_client *client, | ||
| 57 | bool max_baseliune, u8 *value); | ||
| 58 | |||
| 59 | int (*get_version)(struct i2c_client *client, bool iap, u8 *version); | ||
| 60 | int (*get_sm_version)(struct i2c_client *client, u8 *version); | ||
| 61 | int (*get_checksum)(struct i2c_client *client, bool iap, u16 *csum); | ||
| 62 | int (*get_product_id)(struct i2c_client *client, u8 *id); | ||
| 63 | |||
| 64 | int (*get_max)(struct i2c_client *client, | ||
| 65 | unsigned int *max_x, unsigned int *max_y); | ||
| 66 | int (*get_resolution)(struct i2c_client *client, | ||
| 67 | u8 *hw_res_x, u8 *hw_res_y); | ||
| 68 | int (*get_num_traces)(struct i2c_client *client, | ||
| 69 | unsigned int *x_tracenum, | ||
| 70 | unsigned int *y_tracenum); | ||
| 71 | |||
| 72 | int (*iap_get_mode)(struct i2c_client *client, enum tp_mode *mode); | ||
| 73 | int (*iap_reset)(struct i2c_client *client); | ||
| 74 | |||
| 75 | int (*prepare_fw_update)(struct i2c_client *client); | ||
| 76 | int (*write_fw_block)(struct i2c_client *client, | ||
| 77 | const u8 *page, u16 checksum, int idx); | ||
| 78 | int (*finish_fw_update)(struct i2c_client *client, | ||
| 79 | struct completion *reset_done); | ||
| 80 | |||
| 81 | int (*get_report)(struct i2c_client *client, u8 *report); | ||
| 82 | }; | ||
| 83 | |||
| 84 | extern const struct elan_transport_ops elan_smbus_ops, elan_i2c_ops; | ||
| 85 | |||
| 86 | #endif /* _ELAN_I2C_H */ | ||
diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c new file mode 100644 index 000000000000..0cb2be48d537 --- /dev/null +++ b/drivers/input/mouse/elan_i2c_core.c | |||
| @@ -0,0 +1,1137 @@ | |||
| 1 | /* | ||
| 2 | * Elan I2C/SMBus Touchpad driver | ||
| 3 | * | ||
| 4 | * Copyright (c) 2013 ELAN Microelectronics Corp. | ||
| 5 | * | ||
| 6 | * Author: æž—æ”¿ç¶ (Duson Lin) <dusonlin@emc.com.tw> | ||
| 7 | * Version: 1.5.5 | ||
| 8 | * | ||
| 9 | * Based on cyapa driver: | ||
| 10 | * copyright (c) 2011-2012 Cypress Semiconductor, Inc. | ||
| 11 | * copyright (c) 2011-2012 Google, Inc. | ||
| 12 | * | ||
| 13 | * This program is free software; you can redistribute it and/or modify it | ||
| 14 | * under the terms of the GNU General Public License version 2 as published | ||
| 15 | * by the Free Software Foundation. | ||
| 16 | * | ||
| 17 | * Trademarks are the property of their respective owners. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <linux/acpi.h> | ||
| 21 | #include <linux/delay.h> | ||
| 22 | #include <linux/device.h> | ||
| 23 | #include <linux/firmware.h> | ||
| 24 | #include <linux/i2c.h> | ||
| 25 | #include <linux/init.h> | ||
| 26 | #include <linux/input/mt.h> | ||
| 27 | #include <linux/interrupt.h> | ||
| 28 | #include <linux/module.h> | ||
| 29 | #include <linux/slab.h> | ||
| 30 | #include <linux/kernel.h> | ||
| 31 | #include <linux/sched.h> | ||
| 32 | #include <linux/input.h> | ||
| 33 | #include <linux/uaccess.h> | ||
| 34 | #include <linux/jiffies.h> | ||
| 35 | #include <linux/completion.h> | ||
| 36 | #include <linux/of.h> | ||
| 37 | #include <linux/regulator/consumer.h> | ||
| 38 | #include <asm/unaligned.h> | ||
| 39 | |||
| 40 | #include "elan_i2c.h" | ||
| 41 | |||
| 42 | #define DRIVER_NAME "elan_i2c" | ||
| 43 | #define ELAN_DRIVER_VERSION "1.5.5" | ||
| 44 | #define ETP_PRESSURE_OFFSET 25 | ||
| 45 | #define ETP_MAX_PRESSURE 255 | ||
| 46 | #define ETP_FWIDTH_REDUCE 90 | ||
| 47 | #define ETP_FINGER_WIDTH 15 | ||
| 48 | #define ETP_RETRY_COUNT 3 | ||
| 49 | |||
| 50 | #define ETP_MAX_FINGERS 5 | ||
| 51 | #define ETP_FINGER_DATA_LEN 5 | ||
| 52 | #define ETP_REPORT_ID 0x5D | ||
| 53 | #define ETP_REPORT_ID_OFFSET 2 | ||
| 54 | #define ETP_TOUCH_INFO_OFFSET 3 | ||
| 55 | #define ETP_FINGER_DATA_OFFSET 4 | ||
| 56 | #define ETP_MAX_REPORT_LEN 34 | ||
| 57 | |||
| 58 | /* The main device structure */ | ||
| 59 | struct elan_tp_data { | ||
| 60 | struct i2c_client *client; | ||
| 61 | struct input_dev *input; | ||
| 62 | struct regulator *vcc; | ||
| 63 | |||
| 64 | const struct elan_transport_ops *ops; | ||
| 65 | |||
| 66 | /* for fw update */ | ||
| 67 | struct completion fw_completion; | ||
| 68 | bool in_fw_update; | ||
| 69 | |||
| 70 | struct mutex sysfs_mutex; | ||
| 71 | |||
| 72 | unsigned int max_x; | ||
| 73 | unsigned int max_y; | ||
| 74 | unsigned int width_x; | ||
| 75 | unsigned int width_y; | ||
| 76 | unsigned int x_res; | ||
| 77 | unsigned int y_res; | ||
| 78 | |||
| 79 | u8 product_id; | ||
| 80 | u8 fw_version; | ||
| 81 | u8 sm_version; | ||
| 82 | u8 iap_version; | ||
| 83 | u16 fw_checksum; | ||
| 84 | |||
| 85 | u8 mode; | ||
| 86 | |||
| 87 | bool irq_wake; | ||
| 88 | |||
| 89 | u8 min_baseline; | ||
| 90 | u8 max_baseline; | ||
| 91 | bool baseline_ready; | ||
| 92 | }; | ||
| 93 | |||
| 94 | static int elan_enable_power(struct elan_tp_data *data) | ||
| 95 | { | ||
| 96 | int repeat = ETP_RETRY_COUNT; | ||
| 97 | int error; | ||
| 98 | |||
| 99 | error = regulator_enable(data->vcc); | ||
| 100 | if (error) { | ||
| 101 | dev_err(&data->client->dev, | ||
| 102 | "Failed to enable regulator: %d\n", error); | ||
| 103 | return error; | ||
| 104 | } | ||
| 105 | |||
| 106 | do { | ||
| 107 | error = data->ops->power_control(data->client, true); | ||
| 108 | if (error >= 0) | ||
| 109 | return 0; | ||
| 110 | |||
| 111 | msleep(30); | ||
| 112 | } while (--repeat > 0); | ||
| 113 | |||
| 114 | return error; | ||
| 115 | } | ||
| 116 | |||
| 117 | static int elan_disable_power(struct elan_tp_data *data) | ||
| 118 | { | ||
| 119 | int repeat = ETP_RETRY_COUNT; | ||
| 120 | int error; | ||
| 121 | |||
| 122 | do { | ||
| 123 | error = data->ops->power_control(data->client, false); | ||
| 124 | if (!error) { | ||
| 125 | error = regulator_disable(data->vcc); | ||
| 126 | if (error) { | ||
| 127 | dev_err(&data->client->dev, | ||
| 128 | "Failed to disable regulator: %d\n", | ||
| 129 | error); | ||
| 130 | /* Attempt to power the chip back up */ | ||
| 131 | data->ops->power_control(data->client, true); | ||
| 132 | break; | ||
| 133 | } | ||
| 134 | |||
| 135 | return 0; | ||
| 136 | } | ||
| 137 | |||
| 138 | msleep(30); | ||
| 139 | } while (--repeat > 0); | ||
| 140 | |||
| 141 | return error; | ||
| 142 | } | ||
| 143 | |||
| 144 | static int elan_sleep(struct elan_tp_data *data) | ||
| 145 | { | ||
| 146 | int repeat = ETP_RETRY_COUNT; | ||
| 147 | int error; | ||
| 148 | |||
| 149 | do { | ||
| 150 | error = data->ops->sleep_control(data->client, true); | ||
| 151 | if (!error) | ||
| 152 | return 0; | ||
| 153 | |||
| 154 | msleep(30); | ||
| 155 | } while (--repeat > 0); | ||
| 156 | |||
| 157 | return error; | ||
| 158 | } | ||
| 159 | |||
| 160 | static int __elan_initialize(struct elan_tp_data *data) | ||
| 161 | { | ||
| 162 | struct i2c_client *client = data->client; | ||
| 163 | int error; | ||
| 164 | |||
| 165 | error = data->ops->initialize(client); | ||
| 166 | if (error) { | ||
| 167 | dev_err(&client->dev, "device initialize failed: %d\n", error); | ||
| 168 | return error; | ||
| 169 | } | ||
| 170 | |||
| 171 | data->mode |= ETP_ENABLE_ABS; | ||
| 172 | error = data->ops->set_mode(client, data->mode); | ||
| 173 | if (error) { | ||
| 174 | dev_err(&client->dev, | ||
| 175 | "failed to switch to absolute mode: %d\n", error); | ||
| 176 | return error; | ||
| 177 | } | ||
| 178 | |||
| 179 | error = data->ops->sleep_control(client, false); | ||
| 180 | if (error) { | ||
| 181 | dev_err(&client->dev, | ||
| 182 | "failed to wake device up: %d\n", error); | ||
| 183 | return error; | ||
| 184 | } | ||
| 185 | |||
| 186 | return 0; | ||
| 187 | } | ||
| 188 | |||
| 189 | static int elan_initialize(struct elan_tp_data *data) | ||
| 190 | { | ||
| 191 | int repeat = ETP_RETRY_COUNT; | ||
| 192 | int error; | ||
| 193 | |||
| 194 | do { | ||
| 195 | error = __elan_initialize(data); | ||
| 196 | if (!error) | ||
| 197 | return 0; | ||
| 198 | |||
| 199 | repeat--; | ||
| 200 | msleep(30); | ||
| 201 | } while (--repeat > 0); | ||
| 202 | |||
| 203 | return error; | ||
| 204 | } | ||
| 205 | |||
| 206 | static int elan_query_device_info(struct elan_tp_data *data) | ||
| 207 | { | ||
| 208 | int error; | ||
| 209 | |||
| 210 | error = data->ops->get_product_id(data->client, &data->product_id); | ||
| 211 | if (error) | ||
| 212 | return error; | ||
| 213 | |||
| 214 | error = data->ops->get_version(data->client, false, &data->fw_version); | ||
| 215 | if (error) | ||
| 216 | return error; | ||
| 217 | |||
| 218 | error = data->ops->get_checksum(data->client, false, | ||
| 219 | &data->fw_checksum); | ||
| 220 | if (error) | ||
| 221 | return error; | ||
| 222 | |||
| 223 | error = data->ops->get_sm_version(data->client, &data->sm_version); | ||
| 224 | if (error) | ||
| 225 | return error; | ||
| 226 | |||
| 227 | error = data->ops->get_version(data->client, true, &data->iap_version); | ||
| 228 | if (error) | ||
| 229 | return error; | ||
| 230 | |||
| 231 | return 0; | ||
| 232 | } | ||
| 233 | |||
| 234 | static unsigned int elan_convert_resolution(u8 val) | ||
| 235 | { | ||
| 236 | /* | ||
| 237 | * (value from firmware) * 10 + 790 = dpi | ||
| 238 | * | ||
| 239 | * We also have to convert dpi to dots/mm (*10/254 to avoid floating | ||
| 240 | * point). | ||
| 241 | */ | ||
| 242 | |||
| 243 | return ((int)(char)val * 10 + 790) * 10 / 254; | ||
| 244 | } | ||
| 245 | |||
| 246 | static int elan_query_device_parameters(struct elan_tp_data *data) | ||
| 247 | { | ||
| 248 | unsigned int x_traces, y_traces; | ||
| 249 | u8 hw_x_res, hw_y_res; | ||
| 250 | int error; | ||
| 251 | |||
| 252 | error = data->ops->get_max(data->client, &data->max_x, &data->max_y); | ||
| 253 | if (error) | ||
| 254 | return error; | ||
| 255 | |||
| 256 | error = data->ops->get_num_traces(data->client, &x_traces, &y_traces); | ||
| 257 | if (error) | ||
| 258 | return error; | ||
| 259 | |||
| 260 | data->width_x = data->max_x / x_traces; | ||
| 261 | data->width_y = data->max_y / y_traces; | ||
| 262 | |||
| 263 | error = data->ops->get_resolution(data->client, &hw_x_res, &hw_y_res); | ||
| 264 | if (error) | ||
| 265 | return error; | ||
| 266 | |||
| 267 | data->x_res = elan_convert_resolution(hw_x_res); | ||
| 268 | data->y_res = elan_convert_resolution(hw_y_res); | ||
| 269 | |||
| 270 | return 0; | ||
| 271 | } | ||
| 272 | |||
| 273 | /* | ||
| 274 | ********************************************************** | ||
| 275 | * IAP firmware updater related routines | ||
| 276 | ********************************************************** | ||
| 277 | */ | ||
| 278 | static int elan_write_fw_block(struct elan_tp_data *data, | ||
| 279 | const u8 *page, u16 checksum, int idx) | ||
| 280 | { | ||
| 281 | int retry = ETP_RETRY_COUNT; | ||
| 282 | int error; | ||
| 283 | |||
| 284 | do { | ||
| 285 | error = data->ops->write_fw_block(data->client, | ||
| 286 | page, checksum, idx); | ||
| 287 | if (!error) | ||
| 288 | return 0; | ||
| 289 | |||
| 290 | dev_dbg(&data->client->dev, | ||
| 291 | "IAP retrying page %d (error: %d)\n", idx, error); | ||
| 292 | } while (--retry > 0); | ||
| 293 | |||
| 294 | return error; | ||
| 295 | } | ||
| 296 | |||
| 297 | static int __elan_update_firmware(struct elan_tp_data *data, | ||
| 298 | const struct firmware *fw) | ||
| 299 | { | ||
| 300 | struct i2c_client *client = data->client; | ||
| 301 | struct device *dev = &client->dev; | ||
| 302 | int i, j; | ||
| 303 | int error; | ||
| 304 | u16 iap_start_addr; | ||
| 305 | u16 boot_page_count; | ||
| 306 | u16 sw_checksum = 0, fw_checksum = 0; | ||
| 307 | |||
| 308 | error = data->ops->prepare_fw_update(client); | ||
| 309 | if (error) | ||
| 310 | return error; | ||
| 311 | |||
| 312 | iap_start_addr = get_unaligned_le16(&fw->data[ETP_IAP_START_ADDR * 2]); | ||
| 313 | |||
| 314 | boot_page_count = (iap_start_addr * 2) / ETP_FW_PAGE_SIZE; | ||
| 315 | for (i = boot_page_count; i < ETP_FW_PAGE_COUNT; i++) { | ||
| 316 | u16 checksum = 0; | ||
| 317 | const u8 *page = &fw->data[i * ETP_FW_PAGE_SIZE]; | ||
| 318 | |||
| 319 | for (j = 0; j < ETP_FW_PAGE_SIZE; j += 2) | ||
| 320 | checksum += ((page[j + 1] << 8) | page[j]); | ||
| 321 | |||
| 322 | error = elan_write_fw_block(data, page, checksum, i); | ||
| 323 | if (error) { | ||
| 324 | dev_err(dev, "write page %d fail: %d\n", i, error); | ||
| 325 | return error; | ||
| 326 | } | ||
| 327 | |||
| 328 | sw_checksum += checksum; | ||
| 329 | } | ||
| 330 | |||
| 331 | /* Wait WDT reset and power on reset */ | ||
| 332 | msleep(600); | ||
| 333 | |||
| 334 | error = data->ops->finish_fw_update(client, &data->fw_completion); | ||
| 335 | if (error) | ||
| 336 | return error; | ||
| 337 | |||
| 338 | error = data->ops->get_checksum(client, true, &fw_checksum); | ||
| 339 | if (error) | ||
| 340 | return error; | ||
| 341 | |||
| 342 | if (sw_checksum != fw_checksum) { | ||
| 343 | dev_err(dev, "checksum diff sw=[%04X], fw=[%04X]\n", | ||
| 344 | sw_checksum, fw_checksum); | ||
| 345 | return -EIO; | ||
| 346 | } | ||
| 347 | |||
| 348 | return 0; | ||
| 349 | } | ||
| 350 | |||
| 351 | static int elan_update_firmware(struct elan_tp_data *data, | ||
| 352 | const struct firmware *fw) | ||
| 353 | { | ||
| 354 | struct i2c_client *client = data->client; | ||
| 355 | int retval; | ||
| 356 | |||
| 357 | dev_dbg(&client->dev, "Starting firmware update....\n"); | ||
| 358 | |||
| 359 | disable_irq(client->irq); | ||
| 360 | data->in_fw_update = true; | ||
| 361 | |||
| 362 | retval = __elan_update_firmware(data, fw); | ||
| 363 | if (retval) { | ||
| 364 | dev_err(&client->dev, "firmware update failed: %d\n", retval); | ||
| 365 | data->ops->iap_reset(client); | ||
| 366 | } else { | ||
| 367 | /* Reinitialize TP after fw is updated */ | ||
| 368 | elan_initialize(data); | ||
| 369 | elan_query_device_info(data); | ||
| 370 | } | ||
| 371 | |||
| 372 | data->in_fw_update = false; | ||
| 373 | enable_irq(client->irq); | ||
| 374 | |||
| 375 | return retval; | ||
| 376 | } | ||
| 377 | |||
| 378 | /* | ||
| 379 | ******************************************************************* | ||
| 380 | * SYSFS attributes | ||
| 381 | ******************************************************************* | ||
| 382 | */ | ||
| 383 | static ssize_t elan_sysfs_read_fw_checksum(struct device *dev, | ||
| 384 | struct device_attribute *attr, | ||
| 385 | char *buf) | ||
| 386 | { | ||
| 387 | struct i2c_client *client = to_i2c_client(dev); | ||
| 388 | struct elan_tp_data *data = i2c_get_clientdata(client); | ||
| 389 | |||
| 390 | return sprintf(buf, "0x%04x\n", data->fw_checksum); | ||
| 391 | } | ||
| 392 | |||
| 393 | static ssize_t elan_sysfs_read_product_id(struct device *dev, | ||
| 394 | struct device_attribute *attr, | ||
| 395 | char *buf) | ||
| 396 | { | ||
| 397 | struct i2c_client *client = to_i2c_client(dev); | ||
| 398 | struct elan_tp_data *data = i2c_get_clientdata(client); | ||
| 399 | |||
| 400 | return sprintf(buf, "%d.0\n", data->product_id); | ||
| 401 | } | ||
| 402 | |||
| 403 | static ssize_t elan_sysfs_read_fw_ver(struct device *dev, | ||
| 404 | struct device_attribute *attr, | ||
| 405 | char *buf) | ||
| 406 | { | ||
| 407 | struct i2c_client *client = to_i2c_client(dev); | ||
| 408 | struct elan_tp_data *data = i2c_get_clientdata(client); | ||
| 409 | |||
| 410 | return sprintf(buf, "%d.0\n", data->fw_version); | ||
| 411 | } | ||
| 412 | |||
| 413 | static ssize_t elan_sysfs_read_sm_ver(struct device *dev, | ||
| 414 | struct device_attribute *attr, | ||
| 415 | char *buf) | ||
| 416 | { | ||
| 417 | struct i2c_client *client = to_i2c_client(dev); | ||
| 418 | struct elan_tp_data *data = i2c_get_clientdata(client); | ||
| 419 | |||
| 420 | return sprintf(buf, "%d.0\n", data->sm_version); | ||
| 421 | } | ||
| 422 | |||
| 423 | static ssize_t elan_sysfs_read_iap_ver(struct device *dev, | ||
| 424 | struct device_attribute *attr, | ||
| 425 | char *buf) | ||
| 426 | { | ||
| 427 | struct i2c_client *client = to_i2c_client(dev); | ||
| 428 | struct elan_tp_data *data = i2c_get_clientdata(client); | ||
| 429 | |||
| 430 | return sprintf(buf, "%d.0\n", data->iap_version); | ||
| 431 | } | ||
| 432 | |||
| 433 | static ssize_t elan_sysfs_update_fw(struct device *dev, | ||
| 434 | struct device_attribute *attr, | ||
| 435 | const char *buf, size_t count) | ||
| 436 | { | ||
| 437 | struct i2c_client *client = to_i2c_client(dev); | ||
| 438 | struct elan_tp_data *data = i2c_get_clientdata(client); | ||
| 439 | const struct firmware *fw; | ||
| 440 | int error; | ||
| 441 | |||
| 442 | error = request_firmware(&fw, ETP_FW_NAME, dev); | ||
| 443 | if (error) { | ||
| 444 | dev_err(dev, "cannot load firmware %s: %d\n", | ||
| 445 | ETP_FW_NAME, error); | ||
| 446 | return error; | ||
| 447 | } | ||
| 448 | |||
| 449 | /* Firmware must be exactly PAGE_NUM * PAGE_SIZE bytes */ | ||
| 450 | if (fw->size != ETP_FW_SIZE) { | ||
| 451 | dev_err(dev, "invalid firmware size = %zu, expected %d.\n", | ||
| 452 | fw->size, ETP_FW_SIZE); | ||
| 453 | error = -EBADF; | ||
| 454 | goto out_release_fw; | ||
| 455 | } | ||
| 456 | |||
| 457 | error = mutex_lock_interruptible(&data->sysfs_mutex); | ||
| 458 | if (error) | ||
| 459 | goto out_release_fw; | ||
| 460 | |||
| 461 | error = elan_update_firmware(data, fw); | ||
| 462 | |||
| 463 | mutex_unlock(&data->sysfs_mutex); | ||
| 464 | |||
| 465 | out_release_fw: | ||
| 466 | release_firmware(fw); | ||
| 467 | return error ?: count; | ||
| 468 | } | ||
| 469 | |||
| 470 | static ssize_t calibrate_store(struct device *dev, | ||
| 471 | struct device_attribute *attr, | ||
| 472 | const char *buf, size_t count) | ||
| 473 | { | ||
| 474 | struct i2c_client *client = to_i2c_client(dev); | ||
| 475 | struct elan_tp_data *data = i2c_get_clientdata(client); | ||
| 476 | int tries = 20; | ||
| 477 | int retval; | ||
| 478 | int error; | ||
| 479 | u8 val[3]; | ||
| 480 | |||
| 481 | retval = mutex_lock_interruptible(&data->sysfs_mutex); | ||
| 482 | if (retval) | ||
| 483 | return retval; | ||
| 484 | |||
| 485 | disable_irq(client->irq); | ||
| 486 | |||
| 487 | data->mode |= ETP_ENABLE_CALIBRATE; | ||
| 488 | retval = data->ops->set_mode(client, data->mode); | ||
| 489 | if (retval) { | ||
| 490 | dev_err(dev, "failed to enable calibration mode: %d\n", | ||
| 491 | retval); | ||
| 492 | goto out; | ||
| 493 | } | ||
| 494 | |||
| 495 | retval = data->ops->calibrate(client); | ||
| 496 | if (retval) { | ||
| 497 | dev_err(dev, "failed to start calibration: %d\n", | ||
| 498 | retval); | ||
| 499 | goto out_disable_calibrate; | ||
| 500 | } | ||
| 501 | |||
| 502 | val[0] = 0xff; | ||
| 503 | do { | ||
| 504 | /* Wait 250ms before checking if calibration has completed. */ | ||
| 505 | msleep(250); | ||
| 506 | |||
| 507 | retval = data->ops->calibrate_result(client, val); | ||
| 508 | if (retval) | ||
| 509 | dev_err(dev, "failed to check calibration result: %d\n", | ||
| 510 | retval); | ||
| 511 | else if (val[0] == 0) | ||
| 512 | break; /* calibration done */ | ||
| 513 | |||
| 514 | } while (--tries); | ||
| 515 | |||
| 516 | if (tries == 0) { | ||
| 517 | dev_err(dev, "failed to calibrate. Timeout.\n"); | ||
| 518 | retval = -ETIMEDOUT; | ||
| 519 | } | ||
| 520 | |||
| 521 | out_disable_calibrate: | ||
| 522 | data->mode &= ~ETP_ENABLE_CALIBRATE; | ||
| 523 | error = data->ops->set_mode(data->client, data->mode); | ||
| 524 | if (error) { | ||
| 525 | dev_err(dev, "failed to disable calibration mode: %d\n", | ||
| 526 | error); | ||
| 527 | if (!retval) | ||
| 528 | retval = error; | ||
| 529 | } | ||
| 530 | out: | ||
| 531 | enable_irq(client->irq); | ||
| 532 | mutex_unlock(&data->sysfs_mutex); | ||
| 533 | return retval ?: count; | ||
| 534 | } | ||
| 535 | |||
| 536 | static ssize_t elan_sysfs_read_mode(struct device *dev, | ||
| 537 | struct device_attribute *attr, | ||
| 538 | char *buf) | ||
| 539 | { | ||
| 540 | struct i2c_client *client = to_i2c_client(dev); | ||
| 541 | struct elan_tp_data *data = i2c_get_clientdata(client); | ||
| 542 | int error; | ||
| 543 | enum tp_mode mode; | ||
| 544 | |||
| 545 | error = mutex_lock_interruptible(&data->sysfs_mutex); | ||
| 546 | if (error) | ||
| 547 | return error; | ||
| 548 | |||
| 549 | error = data->ops->iap_get_mode(data->client, &mode); | ||
| 550 | |||
| 551 | mutex_unlock(&data->sysfs_mutex); | ||
| 552 | |||
| 553 | if (error) | ||
| 554 | return error; | ||
| 555 | |||
| 556 | return sprintf(buf, "%d\n", (int)mode); | ||
| 557 | } | ||
| 558 | |||
| 559 | static DEVICE_ATTR(product_id, S_IRUGO, elan_sysfs_read_product_id, NULL); | ||
| 560 | static DEVICE_ATTR(firmware_version, S_IRUGO, elan_sysfs_read_fw_ver, NULL); | ||
| 561 | static DEVICE_ATTR(sample_version, S_IRUGO, elan_sysfs_read_sm_ver, NULL); | ||
| 562 | static DEVICE_ATTR(iap_version, S_IRUGO, elan_sysfs_read_iap_ver, NULL); | ||
| 563 | static DEVICE_ATTR(fw_checksum, S_IRUGO, elan_sysfs_read_fw_checksum, NULL); | ||
| 564 | static DEVICE_ATTR(mode, S_IRUGO, elan_sysfs_read_mode, NULL); | ||
| 565 | static DEVICE_ATTR(update_fw, S_IWUSR, NULL, elan_sysfs_update_fw); | ||
| 566 | |||
| 567 | static DEVICE_ATTR_WO(calibrate); | ||
| 568 | |||
| 569 | static struct attribute *elan_sysfs_entries[] = { | ||
| 570 | &dev_attr_product_id.attr, | ||
| 571 | &dev_attr_firmware_version.attr, | ||
| 572 | &dev_attr_sample_version.attr, | ||
| 573 | &dev_attr_iap_version.attr, | ||
| 574 | &dev_attr_fw_checksum.attr, | ||
| 575 | &dev_attr_calibrate.attr, | ||
| 576 | &dev_attr_mode.attr, | ||
| 577 | &dev_attr_update_fw.attr, | ||
| 578 | NULL, | ||
| 579 | }; | ||
| 580 | |||
| 581 | static const struct attribute_group elan_sysfs_group = { | ||
| 582 | .attrs = elan_sysfs_entries, | ||
| 583 | }; | ||
| 584 | |||
| 585 | static ssize_t acquire_store(struct device *dev, struct device_attribute *attr, | ||
| 586 | const char *buf, size_t count) | ||
| 587 | { | ||
| 588 | struct i2c_client *client = to_i2c_client(dev); | ||
| 589 | struct elan_tp_data *data = i2c_get_clientdata(client); | ||
| 590 | int error; | ||
| 591 | int retval; | ||
| 592 | |||
| 593 | retval = mutex_lock_interruptible(&data->sysfs_mutex); | ||
| 594 | if (retval) | ||
| 595 | return retval; | ||
| 596 | |||
| 597 | disable_irq(client->irq); | ||
| 598 | |||
| 599 | data->baseline_ready = false; | ||
| 600 | |||
| 601 | data->mode |= ETP_ENABLE_CALIBRATE; | ||
| 602 | retval = data->ops->set_mode(data->client, data->mode); | ||
| 603 | if (retval) { | ||
| 604 | dev_err(dev, "Failed to enable calibration mode to get baseline: %d\n", | ||
| 605 | retval); | ||
| 606 | goto out; | ||
| 607 | } | ||
| 608 | |||
| 609 | msleep(250); | ||
| 610 | |||
| 611 | retval = data->ops->get_baseline_data(data->client, true, | ||
| 612 | &data->max_baseline); | ||
| 613 | if (retval) { | ||
| 614 | dev_err(dev, "Failed to read max baseline form device: %d\n", | ||
| 615 | retval); | ||
| 616 | goto out_disable_calibrate; | ||
| 617 | } | ||
| 618 | |||
| 619 | retval = data->ops->get_baseline_data(data->client, false, | ||
| 620 | &data->min_baseline); | ||
| 621 | if (retval) { | ||
| 622 | dev_err(dev, "Failed to read min baseline form device: %d\n", | ||
| 623 | retval); | ||
| 624 | goto out_disable_calibrate; | ||
| 625 | } | ||
| 626 | |||
| 627 | data->baseline_ready = true; | ||
| 628 | |||
| 629 | out_disable_calibrate: | ||
| 630 | data->mode &= ~ETP_ENABLE_CALIBRATE; | ||
| 631 | error = data->ops->set_mode(data->client, data->mode); | ||
| 632 | if (error) { | ||
| 633 | dev_err(dev, "Failed to disable calibration mode after acquiring baseline: %d\n", | ||
| 634 | error); | ||
| 635 | if (!retval) | ||
| 636 | retval = error; | ||
| 637 | } | ||
| 638 | out: | ||
| 639 | enable_irq(client->irq); | ||
| 640 | mutex_unlock(&data->sysfs_mutex); | ||
| 641 | return retval ?: count; | ||
| 642 | } | ||
| 643 | |||
| 644 | static ssize_t min_show(struct device *dev, | ||
| 645 | struct device_attribute *attr, char *buf) | ||
| 646 | { | ||
| 647 | struct i2c_client *client = to_i2c_client(dev); | ||
| 648 | struct elan_tp_data *data = i2c_get_clientdata(client); | ||
| 649 | int retval; | ||
| 650 | |||
| 651 | retval = mutex_lock_interruptible(&data->sysfs_mutex); | ||
| 652 | if (retval) | ||
| 653 | return retval; | ||
| 654 | |||
| 655 | if (!data->baseline_ready) { | ||
| 656 | retval = -ENODATA; | ||
| 657 | goto out; | ||
| 658 | } | ||
| 659 | |||
| 660 | retval = snprintf(buf, PAGE_SIZE, "%d", data->min_baseline); | ||
| 661 | |||
| 662 | out: | ||
| 663 | mutex_unlock(&data->sysfs_mutex); | ||
| 664 | return retval; | ||
| 665 | } | ||
| 666 | |||
| 667 | static ssize_t max_show(struct device *dev, | ||
| 668 | struct device_attribute *attr, char *buf) | ||
| 669 | { | ||
| 670 | struct i2c_client *client = to_i2c_client(dev); | ||
| 671 | struct elan_tp_data *data = i2c_get_clientdata(client); | ||
| 672 | int retval; | ||
| 673 | |||
| 674 | retval = mutex_lock_interruptible(&data->sysfs_mutex); | ||
| 675 | if (retval) | ||
| 676 | return retval; | ||
| 677 | |||
| 678 | if (!data->baseline_ready) { | ||
| 679 | retval = -ENODATA; | ||
| 680 | goto out; | ||
| 681 | } | ||
| 682 | |||
| 683 | retval = snprintf(buf, PAGE_SIZE, "%d", data->max_baseline); | ||
| 684 | |||
| 685 | out: | ||
| 686 | mutex_unlock(&data->sysfs_mutex); | ||
| 687 | return retval; | ||
| 688 | } | ||
| 689 | |||
| 690 | |||
| 691 | static DEVICE_ATTR_WO(acquire); | ||
| 692 | static DEVICE_ATTR_RO(min); | ||
| 693 | static DEVICE_ATTR_RO(max); | ||
| 694 | |||
| 695 | static struct attribute *elan_baseline_sysfs_entries[] = { | ||
| 696 | &dev_attr_acquire.attr, | ||
| 697 | &dev_attr_min.attr, | ||
| 698 | &dev_attr_max.attr, | ||
| 699 | NULL, | ||
| 700 | }; | ||
| 701 | |||
| 702 | static const struct attribute_group elan_baseline_sysfs_group = { | ||
| 703 | .name = "baseline", | ||
| 704 | .attrs = elan_baseline_sysfs_entries, | ||
| 705 | }; | ||
| 706 | |||
| 707 | static const struct attribute_group *elan_sysfs_groups[] = { | ||
| 708 | &elan_sysfs_group, | ||
| 709 | &elan_baseline_sysfs_group, | ||
| 710 | NULL | ||
| 711 | }; | ||
| 712 | |||
| 713 | /* | ||
| 714 | ****************************************************************** | ||
| 715 | * Elan isr functions | ||
| 716 | ****************************************************************** | ||
| 717 | */ | ||
| 718 | static void elan_report_contact(struct elan_tp_data *data, | ||
| 719 | int contact_num, bool contact_valid, | ||
| 720 | u8 *finger_data) | ||
| 721 | { | ||
| 722 | struct input_dev *input = data->input; | ||
| 723 | unsigned int pos_x, pos_y; | ||
| 724 | unsigned int pressure, mk_x, mk_y; | ||
| 725 | unsigned int area_x, area_y, major, minor, new_pressure; | ||
| 726 | |||
| 727 | |||
| 728 | if (contact_valid) { | ||
| 729 | pos_x = ((finger_data[0] & 0xf0) << 4) | | ||
| 730 | finger_data[1]; | ||
| 731 | pos_y = ((finger_data[0] & 0x0f) << 8) | | ||
| 732 | finger_data[2]; | ||
| 733 | mk_x = (finger_data[3] & 0x0f); | ||
| 734 | mk_y = (finger_data[3] >> 4); | ||
| 735 | pressure = finger_data[4]; | ||
| 736 | |||
| 737 | if (pos_x > data->max_x || pos_y > data->max_y) { | ||
| 738 | dev_dbg(input->dev.parent, | ||
| 739 | "[%d] x=%d y=%d over max (%d, %d)", | ||
| 740 | contact_num, pos_x, pos_y, | ||
| 741 | data->max_x, data->max_y); | ||
| 742 | return; | ||
| 743 | } | ||
| 744 | |||
| 745 | /* | ||
| 746 | * To avoid treating large finger as palm, let's reduce the | ||
| 747 | * width x and y per trace. | ||
| 748 | */ | ||
| 749 | area_x = mk_x * (data->width_x - ETP_FWIDTH_REDUCE); | ||
| 750 | area_y = mk_y * (data->width_y - ETP_FWIDTH_REDUCE); | ||
| 751 | |||
| 752 | major = max(area_x, area_y); | ||
| 753 | minor = min(area_x, area_y); | ||
| 754 | |||
| 755 | new_pressure = pressure + ETP_PRESSURE_OFFSET; | ||
| 756 | if (new_pressure > ETP_MAX_PRESSURE) | ||
| 757 | new_pressure = ETP_MAX_PRESSURE; | ||
| 758 | |||
| 759 | input_mt_slot(input, contact_num); | ||
| 760 | input_mt_report_slot_state(input, MT_TOOL_FINGER, true); | ||
| 761 | input_report_abs(input, ABS_MT_POSITION_X, pos_x); | ||
| 762 | input_report_abs(input, ABS_MT_POSITION_Y, data->max_y - pos_y); | ||
| 763 | input_report_abs(input, ABS_MT_PRESSURE, new_pressure); | ||
| 764 | input_report_abs(input, ABS_TOOL_WIDTH, mk_x); | ||
| 765 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, major); | ||
| 766 | input_report_abs(input, ABS_MT_TOUCH_MINOR, minor); | ||
| 767 | } else { | ||
| 768 | input_mt_slot(input, contact_num); | ||
| 769 | input_mt_report_slot_state(input, MT_TOOL_FINGER, false); | ||
| 770 | } | ||
| 771 | } | ||
| 772 | |||
| 773 | static void elan_report_absolute(struct elan_tp_data *data, u8 *packet) | ||
| 774 | { | ||
| 775 | struct input_dev *input = data->input; | ||
| 776 | u8 *finger_data = &packet[ETP_FINGER_DATA_OFFSET]; | ||
| 777 | int i; | ||
| 778 | u8 tp_info = packet[ETP_TOUCH_INFO_OFFSET]; | ||
| 779 | bool contact_valid; | ||
| 780 | |||
| 781 | for (i = 0; i < ETP_MAX_FINGERS; i++) { | ||
| 782 | contact_valid = tp_info & (1U << (3 + i)); | ||
| 783 | elan_report_contact(data, i, contact_valid, finger_data); | ||
| 784 | |||
| 785 | if (contact_valid) | ||
| 786 | finger_data += ETP_FINGER_DATA_LEN; | ||
| 787 | } | ||
| 788 | |||
| 789 | input_report_key(input, BTN_LEFT, tp_info & 0x01); | ||
| 790 | input_mt_report_pointer_emulation(input, true); | ||
| 791 | input_sync(input); | ||
| 792 | } | ||
| 793 | |||
| 794 | static irqreturn_t elan_isr(int irq, void *dev_id) | ||
| 795 | { | ||
| 796 | struct elan_tp_data *data = dev_id; | ||
| 797 | struct device *dev = &data->client->dev; | ||
| 798 | int error; | ||
| 799 | u8 report[ETP_MAX_REPORT_LEN]; | ||
| 800 | |||
| 801 | /* | ||
| 802 | * When device is connected to i2c bus, when all IAP page writes | ||
| 803 | * complete, the driver will receive interrupt and must read | ||
| 804 | * 0000 to confirm that IAP is finished. | ||
| 805 | */ | ||
| 806 | if (data->in_fw_update) { | ||
| 807 | complete(&data->fw_completion); | ||
| 808 | goto out; | ||
| 809 | } | ||
| 810 | |||
| 811 | error = data->ops->get_report(data->client, report); | ||
| 812 | if (error) | ||
| 813 | goto out; | ||
| 814 | |||
| 815 | if (report[ETP_REPORT_ID_OFFSET] != ETP_REPORT_ID) | ||
| 816 | dev_err(dev, "invalid report id data (%x)\n", | ||
| 817 | report[ETP_REPORT_ID_OFFSET]); | ||
| 818 | else | ||
| 819 | elan_report_absolute(data, report); | ||
| 820 | |||
| 821 | out: | ||
| 822 | return IRQ_HANDLED; | ||
| 823 | } | ||
| 824 | |||
| 825 | /* | ||
| 826 | ****************************************************************** | ||
| 827 | * Elan initialization functions | ||
| 828 | ****************************************************************** | ||
| 829 | */ | ||
| 830 | static int elan_setup_input_device(struct elan_tp_data *data) | ||
| 831 | { | ||
| 832 | struct device *dev = &data->client->dev; | ||
| 833 | struct input_dev *input; | ||
| 834 | unsigned int max_width = max(data->width_x, data->width_y); | ||
| 835 | unsigned int min_width = min(data->width_x, data->width_y); | ||
| 836 | int error; | ||
| 837 | |||
| 838 | input = devm_input_allocate_device(dev); | ||
| 839 | if (!input) | ||
| 840 | return -ENOMEM; | ||
| 841 | |||
| 842 | input->name = "Elan Touchpad"; | ||
| 843 | input->id.bustype = BUS_I2C; | ||
| 844 | input_set_drvdata(input, data); | ||
| 845 | |||
| 846 | error = input_mt_init_slots(input, ETP_MAX_FINGERS, | ||
| 847 | INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED); | ||
| 848 | if (error) { | ||
| 849 | dev_err(dev, "failed to initialize MT slots: %d\n", error); | ||
| 850 | return error; | ||
| 851 | } | ||
| 852 | |||
| 853 | __set_bit(EV_ABS, input->evbit); | ||
| 854 | __set_bit(INPUT_PROP_POINTER, input->propbit); | ||
| 855 | __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); | ||
| 856 | __set_bit(BTN_LEFT, input->keybit); | ||
| 857 | |||
| 858 | /* Set up ST parameters */ | ||
| 859 | input_set_abs_params(input, ABS_X, 0, data->max_x, 0, 0); | ||
| 860 | input_set_abs_params(input, ABS_Y, 0, data->max_y, 0, 0); | ||
| 861 | input_abs_set_res(input, ABS_X, data->x_res); | ||
| 862 | input_abs_set_res(input, ABS_Y, data->y_res); | ||
| 863 | input_set_abs_params(input, ABS_PRESSURE, 0, ETP_MAX_PRESSURE, 0, 0); | ||
| 864 | input_set_abs_params(input, ABS_TOOL_WIDTH, 0, ETP_FINGER_WIDTH, 0, 0); | ||
| 865 | |||
| 866 | /* And MT parameters */ | ||
| 867 | input_set_abs_params(input, ABS_MT_POSITION_X, 0, data->max_x, 0, 0); | ||
| 868 | input_set_abs_params(input, ABS_MT_POSITION_Y, 0, data->max_y, 0, 0); | ||
| 869 | input_abs_set_res(input, ABS_MT_POSITION_X, data->x_res); | ||
| 870 | input_abs_set_res(input, ABS_MT_POSITION_Y, data->y_res); | ||
| 871 | input_set_abs_params(input, ABS_MT_PRESSURE, 0, | ||
| 872 | ETP_MAX_PRESSURE, 0, 0); | ||
| 873 | input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, | ||
| 874 | ETP_FINGER_WIDTH * max_width, 0, 0); | ||
| 875 | input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, | ||
| 876 | ETP_FINGER_WIDTH * min_width, 0, 0); | ||
| 877 | |||
| 878 | data->input = input; | ||
| 879 | |||
| 880 | return 0; | ||
| 881 | } | ||
| 882 | |||
| 883 | static void elan_disable_regulator(void *_data) | ||
| 884 | { | ||
| 885 | struct elan_tp_data *data = _data; | ||
| 886 | |||
| 887 | regulator_disable(data->vcc); | ||
| 888 | } | ||
| 889 | |||
| 890 | static void elan_remove_sysfs_groups(void *_data) | ||
| 891 | { | ||
| 892 | struct elan_tp_data *data = _data; | ||
| 893 | |||
| 894 | sysfs_remove_groups(&data->client->dev.kobj, elan_sysfs_groups); | ||
| 895 | } | ||
| 896 | |||
| 897 | static int elan_probe(struct i2c_client *client, | ||
| 898 | const struct i2c_device_id *dev_id) | ||
| 899 | { | ||
| 900 | const struct elan_transport_ops *transport_ops; | ||
| 901 | struct device *dev = &client->dev; | ||
| 902 | struct elan_tp_data *data; | ||
| 903 | unsigned long irqflags; | ||
| 904 | int error; | ||
| 905 | |||
| 906 | if (IS_ENABLED(CONFIG_MOUSE_ELAN_I2C_I2C) && | ||
| 907 | i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { | ||
| 908 | transport_ops = &elan_i2c_ops; | ||
| 909 | } else if (IS_ENABLED(CONFIG_MOUSE_ELAN_I2C_SMBUS) && | ||
| 910 | i2c_check_functionality(client->adapter, | ||
| 911 | I2C_FUNC_SMBUS_BYTE_DATA | | ||
| 912 | I2C_FUNC_SMBUS_BLOCK_DATA | | ||
| 913 | I2C_FUNC_SMBUS_I2C_BLOCK)) { | ||
| 914 | transport_ops = &elan_smbus_ops; | ||
| 915 | } else { | ||
| 916 | dev_err(dev, "not a supported I2C/SMBus adapter\n"); | ||
| 917 | return -EIO; | ||
| 918 | } | ||
| 919 | |||
| 920 | data = devm_kzalloc(&client->dev, sizeof(struct elan_tp_data), | ||
| 921 | GFP_KERNEL); | ||
| 922 | if (!data) | ||
| 923 | return -ENOMEM; | ||
| 924 | |||
| 925 | i2c_set_clientdata(client, data); | ||
| 926 | |||
| 927 | data->ops = transport_ops; | ||
| 928 | data->client = client; | ||
| 929 | init_completion(&data->fw_completion); | ||
| 930 | mutex_init(&data->sysfs_mutex); | ||
| 931 | |||
| 932 | data->vcc = devm_regulator_get(&client->dev, "vcc"); | ||
| 933 | if (IS_ERR(data->vcc)) { | ||
| 934 | error = PTR_ERR(data->vcc); | ||
| 935 | if (error != -EPROBE_DEFER) | ||
| 936 | dev_err(&client->dev, | ||
| 937 | "Failed to get 'vcc' regulator: %d\n", | ||
| 938 | error); | ||
| 939 | return error; | ||
| 940 | } | ||
| 941 | |||
| 942 | error = regulator_enable(data->vcc); | ||
| 943 | if (error) { | ||
| 944 | dev_err(&client->dev, | ||
| 945 | "Failed to enable regulator: %d\n", error); | ||
| 946 | return error; | ||
| 947 | } | ||
| 948 | |||
| 949 | error = devm_add_action(&client->dev, | ||
| 950 | elan_disable_regulator, data); | ||
| 951 | if (error) { | ||
| 952 | regulator_disable(data->vcc); | ||
| 953 | dev_err(&client->dev, | ||
| 954 | "Failed to add disable regulator action: %d\n", | ||
| 955 | error); | ||
| 956 | return error; | ||
| 957 | } | ||
| 958 | |||
| 959 | /* Initialize the touchpad. */ | ||
| 960 | error = elan_initialize(data); | ||
| 961 | if (error) | ||
| 962 | return error; | ||
| 963 | |||
| 964 | error = elan_query_device_info(data); | ||
| 965 | if (error) | ||
| 966 | return error; | ||
| 967 | |||
| 968 | error = elan_query_device_parameters(data); | ||
| 969 | if (error) | ||
| 970 | return error; | ||
| 971 | |||
| 972 | dev_dbg(&client->dev, | ||
| 973 | "Elan Touchpad Information:\n" | ||
| 974 | " Module product ID: 0x%04x\n" | ||
| 975 | " Firmware Version: 0x%04x\n" | ||
| 976 | " Sample Version: 0x%04x\n" | ||
| 977 | " IAP Version: 0x%04x\n" | ||
| 978 | " Max ABS X,Y: %d,%d\n" | ||
| 979 | " Width X,Y: %d,%d\n" | ||
| 980 | " Resolution X,Y: %d,%d (dots/mm)\n", | ||
| 981 | data->product_id, | ||
| 982 | data->fw_version, | ||
| 983 | data->sm_version, | ||
| 984 | data->iap_version, | ||
| 985 | data->max_x, data->max_y, | ||
| 986 | data->width_x, data->width_y, | ||
| 987 | data->x_res, data->y_res); | ||
| 988 | |||
| 989 | /* Set up input device properties based on queried parameters. */ | ||
| 990 | error = elan_setup_input_device(data); | ||
| 991 | if (error) | ||
| 992 | return error; | ||
| 993 | |||
| 994 | /* | ||
| 995 | * Systems using device tree should set up interrupt via DTS, | ||
| 996 | * the rest will use the default falling edge interrupts. | ||
| 997 | */ | ||
| 998 | irqflags = client->dev.of_node ? 0 : IRQF_TRIGGER_FALLING; | ||
| 999 | |||
| 1000 | error = devm_request_threaded_irq(&client->dev, client->irq, | ||
| 1001 | NULL, elan_isr, | ||
| 1002 | irqflags | IRQF_ONESHOT, | ||
| 1003 | client->name, data); | ||
| 1004 | if (error) { | ||
| 1005 | dev_err(&client->dev, "cannot register irq=%d\n", client->irq); | ||
| 1006 | return error; | ||
| 1007 | } | ||
| 1008 | |||
| 1009 | error = sysfs_create_groups(&client->dev.kobj, elan_sysfs_groups); | ||
| 1010 | if (error) { | ||
| 1011 | dev_err(&client->dev, "failed to create sysfs attributes: %d\n", | ||
| 1012 | error); | ||
| 1013 | return error; | ||
| 1014 | } | ||
| 1015 | |||
| 1016 | error = devm_add_action(&client->dev, | ||
| 1017 | elan_remove_sysfs_groups, data); | ||
| 1018 | if (error) { | ||
| 1019 | elan_remove_sysfs_groups(data); | ||
| 1020 | dev_err(&client->dev, | ||
| 1021 | "Failed to add sysfs cleanup action: %d\n", | ||
| 1022 | error); | ||
| 1023 | return error; | ||
| 1024 | } | ||
| 1025 | |||
| 1026 | error = input_register_device(data->input); | ||
| 1027 | if (error) { | ||
| 1028 | dev_err(&client->dev, "failed to register input device: %d\n", | ||
| 1029 | error); | ||
| 1030 | return error; | ||
| 1031 | } | ||
| 1032 | |||
| 1033 | /* | ||
| 1034 | * Systems using device tree should set up wakeup via DTS, | ||
| 1035 | * the rest will configure device as wakeup source by default. | ||
| 1036 | */ | ||
| 1037 | if (!client->dev.of_node) | ||
| 1038 | device_init_wakeup(&client->dev, true); | ||
| 1039 | |||
| 1040 | return 0; | ||
| 1041 | } | ||
| 1042 | |||
| 1043 | static int __maybe_unused elan_suspend(struct device *dev) | ||
| 1044 | { | ||
| 1045 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1046 | struct elan_tp_data *data = i2c_get_clientdata(client); | ||
| 1047 | int ret; | ||
| 1048 | |||
| 1049 | /* | ||
| 1050 | * We are taking the mutex to make sure sysfs operations are | ||
| 1051 | * complete before we attempt to bring the device into low[er] | ||
| 1052 | * power mode. | ||
| 1053 | */ | ||
| 1054 | ret = mutex_lock_interruptible(&data->sysfs_mutex); | ||
| 1055 | if (ret) | ||
| 1056 | return ret; | ||
| 1057 | |||
| 1058 | disable_irq(client->irq); | ||
| 1059 | |||
| 1060 | if (device_may_wakeup(dev)) { | ||
| 1061 | ret = elan_sleep(data); | ||
| 1062 | /* Enable wake from IRQ */ | ||
| 1063 | data->irq_wake = (enable_irq_wake(client->irq) == 0); | ||
| 1064 | } else { | ||
| 1065 | ret = elan_disable_power(data); | ||
| 1066 | } | ||
| 1067 | |||
| 1068 | mutex_unlock(&data->sysfs_mutex); | ||
| 1069 | return ret; | ||
| 1070 | } | ||
| 1071 | |||
| 1072 | static int __maybe_unused elan_resume(struct device *dev) | ||
| 1073 | { | ||
| 1074 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1075 | struct elan_tp_data *data = i2c_get_clientdata(client); | ||
| 1076 | int error; | ||
| 1077 | |||
| 1078 | if (device_may_wakeup(dev) && data->irq_wake) { | ||
| 1079 | disable_irq_wake(client->irq); | ||
| 1080 | data->irq_wake = false; | ||
| 1081 | } | ||
| 1082 | |||
| 1083 | error = elan_enable_power(data); | ||
| 1084 | if (error) | ||
| 1085 | dev_err(dev, "power up when resuming failed: %d\n", error); | ||
| 1086 | |||
| 1087 | error = elan_initialize(data); | ||
| 1088 | if (error) | ||
| 1089 | dev_err(dev, "initialize when resuming failed: %d\n", error); | ||
| 1090 | |||
| 1091 | enable_irq(data->client->irq); | ||
| 1092 | |||
| 1093 | return 0; | ||
| 1094 | } | ||
| 1095 | |||
| 1096 | static SIMPLE_DEV_PM_OPS(elan_pm_ops, elan_suspend, elan_resume); | ||
| 1097 | |||
| 1098 | static const struct i2c_device_id elan_id[] = { | ||
| 1099 | { DRIVER_NAME, 0 }, | ||
| 1100 | { }, | ||
| 1101 | }; | ||
| 1102 | MODULE_DEVICE_TABLE(i2c, elan_id); | ||
| 1103 | |||
| 1104 | #ifdef CONFIG_ACPI | ||
| 1105 | static const struct acpi_device_id elan_acpi_id[] = { | ||
| 1106 | { "ELAN0000", 0 }, | ||
| 1107 | { } | ||
| 1108 | }; | ||
| 1109 | MODULE_DEVICE_TABLE(acpi, elan_acpi_id); | ||
| 1110 | #endif | ||
| 1111 | |||
| 1112 | #ifdef CONFIG_OF | ||
| 1113 | static const struct of_device_id elan_of_match[] = { | ||
| 1114 | { .compatible = "elan,ekth3000" }, | ||
| 1115 | { /* sentinel */ } | ||
| 1116 | }; | ||
| 1117 | MODULE_DEVICE_TABLE(of, elan_of_match); | ||
| 1118 | #endif | ||
| 1119 | |||
| 1120 | static struct i2c_driver elan_driver = { | ||
| 1121 | .driver = { | ||
| 1122 | .name = DRIVER_NAME, | ||
| 1123 | .owner = THIS_MODULE, | ||
| 1124 | .pm = &elan_pm_ops, | ||
| 1125 | .acpi_match_table = ACPI_PTR(elan_acpi_id), | ||
| 1126 | .of_match_table = of_match_ptr(elan_of_match), | ||
| 1127 | }, | ||
| 1128 | .probe = elan_probe, | ||
| 1129 | .id_table = elan_id, | ||
| 1130 | }; | ||
| 1131 | |||
| 1132 | module_i2c_driver(elan_driver); | ||
| 1133 | |||
| 1134 | MODULE_AUTHOR("Duson Lin <dusonlin@emc.com.tw>"); | ||
| 1135 | MODULE_DESCRIPTION("Elan I2C/SMBus Touchpad driver"); | ||
| 1136 | MODULE_LICENSE("GPL"); | ||
| 1137 | MODULE_VERSION(ELAN_DRIVER_VERSION); | ||
diff --git a/drivers/input/mouse/elan_i2c_i2c.c b/drivers/input/mouse/elan_i2c_i2c.c new file mode 100644 index 000000000000..97d4937fc244 --- /dev/null +++ b/drivers/input/mouse/elan_i2c_i2c.c | |||
| @@ -0,0 +1,611 @@ | |||
| 1 | /* | ||
| 2 | * Elan I2C/SMBus Touchpad driver - I2C interface | ||
| 3 | * | ||
| 4 | * Copyright (c) 2013 ELAN Microelectronics Corp. | ||
| 5 | * | ||
| 6 | * Author: æž—æ”¿ç¶ (Duson Lin) <dusonlin@emc.com.tw> | ||
| 7 | * Version: 1.5.5 | ||
| 8 | * | ||
| 9 | * Based on cyapa driver: | ||
| 10 | * copyright (c) 2011-2012 Cypress Semiconductor, Inc. | ||
| 11 | * copyright (c) 2011-2012 Google, Inc. | ||
| 12 | * | ||
| 13 | * This program is free software; you can redistribute it and/or modify it | ||
| 14 | * under the terms of the GNU General Public License version 2 as published | ||
| 15 | * by the Free Software Foundation. | ||
| 16 | * | ||
| 17 | * Trademarks are the property of their respective owners. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <linux/completion.h> | ||
| 21 | #include <linux/delay.h> | ||
| 22 | #include <linux/i2c.h> | ||
| 23 | #include <linux/interrupt.h> | ||
| 24 | #include <linux/jiffies.h> | ||
| 25 | #include <linux/kernel.h> | ||
| 26 | #include <linux/sched.h> | ||
| 27 | #include <asm/unaligned.h> | ||
| 28 | |||
| 29 | #include "elan_i2c.h" | ||
| 30 | |||
| 31 | /* Elan i2c commands */ | ||
| 32 | #define ETP_I2C_RESET 0x0100 | ||
| 33 | #define ETP_I2C_WAKE_UP 0x0800 | ||
| 34 | #define ETP_I2C_SLEEP 0x0801 | ||
| 35 | #define ETP_I2C_DESC_CMD 0x0001 | ||
| 36 | #define ETP_I2C_REPORT_DESC_CMD 0x0002 | ||
| 37 | #define ETP_I2C_STAND_CMD 0x0005 | ||
| 38 | #define ETP_I2C_UNIQUEID_CMD 0x0101 | ||
| 39 | #define ETP_I2C_FW_VERSION_CMD 0x0102 | ||
| 40 | #define ETP_I2C_SM_VERSION_CMD 0x0103 | ||
| 41 | #define ETP_I2C_XY_TRACENUM_CMD 0x0105 | ||
| 42 | #define ETP_I2C_MAX_X_AXIS_CMD 0x0106 | ||
| 43 | #define ETP_I2C_MAX_Y_AXIS_CMD 0x0107 | ||
| 44 | #define ETP_I2C_RESOLUTION_CMD 0x0108 | ||
| 45 | #define ETP_I2C_IAP_VERSION_CMD 0x0110 | ||
| 46 | #define ETP_I2C_SET_CMD 0x0300 | ||
| 47 | #define ETP_I2C_POWER_CMD 0x0307 | ||
| 48 | #define ETP_I2C_FW_CHECKSUM_CMD 0x030F | ||
| 49 | #define ETP_I2C_IAP_CTRL_CMD 0x0310 | ||
| 50 | #define ETP_I2C_IAP_CMD 0x0311 | ||
| 51 | #define ETP_I2C_IAP_RESET_CMD 0x0314 | ||
| 52 | #define ETP_I2C_IAP_CHECKSUM_CMD 0x0315 | ||
| 53 | #define ETP_I2C_CALIBRATE_CMD 0x0316 | ||
| 54 | #define ETP_I2C_MAX_BASELINE_CMD 0x0317 | ||
| 55 | #define ETP_I2C_MIN_BASELINE_CMD 0x0318 | ||
| 56 | |||
| 57 | #define ETP_I2C_REPORT_LEN 34 | ||
| 58 | #define ETP_I2C_DESC_LENGTH 30 | ||
| 59 | #define ETP_I2C_REPORT_DESC_LENGTH 158 | ||
| 60 | #define ETP_I2C_INF_LENGTH 2 | ||
| 61 | #define ETP_I2C_IAP_PASSWORD 0x1EA5 | ||
| 62 | #define ETP_I2C_IAP_RESET 0xF0F0 | ||
| 63 | #define ETP_I2C_MAIN_MODE_ON (1 << 9) | ||
| 64 | #define ETP_I2C_IAP_REG_L 0x01 | ||
| 65 | #define ETP_I2C_IAP_REG_H 0x06 | ||
| 66 | |||
| 67 | static int elan_i2c_read_block(struct i2c_client *client, | ||
| 68 | u16 reg, u8 *val, u16 len) | ||
| 69 | { | ||
| 70 | __le16 buf[] = { | ||
| 71 | cpu_to_le16(reg), | ||
| 72 | }; | ||
| 73 | struct i2c_msg msgs[] = { | ||
| 74 | { | ||
| 75 | .addr = client->addr, | ||
| 76 | .flags = client->flags & I2C_M_TEN, | ||
| 77 | .len = sizeof(buf), | ||
| 78 | .buf = (u8 *)buf, | ||
| 79 | }, | ||
| 80 | { | ||
| 81 | .addr = client->addr, | ||
| 82 | .flags = (client->flags & I2C_M_TEN) | I2C_M_RD, | ||
| 83 | .len = len, | ||
| 84 | .buf = val, | ||
| 85 | } | ||
| 86 | }; | ||
| 87 | int ret; | ||
| 88 | |||
| 89 | ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); | ||
| 90 | return ret == ARRAY_SIZE(msgs) ? 0 : (ret < 0 ? ret : -EIO); | ||
| 91 | } | ||
| 92 | |||
| 93 | static int elan_i2c_read_cmd(struct i2c_client *client, u16 reg, u8 *val) | ||
| 94 | { | ||
| 95 | int retval; | ||
| 96 | |||
| 97 | retval = elan_i2c_read_block(client, reg, val, ETP_I2C_INF_LENGTH); | ||
| 98 | if (retval < 0) { | ||
| 99 | dev_err(&client->dev, "reading cmd (0x%04x) fail.\n", reg); | ||
| 100 | return retval; | ||
| 101 | } | ||
| 102 | |||
| 103 | return 0; | ||
| 104 | } | ||
| 105 | |||
| 106 | static int elan_i2c_write_cmd(struct i2c_client *client, u16 reg, u16 cmd) | ||
| 107 | { | ||
| 108 | __le16 buf[] = { | ||
| 109 | cpu_to_le16(reg), | ||
| 110 | cpu_to_le16(cmd), | ||
| 111 | }; | ||
| 112 | struct i2c_msg msg = { | ||
| 113 | .addr = client->addr, | ||
| 114 | .flags = client->flags & I2C_M_TEN, | ||
| 115 | .len = sizeof(buf), | ||
| 116 | .buf = (u8 *)buf, | ||
| 117 | }; | ||
| 118 | int ret; | ||
| 119 | |||
| 120 | ret = i2c_transfer(client->adapter, &msg, 1); | ||
| 121 | return ret == 1 ? 0 : (ret < 0 ? ret : -EIO); | ||
| 122 | } | ||
| 123 | |||
| 124 | static int elan_i2c_initialize(struct i2c_client *client) | ||
| 125 | { | ||
| 126 | struct device *dev = &client->dev; | ||
| 127 | int error; | ||
| 128 | u8 val[256]; | ||
| 129 | |||
| 130 | error = elan_i2c_write_cmd(client, ETP_I2C_STAND_CMD, ETP_I2C_RESET); | ||
| 131 | if (error) { | ||
| 132 | dev_err(dev, "device reset failed: %d\n", error); | ||
| 133 | return error; | ||
| 134 | } | ||
| 135 | |||
| 136 | /* Wait for the device to reset */ | ||
| 137 | msleep(100); | ||
| 138 | |||
| 139 | /* get reset acknowledgement 0000 */ | ||
| 140 | error = i2c_master_recv(client, val, ETP_I2C_INF_LENGTH); | ||
| 141 | if (error < 0) { | ||
| 142 | dev_err(dev, "failed to read reset response: %d\n", error); | ||
| 143 | return error; | ||
| 144 | } | ||
| 145 | |||
| 146 | error = elan_i2c_read_block(client, ETP_I2C_DESC_CMD, | ||
| 147 | val, ETP_I2C_DESC_LENGTH); | ||
| 148 | if (error) { | ||
| 149 | dev_err(dev, "cannot get device descriptor: %d\n", error); | ||
| 150 | return error; | ||
| 151 | } | ||
| 152 | |||
| 153 | error = elan_i2c_read_block(client, ETP_I2C_REPORT_DESC_CMD, | ||
| 154 | val, ETP_I2C_REPORT_DESC_LENGTH); | ||
| 155 | if (error) { | ||
| 156 | dev_err(dev, "fetching report descriptor failed.: %d\n", error); | ||
| 157 | return error; | ||
| 158 | } | ||
| 159 | |||
| 160 | return 0; | ||
| 161 | } | ||
| 162 | |||
| 163 | static int elan_i2c_sleep_control(struct i2c_client *client, bool sleep) | ||
| 164 | { | ||
| 165 | return elan_i2c_write_cmd(client, ETP_I2C_STAND_CMD, | ||
| 166 | sleep ? ETP_I2C_SLEEP : ETP_I2C_WAKE_UP); | ||
| 167 | } | ||
| 168 | |||
| 169 | static int elan_i2c_power_control(struct i2c_client *client, bool enable) | ||
| 170 | { | ||
| 171 | u8 val[2]; | ||
| 172 | u16 reg; | ||
| 173 | int error; | ||
| 174 | |||
| 175 | error = elan_i2c_read_cmd(client, ETP_I2C_POWER_CMD, val); | ||
| 176 | if (error) { | ||
| 177 | dev_err(&client->dev, | ||
| 178 | "failed to read current power state: %d\n", | ||
| 179 | error); | ||
| 180 | return error; | ||
| 181 | } | ||
| 182 | |||
| 183 | reg = le16_to_cpup((__le16 *)val); | ||
| 184 | if (enable) | ||
| 185 | reg &= ~ETP_DISABLE_POWER; | ||
| 186 | else | ||
| 187 | reg |= ETP_DISABLE_POWER; | ||
| 188 | |||
| 189 | error = elan_i2c_write_cmd(client, ETP_I2C_POWER_CMD, reg); | ||
| 190 | if (error) { | ||
| 191 | dev_err(&client->dev, | ||
| 192 | "failed to write current power state: %d\n", | ||
| 193 | error); | ||
| 194 | return error; | ||
| 195 | } | ||
| 196 | |||
| 197 | return 0; | ||
| 198 | } | ||
| 199 | |||
| 200 | static int elan_i2c_set_mode(struct i2c_client *client, u8 mode) | ||
| 201 | { | ||
| 202 | return elan_i2c_write_cmd(client, ETP_I2C_SET_CMD, mode); | ||
| 203 | } | ||
| 204 | |||
| 205 | |||
| 206 | static int elan_i2c_calibrate(struct i2c_client *client) | ||
| 207 | { | ||
| 208 | return elan_i2c_write_cmd(client, ETP_I2C_CALIBRATE_CMD, 1); | ||
| 209 | } | ||
| 210 | |||
| 211 | static int elan_i2c_calibrate_result(struct i2c_client *client, u8 *val) | ||
| 212 | { | ||
| 213 | return elan_i2c_read_block(client, ETP_I2C_CALIBRATE_CMD, val, 1); | ||
| 214 | } | ||
| 215 | |||
| 216 | static int elan_i2c_get_baseline_data(struct i2c_client *client, | ||
| 217 | bool max_baseline, u8 *value) | ||
| 218 | { | ||
| 219 | int error; | ||
| 220 | u8 val[3]; | ||
| 221 | |||
| 222 | error = elan_i2c_read_cmd(client, | ||
| 223 | max_baseline ? ETP_I2C_MAX_BASELINE_CMD : | ||
| 224 | ETP_I2C_MIN_BASELINE_CMD, | ||
| 225 | val); | ||
| 226 | if (error) | ||
| 227 | return error; | ||
| 228 | |||
| 229 | *value = le16_to_cpup((__le16 *)val); | ||
| 230 | |||
| 231 | return 0; | ||
| 232 | } | ||
| 233 | |||
| 234 | static int elan_i2c_get_version(struct i2c_client *client, | ||
| 235 | bool iap, u8 *version) | ||
| 236 | { | ||
| 237 | int error; | ||
| 238 | u8 val[3]; | ||
| 239 | |||
| 240 | error = elan_i2c_read_cmd(client, | ||
| 241 | iap ? ETP_I2C_IAP_VERSION_CMD : | ||
| 242 | ETP_I2C_FW_VERSION_CMD, | ||
| 243 | val); | ||
| 244 | if (error) { | ||
| 245 | dev_err(&client->dev, "failed to get %s version: %d\n", | ||
| 246 | iap ? "IAP" : "FW", error); | ||
| 247 | return error; | ||
| 248 | } | ||
| 249 | |||
| 250 | *version = val[0]; | ||
| 251 | return 0; | ||
| 252 | } | ||
| 253 | |||
| 254 | static int elan_i2c_get_sm_version(struct i2c_client *client, u8 *version) | ||
| 255 | { | ||
| 256 | int error; | ||
| 257 | u8 val[3]; | ||
| 258 | |||
| 259 | error = elan_i2c_read_cmd(client, ETP_I2C_SM_VERSION_CMD, val); | ||
| 260 | if (error) { | ||
| 261 | dev_err(&client->dev, "failed to get SM version: %d\n", error); | ||
| 262 | return error; | ||
| 263 | } | ||
| 264 | |||
| 265 | *version = val[0]; | ||
| 266 | return 0; | ||
| 267 | } | ||
| 268 | |||
| 269 | static int elan_i2c_get_product_id(struct i2c_client *client, u8 *id) | ||
| 270 | { | ||
| 271 | int error; | ||
| 272 | u8 val[3]; | ||
| 273 | |||
| 274 | error = elan_i2c_read_cmd(client, ETP_I2C_UNIQUEID_CMD, val); | ||
| 275 | if (error) { | ||
| 276 | dev_err(&client->dev, "failed to get product ID: %d\n", error); | ||
| 277 | return error; | ||
| 278 | } | ||
| 279 | |||
| 280 | *id = val[0]; | ||
| 281 | return 0; | ||
| 282 | } | ||
| 283 | |||
| 284 | static int elan_i2c_get_checksum(struct i2c_client *client, | ||
| 285 | bool iap, u16 *csum) | ||
| 286 | { | ||
| 287 | int error; | ||
| 288 | u8 val[3]; | ||
| 289 | |||
| 290 | error = elan_i2c_read_cmd(client, | ||
| 291 | iap ? ETP_I2C_IAP_CHECKSUM_CMD : | ||
| 292 | ETP_I2C_FW_CHECKSUM_CMD, | ||
| 293 | val); | ||
| 294 | if (error) { | ||
| 295 | dev_err(&client->dev, "failed to get %s checksum: %d\n", | ||
| 296 | iap ? "IAP" : "FW", error); | ||
| 297 | return error; | ||
| 298 | } | ||
| 299 | |||
| 300 | *csum = le16_to_cpup((__le16 *)val); | ||
| 301 | return 0; | ||
| 302 | } | ||
| 303 | |||
| 304 | static int elan_i2c_get_max(struct i2c_client *client, | ||
| 305 | unsigned int *max_x, unsigned int *max_y) | ||
| 306 | { | ||
| 307 | int error; | ||
| 308 | u8 val[3]; | ||
| 309 | |||
| 310 | error = elan_i2c_read_cmd(client, ETP_I2C_MAX_X_AXIS_CMD, val); | ||
| 311 | if (error) { | ||
| 312 | dev_err(&client->dev, "failed to get X dimension: %d\n", error); | ||
| 313 | return error; | ||
| 314 | } | ||
| 315 | |||
| 316 | *max_x = le16_to_cpup((__le16 *)val) & 0x0fff; | ||
| 317 | |||
| 318 | error = elan_i2c_read_cmd(client, ETP_I2C_MAX_Y_AXIS_CMD, val); | ||
| 319 | if (error) { | ||
| 320 | dev_err(&client->dev, "failed to get Y dimension: %d\n", error); | ||
| 321 | return error; | ||
| 322 | } | ||
| 323 | |||
| 324 | *max_y = le16_to_cpup((__le16 *)val) & 0x0fff; | ||
| 325 | |||
| 326 | return 0; | ||
| 327 | } | ||
| 328 | |||
| 329 | static int elan_i2c_get_resolution(struct i2c_client *client, | ||
| 330 | u8 *hw_res_x, u8 *hw_res_y) | ||
| 331 | { | ||
| 332 | int error; | ||
| 333 | u8 val[3]; | ||
| 334 | |||
| 335 | error = elan_i2c_read_cmd(client, ETP_I2C_RESOLUTION_CMD, val); | ||
| 336 | if (error) { | ||
| 337 | dev_err(&client->dev, "failed to get resolution: %d\n", error); | ||
| 338 | return error; | ||
| 339 | } | ||
| 340 | |||
| 341 | *hw_res_x = val[0]; | ||
| 342 | *hw_res_y = val[1]; | ||
| 343 | |||
| 344 | return 0; | ||
| 345 | } | ||
| 346 | |||
| 347 | static int elan_i2c_get_num_traces(struct i2c_client *client, | ||
| 348 | unsigned int *x_traces, | ||
| 349 | unsigned int *y_traces) | ||
| 350 | { | ||
| 351 | int error; | ||
| 352 | u8 val[3]; | ||
| 353 | |||
| 354 | error = elan_i2c_read_cmd(client, ETP_I2C_XY_TRACENUM_CMD, val); | ||
| 355 | if (error) { | ||
| 356 | dev_err(&client->dev, "failed to get trace info: %d\n", error); | ||
| 357 | return error; | ||
| 358 | } | ||
| 359 | |||
| 360 | *x_traces = val[0] - 1; | ||
| 361 | *y_traces = val[1] - 1; | ||
| 362 | |||
| 363 | return 0; | ||
| 364 | } | ||
| 365 | |||
| 366 | static int elan_i2c_iap_get_mode(struct i2c_client *client, enum tp_mode *mode) | ||
| 367 | { | ||
| 368 | int error; | ||
| 369 | u16 constant; | ||
| 370 | u8 val[3]; | ||
| 371 | |||
| 372 | error = elan_i2c_read_cmd(client, ETP_I2C_IAP_CTRL_CMD, val); | ||
| 373 | if (error) { | ||
| 374 | dev_err(&client->dev, | ||
| 375 | "failed to read iap control register: %d\n", | ||
| 376 | error); | ||
| 377 | return error; | ||
| 378 | } | ||
| 379 | |||
| 380 | constant = le16_to_cpup((__le16 *)val); | ||
| 381 | dev_dbg(&client->dev, "iap control reg: 0x%04x.\n", constant); | ||
| 382 | |||
| 383 | *mode = (constant & ETP_I2C_MAIN_MODE_ON) ? MAIN_MODE : IAP_MODE; | ||
| 384 | |||
| 385 | return 0; | ||
| 386 | } | ||
| 387 | |||
| 388 | static int elan_i2c_iap_reset(struct i2c_client *client) | ||
| 389 | { | ||
| 390 | int error; | ||
| 391 | |||
| 392 | error = elan_i2c_write_cmd(client, ETP_I2C_IAP_RESET_CMD, | ||
| 393 | ETP_I2C_IAP_RESET); | ||
| 394 | if (error) { | ||
| 395 | dev_err(&client->dev, "cannot reset IC: %d\n", error); | ||
| 396 | return error; | ||
| 397 | } | ||
| 398 | |||
| 399 | return 0; | ||
| 400 | } | ||
| 401 | |||
| 402 | static int elan_i2c_set_flash_key(struct i2c_client *client) | ||
| 403 | { | ||
| 404 | int error; | ||
| 405 | |||
| 406 | error = elan_i2c_write_cmd(client, ETP_I2C_IAP_CMD, | ||
| 407 | ETP_I2C_IAP_PASSWORD); | ||
| 408 | if (error) { | ||
| 409 | dev_err(&client->dev, "cannot set flash key: %d\n", error); | ||
| 410 | return error; | ||
| 411 | } | ||
| 412 | |||
| 413 | return 0; | ||
| 414 | } | ||
| 415 | |||
| 416 | static int elan_i2c_prepare_fw_update(struct i2c_client *client) | ||
| 417 | { | ||
| 418 | struct device *dev = &client->dev; | ||
| 419 | int error; | ||
| 420 | enum tp_mode mode; | ||
| 421 | u8 val[3]; | ||
| 422 | u16 password; | ||
| 423 | |||
| 424 | /* Get FW in which mode (IAP_MODE/MAIN_MODE) */ | ||
| 425 | error = elan_i2c_iap_get_mode(client, &mode); | ||
| 426 | if (error) | ||
| 427 | return error; | ||
| 428 | |||
| 429 | if (mode == IAP_MODE) { | ||
| 430 | /* Reset IC */ | ||
| 431 | error = elan_i2c_iap_reset(client); | ||
| 432 | if (error) | ||
| 433 | return error; | ||
| 434 | |||
| 435 | msleep(30); | ||
| 436 | } | ||
| 437 | |||
| 438 | /* Set flash key*/ | ||
| 439 | error = elan_i2c_set_flash_key(client); | ||
| 440 | if (error) | ||
| 441 | return error; | ||
| 442 | |||
| 443 | /* Wait for F/W IAP initialization */ | ||
| 444 | msleep(mode == MAIN_MODE ? 100 : 30); | ||
| 445 | |||
| 446 | /* Check if we are in IAP mode or not */ | ||
| 447 | error = elan_i2c_iap_get_mode(client, &mode); | ||
| 448 | if (error) | ||
| 449 | return error; | ||
| 450 | |||
| 451 | if (mode == MAIN_MODE) { | ||
| 452 | dev_err(dev, "wrong mode: %d\n", mode); | ||
| 453 | return -EIO; | ||
| 454 | } | ||
| 455 | |||
| 456 | /* Set flash key again */ | ||
| 457 | error = elan_i2c_set_flash_key(client); | ||
| 458 | if (error) | ||
| 459 | return error; | ||
| 460 | |||
| 461 | /* Wait for F/W IAP initialization */ | ||
| 462 | msleep(30); | ||
| 463 | |||
| 464 | /* read back to check we actually enabled successfully. */ | ||
| 465 | error = elan_i2c_read_cmd(client, ETP_I2C_IAP_CMD, val); | ||
| 466 | if (error) { | ||
| 467 | dev_err(dev, "cannot read iap password: %d\n", | ||
| 468 | error); | ||
| 469 | return error; | ||
| 470 | } | ||
| 471 | |||
| 472 | password = le16_to_cpup((__le16 *)val); | ||
| 473 | if (password != ETP_I2C_IAP_PASSWORD) { | ||
| 474 | dev_err(dev, "wrong iap password: 0x%X\n", password); | ||
| 475 | return -EIO; | ||
| 476 | } | ||
| 477 | |||
| 478 | return 0; | ||
| 479 | } | ||
| 480 | |||
| 481 | static int elan_i2c_write_fw_block(struct i2c_client *client, | ||
| 482 | const u8 *page, u16 checksum, int idx) | ||
| 483 | { | ||
| 484 | struct device *dev = &client->dev; | ||
| 485 | u8 page_store[ETP_FW_PAGE_SIZE + 4]; | ||
| 486 | u8 val[3]; | ||
| 487 | u16 result; | ||
| 488 | int ret, error; | ||
| 489 | |||
| 490 | page_store[0] = ETP_I2C_IAP_REG_L; | ||
| 491 | page_store[1] = ETP_I2C_IAP_REG_H; | ||
| 492 | memcpy(&page_store[2], page, ETP_FW_PAGE_SIZE); | ||
| 493 | /* recode checksum at last two bytes */ | ||
| 494 | put_unaligned_le16(checksum, &page_store[ETP_FW_PAGE_SIZE + 2]); | ||
| 495 | |||
| 496 | ret = i2c_master_send(client, page_store, sizeof(page_store)); | ||
| 497 | if (ret != sizeof(page_store)) { | ||
| 498 | error = ret < 0 ? ret : -EIO; | ||
| 499 | dev_err(dev, "Failed to write page %d: %d\n", idx, error); | ||
| 500 | return error; | ||
| 501 | } | ||
| 502 | |||
| 503 | /* Wait for F/W to update one page ROM data. */ | ||
| 504 | msleep(20); | ||
| 505 | |||
| 506 | error = elan_i2c_read_cmd(client, ETP_I2C_IAP_CTRL_CMD, val); | ||
| 507 | if (error) { | ||
| 508 | dev_err(dev, "Failed to read IAP write result: %d\n", error); | ||
| 509 | return error; | ||
| 510 | } | ||
| 511 | |||
| 512 | result = le16_to_cpup((__le16 *)val); | ||
| 513 | if (result & (ETP_FW_IAP_PAGE_ERR | ETP_FW_IAP_INTF_ERR)) { | ||
| 514 | dev_err(dev, "IAP reports failed write: %04hx\n", | ||
| 515 | result); | ||
| 516 | return -EIO; | ||
| 517 | } | ||
| 518 | |||
| 519 | return 0; | ||
| 520 | } | ||
| 521 | |||
| 522 | static int elan_i2c_finish_fw_update(struct i2c_client *client, | ||
| 523 | struct completion *completion) | ||
| 524 | { | ||
| 525 | struct device *dev = &client->dev; | ||
| 526 | long ret; | ||
| 527 | int error; | ||
| 528 | int len; | ||
| 529 | u8 buffer[ETP_I2C_INF_LENGTH]; | ||
| 530 | |||
| 531 | reinit_completion(completion); | ||
| 532 | enable_irq(client->irq); | ||
| 533 | |||
| 534 | error = elan_i2c_write_cmd(client, ETP_I2C_STAND_CMD, ETP_I2C_RESET); | ||
| 535 | if (!error) | ||
| 536 | ret = wait_for_completion_interruptible_timeout(completion, | ||
| 537 | msecs_to_jiffies(300)); | ||
| 538 | disable_irq(client->irq); | ||
| 539 | |||
| 540 | if (error) { | ||
| 541 | dev_err(dev, "device reset failed: %d\n", error); | ||
| 542 | return error; | ||
| 543 | } else if (ret == 0) { | ||
| 544 | dev_err(dev, "timeout waiting for device reset\n"); | ||
| 545 | return -ETIMEDOUT; | ||
| 546 | } else if (ret < 0) { | ||
| 547 | error = ret; | ||
| 548 | dev_err(dev, "error waiting for device reset: %d\n", error); | ||
| 549 | return error; | ||
| 550 | } | ||
| 551 | |||
| 552 | len = i2c_master_recv(client, buffer, ETP_I2C_INF_LENGTH); | ||
| 553 | if (len != ETP_I2C_INF_LENGTH) { | ||
| 554 | error = len < 0 ? len : -EIO; | ||
| 555 | dev_err(dev, "failed to read INT signal: %d (%d)\n", | ||
| 556 | error, len); | ||
| 557 | return error; | ||
| 558 | } | ||
| 559 | |||
| 560 | return 0; | ||
| 561 | } | ||
| 562 | |||
| 563 | static int elan_i2c_get_report(struct i2c_client *client, u8 *report) | ||
| 564 | { | ||
| 565 | int len; | ||
| 566 | |||
| 567 | len = i2c_master_recv(client, report, ETP_I2C_REPORT_LEN); | ||
| 568 | if (len < 0) { | ||
| 569 | dev_err(&client->dev, "failed to read report data: %d\n", len); | ||
| 570 | return len; | ||
| 571 | } | ||
| 572 | |||
| 573 | if (len != ETP_I2C_REPORT_LEN) { | ||
| 574 | dev_err(&client->dev, | ||
| 575 | "wrong report length (%d vs %d expected)\n", | ||
| 576 | len, ETP_I2C_REPORT_LEN); | ||
| 577 | return -EIO; | ||
| 578 | } | ||
| 579 | |||
| 580 | return 0; | ||
| 581 | } | ||
| 582 | |||
| 583 | const struct elan_transport_ops elan_i2c_ops = { | ||
| 584 | .initialize = elan_i2c_initialize, | ||
| 585 | .sleep_control = elan_i2c_sleep_control, | ||
| 586 | .power_control = elan_i2c_power_control, | ||
| 587 | .set_mode = elan_i2c_set_mode, | ||
| 588 | |||
| 589 | .calibrate = elan_i2c_calibrate, | ||
| 590 | .calibrate_result = elan_i2c_calibrate_result, | ||
| 591 | |||
| 592 | .get_baseline_data = elan_i2c_get_baseline_data, | ||
| 593 | |||
| 594 | .get_version = elan_i2c_get_version, | ||
| 595 | .get_sm_version = elan_i2c_get_sm_version, | ||
| 596 | .get_product_id = elan_i2c_get_product_id, | ||
| 597 | .get_checksum = elan_i2c_get_checksum, | ||
| 598 | |||
| 599 | .get_max = elan_i2c_get_max, | ||
| 600 | .get_resolution = elan_i2c_get_resolution, | ||
| 601 | .get_num_traces = elan_i2c_get_num_traces, | ||
| 602 | |||
| 603 | .iap_get_mode = elan_i2c_iap_get_mode, | ||
| 604 | .iap_reset = elan_i2c_iap_reset, | ||
| 605 | |||
| 606 | .prepare_fw_update = elan_i2c_prepare_fw_update, | ||
| 607 | .write_fw_block = elan_i2c_write_fw_block, | ||
| 608 | .finish_fw_update = elan_i2c_finish_fw_update, | ||
| 609 | |||
| 610 | .get_report = elan_i2c_get_report, | ||
| 611 | }; | ||
diff --git a/drivers/input/mouse/elan_i2c_smbus.c b/drivers/input/mouse/elan_i2c_smbus.c new file mode 100644 index 000000000000..359bf8583d54 --- /dev/null +++ b/drivers/input/mouse/elan_i2c_smbus.c | |||
| @@ -0,0 +1,514 @@ | |||
| 1 | /* | ||
| 2 | * Elan I2C/SMBus Touchpad driver - SMBus interface | ||
| 3 | * | ||
| 4 | * Copyright (c) 2013 ELAN Microelectronics Corp. | ||
| 5 | * | ||
| 6 | * Author: æž—æ”¿ç¶ (Duson Lin) <dusonlin@emc.com.tw> | ||
| 7 | * Version: 1.5.5 | ||
| 8 | * | ||
| 9 | * Based on cyapa driver: | ||
| 10 | * copyright (c) 2011-2012 Cypress Semiconductor, Inc. | ||
| 11 | * copyright (c) 2011-2012 Google, Inc. | ||
| 12 | * | ||
| 13 | * This program is free software; you can redistribute it and/or modify it | ||
| 14 | * under the terms of the GNU General Public License version 2 as published | ||
| 15 | * by the Free Software Foundation. | ||
| 16 | * | ||
| 17 | * Trademarks are the property of their respective owners. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <linux/delay.h> | ||
| 21 | #include <linux/i2c.h> | ||
| 22 | #include <linux/init.h> | ||
| 23 | #include <linux/kernel.h> | ||
| 24 | |||
| 25 | #include "elan_i2c.h" | ||
| 26 | |||
| 27 | /* Elan SMbus commands */ | ||
| 28 | #define ETP_SMBUS_IAP_CMD 0x00 | ||
| 29 | #define ETP_SMBUS_ENABLE_TP 0x20 | ||
| 30 | #define ETP_SMBUS_SLEEP_CMD 0x21 | ||
| 31 | #define ETP_SMBUS_IAP_PASSWORD_WRITE 0x29 | ||
| 32 | #define ETP_SMBUS_IAP_PASSWORD_READ 0x80 | ||
| 33 | #define ETP_SMBUS_WRITE_FW_BLOCK 0x2A | ||
| 34 | #define ETP_SMBUS_IAP_RESET_CMD 0x2B | ||
| 35 | #define ETP_SMBUS_RANGE_CMD 0xA0 | ||
| 36 | #define ETP_SMBUS_FW_VERSION_CMD 0xA1 | ||
| 37 | #define ETP_SMBUS_XY_TRACENUM_CMD 0xA2 | ||
| 38 | #define ETP_SMBUS_SM_VERSION_CMD 0xA3 | ||
| 39 | #define ETP_SMBUS_UNIQUEID_CMD 0xA3 | ||
| 40 | #define ETP_SMBUS_RESOLUTION_CMD 0xA4 | ||
| 41 | #define ETP_SMBUS_HELLOPACKET_CMD 0xA7 | ||
| 42 | #define ETP_SMBUS_PACKET_QUERY 0xA8 | ||
| 43 | #define ETP_SMBUS_IAP_VERSION_CMD 0xAC | ||
| 44 | #define ETP_SMBUS_IAP_CTRL_CMD 0xAD | ||
| 45 | #define ETP_SMBUS_IAP_CHECKSUM_CMD 0xAE | ||
| 46 | #define ETP_SMBUS_FW_CHECKSUM_CMD 0xAF | ||
| 47 | #define ETP_SMBUS_MAX_BASELINE_CMD 0xC3 | ||
| 48 | #define ETP_SMBUS_MIN_BASELINE_CMD 0xC4 | ||
| 49 | #define ETP_SMBUS_CALIBRATE_QUERY 0xC5 | ||
| 50 | |||
| 51 | #define ETP_SMBUS_REPORT_LEN 32 | ||
| 52 | #define ETP_SMBUS_REPORT_OFFSET 2 | ||
| 53 | #define ETP_SMBUS_HELLOPACKET_LEN 5 | ||
| 54 | #define ETP_SMBUS_IAP_PASSWORD 0x1234 | ||
| 55 | #define ETP_SMBUS_IAP_MODE_ON (1 << 6) | ||
| 56 | |||
| 57 | static int elan_smbus_initialize(struct i2c_client *client) | ||
| 58 | { | ||
| 59 | u8 check[ETP_SMBUS_HELLOPACKET_LEN] = { 0x55, 0x55, 0x55, 0x55, 0x55 }; | ||
| 60 | u8 values[ETP_SMBUS_HELLOPACKET_LEN] = { 0, 0, 0, 0, 0 }; | ||
| 61 | int len, error; | ||
| 62 | |||
| 63 | /* Get hello packet */ | ||
| 64 | len = i2c_smbus_read_block_data(client, | ||
| 65 | ETP_SMBUS_HELLOPACKET_CMD, values); | ||
| 66 | if (len != ETP_SMBUS_HELLOPACKET_LEN) { | ||
| 67 | dev_err(&client->dev, "hello packet length fail: %d\n", len); | ||
| 68 | error = len < 0 ? len : -EIO; | ||
| 69 | return error; | ||
| 70 | } | ||
| 71 | |||
| 72 | /* compare hello packet */ | ||
| 73 | if (memcmp(values, check, ETP_SMBUS_HELLOPACKET_LEN)) { | ||
| 74 | dev_err(&client->dev, "hello packet fail [%*px]\n", | ||
| 75 | ETP_SMBUS_HELLOPACKET_LEN, values); | ||
| 76 | return -ENXIO; | ||
| 77 | } | ||
| 78 | |||
| 79 | /* enable tp */ | ||
| 80 | error = i2c_smbus_write_byte(client, ETP_SMBUS_ENABLE_TP); | ||
| 81 | if (error) { | ||
| 82 | dev_err(&client->dev, "failed to enable touchpad: %d\n", error); | ||
| 83 | return error; | ||
| 84 | } | ||
| 85 | |||
| 86 | return 0; | ||
| 87 | } | ||
| 88 | |||
| 89 | static int elan_smbus_set_mode(struct i2c_client *client, u8 mode) | ||
| 90 | { | ||
| 91 | u8 cmd[4] = { 0x00, 0x07, 0x00, mode }; | ||
| 92 | |||
| 93 | return i2c_smbus_write_block_data(client, ETP_SMBUS_IAP_CMD, | ||
| 94 | sizeof(cmd), cmd); | ||
| 95 | } | ||
| 96 | |||
| 97 | static int elan_smbus_sleep_control(struct i2c_client *client, bool sleep) | ||
| 98 | { | ||
| 99 | if (sleep) | ||
| 100 | return i2c_smbus_write_byte(client, ETP_SMBUS_SLEEP_CMD); | ||
| 101 | else | ||
| 102 | return 0; /* XXX should we send ETP_SMBUS_ENABLE_TP here? */ | ||
| 103 | } | ||
| 104 | |||
| 105 | static int elan_smbus_power_control(struct i2c_client *client, bool enable) | ||
| 106 | { | ||
| 107 | return 0; /* A no-op */ | ||
| 108 | } | ||
| 109 | |||
| 110 | static int elan_smbus_calibrate(struct i2c_client *client) | ||
| 111 | { | ||
| 112 | u8 cmd[4] = { 0x00, 0x08, 0x00, 0x01 }; | ||
| 113 | |||
| 114 | return i2c_smbus_write_block_data(client, ETP_SMBUS_IAP_CMD, | ||
| 115 | sizeof(cmd), cmd); | ||
| 116 | } | ||
| 117 | |||
| 118 | static int elan_smbus_calibrate_result(struct i2c_client *client, u8 *val) | ||
| 119 | { | ||
| 120 | int error; | ||
| 121 | |||
| 122 | error = i2c_smbus_read_block_data(client, | ||
| 123 | ETP_SMBUS_CALIBRATE_QUERY, val); | ||
| 124 | if (error < 0) | ||
| 125 | return error; | ||
| 126 | |||
| 127 | return 0; | ||
| 128 | } | ||
| 129 | |||
| 130 | static int elan_smbus_get_baseline_data(struct i2c_client *client, | ||
| 131 | bool max_baseline, u8 *value) | ||
| 132 | { | ||
| 133 | int error; | ||
| 134 | u8 val[3]; | ||
| 135 | |||
| 136 | error = i2c_smbus_read_block_data(client, | ||
| 137 | max_baseline ? | ||
| 138 | ETP_SMBUS_MAX_BASELINE_CMD : | ||
| 139 | ETP_SMBUS_MIN_BASELINE_CMD, | ||
| 140 | val); | ||
| 141 | if (error < 0) | ||
| 142 | return error; | ||
| 143 | |||
| 144 | *value = be16_to_cpup((__be16 *)val); | ||
| 145 | |||
| 146 | return 0; | ||
| 147 | } | ||
| 148 | |||
| 149 | static int elan_smbus_get_version(struct i2c_client *client, | ||
| 150 | bool iap, u8 *version) | ||
| 151 | { | ||
| 152 | int error; | ||
| 153 | u8 val[3]; | ||
| 154 | |||
| 155 | error = i2c_smbus_read_block_data(client, | ||
| 156 | iap ? ETP_SMBUS_IAP_VERSION_CMD : | ||
| 157 | ETP_SMBUS_FW_VERSION_CMD, | ||
| 158 | val); | ||
| 159 | if (error < 0) { | ||
| 160 | dev_err(&client->dev, "failed to get %s version: %d\n", | ||
| 161 | iap ? "IAP" : "FW", error); | ||
| 162 | return error; | ||
| 163 | } | ||
| 164 | |||
| 165 | *version = val[2]; | ||
| 166 | return 0; | ||
| 167 | } | ||
| 168 | |||
| 169 | static int elan_smbus_get_sm_version(struct i2c_client *client, u8 *version) | ||
| 170 | { | ||
| 171 | int error; | ||
| 172 | u8 val[3]; | ||
| 173 | |||
| 174 | error = i2c_smbus_read_block_data(client, | ||
| 175 | ETP_SMBUS_SM_VERSION_CMD, val); | ||
| 176 | if (error < 0) { | ||
| 177 | dev_err(&client->dev, "failed to get SM version: %d\n", error); | ||
| 178 | return error; | ||
| 179 | } | ||
| 180 | |||
| 181 | *version = val[0]; /* XXX Why 0 and not 2 as in IAP/FW versions? */ | ||
| 182 | return 0; | ||
| 183 | } | ||
| 184 | |||
| 185 | static int elan_smbus_get_product_id(struct i2c_client *client, u8 *id) | ||
| 186 | { | ||
| 187 | int error; | ||
| 188 | u8 val[3]; | ||
| 189 | |||
| 190 | error = i2c_smbus_read_block_data(client, | ||
| 191 | ETP_SMBUS_UNIQUEID_CMD, val); | ||
| 192 | if (error < 0) { | ||
| 193 | dev_err(&client->dev, "failed to get product ID: %d\n", error); | ||
| 194 | return error; | ||
| 195 | } | ||
| 196 | |||
| 197 | *id = val[1]; | ||
| 198 | return 0; | ||
| 199 | } | ||
| 200 | |||
| 201 | static int elan_smbus_get_checksum(struct i2c_client *client, | ||
| 202 | bool iap, u16 *csum) | ||
| 203 | { | ||
| 204 | int error; | ||
| 205 | u8 val[3]; | ||
| 206 | |||
| 207 | error = i2c_smbus_read_block_data(client, | ||
| 208 | iap ? ETP_SMBUS_FW_CHECKSUM_CMD : | ||
| 209 | ETP_SMBUS_IAP_CHECKSUM_CMD, | ||
| 210 | val); | ||
| 211 | if (error < 0) { | ||
| 212 | dev_err(&client->dev, "failed to get %s checksum: %d\n", | ||
| 213 | iap ? "IAP" : "FW", error); | ||
| 214 | return error; | ||
| 215 | } | ||
| 216 | |||
| 217 | *csum = be16_to_cpup((__be16 *)val); | ||
| 218 | return 0; | ||
| 219 | } | ||
| 220 | |||
| 221 | static int elan_smbus_get_max(struct i2c_client *client, | ||
| 222 | unsigned int *max_x, unsigned int *max_y) | ||
| 223 | { | ||
| 224 | int error; | ||
| 225 | u8 val[3]; | ||
| 226 | |||
| 227 | error = i2c_smbus_read_block_data(client, ETP_SMBUS_RANGE_CMD, val); | ||
| 228 | if (error) { | ||
| 229 | dev_err(&client->dev, "failed to get dimensions: %d\n", error); | ||
| 230 | return error; | ||
| 231 | } | ||
| 232 | |||
| 233 | *max_x = (0x0f & val[0]) << 8 | val[1]; | ||
| 234 | *max_y = (0xf0 & val[0]) << 4 | val[2]; | ||
| 235 | |||
| 236 | return 0; | ||
| 237 | } | ||
| 238 | |||
| 239 | static int elan_smbus_get_resolution(struct i2c_client *client, | ||
| 240 | u8 *hw_res_x, u8 *hw_res_y) | ||
| 241 | { | ||
| 242 | int error; | ||
| 243 | u8 val[3]; | ||
| 244 | |||
| 245 | error = i2c_smbus_read_block_data(client, | ||
| 246 | ETP_SMBUS_RESOLUTION_CMD, val); | ||
| 247 | if (error) { | ||
| 248 | dev_err(&client->dev, "failed to get resolution: %d\n", error); | ||
| 249 | return error; | ||
| 250 | } | ||
| 251 | |||
| 252 | *hw_res_x = val[1] & 0x0F; | ||
| 253 | *hw_res_y = (val[1] & 0xF0) >> 4; | ||
| 254 | |||
| 255 | return 0; | ||
| 256 | } | ||
| 257 | |||
| 258 | static int elan_smbus_get_num_traces(struct i2c_client *client, | ||
| 259 | unsigned int *x_traces, | ||
| 260 | unsigned int *y_traces) | ||
| 261 | { | ||
| 262 | int error; | ||
| 263 | u8 val[3]; | ||
| 264 | |||
| 265 | error = i2c_smbus_read_block_data(client, | ||
| 266 | ETP_SMBUS_XY_TRACENUM_CMD, val); | ||
| 267 | if (error) { | ||
| 268 | dev_err(&client->dev, "failed to get trace info: %d\n", error); | ||
| 269 | return error; | ||
| 270 | } | ||
| 271 | |||
| 272 | *x_traces = val[1] - 1; | ||
| 273 | *y_traces = val[2] - 1; | ||
| 274 | |||
| 275 | return 0; | ||
| 276 | } | ||
| 277 | |||
| 278 | static int elan_smbus_iap_get_mode(struct i2c_client *client, | ||
| 279 | enum tp_mode *mode) | ||
| 280 | { | ||
| 281 | int error; | ||
| 282 | u16 constant; | ||
| 283 | u8 val[3]; | ||
| 284 | |||
| 285 | error = i2c_smbus_read_block_data(client, ETP_SMBUS_IAP_CTRL_CMD, val); | ||
| 286 | if (error < 0) { | ||
| 287 | dev_err(&client->dev, "failed to read iap ctrol register: %d\n", | ||
| 288 | error); | ||
| 289 | return error; | ||
| 290 | } | ||
| 291 | |||
| 292 | constant = be16_to_cpup((__be16 *)val); | ||
| 293 | dev_dbg(&client->dev, "iap control reg: 0x%04x.\n", constant); | ||
| 294 | |||
| 295 | *mode = (constant & ETP_SMBUS_IAP_MODE_ON) ? IAP_MODE : MAIN_MODE; | ||
| 296 | |||
| 297 | return 0; | ||
| 298 | } | ||
| 299 | |||
| 300 | static int elan_smbus_iap_reset(struct i2c_client *client) | ||
| 301 | { | ||
| 302 | int error; | ||
| 303 | |||
| 304 | error = i2c_smbus_write_byte(client, ETP_SMBUS_IAP_RESET_CMD); | ||
| 305 | if (error) { | ||
| 306 | dev_err(&client->dev, "cannot reset IC: %d\n", error); | ||
| 307 | return error; | ||
| 308 | } | ||
| 309 | |||
| 310 | return 0; | ||
| 311 | } | ||
| 312 | |||
| 313 | static int elan_smbus_set_flash_key(struct i2c_client *client) | ||
| 314 | { | ||
| 315 | int error; | ||
| 316 | u8 cmd[4] = { 0x00, 0x0B, 0x00, 0x5A }; | ||
| 317 | |||
| 318 | error = i2c_smbus_write_block_data(client, ETP_SMBUS_IAP_CMD, | ||
| 319 | sizeof(cmd), cmd); | ||
| 320 | if (error) { | ||
| 321 | dev_err(&client->dev, "cannot set flash key: %d\n", error); | ||
| 322 | return error; | ||
| 323 | } | ||
| 324 | |||
| 325 | return 0; | ||
| 326 | } | ||
| 327 | |||
| 328 | static int elan_smbus_prepare_fw_update(struct i2c_client *client) | ||
| 329 | { | ||
| 330 | struct device *dev = &client->dev; | ||
| 331 | int len; | ||
| 332 | int error; | ||
| 333 | enum tp_mode mode; | ||
| 334 | u8 val[3]; | ||
| 335 | u8 cmd[4] = {0x0F, 0x78, 0x00, 0x06}; | ||
| 336 | u16 password; | ||
| 337 | |||
| 338 | /* Get FW in which mode (IAP_MODE/MAIN_MODE) */ | ||
| 339 | error = elan_smbus_iap_get_mode(client, &mode); | ||
| 340 | if (error) | ||
| 341 | return error; | ||
| 342 | |||
| 343 | if (mode == MAIN_MODE) { | ||
| 344 | |||
| 345 | /* set flash key */ | ||
| 346 | error = elan_smbus_set_flash_key(client); | ||
| 347 | if (error) | ||
| 348 | return error; | ||
| 349 | |||
| 350 | /* write iap password */ | ||
| 351 | if (i2c_smbus_write_byte(client, | ||
| 352 | ETP_SMBUS_IAP_PASSWORD_WRITE) < 0) { | ||
| 353 | dev_err(dev, "cannot write iap password\n"); | ||
| 354 | return -EIO; | ||
| 355 | } | ||
| 356 | |||
| 357 | error = i2c_smbus_write_block_data(client, ETP_SMBUS_IAP_CMD, | ||
| 358 | sizeof(cmd), cmd); | ||
| 359 | if (error) { | ||
| 360 | dev_err(dev, "failed to write iap password: %d\n", | ||
| 361 | error); | ||
| 362 | return error; | ||
| 363 | } | ||
| 364 | |||
| 365 | /* | ||
| 366 | * Read back password to make sure we enabled flash | ||
| 367 | * successfully. | ||
| 368 | */ | ||
| 369 | len = i2c_smbus_read_block_data(client, | ||
| 370 | ETP_SMBUS_IAP_PASSWORD_READ, | ||
| 371 | val); | ||
| 372 | if (len < sizeof(u16)) { | ||
| 373 | error = len < 0 ? len : -EIO; | ||
| 374 | dev_err(dev, "failed to read iap password: %d\n", | ||
| 375 | error); | ||
| 376 | return error; | ||
| 377 | } | ||
| 378 | |||
| 379 | password = be16_to_cpup((__be16 *)val); | ||
| 380 | if (password != ETP_SMBUS_IAP_PASSWORD) { | ||
| 381 | dev_err(dev, "wrong iap password = 0x%X\n", password); | ||
| 382 | return -EIO; | ||
| 383 | } | ||
| 384 | |||
| 385 | /* Wait 30ms for MAIN_MODE change to IAP_MODE */ | ||
| 386 | msleep(30); | ||
| 387 | } | ||
| 388 | |||
| 389 | error = elan_smbus_set_flash_key(client); | ||
| 390 | if (error) | ||
| 391 | return error; | ||
| 392 | |||
| 393 | /* Reset IC */ | ||
| 394 | error = elan_smbus_iap_reset(client); | ||
| 395 | if (error) | ||
| 396 | return error; | ||
| 397 | |||
| 398 | return 0; | ||
| 399 | } | ||
| 400 | |||
| 401 | |||
| 402 | static int elan_smbus_write_fw_block(struct i2c_client *client, | ||
| 403 | const u8 *page, u16 checksum, int idx) | ||
| 404 | { | ||
| 405 | struct device *dev = &client->dev; | ||
| 406 | int error; | ||
| 407 | u16 result; | ||
| 408 | u8 val[3]; | ||
| 409 | |||
| 410 | /* | ||
| 411 | * Due to the limitation of smbus protocol limiting | ||
| 412 | * transfer to 32 bytes at a time, we must split block | ||
| 413 | * in 2 transfers. | ||
| 414 | */ | ||
| 415 | error = i2c_smbus_write_block_data(client, | ||
| 416 | ETP_SMBUS_WRITE_FW_BLOCK, | ||
| 417 | ETP_FW_PAGE_SIZE / 2, | ||
| 418 | page); | ||
| 419 | if (error) { | ||
| 420 | dev_err(dev, "Failed to write page %d (part %d): %d\n", | ||
| 421 | idx, 1, error); | ||
| 422 | return error; | ||
| 423 | } | ||
| 424 | |||
| 425 | error = i2c_smbus_write_block_data(client, | ||
| 426 | ETP_SMBUS_WRITE_FW_BLOCK, | ||
| 427 | ETP_FW_PAGE_SIZE / 2, | ||
| 428 | page + ETP_FW_PAGE_SIZE / 2); | ||
| 429 | if (error) { | ||
| 430 | dev_err(dev, "Failed to write page %d (part %d): %d\n", | ||
| 431 | idx, 2, error); | ||
| 432 | return error; | ||
| 433 | } | ||
| 434 | |||
| 435 | |||
| 436 | /* Wait for F/W to update one page ROM data. */ | ||
| 437 | usleep_range(8000, 10000); | ||
| 438 | |||
| 439 | error = i2c_smbus_read_block_data(client, | ||
| 440 | ETP_SMBUS_IAP_CTRL_CMD, val); | ||
| 441 | if (error < 0) { | ||
| 442 | dev_err(dev, "Failed to read IAP write result: %d\n", | ||
| 443 | error); | ||
| 444 | return error; | ||
| 445 | } | ||
| 446 | |||
| 447 | result = be16_to_cpup((__be16 *)val); | ||
| 448 | if (result & (ETP_FW_IAP_PAGE_ERR | ETP_FW_IAP_INTF_ERR)) { | ||
| 449 | dev_err(dev, "IAP reports failed write: %04hx\n", | ||
| 450 | result); | ||
| 451 | return -EIO; | ||
| 452 | } | ||
| 453 | |||
| 454 | return 0; | ||
| 455 | } | ||
| 456 | |||
| 457 | static int elan_smbus_get_report(struct i2c_client *client, u8 *report) | ||
| 458 | { | ||
| 459 | int len; | ||
| 460 | |||
| 461 | len = i2c_smbus_read_block_data(client, | ||
| 462 | ETP_SMBUS_PACKET_QUERY, | ||
| 463 | &report[ETP_SMBUS_REPORT_OFFSET]); | ||
| 464 | if (len < 0) { | ||
| 465 | dev_err(&client->dev, "failed to read report data: %d\n", len); | ||
| 466 | return len; | ||
| 467 | } | ||
| 468 | |||
| 469 | if (len != ETP_SMBUS_REPORT_LEN) { | ||
| 470 | dev_err(&client->dev, | ||
| 471 | "wrong report length (%d vs %d expected)\n", | ||
| 472 | len, ETP_SMBUS_REPORT_LEN); | ||
| 473 | return -EIO; | ||
| 474 | } | ||
| 475 | |||
| 476 | return 0; | ||
| 477 | } | ||
| 478 | |||
| 479 | static int elan_smbus_finish_fw_update(struct i2c_client *client, | ||
| 480 | struct completion *fw_completion) | ||
| 481 | { | ||
| 482 | /* No special handling unlike I2C transport */ | ||
| 483 | return 0; | ||
| 484 | } | ||
| 485 | |||
| 486 | const struct elan_transport_ops elan_smbus_ops = { | ||
| 487 | .initialize = elan_smbus_initialize, | ||
| 488 | .sleep_control = elan_smbus_sleep_control, | ||
| 489 | .power_control = elan_smbus_power_control, | ||
| 490 | .set_mode = elan_smbus_set_mode, | ||
| 491 | |||
| 492 | .calibrate = elan_smbus_calibrate, | ||
| 493 | .calibrate_result = elan_smbus_calibrate_result, | ||
| 494 | |||
| 495 | .get_baseline_data = elan_smbus_get_baseline_data, | ||
| 496 | |||
| 497 | .get_version = elan_smbus_get_version, | ||
| 498 | .get_sm_version = elan_smbus_get_sm_version, | ||
| 499 | .get_product_id = elan_smbus_get_product_id, | ||
| 500 | .get_checksum = elan_smbus_get_checksum, | ||
| 501 | |||
| 502 | .get_max = elan_smbus_get_max, | ||
| 503 | .get_resolution = elan_smbus_get_resolution, | ||
| 504 | .get_num_traces = elan_smbus_get_num_traces, | ||
| 505 | |||
| 506 | .iap_get_mode = elan_smbus_iap_get_mode, | ||
| 507 | .iap_reset = elan_smbus_iap_reset, | ||
| 508 | |||
| 509 | .prepare_fw_update = elan_smbus_prepare_fw_update, | ||
| 510 | .write_fw_block = elan_smbus_write_fw_block, | ||
| 511 | .finish_fw_update = elan_smbus_finish_fw_update, | ||
| 512 | |||
| 513 | .get_report = elan_smbus_get_report, | ||
| 514 | }; | ||
diff --git a/drivers/input/mouse/lifebook.h b/drivers/input/mouse/lifebook.h index 4c4326c6f504..0baf02a70a99 100644 --- a/drivers/input/mouse/lifebook.h +++ b/drivers/input/mouse/lifebook.h | |||
| @@ -16,14 +16,14 @@ void lifebook_module_init(void); | |||
| 16 | int lifebook_detect(struct psmouse *psmouse, bool set_properties); | 16 | int lifebook_detect(struct psmouse *psmouse, bool set_properties); |
| 17 | int lifebook_init(struct psmouse *psmouse); | 17 | int lifebook_init(struct psmouse *psmouse); |
| 18 | #else | 18 | #else |
| 19 | inline void lifebook_module_init(void) | 19 | static inline void lifebook_module_init(void) |
| 20 | { | 20 | { |
| 21 | } | 21 | } |
| 22 | inline int lifebook_detect(struct psmouse *psmouse, bool set_properties) | 22 | static inline int lifebook_detect(struct psmouse *psmouse, bool set_properties) |
| 23 | { | 23 | { |
| 24 | return -ENOSYS; | 24 | return -ENOSYS; |
| 25 | } | 25 | } |
| 26 | inline int lifebook_init(struct psmouse *psmouse) | 26 | static inline int lifebook_init(struct psmouse *psmouse) |
| 27 | { | 27 | { |
| 28 | return -ENOSYS; | 28 | return -ENOSYS; |
| 29 | } | 29 | } |
diff --git a/drivers/input/mouse/navpoint.c b/drivers/input/mouse/navpoint.c index 2a0360f5b5f7..d6e8f58a1de3 100644 --- a/drivers/input/mouse/navpoint.c +++ b/drivers/input/mouse/navpoint.c | |||
| @@ -318,8 +318,7 @@ static int navpoint_remove(struct platform_device *pdev) | |||
| 318 | return 0; | 318 | return 0; |
| 319 | } | 319 | } |
| 320 | 320 | ||
| 321 | #ifdef CONFIG_PM_SLEEP | 321 | static int __maybe_unused navpoint_suspend(struct device *dev) |
| 322 | static int navpoint_suspend(struct device *dev) | ||
| 323 | { | 322 | { |
| 324 | struct platform_device *pdev = to_platform_device(dev); | 323 | struct platform_device *pdev = to_platform_device(dev); |
| 325 | struct navpoint *navpoint = platform_get_drvdata(pdev); | 324 | struct navpoint *navpoint = platform_get_drvdata(pdev); |
| @@ -333,7 +332,7 @@ static int navpoint_suspend(struct device *dev) | |||
| 333 | return 0; | 332 | return 0; |
| 334 | } | 333 | } |
| 335 | 334 | ||
| 336 | static int navpoint_resume(struct device *dev) | 335 | static int __maybe_unused navpoint_resume(struct device *dev) |
| 337 | { | 336 | { |
| 338 | struct platform_device *pdev = to_platform_device(dev); | 337 | struct platform_device *pdev = to_platform_device(dev); |
| 339 | struct navpoint *navpoint = platform_get_drvdata(pdev); | 338 | struct navpoint *navpoint = platform_get_drvdata(pdev); |
| @@ -346,7 +345,6 @@ static int navpoint_resume(struct device *dev) | |||
| 346 | 345 | ||
| 347 | return 0; | 346 | return 0; |
| 348 | } | 347 | } |
| 349 | #endif | ||
| 350 | 348 | ||
| 351 | static SIMPLE_DEV_PM_OPS(navpoint_pm_ops, navpoint_suspend, navpoint_resume); | 349 | static SIMPLE_DEV_PM_OPS(navpoint_pm_ops, navpoint_suspend, navpoint_resume); |
| 352 | 350 | ||
diff --git a/drivers/input/mouse/synaptics_i2c.c b/drivers/input/mouse/synaptics_i2c.c index ad822608f6ee..878f18498f3b 100644 --- a/drivers/input/mouse/synaptics_i2c.c +++ b/drivers/input/mouse/synaptics_i2c.c | |||
| @@ -614,8 +614,7 @@ static int synaptics_i2c_remove(struct i2c_client *client) | |||
| 614 | return 0; | 614 | return 0; |
| 615 | } | 615 | } |
| 616 | 616 | ||
| 617 | #ifdef CONFIG_PM_SLEEP | 617 | static int __maybe_unused synaptics_i2c_suspend(struct device *dev) |
| 618 | static int synaptics_i2c_suspend(struct device *dev) | ||
| 619 | { | 618 | { |
| 620 | struct i2c_client *client = to_i2c_client(dev); | 619 | struct i2c_client *client = to_i2c_client(dev); |
| 621 | struct synaptics_i2c *touch = i2c_get_clientdata(client); | 620 | struct synaptics_i2c *touch = i2c_get_clientdata(client); |
| @@ -628,7 +627,7 @@ static int synaptics_i2c_suspend(struct device *dev) | |||
| 628 | return 0; | 627 | return 0; |
| 629 | } | 628 | } |
| 630 | 629 | ||
| 631 | static int synaptics_i2c_resume(struct device *dev) | 630 | static int __maybe_unused synaptics_i2c_resume(struct device *dev) |
| 632 | { | 631 | { |
| 633 | int ret; | 632 | int ret; |
| 634 | struct i2c_client *client = to_i2c_client(dev); | 633 | struct i2c_client *client = to_i2c_client(dev); |
| @@ -643,7 +642,6 @@ static int synaptics_i2c_resume(struct device *dev) | |||
| 643 | 642 | ||
| 644 | return 0; | 643 | return 0; |
| 645 | } | 644 | } |
| 646 | #endif | ||
| 647 | 645 | ||
| 648 | static SIMPLE_DEV_PM_OPS(synaptics_i2c_pm, synaptics_i2c_suspend, | 646 | static SIMPLE_DEV_PM_OPS(synaptics_i2c_pm, synaptics_i2c_suspend, |
| 649 | synaptics_i2c_resume); | 647 | synaptics_i2c_resume); |
diff --git a/drivers/input/serio/altera_ps2.c b/drivers/input/serio/altera_ps2.c index 8921c96589be..131d7826dc6b 100644 --- a/drivers/input/serio/altera_ps2.c +++ b/drivers/input/serio/altera_ps2.c | |||
| @@ -24,9 +24,7 @@ | |||
| 24 | 24 | ||
| 25 | struct ps2if { | 25 | struct ps2if { |
| 26 | struct serio *io; | 26 | struct serio *io; |
| 27 | struct resource *iomem_res; | ||
| 28 | void __iomem *base; | 27 | void __iomem *base; |
| 29 | unsigned irq; | ||
| 30 | }; | 28 | }; |
| 31 | 29 | ||
| 32 | /* | 30 | /* |
| @@ -83,16 +81,34 @@ static void altera_ps2_close(struct serio *io) | |||
| 83 | static int altera_ps2_probe(struct platform_device *pdev) | 81 | static int altera_ps2_probe(struct platform_device *pdev) |
| 84 | { | 82 | { |
| 85 | struct ps2if *ps2if; | 83 | struct ps2if *ps2if; |
| 84 | struct resource *res; | ||
| 86 | struct serio *serio; | 85 | struct serio *serio; |
| 87 | int error, irq; | 86 | int error, irq; |
| 88 | 87 | ||
| 89 | ps2if = kzalloc(sizeof(struct ps2if), GFP_KERNEL); | 88 | ps2if = devm_kzalloc(&pdev->dev, sizeof(struct ps2if), GFP_KERNEL); |
| 90 | serio = kzalloc(sizeof(struct serio), GFP_KERNEL); | 89 | if (!ps2if) |
| 91 | if (!ps2if || !serio) { | 90 | return -ENOMEM; |
| 92 | error = -ENOMEM; | 91 | |
| 93 | goto err_free_mem; | 92 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 93 | ps2if->base = devm_ioremap_resource(&pdev->dev, res); | ||
| 94 | if (IS_ERR(ps2if->base)) | ||
| 95 | return PTR_ERR(ps2if->base); | ||
| 96 | |||
| 97 | irq = platform_get_irq(pdev, 0); | ||
| 98 | if (irq < 0) | ||
| 99 | return -ENXIO; | ||
| 100 | |||
| 101 | error = devm_request_irq(&pdev->dev, irq, altera_ps2_rxint, 0, | ||
| 102 | pdev->name, ps2if); | ||
| 103 | if (error) { | ||
| 104 | dev_err(&pdev->dev, "could not request IRQ %d\n", irq); | ||
| 105 | return error; | ||
| 94 | } | 106 | } |
| 95 | 107 | ||
| 108 | serio = kzalloc(sizeof(struct serio), GFP_KERNEL); | ||
| 109 | if (!serio) | ||
| 110 | return -ENOMEM; | ||
| 111 | |||
| 96 | serio->id.type = SERIO_8042; | 112 | serio->id.type = SERIO_8042; |
| 97 | serio->write = altera_ps2_write; | 113 | serio->write = altera_ps2_write; |
| 98 | serio->open = altera_ps2_open; | 114 | serio->open = altera_ps2_open; |
| @@ -103,56 +119,12 @@ static int altera_ps2_probe(struct platform_device *pdev) | |||
| 103 | serio->dev.parent = &pdev->dev; | 119 | serio->dev.parent = &pdev->dev; |
| 104 | ps2if->io = serio; | 120 | ps2if->io = serio; |
| 105 | 121 | ||
| 106 | ps2if->iomem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 122 | dev_info(&pdev->dev, "base %p, irq %d\n", ps2if->base, irq); |
| 107 | if (ps2if->iomem_res == NULL) { | ||
| 108 | error = -ENOENT; | ||
| 109 | goto err_free_mem; | ||
| 110 | } | ||
| 111 | |||
| 112 | |||
| 113 | irq = platform_get_irq(pdev, 0); | ||
| 114 | if (irq < 0) { | ||
| 115 | error = -ENXIO; | ||
| 116 | goto err_free_mem; | ||
| 117 | } | ||
| 118 | ps2if->irq = irq; | ||
| 119 | |||
| 120 | if (!request_mem_region(ps2if->iomem_res->start, | ||
| 121 | resource_size(ps2if->iomem_res), pdev->name)) { | ||
| 122 | error = -EBUSY; | ||
| 123 | goto err_free_mem; | ||
| 124 | } | ||
| 125 | |||
| 126 | ps2if->base = ioremap(ps2if->iomem_res->start, | ||
| 127 | resource_size(ps2if->iomem_res)); | ||
| 128 | if (!ps2if->base) { | ||
| 129 | error = -ENOMEM; | ||
| 130 | goto err_free_res; | ||
| 131 | } | ||
| 132 | |||
| 133 | error = request_irq(ps2if->irq, altera_ps2_rxint, 0, pdev->name, ps2if); | ||
| 134 | if (error) { | ||
| 135 | dev_err(&pdev->dev, "could not allocate IRQ %d: %d\n", | ||
| 136 | ps2if->irq, error); | ||
| 137 | goto err_unmap; | ||
| 138 | } | ||
| 139 | |||
| 140 | dev_info(&pdev->dev, "base %p, irq %d\n", ps2if->base, ps2if->irq); | ||
| 141 | 123 | ||
| 142 | serio_register_port(ps2if->io); | 124 | serio_register_port(ps2if->io); |
| 143 | platform_set_drvdata(pdev, ps2if); | 125 | platform_set_drvdata(pdev, ps2if); |
| 144 | 126 | ||
| 145 | return 0; | 127 | return 0; |
| 146 | |||
| 147 | err_unmap: | ||
| 148 | iounmap(ps2if->base); | ||
| 149 | err_free_res: | ||
| 150 | release_mem_region(ps2if->iomem_res->start, | ||
| 151 | resource_size(ps2if->iomem_res)); | ||
| 152 | err_free_mem: | ||
| 153 | kfree(ps2if); | ||
| 154 | kfree(serio); | ||
| 155 | return error; | ||
| 156 | } | 128 | } |
| 157 | 129 | ||
| 158 | /* | 130 | /* |
| @@ -163,11 +135,6 @@ static int altera_ps2_remove(struct platform_device *pdev) | |||
| 163 | struct ps2if *ps2if = platform_get_drvdata(pdev); | 135 | struct ps2if *ps2if = platform_get_drvdata(pdev); |
| 164 | 136 | ||
| 165 | serio_unregister_port(ps2if->io); | 137 | serio_unregister_port(ps2if->io); |
| 166 | free_irq(ps2if->irq, ps2if); | ||
| 167 | iounmap(ps2if->base); | ||
| 168 | release_mem_region(ps2if->iomem_res->start, | ||
| 169 | resource_size(ps2if->iomem_res)); | ||
| 170 | kfree(ps2if); | ||
| 171 | 138 | ||
| 172 | return 0; | 139 | return 0; |
| 173 | } | 140 | } |
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index faeeb1372462..c66d1b53843e 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
| @@ -579,6 +579,16 @@ static const struct dmi_system_id __initconst i8042_dmi_nopnp_table[] = { | |||
| 579 | }, | 579 | }, |
| 580 | }, | 580 | }, |
| 581 | { | 581 | { |
| 582 | /* | ||
| 583 | * Intel NUC D54250WYK - does not have i8042 controller but | ||
| 584 | * declares PS/2 devices in DSDT. | ||
| 585 | */ | ||
| 586 | .matches = { | ||
| 587 | DMI_MATCH(DMI_BOARD_NAME, "D54250WYK"), | ||
| 588 | DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), | ||
| 589 | }, | ||
| 590 | }, | ||
| 591 | { | ||
| 582 | /* MSI Wind U-100 */ | 592 | /* MSI Wind U-100 */ |
| 583 | .matches = { | 593 | .matches = { |
| 584 | DMI_MATCH(DMI_BOARD_NAME, "U-100"), | 594 | DMI_MATCH(DMI_BOARD_NAME, "U-100"), |
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index d399b8b0f000..a05a5179da32 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c | |||
| @@ -514,7 +514,7 @@ static void serio_release_port(struct device *dev) | |||
| 514 | */ | 514 | */ |
| 515 | static void serio_init_port(struct serio *serio) | 515 | static void serio_init_port(struct serio *serio) |
| 516 | { | 516 | { |
| 517 | static atomic_t serio_no = ATOMIC_INIT(0); | 517 | static atomic_t serio_no = ATOMIC_INIT(-1); |
| 518 | 518 | ||
| 519 | __module_get(THIS_MODULE); | 519 | __module_get(THIS_MODULE); |
| 520 | 520 | ||
| @@ -525,7 +525,7 @@ static void serio_init_port(struct serio *serio) | |||
| 525 | mutex_init(&serio->drv_mutex); | 525 | mutex_init(&serio->drv_mutex); |
| 526 | device_initialize(&serio->dev); | 526 | device_initialize(&serio->dev); |
| 527 | dev_set_name(&serio->dev, "serio%lu", | 527 | dev_set_name(&serio->dev, "serio%lu", |
| 528 | (unsigned long)atomic_inc_return(&serio_no) - 1); | 528 | (unsigned long)atomic_inc_return(&serio_no)); |
| 529 | serio->dev.bus = &serio_bus; | 529 | serio->dev.bus = &serio_bus; |
| 530 | serio->dev.release = serio_release_port; | 530 | serio->dev.release = serio_release_port; |
| 531 | serio->dev.groups = serio_device_attr_groups; | 531 | serio->dev.groups = serio_device_attr_groups; |
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index c9a02fe57576..71ef5d65a0c6 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c | |||
| @@ -292,7 +292,7 @@ static irqreturn_t serio_raw_interrupt(struct serio *serio, unsigned char data, | |||
| 292 | 292 | ||
| 293 | static int serio_raw_connect(struct serio *serio, struct serio_driver *drv) | 293 | static int serio_raw_connect(struct serio *serio, struct serio_driver *drv) |
| 294 | { | 294 | { |
| 295 | static atomic_t serio_raw_no = ATOMIC_INIT(0); | 295 | static atomic_t serio_raw_no = ATOMIC_INIT(-1); |
| 296 | struct serio_raw *serio_raw; | 296 | struct serio_raw *serio_raw; |
| 297 | int err; | 297 | int err; |
| 298 | 298 | ||
| @@ -303,7 +303,7 @@ static int serio_raw_connect(struct serio *serio, struct serio_driver *drv) | |||
| 303 | } | 303 | } |
| 304 | 304 | ||
| 305 | snprintf(serio_raw->name, sizeof(serio_raw->name), | 305 | snprintf(serio_raw->name, sizeof(serio_raw->name), |
| 306 | "serio_raw%ld", (long)atomic_inc_return(&serio_raw_no) - 1); | 306 | "serio_raw%ld", (long)atomic_inc_return(&serio_raw_no)); |
| 307 | kref_init(&serio_raw->kref); | 307 | kref_init(&serio_raw->kref); |
| 308 | INIT_LIST_HEAD(&serio_raw->client_list); | 308 | INIT_LIST_HEAD(&serio_raw->client_list); |
| 309 | init_waitqueue_head(&serio_raw->wait); | 309 | init_waitqueue_head(&serio_raw->wait); |
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index e1d8003d01f8..58917525126e 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
| @@ -295,6 +295,19 @@ config TOUCHSCREEN_FUJITSU | |||
| 295 | To compile this driver as a module, choose M here: the | 295 | To compile this driver as a module, choose M here: the |
| 296 | module will be called fujitsu-ts. | 296 | module will be called fujitsu-ts. |
| 297 | 297 | ||
| 298 | config TOUCHSCREEN_GOODIX | ||
| 299 | tristate "Goodix I2C touchscreen" | ||
| 300 | depends on I2C && ACPI | ||
| 301 | help | ||
| 302 | Say Y here if you have the Goodix touchscreen (such as one | ||
| 303 | installed in Onda v975w tablets) connected to your | ||
| 304 | system. | ||
| 305 | |||
| 306 | If unsure, say N. | ||
| 307 | |||
| 308 | To compile this driver as a module, choose M here: the | ||
| 309 | module will be called goodix. | ||
| 310 | |||
| 298 | config TOUCHSCREEN_ILI210X | 311 | config TOUCHSCREEN_ILI210X |
| 299 | tristate "Ilitek ILI210X based touchscreen" | 312 | tristate "Ilitek ILI210X based touchscreen" |
| 300 | depends on I2C | 313 | depends on I2C |
| @@ -334,6 +347,18 @@ config TOUCHSCREEN_GUNZE | |||
| 334 | To compile this driver as a module, choose M here: the | 347 | To compile this driver as a module, choose M here: the |
| 335 | module will be called gunze. | 348 | module will be called gunze. |
| 336 | 349 | ||
| 350 | config TOUCHSCREEN_ELAN | ||
| 351 | tristate "Elan eKTH I2C touchscreen" | ||
| 352 | depends on I2C | ||
| 353 | help | ||
| 354 | Say Y here if you have an Elan eKTH I2C touchscreen | ||
| 355 | connected to your system. | ||
| 356 | |||
| 357 | If unsure, say N. | ||
| 358 | |||
| 359 | To compile this driver as a module, choose M here: the | ||
| 360 | module will be called elants_i2c. | ||
| 361 | |||
| 337 | config TOUCHSCREEN_ELO | 362 | config TOUCHSCREEN_ELO |
| 338 | tristate "Elo serial touchscreens" | 363 | tristate "Elo serial touchscreens" |
| 339 | select SERIO | 364 | select SERIO |
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 090e61cc9171..0242fea2102a 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile | |||
| @@ -31,9 +31,11 @@ obj-$(CONFIG_TOUCHSCREEN_EDT_FT5X06) += edt-ft5x06.o | |||
| 31 | obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE) += hampshire.o | 31 | obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE) += hampshire.o |
| 32 | obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o | 32 | obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o |
| 33 | obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o | 33 | obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o |
| 34 | obj-$(CONFIG_TOUCHSCREEN_ELAN) += elants_i2c.o | ||
| 34 | obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o | 35 | obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o |
| 35 | obj-$(CONFIG_TOUCHSCREEN_EGALAX) += egalax_ts.o | 36 | obj-$(CONFIG_TOUCHSCREEN_EGALAX) += egalax_ts.o |
| 36 | obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o | 37 | obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o |
| 38 | obj-$(CONFIG_TOUCHSCREEN_GOODIX) += goodix.o | ||
| 37 | obj-$(CONFIG_TOUCHSCREEN_ILI210X) += ili210x.o | 39 | obj-$(CONFIG_TOUCHSCREEN_ILI210X) += ili210x.o |
| 38 | obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o | 40 | obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o |
| 39 | obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) += intel-mid-touch.o | 41 | obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) += intel-mid-touch.o |
diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c index 523865daa1d3..da4e5bb5e045 100644 --- a/drivers/input/touchscreen/ad7877.c +++ b/drivers/input/touchscreen/ad7877.c | |||
| @@ -820,8 +820,7 @@ static int ad7877_remove(struct spi_device *spi) | |||
| 820 | return 0; | 820 | return 0; |
| 821 | } | 821 | } |
| 822 | 822 | ||
| 823 | #ifdef CONFIG_PM_SLEEP | 823 | static int __maybe_unused ad7877_suspend(struct device *dev) |
| 824 | static int ad7877_suspend(struct device *dev) | ||
| 825 | { | 824 | { |
| 826 | struct ad7877 *ts = dev_get_drvdata(dev); | 825 | struct ad7877 *ts = dev_get_drvdata(dev); |
| 827 | 826 | ||
| @@ -830,7 +829,7 @@ static int ad7877_suspend(struct device *dev) | |||
| 830 | return 0; | 829 | return 0; |
| 831 | } | 830 | } |
| 832 | 831 | ||
| 833 | static int ad7877_resume(struct device *dev) | 832 | static int __maybe_unused ad7877_resume(struct device *dev) |
| 834 | { | 833 | { |
| 835 | struct ad7877 *ts = dev_get_drvdata(dev); | 834 | struct ad7877 *ts = dev_get_drvdata(dev); |
| 836 | 835 | ||
| @@ -838,7 +837,6 @@ static int ad7877_resume(struct device *dev) | |||
| 838 | 837 | ||
| 839 | return 0; | 838 | return 0; |
| 840 | } | 839 | } |
| 841 | #endif | ||
| 842 | 840 | ||
| 843 | static SIMPLE_DEV_PM_OPS(ad7877_pm, ad7877_suspend, ad7877_resume); | 841 | static SIMPLE_DEV_PM_OPS(ad7877_pm, ad7877_suspend, ad7877_resume); |
| 844 | 842 | ||
diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c index 1eb9d3c20886..fec66ad80513 100644 --- a/drivers/input/touchscreen/ad7879.c +++ b/drivers/input/touchscreen/ad7879.c | |||
| @@ -284,8 +284,7 @@ static void ad7879_close(struct input_dev* input) | |||
| 284 | __ad7879_disable(ts); | 284 | __ad7879_disable(ts); |
| 285 | } | 285 | } |
| 286 | 286 | ||
| 287 | #ifdef CONFIG_PM_SLEEP | 287 | static int __maybe_unused ad7879_suspend(struct device *dev) |
| 288 | static int ad7879_suspend(struct device *dev) | ||
| 289 | { | 288 | { |
| 290 | struct ad7879 *ts = dev_get_drvdata(dev); | 289 | struct ad7879 *ts = dev_get_drvdata(dev); |
| 291 | 290 | ||
| @@ -301,7 +300,7 @@ static int ad7879_suspend(struct device *dev) | |||
| 301 | return 0; | 300 | return 0; |
| 302 | } | 301 | } |
| 303 | 302 | ||
| 304 | static int ad7879_resume(struct device *dev) | 303 | static int __maybe_unused ad7879_resume(struct device *dev) |
| 305 | { | 304 | { |
| 306 | struct ad7879 *ts = dev_get_drvdata(dev); | 305 | struct ad7879 *ts = dev_get_drvdata(dev); |
| 307 | 306 | ||
| @@ -316,7 +315,6 @@ static int ad7879_resume(struct device *dev) | |||
| 316 | 315 | ||
| 317 | return 0; | 316 | return 0; |
| 318 | } | 317 | } |
| 319 | #endif | ||
| 320 | 318 | ||
| 321 | SIMPLE_DEV_PM_OPS(ad7879_pm_ops, ad7879_suspend, ad7879_resume); | 319 | SIMPLE_DEV_PM_OPS(ad7879_pm_ops, ad7879_suspend, ad7879_resume); |
| 322 | EXPORT_SYMBOL(ad7879_pm_ops); | 320 | EXPORT_SYMBOL(ad7879_pm_ops); |
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index e57ba52bf484..e4eb8a6c658f 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
| @@ -883,8 +883,7 @@ static irqreturn_t ads7846_irq(int irq, void *handle) | |||
| 883 | return IRQ_HANDLED; | 883 | return IRQ_HANDLED; |
| 884 | } | 884 | } |
| 885 | 885 | ||
| 886 | #ifdef CONFIG_PM_SLEEP | 886 | static int __maybe_unused ads7846_suspend(struct device *dev) |
| 887 | static int ads7846_suspend(struct device *dev) | ||
| 888 | { | 887 | { |
| 889 | struct ads7846 *ts = dev_get_drvdata(dev); | 888 | struct ads7846 *ts = dev_get_drvdata(dev); |
| 890 | 889 | ||
| @@ -906,7 +905,7 @@ static int ads7846_suspend(struct device *dev) | |||
| 906 | return 0; | 905 | return 0; |
| 907 | } | 906 | } |
| 908 | 907 | ||
| 909 | static int ads7846_resume(struct device *dev) | 908 | static int __maybe_unused ads7846_resume(struct device *dev) |
| 910 | { | 909 | { |
| 911 | struct ads7846 *ts = dev_get_drvdata(dev); | 910 | struct ads7846 *ts = dev_get_drvdata(dev); |
| 912 | 911 | ||
| @@ -927,7 +926,6 @@ static int ads7846_resume(struct device *dev) | |||
| 927 | 926 | ||
| 928 | return 0; | 927 | return 0; |
| 929 | } | 928 | } |
| 930 | #endif | ||
| 931 | 929 | ||
| 932 | static SIMPLE_DEV_PM_OPS(ads7846_pm, ads7846_suspend, ads7846_resume); | 930 | static SIMPLE_DEV_PM_OPS(ads7846_pm, ads7846_suspend, ads7846_resume); |
| 933 | 931 | ||
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index aaacf8bfa61f..bb070206223c 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c | |||
| @@ -2244,8 +2244,7 @@ static int mxt_remove(struct i2c_client *client) | |||
| 2244 | return 0; | 2244 | return 0; |
| 2245 | } | 2245 | } |
| 2246 | 2246 | ||
| 2247 | #ifdef CONFIG_PM_SLEEP | 2247 | static int __maybe_unused mxt_suspend(struct device *dev) |
| 2248 | static int mxt_suspend(struct device *dev) | ||
| 2249 | { | 2248 | { |
| 2250 | struct i2c_client *client = to_i2c_client(dev); | 2249 | struct i2c_client *client = to_i2c_client(dev); |
| 2251 | struct mxt_data *data = i2c_get_clientdata(client); | 2250 | struct mxt_data *data = i2c_get_clientdata(client); |
| @@ -2261,7 +2260,7 @@ static int mxt_suspend(struct device *dev) | |||
| 2261 | return 0; | 2260 | return 0; |
| 2262 | } | 2261 | } |
| 2263 | 2262 | ||
| 2264 | static int mxt_resume(struct device *dev) | 2263 | static int __maybe_unused mxt_resume(struct device *dev) |
| 2265 | { | 2264 | { |
| 2266 | struct i2c_client *client = to_i2c_client(dev); | 2265 | struct i2c_client *client = to_i2c_client(dev); |
| 2267 | struct mxt_data *data = i2c_get_clientdata(client); | 2266 | struct mxt_data *data = i2c_get_clientdata(client); |
| @@ -2276,7 +2275,6 @@ static int mxt_resume(struct device *dev) | |||
| 2276 | 2275 | ||
| 2277 | return 0; | 2276 | return 0; |
| 2278 | } | 2277 | } |
| 2279 | #endif | ||
| 2280 | 2278 | ||
| 2281 | static SIMPLE_DEV_PM_OPS(mxt_pm_ops, mxt_suspend, mxt_resume); | 2279 | static SIMPLE_DEV_PM_OPS(mxt_pm_ops, mxt_suspend, mxt_resume); |
| 2282 | 2280 | ||
diff --git a/drivers/input/touchscreen/auo-pixcir-ts.c b/drivers/input/touchscreen/auo-pixcir-ts.c index 7f3c94787787..40e02dd5b2f9 100644 --- a/drivers/input/touchscreen/auo-pixcir-ts.c +++ b/drivers/input/touchscreen/auo-pixcir-ts.c | |||
| @@ -417,8 +417,7 @@ static void auo_pixcir_input_close(struct input_dev *dev) | |||
| 417 | return; | 417 | return; |
| 418 | } | 418 | } |
| 419 | 419 | ||
| 420 | #ifdef CONFIG_PM_SLEEP | 420 | static int __maybe_unused auo_pixcir_suspend(struct device *dev) |
| 421 | static int auo_pixcir_suspend(struct device *dev) | ||
| 422 | { | 421 | { |
| 423 | struct i2c_client *client = to_i2c_client(dev); | 422 | struct i2c_client *client = to_i2c_client(dev); |
| 424 | struct auo_pixcir_ts *ts = i2c_get_clientdata(client); | 423 | struct auo_pixcir_ts *ts = i2c_get_clientdata(client); |
| @@ -450,7 +449,7 @@ unlock: | |||
| 450 | return ret; | 449 | return ret; |
| 451 | } | 450 | } |
| 452 | 451 | ||
| 453 | static int auo_pixcir_resume(struct device *dev) | 452 | static int __maybe_unused auo_pixcir_resume(struct device *dev) |
| 454 | { | 453 | { |
| 455 | struct i2c_client *client = to_i2c_client(dev); | 454 | struct i2c_client *client = to_i2c_client(dev); |
| 456 | struct auo_pixcir_ts *ts = i2c_get_clientdata(client); | 455 | struct auo_pixcir_ts *ts = i2c_get_clientdata(client); |
| @@ -479,7 +478,6 @@ unlock: | |||
| 479 | 478 | ||
| 480 | return ret; | 479 | return ret; |
| 481 | } | 480 | } |
| 482 | #endif | ||
| 483 | 481 | ||
| 484 | static SIMPLE_DEV_PM_OPS(auo_pixcir_pm_ops, | 482 | static SIMPLE_DEV_PM_OPS(auo_pixcir_pm_ops, |
| 485 | auo_pixcir_suspend, auo_pixcir_resume); | 483 | auo_pixcir_suspend, auo_pixcir_resume); |
diff --git a/drivers/input/touchscreen/cy8ctmg110_ts.c b/drivers/input/touchscreen/cy8ctmg110_ts.c index 5bf1aeeea825..f2119ee0e21b 100644 --- a/drivers/input/touchscreen/cy8ctmg110_ts.c +++ b/drivers/input/touchscreen/cy8ctmg110_ts.c | |||
| @@ -291,8 +291,7 @@ err_free_mem: | |||
| 291 | return err; | 291 | return err; |
| 292 | } | 292 | } |
| 293 | 293 | ||
| 294 | #ifdef CONFIG_PM_SLEEP | 294 | static int __maybe_unused cy8ctmg110_suspend(struct device *dev) |
| 295 | static int cy8ctmg110_suspend(struct device *dev) | ||
| 296 | { | 295 | { |
| 297 | struct i2c_client *client = to_i2c_client(dev); | 296 | struct i2c_client *client = to_i2c_client(dev); |
| 298 | struct cy8ctmg110 *ts = i2c_get_clientdata(client); | 297 | struct cy8ctmg110 *ts = i2c_get_clientdata(client); |
| @@ -306,7 +305,7 @@ static int cy8ctmg110_suspend(struct device *dev) | |||
| 306 | return 0; | 305 | return 0; |
| 307 | } | 306 | } |
| 308 | 307 | ||
| 309 | static int cy8ctmg110_resume(struct device *dev) | 308 | static int __maybe_unused cy8ctmg110_resume(struct device *dev) |
| 310 | { | 309 | { |
| 311 | struct i2c_client *client = to_i2c_client(dev); | 310 | struct i2c_client *client = to_i2c_client(dev); |
| 312 | struct cy8ctmg110 *ts = i2c_get_clientdata(client); | 311 | struct cy8ctmg110 *ts = i2c_get_clientdata(client); |
| @@ -319,7 +318,6 @@ static int cy8ctmg110_resume(struct device *dev) | |||
| 319 | } | 318 | } |
| 320 | return 0; | 319 | return 0; |
| 321 | } | 320 | } |
| 322 | #endif | ||
| 323 | 321 | ||
| 324 | static SIMPLE_DEV_PM_OPS(cy8ctmg110_pm, cy8ctmg110_suspend, cy8ctmg110_resume); | 322 | static SIMPLE_DEV_PM_OPS(cy8ctmg110_pm, cy8ctmg110_suspend, cy8ctmg110_resume); |
| 325 | 323 | ||
diff --git a/drivers/input/touchscreen/cyttsp_core.c b/drivers/input/touchscreen/cyttsp_core.c index eee656f77a2e..5b74e8b84e79 100644 --- a/drivers/input/touchscreen/cyttsp_core.c +++ b/drivers/input/touchscreen/cyttsp_core.c | |||
| @@ -472,8 +472,7 @@ static int cyttsp_disable(struct cyttsp *ts) | |||
| 472 | return 0; | 472 | return 0; |
| 473 | } | 473 | } |
| 474 | 474 | ||
| 475 | #ifdef CONFIG_PM_SLEEP | 475 | static int __maybe_unused cyttsp_suspend(struct device *dev) |
| 476 | static int cyttsp_suspend(struct device *dev) | ||
| 477 | { | 476 | { |
| 478 | struct cyttsp *ts = dev_get_drvdata(dev); | 477 | struct cyttsp *ts = dev_get_drvdata(dev); |
| 479 | int retval = 0; | 478 | int retval = 0; |
| @@ -491,7 +490,7 @@ static int cyttsp_suspend(struct device *dev) | |||
| 491 | return retval; | 490 | return retval; |
| 492 | } | 491 | } |
| 493 | 492 | ||
| 494 | static int cyttsp_resume(struct device *dev) | 493 | static int __maybe_unused cyttsp_resume(struct device *dev) |
| 495 | { | 494 | { |
| 496 | struct cyttsp *ts = dev_get_drvdata(dev); | 495 | struct cyttsp *ts = dev_get_drvdata(dev); |
| 497 | 496 | ||
| @@ -507,8 +506,6 @@ static int cyttsp_resume(struct device *dev) | |||
| 507 | return 0; | 506 | return 0; |
| 508 | } | 507 | } |
| 509 | 508 | ||
| 510 | #endif | ||
| 511 | |||
| 512 | SIMPLE_DEV_PM_OPS(cyttsp_pm_ops, cyttsp_suspend, cyttsp_resume); | 509 | SIMPLE_DEV_PM_OPS(cyttsp_pm_ops, cyttsp_suspend, cyttsp_resume); |
| 513 | EXPORT_SYMBOL_GPL(cyttsp_pm_ops); | 510 | EXPORT_SYMBOL_GPL(cyttsp_pm_ops); |
| 514 | 511 | ||
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index ee3434f1e949..3793fcc7e5db 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c | |||
| @@ -1092,8 +1092,7 @@ static int edt_ft5x06_ts_remove(struct i2c_client *client) | |||
| 1092 | return 0; | 1092 | return 0; |
| 1093 | } | 1093 | } |
| 1094 | 1094 | ||
| 1095 | #ifdef CONFIG_PM_SLEEP | 1095 | static int __maybe_unused edt_ft5x06_ts_suspend(struct device *dev) |
| 1096 | static int edt_ft5x06_ts_suspend(struct device *dev) | ||
| 1097 | { | 1096 | { |
| 1098 | struct i2c_client *client = to_i2c_client(dev); | 1097 | struct i2c_client *client = to_i2c_client(dev); |
| 1099 | 1098 | ||
| @@ -1103,7 +1102,7 @@ static int edt_ft5x06_ts_suspend(struct device *dev) | |||
| 1103 | return 0; | 1102 | return 0; |
| 1104 | } | 1103 | } |
| 1105 | 1104 | ||
| 1106 | static int edt_ft5x06_ts_resume(struct device *dev) | 1105 | static int __maybe_unused edt_ft5x06_ts_resume(struct device *dev) |
| 1107 | { | 1106 | { |
| 1108 | struct i2c_client *client = to_i2c_client(dev); | 1107 | struct i2c_client *client = to_i2c_client(dev); |
| 1109 | 1108 | ||
| @@ -1112,7 +1111,6 @@ static int edt_ft5x06_ts_resume(struct device *dev) | |||
| 1112 | 1111 | ||
| 1113 | return 0; | 1112 | return 0; |
| 1114 | } | 1113 | } |
| 1115 | #endif | ||
| 1116 | 1114 | ||
| 1117 | static SIMPLE_DEV_PM_OPS(edt_ft5x06_ts_pm_ops, | 1115 | static SIMPLE_DEV_PM_OPS(edt_ft5x06_ts_pm_ops, |
| 1118 | edt_ft5x06_ts_suspend, edt_ft5x06_ts_resume); | 1116 | edt_ft5x06_ts_suspend, edt_ft5x06_ts_resume); |
diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c index b1884ddd7a84..09be6ced7151 100644 --- a/drivers/input/touchscreen/eeti_ts.c +++ b/drivers/input/touchscreen/eeti_ts.c | |||
| @@ -264,8 +264,7 @@ static int eeti_ts_remove(struct i2c_client *client) | |||
| 264 | return 0; | 264 | return 0; |
| 265 | } | 265 | } |
| 266 | 266 | ||
| 267 | #ifdef CONFIG_PM_SLEEP | 267 | static int __maybe_unused eeti_ts_suspend(struct device *dev) |
| 268 | static int eeti_ts_suspend(struct device *dev) | ||
| 269 | { | 268 | { |
| 270 | struct i2c_client *client = to_i2c_client(dev); | 269 | struct i2c_client *client = to_i2c_client(dev); |
| 271 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); | 270 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); |
| @@ -284,7 +283,7 @@ static int eeti_ts_suspend(struct device *dev) | |||
| 284 | return 0; | 283 | return 0; |
| 285 | } | 284 | } |
| 286 | 285 | ||
| 287 | static int eeti_ts_resume(struct device *dev) | 286 | static int __maybe_unused eeti_ts_resume(struct device *dev) |
| 288 | { | 287 | { |
| 289 | struct i2c_client *client = to_i2c_client(dev); | 288 | struct i2c_client *client = to_i2c_client(dev); |
| 290 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); | 289 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); |
| @@ -302,7 +301,6 @@ static int eeti_ts_resume(struct device *dev) | |||
| 302 | 301 | ||
| 303 | return 0; | 302 | return 0; |
| 304 | } | 303 | } |
| 305 | #endif | ||
| 306 | 304 | ||
| 307 | static SIMPLE_DEV_PM_OPS(eeti_ts_pm, eeti_ts_suspend, eeti_ts_resume); | 305 | static SIMPLE_DEV_PM_OPS(eeti_ts_pm, eeti_ts_suspend, eeti_ts_resume); |
| 308 | 306 | ||
diff --git a/drivers/input/touchscreen/egalax_ts.c b/drivers/input/touchscreen/egalax_ts.c index c8057847d71d..4c56299284ef 100644 --- a/drivers/input/touchscreen/egalax_ts.c +++ b/drivers/input/touchscreen/egalax_ts.c | |||
| @@ -239,8 +239,7 @@ static const struct i2c_device_id egalax_ts_id[] = { | |||
| 239 | }; | 239 | }; |
| 240 | MODULE_DEVICE_TABLE(i2c, egalax_ts_id); | 240 | MODULE_DEVICE_TABLE(i2c, egalax_ts_id); |
| 241 | 241 | ||
| 242 | #ifdef CONFIG_PM_SLEEP | 242 | static int __maybe_unused egalax_ts_suspend(struct device *dev) |
| 243 | static int egalax_ts_suspend(struct device *dev) | ||
| 244 | { | 243 | { |
| 245 | static const u8 suspend_cmd[MAX_I2C_DATA_LEN] = { | 244 | static const u8 suspend_cmd[MAX_I2C_DATA_LEN] = { |
| 246 | 0x3, 0x6, 0xa, 0x3, 0x36, 0x3f, 0x2, 0, 0, 0 | 245 | 0x3, 0x6, 0xa, 0x3, 0x36, 0x3f, 0x2, 0, 0, 0 |
| @@ -252,13 +251,12 @@ static int egalax_ts_suspend(struct device *dev) | |||
| 252 | return ret > 0 ? 0 : ret; | 251 | return ret > 0 ? 0 : ret; |
| 253 | } | 252 | } |
| 254 | 253 | ||
| 255 | static int egalax_ts_resume(struct device *dev) | 254 | static int __maybe_unused egalax_ts_resume(struct device *dev) |
| 256 | { | 255 | { |
| 257 | struct i2c_client *client = to_i2c_client(dev); | 256 | struct i2c_client *client = to_i2c_client(dev); |
| 258 | 257 | ||
| 259 | return egalax_wake_up_device(client); | 258 | return egalax_wake_up_device(client); |
| 260 | } | 259 | } |
| 261 | #endif | ||
| 262 | 260 | ||
| 263 | static SIMPLE_DEV_PM_OPS(egalax_ts_pm_ops, egalax_ts_suspend, egalax_ts_resume); | 261 | static SIMPLE_DEV_PM_OPS(egalax_ts_pm_ops, egalax_ts_suspend, egalax_ts_resume); |
| 264 | 262 | ||
diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c new file mode 100644 index 000000000000..a510f7ef9b66 --- /dev/null +++ b/drivers/input/touchscreen/elants_i2c.c | |||
| @@ -0,0 +1,1271 @@ | |||
| 1 | /* | ||
| 2 | * Elan Microelectronics touch panels with I2C interface | ||
| 3 | * | ||
| 4 | * Copyright (C) 2014 Elan Microelectronics Corporation. | ||
| 5 | * Scott Liu <scott.liu@emc.com.tw> | ||
| 6 | * | ||
| 7 | * This code is partly based on hid-multitouch.c: | ||
| 8 | * | ||
| 9 | * Copyright (c) 2010-2012 Stephane Chatty <chatty@enac.fr> | ||
| 10 | * Copyright (c) 2010-2012 Benjamin Tissoires <benjamin.tissoires@gmail.com> | ||
| 11 | * Copyright (c) 2010-2012 Ecole Nationale de l'Aviation Civile, France | ||
| 12 | * | ||
| 13 | * | ||
| 14 | * This code is partly based on i2c-hid.c: | ||
| 15 | * | ||
| 16 | * Copyright (c) 2012 Benjamin Tissoires <benjamin.tissoires@gmail.com> | ||
| 17 | * Copyright (c) 2012 Ecole Nationale de l'Aviation Civile, France | ||
| 18 | * Copyright (c) 2012 Red Hat, Inc | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | * This software is licensed under the terms of the GNU General Public | ||
| 23 | * License version 2, as published by the Free Software Foundation, and | ||
| 24 | * may be copied, distributed, and modified under those terms. | ||
| 25 | */ | ||
| 26 | |||
| 27 | #include <linux/module.h> | ||
| 28 | #include <linux/input.h> | ||
| 29 | #include <linux/interrupt.h> | ||
| 30 | #include <linux/platform_device.h> | ||
| 31 | #include <linux/async.h> | ||
| 32 | #include <linux/i2c.h> | ||
| 33 | #include <linux/delay.h> | ||
| 34 | #include <linux/uaccess.h> | ||
| 35 | #include <linux/buffer_head.h> | ||
| 36 | #include <linux/version.h> | ||
| 37 | #include <linux/slab.h> | ||
| 38 | #include <linux/firmware.h> | ||
| 39 | #include <linux/version.h> | ||
| 40 | #include <linux/input/mt.h> | ||
| 41 | #include <linux/acpi.h> | ||
| 42 | #include <linux/of.h> | ||
| 43 | #include <asm/unaligned.h> | ||
| 44 | |||
| 45 | /* Device, Driver information */ | ||
| 46 | #define DEVICE_NAME "elants_i2c" | ||
| 47 | #define DRV_VERSION "1.0.9" | ||
| 48 | |||
| 49 | /* Convert from rows or columns into resolution */ | ||
| 50 | #define ELAN_TS_RESOLUTION(n, m) (((n) - 1) * (m)) | ||
| 51 | |||
| 52 | /* FW header data */ | ||
| 53 | #define HEADER_SIZE 4 | ||
| 54 | #define FW_HDR_TYPE 0 | ||
| 55 | #define FW_HDR_COUNT 1 | ||
| 56 | #define FW_HDR_LENGTH 2 | ||
| 57 | |||
| 58 | /* Buffer mode Queue Header information */ | ||
| 59 | #define QUEUE_HEADER_SINGLE 0x62 | ||
| 60 | #define QUEUE_HEADER_NORMAL 0X63 | ||
| 61 | #define QUEUE_HEADER_WAIT 0x64 | ||
| 62 | |||
| 63 | /* Command header definition */ | ||
| 64 | #define CMD_HEADER_WRITE 0x54 | ||
| 65 | #define CMD_HEADER_READ 0x53 | ||
| 66 | #define CMD_HEADER_6B_READ 0x5B | ||
| 67 | #define CMD_HEADER_RESP 0x52 | ||
| 68 | #define CMD_HEADER_6B_RESP 0x9B | ||
| 69 | #define CMD_HEADER_HELLO 0x55 | ||
| 70 | #define CMD_HEADER_REK 0x66 | ||
| 71 | |||
| 72 | /* FW position data */ | ||
| 73 | #define PACKET_SIZE 55 | ||
| 74 | #define MAX_CONTACT_NUM 10 | ||
| 75 | #define FW_POS_HEADER 0 | ||
| 76 | #define FW_POS_STATE 1 | ||
| 77 | #define FW_POS_TOTAL 2 | ||
| 78 | #define FW_POS_XY 3 | ||
| 79 | #define FW_POS_CHECKSUM 34 | ||
| 80 | #define FW_POS_WIDTH 35 | ||
| 81 | #define FW_POS_PRESSURE 45 | ||
| 82 | |||
| 83 | #define HEADER_REPORT_10_FINGER 0x62 | ||
| 84 | |||
| 85 | /* Header (4 bytes) plus 3 fill 10-finger packets */ | ||
| 86 | #define MAX_PACKET_SIZE 169 | ||
| 87 | |||
| 88 | #define BOOT_TIME_DELAY_MS 50 | ||
| 89 | |||
| 90 | /* FW read command, 0x53 0x?? 0x0, 0x01 */ | ||
| 91 | #define E_ELAN_INFO_FW_VER 0x00 | ||
| 92 | #define E_ELAN_INFO_BC_VER 0x10 | ||
| 93 | #define E_ELAN_INFO_TEST_VER 0xE0 | ||
| 94 | #define E_ELAN_INFO_FW_ID 0xF0 | ||
| 95 | #define E_INFO_OSR 0xD6 | ||
| 96 | #define E_INFO_PHY_SCAN 0xD7 | ||
| 97 | #define E_INFO_PHY_DRIVER 0xD8 | ||
| 98 | |||
| 99 | #define MAX_RETRIES 3 | ||
| 100 | #define MAX_FW_UPDATE_RETRIES 30 | ||
| 101 | |||
| 102 | #define ELAN_FW_PAGESIZE 132 | ||
| 103 | #define ELAN_FW_FILENAME "elants_i2c.bin" | ||
| 104 | |||
| 105 | /* calibration timeout definition */ | ||
| 106 | #define ELAN_CALI_TIMEOUT_MSEC 10000 | ||
| 107 | |||
| 108 | enum elants_state { | ||
| 109 | ELAN_STATE_NORMAL, | ||
| 110 | ELAN_WAIT_QUEUE_HEADER, | ||
| 111 | ELAN_WAIT_RECALIBRATION, | ||
| 112 | }; | ||
| 113 | |||
| 114 | enum elants_iap_mode { | ||
| 115 | ELAN_IAP_OPERATIONAL, | ||
| 116 | ELAN_IAP_RECOVERY, | ||
| 117 | }; | ||
| 118 | |||
| 119 | /* struct elants_data - represents state of Elan touchscreen device */ | ||
| 120 | struct elants_data { | ||
| 121 | struct i2c_client *client; | ||
| 122 | struct input_dev *input; | ||
| 123 | |||
| 124 | u16 fw_version; | ||
| 125 | u8 test_version; | ||
| 126 | u8 solution_version; | ||
| 127 | u8 bc_version; | ||
| 128 | u8 iap_version; | ||
| 129 | u16 hw_version; | ||
| 130 | unsigned int x_res; /* resolution in units/mm */ | ||
| 131 | unsigned int y_res; | ||
| 132 | unsigned int x_max; | ||
| 133 | unsigned int y_max; | ||
| 134 | |||
| 135 | enum elants_state state; | ||
| 136 | enum elants_iap_mode iap_mode; | ||
| 137 | |||
| 138 | /* Guards against concurrent access to the device via sysfs */ | ||
| 139 | struct mutex sysfs_mutex; | ||
| 140 | |||
| 141 | u8 cmd_resp[HEADER_SIZE]; | ||
| 142 | struct completion cmd_done; | ||
| 143 | |||
| 144 | u8 buf[MAX_PACKET_SIZE]; | ||
| 145 | |||
| 146 | bool wake_irq_enabled; | ||
| 147 | }; | ||
| 148 | |||
| 149 | static int elants_i2c_send(struct i2c_client *client, | ||
| 150 | const void *data, size_t size) | ||
| 151 | { | ||
| 152 | int ret; | ||
| 153 | |||
| 154 | ret = i2c_master_send(client, data, size); | ||
| 155 | if (ret == size) | ||
| 156 | return 0; | ||
| 157 | |||
| 158 | if (ret >= 0) | ||
| 159 | ret = -EIO; | ||
| 160 | |||
| 161 | dev_err(&client->dev, "%s failed (%*ph): %d\n", | ||
| 162 | __func__, (int)size, data, ret); | ||
| 163 | |||
| 164 | return ret; | ||
| 165 | } | ||
| 166 | |||
| 167 | static int elants_i2c_read(struct i2c_client *client, void *data, size_t size) | ||
| 168 | { | ||
| 169 | int ret; | ||
| 170 | |||
| 171 | ret = i2c_master_recv(client, data, size); | ||
| 172 | if (ret == size) | ||
| 173 | return 0; | ||
| 174 | |||
| 175 | if (ret >= 0) | ||
| 176 | ret = -EIO; | ||
| 177 | |||
| 178 | dev_err(&client->dev, "%s failed: %d\n", __func__, ret); | ||
| 179 | |||
| 180 | return ret; | ||
| 181 | } | ||
| 182 | |||
| 183 | static int elants_i2c_execute_command(struct i2c_client *client, | ||
| 184 | const u8 *cmd, size_t cmd_size, | ||
| 185 | u8 *resp, size_t resp_size) | ||
| 186 | { | ||
| 187 | struct i2c_msg msgs[2]; | ||
| 188 | int ret; | ||
| 189 | u8 expected_response; | ||
| 190 | |||
| 191 | switch (cmd[0]) { | ||
| 192 | case CMD_HEADER_READ: | ||
| 193 | expected_response = CMD_HEADER_RESP; | ||
| 194 | break; | ||
| 195 | |||
| 196 | case CMD_HEADER_6B_READ: | ||
| 197 | expected_response = CMD_HEADER_6B_RESP; | ||
| 198 | break; | ||
| 199 | |||
| 200 | default: | ||
| 201 | dev_err(&client->dev, "%s: invalid command %*ph\n", | ||
| 202 | __func__, (int)cmd_size, cmd); | ||
| 203 | return -EINVAL; | ||
| 204 | } | ||
| 205 | |||
| 206 | msgs[0].addr = client->addr; | ||
| 207 | msgs[0].flags = client->flags & I2C_M_TEN; | ||
| 208 | msgs[0].len = cmd_size; | ||
| 209 | msgs[0].buf = (u8 *)cmd; | ||
| 210 | |||
| 211 | msgs[1].addr = client->addr; | ||
| 212 | msgs[1].flags = client->flags & I2C_M_TEN; | ||
| 213 | msgs[1].flags |= I2C_M_RD; | ||
| 214 | msgs[1].len = resp_size; | ||
| 215 | msgs[1].buf = resp; | ||
| 216 | |||
| 217 | ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); | ||
| 218 | if (ret < 0) | ||
| 219 | return ret; | ||
| 220 | |||
| 221 | if (ret != ARRAY_SIZE(msgs) || resp[FW_HDR_TYPE] != expected_response) | ||
| 222 | return -EIO; | ||
| 223 | |||
| 224 | return 0; | ||
| 225 | } | ||
| 226 | |||
| 227 | static int elants_i2c_calibrate(struct elants_data *ts) | ||
| 228 | { | ||
| 229 | struct i2c_client *client = ts->client; | ||
| 230 | int ret, error; | ||
| 231 | static const u8 w_flashkey[] = { 0x54, 0xC0, 0xE1, 0x5A }; | ||
| 232 | static const u8 rek[] = { 0x54, 0x29, 0x00, 0x01 }; | ||
| 233 | static const u8 rek_resp[] = { CMD_HEADER_REK, 0x66, 0x66, 0x66 }; | ||
| 234 | |||
| 235 | disable_irq(client->irq); | ||
| 236 | |||
| 237 | ts->state = ELAN_WAIT_RECALIBRATION; | ||
| 238 | reinit_completion(&ts->cmd_done); | ||
| 239 | |||
| 240 | elants_i2c_send(client, w_flashkey, sizeof(w_flashkey)); | ||
| 241 | elants_i2c_send(client, rek, sizeof(rek)); | ||
| 242 | |||
| 243 | enable_irq(client->irq); | ||
| 244 | |||
| 245 | ret = wait_for_completion_interruptible_timeout(&ts->cmd_done, | ||
| 246 | msecs_to_jiffies(ELAN_CALI_TIMEOUT_MSEC)); | ||
| 247 | |||
| 248 | ts->state = ELAN_STATE_NORMAL; | ||
| 249 | |||
| 250 | if (ret <= 0) { | ||
| 251 | error = ret < 0 ? ret : -ETIMEDOUT; | ||
| 252 | dev_err(&client->dev, | ||
| 253 | "error while waiting for calibration to complete: %d\n", | ||
| 254 | error); | ||
| 255 | return error; | ||
| 256 | } | ||
| 257 | |||
| 258 | if (memcmp(rek_resp, ts->cmd_resp, sizeof(rek_resp))) { | ||
| 259 | dev_err(&client->dev, | ||
| 260 | "unexpected calibration response: %*ph\n", | ||
| 261 | (int)sizeof(ts->cmd_resp), ts->cmd_resp); | ||
| 262 | return -EINVAL; | ||
| 263 | } | ||
| 264 | |||
| 265 | return 0; | ||
| 266 | } | ||
| 267 | |||
| 268 | static int elants_i2c_sw_reset(struct i2c_client *client) | ||
| 269 | { | ||
| 270 | const u8 soft_rst_cmd[] = { 0x77, 0x77, 0x77, 0x77 }; | ||
| 271 | int error; | ||
| 272 | |||
| 273 | error = elants_i2c_send(client, soft_rst_cmd, | ||
| 274 | sizeof(soft_rst_cmd)); | ||
| 275 | if (error) { | ||
| 276 | dev_err(&client->dev, "software reset failed: %d\n", error); | ||
| 277 | return error; | ||
| 278 | } | ||
| 279 | |||
| 280 | /* | ||
| 281 | * We should wait at least 10 msec (but no more than 40) before | ||
| 282 | * sending fastboot or IAP command to the device. | ||
| 283 | */ | ||
| 284 | msleep(30); | ||
| 285 | |||
| 286 | return 0; | ||
| 287 | } | ||
| 288 | |||
| 289 | static u16 elants_i2c_parse_version(u8 *buf) | ||
| 290 | { | ||
| 291 | return get_unaligned_be32(buf) >> 4; | ||
| 292 | } | ||
| 293 | |||
| 294 | static int elants_i2c_query_fw_id(struct elants_data *ts) | ||
| 295 | { | ||
| 296 | struct i2c_client *client = ts->client; | ||
| 297 | int error, retry_cnt; | ||
| 298 | const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_FW_ID, 0x00, 0x01 }; | ||
| 299 | u8 resp[HEADER_SIZE]; | ||
| 300 | |||
| 301 | for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) { | ||
| 302 | error = elants_i2c_execute_command(client, cmd, sizeof(cmd), | ||
| 303 | resp, sizeof(resp)); | ||
| 304 | if (!error) { | ||
| 305 | ts->hw_version = elants_i2c_parse_version(resp); | ||
| 306 | if (ts->hw_version != 0xffff) | ||
| 307 | return 0; | ||
| 308 | } | ||
| 309 | |||
| 310 | dev_dbg(&client->dev, "read fw id error=%d, buf=%*phC\n", | ||
| 311 | error, (int)sizeof(resp), resp); | ||
| 312 | } | ||
| 313 | |||
| 314 | dev_err(&client->dev, | ||
| 315 | "Failed to read fw id or fw id is invalid\n"); | ||
| 316 | |||
| 317 | return -EINVAL; | ||
| 318 | } | ||
| 319 | |||
| 320 | static int elants_i2c_query_fw_version(struct elants_data *ts) | ||
| 321 | { | ||
| 322 | struct i2c_client *client = ts->client; | ||
| 323 | int error, retry_cnt; | ||
| 324 | const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_FW_VER, 0x00, 0x01 }; | ||
| 325 | u8 resp[HEADER_SIZE]; | ||
| 326 | |||
| 327 | for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) { | ||
| 328 | error = elants_i2c_execute_command(client, cmd, sizeof(cmd), | ||
| 329 | resp, sizeof(resp)); | ||
| 330 | if (!error) { | ||
| 331 | ts->fw_version = elants_i2c_parse_version(resp); | ||
| 332 | if (ts->fw_version != 0x0000 && | ||
| 333 | ts->fw_version != 0xffff) | ||
| 334 | return 0; | ||
| 335 | } | ||
| 336 | |||
| 337 | dev_dbg(&client->dev, "read fw version error=%d, buf=%*phC\n", | ||
| 338 | error, (int)sizeof(resp), resp); | ||
| 339 | } | ||
| 340 | |||
| 341 | dev_err(&client->dev, | ||
| 342 | "Failed to read fw version or fw version is invalid\n"); | ||
| 343 | |||
| 344 | return -EINVAL; | ||
| 345 | } | ||
| 346 | |||
| 347 | static int elants_i2c_query_test_version(struct elants_data *ts) | ||
| 348 | { | ||
| 349 | struct i2c_client *client = ts->client; | ||
| 350 | int error, retry_cnt; | ||
| 351 | u16 version; | ||
| 352 | const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_TEST_VER, 0x00, 0x01 }; | ||
| 353 | u8 resp[HEADER_SIZE]; | ||
| 354 | |||
| 355 | for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) { | ||
| 356 | error = elants_i2c_execute_command(client, cmd, sizeof(cmd), | ||
| 357 | resp, sizeof(resp)); | ||
| 358 | if (!error) { | ||
| 359 | version = elants_i2c_parse_version(resp); | ||
| 360 | ts->test_version = version >> 8; | ||
| 361 | ts->solution_version = version & 0xff; | ||
| 362 | |||
| 363 | return 0; | ||
| 364 | } | ||
| 365 | |||
| 366 | dev_dbg(&client->dev, | ||
| 367 | "read test version error rc=%d, buf=%*phC\n", | ||
| 368 | error, (int)sizeof(resp), resp); | ||
| 369 | } | ||
| 370 | |||
| 371 | dev_err(&client->dev, "Failed to read test version\n"); | ||
| 372 | |||
| 373 | return -EINVAL; | ||
| 374 | } | ||
| 375 | |||
| 376 | static int elants_i2c_query_bc_version(struct elants_data *ts) | ||
| 377 | { | ||
| 378 | struct i2c_client *client = ts->client; | ||
| 379 | const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_BC_VER, 0x00, 0x01 }; | ||
| 380 | u8 resp[HEADER_SIZE]; | ||
| 381 | u16 version; | ||
| 382 | int error; | ||
| 383 | |||
| 384 | error = elants_i2c_execute_command(client, cmd, sizeof(cmd), | ||
| 385 | resp, sizeof(resp)); | ||
| 386 | if (error) { | ||
| 387 | dev_err(&client->dev, | ||
| 388 | "read BC version error=%d, buf=%*phC\n", | ||
| 389 | error, (int)sizeof(resp), resp); | ||
| 390 | return error; | ||
| 391 | } | ||
| 392 | |||
| 393 | version = elants_i2c_parse_version(resp); | ||
| 394 | ts->bc_version = version >> 8; | ||
| 395 | ts->iap_version = version & 0xff; | ||
| 396 | |||
| 397 | return 0; | ||
| 398 | } | ||
| 399 | |||
| 400 | static int elants_i2c_query_ts_info(struct elants_data *ts) | ||
| 401 | { | ||
| 402 | struct i2c_client *client = ts->client; | ||
| 403 | int error; | ||
| 404 | u8 resp[17]; | ||
| 405 | u16 phy_x, phy_y, rows, cols, osr; | ||
| 406 | const u8 get_resolution_cmd[] = { | ||
| 407 | CMD_HEADER_6B_READ, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
| 408 | }; | ||
| 409 | const u8 get_osr_cmd[] = { | ||
| 410 | CMD_HEADER_READ, E_INFO_OSR, 0x00, 0x01 | ||
| 411 | }; | ||
| 412 | const u8 get_physical_scan_cmd[] = { | ||
| 413 | CMD_HEADER_READ, E_INFO_PHY_SCAN, 0x00, 0x01 | ||
| 414 | }; | ||
| 415 | const u8 get_physical_drive_cmd[] = { | ||
| 416 | CMD_HEADER_READ, E_INFO_PHY_DRIVER, 0x00, 0x01 | ||
| 417 | }; | ||
| 418 | |||
| 419 | /* Get trace number */ | ||
| 420 | error = elants_i2c_execute_command(client, | ||
| 421 | get_resolution_cmd, | ||
| 422 | sizeof(get_resolution_cmd), | ||
| 423 | resp, sizeof(resp)); | ||
| 424 | if (error) { | ||
| 425 | dev_err(&client->dev, "get resolution command failed: %d\n", | ||
| 426 | error); | ||
| 427 | return error; | ||
| 428 | } | ||
| 429 | |||
| 430 | rows = resp[2] + resp[6] + resp[10]; | ||
| 431 | cols = resp[3] + resp[7] + resp[11]; | ||
| 432 | |||
| 433 | /* Process mm_to_pixel information */ | ||
| 434 | error = elants_i2c_execute_command(client, | ||
| 435 | get_osr_cmd, sizeof(get_osr_cmd), | ||
| 436 | resp, sizeof(resp)); | ||
| 437 | if (error) { | ||
| 438 | dev_err(&client->dev, "get osr command failed: %d\n", | ||
| 439 | error); | ||
| 440 | return error; | ||
| 441 | } | ||
| 442 | |||
| 443 | osr = resp[3]; | ||
| 444 | |||
| 445 | error = elants_i2c_execute_command(client, | ||
| 446 | get_physical_scan_cmd, | ||
| 447 | sizeof(get_physical_scan_cmd), | ||
| 448 | resp, sizeof(resp)); | ||
| 449 | if (error) { | ||
| 450 | dev_err(&client->dev, "get physical scan command failed: %d\n", | ||
| 451 | error); | ||
| 452 | return error; | ||
| 453 | } | ||
| 454 | |||
| 455 | phy_x = get_unaligned_be16(&resp[2]); | ||
| 456 | |||
| 457 | error = elants_i2c_execute_command(client, | ||
| 458 | get_physical_drive_cmd, | ||
| 459 | sizeof(get_physical_drive_cmd), | ||
| 460 | resp, sizeof(resp)); | ||
| 461 | if (error) { | ||
| 462 | dev_err(&client->dev, "get physical drive command failed: %d\n", | ||
| 463 | error); | ||
| 464 | return error; | ||
| 465 | } | ||
| 466 | |||
| 467 | phy_y = get_unaligned_be16(&resp[2]); | ||
| 468 | |||
| 469 | dev_dbg(&client->dev, "phy_x=%d, phy_y=%d\n", phy_x, phy_y); | ||
| 470 | |||
| 471 | if (rows == 0 || cols == 0 || osr == 0) { | ||
| 472 | dev_warn(&client->dev, | ||
| 473 | "invalid trace number data: %d, %d, %d\n", | ||
| 474 | rows, cols, osr); | ||
| 475 | } else { | ||
| 476 | /* translate trace number to TS resolution */ | ||
| 477 | ts->x_max = ELAN_TS_RESOLUTION(rows, osr); | ||
| 478 | ts->x_res = DIV_ROUND_CLOSEST(ts->x_max, phy_x); | ||
| 479 | ts->y_max = ELAN_TS_RESOLUTION(cols, osr); | ||
| 480 | ts->y_res = DIV_ROUND_CLOSEST(ts->y_max, phy_y); | ||
| 481 | } | ||
| 482 | |||
| 483 | return 0; | ||
| 484 | } | ||
| 485 | |||
| 486 | static int elants_i2c_fastboot(struct i2c_client *client) | ||
| 487 | { | ||
| 488 | const u8 boot_cmd[] = { 0x4D, 0x61, 0x69, 0x6E }; | ||
| 489 | int error; | ||
| 490 | |||
| 491 | error = elants_i2c_send(client, boot_cmd, sizeof(boot_cmd)); | ||
| 492 | if (error) { | ||
| 493 | dev_err(&client->dev, "boot failed: %d\n", error); | ||
| 494 | return error; | ||
| 495 | } | ||
| 496 | |||
| 497 | dev_dbg(&client->dev, "boot success -- 0x%x\n", client->addr); | ||
| 498 | return 0; | ||
| 499 | } | ||
| 500 | |||
| 501 | static int elants_i2c_initialize(struct elants_data *ts) | ||
| 502 | { | ||
| 503 | struct i2c_client *client = ts->client; | ||
| 504 | int error, retry_cnt; | ||
| 505 | const u8 hello_packet[] = { 0x55, 0x55, 0x55, 0x55 }; | ||
| 506 | const u8 recov_packet[] = { 0x55, 0x55, 0x80, 0x80 }; | ||
| 507 | u8 buf[HEADER_SIZE]; | ||
| 508 | |||
| 509 | for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) { | ||
| 510 | error = elants_i2c_sw_reset(client); | ||
| 511 | if (error) { | ||
| 512 | /* Continue initializing if it's the last try */ | ||
| 513 | if (retry_cnt < MAX_RETRIES - 1) | ||
| 514 | continue; | ||
| 515 | } | ||
| 516 | |||
| 517 | error = elants_i2c_fastboot(client); | ||
| 518 | if (error) { | ||
| 519 | /* Continue initializing if it's the last try */ | ||
| 520 | if (retry_cnt < MAX_RETRIES - 1) | ||
| 521 | continue; | ||
| 522 | } | ||
| 523 | |||
| 524 | /* Wait for Hello packet */ | ||
| 525 | msleep(BOOT_TIME_DELAY_MS); | ||
| 526 | |||
| 527 | error = elants_i2c_read(client, buf, sizeof(buf)); | ||
| 528 | if (error) { | ||
| 529 | dev_err(&client->dev, | ||
| 530 | "failed to read 'hello' packet: %d\n", error); | ||
| 531 | } else if (!memcmp(buf, hello_packet, sizeof(hello_packet))) { | ||
| 532 | ts->iap_mode = ELAN_IAP_OPERATIONAL; | ||
| 533 | break; | ||
| 534 | } else if (!memcmp(buf, recov_packet, sizeof(recov_packet))) { | ||
| 535 | /* | ||
| 536 | * Setting error code will mark device | ||
| 537 | * in recovery mode below. | ||
| 538 | */ | ||
| 539 | error = -EIO; | ||
| 540 | break; | ||
| 541 | } else { | ||
| 542 | error = -EINVAL; | ||
| 543 | dev_err(&client->dev, | ||
| 544 | "invalid 'hello' packet: %*ph\n", | ||
| 545 | (int)sizeof(buf), buf); | ||
| 546 | } | ||
| 547 | } | ||
| 548 | |||
| 549 | if (!error) | ||
| 550 | error = elants_i2c_query_fw_id(ts); | ||
| 551 | if (!error) | ||
| 552 | error = elants_i2c_query_fw_version(ts); | ||
| 553 | |||
| 554 | if (error) { | ||
| 555 | ts->iap_mode = ELAN_IAP_RECOVERY; | ||
| 556 | } else { | ||
| 557 | elants_i2c_query_test_version(ts); | ||
| 558 | elants_i2c_query_bc_version(ts); | ||
| 559 | elants_i2c_query_ts_info(ts); | ||
| 560 | } | ||
| 561 | |||
| 562 | return 0; | ||
| 563 | } | ||
| 564 | |||
| 565 | /* | ||
| 566 | * Firmware update interface. | ||
| 567 | */ | ||
| 568 | |||
| 569 | static int elants_i2c_fw_write_page(struct i2c_client *client, | ||
| 570 | const void *page) | ||
| 571 | { | ||
| 572 | const u8 ack_ok[] = { 0xaa, 0xaa }; | ||
| 573 | u8 buf[2]; | ||
| 574 | int retry; | ||
| 575 | int error; | ||
| 576 | |||
| 577 | for (retry = 0; retry < MAX_FW_UPDATE_RETRIES; retry++) { | ||
| 578 | error = elants_i2c_send(client, page, ELAN_FW_PAGESIZE); | ||
| 579 | if (error) { | ||
| 580 | dev_err(&client->dev, | ||
| 581 | "IAP Write Page failed: %d\n", error); | ||
| 582 | continue; | ||
| 583 | } | ||
| 584 | |||
| 585 | error = elants_i2c_read(client, buf, 2); | ||
| 586 | if (error) { | ||
| 587 | dev_err(&client->dev, | ||
| 588 | "IAP Ack read failed: %d\n", error); | ||
| 589 | return error; | ||
| 590 | } | ||
| 591 | |||
| 592 | if (!memcmp(buf, ack_ok, sizeof(ack_ok))) | ||
| 593 | return 0; | ||
| 594 | |||
| 595 | error = -EIO; | ||
| 596 | dev_err(&client->dev, | ||
| 597 | "IAP Get Ack Error [%02x:%02x]\n", | ||
| 598 | buf[0], buf[1]); | ||
| 599 | } | ||
| 600 | |||
| 601 | return error; | ||
| 602 | } | ||
| 603 | |||
| 604 | static int elants_i2c_do_update_firmware(struct i2c_client *client, | ||
| 605 | const struct firmware *fw, | ||
| 606 | bool force) | ||
| 607 | { | ||
| 608 | const u8 enter_iap[] = { 0x45, 0x49, 0x41, 0x50 }; | ||
| 609 | const u8 enter_iap2[] = { 0x54, 0x00, 0x12, 0x34 }; | ||
| 610 | const u8 iap_ack[] = { 0x55, 0xaa, 0x33, 0xcc }; | ||
| 611 | u8 buf[HEADER_SIZE]; | ||
| 612 | u16 send_id; | ||
| 613 | int page, n_fw_pages; | ||
| 614 | int error; | ||
| 615 | |||
| 616 | /* Recovery mode detection! */ | ||
| 617 | if (force) { | ||
| 618 | dev_dbg(&client->dev, "Recovery mode procedure\n"); | ||
| 619 | error = elants_i2c_send(client, enter_iap2, sizeof(enter_iap2)); | ||
| 620 | } else { | ||
| 621 | /* Start IAP Procedure */ | ||
| 622 | dev_dbg(&client->dev, "Normal IAP procedure\n"); | ||
| 623 | elants_i2c_sw_reset(client); | ||
| 624 | |||
| 625 | error = elants_i2c_send(client, enter_iap, sizeof(enter_iap)); | ||
| 626 | } | ||
| 627 | |||
| 628 | if (error) { | ||
| 629 | dev_err(&client->dev, "failed to enter IAP mode: %d\n", error); | ||
| 630 | return error; | ||
| 631 | } | ||
| 632 | |||
| 633 | msleep(20); | ||
| 634 | |||
| 635 | /* check IAP state */ | ||
| 636 | error = elants_i2c_read(client, buf, 4); | ||
| 637 | if (error) { | ||
| 638 | dev_err(&client->dev, | ||
| 639 | "failed to read IAP acknowledgement: %d\n", | ||
| 640 | error); | ||
| 641 | return error; | ||
| 642 | } | ||
| 643 | |||
| 644 | if (memcmp(buf, iap_ack, sizeof(iap_ack))) { | ||
| 645 | dev_err(&client->dev, | ||
| 646 | "failed to enter IAP: %*ph (expected %*ph)\n", | ||
| 647 | (int)sizeof(buf), buf, (int)sizeof(iap_ack), iap_ack); | ||
| 648 | return -EIO; | ||
| 649 | } | ||
| 650 | |||
| 651 | dev_info(&client->dev, "successfully entered IAP mode"); | ||
| 652 | |||
| 653 | send_id = client->addr; | ||
| 654 | error = elants_i2c_send(client, &send_id, 1); | ||
| 655 | if (error) { | ||
| 656 | dev_err(&client->dev, "sending dummy byte failed: %d\n", | ||
| 657 | error); | ||
| 658 | return error; | ||
| 659 | } | ||
| 660 | |||
| 661 | /* Clear the last page of Master */ | ||
| 662 | error = elants_i2c_send(client, fw->data, ELAN_FW_PAGESIZE); | ||
| 663 | if (error) { | ||
| 664 | dev_err(&client->dev, "clearing of the last page failed: %d\n", | ||
| 665 | error); | ||
| 666 | return error; | ||
| 667 | } | ||
| 668 | |||
| 669 | error = elants_i2c_read(client, buf, 2); | ||
| 670 | if (error) { | ||
| 671 | dev_err(&client->dev, | ||
| 672 | "failed to read ACK for clearing the last page: %d\n", | ||
| 673 | error); | ||
| 674 | return error; | ||
| 675 | } | ||
| 676 | |||
| 677 | n_fw_pages = fw->size / ELAN_FW_PAGESIZE; | ||
| 678 | dev_dbg(&client->dev, "IAP Pages = %d\n", n_fw_pages); | ||
| 679 | |||
| 680 | for (page = 0; page < n_fw_pages; page++) { | ||
| 681 | error = elants_i2c_fw_write_page(client, | ||
| 682 | fw->data + page * ELAN_FW_PAGESIZE); | ||
| 683 | if (error) { | ||
| 684 | dev_err(&client->dev, | ||
| 685 | "failed to write FW page %d: %d\n", | ||
| 686 | page, error); | ||
| 687 | return error; | ||
| 688 | } | ||
| 689 | } | ||
| 690 | |||
| 691 | /* Old iap needs to wait 200ms for WDT and rest is for hello packets */ | ||
| 692 | msleep(300); | ||
| 693 | |||
| 694 | dev_info(&client->dev, "firmware update completed\n"); | ||
| 695 | return 0; | ||
| 696 | } | ||
| 697 | |||
| 698 | static int elants_i2c_fw_update(struct elants_data *ts) | ||
| 699 | { | ||
| 700 | struct i2c_client *client = ts->client; | ||
| 701 | const struct firmware *fw; | ||
| 702 | int error; | ||
| 703 | |||
| 704 | error = request_firmware(&fw, ELAN_FW_FILENAME, &client->dev); | ||
| 705 | if (error) { | ||
| 706 | dev_err(&client->dev, "failed to request firmware %s: %d\n", | ||
| 707 | ELAN_FW_FILENAME, error); | ||
| 708 | return error; | ||
| 709 | } | ||
| 710 | |||
| 711 | if (fw->size % ELAN_FW_PAGESIZE) { | ||
| 712 | dev_err(&client->dev, "invalid firmware length: %zu\n", | ||
| 713 | fw->size); | ||
| 714 | error = -EINVAL; | ||
| 715 | goto out; | ||
| 716 | } | ||
| 717 | |||
| 718 | disable_irq(client->irq); | ||
| 719 | |||
| 720 | error = elants_i2c_do_update_firmware(client, fw, | ||
| 721 | ts->iap_mode == ELAN_IAP_RECOVERY); | ||
| 722 | if (error) { | ||
| 723 | dev_err(&client->dev, "firmware update failed: %d\n", error); | ||
| 724 | ts->iap_mode = ELAN_IAP_RECOVERY; | ||
| 725 | goto out_enable_irq; | ||
| 726 | } | ||
| 727 | |||
| 728 | error = elants_i2c_initialize(ts); | ||
| 729 | if (error) { | ||
| 730 | dev_err(&client->dev, | ||
| 731 | "failed to initialize device after firmware update: %d\n", | ||
| 732 | error); | ||
| 733 | ts->iap_mode = ELAN_IAP_RECOVERY; | ||
| 734 | goto out_enable_irq; | ||
| 735 | } | ||
| 736 | |||
| 737 | ts->iap_mode = ELAN_IAP_OPERATIONAL; | ||
| 738 | |||
| 739 | out_enable_irq: | ||
| 740 | ts->state = ELAN_STATE_NORMAL; | ||
| 741 | enable_irq(client->irq); | ||
| 742 | msleep(100); | ||
| 743 | |||
| 744 | if (!error) | ||
| 745 | elants_i2c_calibrate(ts); | ||
| 746 | out: | ||
| 747 | release_firmware(fw); | ||
| 748 | return error; | ||
| 749 | } | ||
| 750 | |||
| 751 | /* | ||
| 752 | * Event reporting. | ||
| 753 | */ | ||
| 754 | |||
| 755 | static void elants_i2c_mt_event(struct elants_data *ts, u8 *buf) | ||
| 756 | { | ||
| 757 | struct input_dev *input = ts->input; | ||
| 758 | unsigned int n_fingers; | ||
| 759 | u16 finger_state; | ||
| 760 | int i; | ||
| 761 | |||
| 762 | n_fingers = buf[FW_POS_STATE + 1] & 0x0f; | ||
| 763 | finger_state = ((buf[FW_POS_STATE + 1] & 0x30) << 4) | | ||
| 764 | buf[FW_POS_STATE]; | ||
| 765 | |||
| 766 | dev_dbg(&ts->client->dev, | ||
| 767 | "n_fingers: %u, state: %04x\n", n_fingers, finger_state); | ||
| 768 | |||
| 769 | for (i = 0; i < MAX_CONTACT_NUM && n_fingers; i++) { | ||
| 770 | if (finger_state & 1) { | ||
| 771 | unsigned int x, y, p, w; | ||
| 772 | u8 *pos; | ||
| 773 | |||
| 774 | pos = &buf[FW_POS_XY + i * 3]; | ||
| 775 | x = (((u16)pos[0] & 0xf0) << 4) | pos[1]; | ||
| 776 | y = (((u16)pos[0] & 0x0f) << 8) | pos[2]; | ||
| 777 | p = buf[FW_POS_PRESSURE + i]; | ||
| 778 | w = buf[FW_POS_WIDTH + i]; | ||
| 779 | |||
| 780 | dev_dbg(&ts->client->dev, "i=%d x=%d y=%d p=%d w=%d\n", | ||
| 781 | i, x, y, p, w); | ||
| 782 | |||
| 783 | input_mt_slot(input, i); | ||
| 784 | input_mt_report_slot_state(input, MT_TOOL_FINGER, true); | ||
| 785 | input_event(input, EV_ABS, ABS_MT_POSITION_X, x); | ||
| 786 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, y); | ||
| 787 | input_event(input, EV_ABS, ABS_MT_PRESSURE, p); | ||
| 788 | input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, w); | ||
| 789 | |||
| 790 | n_fingers--; | ||
| 791 | } | ||
| 792 | |||
| 793 | finger_state >>= 1; | ||
| 794 | } | ||
| 795 | |||
| 796 | input_mt_sync_frame(input); | ||
| 797 | input_sync(input); | ||
| 798 | } | ||
| 799 | |||
| 800 | static u8 elants_i2c_calculate_checksum(u8 *buf) | ||
| 801 | { | ||
| 802 | u8 checksum = 0; | ||
| 803 | u8 i; | ||
| 804 | |||
| 805 | for (i = 0; i < FW_POS_CHECKSUM; i++) | ||
| 806 | checksum += buf[i]; | ||
| 807 | |||
| 808 | return checksum; | ||
| 809 | } | ||
| 810 | |||
| 811 | static void elants_i2c_event(struct elants_data *ts, u8 *buf) | ||
| 812 | { | ||
| 813 | u8 checksum = elants_i2c_calculate_checksum(buf); | ||
| 814 | |||
| 815 | if (unlikely(buf[FW_POS_CHECKSUM] != checksum)) | ||
| 816 | dev_warn(&ts->client->dev, | ||
| 817 | "%s: invalid checksum for packet %02x: %02x vs. %02x\n", | ||
| 818 | __func__, buf[FW_POS_HEADER], | ||
| 819 | checksum, buf[FW_POS_CHECKSUM]); | ||
| 820 | else if (unlikely(buf[FW_POS_HEADER] != HEADER_REPORT_10_FINGER)) | ||
| 821 | dev_warn(&ts->client->dev, | ||
| 822 | "%s: unknown packet type: %02x\n", | ||
| 823 | __func__, buf[FW_POS_HEADER]); | ||
| 824 | else | ||
| 825 | elants_i2c_mt_event(ts, buf); | ||
| 826 | } | ||
| 827 | |||
| 828 | static irqreturn_t elants_i2c_irq(int irq, void *_dev) | ||
| 829 | { | ||
| 830 | const u8 wait_packet[] = { 0x64, 0x64, 0x64, 0x64 }; | ||
| 831 | struct elants_data *ts = _dev; | ||
| 832 | struct i2c_client *client = ts->client; | ||
| 833 | int report_count, report_len; | ||
| 834 | int i; | ||
| 835 | int len; | ||
| 836 | |||
| 837 | len = i2c_master_recv(client, ts->buf, sizeof(ts->buf)); | ||
| 838 | if (len < 0) { | ||
| 839 | dev_err(&client->dev, "%s: failed to read data: %d\n", | ||
| 840 | __func__, len); | ||
| 841 | goto out; | ||
| 842 | } | ||
| 843 | |||
| 844 | dev_dbg(&client->dev, "%s: packet %*ph\n", | ||
| 845 | __func__, HEADER_SIZE, ts->buf); | ||
| 846 | |||
| 847 | switch (ts->state) { | ||
| 848 | case ELAN_WAIT_RECALIBRATION: | ||
| 849 | if (ts->buf[FW_HDR_TYPE] == CMD_HEADER_REK) { | ||
| 850 | memcpy(ts->cmd_resp, ts->buf, sizeof(ts->cmd_resp)); | ||
| 851 | complete(&ts->cmd_done); | ||
| 852 | ts->state = ELAN_STATE_NORMAL; | ||
| 853 | } | ||
| 854 | break; | ||
| 855 | |||
| 856 | case ELAN_WAIT_QUEUE_HEADER: | ||
| 857 | if (ts->buf[FW_HDR_TYPE] != QUEUE_HEADER_NORMAL) | ||
| 858 | break; | ||
| 859 | |||
| 860 | ts->state = ELAN_STATE_NORMAL; | ||
| 861 | /* fall through */ | ||
| 862 | |||
| 863 | case ELAN_STATE_NORMAL: | ||
| 864 | |||
| 865 | switch (ts->buf[FW_HDR_TYPE]) { | ||
| 866 | case CMD_HEADER_HELLO: | ||
| 867 | case CMD_HEADER_RESP: | ||
| 868 | case CMD_HEADER_REK: | ||
| 869 | break; | ||
| 870 | |||
| 871 | case QUEUE_HEADER_WAIT: | ||
| 872 | if (memcmp(ts->buf, wait_packet, sizeof(wait_packet))) { | ||
| 873 | dev_err(&client->dev, | ||
| 874 | "invalid wait packet %*ph\n", | ||
| 875 | HEADER_SIZE, ts->buf); | ||
| 876 | } else { | ||
| 877 | ts->state = ELAN_WAIT_QUEUE_HEADER; | ||
| 878 | udelay(30); | ||
| 879 | } | ||
| 880 | break; | ||
| 881 | |||
| 882 | case QUEUE_HEADER_SINGLE: | ||
| 883 | elants_i2c_event(ts, &ts->buf[HEADER_SIZE]); | ||
| 884 | break; | ||
| 885 | |||
| 886 | case QUEUE_HEADER_NORMAL: | ||
| 887 | report_count = ts->buf[FW_HDR_COUNT]; | ||
| 888 | if (report_count > 3) { | ||
| 889 | dev_err(&client->dev, | ||
| 890 | "too large report count: %*ph\n", | ||
| 891 | HEADER_SIZE, ts->buf); | ||
| 892 | break; | ||
| 893 | } | ||
| 894 | |||
| 895 | report_len = ts->buf[FW_HDR_LENGTH] / report_count; | ||
| 896 | if (report_len != PACKET_SIZE) { | ||
| 897 | dev_err(&client->dev, | ||
| 898 | "mismatching report length: %*ph\n", | ||
| 899 | HEADER_SIZE, ts->buf); | ||
| 900 | break; | ||
| 901 | } | ||
| 902 | |||
| 903 | for (i = 0; i < report_count; i++) { | ||
| 904 | u8 *buf = ts->buf + HEADER_SIZE + | ||
| 905 | i * PACKET_SIZE; | ||
| 906 | elants_i2c_event(ts, buf); | ||
| 907 | } | ||
| 908 | break; | ||
| 909 | |||
| 910 | default: | ||
| 911 | dev_err(&client->dev, "unknown packet %*ph\n", | ||
| 912 | HEADER_SIZE, ts->buf); | ||
| 913 | break; | ||
| 914 | } | ||
| 915 | break; | ||
| 916 | } | ||
| 917 | |||
| 918 | out: | ||
| 919 | return IRQ_HANDLED; | ||
| 920 | } | ||
| 921 | |||
| 922 | /* | ||
| 923 | * sysfs interface | ||
| 924 | */ | ||
| 925 | static ssize_t calibrate_store(struct device *dev, | ||
| 926 | struct device_attribute *attr, | ||
| 927 | const char *buf, size_t count) | ||
| 928 | { | ||
| 929 | struct i2c_client *client = to_i2c_client(dev); | ||
| 930 | struct elants_data *ts = i2c_get_clientdata(client); | ||
| 931 | int error; | ||
| 932 | |||
| 933 | error = mutex_lock_interruptible(&ts->sysfs_mutex); | ||
| 934 | if (error) | ||
| 935 | return error; | ||
| 936 | |||
| 937 | error = elants_i2c_calibrate(ts); | ||
| 938 | |||
| 939 | mutex_unlock(&ts->sysfs_mutex); | ||
| 940 | return error ?: count; | ||
| 941 | } | ||
| 942 | |||
| 943 | static ssize_t write_update_fw(struct device *dev, | ||
| 944 | struct device_attribute *attr, | ||
| 945 | const char *buf, size_t count) | ||
| 946 | { | ||
| 947 | struct i2c_client *client = to_i2c_client(dev); | ||
| 948 | struct elants_data *ts = i2c_get_clientdata(client); | ||
| 949 | int error; | ||
| 950 | |||
| 951 | error = mutex_lock_interruptible(&ts->sysfs_mutex); | ||
| 952 | if (error) | ||
| 953 | return error; | ||
| 954 | |||
| 955 | error = elants_i2c_fw_update(ts); | ||
| 956 | dev_dbg(dev, "firmware update result: %d\n", error); | ||
| 957 | |||
| 958 | mutex_unlock(&ts->sysfs_mutex); | ||
| 959 | return error ?: count; | ||
| 960 | } | ||
| 961 | |||
| 962 | static ssize_t show_iap_mode(struct device *dev, | ||
| 963 | struct device_attribute *attr, char *buf) | ||
| 964 | { | ||
| 965 | struct i2c_client *client = to_i2c_client(dev); | ||
| 966 | struct elants_data *ts = i2c_get_clientdata(client); | ||
| 967 | |||
| 968 | return sprintf(buf, "%s\n", | ||
| 969 | ts->iap_mode == ELAN_IAP_OPERATIONAL ? | ||
| 970 | "Normal" : "Recovery"); | ||
| 971 | } | ||
| 972 | |||
| 973 | static DEVICE_ATTR(calibrate, S_IWUSR, NULL, calibrate_store); | ||
| 974 | static DEVICE_ATTR(iap_mode, S_IRUGO, show_iap_mode, NULL); | ||
| 975 | static DEVICE_ATTR(update_fw, S_IWUSR, NULL, write_update_fw); | ||
| 976 | |||
| 977 | struct elants_version_attribute { | ||
| 978 | struct device_attribute dattr; | ||
| 979 | size_t field_offset; | ||
| 980 | size_t field_size; | ||
| 981 | }; | ||
| 982 | |||
| 983 | #define __ELANTS_FIELD_SIZE(_field) \ | ||
| 984 | sizeof(((struct elants_data *)NULL)->_field) | ||
| 985 | #define __ELANTS_VERIFY_SIZE(_field) \ | ||
| 986 | (BUILD_BUG_ON_ZERO(__ELANTS_FIELD_SIZE(_field) > 2) + \ | ||
| 987 | __ELANTS_FIELD_SIZE(_field)) | ||
| 988 | #define ELANTS_VERSION_ATTR(_field) \ | ||
| 989 | struct elants_version_attribute elants_ver_attr_##_field = { \ | ||
| 990 | .dattr = __ATTR(_field, S_IRUGO, \ | ||
| 991 | elants_version_attribute_show, NULL), \ | ||
| 992 | .field_offset = offsetof(struct elants_data, _field), \ | ||
| 993 | .field_size = __ELANTS_VERIFY_SIZE(_field), \ | ||
| 994 | } | ||
| 995 | |||
| 996 | static ssize_t elants_version_attribute_show(struct device *dev, | ||
| 997 | struct device_attribute *dattr, | ||
| 998 | char *buf) | ||
| 999 | { | ||
| 1000 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1001 | struct elants_data *ts = i2c_get_clientdata(client); | ||
| 1002 | struct elants_version_attribute *attr = | ||
| 1003 | container_of(dattr, struct elants_version_attribute, dattr); | ||
| 1004 | u8 *field = (u8 *)((char *)ts + attr->field_offset); | ||
| 1005 | unsigned int fmt_size; | ||
| 1006 | unsigned int val; | ||
| 1007 | |||
| 1008 | if (attr->field_size == 1) { | ||
| 1009 | val = *field; | ||
| 1010 | fmt_size = 2; /* 2 HEX digits */ | ||
| 1011 | } else { | ||
| 1012 | val = *(u16 *)field; | ||
| 1013 | fmt_size = 4; /* 4 HEX digits */ | ||
| 1014 | } | ||
| 1015 | |||
| 1016 | return sprintf(buf, "%0*x\n", fmt_size, val); | ||
| 1017 | } | ||
| 1018 | |||
| 1019 | static ELANTS_VERSION_ATTR(fw_version); | ||
| 1020 | static ELANTS_VERSION_ATTR(hw_version); | ||
| 1021 | static ELANTS_VERSION_ATTR(test_version); | ||
| 1022 | static ELANTS_VERSION_ATTR(solution_version); | ||
| 1023 | static ELANTS_VERSION_ATTR(bc_version); | ||
| 1024 | static ELANTS_VERSION_ATTR(iap_version); | ||
| 1025 | |||
| 1026 | static struct attribute *elants_attributes[] = { | ||
| 1027 | &dev_attr_calibrate.attr, | ||
| 1028 | &dev_attr_update_fw.attr, | ||
| 1029 | &dev_attr_iap_mode.attr, | ||
| 1030 | |||
| 1031 | &elants_ver_attr_fw_version.dattr.attr, | ||
| 1032 | &elants_ver_attr_hw_version.dattr.attr, | ||
| 1033 | &elants_ver_attr_test_version.dattr.attr, | ||
| 1034 | &elants_ver_attr_solution_version.dattr.attr, | ||
| 1035 | &elants_ver_attr_bc_version.dattr.attr, | ||
| 1036 | &elants_ver_attr_iap_version.dattr.attr, | ||
| 1037 | NULL | ||
| 1038 | }; | ||
| 1039 | |||
| 1040 | static struct attribute_group elants_attribute_group = { | ||
| 1041 | .attrs = elants_attributes, | ||
| 1042 | }; | ||
| 1043 | |||
| 1044 | static void elants_i2c_remove_sysfs_group(void *_data) | ||
| 1045 | { | ||
| 1046 | struct elants_data *ts = _data; | ||
| 1047 | |||
| 1048 | sysfs_remove_group(&ts->client->dev.kobj, &elants_attribute_group); | ||
| 1049 | } | ||
| 1050 | |||
| 1051 | static int elants_i2c_probe(struct i2c_client *client, | ||
| 1052 | const struct i2c_device_id *id) | ||
| 1053 | { | ||
| 1054 | union i2c_smbus_data dummy; | ||
| 1055 | struct elants_data *ts; | ||
| 1056 | unsigned long irqflags; | ||
| 1057 | int error; | ||
| 1058 | |||
| 1059 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { | ||
| 1060 | dev_err(&client->dev, | ||
| 1061 | "%s: i2c check functionality error\n", DEVICE_NAME); | ||
| 1062 | return -ENXIO; | ||
| 1063 | } | ||
| 1064 | |||
| 1065 | /* Make sure there is something at this address */ | ||
| 1066 | if (i2c_smbus_xfer(client->adapter, client->addr, 0, | ||
| 1067 | I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &dummy) < 0) { | ||
| 1068 | dev_err(&client->dev, "nothing at this address\n"); | ||
| 1069 | return -ENXIO; | ||
| 1070 | } | ||
| 1071 | |||
| 1072 | ts = devm_kzalloc(&client->dev, sizeof(struct elants_data), GFP_KERNEL); | ||
| 1073 | if (!ts) | ||
| 1074 | return -ENOMEM; | ||
| 1075 | |||
| 1076 | mutex_init(&ts->sysfs_mutex); | ||
| 1077 | init_completion(&ts->cmd_done); | ||
| 1078 | |||
| 1079 | ts->client = client; | ||
| 1080 | i2c_set_clientdata(client, ts); | ||
| 1081 | |||
| 1082 | error = elants_i2c_initialize(ts); | ||
| 1083 | if (error) { | ||
| 1084 | dev_err(&client->dev, "failed to initialize: %d\n", error); | ||
| 1085 | return error; | ||
| 1086 | } | ||
| 1087 | |||
| 1088 | ts->input = devm_input_allocate_device(&client->dev); | ||
| 1089 | if (!ts->input) { | ||
| 1090 | dev_err(&client->dev, "Failed to allocate input device\n"); | ||
| 1091 | return -ENOMEM; | ||
| 1092 | } | ||
| 1093 | |||
| 1094 | ts->input->name = "Elan Touchscreen"; | ||
| 1095 | ts->input->id.bustype = BUS_I2C; | ||
| 1096 | |||
| 1097 | __set_bit(BTN_TOUCH, ts->input->keybit); | ||
| 1098 | __set_bit(EV_ABS, ts->input->evbit); | ||
| 1099 | __set_bit(EV_KEY, ts->input->evbit); | ||
| 1100 | |||
| 1101 | /* Single touch input params setup */ | ||
| 1102 | input_set_abs_params(ts->input, ABS_X, 0, ts->x_max, 0, 0); | ||
| 1103 | input_set_abs_params(ts->input, ABS_Y, 0, ts->y_max, 0, 0); | ||
| 1104 | input_set_abs_params(ts->input, ABS_PRESSURE, 0, 255, 0, 0); | ||
| 1105 | input_abs_set_res(ts->input, ABS_X, ts->x_res); | ||
| 1106 | input_abs_set_res(ts->input, ABS_Y, ts->y_res); | ||
| 1107 | |||
| 1108 | /* Multitouch input params setup */ | ||
| 1109 | error = input_mt_init_slots(ts->input, MAX_CONTACT_NUM, | ||
| 1110 | INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); | ||
| 1111 | if (error) { | ||
| 1112 | dev_err(&client->dev, | ||
| 1113 | "failed to initialize MT slots: %d\n", error); | ||
| 1114 | return error; | ||
| 1115 | } | ||
| 1116 | |||
| 1117 | input_set_abs_params(ts->input, ABS_MT_POSITION_X, 0, ts->x_max, 0, 0); | ||
| 1118 | input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, ts->y_max, 0, 0); | ||
| 1119 | input_set_abs_params(ts->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); | ||
| 1120 | input_set_abs_params(ts->input, ABS_MT_PRESSURE, 0, 255, 0, 0); | ||
| 1121 | input_abs_set_res(ts->input, ABS_MT_POSITION_X, ts->x_res); | ||
| 1122 | input_abs_set_res(ts->input, ABS_MT_POSITION_Y, ts->y_res); | ||
| 1123 | |||
| 1124 | input_set_drvdata(ts->input, ts); | ||
| 1125 | |||
| 1126 | error = input_register_device(ts->input); | ||
| 1127 | if (error) { | ||
| 1128 | dev_err(&client->dev, | ||
| 1129 | "unable to register input device: %d\n", error); | ||
| 1130 | return error; | ||
| 1131 | } | ||
| 1132 | |||
| 1133 | /* | ||
| 1134 | * Systems using device tree should set up interrupt via DTS, | ||
| 1135 | * the rest will use the default falling edge interrupts. | ||
| 1136 | */ | ||
| 1137 | irqflags = client->dev.of_node ? 0 : IRQF_TRIGGER_FALLING; | ||
| 1138 | |||
| 1139 | error = devm_request_threaded_irq(&client->dev, client->irq, | ||
| 1140 | NULL, elants_i2c_irq, | ||
| 1141 | irqflags | IRQF_ONESHOT, | ||
| 1142 | client->name, ts); | ||
| 1143 | if (error) { | ||
| 1144 | dev_err(&client->dev, "Failed to register interrupt\n"); | ||
| 1145 | return error; | ||
| 1146 | } | ||
| 1147 | |||
| 1148 | /* | ||
| 1149 | * Systems using device tree should set up wakeup via DTS, | ||
| 1150 | * the rest will configure device as wakeup source by default. | ||
| 1151 | */ | ||
| 1152 | if (!client->dev.of_node) | ||
| 1153 | device_init_wakeup(&client->dev, true); | ||
| 1154 | |||
| 1155 | error = sysfs_create_group(&client->dev.kobj, &elants_attribute_group); | ||
| 1156 | if (error) { | ||
| 1157 | dev_err(&client->dev, "failed to create sysfs attributes: %d\n", | ||
| 1158 | error); | ||
| 1159 | return error; | ||
| 1160 | } | ||
| 1161 | |||
| 1162 | error = devm_add_action(&client->dev, | ||
| 1163 | elants_i2c_remove_sysfs_group, ts); | ||
| 1164 | if (error) { | ||
| 1165 | elants_i2c_remove_sysfs_group(ts); | ||
| 1166 | dev_err(&client->dev, | ||
| 1167 | "Failed to add sysfs cleanup action: %d\n", | ||
| 1168 | error); | ||
| 1169 | return error; | ||
| 1170 | } | ||
| 1171 | |||
| 1172 | return 0; | ||
| 1173 | } | ||
| 1174 | |||
| 1175 | static int __maybe_unused elants_i2c_suspend(struct device *dev) | ||
| 1176 | { | ||
| 1177 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1178 | struct elants_data *ts = i2c_get_clientdata(client); | ||
| 1179 | const u8 set_sleep_cmd[] = { 0x54, 0x50, 0x00, 0x01 }; | ||
| 1180 | int retry_cnt; | ||
| 1181 | int error; | ||
| 1182 | |||
| 1183 | /* Command not support in IAP recovery mode */ | ||
| 1184 | if (ts->iap_mode != ELAN_IAP_OPERATIONAL) | ||
| 1185 | return -EBUSY; | ||
| 1186 | |||
| 1187 | disable_irq(client->irq); | ||
| 1188 | |||
| 1189 | for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) { | ||
| 1190 | error = elants_i2c_send(client, set_sleep_cmd, | ||
| 1191 | sizeof(set_sleep_cmd)); | ||
| 1192 | if (!error) | ||
| 1193 | break; | ||
| 1194 | |||
| 1195 | dev_err(&client->dev, "suspend command failed: %d\n", error); | ||
| 1196 | } | ||
| 1197 | |||
| 1198 | if (device_may_wakeup(dev)) | ||
| 1199 | ts->wake_irq_enabled = (enable_irq_wake(client->irq) == 0); | ||
| 1200 | |||
| 1201 | return 0; | ||
| 1202 | } | ||
| 1203 | |||
| 1204 | static int __maybe_unused elants_i2c_resume(struct device *dev) | ||
| 1205 | { | ||
| 1206 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1207 | struct elants_data *ts = i2c_get_clientdata(client); | ||
| 1208 | const u8 set_active_cmd[] = { 0x54, 0x58, 0x00, 0x01 }; | ||
| 1209 | int retry_cnt; | ||
| 1210 | int error; | ||
| 1211 | |||
| 1212 | if (device_may_wakeup(dev) && ts->wake_irq_enabled) | ||
| 1213 | disable_irq_wake(client->irq); | ||
| 1214 | |||
| 1215 | for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) { | ||
| 1216 | error = elants_i2c_send(client, set_active_cmd, | ||
| 1217 | sizeof(set_active_cmd)); | ||
| 1218 | if (!error) | ||
| 1219 | break; | ||
| 1220 | |||
| 1221 | dev_err(&client->dev, "resume command failed: %d\n", error); | ||
| 1222 | } | ||
| 1223 | |||
| 1224 | ts->state = ELAN_STATE_NORMAL; | ||
| 1225 | enable_irq(client->irq); | ||
| 1226 | |||
| 1227 | return 0; | ||
| 1228 | } | ||
| 1229 | |||
| 1230 | static SIMPLE_DEV_PM_OPS(elants_i2c_pm_ops, | ||
| 1231 | elants_i2c_suspend, elants_i2c_resume); | ||
| 1232 | |||
| 1233 | static const struct i2c_device_id elants_i2c_id[] = { | ||
| 1234 | { DEVICE_NAME, 0 }, | ||
| 1235 | { } | ||
| 1236 | }; | ||
| 1237 | MODULE_DEVICE_TABLE(i2c, elants_i2c_id); | ||
| 1238 | |||
| 1239 | #ifdef CONFIG_ACPI | ||
| 1240 | static const struct acpi_device_id elants_acpi_id[] = { | ||
| 1241 | { "ELAN0001", 0 }, | ||
| 1242 | { } | ||
| 1243 | }; | ||
| 1244 | MODULE_DEVICE_TABLE(acpi, elants_acpi_id); | ||
| 1245 | #endif | ||
| 1246 | |||
| 1247 | #ifdef CONFIG_OF | ||
| 1248 | static const struct of_device_id elants_of_match[] = { | ||
| 1249 | { .compatible = "elan,ekth3500" }, | ||
| 1250 | { /* sentinel */ } | ||
| 1251 | }; | ||
| 1252 | MODULE_DEVICE_TABLE(of, elants_of_match); | ||
| 1253 | #endif | ||
| 1254 | |||
| 1255 | static struct i2c_driver elants_i2c_driver = { | ||
| 1256 | .probe = elants_i2c_probe, | ||
| 1257 | .id_table = elants_i2c_id, | ||
| 1258 | .driver = { | ||
| 1259 | .name = DEVICE_NAME, | ||
| 1260 | .owner = THIS_MODULE, | ||
| 1261 | .pm = &elants_i2c_pm_ops, | ||
| 1262 | .acpi_match_table = ACPI_PTR(elants_acpi_id), | ||
| 1263 | .of_match_table = of_match_ptr(elants_of_match), | ||
| 1264 | }, | ||
| 1265 | }; | ||
| 1266 | module_i2c_driver(elants_i2c_driver); | ||
| 1267 | |||
| 1268 | MODULE_AUTHOR("Scott Liu <scott.liu@emc.com.tw>"); | ||
| 1269 | MODULE_DESCRIPTION("Elan I2c Touchscreen driver"); | ||
| 1270 | MODULE_VERSION(DRV_VERSION); | ||
| 1271 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c new file mode 100644 index 000000000000..ca196689f025 --- /dev/null +++ b/drivers/input/touchscreen/goodix.c | |||
| @@ -0,0 +1,395 @@ | |||
| 1 | /* | ||
| 2 | * Driver for Goodix Touchscreens | ||
| 3 | * | ||
| 4 | * Copyright (c) 2014 Red Hat Inc. | ||
| 5 | * | ||
| 6 | * This code is based on gt9xx.c authored by andrew@goodix.com: | ||
| 7 | * | ||
| 8 | * 2010 - 2012 Goodix Technology. | ||
| 9 | */ | ||
| 10 | |||
| 11 | /* | ||
| 12 | * This program is free software; you can redistribute it and/or modify it | ||
| 13 | * under the terms of the GNU General Public License as published by the Free | ||
| 14 | * Software Foundation; version 2 of the License. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/kernel.h> | ||
| 18 | #include <linux/i2c.h> | ||
| 19 | #include <linux/input.h> | ||
| 20 | #include <linux/input/mt.h> | ||
| 21 | #include <linux/module.h> | ||
| 22 | #include <linux/delay.h> | ||
| 23 | #include <linux/irq.h> | ||
| 24 | #include <linux/interrupt.h> | ||
| 25 | #include <linux/slab.h> | ||
| 26 | #include <asm/unaligned.h> | ||
| 27 | |||
| 28 | struct goodix_ts_data { | ||
| 29 | struct i2c_client *client; | ||
| 30 | struct input_dev *input_dev; | ||
| 31 | int abs_x_max; | ||
| 32 | int abs_y_max; | ||
| 33 | unsigned int max_touch_num; | ||
| 34 | unsigned int int_trigger_type; | ||
| 35 | }; | ||
| 36 | |||
| 37 | #define GOODIX_MAX_HEIGHT 4096 | ||
| 38 | #define GOODIX_MAX_WIDTH 4096 | ||
| 39 | #define GOODIX_INT_TRIGGER 1 | ||
| 40 | #define GOODIX_CONTACT_SIZE 8 | ||
| 41 | #define GOODIX_MAX_CONTACTS 10 | ||
| 42 | |||
| 43 | #define GOODIX_CONFIG_MAX_LENGTH 240 | ||
| 44 | |||
| 45 | /* Register defines */ | ||
| 46 | #define GOODIX_READ_COOR_ADDR 0x814E | ||
| 47 | #define GOODIX_REG_CONFIG_DATA 0x8047 | ||
| 48 | #define GOODIX_REG_VERSION 0x8140 | ||
| 49 | |||
| 50 | #define RESOLUTION_LOC 1 | ||
| 51 | #define TRIGGER_LOC 6 | ||
| 52 | |||
| 53 | static const unsigned long goodix_irq_flags[] = { | ||
| 54 | IRQ_TYPE_EDGE_RISING, | ||
| 55 | IRQ_TYPE_EDGE_FALLING, | ||
| 56 | IRQ_TYPE_LEVEL_LOW, | ||
| 57 | IRQ_TYPE_LEVEL_HIGH, | ||
| 58 | }; | ||
| 59 | |||
| 60 | /** | ||
| 61 | * goodix_i2c_read - read data from a register of the i2c slave device. | ||
| 62 | * | ||
| 63 | * @client: i2c device. | ||
| 64 | * @reg: the register to read from. | ||
| 65 | * @buf: raw write data buffer. | ||
| 66 | * @len: length of the buffer to write | ||
| 67 | */ | ||
| 68 | static int goodix_i2c_read(struct i2c_client *client, | ||
| 69 | u16 reg, u8 *buf, int len) | ||
| 70 | { | ||
| 71 | struct i2c_msg msgs[2]; | ||
| 72 | u16 wbuf = cpu_to_be16(reg); | ||
| 73 | int ret; | ||
| 74 | |||
| 75 | msgs[0].flags = 0; | ||
| 76 | msgs[0].addr = client->addr; | ||
| 77 | msgs[0].len = 2; | ||
| 78 | msgs[0].buf = (u8 *) &wbuf; | ||
| 79 | |||
| 80 | msgs[1].flags = I2C_M_RD; | ||
| 81 | msgs[1].addr = client->addr; | ||
| 82 | msgs[1].len = len; | ||
| 83 | msgs[1].buf = buf; | ||
| 84 | |||
| 85 | ret = i2c_transfer(client->adapter, msgs, 2); | ||
| 86 | return ret < 0 ? ret : (ret != ARRAY_SIZE(msgs) ? -EIO : 0); | ||
| 87 | } | ||
| 88 | |||
| 89 | static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data) | ||
| 90 | { | ||
| 91 | int touch_num; | ||
| 92 | int error; | ||
| 93 | |||
| 94 | error = goodix_i2c_read(ts->client, GOODIX_READ_COOR_ADDR, data, | ||
| 95 | GOODIX_CONTACT_SIZE + 1); | ||
| 96 | if (error) { | ||
| 97 | dev_err(&ts->client->dev, "I2C transfer error: %d\n", error); | ||
| 98 | return error; | ||
| 99 | } | ||
| 100 | |||
| 101 | touch_num = data[0] & 0x0f; | ||
| 102 | if (touch_num > GOODIX_MAX_CONTACTS) | ||
| 103 | return -EPROTO; | ||
| 104 | |||
| 105 | if (touch_num > 1) { | ||
| 106 | data += 1 + GOODIX_CONTACT_SIZE; | ||
| 107 | error = goodix_i2c_read(ts->client, | ||
| 108 | GOODIX_READ_COOR_ADDR + | ||
| 109 | 1 + GOODIX_CONTACT_SIZE, | ||
| 110 | data, | ||
| 111 | GOODIX_CONTACT_SIZE * (touch_num - 1)); | ||
| 112 | if (error) | ||
| 113 | return error; | ||
| 114 | } | ||
| 115 | |||
| 116 | return touch_num; | ||
| 117 | } | ||
| 118 | |||
| 119 | static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data) | ||
| 120 | { | ||
| 121 | int id = coor_data[0] & 0x0F; | ||
| 122 | int input_x = get_unaligned_le16(&coor_data[1]); | ||
| 123 | int input_y = get_unaligned_le16(&coor_data[3]); | ||
| 124 | int input_w = get_unaligned_le16(&coor_data[5]); | ||
| 125 | |||
| 126 | input_mt_slot(ts->input_dev, id); | ||
| 127 | input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true); | ||
| 128 | input_report_abs(ts->input_dev, ABS_MT_POSITION_X, input_x); | ||
| 129 | input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, input_y); | ||
| 130 | input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, input_w); | ||
| 131 | input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, input_w); | ||
| 132 | } | ||
| 133 | |||
| 134 | /** | ||
| 135 | * goodix_process_events - Process incoming events | ||
| 136 | * | ||
| 137 | * @ts: our goodix_ts_data pointer | ||
| 138 | * | ||
| 139 | * Called when the IRQ is triggered. Read the current device state, and push | ||
| 140 | * the input events to the user space. | ||
| 141 | */ | ||
| 142 | static void goodix_process_events(struct goodix_ts_data *ts) | ||
| 143 | { | ||
| 144 | u8 point_data[1 + GOODIX_CONTACT_SIZE * GOODIX_MAX_CONTACTS]; | ||
| 145 | int touch_num; | ||
| 146 | int i; | ||
| 147 | |||
| 148 | touch_num = goodix_ts_read_input_report(ts, point_data); | ||
| 149 | if (touch_num < 0) | ||
| 150 | return; | ||
| 151 | |||
| 152 | for (i = 0; i < touch_num; i++) | ||
| 153 | goodix_ts_report_touch(ts, | ||
| 154 | &point_data[1 + GOODIX_CONTACT_SIZE * i]); | ||
| 155 | |||
| 156 | input_mt_sync_frame(ts->input_dev); | ||
| 157 | input_sync(ts->input_dev); | ||
| 158 | } | ||
| 159 | |||
| 160 | /** | ||
| 161 | * goodix_ts_irq_handler - The IRQ handler | ||
| 162 | * | ||
| 163 | * @irq: interrupt number. | ||
| 164 | * @dev_id: private data pointer. | ||
| 165 | */ | ||
| 166 | static irqreturn_t goodix_ts_irq_handler(int irq, void *dev_id) | ||
| 167 | { | ||
| 168 | static const u8 end_cmd[] = { | ||
| 169 | GOODIX_READ_COOR_ADDR >> 8, | ||
| 170 | GOODIX_READ_COOR_ADDR & 0xff, | ||
| 171 | 0 | ||
| 172 | }; | ||
| 173 | struct goodix_ts_data *ts = dev_id; | ||
| 174 | |||
| 175 | goodix_process_events(ts); | ||
| 176 | |||
| 177 | if (i2c_master_send(ts->client, end_cmd, sizeof(end_cmd)) < 0) | ||
| 178 | dev_err(&ts->client->dev, "I2C write end_cmd error\n"); | ||
| 179 | |||
| 180 | return IRQ_HANDLED; | ||
| 181 | } | ||
| 182 | |||
| 183 | /** | ||
| 184 | * goodix_read_config - Read the embedded configuration of the panel | ||
| 185 | * | ||
| 186 | * @ts: our goodix_ts_data pointer | ||
| 187 | * | ||
| 188 | * Must be called during probe | ||
| 189 | */ | ||
| 190 | static void goodix_read_config(struct goodix_ts_data *ts) | ||
| 191 | { | ||
| 192 | u8 config[GOODIX_CONFIG_MAX_LENGTH]; | ||
| 193 | int error; | ||
| 194 | |||
| 195 | error = goodix_i2c_read(ts->client, GOODIX_REG_CONFIG_DATA, | ||
| 196 | config, | ||
| 197 | GOODIX_CONFIG_MAX_LENGTH); | ||
| 198 | if (error) { | ||
| 199 | dev_warn(&ts->client->dev, | ||
| 200 | "Error reading config (%d), using defaults\n", | ||
| 201 | error); | ||
| 202 | ts->abs_x_max = GOODIX_MAX_WIDTH; | ||
| 203 | ts->abs_y_max = GOODIX_MAX_HEIGHT; | ||
| 204 | ts->int_trigger_type = GOODIX_INT_TRIGGER; | ||
| 205 | return; | ||
| 206 | } | ||
| 207 | |||
| 208 | ts->abs_x_max = get_unaligned_le16(&config[RESOLUTION_LOC]); | ||
| 209 | ts->abs_y_max = get_unaligned_le16(&config[RESOLUTION_LOC + 2]); | ||
| 210 | ts->int_trigger_type = (config[TRIGGER_LOC]) & 0x03; | ||
| 211 | if (!ts->abs_x_max || !ts->abs_y_max) { | ||
| 212 | dev_err(&ts->client->dev, | ||
| 213 | "Invalid config, using defaults\n"); | ||
| 214 | ts->abs_x_max = GOODIX_MAX_WIDTH; | ||
| 215 | ts->abs_y_max = GOODIX_MAX_HEIGHT; | ||
| 216 | } | ||
| 217 | } | ||
| 218 | |||
| 219 | |||
| 220 | /** | ||
| 221 | * goodix_read_version - Read goodix touchscreen version | ||
| 222 | * | ||
| 223 | * @client: the i2c client | ||
| 224 | * @version: output buffer containing the version on success | ||
| 225 | */ | ||
| 226 | static int goodix_read_version(struct i2c_client *client, u16 *version) | ||
| 227 | { | ||
| 228 | int error; | ||
| 229 | u8 buf[6]; | ||
| 230 | |||
| 231 | error = goodix_i2c_read(client, GOODIX_REG_VERSION, buf, sizeof(buf)); | ||
| 232 | if (error) { | ||
| 233 | dev_err(&client->dev, "read version failed: %d\n", error); | ||
| 234 | return error; | ||
| 235 | } | ||
| 236 | |||
| 237 | if (version) | ||
| 238 | *version = get_unaligned_le16(&buf[4]); | ||
| 239 | |||
| 240 | dev_info(&client->dev, "IC VERSION: %6ph\n", buf); | ||
| 241 | |||
| 242 | return 0; | ||
| 243 | } | ||
| 244 | |||
| 245 | /** | ||
| 246 | * goodix_i2c_test - I2C test function to check if the device answers. | ||
| 247 | * | ||
| 248 | * @client: the i2c client | ||
| 249 | */ | ||
| 250 | static int goodix_i2c_test(struct i2c_client *client) | ||
| 251 | { | ||
| 252 | int retry = 0; | ||
| 253 | int error; | ||
| 254 | u8 test; | ||
| 255 | |||
| 256 | while (retry++ < 2) { | ||
| 257 | error = goodix_i2c_read(client, GOODIX_REG_CONFIG_DATA, | ||
| 258 | &test, 1); | ||
| 259 | if (!error) | ||
| 260 | return 0; | ||
| 261 | |||
| 262 | dev_err(&client->dev, "i2c test failed attempt %d: %d\n", | ||
| 263 | retry, error); | ||
| 264 | msleep(20); | ||
| 265 | } | ||
| 266 | |||
| 267 | return error; | ||
| 268 | } | ||
| 269 | |||
| 270 | /** | ||
| 271 | * goodix_request_input_dev - Allocate, populate and register the input device | ||
| 272 | * | ||
| 273 | * @ts: our goodix_ts_data pointer | ||
| 274 | * | ||
| 275 | * Must be called during probe | ||
| 276 | */ | ||
| 277 | static int goodix_request_input_dev(struct goodix_ts_data *ts) | ||
| 278 | { | ||
| 279 | int error; | ||
| 280 | |||
| 281 | ts->input_dev = devm_input_allocate_device(&ts->client->dev); | ||
| 282 | if (!ts->input_dev) { | ||
| 283 | dev_err(&ts->client->dev, "Failed to allocate input device."); | ||
| 284 | return -ENOMEM; | ||
| 285 | } | ||
| 286 | |||
| 287 | ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | | ||
| 288 | BIT_MASK(EV_KEY) | | ||
| 289 | BIT_MASK(EV_ABS); | ||
| 290 | |||
| 291 | input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, | ||
| 292 | ts->abs_x_max, 0, 0); | ||
| 293 | input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, | ||
| 294 | ts->abs_y_max, 0, 0); | ||
| 295 | input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); | ||
| 296 | input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); | ||
| 297 | |||
| 298 | input_mt_init_slots(ts->input_dev, GOODIX_MAX_CONTACTS, | ||
| 299 | INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); | ||
| 300 | |||
| 301 | ts->input_dev->name = "Goodix Capacitive TouchScreen"; | ||
| 302 | ts->input_dev->phys = "input/ts"; | ||
| 303 | ts->input_dev->id.bustype = BUS_I2C; | ||
| 304 | ts->input_dev->id.vendor = 0x0416; | ||
| 305 | ts->input_dev->id.product = 0x1001; | ||
| 306 | ts->input_dev->id.version = 10427; | ||
| 307 | |||
| 308 | error = input_register_device(ts->input_dev); | ||
| 309 | if (error) { | ||
| 310 | dev_err(&ts->client->dev, | ||
| 311 | "Failed to register input device: %d", error); | ||
| 312 | return error; | ||
| 313 | } | ||
| 314 | |||
| 315 | return 0; | ||
| 316 | } | ||
| 317 | |||
| 318 | static int goodix_ts_probe(struct i2c_client *client, | ||
| 319 | const struct i2c_device_id *id) | ||
| 320 | { | ||
| 321 | struct goodix_ts_data *ts; | ||
| 322 | unsigned long irq_flags; | ||
| 323 | int error; | ||
| 324 | u16 version_info; | ||
| 325 | |||
| 326 | dev_dbg(&client->dev, "I2C Address: 0x%02x\n", client->addr); | ||
| 327 | |||
| 328 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { | ||
| 329 | dev_err(&client->dev, "I2C check functionality failed.\n"); | ||
| 330 | return -ENXIO; | ||
| 331 | } | ||
| 332 | |||
| 333 | ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL); | ||
| 334 | if (!ts) | ||
| 335 | return -ENOMEM; | ||
| 336 | |||
| 337 | ts->client = client; | ||
| 338 | i2c_set_clientdata(client, ts); | ||
| 339 | |||
| 340 | error = goodix_i2c_test(client); | ||
| 341 | if (error) { | ||
| 342 | dev_err(&client->dev, "I2C communication failure: %d\n", error); | ||
| 343 | return error; | ||
| 344 | } | ||
| 345 | |||
| 346 | error = goodix_read_version(client, &version_info); | ||
| 347 | if (error) { | ||
| 348 | dev_err(&client->dev, "Read version failed.\n"); | ||
| 349 | return error; | ||
| 350 | } | ||
| 351 | |||
| 352 | goodix_read_config(ts); | ||
| 353 | |||
| 354 | error = goodix_request_input_dev(ts); | ||
| 355 | if (error) | ||
| 356 | return error; | ||
| 357 | |||
| 358 | irq_flags = goodix_irq_flags[ts->int_trigger_type] | IRQF_ONESHOT; | ||
| 359 | error = devm_request_threaded_irq(&ts->client->dev, client->irq, | ||
| 360 | NULL, goodix_ts_irq_handler, | ||
| 361 | irq_flags, client->name, ts); | ||
| 362 | if (error) { | ||
| 363 | dev_err(&client->dev, "request IRQ failed: %d\n", error); | ||
| 364 | return error; | ||
| 365 | } | ||
| 366 | |||
| 367 | return 0; | ||
| 368 | } | ||
| 369 | |||
| 370 | static const struct i2c_device_id goodix_ts_id[] = { | ||
| 371 | { "GDIX1001:00", 0 }, | ||
| 372 | { } | ||
| 373 | }; | ||
| 374 | |||
| 375 | static const struct acpi_device_id goodix_acpi_match[] = { | ||
| 376 | { "GDIX1001", 0 }, | ||
| 377 | { } | ||
| 378 | }; | ||
| 379 | MODULE_DEVICE_TABLE(acpi, goodix_acpi_match); | ||
| 380 | |||
| 381 | static struct i2c_driver goodix_ts_driver = { | ||
| 382 | .probe = goodix_ts_probe, | ||
| 383 | .id_table = goodix_ts_id, | ||
| 384 | .driver = { | ||
| 385 | .name = "Goodix-TS", | ||
| 386 | .owner = THIS_MODULE, | ||
| 387 | .acpi_match_table = goodix_acpi_match, | ||
| 388 | }, | ||
| 389 | }; | ||
| 390 | module_i2c_driver(goodix_ts_driver); | ||
| 391 | |||
| 392 | MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>"); | ||
| 393 | MODULE_AUTHOR("Bastien Nocera <hadess@hadess.net>"); | ||
| 394 | MODULE_DESCRIPTION("Goodix touchscreen driver"); | ||
| 395 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c index 2a5089139818..da6dc819c846 100644 --- a/drivers/input/touchscreen/ili210x.c +++ b/drivers/input/touchscreen/ili210x.c | |||
| @@ -311,8 +311,7 @@ static int ili210x_i2c_remove(struct i2c_client *client) | |||
| 311 | return 0; | 311 | return 0; |
| 312 | } | 312 | } |
| 313 | 313 | ||
| 314 | #ifdef CONFIG_PM_SLEEP | 314 | static int __maybe_unused ili210x_i2c_suspend(struct device *dev) |
| 315 | static int ili210x_i2c_suspend(struct device *dev) | ||
| 316 | { | 315 | { |
| 317 | struct i2c_client *client = to_i2c_client(dev); | 316 | struct i2c_client *client = to_i2c_client(dev); |
| 318 | 317 | ||
| @@ -322,7 +321,7 @@ static int ili210x_i2c_suspend(struct device *dev) | |||
| 322 | return 0; | 321 | return 0; |
| 323 | } | 322 | } |
| 324 | 323 | ||
| 325 | static int ili210x_i2c_resume(struct device *dev) | 324 | static int __maybe_unused ili210x_i2c_resume(struct device *dev) |
| 326 | { | 325 | { |
| 327 | struct i2c_client *client = to_i2c_client(dev); | 326 | struct i2c_client *client = to_i2c_client(dev); |
| 328 | 327 | ||
| @@ -331,7 +330,6 @@ static int ili210x_i2c_resume(struct device *dev) | |||
| 331 | 330 | ||
| 332 | return 0; | 331 | return 0; |
| 333 | } | 332 | } |
| 334 | #endif | ||
| 335 | 333 | ||
| 336 | static SIMPLE_DEV_PM_OPS(ili210x_i2c_pm, | 334 | static SIMPLE_DEV_PM_OPS(ili210x_i2c_pm, |
| 337 | ili210x_i2c_suspend, ili210x_i2c_resume); | 335 | ili210x_i2c_suspend, ili210x_i2c_resume); |
diff --git a/drivers/input/touchscreen/ipaq-micro-ts.c b/drivers/input/touchscreen/ipaq-micro-ts.c index 62c8976e616f..33c134820ef9 100644 --- a/drivers/input/touchscreen/ipaq-micro-ts.c +++ b/drivers/input/touchscreen/ipaq-micro-ts.c | |||
| @@ -122,8 +122,7 @@ static int micro_ts_probe(struct platform_device *pdev) | |||
| 122 | return 0; | 122 | return 0; |
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | #ifdef CONFIG_PM_SLEEP | 125 | static int __maybe_unused micro_ts_suspend(struct device *dev) |
| 126 | static int micro_ts_suspend(struct device *dev) | ||
| 127 | { | 126 | { |
| 128 | struct touchscreen_data *ts = dev_get_drvdata(dev); | 127 | struct touchscreen_data *ts = dev_get_drvdata(dev); |
| 129 | 128 | ||
| @@ -132,7 +131,7 @@ static int micro_ts_suspend(struct device *dev) | |||
| 132 | return 0; | 131 | return 0; |
| 133 | } | 132 | } |
| 134 | 133 | ||
| 135 | static int micro_ts_resume(struct device *dev) | 134 | static int __maybe_unused micro_ts_resume(struct device *dev) |
| 136 | { | 135 | { |
| 137 | struct touchscreen_data *ts = dev_get_drvdata(dev); | 136 | struct touchscreen_data *ts = dev_get_drvdata(dev); |
| 138 | struct input_dev *input = ts->input; | 137 | struct input_dev *input = ts->input; |
| @@ -146,7 +145,6 @@ static int micro_ts_resume(struct device *dev) | |||
| 146 | 145 | ||
| 147 | return 0; | 146 | return 0; |
| 148 | } | 147 | } |
| 149 | #endif | ||
| 150 | 148 | ||
| 151 | static const struct dev_pm_ops micro_ts_dev_pm_ops = { | 149 | static const struct dev_pm_ops micro_ts_dev_pm_ops = { |
| 152 | SET_SYSTEM_SLEEP_PM_OPS(micro_ts_suspend, micro_ts_resume) | 150 | SET_SYSTEM_SLEEP_PM_OPS(micro_ts_suspend, micro_ts_resume) |
diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c index 372bbf7658fe..67c0d31613d8 100644 --- a/drivers/input/touchscreen/mms114.c +++ b/drivers/input/touchscreen/mms114.c | |||
| @@ -515,8 +515,7 @@ static int mms114_probe(struct i2c_client *client, | |||
| 515 | return 0; | 515 | return 0; |
| 516 | } | 516 | } |
| 517 | 517 | ||
| 518 | #ifdef CONFIG_PM_SLEEP | 518 | static int __maybe_unused mms114_suspend(struct device *dev) |
| 519 | static int mms114_suspend(struct device *dev) | ||
| 520 | { | 519 | { |
| 521 | struct i2c_client *client = to_i2c_client(dev); | 520 | struct i2c_client *client = to_i2c_client(dev); |
| 522 | struct mms114_data *data = i2c_get_clientdata(client); | 521 | struct mms114_data *data = i2c_get_clientdata(client); |
| @@ -540,7 +539,7 @@ static int mms114_suspend(struct device *dev) | |||
| 540 | return 0; | 539 | return 0; |
| 541 | } | 540 | } |
| 542 | 541 | ||
| 543 | static int mms114_resume(struct device *dev) | 542 | static int __maybe_unused mms114_resume(struct device *dev) |
| 544 | { | 543 | { |
| 545 | struct i2c_client *client = to_i2c_client(dev); | 544 | struct i2c_client *client = to_i2c_client(dev); |
| 546 | struct mms114_data *data = i2c_get_clientdata(client); | 545 | struct mms114_data *data = i2c_get_clientdata(client); |
| @@ -559,7 +558,6 @@ static int mms114_resume(struct device *dev) | |||
| 559 | 558 | ||
| 560 | return 0; | 559 | return 0; |
| 561 | } | 560 | } |
| 562 | #endif | ||
| 563 | 561 | ||
| 564 | static SIMPLE_DEV_PM_OPS(mms114_pm_ops, mms114_suspend, mms114_resume); | 562 | static SIMPLE_DEV_PM_OPS(mms114_pm_ops, mms114_suspend, mms114_resume); |
| 565 | 563 | ||
diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c index fc49c75317d1..4fb5537fdd42 100644 --- a/drivers/input/touchscreen/pixcir_i2c_ts.c +++ b/drivers/input/touchscreen/pixcir_i2c_ts.c | |||
| @@ -347,8 +347,7 @@ static void pixcir_input_close(struct input_dev *dev) | |||
| 347 | pixcir_stop(ts); | 347 | pixcir_stop(ts); |
| 348 | } | 348 | } |
| 349 | 349 | ||
| 350 | #ifdef CONFIG_PM_SLEEP | 350 | static int __maybe_unused pixcir_i2c_ts_suspend(struct device *dev) |
| 351 | static int pixcir_i2c_ts_suspend(struct device *dev) | ||
| 352 | { | 351 | { |
| 353 | struct i2c_client *client = to_i2c_client(dev); | 352 | struct i2c_client *client = to_i2c_client(dev); |
| 354 | struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client); | 353 | struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client); |
| @@ -377,7 +376,7 @@ unlock: | |||
| 377 | return ret; | 376 | return ret; |
| 378 | } | 377 | } |
| 379 | 378 | ||
| 380 | static int pixcir_i2c_ts_resume(struct device *dev) | 379 | static int __maybe_unused pixcir_i2c_ts_resume(struct device *dev) |
| 381 | { | 380 | { |
| 382 | struct i2c_client *client = to_i2c_client(dev); | 381 | struct i2c_client *client = to_i2c_client(dev); |
| 383 | struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client); | 382 | struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client); |
| @@ -405,7 +404,6 @@ unlock: | |||
| 405 | 404 | ||
| 406 | return ret; | 405 | return ret; |
| 407 | } | 406 | } |
| 408 | #endif | ||
| 409 | 407 | ||
| 410 | static SIMPLE_DEV_PM_OPS(pixcir_dev_pm_ops, | 408 | static SIMPLE_DEV_PM_OPS(pixcir_dev_pm_ops, |
| 411 | pixcir_i2c_ts_suspend, pixcir_i2c_ts_resume); | 409 | pixcir_i2c_ts_suspend, pixcir_i2c_ts_resume); |
diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c index 3c0f57efe7b1..697e26e52d54 100644 --- a/drivers/input/touchscreen/st1232.c +++ b/drivers/input/touchscreen/st1232.c | |||
| @@ -243,8 +243,7 @@ static int st1232_ts_remove(struct i2c_client *client) | |||
| 243 | return 0; | 243 | return 0; |
| 244 | } | 244 | } |
| 245 | 245 | ||
| 246 | #ifdef CONFIG_PM_SLEEP | 246 | static int __maybe_unused st1232_ts_suspend(struct device *dev) |
| 247 | static int st1232_ts_suspend(struct device *dev) | ||
| 248 | { | 247 | { |
| 249 | struct i2c_client *client = to_i2c_client(dev); | 248 | struct i2c_client *client = to_i2c_client(dev); |
| 250 | struct st1232_ts_data *ts = i2c_get_clientdata(client); | 249 | struct st1232_ts_data *ts = i2c_get_clientdata(client); |
| @@ -259,7 +258,7 @@ static int st1232_ts_suspend(struct device *dev) | |||
| 259 | return 0; | 258 | return 0; |
| 260 | } | 259 | } |
| 261 | 260 | ||
| 262 | static int st1232_ts_resume(struct device *dev) | 261 | static int __maybe_unused st1232_ts_resume(struct device *dev) |
| 263 | { | 262 | { |
| 264 | struct i2c_client *client = to_i2c_client(dev); | 263 | struct i2c_client *client = to_i2c_client(dev); |
| 265 | struct st1232_ts_data *ts = i2c_get_clientdata(client); | 264 | struct st1232_ts_data *ts = i2c_get_clientdata(client); |
| @@ -274,8 +273,6 @@ static int st1232_ts_resume(struct device *dev) | |||
| 274 | return 0; | 273 | return 0; |
| 275 | } | 274 | } |
| 276 | 275 | ||
| 277 | #endif | ||
| 278 | |||
| 279 | static SIMPLE_DEV_PM_OPS(st1232_ts_pm_ops, | 276 | static SIMPLE_DEV_PM_OPS(st1232_ts_pm_ops, |
| 280 | st1232_ts_suspend, st1232_ts_resume); | 277 | st1232_ts_suspend, st1232_ts_resume); |
| 281 | 278 | ||
diff --git a/drivers/input/touchscreen/tsc2005.c b/drivers/input/touchscreen/tsc2005.c index 52380b68ebdf..72657c579430 100644 --- a/drivers/input/touchscreen/tsc2005.c +++ b/drivers/input/touchscreen/tsc2005.c | |||
| @@ -773,8 +773,7 @@ static int tsc2005_remove(struct spi_device *spi) | |||
| 773 | return 0; | 773 | return 0; |
| 774 | } | 774 | } |
| 775 | 775 | ||
| 776 | #ifdef CONFIG_PM_SLEEP | 776 | static int __maybe_unused tsc2005_suspend(struct device *dev) |
| 777 | static int tsc2005_suspend(struct device *dev) | ||
| 778 | { | 777 | { |
| 779 | struct spi_device *spi = to_spi_device(dev); | 778 | struct spi_device *spi = to_spi_device(dev); |
| 780 | struct tsc2005 *ts = spi_get_drvdata(spi); | 779 | struct tsc2005 *ts = spi_get_drvdata(spi); |
| @@ -791,7 +790,7 @@ static int tsc2005_suspend(struct device *dev) | |||
| 791 | return 0; | 790 | return 0; |
| 792 | } | 791 | } |
| 793 | 792 | ||
| 794 | static int tsc2005_resume(struct device *dev) | 793 | static int __maybe_unused tsc2005_resume(struct device *dev) |
| 795 | { | 794 | { |
| 796 | struct spi_device *spi = to_spi_device(dev); | 795 | struct spi_device *spi = to_spi_device(dev); |
| 797 | struct tsc2005 *ts = spi_get_drvdata(spi); | 796 | struct tsc2005 *ts = spi_get_drvdata(spi); |
| @@ -807,7 +806,6 @@ static int tsc2005_resume(struct device *dev) | |||
| 807 | 806 | ||
| 808 | return 0; | 807 | return 0; |
| 809 | } | 808 | } |
| 810 | #endif | ||
| 811 | 809 | ||
| 812 | static SIMPLE_DEV_PM_OPS(tsc2005_pm_ops, tsc2005_suspend, tsc2005_resume); | 810 | static SIMPLE_DEV_PM_OPS(tsc2005_pm_ops, tsc2005_suspend, tsc2005_resume); |
| 813 | 811 | ||
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c index 0eca00da584b..c1e23cfc6155 100644 --- a/drivers/input/touchscreen/ucb1400_ts.c +++ b/drivers/input/touchscreen/ucb1400_ts.c | |||
| @@ -406,8 +406,7 @@ static int ucb1400_ts_remove(struct platform_device *pdev) | |||
| 406 | return 0; | 406 | return 0; |
| 407 | } | 407 | } |
| 408 | 408 | ||
| 409 | #ifdef CONFIG_PM_SLEEP | 409 | static int __maybe_unused ucb1400_ts_suspend(struct device *dev) |
| 410 | static int ucb1400_ts_suspend(struct device *dev) | ||
| 411 | { | 410 | { |
| 412 | struct ucb1400_ts *ucb = dev_get_platdata(dev); | 411 | struct ucb1400_ts *ucb = dev_get_platdata(dev); |
| 413 | struct input_dev *idev = ucb->ts_idev; | 412 | struct input_dev *idev = ucb->ts_idev; |
| @@ -421,7 +420,7 @@ static int ucb1400_ts_suspend(struct device *dev) | |||
| 421 | return 0; | 420 | return 0; |
| 422 | } | 421 | } |
| 423 | 422 | ||
| 424 | static int ucb1400_ts_resume(struct device *dev) | 423 | static int __maybe_unused ucb1400_ts_resume(struct device *dev) |
| 425 | { | 424 | { |
| 426 | struct ucb1400_ts *ucb = dev_get_platdata(dev); | 425 | struct ucb1400_ts *ucb = dev_get_platdata(dev); |
| 427 | struct input_dev *idev = ucb->ts_idev; | 426 | struct input_dev *idev = ucb->ts_idev; |
| @@ -434,7 +433,6 @@ static int ucb1400_ts_resume(struct device *dev) | |||
| 434 | mutex_unlock(&idev->mutex); | 433 | mutex_unlock(&idev->mutex); |
| 435 | return 0; | 434 | return 0; |
| 436 | } | 435 | } |
| 437 | #endif | ||
| 438 | 436 | ||
| 439 | static SIMPLE_DEV_PM_OPS(ucb1400_ts_pm_ops, | 437 | static SIMPLE_DEV_PM_OPS(ucb1400_ts_pm_ops, |
| 440 | ucb1400_ts_suspend, ucb1400_ts_resume); | 438 | ucb1400_ts_suspend, ucb1400_ts_resume); |
diff --git a/drivers/input/touchscreen/wacom_i2c.c b/drivers/input/touchscreen/wacom_i2c.c index 7ccaa1b12b05..32f8ac003936 100644 --- a/drivers/input/touchscreen/wacom_i2c.c +++ b/drivers/input/touchscreen/wacom_i2c.c | |||
| @@ -242,8 +242,7 @@ static int wacom_i2c_remove(struct i2c_client *client) | |||
| 242 | return 0; | 242 | return 0; |
| 243 | } | 243 | } |
| 244 | 244 | ||
| 245 | #ifdef CONFIG_PM_SLEEP | 245 | static int __maybe_unused wacom_i2c_suspend(struct device *dev) |
| 246 | static int wacom_i2c_suspend(struct device *dev) | ||
| 247 | { | 246 | { |
| 248 | struct i2c_client *client = to_i2c_client(dev); | 247 | struct i2c_client *client = to_i2c_client(dev); |
| 249 | 248 | ||
| @@ -252,7 +251,7 @@ static int wacom_i2c_suspend(struct device *dev) | |||
| 252 | return 0; | 251 | return 0; |
| 253 | } | 252 | } |
| 254 | 253 | ||
| 255 | static int wacom_i2c_resume(struct device *dev) | 254 | static int __maybe_unused wacom_i2c_resume(struct device *dev) |
| 256 | { | 255 | { |
| 257 | struct i2c_client *client = to_i2c_client(dev); | 256 | struct i2c_client *client = to_i2c_client(dev); |
| 258 | 257 | ||
| @@ -260,7 +259,6 @@ static int wacom_i2c_resume(struct device *dev) | |||
| 260 | 259 | ||
| 261 | return 0; | 260 | return 0; |
| 262 | } | 261 | } |
| 263 | #endif | ||
| 264 | 262 | ||
| 265 | static SIMPLE_DEV_PM_OPS(wacom_i2c_pm, wacom_i2c_suspend, wacom_i2c_resume); | 263 | static SIMPLE_DEV_PM_OPS(wacom_i2c_pm, wacom_i2c_suspend, wacom_i2c_resume); |
| 266 | 264 | ||
diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c index 8ba48f5eff7b..19880c7385e3 100644 --- a/drivers/input/touchscreen/zforce_ts.c +++ b/drivers/input/touchscreen/zforce_ts.c | |||
| @@ -602,8 +602,7 @@ static void zforce_input_close(struct input_dev *dev) | |||
| 602 | return; | 602 | return; |
| 603 | } | 603 | } |
| 604 | 604 | ||
| 605 | #ifdef CONFIG_PM_SLEEP | 605 | static int __maybe_unused zforce_suspend(struct device *dev) |
| 606 | static int zforce_suspend(struct device *dev) | ||
| 607 | { | 606 | { |
| 608 | struct i2c_client *client = to_i2c_client(dev); | 607 | struct i2c_client *client = to_i2c_client(dev); |
| 609 | struct zforce_ts *ts = i2c_get_clientdata(client); | 608 | struct zforce_ts *ts = i2c_get_clientdata(client); |
| @@ -648,7 +647,7 @@ unlock: | |||
| 648 | return ret; | 647 | return ret; |
| 649 | } | 648 | } |
| 650 | 649 | ||
| 651 | static int zforce_resume(struct device *dev) | 650 | static int __maybe_unused zforce_resume(struct device *dev) |
| 652 | { | 651 | { |
| 653 | struct i2c_client *client = to_i2c_client(dev); | 652 | struct i2c_client *client = to_i2c_client(dev); |
| 654 | struct zforce_ts *ts = i2c_get_clientdata(client); | 653 | struct zforce_ts *ts = i2c_get_clientdata(client); |
| @@ -685,7 +684,6 @@ unlock: | |||
| 685 | 684 | ||
| 686 | return ret; | 685 | return ret; |
| 687 | } | 686 | } |
| 688 | #endif | ||
| 689 | 687 | ||
| 690 | static SIMPLE_DEV_PM_OPS(zforce_pm_ops, zforce_suspend, zforce_resume); | 688 | static SIMPLE_DEV_PM_OPS(zforce_pm_ops, zforce_suspend, zforce_resume); |
| 691 | 689 | ||
