diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2019-05-10 14:40:35 -0400 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2019-05-10 14:40:35 -0400 |
| commit | 14e0c7317ed58bcd15af5c3d09818ee0f2e3984c (patch) | |
| tree | f9b63dc681574484c23c6b01be81f17cf9c64d6a | |
| parent | 3a349763cf11e63534b8f2d302f2d0c790566497 (diff) | |
| parent | 0981949da8f7498b96c6e0ae60680865ca283bf1 (diff) | |
Merge branch 'next' into for-linus
Prepare input updates for 5.2 merge window.
30 files changed, 2297 insertions, 74 deletions
diff --git a/Documentation/devicetree/bindings/input/gpio-vibrator.yaml b/Documentation/devicetree/bindings/input/gpio-vibrator.yaml new file mode 100644 index 000000000000..903475f52dbd --- /dev/null +++ b/Documentation/devicetree/bindings/input/gpio-vibrator.yaml | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/bindings/input/gpio-vibrator.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: GPIO vibrator | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Luca Weiss <luca@z3ntu.xyz> | ||
| 11 | |||
| 12 | description: |+ | ||
| 13 | Registers a GPIO device as vibrator, where the on/off capability is controlled by a GPIO. | ||
| 14 | |||
| 15 | properties: | ||
| 16 | compatible: | ||
| 17 | const: gpio-vibrator | ||
| 18 | |||
| 19 | enable-gpios: | ||
| 20 | maxItems: 1 | ||
| 21 | |||
| 22 | vcc-supply: | ||
| 23 | description: Regulator that provides power | ||
| 24 | |||
| 25 | required: | ||
| 26 | - compatible | ||
| 27 | - enable-gpios | ||
| 28 | |||
| 29 | examples: | ||
| 30 | - | | ||
| 31 | #include <dt-bindings/gpio/gpio.h> | ||
| 32 | |||
| 33 | vibrator { | ||
| 34 | compatible = "gpio-vibrator"; | ||
| 35 | enable-gpios = <&msmgpio 86 GPIO_ACTIVE_HIGH>; | ||
| 36 | vcc-supply = <&pm8941_l18>; | ||
| 37 | }; | ||
diff --git a/Documentation/devicetree/bindings/input/lpc32xx-key.txt b/Documentation/devicetree/bindings/input/lpc32xx-key.txt index bcf62f856358..2b075a080d30 100644 --- a/Documentation/devicetree/bindings/input/lpc32xx-key.txt +++ b/Documentation/devicetree/bindings/input/lpc32xx-key.txt | |||
| @@ -8,6 +8,7 @@ Required Properties: | |||
| 8 | - reg: Physical base address of the controller and length of memory mapped | 8 | - reg: Physical base address of the controller and length of memory mapped |
| 9 | region. | 9 | region. |
| 10 | - interrupts: The interrupt number to the cpu. | 10 | - interrupts: The interrupt number to the cpu. |
| 11 | - clocks: phandle to clock controller plus clock-specifier pair | ||
| 11 | - nxp,debounce-delay-ms: Debounce delay in ms | 12 | - nxp,debounce-delay-ms: Debounce delay in ms |
| 12 | - nxp,scan-delay-ms: Repeated scan period in ms | 13 | - nxp,scan-delay-ms: Repeated scan period in ms |
| 13 | - linux,keymap: the key-code to be reported when the key is pressed | 14 | - linux,keymap: the key-code to be reported when the key is pressed |
| @@ -22,7 +23,9 @@ Example: | |||
| 22 | key@40050000 { | 23 | key@40050000 { |
| 23 | compatible = "nxp,lpc3220-key"; | 24 | compatible = "nxp,lpc3220-key"; |
| 24 | reg = <0x40050000 0x1000>; | 25 | reg = <0x40050000 0x1000>; |
| 25 | interrupts = <54 0>; | 26 | clocks = <&clk LPC32XX_CLK_KEY>; |
| 27 | interrupt-parent = <&sic1>; | ||
| 28 | interrupts = <22 IRQ_TYPE_LEVEL_HIGH>; | ||
| 26 | keypad,num-rows = <1>; | 29 | keypad,num-rows = <1>; |
| 27 | keypad,num-columns = <1>; | 30 | keypad,num-columns = <1>; |
| 28 | nxp,debounce-delay-ms = <3>; | 31 | nxp,debounce-delay-ms = <3>; |
diff --git a/Documentation/devicetree/bindings/input/microchip,qt1050.txt b/Documentation/devicetree/bindings/input/microchip,qt1050.txt new file mode 100644 index 000000000000..80e75f96252b --- /dev/null +++ b/Documentation/devicetree/bindings/input/microchip,qt1050.txt | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | Microchip AT42QT1050 Five-channel Touch Sensor IC | ||
| 2 | |||
| 3 | The AT42QT1050 (QT1050) is a QTouchADC sensor device. The device can sense from | ||
| 4 | one to five keys, dependent on mode. The QT1050 includes all signal processing | ||
| 5 | functions necessary to provide stable sensing under a wide variety of changing | ||
| 6 | conditions, and the outputs are fully debounced. | ||
| 7 | |||
| 8 | The touchkey device node should be placed inside an I2C bus node. | ||
| 9 | |||
| 10 | Required properties: | ||
| 11 | - compatible: Must be "microchip,qt1050" | ||
| 12 | - reg: The I2C address of the device | ||
| 13 | - interrupts: The sink for the touchpad's IRQ output, | ||
| 14 | see ../interrupt-controller/interrupts.txt | ||
| 15 | |||
| 16 | Optional properties: | ||
| 17 | - wakeup-source: touch keys can be used as a wakeup source | ||
| 18 | |||
| 19 | Each button (key) is represented as a sub-node: | ||
| 20 | |||
| 21 | Each not specified key or key with linux,code set to KEY_RESERVED gets disabled | ||
| 22 | in HW. | ||
| 23 | |||
| 24 | Subnode properties: | ||
| 25 | - linux,code: Keycode to emit. | ||
| 26 | - reg: The key number. Valid values: 0, 1, 2, 3, 4. | ||
| 27 | |||
| 28 | Optional subnode-properties: | ||
| 29 | |||
| 30 | If a optional property is missing or has a invalid value the default value is | ||
| 31 | taken. | ||
| 32 | |||
| 33 | - microchip,pre-charge-time-ns: | ||
| 34 | Each touchpad need some time to precharge. The value depends on the mechanical | ||
| 35 | layout. | ||
| 36 | Valid value range: 0 - 637500; values must be a multiple of 2500; | ||
| 37 | default is 0. | ||
| 38 | - microchip,average-samples: | ||
| 39 | Number of data samples which are averaged for each read. | ||
| 40 | Valid values: 1, 4, 16, 64, 256, 1024, 4096, 16384; default is 1. | ||
| 41 | - microchip,average-scaling: | ||
| 42 | The scaling factor which is used to scale the average-samples. | ||
| 43 | Valid values: 1, 2, 4, 8, 16, 32, 64, 128; default is 1. | ||
| 44 | - microchip,threshold: | ||
| 45 | Number of counts to register a touch detection. | ||
| 46 | Valid value range: 0 - 255; default is 20. | ||
| 47 | |||
| 48 | Example: | ||
| 49 | QT1050 with 3 non continuous keys, key2 and key4 are disabled. | ||
| 50 | |||
| 51 | touchkeys@41 { | ||
| 52 | compatible = "microchip,qt1050"; | ||
| 53 | reg = <0x41>; | ||
| 54 | interrupt-parent = <&gpio0>; | ||
| 55 | interrupts = <17 IRQ_TYPE_EDGE_FALLING>; | ||
| 56 | |||
| 57 | up@0 { | ||
| 58 | reg = <0>; | ||
| 59 | linux,code = <KEY_UP>; | ||
| 60 | microchip,average-samples = <64>; | ||
| 61 | microchip,average-scaling = <16>; | ||
| 62 | microchip,pre-charge-time-ns = <10000>; | ||
| 63 | }; | ||
| 64 | |||
| 65 | right@1 { | ||
| 66 | reg = <1>; | ||
| 67 | linux,code = <KEY_RIGHT>; | ||
| 68 | microchip,average-samples = <64>; | ||
| 69 | microchip,average-scaling = <8>; | ||
| 70 | }; | ||
| 71 | |||
| 72 | down@3 { | ||
| 73 | reg = <3>; | ||
| 74 | linux,code = <KEY_DOWN>; | ||
| 75 | microchip,average-samples = <256>; | ||
| 76 | microchip,average-scaling = <16>; | ||
| 77 | }; | ||
| 78 | }; | ||
diff --git a/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt b/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt index 1458c3179a63..496125c6bfb7 100644 --- a/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt +++ b/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt | |||
| @@ -2,12 +2,14 @@ Allwinner sun4i low res adc attached tablet keys | |||
| 2 | ------------------------------------------------ | 2 | ------------------------------------------------ |
| 3 | 3 | ||
| 4 | Required properties: | 4 | Required properties: |
| 5 | - compatible: "allwinner,sun4i-a10-lradc-keys" | 5 | - compatible: should be one of the following string: |
| 6 | "allwinner,sun4i-a10-lradc-keys" | ||
| 7 | "allwinner,sun8i-a83t-r-lradc" | ||
| 6 | - reg: mmio address range of the chip | 8 | - reg: mmio address range of the chip |
| 7 | - interrupts: interrupt to which the chip is connected | 9 | - interrupts: interrupt to which the chip is connected |
| 8 | - vref-supply: powersupply for the lradc reference voltage | 10 | - vref-supply: powersupply for the lradc reference voltage |
| 9 | 11 | ||
| 10 | Each key is represented as a sub-node of "allwinner,sun4i-a10-lradc-keys": | 12 | Each key is represented as a sub-node of the compatible mentioned above: |
| 11 | 13 | ||
| 12 | Required subnode-properties: | 14 | Required subnode-properties: |
| 13 | - label: Descriptive name of the key. | 15 | - label: Descriptive name of the key. |
diff --git a/Documentation/devicetree/bindings/input/touchscreen/goodix.txt b/Documentation/devicetree/bindings/input/touchscreen/goodix.txt index 8cf0b4d38a7e..fc03ea4cf5ab 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/goodix.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/goodix.txt | |||
| @@ -3,6 +3,7 @@ Device tree bindings for Goodix GT9xx series touchscreen controller | |||
| 3 | Required properties: | 3 | Required properties: |
| 4 | 4 | ||
| 5 | - compatible : Should be "goodix,gt1151" | 5 | - compatible : Should be "goodix,gt1151" |
| 6 | or "goodix,gt5663" | ||
| 6 | or "goodix,gt5688" | 7 | or "goodix,gt5688" |
| 7 | or "goodix,gt911" | 8 | or "goodix,gt911" |
| 8 | or "goodix,gt9110" | 9 | or "goodix,gt9110" |
| @@ -19,6 +20,8 @@ Optional properties: | |||
| 19 | - irq-gpios : GPIO pin used for IRQ. The driver uses the | 20 | - irq-gpios : GPIO pin used for IRQ. The driver uses the |
| 20 | interrupt gpio pin as output to reset the device. | 21 | interrupt gpio pin as output to reset the device. |
| 21 | - reset-gpios : GPIO pin used for reset | 22 | - reset-gpios : GPIO pin used for reset |
| 23 | - AVDD28-supply : Analog power supply regulator on AVDD28 pin | ||
| 24 | - VDDIO-supply : GPIO power supply regulator on VDDIO pin | ||
| 22 | - touchscreen-inverted-x | 25 | - touchscreen-inverted-x |
| 23 | - touchscreen-inverted-y | 26 | - touchscreen-inverted-y |
| 24 | - touchscreen-size-x | 27 | - touchscreen-size-x |
diff --git a/Documentation/devicetree/bindings/input/touchscreen/iqs5xx.txt b/Documentation/devicetree/bindings/input/touchscreen/iqs5xx.txt new file mode 100644 index 000000000000..efa0820e2469 --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/iqs5xx.txt | |||
| @@ -0,0 +1,80 @@ | |||
| 1 | Azoteq IQS550/572/525 Trackpad/Touchscreen Controller | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | |||
| 5 | - compatible : Must be equal to one of the following: | ||
| 6 | "azoteq,iqs550" | ||
| 7 | "azoteq,iqs572" | ||
| 8 | "azoteq,iqs525" | ||
| 9 | |||
| 10 | - reg : I2C slave address for the device. | ||
| 11 | |||
| 12 | - interrupts : GPIO to which the device's active-high RDY | ||
| 13 | output is connected (see [0]). | ||
| 14 | |||
| 15 | - reset-gpios : GPIO to which the device's active-low NRST | ||
| 16 | input is connected (see [1]). | ||
| 17 | |||
| 18 | Optional properties: | ||
| 19 | |||
| 20 | - touchscreen-min-x : See [2]. | ||
| 21 | |||
| 22 | - touchscreen-min-y : See [2]. | ||
| 23 | |||
| 24 | - touchscreen-size-x : See [2]. If this property is omitted, the | ||
| 25 | maximum x-coordinate is specified by the | ||
| 26 | device's "X Resolution" register. | ||
| 27 | |||
| 28 | - touchscreen-size-y : See [2]. If this property is omitted, the | ||
| 29 | maximum y-coordinate is specified by the | ||
| 30 | device's "Y Resolution" register. | ||
| 31 | |||
| 32 | - touchscreen-max-pressure : See [2]. Pressure is expressed as the sum of | ||
| 33 | the deltas across all channels impacted by a | ||
| 34 | touch event. A channel's delta is calculated | ||
| 35 | as its count value minus a reference, where | ||
| 36 | the count value is inversely proportional to | ||
| 37 | the channel's capacitance. | ||
| 38 | |||
| 39 | - touchscreen-fuzz-x : See [2]. | ||
| 40 | |||
| 41 | - touchscreen-fuzz-y : See [2]. | ||
| 42 | |||
| 43 | - touchscreen-fuzz-pressure : See [2]. | ||
| 44 | |||
| 45 | - touchscreen-inverted-x : See [2]. Inversion is applied relative to that | ||
| 46 | which may already be specified by the device's | ||
| 47 | FLIP_X and FLIP_Y register fields. | ||
| 48 | |||
| 49 | - touchscreen-inverted-y : See [2]. Inversion is applied relative to that | ||
| 50 | which may already be specified by the device's | ||
| 51 | FLIP_X and FLIP_Y register fields. | ||
| 52 | |||
| 53 | - touchscreen-swapped-x-y : See [2]. Swapping is applied relative to that | ||
| 54 | which may already be specified by the device's | ||
| 55 | SWITCH_XY_AXIS register field. | ||
| 56 | |||
| 57 | [0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt | ||
| 58 | [1]: Documentation/devicetree/bindings/gpio/gpio.txt | ||
| 59 | [2]: Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt | ||
| 60 | |||
| 61 | Example: | ||
| 62 | |||
| 63 | &i2c1 { | ||
| 64 | /* ... */ | ||
| 65 | |||
| 66 | touchscreen@74 { | ||
| 67 | compatible = "azoteq,iqs550"; | ||
| 68 | reg = <0x74>; | ||
| 69 | interrupt-parent = <&gpio>; | ||
| 70 | interrupts = <17 4>; | ||
| 71 | reset-gpios = <&gpio 27 1>; | ||
| 72 | |||
| 73 | touchscreen-size-x = <640>; | ||
| 74 | touchscreen-size-y = <480>; | ||
| 75 | |||
| 76 | touchscreen-max-pressure = <16000>; | ||
| 77 | }; | ||
| 78 | |||
| 79 | /* ... */ | ||
| 80 | }; | ||
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 4b1a2a8fcc16..51f99549161e 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt | |||
| @@ -53,6 +53,7 @@ avic Shanghai AVIC Optoelectronics Co., Ltd. | |||
| 53 | avnet Avnet, Inc. | 53 | avnet Avnet, Inc. |
| 54 | axentia Axentia Technologies AB | 54 | axentia Axentia Technologies AB |
| 55 | axis Axis Communications AB | 55 | axis Axis Communications AB |
| 56 | azoteq Azoteq (Pty) Ltd | ||
| 56 | bananapi BIPAI KEJI LIMITED | 57 | bananapi BIPAI KEJI LIMITED |
| 57 | bhf Beckhoff Automation GmbH & Co. KG | 58 | bhf Beckhoff Automation GmbH & Co. KG |
| 58 | bitmain Bitmain Technologies | 59 | bitmain Bitmain Technologies |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index da76358cde06..89d00c34a184 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
| @@ -1036,6 +1036,8 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
| 1036 | case 0x28b: map_key_clear(KEY_FORWARDMAIL); break; | 1036 | case 0x28b: map_key_clear(KEY_FORWARDMAIL); break; |
| 1037 | case 0x28c: map_key_clear(KEY_SEND); break; | 1037 | case 0x28c: map_key_clear(KEY_SEND); break; |
| 1038 | 1038 | ||
| 1039 | case 0x29d: map_key_clear(KEY_KBD_LAYOUT_NEXT); break; | ||
| 1040 | |||
| 1039 | case 0x2c7: map_key_clear(KEY_KBDINPUTASSIST_PREV); break; | 1041 | case 0x2c7: map_key_clear(KEY_KBDINPUTASSIST_PREV); break; |
| 1040 | case 0x2c8: map_key_clear(KEY_KBDINPUTASSIST_NEXT); break; | 1042 | case 0x2c8: map_key_clear(KEY_KBDINPUTASSIST_NEXT); break; |
| 1041 | case 0x2c9: map_key_clear(KEY_KBDINPUTASSIST_PREVGROUP); break; | 1043 | case 0x2c9: map_key_clear(KEY_KBDINPUTASSIST_PREVGROUP); break; |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index f48369d6f3a0..ee8dd8b1b09e 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
| @@ -503,14 +503,13 @@ static int evdev_open(struct inode *inode, struct file *file) | |||
| 503 | { | 503 | { |
| 504 | struct evdev *evdev = container_of(inode->i_cdev, struct evdev, cdev); | 504 | struct evdev *evdev = container_of(inode->i_cdev, struct evdev, cdev); |
| 505 | unsigned int bufsize = evdev_compute_buffer_size(evdev->handle.dev); | 505 | unsigned int bufsize = evdev_compute_buffer_size(evdev->handle.dev); |
| 506 | unsigned int size = sizeof(struct evdev_client) + | ||
| 507 | bufsize * sizeof(struct input_event); | ||
| 508 | struct evdev_client *client; | 506 | struct evdev_client *client; |
| 509 | int error; | 507 | int error; |
| 510 | 508 | ||
| 511 | client = kzalloc(size, GFP_KERNEL | __GFP_NOWARN); | 509 | client = kzalloc(struct_size(client, buffer, bufsize), |
| 510 | GFP_KERNEL | __GFP_NOWARN); | ||
| 512 | if (!client) | 511 | if (!client) |
| 513 | client = vzalloc(size); | 512 | client = vzalloc(struct_size(client, buffer, bufsize)); |
| 514 | if (!client) | 513 | if (!client) |
| 515 | return -ENOMEM; | 514 | return -ENOMEM; |
| 516 | 515 | ||
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 52d7f55fca32..1fe039d7326b 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
| @@ -137,6 +137,17 @@ config KEYBOARD_ATKBD_RDI_KEYCODES | |||
| 137 | right-hand column will be interpreted as the key shown in the | 137 | right-hand column will be interpreted as the key shown in the |
| 138 | left-hand column. | 138 | left-hand column. |
| 139 | 139 | ||
| 140 | config KEYBOARD_QT1050 | ||
| 141 | tristate "Microchip AT42QT1050 Touch Sensor Chip" | ||
| 142 | depends on I2C | ||
| 143 | select REGMAP_I2C | ||
| 144 | help | ||
| 145 | Say Y here if you want to use Microchip AT42QT1050 QTouch | ||
| 146 | Sensor chip as input device. | ||
| 147 | |||
| 148 | To compile this driver as a module, choose M here: | ||
| 149 | the module will be called qt1050 | ||
| 150 | |||
| 140 | config KEYBOARD_QT1070 | 151 | config KEYBOARD_QT1070 |
| 141 | tristate "Atmel AT42QT1070 Touch Sensor Chip" | 152 | tristate "Atmel AT42QT1070 Touch Sensor Chip" |
| 142 | depends on I2C | 153 | depends on I2C |
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 182e92985dbf..f0291ca39f62 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
| @@ -50,6 +50,7 @@ obj-$(CONFIG_KEYBOARD_OPENCORES) += opencores-kbd.o | |||
| 50 | obj-$(CONFIG_KEYBOARD_PMIC8XXX) += pmic8xxx-keypad.o | 50 | obj-$(CONFIG_KEYBOARD_PMIC8XXX) += pmic8xxx-keypad.o |
| 51 | obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o | 51 | obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o |
| 52 | obj-$(CONFIG_KEYBOARD_PXA930_ROTARY) += pxa930_rotary.o | 52 | obj-$(CONFIG_KEYBOARD_PXA930_ROTARY) += pxa930_rotary.o |
| 53 | obj-$(CONFIG_KEYBOARD_QT1050) += qt1050.o | ||
| 53 | obj-$(CONFIG_KEYBOARD_QT1070) += qt1070.o | 54 | obj-$(CONFIG_KEYBOARD_QT1070) += qt1070.o |
| 54 | obj-$(CONFIG_KEYBOARD_QT2160) += qt2160.o | 55 | obj-$(CONFIG_KEYBOARD_QT2160) += qt2160.o |
| 55 | obj-$(CONFIG_KEYBOARD_SAMSUNG) += samsung-keypad.o | 56 | obj-$(CONFIG_KEYBOARD_SAMSUNG) += samsung-keypad.o |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 850bb259c20e..3ad93e3e2f4c 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
| @@ -401,6 +401,8 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, | |||
| 401 | if (ps2_handle_response(&atkbd->ps2dev, data)) | 401 | if (ps2_handle_response(&atkbd->ps2dev, data)) |
| 402 | goto out; | 402 | goto out; |
| 403 | 403 | ||
| 404 | pm_wakeup_event(&serio->dev, 0); | ||
| 405 | |||
| 404 | if (!atkbd->enabled) | 406 | if (!atkbd->enabled) |
| 405 | goto out; | 407 | goto out; |
| 406 | 408 | ||
diff --git a/drivers/input/keyboard/qt1050.c b/drivers/input/keyboard/qt1050.c new file mode 100644 index 000000000000..403060d05c3b --- /dev/null +++ b/drivers/input/keyboard/qt1050.c | |||
| @@ -0,0 +1,598 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * Microchip AT42QT1050 QTouch Sensor Controller | ||
| 4 | * | ||
| 5 | * Copyright (C) 2019 Pengutronix, Marco Felsch <kernel@pengutronix.de> | ||
| 6 | * | ||
| 7 | * Base on AT42QT1070 driver by: | ||
| 8 | * Bo Shen <voice.shen@atmel.com> | ||
| 9 | * Copyright (C) 2011 Atmel | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/delay.h> | ||
| 13 | #include <linux/i2c.h> | ||
| 14 | #include <linux/input.h> | ||
| 15 | #include <linux/interrupt.h> | ||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/log2.h> | ||
| 18 | #include <linux/module.h> | ||
| 19 | #include <linux/of.h> | ||
| 20 | #include <linux/regmap.h> | ||
| 21 | |||
| 22 | /* Chip ID */ | ||
| 23 | #define QT1050_CHIP_ID 0x00 | ||
| 24 | #define QT1050_CHIP_ID_VER 0x46 | ||
| 25 | |||
| 26 | /* Firmware version */ | ||
| 27 | #define QT1050_FW_VERSION 0x01 | ||
| 28 | |||
| 29 | /* Detection status */ | ||
| 30 | #define QT1050_DET_STATUS 0x02 | ||
| 31 | |||
| 32 | /* Key status */ | ||
| 33 | #define QT1050_KEY_STATUS 0x03 | ||
| 34 | |||
| 35 | /* Key Signals */ | ||
| 36 | #define QT1050_KEY_SIGNAL_0_MSB 0x06 | ||
| 37 | #define QT1050_KEY_SIGNAL_0_LSB 0x07 | ||
| 38 | #define QT1050_KEY_SIGNAL_1_MSB 0x08 | ||
| 39 | #define QT1050_KEY_SIGNAL_1_LSB 0x09 | ||
| 40 | #define QT1050_KEY_SIGNAL_2_MSB 0x0c | ||
| 41 | #define QT1050_KEY_SIGNAL_2_LSB 0x0d | ||
| 42 | #define QT1050_KEY_SIGNAL_3_MSB 0x0e | ||
| 43 | #define QT1050_KEY_SIGNAL_3_LSB 0x0f | ||
| 44 | #define QT1050_KEY_SIGNAL_4_MSB 0x10 | ||
| 45 | #define QT1050_KEY_SIGNAL_4_LSB 0x11 | ||
| 46 | |||
| 47 | /* Reference data */ | ||
| 48 | #define QT1050_REF_DATA_0_MSB 0x14 | ||
| 49 | #define QT1050_REF_DATA_0_LSB 0x15 | ||
| 50 | #define QT1050_REF_DATA_1_MSB 0x16 | ||
| 51 | #define QT1050_REF_DATA_1_LSB 0x17 | ||
| 52 | #define QT1050_REF_DATA_2_MSB 0x1a | ||
| 53 | #define QT1050_REF_DATA_2_LSB 0x1b | ||
| 54 | #define QT1050_REF_DATA_3_MSB 0x1c | ||
| 55 | #define QT1050_REF_DATA_3_LSB 0x1d | ||
| 56 | #define QT1050_REF_DATA_4_MSB 0x1e | ||
| 57 | #define QT1050_REF_DATA_4_LSB 0x1f | ||
| 58 | |||
| 59 | /* Negative threshold level */ | ||
| 60 | #define QT1050_NTHR_0 0x21 | ||
| 61 | #define QT1050_NTHR_1 0x22 | ||
| 62 | #define QT1050_NTHR_2 0x24 | ||
| 63 | #define QT1050_NTHR_3 0x25 | ||
| 64 | #define QT1050_NTHR_4 0x26 | ||
| 65 | |||
| 66 | /* Pulse / Scale */ | ||
| 67 | #define QT1050_PULSE_SCALE_0 0x28 | ||
| 68 | #define QT1050_PULSE_SCALE_1 0x29 | ||
| 69 | #define QT1050_PULSE_SCALE_2 0x2b | ||
| 70 | #define QT1050_PULSE_SCALE_3 0x2c | ||
| 71 | #define QT1050_PULSE_SCALE_4 0x2d | ||
| 72 | |||
| 73 | /* Detection integrator counter / AKS */ | ||
| 74 | #define QT1050_DI_AKS_0 0x2f | ||
| 75 | #define QT1050_DI_AKS_1 0x30 | ||
| 76 | #define QT1050_DI_AKS_2 0x32 | ||
| 77 | #define QT1050_DI_AKS_3 0x33 | ||
| 78 | #define QT1050_DI_AKS_4 0x34 | ||
| 79 | |||
| 80 | /* Charge Share Delay */ | ||
| 81 | #define QT1050_CSD_0 0x36 | ||
| 82 | #define QT1050_CSD_1 0x37 | ||
| 83 | #define QT1050_CSD_2 0x39 | ||
| 84 | #define QT1050_CSD_3 0x3a | ||
| 85 | #define QT1050_CSD_4 0x3b | ||
| 86 | |||
| 87 | /* Low Power Mode */ | ||
| 88 | #define QT1050_LPMODE 0x3d | ||
| 89 | |||
| 90 | /* Calibration and Reset */ | ||
| 91 | #define QT1050_RES_CAL 0x3f | ||
| 92 | #define QT1050_RES_CAL_RESET BIT(7) | ||
| 93 | #define QT1050_RES_CAL_CALIBRATE BIT(1) | ||
| 94 | |||
| 95 | #define QT1050_MAX_KEYS 5 | ||
| 96 | #define QT1050_RESET_TIME 255 | ||
| 97 | |||
| 98 | struct qt1050_key_regs { | ||
| 99 | unsigned int nthr; | ||
| 100 | unsigned int pulse_scale; | ||
| 101 | unsigned int di_aks; | ||
| 102 | unsigned int csd; | ||
| 103 | }; | ||
| 104 | |||
| 105 | struct qt1050_key { | ||
| 106 | u32 num; | ||
| 107 | u32 charge_delay; | ||
| 108 | u32 thr_cnt; | ||
| 109 | u32 samples; | ||
| 110 | u32 scale; | ||
| 111 | u32 keycode; | ||
| 112 | }; | ||
| 113 | |||
| 114 | struct qt1050_priv { | ||
| 115 | struct i2c_client *client; | ||
| 116 | struct input_dev *input; | ||
| 117 | struct regmap *regmap; | ||
| 118 | struct qt1050_key keys[QT1050_MAX_KEYS]; | ||
| 119 | unsigned short keycodes[QT1050_MAX_KEYS]; | ||
| 120 | u8 reg_keys; | ||
| 121 | u8 last_keys; | ||
| 122 | }; | ||
| 123 | |||
| 124 | static const struct qt1050_key_regs qt1050_key_regs_data[] = { | ||
| 125 | { | ||
| 126 | .nthr = QT1050_NTHR_0, | ||
| 127 | .pulse_scale = QT1050_PULSE_SCALE_0, | ||
| 128 | .di_aks = QT1050_DI_AKS_0, | ||
| 129 | .csd = QT1050_CSD_0, | ||
| 130 | }, { | ||
| 131 | .nthr = QT1050_NTHR_1, | ||
| 132 | .pulse_scale = QT1050_PULSE_SCALE_1, | ||
| 133 | .di_aks = QT1050_DI_AKS_1, | ||
| 134 | .csd = QT1050_CSD_1, | ||
| 135 | }, { | ||
| 136 | .nthr = QT1050_NTHR_2, | ||
| 137 | .pulse_scale = QT1050_PULSE_SCALE_2, | ||
| 138 | .di_aks = QT1050_DI_AKS_2, | ||
| 139 | .csd = QT1050_CSD_2, | ||
| 140 | }, { | ||
| 141 | .nthr = QT1050_NTHR_3, | ||
| 142 | .pulse_scale = QT1050_PULSE_SCALE_3, | ||
| 143 | .di_aks = QT1050_DI_AKS_3, | ||
| 144 | .csd = QT1050_CSD_3, | ||
| 145 | }, { | ||
| 146 | .nthr = QT1050_NTHR_4, | ||
| 147 | .pulse_scale = QT1050_PULSE_SCALE_4, | ||
| 148 | .di_aks = QT1050_DI_AKS_4, | ||
| 149 | .csd = QT1050_CSD_4, | ||
| 150 | } | ||
| 151 | }; | ||
| 152 | |||
| 153 | static bool qt1050_volatile_reg(struct device *dev, unsigned int reg) | ||
| 154 | { | ||
| 155 | switch (reg) { | ||
| 156 | case QT1050_DET_STATUS: | ||
| 157 | case QT1050_KEY_STATUS: | ||
| 158 | case QT1050_KEY_SIGNAL_0_MSB: | ||
| 159 | case QT1050_KEY_SIGNAL_0_LSB: | ||
| 160 | case QT1050_KEY_SIGNAL_1_MSB: | ||
| 161 | case QT1050_KEY_SIGNAL_1_LSB: | ||
| 162 | case QT1050_KEY_SIGNAL_2_MSB: | ||
| 163 | case QT1050_KEY_SIGNAL_2_LSB: | ||
| 164 | case QT1050_KEY_SIGNAL_3_MSB: | ||
| 165 | case QT1050_KEY_SIGNAL_3_LSB: | ||
| 166 | case QT1050_KEY_SIGNAL_4_MSB: | ||
| 167 | case QT1050_KEY_SIGNAL_4_LSB: | ||
| 168 | return true; | ||
| 169 | default: | ||
| 170 | return false; | ||
| 171 | } | ||
| 172 | } | ||
| 173 | |||
| 174 | static const struct regmap_range qt1050_readable_ranges[] = { | ||
| 175 | regmap_reg_range(QT1050_CHIP_ID, QT1050_KEY_STATUS), | ||
| 176 | regmap_reg_range(QT1050_KEY_SIGNAL_0_MSB, QT1050_KEY_SIGNAL_1_LSB), | ||
| 177 | regmap_reg_range(QT1050_KEY_SIGNAL_2_MSB, QT1050_KEY_SIGNAL_4_LSB), | ||
| 178 | regmap_reg_range(QT1050_REF_DATA_0_MSB, QT1050_REF_DATA_1_LSB), | ||
| 179 | regmap_reg_range(QT1050_REF_DATA_2_MSB, QT1050_REF_DATA_4_LSB), | ||
| 180 | regmap_reg_range(QT1050_NTHR_0, QT1050_NTHR_1), | ||
| 181 | regmap_reg_range(QT1050_NTHR_2, QT1050_NTHR_4), | ||
| 182 | regmap_reg_range(QT1050_PULSE_SCALE_0, QT1050_PULSE_SCALE_1), | ||
| 183 | regmap_reg_range(QT1050_PULSE_SCALE_2, QT1050_PULSE_SCALE_4), | ||
| 184 | regmap_reg_range(QT1050_DI_AKS_0, QT1050_DI_AKS_1), | ||
| 185 | regmap_reg_range(QT1050_DI_AKS_2, QT1050_DI_AKS_4), | ||
| 186 | regmap_reg_range(QT1050_CSD_0, QT1050_CSD_1), | ||
| 187 | regmap_reg_range(QT1050_CSD_2, QT1050_RES_CAL), | ||
| 188 | }; | ||
| 189 | |||
| 190 | static const struct regmap_access_table qt1050_readable_table = { | ||
| 191 | .yes_ranges = qt1050_readable_ranges, | ||
| 192 | .n_yes_ranges = ARRAY_SIZE(qt1050_readable_ranges), | ||
| 193 | }; | ||
| 194 | |||
| 195 | static const struct regmap_range qt1050_writeable_ranges[] = { | ||
| 196 | regmap_reg_range(QT1050_NTHR_0, QT1050_NTHR_1), | ||
| 197 | regmap_reg_range(QT1050_NTHR_2, QT1050_NTHR_4), | ||
| 198 | regmap_reg_range(QT1050_PULSE_SCALE_0, QT1050_PULSE_SCALE_1), | ||
| 199 | regmap_reg_range(QT1050_PULSE_SCALE_2, QT1050_PULSE_SCALE_4), | ||
| 200 | regmap_reg_range(QT1050_DI_AKS_0, QT1050_DI_AKS_1), | ||
| 201 | regmap_reg_range(QT1050_DI_AKS_2, QT1050_DI_AKS_4), | ||
| 202 | regmap_reg_range(QT1050_CSD_0, QT1050_CSD_1), | ||
| 203 | regmap_reg_range(QT1050_CSD_2, QT1050_RES_CAL), | ||
| 204 | }; | ||
| 205 | |||
| 206 | static const struct regmap_access_table qt1050_writeable_table = { | ||
| 207 | .yes_ranges = qt1050_writeable_ranges, | ||
| 208 | .n_yes_ranges = ARRAY_SIZE(qt1050_writeable_ranges), | ||
| 209 | }; | ||
| 210 | |||
| 211 | static struct regmap_config qt1050_regmap_config = { | ||
| 212 | .reg_bits = 8, | ||
| 213 | .val_bits = 8, | ||
| 214 | .max_register = QT1050_RES_CAL, | ||
| 215 | |||
| 216 | .cache_type = REGCACHE_RBTREE, | ||
| 217 | |||
| 218 | .wr_table = &qt1050_writeable_table, | ||
| 219 | .rd_table = &qt1050_readable_table, | ||
| 220 | .volatile_reg = qt1050_volatile_reg, | ||
| 221 | }; | ||
| 222 | |||
| 223 | static bool qt1050_identify(struct qt1050_priv *ts) | ||
| 224 | { | ||
| 225 | unsigned int val; | ||
| 226 | int err; | ||
| 227 | |||
| 228 | /* Read Chip ID */ | ||
| 229 | regmap_read(ts->regmap, QT1050_CHIP_ID, &val); | ||
| 230 | if (val != QT1050_CHIP_ID_VER) { | ||
| 231 | dev_err(&ts->client->dev, "ID %d not supported\n", val); | ||
| 232 | return false; | ||
| 233 | } | ||
| 234 | |||
| 235 | /* Read firmware version */ | ||
| 236 | err = regmap_read(ts->regmap, QT1050_FW_VERSION, &val); | ||
| 237 | if (err) { | ||
| 238 | dev_err(&ts->client->dev, "could not read the firmware version\n"); | ||
| 239 | return false; | ||
| 240 | } | ||
| 241 | |||
| 242 | dev_info(&ts->client->dev, "AT42QT1050 firmware version %1d.%1d\n", | ||
| 243 | val >> 4, val & 0xf); | ||
| 244 | |||
| 245 | return true; | ||
| 246 | } | ||
| 247 | |||
| 248 | static irqreturn_t qt1050_irq_threaded(int irq, void *dev_id) | ||
| 249 | { | ||
| 250 | struct qt1050_priv *ts = dev_id; | ||
| 251 | struct input_dev *input = ts->input; | ||
| 252 | unsigned long new_keys, changed; | ||
| 253 | unsigned int val; | ||
| 254 | int i, err; | ||
| 255 | |||
| 256 | /* Read the detected status register, thus clearing interrupt */ | ||
| 257 | err = regmap_read(ts->regmap, QT1050_DET_STATUS, &val); | ||
| 258 | if (err) { | ||
| 259 | dev_err(&ts->client->dev, "Fail to read detection status: %d\n", | ||
| 260 | err); | ||
| 261 | return IRQ_NONE; | ||
| 262 | } | ||
| 263 | |||
| 264 | /* Read which key changed, keys are not continuous */ | ||
| 265 | err = regmap_read(ts->regmap, QT1050_KEY_STATUS, &val); | ||
| 266 | if (err) { | ||
| 267 | dev_err(&ts->client->dev, | ||
| 268 | "Fail to determine the key status: %d\n", err); | ||
| 269 | return IRQ_NONE; | ||
| 270 | } | ||
| 271 | new_keys = (val & 0x70) >> 2 | (val & 0x6) >> 1; | ||
| 272 | changed = ts->last_keys ^ new_keys; | ||
| 273 | /* Report registered keys only */ | ||
| 274 | changed &= ts->reg_keys; | ||
| 275 | |||
| 276 | for_each_set_bit(i, &changed, QT1050_MAX_KEYS) | ||
| 277 | input_report_key(input, ts->keys[i].keycode, | ||
| 278 | test_bit(i, &new_keys)); | ||
| 279 | |||
| 280 | ts->last_keys = new_keys; | ||
| 281 | input_sync(input); | ||
| 282 | |||
| 283 | return IRQ_HANDLED; | ||
| 284 | } | ||
| 285 | |||
| 286 | static const struct qt1050_key_regs *qt1050_get_key_regs(int key_num) | ||
| 287 | { | ||
| 288 | return &qt1050_key_regs_data[key_num]; | ||
| 289 | } | ||
| 290 | |||
| 291 | static int qt1050_set_key(struct regmap *map, int number, int on) | ||
| 292 | { | ||
| 293 | const struct qt1050_key_regs *key_regs; | ||
| 294 | |||
| 295 | key_regs = qt1050_get_key_regs(number); | ||
| 296 | |||
| 297 | return regmap_update_bits(map, key_regs->di_aks, 0xfc, | ||
| 298 | on ? BIT(4) : 0x00); | ||
| 299 | } | ||
| 300 | |||
| 301 | static int qt1050_apply_fw_data(struct qt1050_priv *ts) | ||
| 302 | { | ||
| 303 | struct regmap *map = ts->regmap; | ||
| 304 | struct qt1050_key *button = &ts->keys[0]; | ||
| 305 | const struct qt1050_key_regs *key_regs; | ||
| 306 | int i, err; | ||
| 307 | |||
| 308 | /* Disable all keys and enable only the specified ones */ | ||
| 309 | for (i = 0; i < QT1050_MAX_KEYS; i++) { | ||
| 310 | err = qt1050_set_key(map, i, 0); | ||
| 311 | if (err) | ||
| 312 | return err; | ||
| 313 | } | ||
| 314 | |||
| 315 | for (i = 0; i < QT1050_MAX_KEYS; i++, button++) { | ||
| 316 | /* Keep KEY_RESERVED keys off */ | ||
| 317 | if (button->keycode == KEY_RESERVED) | ||
| 318 | continue; | ||
| 319 | |||
| 320 | err = qt1050_set_key(map, button->num, 1); | ||
| 321 | if (err) | ||
| 322 | return err; | ||
| 323 | |||
| 324 | key_regs = qt1050_get_key_regs(button->num); | ||
| 325 | |||
| 326 | err = regmap_write(map, key_regs->pulse_scale, | ||
| 327 | (button->samples << 4) | (button->scale)); | ||
| 328 | if (err) | ||
| 329 | return err; | ||
| 330 | err = regmap_write(map, key_regs->csd, button->charge_delay); | ||
| 331 | if (err) | ||
| 332 | return err; | ||
| 333 | err = regmap_write(map, key_regs->nthr, button->thr_cnt); | ||
| 334 | if (err) | ||
| 335 | return err; | ||
| 336 | } | ||
| 337 | |||
| 338 | return 0; | ||
| 339 | } | ||
| 340 | |||
| 341 | static int qt1050_parse_fw(struct qt1050_priv *ts) | ||
| 342 | { | ||
| 343 | struct device *dev = &ts->client->dev; | ||
| 344 | struct fwnode_handle *child; | ||
| 345 | int nbuttons; | ||
| 346 | |||
| 347 | nbuttons = device_get_child_node_count(dev); | ||
| 348 | if (nbuttons == 0 || nbuttons > QT1050_MAX_KEYS) | ||
| 349 | return -ENODEV; | ||
| 350 | |||
| 351 | device_for_each_child_node(dev, child) { | ||
| 352 | struct qt1050_key button; | ||
| 353 | |||
| 354 | /* Required properties */ | ||
| 355 | if (fwnode_property_read_u32(child, "linux,code", | ||
| 356 | &button.keycode)) { | ||
| 357 | dev_err(dev, "Button without keycode\n"); | ||
| 358 | goto err; | ||
| 359 | } | ||
| 360 | if (button.keycode >= KEY_MAX) { | ||
| 361 | dev_err(dev, "Invalid keycode 0x%x\n", | ||
| 362 | button.keycode); | ||
| 363 | goto err; | ||
| 364 | } | ||
| 365 | |||
| 366 | if (fwnode_property_read_u32(child, "reg", | ||
| 367 | &button.num)) { | ||
| 368 | dev_err(dev, "Button without pad number\n"); | ||
| 369 | goto err; | ||
| 370 | } | ||
| 371 | if (button.num < 0 || button.num > QT1050_MAX_KEYS - 1) | ||
| 372 | goto err; | ||
| 373 | |||
| 374 | ts->reg_keys |= BIT(button.num); | ||
| 375 | |||
| 376 | /* Optional properties */ | ||
| 377 | if (fwnode_property_read_u32(child, | ||
| 378 | "microchip,pre-charge-time-ns", | ||
| 379 | &button.charge_delay)) { | ||
| 380 | button.charge_delay = 0; | ||
| 381 | } else { | ||
| 382 | if (button.charge_delay % 2500 == 0) | ||
| 383 | button.charge_delay = | ||
| 384 | button.charge_delay / 2500; | ||
| 385 | else | ||
| 386 | button.charge_delay = 0; | ||
| 387 | } | ||
| 388 | |||
| 389 | if (fwnode_property_read_u32(child, "microchip,average-samples", | ||
| 390 | &button.samples)) { | ||
| 391 | button.samples = 0; | ||
| 392 | } else { | ||
| 393 | if (is_power_of_2(button.samples)) | ||
| 394 | button.samples = ilog2(button.samples); | ||
| 395 | else | ||
| 396 | button.samples = 0; | ||
| 397 | } | ||
| 398 | |||
| 399 | if (fwnode_property_read_u32(child, "microchip,average-scaling", | ||
| 400 | &button.scale)) { | ||
| 401 | button.scale = 0; | ||
| 402 | } else { | ||
| 403 | if (is_power_of_2(button.scale)) | ||
| 404 | button.scale = ilog2(button.scale); | ||
| 405 | else | ||
| 406 | button.scale = 0; | ||
| 407 | |||
| 408 | } | ||
| 409 | |||
| 410 | if (fwnode_property_read_u32(child, "microchip,threshold", | ||
| 411 | &button.thr_cnt)) { | ||
| 412 | button.thr_cnt = 20; | ||
| 413 | } else { | ||
| 414 | if (button.thr_cnt > 255) | ||
| 415 | button.thr_cnt = 20; | ||
| 416 | } | ||
| 417 | |||
| 418 | ts->keys[button.num] = button; | ||
| 419 | } | ||
| 420 | |||
| 421 | return 0; | ||
| 422 | |||
| 423 | err: | ||
| 424 | fwnode_handle_put(child); | ||
| 425 | return -EINVAL; | ||
| 426 | } | ||
| 427 | |||
| 428 | static int qt1050_probe(struct i2c_client *client) | ||
| 429 | { | ||
| 430 | struct qt1050_priv *ts; | ||
| 431 | struct input_dev *input; | ||
| 432 | struct device *dev = &client->dev; | ||
| 433 | struct regmap *map; | ||
| 434 | unsigned int status, i; | ||
| 435 | int err; | ||
| 436 | |||
| 437 | /* Check basic functionality */ | ||
| 438 | err = i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE); | ||
| 439 | if (!err) { | ||
| 440 | dev_err(&client->dev, "%s adapter not supported\n", | ||
| 441 | dev_driver_string(&client->adapter->dev)); | ||
| 442 | return -ENODEV; | ||
| 443 | } | ||
| 444 | |||
| 445 | if (!client->irq) { | ||
| 446 | dev_err(dev, "assign a irq line to this device\n"); | ||
| 447 | return -EINVAL; | ||
| 448 | } | ||
| 449 | |||
| 450 | ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL); | ||
| 451 | if (!ts) | ||
| 452 | return -ENOMEM; | ||
| 453 | |||
| 454 | input = devm_input_allocate_device(dev); | ||
| 455 | if (!input) | ||
| 456 | return -ENOMEM; | ||
| 457 | |||
| 458 | map = devm_regmap_init_i2c(client, &qt1050_regmap_config); | ||
| 459 | if (IS_ERR(map)) | ||
| 460 | return PTR_ERR(map); | ||
| 461 | |||
| 462 | ts->client = client; | ||
| 463 | ts->input = input; | ||
| 464 | ts->regmap = map; | ||
| 465 | |||
| 466 | i2c_set_clientdata(client, ts); | ||
| 467 | |||
| 468 | /* Identify the qt1050 chip */ | ||
| 469 | if (!qt1050_identify(ts)) | ||
| 470 | return -ENODEV; | ||
| 471 | |||
| 472 | /* Get pdata */ | ||
| 473 | err = qt1050_parse_fw(ts); | ||
| 474 | if (err) { | ||
| 475 | dev_err(dev, "Failed to parse firmware: %d\n", err); | ||
| 476 | return err; | ||
| 477 | } | ||
| 478 | |||
| 479 | input->name = "AT42QT1050 QTouch Sensor"; | ||
| 480 | input->dev.parent = &client->dev; | ||
| 481 | input->id.bustype = BUS_I2C; | ||
| 482 | |||
| 483 | /* Add the keycode */ | ||
| 484 | input->keycode = ts->keycodes; | ||
| 485 | input->keycodesize = sizeof(ts->keycodes[0]); | ||
| 486 | input->keycodemax = QT1050_MAX_KEYS; | ||
| 487 | |||
| 488 | __set_bit(EV_KEY, input->evbit); | ||
| 489 | for (i = 0; i < QT1050_MAX_KEYS; i++) { | ||
| 490 | ts->keycodes[i] = ts->keys[i].keycode; | ||
| 491 | __set_bit(ts->keycodes[i], input->keybit); | ||
| 492 | } | ||
| 493 | |||
| 494 | /* Trigger re-calibration */ | ||
| 495 | err = regmap_update_bits(ts->regmap, QT1050_RES_CAL, 0x7f, | ||
| 496 | QT1050_RES_CAL_CALIBRATE); | ||
| 497 | if (err) { | ||
| 498 | dev_err(dev, "Trigger calibration failed: %d\n", err); | ||
| 499 | return err; | ||
| 500 | } | ||
| 501 | err = regmap_read_poll_timeout(ts->regmap, QT1050_DET_STATUS, status, | ||
| 502 | status >> 7 == 1, 10000, 200000); | ||
| 503 | if (err) { | ||
| 504 | dev_err(dev, "Calibration failed: %d\n", err); | ||
| 505 | return err; | ||
| 506 | } | ||
| 507 | |||
| 508 | /* Soft reset to set defaults */ | ||
| 509 | err = regmap_update_bits(ts->regmap, QT1050_RES_CAL, | ||
| 510 | QT1050_RES_CAL_RESET, QT1050_RES_CAL_RESET); | ||
| 511 | if (err) { | ||
| 512 | dev_err(dev, "Trigger soft reset failed: %d\n", err); | ||
| 513 | return err; | ||
| 514 | } | ||
| 515 | msleep(QT1050_RESET_TIME); | ||
| 516 | |||
| 517 | /* Set pdata */ | ||
| 518 | err = qt1050_apply_fw_data(ts); | ||
| 519 | if (err) { | ||
| 520 | dev_err(dev, "Failed to set firmware data: %d\n", err); | ||
| 521 | return err; | ||
| 522 | } | ||
| 523 | |||
| 524 | err = devm_request_threaded_irq(dev, client->irq, NULL, | ||
| 525 | qt1050_irq_threaded, IRQF_ONESHOT, | ||
| 526 | "qt1050", ts); | ||
| 527 | if (err) { | ||
| 528 | dev_err(&client->dev, "Failed to request irq: %d\n", err); | ||
| 529 | return err; | ||
| 530 | } | ||
| 531 | |||
| 532 | /* Clear #CHANGE line */ | ||
| 533 | err = regmap_read(ts->regmap, QT1050_DET_STATUS, &status); | ||
| 534 | if (err) { | ||
| 535 | dev_err(dev, "Failed to clear #CHANGE line level: %d\n", err); | ||
| 536 | return err; | ||
| 537 | } | ||
| 538 | |||
| 539 | /* Register the input device */ | ||
| 540 | err = input_register_device(ts->input); | ||
| 541 | if (err) { | ||
| 542 | dev_err(&client->dev, "Failed to register input device: %d\n", | ||
| 543 | err); | ||
| 544 | return err; | ||
| 545 | } | ||
| 546 | |||
| 547 | return 0; | ||
| 548 | } | ||
| 549 | |||
| 550 | static int __maybe_unused qt1050_suspend(struct device *dev) | ||
| 551 | { | ||
| 552 | struct i2c_client *client = to_i2c_client(dev); | ||
| 553 | struct qt1050_priv *ts = i2c_get_clientdata(client); | ||
| 554 | |||
| 555 | disable_irq(client->irq); | ||
| 556 | |||
| 557 | /* | ||
| 558 | * Set measurement interval to 1s (125 x 8ms) if wakeup is allowed | ||
| 559 | * else turn off. The 1s interval seems to be a good compromise between | ||
| 560 | * low power and response time. | ||
| 561 | */ | ||
| 562 | return regmap_write(ts->regmap, QT1050_LPMODE, | ||
| 563 | device_may_wakeup(dev) ? 125 : 0); | ||
| 564 | } | ||
| 565 | |||
| 566 | static int __maybe_unused qt1050_resume(struct device *dev) | ||
| 567 | { | ||
| 568 | struct i2c_client *client = to_i2c_client(dev); | ||
| 569 | struct qt1050_priv *ts = i2c_get_clientdata(client); | ||
| 570 | |||
| 571 | enable_irq(client->irq); | ||
| 572 | |||
| 573 | /* Set measurement interval back to 16ms (2 x 8ms) */ | ||
| 574 | return regmap_write(ts->regmap, QT1050_LPMODE, 2); | ||
| 575 | } | ||
| 576 | |||
| 577 | static SIMPLE_DEV_PM_OPS(qt1050_pm_ops, qt1050_suspend, qt1050_resume); | ||
| 578 | |||
| 579 | static const struct of_device_id __maybe_unused qt1050_of_match[] = { | ||
| 580 | { .compatible = "microchip,qt1050", }, | ||
| 581 | { }, | ||
| 582 | }; | ||
| 583 | MODULE_DEVICE_TABLE(of, qt1050_of_match); | ||
| 584 | |||
| 585 | static struct i2c_driver qt1050_driver = { | ||
| 586 | .driver = { | ||
| 587 | .name = "qt1050", | ||
| 588 | .of_match_table = of_match_ptr(qt1050_of_match), | ||
| 589 | .pm = &qt1050_pm_ops, | ||
| 590 | }, | ||
| 591 | .probe_new = qt1050_probe, | ||
| 592 | }; | ||
| 593 | |||
| 594 | module_i2c_driver(qt1050_driver); | ||
| 595 | |||
| 596 | MODULE_AUTHOR("Marco Felsch <kernel@pengutronix.de"); | ||
| 597 | MODULE_DESCRIPTION("Driver for AT42QT1050 QTouch sensor"); | ||
| 598 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/input/keyboard/snvs_pwrkey.c b/drivers/input/keyboard/snvs_pwrkey.c index 4c67cf30a5d9..5342d8d45f81 100644 --- a/drivers/input/keyboard/snvs_pwrkey.c +++ b/drivers/input/keyboard/snvs_pwrkey.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/of.h> | 15 | #include <linux/of.h> |
| 16 | #include <linux/of_address.h> | 16 | #include <linux/of_address.h> |
| 17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
| 18 | #include <linux/pm_wakeirq.h> | ||
| 18 | #include <linux/mfd/syscon.h> | 19 | #include <linux/mfd/syscon.h> |
| 19 | #include <linux/regmap.h> | 20 | #include <linux/regmap.h> |
| 20 | 21 | ||
| @@ -167,28 +168,9 @@ static int imx_snvs_pwrkey_probe(struct platform_device *pdev) | |||
| 167 | } | 168 | } |
| 168 | 169 | ||
| 169 | device_init_wakeup(&pdev->dev, pdata->wakeup); | 170 | device_init_wakeup(&pdev->dev, pdata->wakeup); |
| 170 | 171 | error = dev_pm_set_wake_irq(&pdev->dev, pdata->irq); | |
| 171 | return 0; | 172 | if (error) |
| 172 | } | 173 | dev_err(&pdev->dev, "irq wake enable failed.\n"); |
| 173 | |||
| 174 | static int __maybe_unused imx_snvs_pwrkey_suspend(struct device *dev) | ||
| 175 | { | ||
| 176 | struct platform_device *pdev = to_platform_device(dev); | ||
| 177 | struct pwrkey_drv_data *pdata = platform_get_drvdata(pdev); | ||
| 178 | |||
| 179 | if (device_may_wakeup(&pdev->dev)) | ||
| 180 | enable_irq_wake(pdata->irq); | ||
| 181 | |||
| 182 | return 0; | ||
| 183 | } | ||
| 184 | |||
| 185 | static int __maybe_unused imx_snvs_pwrkey_resume(struct device *dev) | ||
| 186 | { | ||
| 187 | struct platform_device *pdev = to_platform_device(dev); | ||
| 188 | struct pwrkey_drv_data *pdata = platform_get_drvdata(pdev); | ||
| 189 | |||
| 190 | if (device_may_wakeup(&pdev->dev)) | ||
| 191 | disable_irq_wake(pdata->irq); | ||
| 192 | 174 | ||
| 193 | return 0; | 175 | return 0; |
| 194 | } | 176 | } |
| @@ -199,13 +181,9 @@ static const struct of_device_id imx_snvs_pwrkey_ids[] = { | |||
| 199 | }; | 181 | }; |
| 200 | MODULE_DEVICE_TABLE(of, imx_snvs_pwrkey_ids); | 182 | MODULE_DEVICE_TABLE(of, imx_snvs_pwrkey_ids); |
| 201 | 183 | ||
| 202 | static SIMPLE_DEV_PM_OPS(imx_snvs_pwrkey_pm_ops, imx_snvs_pwrkey_suspend, | ||
| 203 | imx_snvs_pwrkey_resume); | ||
| 204 | |||
| 205 | static struct platform_driver imx_snvs_pwrkey_driver = { | 184 | static struct platform_driver imx_snvs_pwrkey_driver = { |
| 206 | .driver = { | 185 | .driver = { |
| 207 | .name = "snvs_pwrkey", | 186 | .name = "snvs_pwrkey", |
| 208 | .pm = &imx_snvs_pwrkey_pm_ops, | ||
| 209 | .of_match_table = imx_snvs_pwrkey_ids, | 187 | .of_match_table = imx_snvs_pwrkey_ids, |
| 210 | }, | 188 | }, |
| 211 | .probe = imx_snvs_pwrkey_probe, | 189 | .probe = imx_snvs_pwrkey_probe, |
diff --git a/drivers/input/keyboard/sun4i-lradc-keys.c b/drivers/input/keyboard/sun4i-lradc-keys.c index 57272df34cd5..df3eec72a9b2 100644 --- a/drivers/input/keyboard/sun4i-lradc-keys.c +++ b/drivers/input/keyboard/sun4i-lradc-keys.c | |||
| @@ -46,6 +46,7 @@ | |||
| 46 | #define CONTINUE_TIME_SEL(x) ((x) << 16) /* 4 bits */ | 46 | #define CONTINUE_TIME_SEL(x) ((x) << 16) /* 4 bits */ |
| 47 | #define KEY_MODE_SEL(x) ((x) << 12) /* 2 bits */ | 47 | #define KEY_MODE_SEL(x) ((x) << 12) /* 2 bits */ |
| 48 | #define LEVELA_B_CNT(x) ((x) << 8) /* 4 bits */ | 48 | #define LEVELA_B_CNT(x) ((x) << 8) /* 4 bits */ |
| 49 | #define HOLD_KEY_EN(x) ((x) << 7) | ||
| 49 | #define HOLD_EN(x) ((x) << 6) | 50 | #define HOLD_EN(x) ((x) << 6) |
| 50 | #define LEVELB_VOL(x) ((x) << 4) /* 2 bits */ | 51 | #define LEVELB_VOL(x) ((x) << 4) /* 2 bits */ |
| 51 | #define SAMPLE_RATE(x) ((x) << 2) /* 2 bits */ | 52 | #define SAMPLE_RATE(x) ((x) << 2) /* 2 bits */ |
| @@ -63,6 +64,25 @@ | |||
| 63 | #define CHAN0_KEYDOWN_IRQ BIT(1) | 64 | #define CHAN0_KEYDOWN_IRQ BIT(1) |
| 64 | #define CHAN0_DATA_IRQ BIT(0) | 65 | #define CHAN0_DATA_IRQ BIT(0) |
| 65 | 66 | ||
| 67 | /* struct lradc_variant - Describe sun4i-a10-lradc-keys hardware variant | ||
| 68 | * @divisor_numerator: The numerator of lradc Vref internally divisor | ||
| 69 | * @divisor_denominator: The denominator of lradc Vref internally divisor | ||
| 70 | */ | ||
| 71 | struct lradc_variant { | ||
| 72 | u8 divisor_numerator; | ||
| 73 | u8 divisor_denominator; | ||
| 74 | }; | ||
| 75 | |||
| 76 | static const struct lradc_variant lradc_variant_a10 = { | ||
| 77 | .divisor_numerator = 2, | ||
| 78 | .divisor_denominator = 3 | ||
| 79 | }; | ||
| 80 | |||
| 81 | static const struct lradc_variant r_lradc_variant_a83t = { | ||
| 82 | .divisor_numerator = 3, | ||
| 83 | .divisor_denominator = 4 | ||
| 84 | }; | ||
| 85 | |||
| 66 | struct sun4i_lradc_keymap { | 86 | struct sun4i_lradc_keymap { |
| 67 | u32 voltage; | 87 | u32 voltage; |
| 68 | u32 keycode; | 88 | u32 keycode; |
| @@ -74,6 +94,7 @@ struct sun4i_lradc_data { | |||
| 74 | void __iomem *base; | 94 | void __iomem *base; |
| 75 | struct regulator *vref_supply; | 95 | struct regulator *vref_supply; |
| 76 | struct sun4i_lradc_keymap *chan0_map; | 96 | struct sun4i_lradc_keymap *chan0_map; |
| 97 | const struct lradc_variant *variant; | ||
| 77 | u32 chan0_map_count; | 98 | u32 chan0_map_count; |
| 78 | u32 chan0_keycode; | 99 | u32 chan0_keycode; |
| 79 | u32 vref; | 100 | u32 vref; |
| @@ -128,9 +149,9 @@ static int sun4i_lradc_open(struct input_dev *dev) | |||
| 128 | if (error) | 149 | if (error) |
| 129 | return error; | 150 | return error; |
| 130 | 151 | ||
| 131 | /* lradc Vref internally is divided by 2/3 */ | 152 | lradc->vref = regulator_get_voltage(lradc->vref_supply) * |
| 132 | lradc->vref = regulator_get_voltage(lradc->vref_supply) * 2 / 3; | 153 | lradc->variant->divisor_numerator / |
| 133 | 154 | lradc->variant->divisor_denominator; | |
| 134 | /* | 155 | /* |
| 135 | * Set sample time to 4 ms / 250 Hz. Wait 2 * 4 ms for key to | 156 | * Set sample time to 4 ms / 250 Hz. Wait 2 * 4 ms for key to |
| 136 | * stabilize on press, wait (1 + 1) * 4 ms for key release | 157 | * stabilize on press, wait (1 + 1) * 4 ms for key release |
| @@ -222,6 +243,12 @@ static int sun4i_lradc_probe(struct platform_device *pdev) | |||
| 222 | if (error) | 243 | if (error) |
| 223 | return error; | 244 | return error; |
| 224 | 245 | ||
| 246 | lradc->variant = of_device_get_match_data(&pdev->dev); | ||
| 247 | if (!lradc->variant) { | ||
| 248 | dev_err(&pdev->dev, "Missing sun4i-a10-lradc-keys variant\n"); | ||
| 249 | return -EINVAL; | ||
| 250 | } | ||
| 251 | |||
| 225 | lradc->vref_supply = devm_regulator_get(dev, "vref"); | 252 | lradc->vref_supply = devm_regulator_get(dev, "vref"); |
| 226 | if (IS_ERR(lradc->vref_supply)) | 253 | if (IS_ERR(lradc->vref_supply)) |
| 227 | return PTR_ERR(lradc->vref_supply); | 254 | return PTR_ERR(lradc->vref_supply); |
| @@ -265,7 +292,10 @@ static int sun4i_lradc_probe(struct platform_device *pdev) | |||
| 265 | } | 292 | } |
| 266 | 293 | ||
| 267 | static const struct of_device_id sun4i_lradc_of_match[] = { | 294 | static const struct of_device_id sun4i_lradc_of_match[] = { |
| 268 | { .compatible = "allwinner,sun4i-a10-lradc-keys", }, | 295 | { .compatible = "allwinner,sun4i-a10-lradc-keys", |
| 296 | .data = &lradc_variant_a10 }, | ||
| 297 | { .compatible = "allwinner,sun8i-a83t-r-lradc", | ||
| 298 | .data = &r_lradc_variant_a83t }, | ||
| 269 | { /* sentinel */ } | 299 | { /* sentinel */ } |
| 270 | }; | 300 | }; |
| 271 | MODULE_DEVICE_TABLE(of, sun4i_lradc_of_match); | 301 | MODULE_DEVICE_TABLE(of, sun4i_lradc_of_match); |
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index e39aef84f357..16f41eece6d2 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig | |||
| @@ -290,6 +290,18 @@ config INPUT_GPIO_DECODER | |||
| 290 | To compile this driver as a module, choose M here: the module | 290 | To compile this driver as a module, choose M here: the module |
| 291 | will be called gpio_decoder. | 291 | will be called gpio_decoder. |
| 292 | 292 | ||
| 293 | config INPUT_GPIO_VIBRA | ||
| 294 | tristate "GPIO vibrator support" | ||
| 295 | depends on GPIOLIB || COMPILE_TEST | ||
| 296 | select INPUT_FF_MEMLESS | ||
| 297 | help | ||
| 298 | Say Y here to get support for GPIO based vibrator devices. | ||
| 299 | |||
| 300 | If unsure, say N. | ||
| 301 | |||
| 302 | To compile this driver as a module, choose M here: the module will be | ||
| 303 | called gpio-vibra. | ||
| 304 | |||
| 293 | config INPUT_IXP4XX_BEEPER | 305 | config INPUT_IXP4XX_BEEPER |
| 294 | tristate "IXP4XX Beeper support" | 306 | tristate "IXP4XX Beeper support" |
| 295 | depends on ARCH_IXP4XX | 307 | depends on ARCH_IXP4XX |
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 96a6419cb1f2..d871991c2eee 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile | |||
| @@ -36,6 +36,7 @@ obj-$(CONFIG_INPUT_DRV2667_HAPTICS) += drv2667.o | |||
| 36 | obj-$(CONFIG_INPUT_GP2A) += gp2ap002a00f.o | 36 | obj-$(CONFIG_INPUT_GP2A) += gp2ap002a00f.o |
| 37 | obj-$(CONFIG_INPUT_GPIO_BEEPER) += gpio-beeper.o | 37 | obj-$(CONFIG_INPUT_GPIO_BEEPER) += gpio-beeper.o |
| 38 | obj-$(CONFIG_INPUT_GPIO_DECODER) += gpio_decoder.o | 38 | obj-$(CONFIG_INPUT_GPIO_DECODER) += gpio_decoder.o |
| 39 | obj-$(CONFIG_INPUT_GPIO_VIBRA) += gpio-vibra.o | ||
| 39 | obj-$(CONFIG_INPUT_HISI_POWERKEY) += hisi_powerkey.o | 40 | obj-$(CONFIG_INPUT_HISI_POWERKEY) += hisi_powerkey.o |
| 40 | obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o | 41 | obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o |
| 41 | obj-$(CONFIG_INPUT_IMS_PCU) += ims-pcu.o | 42 | obj-$(CONFIG_INPUT_IMS_PCU) += ims-pcu.o |
diff --git a/drivers/input/misc/gpio-vibra.c b/drivers/input/misc/gpio-vibra.c new file mode 100644 index 000000000000..f79f75595dd7 --- /dev/null +++ b/drivers/input/misc/gpio-vibra.c | |||
| @@ -0,0 +1,207 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 2 | /* | ||
| 3 | * GPIO vibrator driver | ||
| 4 | * | ||
| 5 | * Copyright (C) 2019 Luca Weiss <luca@z3ntu.xyz> | ||
| 6 | * | ||
| 7 | * Based on PWM vibrator driver: | ||
| 8 | * Copyright (C) 2017 Collabora Ltd. | ||
| 9 | * | ||
| 10 | * Based on previous work from: | ||
| 11 | * Copyright (C) 2012 Dmitry Torokhov <dmitry.torokhov@gmail.com> | ||
| 12 | * | ||
| 13 | * Based on PWM beeper driver: | ||
| 14 | * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de> | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/gpio/consumer.h> | ||
| 18 | #include <linux/input.h> | ||
| 19 | #include <linux/kernel.h> | ||
| 20 | #include <linux/module.h> | ||
| 21 | #include <linux/of_device.h> | ||
| 22 | #include <linux/platform_device.h> | ||
| 23 | #include <linux/property.h> | ||
| 24 | #include <linux/regulator/consumer.h> | ||
| 25 | #include <linux/slab.h> | ||
| 26 | |||
| 27 | struct gpio_vibrator { | ||
| 28 | struct input_dev *input; | ||
| 29 | struct gpio_desc *gpio; | ||
| 30 | struct regulator *vcc; | ||
| 31 | |||
| 32 | struct work_struct play_work; | ||
| 33 | bool running; | ||
| 34 | bool vcc_on; | ||
| 35 | }; | ||
| 36 | |||
| 37 | static int gpio_vibrator_start(struct gpio_vibrator *vibrator) | ||
| 38 | { | ||
| 39 | struct device *pdev = vibrator->input->dev.parent; | ||
| 40 | int err; | ||
| 41 | |||
| 42 | if (!vibrator->vcc_on) { | ||
| 43 | err = regulator_enable(vibrator->vcc); | ||
| 44 | if (err) { | ||
| 45 | dev_err(pdev, "failed to enable regulator: %d\n", err); | ||
| 46 | return err; | ||
| 47 | } | ||
| 48 | vibrator->vcc_on = true; | ||
| 49 | } | ||
| 50 | |||
| 51 | gpiod_set_value_cansleep(vibrator->gpio, 1); | ||
| 52 | |||
| 53 | return 0; | ||
| 54 | } | ||
| 55 | |||
| 56 | static void gpio_vibrator_stop(struct gpio_vibrator *vibrator) | ||
| 57 | { | ||
| 58 | gpiod_set_value_cansleep(vibrator->gpio, 0); | ||
| 59 | |||
| 60 | if (vibrator->vcc_on) { | ||
| 61 | regulator_disable(vibrator->vcc); | ||
| 62 | vibrator->vcc_on = false; | ||
| 63 | } | ||
| 64 | } | ||
| 65 | |||
| 66 | static void gpio_vibrator_play_work(struct work_struct *work) | ||
| 67 | { | ||
| 68 | struct gpio_vibrator *vibrator = | ||
| 69 | container_of(work, struct gpio_vibrator, play_work); | ||
| 70 | |||
| 71 | if (vibrator->running) | ||
| 72 | gpio_vibrator_start(vibrator); | ||
| 73 | else | ||
| 74 | gpio_vibrator_stop(vibrator); | ||
| 75 | } | ||
| 76 | |||
| 77 | static int gpio_vibrator_play_effect(struct input_dev *dev, void *data, | ||
| 78 | struct ff_effect *effect) | ||
| 79 | { | ||
| 80 | struct gpio_vibrator *vibrator = input_get_drvdata(dev); | ||
| 81 | int level; | ||
| 82 | |||
| 83 | level = effect->u.rumble.strong_magnitude; | ||
| 84 | if (!level) | ||
| 85 | level = effect->u.rumble.weak_magnitude; | ||
| 86 | |||
| 87 | vibrator->running = level; | ||
| 88 | schedule_work(&vibrator->play_work); | ||
| 89 | |||
| 90 | return 0; | ||
| 91 | } | ||
| 92 | |||
| 93 | static void gpio_vibrator_close(struct input_dev *input) | ||
| 94 | { | ||
| 95 | struct gpio_vibrator *vibrator = input_get_drvdata(input); | ||
| 96 | |||
| 97 | cancel_work_sync(&vibrator->play_work); | ||
| 98 | gpio_vibrator_stop(vibrator); | ||
| 99 | vibrator->running = false; | ||
| 100 | } | ||
| 101 | |||
| 102 | static int gpio_vibrator_probe(struct platform_device *pdev) | ||
| 103 | { | ||
| 104 | struct gpio_vibrator *vibrator; | ||
| 105 | int err; | ||
| 106 | |||
| 107 | vibrator = devm_kzalloc(&pdev->dev, sizeof(*vibrator), GFP_KERNEL); | ||
| 108 | if (!vibrator) | ||
| 109 | return -ENOMEM; | ||
| 110 | |||
| 111 | vibrator->input = devm_input_allocate_device(&pdev->dev); | ||
| 112 | if (!vibrator->input) | ||
| 113 | return -ENOMEM; | ||
| 114 | |||
| 115 | vibrator->vcc = devm_regulator_get(&pdev->dev, "vcc"); | ||
| 116 | err = PTR_ERR_OR_ZERO(vibrator->vcc); | ||
| 117 | if (err) { | ||
| 118 | if (err != -EPROBE_DEFER) | ||
| 119 | dev_err(&pdev->dev, "Failed to request regulator: %d\n", | ||
| 120 | err); | ||
| 121 | return err; | ||
| 122 | } | ||
| 123 | |||
| 124 | vibrator->gpio = devm_gpiod_get(&pdev->dev, "enable", GPIOD_OUT_LOW); | ||
| 125 | err = PTR_ERR_OR_ZERO(vibrator->gpio); | ||
| 126 | if (err) { | ||
| 127 | if (err != -EPROBE_DEFER) | ||
| 128 | dev_err(&pdev->dev, "Failed to request main gpio: %d\n", | ||
| 129 | err); | ||
| 130 | return err; | ||
| 131 | } | ||
| 132 | |||
| 133 | INIT_WORK(&vibrator->play_work, gpio_vibrator_play_work); | ||
| 134 | |||
| 135 | vibrator->input->name = "gpio-vibrator"; | ||
| 136 | vibrator->input->id.bustype = BUS_HOST; | ||
| 137 | vibrator->input->close = gpio_vibrator_close; | ||
| 138 | |||
| 139 | input_set_drvdata(vibrator->input, vibrator); | ||
| 140 | input_set_capability(vibrator->input, EV_FF, FF_RUMBLE); | ||
| 141 | |||
| 142 | err = input_ff_create_memless(vibrator->input, NULL, | ||
| 143 | gpio_vibrator_play_effect); | ||
| 144 | if (err) { | ||
| 145 | dev_err(&pdev->dev, "Couldn't create FF dev: %d\n", err); | ||
| 146 | return err; | ||
| 147 | } | ||
| 148 | |||
| 149 | err = input_register_device(vibrator->input); | ||
| 150 | if (err) { | ||
| 151 | dev_err(&pdev->dev, "Couldn't register input dev: %d\n", err); | ||
| 152 | return err; | ||
| 153 | } | ||
| 154 | |||
| 155 | platform_set_drvdata(pdev, vibrator); | ||
| 156 | |||
| 157 | return 0; | ||
| 158 | } | ||
| 159 | |||
| 160 | static int __maybe_unused gpio_vibrator_suspend(struct device *dev) | ||
| 161 | { | ||
| 162 | struct platform_device *pdev = to_platform_device(dev); | ||
| 163 | struct gpio_vibrator *vibrator = platform_get_drvdata(pdev); | ||
| 164 | |||
| 165 | cancel_work_sync(&vibrator->play_work); | ||
| 166 | if (vibrator->running) | ||
| 167 | gpio_vibrator_stop(vibrator); | ||
| 168 | |||
| 169 | return 0; | ||
| 170 | } | ||
| 171 | |||
| 172 | static int __maybe_unused gpio_vibrator_resume(struct device *dev) | ||
| 173 | { | ||
| 174 | struct platform_device *pdev = to_platform_device(dev); | ||
| 175 | struct gpio_vibrator *vibrator = platform_get_drvdata(pdev); | ||
| 176 | |||
| 177 | if (vibrator->running) | ||
| 178 | gpio_vibrator_start(vibrator); | ||
| 179 | |||
| 180 | return 0; | ||
| 181 | } | ||
| 182 | |||
| 183 | static SIMPLE_DEV_PM_OPS(gpio_vibrator_pm_ops, | ||
| 184 | gpio_vibrator_suspend, gpio_vibrator_resume); | ||
| 185 | |||
| 186 | #ifdef CONFIG_OF | ||
| 187 | static const struct of_device_id gpio_vibra_dt_match_table[] = { | ||
| 188 | { .compatible = "gpio-vibrator" }, | ||
| 189 | {} | ||
| 190 | }; | ||
| 191 | MODULE_DEVICE_TABLE(of, gpio_vibra_dt_match_table); | ||
| 192 | #endif | ||
| 193 | |||
| 194 | static struct platform_driver gpio_vibrator_driver = { | ||
| 195 | .probe = gpio_vibrator_probe, | ||
| 196 | .driver = { | ||
| 197 | .name = "gpio-vibrator", | ||
| 198 | .pm = &gpio_vibrator_pm_ops, | ||
| 199 | .of_match_table = of_match_ptr(gpio_vibra_dt_match_table), | ||
| 200 | }, | ||
| 201 | }; | ||
| 202 | module_platform_driver(gpio_vibrator_driver); | ||
| 203 | |||
| 204 | MODULE_AUTHOR("Luca Weiss <luca@z3ntu.xy>"); | ||
| 205 | MODULE_DESCRIPTION("GPIO vibrator driver"); | ||
| 206 | MODULE_LICENSE("GPL"); | ||
| 207 | MODULE_ALIAS("platform:gpio-vibrator"); | ||
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index d3ff1fc09af7..94f7ca5ad077 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
| @@ -373,6 +373,8 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, | |||
| 373 | if (ps2_handle_response(&psmouse->ps2dev, data)) | 373 | if (ps2_handle_response(&psmouse->ps2dev, data)) |
| 374 | goto out; | 374 | goto out; |
| 375 | 375 | ||
| 376 | pm_wakeup_event(&serio->dev, 0); | ||
| 377 | |||
| 376 | if (psmouse->state <= PSMOUSE_RESYNCING) | 378 | if (psmouse->state <= PSMOUSE_RESYNCING) |
| 377 | goto out; | 379 | goto out; |
| 378 | 380 | ||
diff --git a/drivers/input/rmi4/rmi_f54.c b/drivers/input/rmi4/rmi_f54.c index a6f515bcab22..516fea06ed59 100644 --- a/drivers/input/rmi4/rmi_f54.c +++ b/drivers/input/rmi4/rmi_f54.c | |||
| @@ -456,25 +456,15 @@ static int rmi_f54_vidioc_fmt(struct file *file, void *priv, | |||
| 456 | static int rmi_f54_vidioc_enum_fmt(struct file *file, void *priv, | 456 | static int rmi_f54_vidioc_enum_fmt(struct file *file, void *priv, |
| 457 | struct v4l2_fmtdesc *fmt) | 457 | struct v4l2_fmtdesc *fmt) |
| 458 | { | 458 | { |
| 459 | struct f54_data *f54 = video_drvdata(file); | ||
| 460 | |||
| 459 | if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 461 | if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
| 460 | return -EINVAL; | 462 | return -EINVAL; |
| 461 | 463 | ||
| 462 | switch (fmt->index) { | 464 | if (fmt->index) |
| 463 | case 0: | ||
| 464 | fmt->pixelformat = V4L2_TCH_FMT_DELTA_TD16; | ||
| 465 | break; | ||
| 466 | |||
| 467 | case 1: | ||
| 468 | fmt->pixelformat = V4L2_TCH_FMT_DELTA_TD08; | ||
| 469 | break; | ||
| 470 | |||
| 471 | case 2: | ||
| 472 | fmt->pixelformat = V4L2_TCH_FMT_TU16; | ||
| 473 | break; | ||
| 474 | |||
| 475 | default: | ||
| 476 | return -EINVAL; | 465 | return -EINVAL; |
| 477 | } | 466 | |
| 467 | fmt->pixelformat = f54->format.pixelformat; | ||
| 478 | 468 | ||
| 479 | return 0; | 469 | return 0; |
| 480 | } | 470 | } |
| @@ -692,6 +682,7 @@ static int rmi_f54_probe(struct rmi_function *fn) | |||
| 692 | return -ENOMEM; | 682 | return -ENOMEM; |
| 693 | 683 | ||
| 694 | rmi_f54_create_input_map(f54); | 684 | rmi_f54_create_input_map(f54); |
| 685 | rmi_f54_set_input(f54, 0); | ||
| 695 | 686 | ||
| 696 | /* register video device */ | 687 | /* register video device */ |
| 697 | strlcpy(f54->v4l2.name, F54_NAME, sizeof(f54->v4l2.name)); | 688 | strlcpy(f54->v4l2.name, F54_NAME, sizeof(f54->v4l2.name)); |
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index c9c7224d5ae0..bfe436ccb046 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig | |||
| @@ -254,6 +254,7 @@ config SERIO_APBPS2 | |||
| 254 | 254 | ||
| 255 | config SERIO_OLPC_APSP | 255 | config SERIO_OLPC_APSP |
| 256 | tristate "OLPC AP-SP input support" | 256 | tristate "OLPC AP-SP input support" |
| 257 | depends on ARCH_MMP || COMPILE_TEST | ||
| 257 | help | 258 | help |
| 258 | Say Y here if you want support for the keyboard and touchpad included | 259 | Say Y here if you want support for the keyboard and touchpad included |
| 259 | in the OLPC XO-1.75 and XO-4 laptops. | 260 | in the OLPC XO-1.75 and XO-4 laptops. |
diff --git a/drivers/input/serio/hyperv-keyboard.c b/drivers/input/serio/hyperv-keyboard.c index a8b9be3e28db..7935e52b5435 100644 --- a/drivers/input/serio/hyperv-keyboard.c +++ b/drivers/input/serio/hyperv-keyboard.c | |||
| @@ -440,5 +440,7 @@ static void __exit hv_kbd_exit(void) | |||
| 440 | } | 440 | } |
| 441 | 441 | ||
| 442 | MODULE_LICENSE("GPL"); | 442 | MODULE_LICENSE("GPL"); |
| 443 | MODULE_DESCRIPTION("Microsoft Hyper-V Synthetic Keyboard Driver"); | ||
| 444 | |||
| 443 | module_init(hv_kbd_init); | 445 | module_init(hv_kbd_init); |
| 444 | module_exit(hv_kbd_exit); | 446 | module_exit(hv_kbd_exit); |
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 95a78ccbd847..6462f1798fbb 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
| @@ -573,9 +573,6 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) | |||
| 573 | port = &i8042_ports[port_no]; | 573 | port = &i8042_ports[port_no]; |
| 574 | serio = port->exists ? port->serio : NULL; | 574 | serio = port->exists ? port->serio : NULL; |
| 575 | 575 | ||
| 576 | if (irq && serio) | ||
| 577 | pm_wakeup_event(&serio->dev, 0); | ||
| 578 | |||
| 579 | filter_dbg(port->driver_bound, data, "<- i8042 (interrupt, %d, %d%s%s)\n", | 576 | filter_dbg(port->driver_bound, data, "<- i8042 (interrupt, %d, %d%s%s)\n", |
| 580 | port_no, irq, | 577 | port_no, irq, |
| 581 | dfl & SERIO_PARITY ? ", bad parity" : "", | 578 | dfl & SERIO_PARITY ? ", bad parity" : "", |
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index e6a07e68d1ff..22b8e05aa36c 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c | |||
| @@ -409,6 +409,7 @@ bool ps2_handle_ack(struct ps2dev *ps2dev, u8 data) | |||
| 409 | ps2dev->nak = PS2_RET_ERR; | 409 | ps2dev->nak = PS2_RET_ERR; |
| 410 | break; | 410 | break; |
| 411 | } | 411 | } |
| 412 | /* Fall through */ | ||
| 412 | 413 | ||
| 413 | /* | 414 | /* |
| 414 | * Workaround for mice which don't ACK the Get ID command. | 415 | * Workaround for mice which don't ACK the Get ID command. |
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 7a4884ad198b..a2029c3235af 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
| @@ -1312,4 +1312,14 @@ config TOUCHSCREEN_ROHM_BU21023 | |||
| 1312 | To compile this driver as a module, choose M here: the | 1312 | To compile this driver as a module, choose M here: the |
| 1313 | module will be called bu21023_ts. | 1313 | module will be called bu21023_ts. |
| 1314 | 1314 | ||
| 1315 | config TOUCHSCREEN_IQS5XX | ||
| 1316 | tristate "Azoteq IQS550/572/525 trackpad/touchscreen controller" | ||
| 1317 | depends on I2C | ||
| 1318 | help | ||
| 1319 | Say Y to enable support for the Azoteq IQS550/572/525 | ||
| 1320 | family of trackpad/touchscreen controllers. | ||
| 1321 | |||
| 1322 | To compile this driver as a module, choose M here: the | ||
| 1323 | module will be called iqs5xx. | ||
| 1324 | |||
| 1315 | endif | 1325 | endif |
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index fcc7605fba8d..084a596a0c8b 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile | |||
| @@ -110,3 +110,4 @@ obj-$(CONFIG_TOUCHSCREEN_ZFORCE) += zforce_ts.o | |||
| 110 | obj-$(CONFIG_TOUCHSCREEN_COLIBRI_VF50) += colibri-vf50-ts.o | 110 | obj-$(CONFIG_TOUCHSCREEN_COLIBRI_VF50) += colibri-vf50-ts.o |
| 111 | obj-$(CONFIG_TOUCHSCREEN_ROHM_BU21023) += rohm_bu21023.o | 111 | obj-$(CONFIG_TOUCHSCREEN_ROHM_BU21023) += rohm_bu21023.o |
| 112 | obj-$(CONFIG_TOUCHSCREEN_RASPBERRYPI_FW) += raspberrypi-ts.o | 112 | obj-$(CONFIG_TOUCHSCREEN_RASPBERRYPI_FW) += raspberrypi-ts.o |
| 113 | obj-$(CONFIG_TOUCHSCREEN_IQS5XX) += iqs5xx.o | ||
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index 702bfda7ee77..c639ebce914c 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c | |||
| @@ -1,20 +1,8 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (C) 2012 Simon Budig, <simon.budig@kernelconcepts.de> | 3 | * Copyright (C) 2012 Simon Budig, <simon.budig@kernelconcepts.de> |
| 3 | * Daniel Wagener <daniel.wagener@kernelconcepts.de> (M09 firmware support) | 4 | * Daniel Wagener <daniel.wagener@kernelconcepts.de> (M09 firmware support) |
| 4 | * Lothar Waßmann <LW@KARO-electronics.de> (DT support) | 5 | * Lothar Waßmann <LW@KARO-electronics.de> (DT support) |
| 5 | * | ||
| 6 | * This software is licensed under the terms of the GNU General Public | ||
| 7 | * License version 2, as published by the Free Software Foundation, and | ||
| 8 | * may be copied, distributed, and modified under those terms. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public | ||
| 16 | * License along with this library; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 18 | */ | 6 | */ |
| 19 | 7 | ||
| 20 | /* | 8 | /* |
| @@ -39,7 +27,6 @@ | |||
| 39 | #include <linux/gpio/consumer.h> | 27 | #include <linux/gpio/consumer.h> |
| 40 | #include <linux/input/mt.h> | 28 | #include <linux/input/mt.h> |
| 41 | #include <linux/input/touchscreen.h> | 29 | #include <linux/input/touchscreen.h> |
| 42 | #include <linux/of_device.h> | ||
| 43 | 30 | ||
| 44 | #define WORK_REGISTER_THRESHOLD 0x00 | 31 | #define WORK_REGISTER_THRESHOLD 0x00 |
| 45 | #define WORK_REGISTER_REPORT_RATE 0x08 | 32 | #define WORK_REGISTER_REPORT_RATE 0x08 |
| @@ -1073,7 +1060,7 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client, | |||
| 1073 | return -ENOMEM; | 1060 | return -ENOMEM; |
| 1074 | } | 1061 | } |
| 1075 | 1062 | ||
| 1076 | chip_data = of_device_get_match_data(&client->dev); | 1063 | chip_data = device_get_match_data(&client->dev); |
| 1077 | if (!chip_data) | 1064 | if (!chip_data) |
| 1078 | chip_data = (const struct edt_i2c_chip_data *)id->driver_data; | 1065 | chip_data = (const struct edt_i2c_chip_data *)id->driver_data; |
| 1079 | if (!chip_data || !chip_data->max_support_points) { | 1066 | if (!chip_data || !chip_data->max_support_points) { |
| @@ -1254,7 +1241,6 @@ static const struct i2c_device_id edt_ft5x06_ts_id[] = { | |||
| 1254 | }; | 1241 | }; |
| 1255 | MODULE_DEVICE_TABLE(i2c, edt_ft5x06_ts_id); | 1242 | MODULE_DEVICE_TABLE(i2c, edt_ft5x06_ts_id); |
| 1256 | 1243 | ||
| 1257 | #ifdef CONFIG_OF | ||
| 1258 | static const struct of_device_id edt_ft5x06_of_match[] = { | 1244 | static const struct of_device_id edt_ft5x06_of_match[] = { |
| 1259 | { .compatible = "edt,edt-ft5206", .data = &edt_ft5x06_data }, | 1245 | { .compatible = "edt,edt-ft5206", .data = &edt_ft5x06_data }, |
| 1260 | { .compatible = "edt,edt-ft5306", .data = &edt_ft5x06_data }, | 1246 | { .compatible = "edt,edt-ft5306", .data = &edt_ft5x06_data }, |
| @@ -1266,12 +1252,11 @@ static const struct of_device_id edt_ft5x06_of_match[] = { | |||
| 1266 | { /* sentinel */ } | 1252 | { /* sentinel */ } |
| 1267 | }; | 1253 | }; |
| 1268 | MODULE_DEVICE_TABLE(of, edt_ft5x06_of_match); | 1254 | MODULE_DEVICE_TABLE(of, edt_ft5x06_of_match); |
| 1269 | #endif | ||
| 1270 | 1255 | ||
| 1271 | static struct i2c_driver edt_ft5x06_ts_driver = { | 1256 | static struct i2c_driver edt_ft5x06_ts_driver = { |
| 1272 | .driver = { | 1257 | .driver = { |
| 1273 | .name = "edt_ft5x06", | 1258 | .name = "edt_ft5x06", |
| 1274 | .of_match_table = of_match_ptr(edt_ft5x06_of_match), | 1259 | .of_match_table = edt_ft5x06_of_match, |
| 1275 | .pm = &edt_ft5x06_ts_pm_ops, | 1260 | .pm = &edt_ft5x06_ts_pm_ops, |
| 1276 | }, | 1261 | }, |
| 1277 | .id_table = edt_ft5x06_ts_id, | 1262 | .id_table = edt_ft5x06_ts_id, |
| @@ -1283,4 +1268,4 @@ module_i2c_driver(edt_ft5x06_ts_driver); | |||
| 1283 | 1268 | ||
| 1284 | MODULE_AUTHOR("Simon Budig <simon.budig@kernelconcepts.de>"); | 1269 | MODULE_AUTHOR("Simon Budig <simon.budig@kernelconcepts.de>"); |
| 1285 | MODULE_DESCRIPTION("EDT FT5x06 I2C Touchscreen Driver"); | 1270 | MODULE_DESCRIPTION("EDT FT5x06 I2C Touchscreen Driver"); |
| 1286 | MODULE_LICENSE("GPL"); | 1271 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index f57d82220a88..f7c1d168dd89 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
| 28 | #include <linux/irq.h> | 28 | #include <linux/irq.h> |
| 29 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
| 30 | #include <linux/regulator/consumer.h> | ||
| 30 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
| 31 | #include <linux/acpi.h> | 32 | #include <linux/acpi.h> |
| 32 | #include <linux/of.h> | 33 | #include <linux/of.h> |
| @@ -47,6 +48,8 @@ struct goodix_ts_data { | |||
| 47 | struct touchscreen_properties prop; | 48 | struct touchscreen_properties prop; |
| 48 | unsigned int max_touch_num; | 49 | unsigned int max_touch_num; |
| 49 | unsigned int int_trigger_type; | 50 | unsigned int int_trigger_type; |
| 51 | struct regulator *avdd28; | ||
| 52 | struct regulator *vddio; | ||
| 50 | struct gpio_desc *gpiod_int; | 53 | struct gpio_desc *gpiod_int; |
| 51 | struct gpio_desc *gpiod_rst; | 54 | struct gpio_desc *gpiod_rst; |
| 52 | u16 id; | 55 | u16 id; |
| @@ -216,6 +219,7 @@ static const struct goodix_chip_data *goodix_get_chip_data(u16 id) | |||
| 216 | { | 219 | { |
| 217 | switch (id) { | 220 | switch (id) { |
| 218 | case 1151: | 221 | case 1151: |
| 222 | case 5663: | ||
| 219 | case 5688: | 223 | case 5688: |
| 220 | return >1x_chip_data; | 224 | return >1x_chip_data; |
| 221 | 225 | ||
| @@ -532,6 +536,24 @@ static int goodix_get_gpio_config(struct goodix_ts_data *ts) | |||
| 532 | return -EINVAL; | 536 | return -EINVAL; |
| 533 | dev = &ts->client->dev; | 537 | dev = &ts->client->dev; |
| 534 | 538 | ||
| 539 | ts->avdd28 = devm_regulator_get(dev, "AVDD28"); | ||
| 540 | if (IS_ERR(ts->avdd28)) { | ||
| 541 | error = PTR_ERR(ts->avdd28); | ||
| 542 | if (error != -EPROBE_DEFER) | ||
| 543 | dev_err(dev, | ||
| 544 | "Failed to get AVDD28 regulator: %d\n", error); | ||
| 545 | return error; | ||
| 546 | } | ||
| 547 | |||
| 548 | ts->vddio = devm_regulator_get(dev, "VDDIO"); | ||
| 549 | if (IS_ERR(ts->vddio)) { | ||
| 550 | error = PTR_ERR(ts->vddio); | ||
| 551 | if (error != -EPROBE_DEFER) | ||
| 552 | dev_err(dev, | ||
| 553 | "Failed to get VDDIO regulator: %d\n", error); | ||
| 554 | return error; | ||
| 555 | } | ||
| 556 | |||
| 535 | /* Get the interrupt GPIO pin number */ | 557 | /* Get the interrupt GPIO pin number */ |
| 536 | gpiod = devm_gpiod_get_optional(dev, GOODIX_GPIO_INT_NAME, GPIOD_IN); | 558 | gpiod = devm_gpiod_get_optional(dev, GOODIX_GPIO_INT_NAME, GPIOD_IN); |
| 537 | if (IS_ERR(gpiod)) { | 559 | if (IS_ERR(gpiod)) { |
| @@ -764,6 +786,14 @@ err_release_cfg: | |||
| 764 | complete_all(&ts->firmware_loading_complete); | 786 | complete_all(&ts->firmware_loading_complete); |
| 765 | } | 787 | } |
| 766 | 788 | ||
| 789 | static void goodix_disable_regulators(void *arg) | ||
| 790 | { | ||
| 791 | struct goodix_ts_data *ts = arg; | ||
| 792 | |||
| 793 | regulator_disable(ts->vddio); | ||
| 794 | regulator_disable(ts->avdd28); | ||
| 795 | } | ||
| 796 | |||
| 767 | static int goodix_ts_probe(struct i2c_client *client, | 797 | static int goodix_ts_probe(struct i2c_client *client, |
| 768 | const struct i2c_device_id *id) | 798 | const struct i2c_device_id *id) |
| 769 | { | 799 | { |
| @@ -789,6 +819,29 @@ static int goodix_ts_probe(struct i2c_client *client, | |||
| 789 | if (error) | 819 | if (error) |
| 790 | return error; | 820 | return error; |
| 791 | 821 | ||
| 822 | /* power up the controller */ | ||
| 823 | error = regulator_enable(ts->avdd28); | ||
| 824 | if (error) { | ||
| 825 | dev_err(&client->dev, | ||
| 826 | "Failed to enable AVDD28 regulator: %d\n", | ||
| 827 | error); | ||
| 828 | return error; | ||
| 829 | } | ||
| 830 | |||
| 831 | error = regulator_enable(ts->vddio); | ||
| 832 | if (error) { | ||
| 833 | dev_err(&client->dev, | ||
| 834 | "Failed to enable VDDIO regulator: %d\n", | ||
| 835 | error); | ||
| 836 | regulator_disable(ts->avdd28); | ||
| 837 | return error; | ||
| 838 | } | ||
| 839 | |||
| 840 | error = devm_add_action_or_reset(&client->dev, | ||
| 841 | goodix_disable_regulators, ts); | ||
| 842 | if (error) | ||
| 843 | return error; | ||
| 844 | |||
| 792 | if (ts->gpiod_int && ts->gpiod_rst) { | 845 | if (ts->gpiod_int && ts->gpiod_rst) { |
| 793 | /* reset the controller */ | 846 | /* reset the controller */ |
| 794 | error = goodix_reset(ts); | 847 | error = goodix_reset(ts); |
| @@ -945,6 +998,7 @@ MODULE_DEVICE_TABLE(acpi, goodix_acpi_match); | |||
| 945 | #ifdef CONFIG_OF | 998 | #ifdef CONFIG_OF |
| 946 | static const struct of_device_id goodix_of_match[] = { | 999 | static const struct of_device_id goodix_of_match[] = { |
| 947 | { .compatible = "goodix,gt1151" }, | 1000 | { .compatible = "goodix,gt1151" }, |
| 1001 | { .compatible = "goodix,gt5663" }, | ||
| 948 | { .compatible = "goodix,gt5688" }, | 1002 | { .compatible = "goodix,gt5688" }, |
| 949 | { .compatible = "goodix,gt911" }, | 1003 | { .compatible = "goodix,gt911" }, |
| 950 | { .compatible = "goodix,gt9110" }, | 1004 | { .compatible = "goodix,gt9110" }, |
diff --git a/drivers/input/touchscreen/iqs5xx.c b/drivers/input/touchscreen/iqs5xx.c new file mode 100644 index 000000000000..b832fe062645 --- /dev/null +++ b/drivers/input/touchscreen/iqs5xx.c | |||
| @@ -0,0 +1,1133 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 2 | /* | ||
| 3 | * Azoteq IQS550/572/525 Trackpad/Touchscreen Controller | ||
| 4 | * | ||
| 5 | * Copyright (C) 2018 | ||
| 6 | * Author: Jeff LaBundy <jeff@labundy.com> | ||
| 7 | * | ||
| 8 | * These devices require firmware exported from a PC-based configuration tool | ||
| 9 | * made available by the vendor. Firmware files may be pushed to the device's | ||
| 10 | * nonvolatile memory by writing the filename to the 'fw_file' sysfs control. | ||
| 11 | * | ||
| 12 | * Link to PC-based configuration tool and data sheet: http://www.azoteq.com/ | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/delay.h> | ||
| 16 | #include <linux/device.h> | ||
| 17 | #include <linux/err.h> | ||
| 18 | #include <linux/firmware.h> | ||
| 19 | #include <linux/gpio/consumer.h> | ||
| 20 | #include <linux/i2c.h> | ||
| 21 | #include <linux/input.h> | ||
| 22 | #include <linux/input/mt.h> | ||
| 23 | #include <linux/input/touchscreen.h> | ||
| 24 | #include <linux/interrupt.h> | ||
| 25 | #include <linux/kernel.h> | ||
| 26 | #include <linux/module.h> | ||
| 27 | #include <linux/of_device.h> | ||
| 28 | #include <linux/slab.h> | ||
| 29 | #include <asm/unaligned.h> | ||
| 30 | |||
| 31 | #define IQS5XX_FW_FILE_LEN 64 | ||
| 32 | #define IQS5XX_NUM_RETRIES 10 | ||
| 33 | #define IQS5XX_NUM_POINTS 256 | ||
| 34 | #define IQS5XX_NUM_CONTACTS 5 | ||
| 35 | #define IQS5XX_WR_BYTES_MAX 2 | ||
| 36 | |||
| 37 | #define IQS5XX_PROD_NUM_IQS550 40 | ||
| 38 | #define IQS5XX_PROD_NUM_IQS572 58 | ||
| 39 | #define IQS5XX_PROD_NUM_IQS525 52 | ||
| 40 | #define IQS5XX_PROJ_NUM_A000 0 | ||
| 41 | #define IQS5XX_PROJ_NUM_B000 15 | ||
| 42 | #define IQS5XX_MAJOR_VER_MIN 2 | ||
| 43 | |||
| 44 | #define IQS5XX_RESUME 0x00 | ||
| 45 | #define IQS5XX_SUSPEND 0x01 | ||
| 46 | |||
| 47 | #define IQS5XX_SW_INPUT_EVENT 0x10 | ||
| 48 | #define IQS5XX_SETUP_COMPLETE 0x40 | ||
| 49 | #define IQS5XX_EVENT_MODE 0x01 | ||
| 50 | #define IQS5XX_TP_EVENT 0x04 | ||
| 51 | |||
| 52 | #define IQS5XX_FLIP_X 0x01 | ||
| 53 | #define IQS5XX_FLIP_Y 0x02 | ||
| 54 | #define IQS5XX_SWITCH_XY_AXIS 0x04 | ||
| 55 | |||
| 56 | #define IQS5XX_PROD_NUM 0x0000 | ||
| 57 | #define IQS5XX_ABS_X 0x0016 | ||
| 58 | #define IQS5XX_ABS_Y 0x0018 | ||
| 59 | #define IQS5XX_SYS_CTRL0 0x0431 | ||
| 60 | #define IQS5XX_SYS_CTRL1 0x0432 | ||
| 61 | #define IQS5XX_SYS_CFG0 0x058E | ||
| 62 | #define IQS5XX_SYS_CFG1 0x058F | ||
| 63 | #define IQS5XX_TOTAL_RX 0x063D | ||
| 64 | #define IQS5XX_TOTAL_TX 0x063E | ||
| 65 | #define IQS5XX_XY_CFG0 0x0669 | ||
| 66 | #define IQS5XX_X_RES 0x066E | ||
| 67 | #define IQS5XX_Y_RES 0x0670 | ||
| 68 | #define IQS5XX_CHKSM 0x83C0 | ||
| 69 | #define IQS5XX_APP 0x8400 | ||
| 70 | #define IQS5XX_CSTM 0xBE00 | ||
| 71 | #define IQS5XX_PMAP_END 0xBFFF | ||
| 72 | #define IQS5XX_END_COMM 0xEEEE | ||
| 73 | |||
| 74 | #define IQS5XX_CHKSM_LEN (IQS5XX_APP - IQS5XX_CHKSM) | ||
| 75 | #define IQS5XX_APP_LEN (IQS5XX_CSTM - IQS5XX_APP) | ||
| 76 | #define IQS5XX_CSTM_LEN (IQS5XX_PMAP_END + 1 - IQS5XX_CSTM) | ||
| 77 | #define IQS5XX_PMAP_LEN (IQS5XX_PMAP_END + 1 - IQS5XX_CHKSM) | ||
| 78 | |||
| 79 | #define IQS5XX_REC_HDR_LEN 4 | ||
| 80 | #define IQS5XX_REC_LEN_MAX 255 | ||
| 81 | #define IQS5XX_REC_TYPE_DATA 0x00 | ||
| 82 | #define IQS5XX_REC_TYPE_EOF 0x01 | ||
| 83 | |||
| 84 | #define IQS5XX_BL_ADDR_MASK 0x40 | ||
| 85 | #define IQS5XX_BL_CMD_VER 0x00 | ||
| 86 | #define IQS5XX_BL_CMD_READ 0x01 | ||
| 87 | #define IQS5XX_BL_CMD_EXEC 0x02 | ||
| 88 | #define IQS5XX_BL_CMD_CRC 0x03 | ||
| 89 | #define IQS5XX_BL_BLK_LEN_MAX 64 | ||
| 90 | #define IQS5XX_BL_ID 0x0200 | ||
| 91 | #define IQS5XX_BL_STATUS_RESET 0x00 | ||
| 92 | #define IQS5XX_BL_STATUS_AVAIL 0xA5 | ||
| 93 | #define IQS5XX_BL_STATUS_NONE 0xEE | ||
| 94 | #define IQS5XX_BL_CRC_PASS 0x00 | ||
| 95 | #define IQS5XX_BL_CRC_FAIL 0x01 | ||
| 96 | #define IQS5XX_BL_ATTEMPTS 3 | ||
| 97 | |||
| 98 | struct iqs5xx_private { | ||
| 99 | struct i2c_client *client; | ||
| 100 | struct input_dev *input; | ||
| 101 | struct gpio_desc *reset_gpio; | ||
| 102 | struct mutex lock; | ||
| 103 | u8 bl_status; | ||
| 104 | }; | ||
| 105 | |||
| 106 | struct iqs5xx_dev_id_info { | ||
| 107 | __be16 prod_num; | ||
| 108 | __be16 proj_num; | ||
| 109 | u8 major_ver; | ||
| 110 | u8 minor_ver; | ||
| 111 | u8 bl_status; | ||
| 112 | } __packed; | ||
| 113 | |||
| 114 | struct iqs5xx_ihex_rec { | ||
| 115 | char start; | ||
| 116 | char len[2]; | ||
| 117 | char addr[4]; | ||
| 118 | char type[2]; | ||
| 119 | char data[2]; | ||
| 120 | } __packed; | ||
| 121 | |||
| 122 | struct iqs5xx_touch_data { | ||
| 123 | __be16 abs_x; | ||
| 124 | __be16 abs_y; | ||
| 125 | __be16 strength; | ||
| 126 | u8 area; | ||
| 127 | } __packed; | ||
| 128 | |||
| 129 | static int iqs5xx_read_burst(struct i2c_client *client, | ||
| 130 | u16 reg, void *val, u16 len) | ||
| 131 | { | ||
| 132 | __be16 reg_buf = cpu_to_be16(reg); | ||
| 133 | int ret, i; | ||
| 134 | struct i2c_msg msg[] = { | ||
| 135 | { | ||
| 136 | .addr = client->addr, | ||
| 137 | .flags = 0, | ||
| 138 | .len = sizeof(reg_buf), | ||
| 139 | .buf = (u8 *)®_buf, | ||
| 140 | }, | ||
| 141 | { | ||
| 142 | .addr = client->addr, | ||
| 143 | .flags = I2C_M_RD, | ||
| 144 | .len = len, | ||
| 145 | .buf = (u8 *)val, | ||
| 146 | }, | ||
| 147 | }; | ||
| 148 | |||
| 149 | /* | ||
| 150 | * The first addressing attempt outside of a communication window fails | ||
| 151 | * and must be retried, after which the device clock stretches until it | ||
| 152 | * is available. | ||
| 153 | */ | ||
| 154 | for (i = 0; i < IQS5XX_NUM_RETRIES; i++) { | ||
| 155 | ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); | ||
| 156 | if (ret == ARRAY_SIZE(msg)) | ||
| 157 | return 0; | ||
| 158 | |||
| 159 | usleep_range(200, 300); | ||
| 160 | } | ||
| 161 | |||
| 162 | if (ret >= 0) | ||
| 163 | ret = -EIO; | ||
| 164 | |||
| 165 | dev_err(&client->dev, "Failed to read from address 0x%04X: %d\n", | ||
| 166 | reg, ret); | ||
| 167 | |||
| 168 | return ret; | ||
| 169 | } | ||
| 170 | |||
| 171 | static int iqs5xx_read_word(struct i2c_client *client, u16 reg, u16 *val) | ||
| 172 | { | ||
| 173 | __be16 val_buf; | ||
| 174 | int error; | ||
| 175 | |||
| 176 | error = iqs5xx_read_burst(client, reg, &val_buf, sizeof(val_buf)); | ||
| 177 | if (error) | ||
| 178 | return error; | ||
| 179 | |||
| 180 | *val = be16_to_cpu(val_buf); | ||
| 181 | |||
| 182 | return 0; | ||
| 183 | } | ||
| 184 | |||
| 185 | static int iqs5xx_read_byte(struct i2c_client *client, u16 reg, u8 *val) | ||
| 186 | { | ||
| 187 | return iqs5xx_read_burst(client, reg, val, sizeof(*val)); | ||
| 188 | } | ||
| 189 | |||
| 190 | static int iqs5xx_write_burst(struct i2c_client *client, | ||
| 191 | u16 reg, const void *val, u16 len) | ||
| 192 | { | ||
| 193 | int ret, i; | ||
| 194 | u16 mlen = sizeof(reg) + len; | ||
| 195 | u8 mbuf[sizeof(reg) + IQS5XX_WR_BYTES_MAX]; | ||
| 196 | |||
| 197 | if (len > IQS5XX_WR_BYTES_MAX) | ||
| 198 | return -EINVAL; | ||
| 199 | |||
| 200 | put_unaligned_be16(reg, mbuf); | ||
| 201 | memcpy(mbuf + sizeof(reg), val, len); | ||
| 202 | |||
| 203 | /* | ||
| 204 | * The first addressing attempt outside of a communication window fails | ||
| 205 | * and must be retried, after which the device clock stretches until it | ||
| 206 | * is available. | ||
| 207 | */ | ||
| 208 | for (i = 0; i < IQS5XX_NUM_RETRIES; i++) { | ||
| 209 | ret = i2c_master_send(client, mbuf, mlen); | ||
| 210 | if (ret == mlen) | ||
| 211 | return 0; | ||
| 212 | |||
| 213 | usleep_range(200, 300); | ||
| 214 | } | ||
| 215 | |||
| 216 | if (ret >= 0) | ||
| 217 | ret = -EIO; | ||
| 218 | |||
| 219 | dev_err(&client->dev, "Failed to write to address 0x%04X: %d\n", | ||
| 220 | reg, ret); | ||
| 221 | |||
| 222 | return ret; | ||
| 223 | } | ||
| 224 | |||
| 225 | static int iqs5xx_write_word(struct i2c_client *client, u16 reg, u16 val) | ||
| 226 | { | ||
| 227 | __be16 val_buf = cpu_to_be16(val); | ||
| 228 | |||
| 229 | return iqs5xx_write_burst(client, reg, &val_buf, sizeof(val_buf)); | ||
| 230 | } | ||
| 231 | |||
| 232 | static int iqs5xx_write_byte(struct i2c_client *client, u16 reg, u8 val) | ||
| 233 | { | ||
| 234 | return iqs5xx_write_burst(client, reg, &val, sizeof(val)); | ||
| 235 | } | ||
| 236 | |||
| 237 | static void iqs5xx_reset(struct i2c_client *client) | ||
| 238 | { | ||
| 239 | struct iqs5xx_private *iqs5xx = i2c_get_clientdata(client); | ||
| 240 | |||
| 241 | gpiod_set_value_cansleep(iqs5xx->reset_gpio, 1); | ||
| 242 | usleep_range(200, 300); | ||
| 243 | |||
| 244 | gpiod_set_value_cansleep(iqs5xx->reset_gpio, 0); | ||
| 245 | } | ||
| 246 | |||
| 247 | static int iqs5xx_bl_cmd(struct i2c_client *client, u8 bl_cmd, u16 bl_addr) | ||
| 248 | { | ||
| 249 | struct i2c_msg msg; | ||
| 250 | int ret; | ||
| 251 | u8 mbuf[sizeof(bl_cmd) + sizeof(bl_addr)]; | ||
| 252 | |||
| 253 | msg.addr = client->addr ^ IQS5XX_BL_ADDR_MASK; | ||
| 254 | msg.flags = 0; | ||
| 255 | msg.len = sizeof(bl_cmd); | ||
| 256 | msg.buf = mbuf; | ||
| 257 | |||
| 258 | *mbuf = bl_cmd; | ||
| 259 | |||
| 260 | switch (bl_cmd) { | ||
| 261 | case IQS5XX_BL_CMD_VER: | ||
| 262 | case IQS5XX_BL_CMD_CRC: | ||
| 263 | case IQS5XX_BL_CMD_EXEC: | ||
| 264 | break; | ||
| 265 | case IQS5XX_BL_CMD_READ: | ||
| 266 | msg.len += sizeof(bl_addr); | ||
| 267 | put_unaligned_be16(bl_addr, mbuf + sizeof(bl_cmd)); | ||
| 268 | break; | ||
| 269 | default: | ||
| 270 | return -EINVAL; | ||
| 271 | } | ||
| 272 | |||
| 273 | ret = i2c_transfer(client->adapter, &msg, 1); | ||
| 274 | if (ret != 1) | ||
| 275 | goto msg_fail; | ||
| 276 | |||
| 277 | switch (bl_cmd) { | ||
| 278 | case IQS5XX_BL_CMD_VER: | ||
| 279 | msg.len = sizeof(u16); | ||
| 280 | break; | ||
| 281 | case IQS5XX_BL_CMD_CRC: | ||
| 282 | msg.len = sizeof(u8); | ||
| 283 | /* | ||
| 284 | * This delay saves the bus controller the trouble of having to | ||
| 285 | * tolerate a relatively long clock-stretching period while the | ||
| 286 | * CRC is calculated. | ||
| 287 | */ | ||
| 288 | msleep(50); | ||
| 289 | break; | ||
| 290 | case IQS5XX_BL_CMD_EXEC: | ||
| 291 | usleep_range(10000, 10100); | ||
| 292 | /* fall through */ | ||
| 293 | default: | ||
| 294 | return 0; | ||
| 295 | } | ||
| 296 | |||
| 297 | msg.flags = I2C_M_RD; | ||
| 298 | |||
| 299 | ret = i2c_transfer(client->adapter, &msg, 1); | ||
| 300 | if (ret != 1) | ||
| 301 | goto msg_fail; | ||
| 302 | |||
| 303 | if (bl_cmd == IQS5XX_BL_CMD_VER && | ||
| 304 | get_unaligned_be16(mbuf) != IQS5XX_BL_ID) { | ||
| 305 | dev_err(&client->dev, "Unrecognized bootloader ID: 0x%04X\n", | ||
| 306 | get_unaligned_be16(mbuf)); | ||
| 307 | return -EINVAL; | ||
| 308 | } | ||
| 309 | |||
| 310 | if (bl_cmd == IQS5XX_BL_CMD_CRC && *mbuf != IQS5XX_BL_CRC_PASS) { | ||
| 311 | dev_err(&client->dev, "Bootloader CRC failed\n"); | ||
| 312 | return -EIO; | ||
| 313 | } | ||
| 314 | |||
| 315 | return 0; | ||
| 316 | |||
| 317 | msg_fail: | ||
| 318 | if (ret >= 0) | ||
| 319 | ret = -EIO; | ||
| 320 | |||
| 321 | if (bl_cmd != IQS5XX_BL_CMD_VER) | ||
| 322 | dev_err(&client->dev, | ||
| 323 | "Unsuccessful bootloader command 0x%02X: %d\n", | ||
| 324 | bl_cmd, ret); | ||
| 325 | |||
| 326 | return ret; | ||
| 327 | } | ||
| 328 | |||
| 329 | static int iqs5xx_bl_open(struct i2c_client *client) | ||
| 330 | { | ||
| 331 | int error, i, j; | ||
| 332 | |||
| 333 | /* | ||
| 334 | * The device opens a bootloader polling window for 2 ms following the | ||
| 335 | * release of reset. If the host cannot establish communication during | ||
| 336 | * this time frame, it must cycle reset again. | ||
| 337 | */ | ||
| 338 | for (i = 0; i < IQS5XX_BL_ATTEMPTS; i++) { | ||
| 339 | iqs5xx_reset(client); | ||
| 340 | |||
| 341 | for (j = 0; j < IQS5XX_NUM_RETRIES; j++) { | ||
| 342 | error = iqs5xx_bl_cmd(client, IQS5XX_BL_CMD_VER, 0); | ||
| 343 | if (!error || error == -EINVAL) | ||
| 344 | return error; | ||
| 345 | } | ||
| 346 | } | ||
| 347 | |||
| 348 | dev_err(&client->dev, "Failed to open bootloader: %d\n", error); | ||
| 349 | |||
| 350 | return error; | ||
| 351 | } | ||
| 352 | |||
| 353 | static int iqs5xx_bl_write(struct i2c_client *client, | ||
| 354 | u16 bl_addr, u8 *pmap_data, u16 pmap_len) | ||
| 355 | { | ||
| 356 | struct i2c_msg msg; | ||
| 357 | int ret, i; | ||
| 358 | u8 mbuf[sizeof(bl_addr) + IQS5XX_BL_BLK_LEN_MAX]; | ||
| 359 | |||
| 360 | if (pmap_len % IQS5XX_BL_BLK_LEN_MAX) | ||
| 361 | return -EINVAL; | ||
| 362 | |||
| 363 | msg.addr = client->addr ^ IQS5XX_BL_ADDR_MASK; | ||
| 364 | msg.flags = 0; | ||
| 365 | msg.len = sizeof(mbuf); | ||
| 366 | msg.buf = mbuf; | ||
| 367 | |||
| 368 | for (i = 0; i < pmap_len; i += IQS5XX_BL_BLK_LEN_MAX) { | ||
| 369 | put_unaligned_be16(bl_addr + i, mbuf); | ||
| 370 | memcpy(mbuf + sizeof(bl_addr), pmap_data + i, | ||
| 371 | sizeof(mbuf) - sizeof(bl_addr)); | ||
| 372 | |||
| 373 | ret = i2c_transfer(client->adapter, &msg, 1); | ||
| 374 | if (ret != 1) | ||
| 375 | goto msg_fail; | ||
| 376 | |||
| 377 | usleep_range(10000, 10100); | ||
| 378 | } | ||
| 379 | |||
| 380 | return 0; | ||
| 381 | |||
| 382 | msg_fail: | ||
| 383 | if (ret >= 0) | ||
| 384 | ret = -EIO; | ||
| 385 | |||
| 386 | dev_err(&client->dev, "Failed to write block at address 0x%04X: %d\n", | ||
| 387 | bl_addr + i, ret); | ||
| 388 | |||
| 389 | return ret; | ||
| 390 | } | ||
| 391 | |||
| 392 | static int iqs5xx_bl_verify(struct i2c_client *client, | ||
| 393 | u16 bl_addr, u8 *pmap_data, u16 pmap_len) | ||
| 394 | { | ||
| 395 | struct i2c_msg msg; | ||
| 396 | int ret, i; | ||
| 397 | u8 bl_data[IQS5XX_BL_BLK_LEN_MAX]; | ||
| 398 | |||
| 399 | if (pmap_len % IQS5XX_BL_BLK_LEN_MAX) | ||
| 400 | return -EINVAL; | ||
| 401 | |||
| 402 | msg.addr = client->addr ^ IQS5XX_BL_ADDR_MASK; | ||
| 403 | msg.flags = I2C_M_RD; | ||
| 404 | msg.len = sizeof(bl_data); | ||
| 405 | msg.buf = bl_data; | ||
| 406 | |||
| 407 | for (i = 0; i < pmap_len; i += IQS5XX_BL_BLK_LEN_MAX) { | ||
| 408 | ret = iqs5xx_bl_cmd(client, IQS5XX_BL_CMD_READ, bl_addr + i); | ||
| 409 | if (ret) | ||
| 410 | return ret; | ||
| 411 | |||
| 412 | ret = i2c_transfer(client->adapter, &msg, 1); | ||
| 413 | if (ret != 1) | ||
| 414 | goto msg_fail; | ||
| 415 | |||
| 416 | if (memcmp(bl_data, pmap_data + i, sizeof(bl_data))) { | ||
| 417 | dev_err(&client->dev, | ||
| 418 | "Failed to verify block at address 0x%04X\n", | ||
| 419 | bl_addr + i); | ||
| 420 | return -EIO; | ||
| 421 | } | ||
| 422 | } | ||
| 423 | |||
| 424 | return 0; | ||
| 425 | |||
| 426 | msg_fail: | ||
| 427 | if (ret >= 0) | ||
| 428 | ret = -EIO; | ||
| 429 | |||
| 430 | dev_err(&client->dev, "Failed to read block at address 0x%04X: %d\n", | ||
| 431 | bl_addr + i, ret); | ||
| 432 | |||
| 433 | return ret; | ||
| 434 | } | ||
| 435 | |||
| 436 | static int iqs5xx_set_state(struct i2c_client *client, u8 state) | ||
| 437 | { | ||
| 438 | struct iqs5xx_private *iqs5xx = i2c_get_clientdata(client); | ||
| 439 | int error1, error2; | ||
| 440 | |||
| 441 | if (iqs5xx->bl_status == IQS5XX_BL_STATUS_RESET) | ||
| 442 | return 0; | ||
| 443 | |||
| 444 | mutex_lock(&iqs5xx->lock); | ||
| 445 | |||
| 446 | /* | ||
| 447 | * Addressing the device outside of a communication window prompts it | ||
| 448 | * to assert the RDY output, so disable the interrupt line to prevent | ||
| 449 | * the handler from servicing a false interrupt. | ||
| 450 | */ | ||
| 451 | disable_irq(client->irq); | ||
| 452 | |||
| 453 | error1 = iqs5xx_write_byte(client, IQS5XX_SYS_CTRL1, state); | ||
| 454 | error2 = iqs5xx_write_byte(client, IQS5XX_END_COMM, 0); | ||
| 455 | |||
| 456 | usleep_range(50, 100); | ||
| 457 | enable_irq(client->irq); | ||
| 458 | |||
| 459 | mutex_unlock(&iqs5xx->lock); | ||
| 460 | |||
| 461 | if (error1) | ||
| 462 | return error1; | ||
| 463 | |||
| 464 | return error2; | ||
| 465 | } | ||
| 466 | |||
| 467 | static int iqs5xx_open(struct input_dev *input) | ||
| 468 | { | ||
| 469 | struct iqs5xx_private *iqs5xx = input_get_drvdata(input); | ||
| 470 | |||
| 471 | return iqs5xx_set_state(iqs5xx->client, IQS5XX_RESUME); | ||
| 472 | } | ||
| 473 | |||
| 474 | static void iqs5xx_close(struct input_dev *input) | ||
| 475 | { | ||
| 476 | struct iqs5xx_private *iqs5xx = input_get_drvdata(input); | ||
| 477 | |||
| 478 | iqs5xx_set_state(iqs5xx->client, IQS5XX_SUSPEND); | ||
| 479 | } | ||
| 480 | |||
| 481 | static int iqs5xx_axis_init(struct i2c_client *client) | ||
| 482 | { | ||
| 483 | struct iqs5xx_private *iqs5xx = i2c_get_clientdata(client); | ||
| 484 | struct touchscreen_properties prop; | ||
| 485 | struct input_dev *input; | ||
| 486 | int error; | ||
| 487 | u16 max_x, max_x_hw; | ||
| 488 | u16 max_y, max_y_hw; | ||
| 489 | u8 val; | ||
| 490 | |||
| 491 | if (!iqs5xx->input) { | ||
| 492 | input = devm_input_allocate_device(&client->dev); | ||
| 493 | if (!input) | ||
| 494 | return -ENOMEM; | ||
| 495 | |||
| 496 | input->name = client->name; | ||
| 497 | input->id.bustype = BUS_I2C; | ||
| 498 | input->open = iqs5xx_open; | ||
| 499 | input->close = iqs5xx_close; | ||
| 500 | |||
| 501 | input_set_capability(input, EV_ABS, ABS_MT_POSITION_X); | ||
| 502 | input_set_capability(input, EV_ABS, ABS_MT_POSITION_Y); | ||
| 503 | input_set_capability(input, EV_ABS, ABS_MT_PRESSURE); | ||
| 504 | |||
| 505 | error = input_mt_init_slots(input, | ||
| 506 | IQS5XX_NUM_CONTACTS, INPUT_MT_DIRECT); | ||
| 507 | if (error) { | ||
| 508 | dev_err(&client->dev, | ||
| 509 | "Failed to initialize slots: %d\n", error); | ||
| 510 | return error; | ||
| 511 | } | ||
| 512 | |||
| 513 | input_set_drvdata(input, iqs5xx); | ||
| 514 | iqs5xx->input = input; | ||
| 515 | } | ||
| 516 | |||
| 517 | touchscreen_parse_properties(iqs5xx->input, true, &prop); | ||
| 518 | |||
| 519 | error = iqs5xx_read_byte(client, IQS5XX_TOTAL_RX, &val); | ||
| 520 | if (error) | ||
| 521 | return error; | ||
| 522 | max_x_hw = (val - 1) * IQS5XX_NUM_POINTS; | ||
| 523 | |||
| 524 | error = iqs5xx_read_byte(client, IQS5XX_TOTAL_TX, &val); | ||
| 525 | if (error) | ||
| 526 | return error; | ||
| 527 | max_y_hw = (val - 1) * IQS5XX_NUM_POINTS; | ||
| 528 | |||
| 529 | error = iqs5xx_read_byte(client, IQS5XX_XY_CFG0, &val); | ||
| 530 | if (error) | ||
| 531 | return error; | ||
| 532 | |||
| 533 | if (val & IQS5XX_SWITCH_XY_AXIS) | ||
| 534 | swap(max_x_hw, max_y_hw); | ||
| 535 | |||
| 536 | if (prop.swap_x_y) | ||
| 537 | val ^= IQS5XX_SWITCH_XY_AXIS; | ||
| 538 | |||
| 539 | if (prop.invert_x) | ||
| 540 | val ^= prop.swap_x_y ? IQS5XX_FLIP_Y : IQS5XX_FLIP_X; | ||
| 541 | |||
| 542 | if (prop.invert_y) | ||
| 543 | val ^= prop.swap_x_y ? IQS5XX_FLIP_X : IQS5XX_FLIP_Y; | ||
| 544 | |||
| 545 | error = iqs5xx_write_byte(client, IQS5XX_XY_CFG0, val); | ||
| 546 | if (error) | ||
| 547 | return error; | ||
| 548 | |||
| 549 | if (prop.max_x > max_x_hw) { | ||
| 550 | dev_err(&client->dev, "Invalid maximum x-coordinate: %u > %u\n", | ||
| 551 | prop.max_x, max_x_hw); | ||
| 552 | return -EINVAL; | ||
| 553 | } else if (prop.max_x == 0) { | ||
| 554 | error = iqs5xx_read_word(client, IQS5XX_X_RES, &max_x); | ||
| 555 | if (error) | ||
| 556 | return error; | ||
| 557 | |||
| 558 | input_abs_set_max(iqs5xx->input, | ||
| 559 | prop.swap_x_y ? ABS_MT_POSITION_Y : | ||
| 560 | ABS_MT_POSITION_X, | ||
| 561 | max_x); | ||
| 562 | } else { | ||
| 563 | max_x = (u16)prop.max_x; | ||
| 564 | } | ||
| 565 | |||
| 566 | if (prop.max_y > max_y_hw) { | ||
| 567 | dev_err(&client->dev, "Invalid maximum y-coordinate: %u > %u\n", | ||
| 568 | prop.max_y, max_y_hw); | ||
| 569 | return -EINVAL; | ||
| 570 | } else if (prop.max_y == 0) { | ||
| 571 | error = iqs5xx_read_word(client, IQS5XX_Y_RES, &max_y); | ||
| 572 | if (error) | ||
| 573 | return error; | ||
| 574 | |||
| 575 | input_abs_set_max(iqs5xx->input, | ||
| 576 | prop.swap_x_y ? ABS_MT_POSITION_X : | ||
| 577 | ABS_MT_POSITION_Y, | ||
| 578 | max_y); | ||
| 579 | } else { | ||
| 580 | max_y = (u16)prop.max_y; | ||
| 581 | } | ||
| 582 | |||
| 583 | /* | ||
| 584 | * Write horizontal and vertical resolution to the device in case its | ||
| 585 | * original defaults were overridden or swapped as per the properties | ||
| 586 | * specified in the device tree. | ||
| 587 | */ | ||
| 588 | error = iqs5xx_write_word(client, | ||
| 589 | prop.swap_x_y ? IQS5XX_Y_RES : IQS5XX_X_RES, | ||
| 590 | max_x); | ||
| 591 | if (error) | ||
| 592 | return error; | ||
| 593 | |||
| 594 | return iqs5xx_write_word(client, | ||
| 595 | prop.swap_x_y ? IQS5XX_X_RES : IQS5XX_Y_RES, | ||
| 596 | max_y); | ||
| 597 | } | ||
| 598 | |||
| 599 | static int iqs5xx_dev_init(struct i2c_client *client) | ||
| 600 | { | ||
| 601 | struct iqs5xx_private *iqs5xx = i2c_get_clientdata(client); | ||
| 602 | struct iqs5xx_dev_id_info *dev_id_info; | ||
| 603 | int error; | ||
| 604 | u8 val; | ||
| 605 | u8 buf[sizeof(*dev_id_info) + 1]; | ||
| 606 | |||
| 607 | error = iqs5xx_read_burst(client, IQS5XX_PROD_NUM, | ||
| 608 | &buf[1], sizeof(*dev_id_info)); | ||
| 609 | if (error) | ||
| 610 | return iqs5xx_bl_open(client); | ||
| 611 | |||
| 612 | /* | ||
| 613 | * A000 and B000 devices use 8-bit and 16-bit addressing, respectively. | ||
| 614 | * Querying an A000 device's version information with 16-bit addressing | ||
| 615 | * gives the appearance that the data is shifted by one byte; a nonzero | ||
| 616 | * leading array element suggests this could be the case (in which case | ||
| 617 | * the missing zero is prepended). | ||
| 618 | */ | ||
| 619 | buf[0] = 0; | ||
| 620 | dev_id_info = (struct iqs5xx_dev_id_info *)&buf[(buf[1] > 0) ? 0 : 1]; | ||
| 621 | |||
| 622 | switch (be16_to_cpu(dev_id_info->prod_num)) { | ||
| 623 | case IQS5XX_PROD_NUM_IQS550: | ||
| 624 | case IQS5XX_PROD_NUM_IQS572: | ||
| 625 | case IQS5XX_PROD_NUM_IQS525: | ||
| 626 | break; | ||
| 627 | default: | ||
| 628 | dev_err(&client->dev, "Unrecognized product number: %u\n", | ||
| 629 | be16_to_cpu(dev_id_info->prod_num)); | ||
| 630 | return -EINVAL; | ||
| 631 | } | ||
| 632 | |||
| 633 | switch (be16_to_cpu(dev_id_info->proj_num)) { | ||
| 634 | case IQS5XX_PROJ_NUM_A000: | ||
| 635 | dev_err(&client->dev, "Unsupported project number: %u\n", | ||
| 636 | be16_to_cpu(dev_id_info->proj_num)); | ||
| 637 | return iqs5xx_bl_open(client); | ||
| 638 | case IQS5XX_PROJ_NUM_B000: | ||
| 639 | break; | ||
| 640 | default: | ||
| 641 | dev_err(&client->dev, "Unrecognized project number: %u\n", | ||
| 642 | be16_to_cpu(dev_id_info->proj_num)); | ||
| 643 | return -EINVAL; | ||
| 644 | } | ||
| 645 | |||
| 646 | if (dev_id_info->major_ver < IQS5XX_MAJOR_VER_MIN) { | ||
| 647 | dev_err(&client->dev, "Unsupported major version: %u\n", | ||
| 648 | dev_id_info->major_ver); | ||
| 649 | return iqs5xx_bl_open(client); | ||
| 650 | } | ||
| 651 | |||
| 652 | switch (dev_id_info->bl_status) { | ||
| 653 | case IQS5XX_BL_STATUS_AVAIL: | ||
| 654 | case IQS5XX_BL_STATUS_NONE: | ||
| 655 | break; | ||
| 656 | default: | ||
| 657 | dev_err(&client->dev, | ||
| 658 | "Unrecognized bootloader status: 0x%02X\n", | ||
| 659 | dev_id_info->bl_status); | ||
| 660 | return -EINVAL; | ||
| 661 | } | ||
| 662 | |||
| 663 | error = iqs5xx_axis_init(client); | ||
| 664 | if (error) | ||
| 665 | return error; | ||
| 666 | |||
| 667 | error = iqs5xx_read_byte(client, IQS5XX_SYS_CFG0, &val); | ||
| 668 | if (error) | ||
| 669 | return error; | ||
| 670 | |||
| 671 | val |= IQS5XX_SETUP_COMPLETE; | ||
| 672 | val &= ~IQS5XX_SW_INPUT_EVENT; | ||
| 673 | error = iqs5xx_write_byte(client, IQS5XX_SYS_CFG0, val); | ||
| 674 | if (error) | ||
| 675 | return error; | ||
| 676 | |||
| 677 | val = IQS5XX_TP_EVENT | IQS5XX_EVENT_MODE; | ||
| 678 | error = iqs5xx_write_byte(client, IQS5XX_SYS_CFG1, val); | ||
| 679 | if (error) | ||
| 680 | return error; | ||
| 681 | |||
| 682 | error = iqs5xx_write_byte(client, IQS5XX_END_COMM, 0); | ||
| 683 | if (error) | ||
| 684 | return error; | ||
| 685 | |||
| 686 | iqs5xx->bl_status = dev_id_info->bl_status; | ||
| 687 | |||
| 688 | /* | ||
| 689 | * Closure of the first communication window that appears following the | ||
| 690 | * release of reset appears to kick off an initialization period during | ||
| 691 | * which further communication is met with clock stretching. The return | ||
| 692 | * from this function is delayed so that further communication attempts | ||
| 693 | * avoid this period. | ||
| 694 | */ | ||
| 695 | msleep(100); | ||
| 696 | |||
| 697 | return 0; | ||
| 698 | } | ||
| 699 | |||
| 700 | static irqreturn_t iqs5xx_irq(int irq, void *data) | ||
| 701 | { | ||
| 702 | struct iqs5xx_private *iqs5xx = data; | ||
| 703 | struct iqs5xx_touch_data touch_data[IQS5XX_NUM_CONTACTS]; | ||
| 704 | struct i2c_client *client = iqs5xx->client; | ||
| 705 | struct input_dev *input = iqs5xx->input; | ||
| 706 | int error, i; | ||
| 707 | |||
| 708 | /* | ||
| 709 | * This check is purely a precaution, as the device does not assert the | ||
| 710 | * RDY output during bootloader mode. If the device operates outside of | ||
| 711 | * bootloader mode, the input device is guaranteed to be allocated. | ||
| 712 | */ | ||
| 713 | if (iqs5xx->bl_status == IQS5XX_BL_STATUS_RESET) | ||
| 714 | return IRQ_NONE; | ||
| 715 | |||
| 716 | error = iqs5xx_read_burst(client, IQS5XX_ABS_X, | ||
| 717 | touch_data, sizeof(touch_data)); | ||
| 718 | if (error) | ||
| 719 | return IRQ_NONE; | ||
| 720 | |||
| 721 | for (i = 0; i < ARRAY_SIZE(touch_data); i++) { | ||
| 722 | u16 pressure = be16_to_cpu(touch_data[i].strength); | ||
| 723 | |||
| 724 | input_mt_slot(input, i); | ||
| 725 | if (input_mt_report_slot_state(input, MT_TOOL_FINGER, | ||
| 726 | pressure != 0)) { | ||
| 727 | input_report_abs(input, ABS_MT_POSITION_X, | ||
| 728 | be16_to_cpu(touch_data[i].abs_x)); | ||
| 729 | input_report_abs(input, ABS_MT_POSITION_Y, | ||
| 730 | be16_to_cpu(touch_data[i].abs_y)); | ||
| 731 | input_report_abs(input, ABS_MT_PRESSURE, pressure); | ||
| 732 | } | ||
| 733 | } | ||
| 734 | |||
| 735 | input_mt_sync_frame(input); | ||
| 736 | input_sync(input); | ||
| 737 | |||
| 738 | error = iqs5xx_write_byte(client, IQS5XX_END_COMM, 0); | ||
| 739 | if (error) | ||
| 740 | return IRQ_NONE; | ||
| 741 | |||
| 742 | /* | ||
| 743 | * Once the communication window is closed, a small delay is added to | ||
| 744 | * ensure the device's RDY output has been deasserted by the time the | ||
| 745 | * interrupt handler returns. | ||
| 746 | */ | ||
| 747 | usleep_range(50, 100); | ||
| 748 | |||
| 749 | return IRQ_HANDLED; | ||
| 750 | } | ||
| 751 | |||
| 752 | static int iqs5xx_fw_file_parse(struct i2c_client *client, | ||
| 753 | const char *fw_file, u8 *pmap) | ||
| 754 | { | ||
| 755 | const struct firmware *fw; | ||
| 756 | struct iqs5xx_ihex_rec *rec; | ||
| 757 | size_t pos = 0; | ||
| 758 | int error, i; | ||
| 759 | u16 rec_num = 1; | ||
| 760 | u16 rec_addr; | ||
| 761 | u8 rec_len, rec_type, rec_chksm, chksm; | ||
| 762 | u8 rec_hdr[IQS5XX_REC_HDR_LEN]; | ||
| 763 | u8 rec_data[IQS5XX_REC_LEN_MAX]; | ||
| 764 | |||
| 765 | /* | ||
| 766 | * Firmware exported from the vendor's configuration tool deviates from | ||
| 767 | * standard ihex as follows: (1) the checksum for records corresponding | ||
| 768 | * to user-exported settings is not recalculated, and (2) an address of | ||
| 769 | * 0xFFFF is used for the EOF record. | ||
| 770 | * | ||
| 771 | * Because the ihex2fw tool tolerates neither (1) nor (2), the slightly | ||
| 772 | * nonstandard ihex firmware is parsed directly by the driver. | ||
| 773 | */ | ||
| 774 | error = request_firmware(&fw, fw_file, &client->dev); | ||
| 775 | if (error) { | ||
| 776 | dev_err(&client->dev, "Failed to request firmware %s: %d\n", | ||
| 777 | fw_file, error); | ||
| 778 | return error; | ||
| 779 | } | ||
| 780 | |||
| 781 | do { | ||
| 782 | if (pos + sizeof(*rec) > fw->size) { | ||
| 783 | dev_err(&client->dev, "Insufficient firmware size\n"); | ||
| 784 | error = -EINVAL; | ||
| 785 | break; | ||
| 786 | } | ||
| 787 | rec = (struct iqs5xx_ihex_rec *)(fw->data + pos); | ||
| 788 | pos += sizeof(*rec); | ||
| 789 | |||
| 790 | if (rec->start != ':') { | ||
| 791 | dev_err(&client->dev, "Invalid start at record %u\n", | ||
| 792 | rec_num); | ||
| 793 | error = -EINVAL; | ||
| 794 | break; | ||
| 795 | } | ||
| 796 | |||
| 797 | error = hex2bin(rec_hdr, rec->len, sizeof(rec_hdr)); | ||
| 798 | if (error) { | ||
| 799 | dev_err(&client->dev, "Invalid header at record %u\n", | ||
| 800 | rec_num); | ||
| 801 | break; | ||
| 802 | } | ||
| 803 | |||
| 804 | rec_len = *rec_hdr; | ||
| 805 | rec_addr = get_unaligned_be16(rec_hdr + sizeof(rec_len)); | ||
| 806 | rec_type = *(rec_hdr + sizeof(rec_len) + sizeof(rec_addr)); | ||
| 807 | |||
| 808 | if (pos + rec_len * 2 > fw->size) { | ||
| 809 | dev_err(&client->dev, "Insufficient firmware size\n"); | ||
| 810 | error = -EINVAL; | ||
| 811 | break; | ||
| 812 | } | ||
| 813 | pos += (rec_len * 2); | ||
| 814 | |||
| 815 | error = hex2bin(rec_data, rec->data, rec_len); | ||
| 816 | if (error) { | ||
| 817 | dev_err(&client->dev, "Invalid data at record %u\n", | ||
| 818 | rec_num); | ||
| 819 | break; | ||
| 820 | } | ||
| 821 | |||
| 822 | error = hex2bin(&rec_chksm, | ||
| 823 | rec->data + rec_len * 2, sizeof(rec_chksm)); | ||
| 824 | if (error) { | ||
| 825 | dev_err(&client->dev, "Invalid checksum at record %u\n", | ||
| 826 | rec_num); | ||
| 827 | break; | ||
| 828 | } | ||
| 829 | |||
| 830 | chksm = 0; | ||
| 831 | for (i = 0; i < sizeof(rec_hdr); i++) | ||
| 832 | chksm += rec_hdr[i]; | ||
| 833 | for (i = 0; i < rec_len; i++) | ||
| 834 | chksm += rec_data[i]; | ||
| 835 | chksm = ~chksm + 1; | ||
| 836 | |||
| 837 | if (chksm != rec_chksm && rec_addr < IQS5XX_CSTM) { | ||
| 838 | dev_err(&client->dev, | ||
| 839 | "Incorrect checksum at record %u\n", | ||
| 840 | rec_num); | ||
| 841 | error = -EINVAL; | ||
| 842 | break; | ||
| 843 | } | ||
| 844 | |||
| 845 | switch (rec_type) { | ||
| 846 | case IQS5XX_REC_TYPE_DATA: | ||
| 847 | if (rec_addr < IQS5XX_CHKSM || | ||
| 848 | rec_addr > IQS5XX_PMAP_END) { | ||
| 849 | dev_err(&client->dev, | ||
| 850 | "Invalid address at record %u\n", | ||
| 851 | rec_num); | ||
| 852 | error = -EINVAL; | ||
| 853 | } else { | ||
| 854 | memcpy(pmap + rec_addr - IQS5XX_CHKSM, | ||
| 855 | rec_data, rec_len); | ||
| 856 | } | ||
| 857 | break; | ||
| 858 | case IQS5XX_REC_TYPE_EOF: | ||
| 859 | break; | ||
| 860 | default: | ||
| 861 | dev_err(&client->dev, "Invalid type at record %u\n", | ||
| 862 | rec_num); | ||
| 863 | error = -EINVAL; | ||
| 864 | } | ||
| 865 | |||
| 866 | if (error) | ||
| 867 | break; | ||
| 868 | |||
| 869 | rec_num++; | ||
| 870 | while (pos < fw->size) { | ||
| 871 | if (*(fw->data + pos) == ':') | ||
| 872 | break; | ||
| 873 | pos++; | ||
| 874 | } | ||
| 875 | } while (rec_type != IQS5XX_REC_TYPE_EOF); | ||
| 876 | |||
| 877 | release_firmware(fw); | ||
| 878 | |||
| 879 | return error; | ||
| 880 | } | ||
| 881 | |||
| 882 | static int iqs5xx_fw_file_write(struct i2c_client *client, const char *fw_file) | ||
| 883 | { | ||
| 884 | struct iqs5xx_private *iqs5xx = i2c_get_clientdata(client); | ||
| 885 | int error; | ||
| 886 | u8 *pmap; | ||
| 887 | |||
| 888 | if (iqs5xx->bl_status == IQS5XX_BL_STATUS_NONE) | ||
| 889 | return -EPERM; | ||
| 890 | |||
| 891 | pmap = kzalloc(IQS5XX_PMAP_LEN, GFP_KERNEL); | ||
| 892 | if (!pmap) | ||
| 893 | return -ENOMEM; | ||
| 894 | |||
| 895 | error = iqs5xx_fw_file_parse(client, fw_file, pmap); | ||
| 896 | if (error) | ||
| 897 | goto err_kfree; | ||
| 898 | |||
| 899 | mutex_lock(&iqs5xx->lock); | ||
| 900 | |||
| 901 | /* | ||
| 902 | * Disable the interrupt line in case the first attempt(s) to enter the | ||
| 903 | * bootloader don't happen quickly enough, in which case the device may | ||
| 904 | * assert the RDY output until the next attempt. | ||
| 905 | */ | ||
| 906 | disable_irq(client->irq); | ||
| 907 | |||
| 908 | iqs5xx->bl_status = IQS5XX_BL_STATUS_RESET; | ||
| 909 | |||
| 910 | error = iqs5xx_bl_cmd(client, IQS5XX_BL_CMD_VER, 0); | ||
| 911 | if (error) { | ||
| 912 | error = iqs5xx_bl_open(client); | ||
| 913 | if (error) | ||
| 914 | goto err_reset; | ||
| 915 | } | ||
| 916 | |||
| 917 | error = iqs5xx_bl_write(client, IQS5XX_CHKSM, pmap, IQS5XX_PMAP_LEN); | ||
| 918 | if (error) | ||
| 919 | goto err_reset; | ||
| 920 | |||
| 921 | error = iqs5xx_bl_cmd(client, IQS5XX_BL_CMD_CRC, 0); | ||
| 922 | if (error) | ||
| 923 | goto err_reset; | ||
| 924 | |||
| 925 | error = iqs5xx_bl_verify(client, IQS5XX_CSTM, | ||
| 926 | pmap + IQS5XX_CHKSM_LEN + IQS5XX_APP_LEN, | ||
| 927 | IQS5XX_CSTM_LEN); | ||
| 928 | if (error) | ||
| 929 | goto err_reset; | ||
| 930 | |||
| 931 | error = iqs5xx_bl_cmd(client, IQS5XX_BL_CMD_EXEC, 0); | ||
| 932 | |||
| 933 | err_reset: | ||
| 934 | if (error) { | ||
| 935 | iqs5xx_reset(client); | ||
| 936 | usleep_range(10000, 10100); | ||
| 937 | } | ||
| 938 | |||
| 939 | error = iqs5xx_dev_init(client); | ||
| 940 | if (!error && iqs5xx->bl_status == IQS5XX_BL_STATUS_RESET) | ||
| 941 | error = -EINVAL; | ||
| 942 | |||
| 943 | enable_irq(client->irq); | ||
| 944 | |||
| 945 | mutex_unlock(&iqs5xx->lock); | ||
| 946 | |||
| 947 | err_kfree: | ||
| 948 | kfree(pmap); | ||
| 949 | |||
| 950 | return error; | ||
| 951 | } | ||
| 952 | |||
| 953 | static ssize_t fw_file_store(struct device *dev, struct device_attribute *attr, | ||
| 954 | const char *buf, size_t count) | ||
| 955 | { | ||
| 956 | struct iqs5xx_private *iqs5xx = dev_get_drvdata(dev); | ||
| 957 | struct i2c_client *client = iqs5xx->client; | ||
| 958 | size_t len = count; | ||
| 959 | bool input_reg = !iqs5xx->input; | ||
| 960 | char fw_file[IQS5XX_FW_FILE_LEN + 1]; | ||
| 961 | int error; | ||
| 962 | |||
| 963 | if (!len) | ||
| 964 | return -EINVAL; | ||
| 965 | |||
| 966 | if (buf[len - 1] == '\n') | ||
| 967 | len--; | ||
| 968 | |||
| 969 | if (len > IQS5XX_FW_FILE_LEN) | ||
| 970 | return -ENAMETOOLONG; | ||
| 971 | |||
| 972 | memcpy(fw_file, buf, len); | ||
| 973 | fw_file[len] = '\0'; | ||
| 974 | |||
| 975 | error = iqs5xx_fw_file_write(client, fw_file); | ||
| 976 | if (error) | ||
| 977 | return error; | ||
| 978 | |||
| 979 | /* | ||
| 980 | * If the input device was not allocated already, it is guaranteed to | ||
| 981 | * be allocated by this point and can finally be registered. | ||
| 982 | */ | ||
| 983 | if (input_reg) { | ||
| 984 | error = input_register_device(iqs5xx->input); | ||
| 985 | if (error) { | ||
| 986 | dev_err(&client->dev, | ||
| 987 | "Failed to register device: %d\n", | ||
| 988 | error); | ||
| 989 | return error; | ||
| 990 | } | ||
| 991 | } | ||
| 992 | |||
| 993 | return count; | ||
| 994 | } | ||
| 995 | |||
| 996 | static DEVICE_ATTR_WO(fw_file); | ||
| 997 | |||
| 998 | static struct attribute *iqs5xx_attrs[] = { | ||
| 999 | &dev_attr_fw_file.attr, | ||
| 1000 | NULL, | ||
| 1001 | }; | ||
| 1002 | |||
| 1003 | static const struct attribute_group iqs5xx_attr_group = { | ||
| 1004 | .attrs = iqs5xx_attrs, | ||
| 1005 | }; | ||
| 1006 | |||
| 1007 | static int __maybe_unused iqs5xx_suspend(struct device *dev) | ||
| 1008 | { | ||
| 1009 | struct iqs5xx_private *iqs5xx = dev_get_drvdata(dev); | ||
| 1010 | struct input_dev *input = iqs5xx->input; | ||
| 1011 | int error = 0; | ||
| 1012 | |||
| 1013 | if (!input) | ||
| 1014 | return error; | ||
| 1015 | |||
| 1016 | mutex_lock(&input->mutex); | ||
| 1017 | |||
| 1018 | if (input->users) | ||
| 1019 | error = iqs5xx_set_state(iqs5xx->client, IQS5XX_SUSPEND); | ||
| 1020 | |||
| 1021 | mutex_unlock(&input->mutex); | ||
| 1022 | |||
| 1023 | return error; | ||
| 1024 | } | ||
| 1025 | |||
| 1026 | static int __maybe_unused iqs5xx_resume(struct device *dev) | ||
| 1027 | { | ||
| 1028 | struct iqs5xx_private *iqs5xx = dev_get_drvdata(dev); | ||
| 1029 | struct input_dev *input = iqs5xx->input; | ||
| 1030 | int error = 0; | ||
| 1031 | |||
| 1032 | if (!input) | ||
| 1033 | return error; | ||
| 1034 | |||
| 1035 | mutex_lock(&input->mutex); | ||
| 1036 | |||
| 1037 | if (input->users) | ||
| 1038 | error = iqs5xx_set_state(iqs5xx->client, IQS5XX_RESUME); | ||
| 1039 | |||
| 1040 | mutex_unlock(&input->mutex); | ||
| 1041 | |||
| 1042 | return error; | ||
| 1043 | } | ||
| 1044 | |||
| 1045 | static SIMPLE_DEV_PM_OPS(iqs5xx_pm, iqs5xx_suspend, iqs5xx_resume); | ||
| 1046 | |||
| 1047 | static int iqs5xx_probe(struct i2c_client *client, | ||
| 1048 | const struct i2c_device_id *id) | ||
| 1049 | { | ||
| 1050 | struct iqs5xx_private *iqs5xx; | ||
| 1051 | int error; | ||
| 1052 | |||
| 1053 | iqs5xx = devm_kzalloc(&client->dev, sizeof(*iqs5xx), GFP_KERNEL); | ||
| 1054 | if (!iqs5xx) | ||
| 1055 | return -ENOMEM; | ||
| 1056 | |||
| 1057 | dev_set_drvdata(&client->dev, iqs5xx); | ||
| 1058 | |||
| 1059 | i2c_set_clientdata(client, iqs5xx); | ||
| 1060 | iqs5xx->client = client; | ||
| 1061 | |||
| 1062 | iqs5xx->reset_gpio = devm_gpiod_get(&client->dev, | ||
| 1063 | "reset", GPIOD_OUT_LOW); | ||
| 1064 | if (IS_ERR(iqs5xx->reset_gpio)) { | ||
| 1065 | error = PTR_ERR(iqs5xx->reset_gpio); | ||
| 1066 | dev_err(&client->dev, "Failed to request GPIO: %d\n", error); | ||
| 1067 | return error; | ||
| 1068 | } | ||
| 1069 | |||
| 1070 | mutex_init(&iqs5xx->lock); | ||
| 1071 | |||
| 1072 | iqs5xx_reset(client); | ||
| 1073 | usleep_range(10000, 10100); | ||
| 1074 | |||
| 1075 | error = iqs5xx_dev_init(client); | ||
| 1076 | if (error) | ||
| 1077 | return error; | ||
| 1078 | |||
| 1079 | error = devm_request_threaded_irq(&client->dev, client->irq, | ||
| 1080 | NULL, iqs5xx_irq, IRQF_ONESHOT, | ||
| 1081 | client->name, iqs5xx); | ||
| 1082 | if (error) { | ||
| 1083 | dev_err(&client->dev, "Failed to request IRQ: %d\n", error); | ||
| 1084 | return error; | ||
| 1085 | } | ||
| 1086 | |||
| 1087 | error = devm_device_add_group(&client->dev, &iqs5xx_attr_group); | ||
| 1088 | if (error) { | ||
| 1089 | dev_err(&client->dev, "Failed to add attributes: %d\n", error); | ||
| 1090 | return error; | ||
| 1091 | } | ||
| 1092 | |||
| 1093 | if (iqs5xx->input) { | ||
| 1094 | error = input_register_device(iqs5xx->input); | ||
| 1095 | if (error) | ||
| 1096 | dev_err(&client->dev, | ||
| 1097 | "Failed to register device: %d\n", | ||
| 1098 | error); | ||
| 1099 | } | ||
| 1100 | |||
| 1101 | return error; | ||
| 1102 | } | ||
| 1103 | |||
| 1104 | static const struct i2c_device_id iqs5xx_id[] = { | ||
| 1105 | { "iqs550", 0 }, | ||
| 1106 | { "iqs572", 1 }, | ||
| 1107 | { "iqs525", 2 }, | ||
| 1108 | { } | ||
| 1109 | }; | ||
| 1110 | MODULE_DEVICE_TABLE(i2c, iqs5xx_id); | ||
| 1111 | |||
| 1112 | static const struct of_device_id iqs5xx_of_match[] = { | ||
| 1113 | { .compatible = "azoteq,iqs550" }, | ||
| 1114 | { .compatible = "azoteq,iqs572" }, | ||
| 1115 | { .compatible = "azoteq,iqs525" }, | ||
| 1116 | { } | ||
| 1117 | }; | ||
| 1118 | MODULE_DEVICE_TABLE(of, iqs5xx_of_match); | ||
| 1119 | |||
| 1120 | static struct i2c_driver iqs5xx_i2c_driver = { | ||
| 1121 | .driver = { | ||
| 1122 | .name = "iqs5xx", | ||
| 1123 | .of_match_table = iqs5xx_of_match, | ||
| 1124 | .pm = &iqs5xx_pm, | ||
| 1125 | }, | ||
| 1126 | .id_table = iqs5xx_id, | ||
| 1127 | .probe = iqs5xx_probe, | ||
| 1128 | }; | ||
| 1129 | module_i2c_driver(iqs5xx_i2c_driver); | ||
| 1130 | |||
| 1131 | MODULE_AUTHOR("Jeff LaBundy <jeff@labundy.com>"); | ||
| 1132 | MODULE_DESCRIPTION("Azoteq IQS550/572/525 Trackpad/Touchscreen Controller"); | ||
| 1133 | MODULE_LICENSE("GPL"); | ||
diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h index bc5054e51bef..4badaff0f548 100644 --- a/include/uapi/linux/input-event-codes.h +++ b/include/uapi/linux/input-event-codes.h | |||
| @@ -606,6 +606,7 @@ | |||
| 606 | #define KEY_SCREENSAVER 0x245 /* AL Screen Saver */ | 606 | #define KEY_SCREENSAVER 0x245 /* AL Screen Saver */ |
| 607 | #define KEY_VOICECOMMAND 0x246 /* Listening Voice Command */ | 607 | #define KEY_VOICECOMMAND 0x246 /* Listening Voice Command */ |
| 608 | #define KEY_ASSISTANT 0x247 /* AL Context-aware desktop assistant */ | 608 | #define KEY_ASSISTANT 0x247 /* AL Context-aware desktop assistant */ |
| 609 | #define KEY_KBD_LAYOUT_NEXT 0x248 /* AC Next Keyboard Layout Select */ | ||
| 609 | 610 | ||
| 610 | #define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */ | 611 | #define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */ |
| 611 | #define KEY_BRIGHTNESS_MAX 0x251 /* Set Brightness to Maximum */ | 612 | #define KEY_BRIGHTNESS_MAX 0x251 /* Set Brightness to Maximum */ |
