diff --git a/Documentation/devicetree/bindings/input/elants_i2c.txt b/Documentation/devicetree/bindings/input/elants_i2c.txt
deleted file mode 100644
index 5edac8be08028046c3f7ebb93eae8d6fea5b6927..0000000000000000000000000000000000000000
--- a/Documentation/devicetree/bindings/input/elants_i2c.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-Elantech I2C Touchscreen
-
-Required properties:
-- compatible: must be "elan,ekth3500".
-- reg: I2C address of the chip.
-- interrupts: interrupt to which the chip is connected (see interrupt
-  binding[0]).
-
-Optional properties:
-- wakeup-source: touchscreen can be used as a wakeup source.
-- pinctrl-names: should be "default" (see pinctrl binding [1]).
-- pinctrl-0: a phandle pointing to the pin settings for the device (see
-  pinctrl binding [1]).
-- reset-gpios: reset gpio the chip is connected to.
-- vcc33-supply: a phandle for the regulator supplying 3.3V power.
-- vccio-supply: a phandle for the regulator supplying IO power.
-
-[0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
-[1]: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
-
-Example:
-	&i2c1 {
-		/* ... */
-
-		touchscreen@10 {
-			compatible = "elan,ekth3500";
-			reg = <0x10>;
-			interrupt-parent = <&gpio4>;
-			interrupts = <0x0 IRQ_TYPE_EDGE_FALLING>;
-			wakeup-source;
-		};
-
-		/* ... */
-	};
diff --git a/Documentation/devicetree/bindings/input/iqs269a.yaml b/Documentation/devicetree/bindings/input/iqs269a.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..f0242bb4be81d24bd10de67eb7c1c49541ad78c2
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/iqs269a.yaml
@@ -0,0 +1,581 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/iqs269a.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Azoteq IQS269A Capacitive Touch Controller
+
+maintainers:
+  - Jeff LaBundy <jeff@labundy.com>
+
+description: |
+  The Azoteq IQS269A is an 8-channel capacitive touch controller that features
+  additional Hall-effect and inductive sensing capabilities.
+
+  Link to datasheet: https://www.azoteq.com/
+
+properties:
+  compatible:
+    const: azoteq,iqs269a
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 0
+
+  azoteq,hall-enable:
+    type: boolean
+    description:
+      Enables Hall-effect sensing on channels 6 and 7. In this case, keycodes
+      assigned to channel 6 are ignored and keycodes assigned to channel 7 are
+      interpreted as switch codes. Refer to the datasheet for requirements im-
+      posed on channels 6 and 7 by Hall-effect sensing.
+
+  azoteq,suspend-mode:
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - enum: [0, 1, 2, 3]
+        default: 0
+    description: |
+      Specifies the power mode during suspend as follows:
+      0: Automatic (same as normal runtime, i.e. suspend/resume disabled)
+      1: Low power (all sensing at a reduced reporting rate)
+      2: Ultra-low power (channel 0 proximity sensing)
+      3: Halt (no sensing)
+
+  azoteq,clk-div:
+    type: boolean
+    description: Divides the device's core clock by a factor of 4.
+
+  azoteq,ulp-update:
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - minimum: 0
+        maximum: 7
+        default: 3
+    description: Specifies the ultra-low-power mode update rate.
+
+  azoteq,reseed-offset:
+    type: boolean
+    description:
+      Applies an 8-count offset to all long-term averages upon either ATI or
+      reseed events.
+
+  azoteq,filt-str-lp-lta:
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - enum: [0, 1, 2, 3]
+        default: 0
+    description:
+      Specifies the long-term average filter strength during low-power mode.
+
+  azoteq,filt-str-lp-cnt:
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - enum: [0, 1, 2, 3]
+        default: 0
+    description:
+      Specifies the raw count filter strength during low-power mode.
+
+  azoteq,filt-str-np-lta:
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - enum: [0, 1, 2, 3]
+        default: 0
+    description:
+      Specifies the long-term average filter strength during normal-power mode.
+
+  azoteq,filt-str-np-cnt:
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - enum: [0, 1, 2, 3]
+        default: 0
+    description:
+      Specifies the raw count filter strength during normal-power mode.
+
+  azoteq,rate-np-ms:
+    minimum: 0
+    maximum: 255
+    default: 16
+    description: Specifies the report rate (in ms) during normal-power mode.
+
+  azoteq,rate-lp-ms:
+    minimum: 0
+    maximum: 255
+    default: 160
+    description: Specifies the report rate (in ms) during low-power mode.
+
+  azoteq,rate-ulp-ms:
+    multipleOf: 16
+    minimum: 0
+    maximum: 4080
+    default: 160
+    description: Specifies the report rate (in ms) during ultra-low-power mode.
+
+  azoteq,timeout-pwr-ms:
+    multipleOf: 512
+    minimum: 0
+    maximum: 130560
+    default: 2560
+    description:
+      Specifies the length of time (in ms) to wait for an event during normal-
+      power mode before transitioning to low-power mode.
+
+  azoteq,timeout-lta-ms:
+    multipleOf: 512
+    minimum: 0
+    maximum: 130560
+    default: 32768
+    description:
+      Specifies the length of time (in ms) to wait before resetting the long-
+      term average of all channels. Specify the maximum timeout to disable it
+      altogether.
+
+  azoteq,ati-band-disable:
+    type: boolean
+    description: Disables the ATI band check.
+
+  azoteq,ati-lp-only:
+    type: boolean
+    description: Limits automatic ATI to low-power mode.
+
+  azoteq,ati-band-tighten:
+    type: boolean
+    description: Tightens the ATI band from 1/8 to 1/16 of the desired target.
+
+  azoteq,filt-disable:
+    type: boolean
+    description: Disables all raw count filtering.
+
+  azoteq,gpio3-select:
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - minimum: 0
+        maximum: 7
+        default: 0
+    description:
+      Selects the channel for which the GPIO3 pin represents touch state.
+
+  azoteq,dual-direction:
+    type: boolean
+    description:
+      Specifies that long-term averages are to freeze in the presence of either
+      increasing or decreasing counts, thereby permitting events to be reported
+      in either direction.
+
+  azoteq,tx-freq:
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - enum: [0, 1, 2, 3]
+        default: 0
+    description: |
+      Specifies the inductive sensing excitation frequency as follows (paren-
+      thesized numbers represent the frequency if 'azoteq,clk-div' is present):
+      0: 16 MHz (4 MHz)
+      1: 8 MHz (2 MHz)
+      2: 4 MHz (1 MHz)
+      3: 2 MHz (500 kHz)
+
+  azoteq,global-cap-increase:
+    type: boolean
+    description: Increases the global capacitance adder from 0.5 pF to 1.5 pF.
+
+  azoteq,reseed-select:
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - enum: [0, 1, 2, 3]
+        default: 0
+    description: |
+      Specifies the event(s) that prompt the device to reseed (i.e. reset the
+      long-term average) of an associated channel as follows:
+      0: None
+      1: Proximity
+      2: Proximity or touch
+      3: Proximity, touch or deep touch
+
+  azoteq,tracking-enable:
+    type: boolean
+    description:
+      Enables all associated channels to track their respective reference
+      channels.
+
+  azoteq,filt-str-slider:
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - enum: [0, 1, 2, 3]
+        default: 1
+    description: Specifies the slider coordinate filter strength.
+
+patternProperties:
+  "^channel@[0-7]$":
+    type: object
+    description:
+      Represents a single sensing channel. A channel is active if defined and
+      inactive otherwise.
+
+    properties:
+      reg:
+        minimum: 0
+        maximum: 7
+        description: Index of the channel.
+
+      azoteq,reseed-disable:
+        type: boolean
+        description:
+          Prevents the channel from being reseeded if the long-term average
+          timeout (defined in 'azoteq,timeout-lta') expires.
+
+      azoteq,blocking-enable:
+        type: boolean
+        description: Specifies that the channel is a blocking channel.
+
+      azoteq,slider0-select:
+        type: boolean
+        description: Specifies that the channel participates in slider 0.
+
+      azoteq,slider1-select:
+        type: boolean
+        description: Specifies that the channel participates in slider 1.
+
+      azoteq,rx-enable:
+        allOf:
+          - $ref: /schemas/types.yaml#/definitions/uint32-array
+          - minItems: 1
+            maxItems: 8
+            items:
+              minimum: 0
+              maximum: 7
+        description:
+          Specifies the CRX pin(s) associated with the channel. By default, only
+          the CRX pin corresponding to the channel's index is enabled (e.g. CRX0
+          for channel 0).
+
+      azoteq,tx-enable:
+        allOf:
+          - $ref: /schemas/types.yaml#/definitions/uint32-array
+          - minItems: 1
+            maxItems: 8
+            items:
+              minimum: 0
+              maximum: 7
+            default: [0, 1, 2, 3, 4, 5, 6, 7]
+        description: Specifies the TX pin(s) associated with the channel.
+
+      azoteq,meas-cap-decrease:
+        type: boolean
+        description:
+          Decreases the internal measurement capacitance from 60 pF to 15 pF.
+
+      azoteq,rx-float-inactive:
+        type: boolean
+        description: Floats any inactive CRX pins instead of grounding them.
+
+      azoteq,local-cap-size:
+        allOf:
+          - $ref: /schemas/types.yaml#/definitions/uint32
+          - enum: [0, 1, 2]
+            default: 0
+        description: |
+          Specifies the capacitance to be added to the channel as follows:
+          0: None
+          1: Global adder (based on 'azoteq,global-cap-increase')
+          2: Global adder + 0.5 pF
+
+      azoteq,invert-enable:
+        type: boolean
+        description:
+          Inverts the polarity of the states reported for proximity, touch and
+          deep-touch events relative to their respective thresholds.
+
+      azoteq,proj-bias:
+        allOf:
+          - $ref: /schemas/types.yaml#/definitions/uint32
+          - enum: [0, 1, 2, 3]
+            default: 2
+        description: |
+          Specifies the bias current applied during projected-capacitance
+          sensing as follows:
+          0: 2.5 uA
+          1: 5 uA
+          2: 10 uA
+          3: 20 uA
+
+      azoteq,sense-mode:
+        allOf:
+          - $ref: /schemas/types.yaml#/definitions/uint32
+          - enum: [0, 1, 9, 14, 15]
+            default: 0
+        description: |
+          Specifies the channel's sensing mode as follows:
+          0:  Self capacitance
+          1:  Projected capacitance
+          9:  Self or mutual inductance
+          14: Hall effect
+          15: Temperature
+
+      azoteq,sense-freq:
+        allOf:
+          - $ref: /schemas/types.yaml#/definitions/uint32
+          - enum: [0, 1, 2, 3]
+            default: 1
+        description: |
+          Specifies the channel's sensing frequency as follows (parenthesized
+          numbers represent the frequency if 'azoteq,clk-div' is present):
+          0: 4 MHz (1 MHz)
+          1: 2 MHz (500 kHz)
+          2: 1 MHz (250 kHz)
+          3: 500 kHz (125 kHz)
+
+      azoteq,static-enable:
+        type: boolean
+        description: Enables the static front-end for the channel.
+
+      azoteq,ati-mode:
+        allOf:
+          - $ref: /schemas/types.yaml#/definitions/uint32
+          - enum: [0, 1, 2, 3]
+            default: 3
+        description: |
+          Specifies the channel's ATI mode as follows:
+          0: Disabled
+          1: Semi-partial
+          2: Partial
+          3: Full
+
+      azoteq,ati-base:
+        allOf:
+          - $ref: /schemas/types.yaml#/definitions/uint32
+          - enum: [75, 100, 150, 200]
+            default: 100
+        description: Specifies the channel's ATI base.
+
+      azoteq,ati-target:
+        allOf:
+          - $ref: /schemas/types.yaml#/definitions/uint32
+          - multipleOf: 32
+            minimum: 0
+            maximum: 2016
+            default: 512
+        description: Specifies the channel's ATI target.
+
+      azoteq,assoc-select:
+        allOf:
+          - $ref: /schemas/types.yaml#/definitions/uint32-array
+          - minItems: 1
+            maxItems: 8
+            items:
+              minimum: 0
+              maximum: 7
+        description:
+          Specifies the associated channels for which the channel serves as a
+          reference channel. By default, no channels are selected.
+
+      azoteq,assoc-weight:
+        allOf:
+          - $ref: /schemas/types.yaml#/definitions/uint32
+          - minimum: 0
+            maximum: 255
+            default: 0
+        description:
+          Specifies the channel's impact weight if it acts as an associated
+          channel (0 = 0% impact, 255 = 200% impact).
+
+    patternProperties:
+      "^event-prox(-alt)?$":
+        type: object
+        description:
+          Represents a proximity event reported by the channel in response to
+          a decrease in counts. Node names suffixed with '-alt' instead corre-
+          spond to an increase in counts.
+
+          By default, the long-term average tracks an increase in counts such
+          that only events corresponding to a decrease in counts are reported
+          (refer to the datasheet for more information).
+
+          Specify 'azoteq,dual-direction' to freeze the long-term average when
+          the counts increase or decrease such that events of either direction
+          can be reported. Alternatively, specify 'azoteq,invert-enable' to in-
+          vert the polarity of the states reported by the channel.
+
+          Complementary events (e.g. event-touch and event-touch-alt) can both
+          be present and specify different key or switch codes, but not differ-
+          ent thresholds or hysteresis (if applicable).
+
+        properties:
+          azoteq,thresh:
+            allOf:
+              - $ref: /schemas/types.yaml#/definitions/uint32
+              - minimum: 0
+                maximum: 255
+                default: 10
+            description: Specifies the threshold for the event.
+
+          linux,code:
+            $ref: /schemas/types.yaml#/definitions/uint32
+            description: Numeric key or switch code associated with the event.
+
+        additionalProperties: false
+
+      "^event-touch(-alt)?$":
+        type: object
+        description: Represents a touch event reported by the channel.
+
+        properties:
+          azoteq,thresh:
+            allOf:
+              - $ref: /schemas/types.yaml#/definitions/uint32
+              - minimum: 0
+                maximum: 255
+                default: 8
+            description: Specifies the threshold for the event.
+
+          azoteq,hyst:
+            allOf:
+              - $ref: /schemas/types.yaml#/definitions/uint32
+              - minimum: 0
+                maximum: 15
+                default: 4
+            description: Specifies the hysteresis for the event.
+
+          linux,code:
+            $ref: /schemas/types.yaml#/definitions/uint32
+            description: Numeric key or switch code associated with the event.
+
+        additionalProperties: false
+
+      "^event-deep(-alt)?$":
+        type: object
+        description: Represents a deep-touch event reported by the channel.
+
+        properties:
+          azoteq,thresh:
+            allOf:
+              - $ref: /schemas/types.yaml#/definitions/uint32
+              - minimum: 0
+                maximum: 255
+                default: 26
+            description: Specifies the threshold for the event.
+
+          azoteq,hyst:
+            allOf:
+              - $ref: /schemas/types.yaml#/definitions/uint32
+              - minimum: 0
+                maximum: 15
+                default: 0
+            description: Specifies the hysteresis for the event.
+
+          linux,code:
+            $ref: /schemas/types.yaml#/definitions/uint32
+            description: Numeric key or switch code associated with the event.
+
+        additionalProperties: false
+
+    required:
+      - reg
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - "#address-cells"
+  - "#size-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/input/input.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    i2c {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            iqs269a@44 {
+                    #address-cells = <1>;
+                    #size-cells = <0>;
+
+                    compatible = "azoteq,iqs269a";
+                    reg = <0x44>;
+                    interrupt-parent = <&gpio>;
+                    interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
+
+                    azoteq,hall-enable;
+                    azoteq,suspend-mode = <2>;
+
+                    channel@0 {
+                            reg = <0x0>;
+
+                            event-prox {
+                                    linux,code = <KEY_POWER>;
+                            };
+                    };
+
+                    channel@1 {
+                            reg = <0x1>;
+                            azoteq,slider0-select;
+                    };
+
+                    channel@2 {
+                            reg = <0x2>;
+                            azoteq,slider0-select;
+                    };
+
+                    channel@3 {
+                            reg = <0x3>;
+                            azoteq,slider0-select;
+                    };
+
+                    channel@4 {
+                            reg = <0x4>;
+                            azoteq,slider0-select;
+                    };
+
+                    channel@5 {
+                            reg = <0x5>;
+                            azoteq,slider0-select;
+                    };
+
+                    channel@6 {
+                            reg = <0x6>;
+                            azoteq,invert-enable;
+                            azoteq,static-enable;
+                            azoteq,reseed-disable;
+                            azoteq,rx-enable = <0>;
+                            azoteq,sense-freq = <0x0>;
+                            azoteq,sense-mode = <0xE>;
+                            azoteq,ati-mode = <0x0>;
+                            azoteq,ati-base = <200>;
+                            azoteq,ati-target = <320>;
+                    };
+
+                    channel@7 {
+                            reg = <0x7>;
+                            azoteq,invert-enable;
+                            azoteq,static-enable;
+                            azoteq,reseed-disable;
+                            azoteq,rx-enable = <0>, <6>;
+                            azoteq,sense-freq = <0x0>;
+                            azoteq,sense-mode = <0xE>;
+                            azoteq,ati-mode = <0x3>;
+                            azoteq,ati-base = <200>;
+                            azoteq,ati-target = <320>;
+
+                            event-touch {
+                                    linux,code = <SW_LID>;
+                            };
+                    };
+            };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/input/msm-vibrator.txt b/Documentation/devicetree/bindings/input/msm-vibrator.txt
deleted file mode 100644
index 8dcf014ef2e57fb9c66b5b4af60a8880851d9914..0000000000000000000000000000000000000000
--- a/Documentation/devicetree/bindings/input/msm-vibrator.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-* Device tree bindings for the Qualcomm MSM vibrator
-
-Required properties:
-
-  - compatible: Should be one of
-		"qcom,msm8226-vibrator"
-		"qcom,msm8974-vibrator"
-  - reg: the base address and length of the IO memory for the registers.
-  - pinctrl-names: set to default.
-  - pinctrl-0: phandles pointing to pin configuration nodes. See
-               Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
-  - clock-names: set to pwm
-  - clocks: phandle of the clock. See
-            Documentation/devicetree/bindings/clock/clock-bindings.txt
-  - enable-gpios: GPIO that enables the vibrator.
-
-Optional properties:
-
-  - vcc-supply: phandle to the regulator that provides power to the sensor.
-
-Example from a LG Nexus 5 (hammerhead) phone:
-
-vibrator@fd8c3450 {
-	reg = <0xfd8c3450 0x400>;
-	compatible = "qcom,msm8974-vibrator";
-
-	vcc-supply = <&pm8941_l19>;
-
-	clocks = <&mmcc CAMSS_GP1_CLK>;
-	clock-names = "pwm";
-
-	enable-gpios = <&msmgpio 60 GPIO_ACTIVE_HIGH>;
-
-	pinctrl-names = "default";
-	pinctrl-0 = <&vibrator_pin>;
-};
diff --git a/Documentation/devicetree/bindings/input/touchscreen/cypress,cy8ctma140.yaml b/Documentation/devicetree/bindings/input/touchscreen/cypress,cy8ctma140.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..8c73e52643124df645da10bc6a1cd65fbef3b430
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/cypress,cy8ctma140.yaml
@@ -0,0 +1,72 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/touchscreen/cypress,cy8ctma140.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Cypress CY8CTMA140 series touchscreen controller bindings
+
+maintainers:
+  - Linus Walleij <linus.walleij@linaro.org>
+
+allOf:
+  - $ref: touchscreen.yaml#
+
+properties:
+  compatible:
+    const: cypress,cy8ctma140
+
+  reg:
+    const: 0x20
+
+  clock-frequency:
+    description: I2C client clock frequency, defined for host
+    minimum: 100000
+    maximum: 400000
+
+  interrupts:
+    maxItems: 1
+
+  vcpin-supply:
+    description: Analog power supply regulator on VCPIN pin
+
+  vdd-supply:
+    description: Digital power supply regulator on VDD pin
+
+  touchscreen-inverted-x: true
+  touchscreen-inverted-y: true
+  touchscreen-size-x: true
+  touchscreen-size-y: true
+  touchscreen-swapped-x-y: true
+  touchscreen-max-pressure: true
+
+additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - touchscreen-size-x
+  - touchscreen-size-y
+  - touchscreen-max-pressure
+
+examples:
+- |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    i2c {
+      #address-cells = <1>;
+      #size-cells = <0>;
+      touchscreen@20 {
+        compatible = "cypress,cy8ctma140";
+        reg = <0x20>;
+        touchscreen-size-x = <480>;
+        touchscreen-size-y = <800>;
+        touchscreen-max-pressure = <255>;
+        interrupt-parent = <&gpio6>;
+        interrupts = <26 IRQ_TYPE_EDGE_FALLING>;
+        vdd-supply = <&ab8500_ldo_aux2_reg>;
+        vcpin-supply = <&ab8500_ldo_aux2_reg>;
+      };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/input/touchscreen/elan,elants_i2c.yaml b/Documentation/devicetree/bindings/input/touchscreen/elan,elants_i2c.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..a792d6377b1daf08e4d38dcf4c84343ce5013350
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/elan,elants_i2c.yaml
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/input/touchscreen/elan,elants_i2c.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Elantech I2C Touchscreen
+
+maintainers:
+  - David Heidelberg <david@ixit.cz>
+
+allOf:
+  - $ref: touchscreen.yaml#
+
+properties:
+  compatible:
+    enum:
+      - elan,ektf3624
+      - elan,ekth3500
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  wakeup-source:
+    type: boolean
+    description: touchscreen can be used as a wakeup source.
+
+  reset-gpios:
+    description: reset gpio the chip is connected to.
+
+  vcc33-supply:
+    description: a phandle for the regulator supplying 3.3V power.
+
+  vccio-supply:
+    description: a phandle for the regulator supplying IO power.
+
+  touchscreen-inverted-x: true
+  touchscreen-inverted-y: true
+  touchscreen-size-x: true
+  touchscreen-size-y: true
+  touchscreen-swapped-x-y: true
+
+additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        touchscreen@10 {
+            compatible = "elan,ekth3500";
+            reg = <0x10>;
+
+            interrupt-parent = <&gpio4>;
+            interrupts = <0x0 IRQ_TYPE_EDGE_FALLING>;
+            wakeup-source;
+        };
+    };
diff --git a/Documentation/devicetree/bindings/input/touchscreen/mms114.txt b/Documentation/devicetree/bindings/input/touchscreen/mms114.txt
index 2cd954051d299f1f4adc3e130184d9e04eac4a41..707234cfd7e6f63be2e1fea16ee71aa6c1b12b67 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/mms114.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/mms114.txt
@@ -1,9 +1,10 @@
-* MELFAS MMS114/MMS152 touchscreen controller
+* MELFAS MMS114/MMS152/MMS345L touchscreen controller
 
 Required properties:
 - compatible: should be one of:
 	- "melfas,mms114"
 	- "melfas,mms152"
+	- "melfas,mms345l"
 - reg: I2C address of the chip
 - interrupts: interrupt to which the chip is connected
 - touchscreen-size-x: See [1]
diff --git a/MAINTAINERS b/MAINTAINERS
index 12dd77fb4e4e570ae8e8c85210761c32265cdb6c..9b4e836543a372f4e20a04cc5ae5f8ee9108be1e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4710,6 +4710,12 @@ Q:	http://patchwork.linuxtv.org/project/linux-media/list/
 T:	git git://linuxtv.org/anttip/media_tree.git
 F:	drivers/media/common/cypress_firmware*
 
+CYPRESS CY8CTMA140 TOUCHSCREEN DRIVER
+M:	Linus Walleij <linus.walleij@linaro.org>
+L:	linux-input@vger.kernel.org
+S:	Maintained
+F:	drivers/input/touchscreen/cy8ctma140.c
+
 CYTTSP TOUCHSCREEN DRIVER
 M:	Ferruh Yigit <fery@cypress.com>
 L:	linux-input@vger.kernel.org
diff --git a/drivers/hid/hid-alps.c b/drivers/hid/hid-alps.c
index b2ad319a74b9ac228183779324371cc3fd5b7cb7..6f1fe7248d81c7404e8ea864f09ca65967ebfc52 100644
--- a/drivers/hid/hid-alps.c
+++ b/drivers/hid/hid-alps.c
@@ -387,8 +387,7 @@ static int u1_raw_event(struct alps_dev *hdata, u8 *data, int size)
 				input_report_abs(hdata->input,
 					ABS_MT_PRESSURE, z);
 			} else {
-				input_mt_report_slot_state(hdata->input,
-					MT_TOOL_FINGER, 0);
+				input_mt_report_slot_inactive(hdata->input);
 			}
 		}
 
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 35c8c174a0ce66c03daa5a25c4d7a5d0ce3902aa..3f94b4954225b38ea6fa4bea9194bebb1ab8b383 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -899,7 +899,7 @@ static void mt_release_pending_palms(struct mt_device *td,
 		clear_bit(slotnum, app->pending_palm_slots);
 
 		input_mt_slot(input, slotnum);
-		input_mt_report_slot_state(input, MT_TOOL_PALM, false);
+		input_mt_report_slot_inactive(input);
 
 		need_sync = true;
 	}
@@ -1643,9 +1643,7 @@ static void mt_release_contacts(struct hid_device *hid)
 		if (mt) {
 			for (i = 0; i < mt->num_slots; i++) {
 				input_mt_slot(input_dev, i);
-				input_mt_report_slot_state(input_dev,
-							   MT_TOOL_FINGER,
-							   false);
+				input_mt_report_slot_inactive(input_dev);
 			}
 			input_mt_sync_frame(input_dev);
 			input_sync(input_dev);
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 0d57e51b8ba1f8640063b043a4d1007e6376ab68..e494295d1c7b7134cf8a1ba67682a19306b9ca7b 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -282,7 +282,8 @@ static void evdev_pass_values(struct evdev_client *client,
 	spin_unlock(&client->buffer_lock);
 
 	if (wakeup)
-		wake_up_interruptible(&evdev->wait);
+		wake_up_interruptible_poll(&evdev->wait,
+			EPOLLIN | EPOLLOUT | EPOLLRDNORM | EPOLLWRNORM);
 }
 
 /*
@@ -429,7 +430,7 @@ static void evdev_hangup(struct evdev *evdev)
 		kill_fasync(&client->fasync, SIGIO, POLL_HUP);
 	spin_unlock(&evdev->client_lock);
 
-	wake_up_interruptible(&evdev->wait);
+	wake_up_interruptible_poll(&evdev->wait, EPOLLHUP | EPOLLERR);
 }
 
 static int evdev_release(struct inode *inode, struct file *file)
@@ -945,7 +946,7 @@ static int evdev_revoke(struct evdev *evdev, struct evdev_client *client,
 	client->revoked = true;
 	evdev_ungrab(evdev, client);
 	input_flush_device(&evdev->handle, file);
-	wake_up_interruptible(&evdev->wait);
+	wake_up_interruptible_poll(&evdev->wait, EPOLLHUP | EPOLLERR);
 
 	return 0;
 }
diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig
index 940b744639c7f435bb000eb36dc1a43f332e4480..6f73f02059b50cd6faf5d2ba7acfcece980975a8 100644
--- a/drivers/input/joystick/Kconfig
+++ b/drivers/input/joystick/Kconfig
@@ -45,6 +45,7 @@ config JOYSTICK_A3D
 config JOYSTICK_ADI
 	tristate "Logitech ADI digital joysticks and gamepads"
 	select GAMEPORT
+	depends on ADI!=m # avoid module name conflict
 	help
 	  Say Y here if you have a Logitech controller using the ADI
 	  protocol over the PC gameport.
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 28de965a08d5a2259572bdcab4cc5fc50fa81dc1..793ecbbda32caf29c82884030b4957c5a9a94271 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -701,7 +701,7 @@ config KEYBOARD_SPEAR
 	  Say Y here if you want to use the SPEAR keyboard.
 
 	  To compile this driver as a module, choose M here: the
-	  module will be called spear-keboard.
+	  module will be called spear-keyboard.
 
 config KEYBOARD_TC3589X
 	tristate "TC3589X Keypad support"
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 7e3eae54c1926ea882ec9cf23652a759af24a775..6ec28265771df5ecd19eea8c708cfcec79228d56 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -24,6 +24,7 @@
 #include <linux/libps2.h>
 #include <linux/mutex.h>
 #include <linux/dmi.h>
+#include <linux/property.h>
 
 #define DRIVER_DESC	"AT and PS/2 keyboard driver"
 
@@ -63,6 +64,11 @@ static bool atkbd_terminal;
 module_param_named(terminal, atkbd_terminal, bool, 0);
 MODULE_PARM_DESC(terminal, "Enable break codes on an IBM Terminal keyboard connected via AT/PS2");
 
+#define MAX_FUNCTION_ROW_KEYS	24
+
+#define SCANCODE(keymap)	((keymap >> 16) & 0xFFFF)
+#define KEYCODE(keymap)		(keymap & 0xFFFF)
+
 /*
  * Scancode to keycode tables. These are just the default setting, and
  * are loadable via a userland utility.
@@ -230,6 +236,9 @@ struct atkbd {
 
 	/* Serializes reconnect(), attr->set() and event work */
 	struct mutex mutex;
+
+	u32 function_row_physmap[MAX_FUNCTION_ROW_KEYS];
+	int num_function_row_keys;
 };
 
 /*
@@ -283,6 +292,7 @@ static struct device_attribute atkbd_attr_##_name =				\
 	__ATTR(_name, S_IRUGO, atkbd_do_show_##_name, NULL);
 
 ATKBD_DEFINE_RO_ATTR(err_count);
+ATKBD_DEFINE_RO_ATTR(function_row_physmap);
 
 static struct attribute *atkbd_attributes[] = {
 	&atkbd_attr_extra.attr,
@@ -292,11 +302,42 @@ static struct attribute *atkbd_attributes[] = {
 	&atkbd_attr_softrepeat.attr,
 	&atkbd_attr_softraw.attr,
 	&atkbd_attr_err_count.attr,
+	&atkbd_attr_function_row_physmap.attr,
 	NULL
 };
 
+static ssize_t atkbd_show_function_row_physmap(struct atkbd *atkbd, char *buf)
+{
+	ssize_t size = 0;
+	int i;
+
+	if (!atkbd->num_function_row_keys)
+		return 0;
+
+	for (i = 0; i < atkbd->num_function_row_keys; i++)
+		size += scnprintf(buf + size, PAGE_SIZE - size, "%02X ",
+				  atkbd->function_row_physmap[i]);
+	size += scnprintf(buf + size, PAGE_SIZE - size, "\n");
+	return size;
+}
+
+static umode_t atkbd_attr_is_visible(struct kobject *kobj,
+				struct attribute *attr, int i)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct serio *serio = to_serio_port(dev);
+	struct atkbd *atkbd = serio_get_drvdata(serio);
+
+	if (attr == &atkbd_attr_function_row_physmap.attr &&
+	    !atkbd->num_function_row_keys)
+		return 0;
+
+	return attr->mode;
+}
+
 static struct attribute_group atkbd_attribute_group = {
 	.attrs	= atkbd_attributes,
+	.is_visible = atkbd_attr_is_visible,
 };
 
 static const unsigned int xl_table[] = {
@@ -994,6 +1035,39 @@ static unsigned int atkbd_oqo_01plus_scancode_fixup(struct atkbd *atkbd,
 	return code;
 }
 
+static int atkbd_get_keymap_from_fwnode(struct atkbd *atkbd)
+{
+	struct device *dev = &atkbd->ps2dev.serio->dev;
+	int i, n;
+	u32 *ptr;
+	u16 scancode, keycode;
+
+	/* Parse "linux,keymap" property */
+	n = device_property_count_u32(dev, "linux,keymap");
+	if (n <= 0 || n > ATKBD_KEYMAP_SIZE)
+		return -ENXIO;
+
+	ptr = kcalloc(n, sizeof(u32), GFP_KERNEL);
+	if (!ptr)
+		return -ENOMEM;
+
+	if (device_property_read_u32_array(dev, "linux,keymap", ptr, n)) {
+		dev_err(dev, "problem parsing FW keymap property\n");
+		kfree(ptr);
+		return -EINVAL;
+	}
+
+	memset(atkbd->keycode, 0, sizeof(atkbd->keycode));
+	for (i = 0; i < n; i++) {
+		scancode = SCANCODE(ptr[i]);
+		keycode = KEYCODE(ptr[i]);
+		atkbd->keycode[scancode] = keycode;
+	}
+
+	kfree(ptr);
+	return 0;
+}
+
 /*
  * atkbd_set_keycode_table() initializes keyboard's keycode table
  * according to the selected scancode set
@@ -1001,13 +1075,16 @@ static unsigned int atkbd_oqo_01plus_scancode_fixup(struct atkbd *atkbd,
 
 static void atkbd_set_keycode_table(struct atkbd *atkbd)
 {
+	struct device *dev = &atkbd->ps2dev.serio->dev;
 	unsigned int scancode;
 	int i, j;
 
 	memset(atkbd->keycode, 0, sizeof(atkbd->keycode));
 	bitmap_zero(atkbd->force_release_mask, ATKBD_KEYMAP_SIZE);
 
-	if (atkbd->translated) {
+	if (!atkbd_get_keymap_from_fwnode(atkbd)) {
+		dev_dbg(dev, "Using FW keymap\n");
+	} else if (atkbd->translated) {
 		for (i = 0; i < 128; i++) {
 			scancode = atkbd_unxlate_table[i];
 			atkbd->keycode[i] = atkbd_set2_keycode[scancode];
@@ -1121,6 +1198,22 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd)
 	}
 }
 
+static void atkbd_parse_fwnode_data(struct serio *serio)
+{
+	struct atkbd *atkbd = serio_get_drvdata(serio);
+	struct device *dev = &serio->dev;
+	int n;
+
+	/* Parse "function-row-physmap" property */
+	n = device_property_count_u32(dev, "function-row-physmap");
+	if (n > 0 && n <= MAX_FUNCTION_ROW_KEYS &&
+	    !device_property_read_u32_array(dev, "function-row-physmap",
+					    atkbd->function_row_physmap, n)) {
+		atkbd->num_function_row_keys = n;
+		dev_dbg(dev, "FW reported %d function-row key locations\n", n);
+	}
+}
+
 /*
  * atkbd_connect() is called when the serio module finds an interface
  * that isn't handled yet by an appropriate device driver. We check if
@@ -1184,6 +1277,8 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
 		atkbd->id = 0xab00;
 	}
 
+	atkbd_parse_fwnode_data(serio);
+
 	atkbd_set_keycode_table(atkbd);
 	atkbd_set_device_attrs(atkbd);
 
diff --git a/drivers/input/keyboard/imx_sc_key.c b/drivers/input/keyboard/imx_sc_key.c
index 9f809aeb785c4927d60009d233610d313fc07e9d..d18839f1f4f60dedb52f1b77fd9337ad724faa5d 100644
--- a/drivers/input/keyboard/imx_sc_key.c
+++ b/drivers/input/keyboard/imx_sc_key.c
@@ -99,6 +99,15 @@ static void imx_sc_check_for_events(struct work_struct *work)
 				      msecs_to_jiffies(REPEAT_INTERVAL));
 }
 
+static void imx_sc_key_action(void *data)
+{
+	struct imx_key_drv_data *priv = data;
+
+	imx_scu_irq_group_enable(SC_IRQ_GROUP_WAKE, SC_IRQ_BUTTON, false);
+	imx_scu_irq_unregister_notifier(&priv->key_notifier);
+	cancel_delayed_work_sync(&priv->check_work);
+}
+
 static int imx_sc_key_probe(struct platform_device *pdev)
 {
 	struct imx_key_drv_data *priv;
@@ -149,27 +158,16 @@ static int imx_sc_key_probe(struct platform_device *pdev)
 		return error;
 	}
 
+	error = devm_add_action_or_reset(&pdev->dev, imx_sc_key_action, &priv);
+	if (error)
+		return error;
+
 	priv->key_notifier.notifier_call = imx_sc_key_notify;
 	error = imx_scu_irq_register_notifier(&priv->key_notifier);
-	if (error) {
-		imx_scu_irq_group_enable(SC_IRQ_GROUP_WAKE, SC_IRQ_BUTTON,
-					 false);
+	if (error)
 		dev_err(&pdev->dev, "failed to register scu notifier\n");
-		return error;
-	}
-
-	return 0;
-}
-
-static int imx_sc_key_remove(struct platform_device *pdev)
-{
-	struct imx_key_drv_data *priv = platform_get_drvdata(pdev);
-
-	imx_scu_irq_group_enable(SC_IRQ_GROUP_WAKE, SC_IRQ_BUTTON, false);
-	imx_scu_irq_unregister_notifier(&priv->key_notifier);
-	cancel_delayed_work_sync(&priv->check_work);
 
-	return 0;
+	return error;
 }
 
 static const struct of_device_id imx_sc_key_ids[] = {
@@ -184,7 +182,6 @@ static struct platform_driver imx_sc_key_driver = {
 		.of_match_table = imx_sc_key_ids,
 	},
 	.probe = imx_sc_key_probe,
-	.remove = imx_sc_key_remove,
 };
 module_platform_driver(imx_sc_key_driver);
 
diff --git a/drivers/input/keyboard/tca6416-keypad.c b/drivers/input/keyboard/tca6416-keypad.c
index 21758767ccf063613a755f8f430f0f62c01acc88..9b0f9665dcb04ab89fdf7b729ad8196b7c92e27a 100644
--- a/drivers/input/keyboard/tca6416-keypad.c
+++ b/drivers/input/keyboard/tca6416-keypad.c
@@ -374,5 +374,5 @@ static void __exit tca6416_keypad_exit(void)
 module_exit(tca6416_keypad_exit);
 
 MODULE_AUTHOR("Sriramakrishnan <srk@ti.com>");
-MODULE_DESCRIPTION("Keypad driver over tca6146 IO expander");
+MODULE_DESCRIPTION("Keypad driver over tca6416 IO expander");
 MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 7e2e658d551c1f89195b2f94ecf60ed15db81d66..362e8a01980cdafe1f1f317ccb8495b4f3111929 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -117,16 +117,6 @@ config INPUT_E3X0_BUTTON
 	  To compile this driver as a module, choose M here: the
 	  module will be called e3x0_button.
 
-config INPUT_MSM_VIBRATOR
-	tristate "Qualcomm MSM vibrator driver"
-	select INPUT_FF_MEMLESS
-	help
-	  Support for the vibrator that is found on various Qualcomm MSM
-	  SOCs.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called msm_vibrator.
-
 config INPUT_PCSPKR
 	tristate "PC Speaker support"
 	depends on PCSPKR_PLATFORM
@@ -265,17 +255,6 @@ config INPUT_APANEL
 	 To compile this driver as a module, choose M here: the module will
 	 be called apanel.
 
-config INPUT_GP2A
-	tristate "Sharp GP2AP002A00F I2C Proximity/Opto sensor driver"
-	depends on I2C
-	depends on GPIOLIB || COMPILE_TEST
-	help
-	  Say Y here if you have a Sharp GP2AP002A00F proximity/als combo-chip
-	  hooked to an I2C bus.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called gp2ap002a00f.
-
 config INPUT_GPIO_BEEPER
 	tristate "Generic GPIO Beeper support"
 	depends on GPIOLIB || COMPILE_TEST
@@ -739,6 +718,17 @@ config INPUT_IMS_PCU
 	  To compile this driver as a module, choose M here: the module will be
 	  called ims_pcu.
 
+config INPUT_IQS269A
+	tristate "Azoteq IQS269A capacitive touch controller"
+	depends on I2C
+	select REGMAP_I2C
+	help
+	  Say Y to enable support for the Azoteq IQS269A capacitive
+	  touch controller.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called iqs269a.
+
 config INPUT_CMA3000
 	tristate "VTI CMA3000 Tri-axis accelerometer"
 	help
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 8fd187f314bdffd6715793a7e5b654f47e38d6b6..a48e5f2d859d4448cfdb07865a3920a506df3c5e 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -33,13 +33,13 @@ obj-$(CONFIG_INPUT_E3X0_BUTTON)		+= e3x0-button.o
 obj-$(CONFIG_INPUT_DRV260X_HAPTICS)	+= drv260x.o
 obj-$(CONFIG_INPUT_DRV2665_HAPTICS)	+= drv2665.o
 obj-$(CONFIG_INPUT_DRV2667_HAPTICS)	+= drv2667.o
-obj-$(CONFIG_INPUT_GP2A)		+= gp2ap002a00f.o
 obj-$(CONFIG_INPUT_GPIO_BEEPER)		+= gpio-beeper.o
 obj-$(CONFIG_INPUT_GPIO_DECODER)	+= gpio_decoder.o
 obj-$(CONFIG_INPUT_GPIO_VIBRA)		+= gpio-vibra.o
 obj-$(CONFIG_INPUT_HISI_POWERKEY)	+= hisi_powerkey.o
 obj-$(CONFIG_HP_SDC_RTC)		+= hp_sdc_rtc.o
 obj-$(CONFIG_INPUT_IMS_PCU)		+= ims-pcu.o
+obj-$(CONFIG_INPUT_IQS269A)		+= iqs269a.o
 obj-$(CONFIG_INPUT_IXP4XX_BEEPER)	+= ixp4xx-beeper.o
 obj-$(CONFIG_INPUT_KEYSPAN_REMOTE)	+= keyspan_remote.o
 obj-$(CONFIG_INPUT_KXTJ9)		+= kxtj9.o
@@ -50,7 +50,6 @@ obj-$(CONFIG_INPUT_MAX8925_ONKEY)	+= max8925_onkey.o
 obj-$(CONFIG_INPUT_MAX8997_HAPTIC)	+= max8997_haptic.o
 obj-$(CONFIG_INPUT_MC13783_PWRBUTTON)	+= mc13783-pwrbutton.o
 obj-$(CONFIG_INPUT_MMA8450)		+= mma8450.o
-obj-$(CONFIG_INPUT_MSM_VIBRATOR)	+= msm-vibrator.o
 obj-$(CONFIG_INPUT_PALMAS_PWRBUTTON)	+= palmas-pwrbutton.o
 obj-$(CONFIG_INPUT_PCAP)		+= pcap_keys.o
 obj-$(CONFIG_INPUT_PCF50633_PMU)	+= pcf50633-input.o
diff --git a/drivers/input/misc/gp2ap002a00f.c b/drivers/input/misc/gp2ap002a00f.c
deleted file mode 100644
index 90abda8eea67a4fe7279b9f1d2321b5dba164f74..0000000000000000000000000000000000000000
--- a/drivers/input/misc/gp2ap002a00f.c
+++ /dev/null
@@ -1,281 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2011 Sony Ericsson Mobile Communications Inc.
- *
- * Author: Courtney Cavin <courtney.cavin@sonyericsson.com>
- * Prepared for up-stream by: Oskar Andero <oskar.andero@sonyericsson.com>
- */
-
-#include <linux/i2c.h>
-#include <linux/irq.h>
-#include <linux/slab.h>
-#include <linux/input.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/delay.h>
-#include <linux/input/gp2ap002a00f.h>
-
-struct gp2a_data {
-	struct input_dev *input;
-	const struct gp2a_platform_data *pdata;
-	struct i2c_client *i2c_client;
-};
-
-enum gp2a_addr {
-	GP2A_ADDR_PROX	= 0x0,
-	GP2A_ADDR_GAIN	= 0x1,
-	GP2A_ADDR_HYS	= 0x2,
-	GP2A_ADDR_CYCLE	= 0x3,
-	GP2A_ADDR_OPMOD	= 0x4,
-	GP2A_ADDR_CON	= 0x6
-};
-
-enum gp2a_controls {
-	/* Software Shutdown control: 0 = shutdown, 1 = normal operation */
-	GP2A_CTRL_SSD	= 0x01
-};
-
-static int gp2a_report(struct gp2a_data *dt)
-{
-	int vo = gpio_get_value(dt->pdata->vout_gpio);
-
-	input_report_switch(dt->input, SW_FRONT_PROXIMITY, !vo);
-	input_sync(dt->input);
-
-	return 0;
-}
-
-static irqreturn_t gp2a_irq(int irq, void *handle)
-{
-	struct gp2a_data *dt = handle;
-
-	gp2a_report(dt);
-
-	return IRQ_HANDLED;
-}
-
-static int gp2a_enable(struct gp2a_data *dt)
-{
-	return i2c_smbus_write_byte_data(dt->i2c_client, GP2A_ADDR_OPMOD,
-					 GP2A_CTRL_SSD);
-}
-
-static int gp2a_disable(struct gp2a_data *dt)
-{
-	return i2c_smbus_write_byte_data(dt->i2c_client, GP2A_ADDR_OPMOD,
-					 0x00);
-}
-
-static int gp2a_device_open(struct input_dev *dev)
-{
-	struct gp2a_data *dt = input_get_drvdata(dev);
-	int error;
-
-	error = gp2a_enable(dt);
-	if (error < 0) {
-		dev_err(&dt->i2c_client->dev,
-			"unable to activate, err %d\n", error);
-		return error;
-	}
-
-	gp2a_report(dt);
-
-	return 0;
-}
-
-static void gp2a_device_close(struct input_dev *dev)
-{
-	struct gp2a_data *dt = input_get_drvdata(dev);
-	int error;
-
-	error = gp2a_disable(dt);
-	if (error < 0)
-		dev_err(&dt->i2c_client->dev,
-			"unable to deactivate, err %d\n", error);
-}
-
-static int gp2a_initialize(struct gp2a_data *dt)
-{
-	int error;
-
-	error = i2c_smbus_write_byte_data(dt->i2c_client, GP2A_ADDR_GAIN,
-					  0x08);
-	if (error < 0)
-		return error;
-
-	error = i2c_smbus_write_byte_data(dt->i2c_client, GP2A_ADDR_HYS,
-					  0xc2);
-	if (error < 0)
-		return error;
-
-	error = i2c_smbus_write_byte_data(dt->i2c_client, GP2A_ADDR_CYCLE,
-					  0x04);
-	if (error < 0)
-		return error;
-
-	error = gp2a_disable(dt);
-
-	return error;
-}
-
-static int gp2a_probe(struct i2c_client *client,
-				const struct i2c_device_id *id)
-{
-	const struct gp2a_platform_data *pdata = dev_get_platdata(&client->dev);
-	struct gp2a_data *dt;
-	int error;
-
-	if (!pdata)
-		return -EINVAL;
-
-	if (pdata->hw_setup) {
-		error = pdata->hw_setup(client);
-		if (error < 0)
-			return error;
-	}
-
-	error = gpio_request_one(pdata->vout_gpio, GPIOF_IN, GP2A_I2C_NAME);
-	if (error)
-		goto err_hw_shutdown;
-
-	dt = kzalloc(sizeof(struct gp2a_data), GFP_KERNEL);
-	if (!dt) {
-		error = -ENOMEM;
-		goto err_free_gpio;
-	}
-
-	dt->pdata = pdata;
-	dt->i2c_client = client;
-
-	error = gp2a_initialize(dt);
-	if (error < 0)
-		goto err_free_mem;
-
-	dt->input = input_allocate_device();
-	if (!dt->input) {
-		error = -ENOMEM;
-		goto err_free_mem;
-	}
-
-	input_set_drvdata(dt->input, dt);
-
-	dt->input->open = gp2a_device_open;
-	dt->input->close = gp2a_device_close;
-	dt->input->name = GP2A_I2C_NAME;
-	dt->input->id.bustype = BUS_I2C;
-	dt->input->dev.parent = &client->dev;
-
-	input_set_capability(dt->input, EV_SW, SW_FRONT_PROXIMITY);
-
-	error = request_threaded_irq(client->irq, NULL, gp2a_irq,
-			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
-				IRQF_ONESHOT,
-			GP2A_I2C_NAME, dt);
-	if (error) {
-		dev_err(&client->dev, "irq request failed\n");
-		goto err_free_input_dev;
-	}
-
-	error = input_register_device(dt->input);
-	if (error) {
-		dev_err(&client->dev, "device registration failed\n");
-		goto err_free_irq;
-	}
-
-	device_init_wakeup(&client->dev, pdata->wakeup);
-	i2c_set_clientdata(client, dt);
-
-	return 0;
-
-err_free_irq:
-	free_irq(client->irq, dt);
-err_free_input_dev:
-	input_free_device(dt->input);
-err_free_mem:
-	kfree(dt);
-err_free_gpio:
-	gpio_free(pdata->vout_gpio);
-err_hw_shutdown:
-	if (pdata->hw_shutdown)
-		pdata->hw_shutdown(client);
-	return error;
-}
-
-static int gp2a_remove(struct i2c_client *client)
-{
-	struct gp2a_data *dt = i2c_get_clientdata(client);
-	const struct gp2a_platform_data *pdata = dt->pdata;
-
-	free_irq(client->irq, dt);
-
-	input_unregister_device(dt->input);
-	kfree(dt);
-
-	gpio_free(pdata->vout_gpio);
-
-	if (pdata->hw_shutdown)
-		pdata->hw_shutdown(client);
-
-	return 0;
-}
-
-static int __maybe_unused gp2a_suspend(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct gp2a_data *dt = i2c_get_clientdata(client);
-	int retval = 0;
-
-	if (device_may_wakeup(&client->dev)) {
-		enable_irq_wake(client->irq);
-	} else {
-		mutex_lock(&dt->input->mutex);
-		if (dt->input->users)
-			retval = gp2a_disable(dt);
-		mutex_unlock(&dt->input->mutex);
-	}
-
-	return retval;
-}
-
-static int __maybe_unused gp2a_resume(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct gp2a_data *dt = i2c_get_clientdata(client);
-	int retval = 0;
-
-	if (device_may_wakeup(&client->dev)) {
-		disable_irq_wake(client->irq);
-	} else {
-		mutex_lock(&dt->input->mutex);
-		if (dt->input->users)
-			retval = gp2a_enable(dt);
-		mutex_unlock(&dt->input->mutex);
-	}
-
-	return retval;
-}
-
-static SIMPLE_DEV_PM_OPS(gp2a_pm, gp2a_suspend, gp2a_resume);
-
-static const struct i2c_device_id gp2a_i2c_id[] = {
-	{ GP2A_I2C_NAME, 0 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, gp2a_i2c_id);
-
-static struct i2c_driver gp2a_i2c_driver = {
-	.driver = {
-		.name	= GP2A_I2C_NAME,
-		.pm	= &gp2a_pm,
-	},
-	.probe		= gp2a_probe,
-	.remove		= gp2a_remove,
-	.id_table	= gp2a_i2c_id,
-};
-
-module_i2c_driver(gp2a_i2c_driver);
-
-MODULE_AUTHOR("Courtney Cavin <courtney.cavin@sonyericsson.com>");
-MODULE_DESCRIPTION("Sharp GP2AP002A00F I2C Proximity/Opto sensor driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/input/misc/iqs269a.c b/drivers/input/misc/iqs269a.c
new file mode 100644
index 0000000000000000000000000000000000000000..6699eb160a0f41053b48934c64e4434eface7034
--- /dev/null
+++ b/drivers/input/misc/iqs269a.c
@@ -0,0 +1,1833 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Azoteq IQS269A Capacitive Touch Controller
+ *
+ * Copyright (C) 2020 Jeff LaBundy <jeff@labundy.com>
+ *
+ * This driver registers up to 3 input devices: one representing capacitive or
+ * inductive keys as well as Hall-effect switches, and one for each of the two
+ * axial sliders presented by the device.
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of_device.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#define IQS269_VER_INFO				0x00
+#define IQS269_VER_INFO_PROD_NUM		0x4F
+
+#define IQS269_SYS_FLAGS			0x02
+#define IQS269_SYS_FLAGS_SHOW_RESET		BIT(15)
+#define IQS269_SYS_FLAGS_PWR_MODE_MASK		GENMASK(12, 11)
+#define IQS269_SYS_FLAGS_PWR_MODE_SHIFT		11
+#define IQS269_SYS_FLAGS_IN_ATI			BIT(10)
+
+#define IQS269_CHx_COUNTS			0x08
+
+#define IQS269_SLIDER_X				0x30
+
+#define IQS269_CAL_DATA_A			0x35
+#define IQS269_CAL_DATA_A_HALL_BIN_L_MASK	GENMASK(15, 12)
+#define IQS269_CAL_DATA_A_HALL_BIN_L_SHIFT	12
+#define IQS269_CAL_DATA_A_HALL_BIN_R_MASK	GENMASK(11, 8)
+#define IQS269_CAL_DATA_A_HALL_BIN_R_SHIFT	8
+
+#define IQS269_SYS_SETTINGS			0x80
+#define IQS269_SYS_SETTINGS_CLK_DIV		BIT(15)
+#define IQS269_SYS_SETTINGS_ULP_AUTO		BIT(14)
+#define IQS269_SYS_SETTINGS_DIS_AUTO		BIT(13)
+#define IQS269_SYS_SETTINGS_PWR_MODE_MASK	GENMASK(12, 11)
+#define IQS269_SYS_SETTINGS_PWR_MODE_SHIFT	11
+#define IQS269_SYS_SETTINGS_PWR_MODE_MAX	3
+#define IQS269_SYS_SETTINGS_ULP_UPDATE_MASK	GENMASK(10, 8)
+#define IQS269_SYS_SETTINGS_ULP_UPDATE_SHIFT	8
+#define IQS269_SYS_SETTINGS_ULP_UPDATE_MAX	7
+#define IQS269_SYS_SETTINGS_RESEED_OFFSET	BIT(6)
+#define IQS269_SYS_SETTINGS_EVENT_MODE		BIT(5)
+#define IQS269_SYS_SETTINGS_EVENT_MODE_LP	BIT(4)
+#define IQS269_SYS_SETTINGS_REDO_ATI		BIT(2)
+#define IQS269_SYS_SETTINGS_ACK_RESET		BIT(0)
+
+#define IQS269_FILT_STR_LP_LTA_MASK		GENMASK(7, 6)
+#define IQS269_FILT_STR_LP_LTA_SHIFT		6
+#define IQS269_FILT_STR_LP_CNT_MASK		GENMASK(5, 4)
+#define IQS269_FILT_STR_LP_CNT_SHIFT		4
+#define IQS269_FILT_STR_NP_LTA_MASK		GENMASK(3, 2)
+#define IQS269_FILT_STR_NP_LTA_SHIFT		2
+#define IQS269_FILT_STR_NP_CNT_MASK		GENMASK(1, 0)
+#define IQS269_FILT_STR_MAX			3
+
+#define IQS269_EVENT_MASK_SYS			BIT(6)
+#define IQS269_EVENT_MASK_DEEP			BIT(2)
+#define IQS269_EVENT_MASK_TOUCH			BIT(1)
+#define IQS269_EVENT_MASK_PROX			BIT(0)
+
+#define IQS269_RATE_NP_MS_MAX			255
+#define IQS269_RATE_LP_MS_MAX			255
+#define IQS269_RATE_ULP_MS_MAX			4080
+#define IQS269_TIMEOUT_PWR_MS_MAX		130560
+#define IQS269_TIMEOUT_LTA_MS_MAX		130560
+
+#define IQS269_MISC_A_ATI_BAND_DISABLE		BIT(15)
+#define IQS269_MISC_A_ATI_LP_ONLY		BIT(14)
+#define IQS269_MISC_A_ATI_BAND_TIGHTEN		BIT(13)
+#define IQS269_MISC_A_FILT_DISABLE		BIT(12)
+#define IQS269_MISC_A_GPIO3_SELECT_MASK		GENMASK(10, 8)
+#define IQS269_MISC_A_GPIO3_SELECT_SHIFT	8
+#define IQS269_MISC_A_DUAL_DIR			BIT(6)
+#define IQS269_MISC_A_TX_FREQ_MASK		GENMASK(5, 4)
+#define IQS269_MISC_A_TX_FREQ_SHIFT		4
+#define IQS269_MISC_A_TX_FREQ_MAX		3
+#define IQS269_MISC_A_GLOBAL_CAP_SIZE		BIT(0)
+
+#define IQS269_MISC_B_RESEED_UI_SEL_MASK	GENMASK(7, 6)
+#define IQS269_MISC_B_RESEED_UI_SEL_SHIFT	6
+#define IQS269_MISC_B_RESEED_UI_SEL_MAX		3
+#define IQS269_MISC_B_TRACKING_UI_ENABLE	BIT(4)
+#define IQS269_MISC_B_FILT_STR_SLIDER		GENMASK(1, 0)
+
+#define IQS269_CHx_SETTINGS			0x8C
+
+#define IQS269_CHx_ENG_A_MEAS_CAP_SIZE		BIT(15)
+#define IQS269_CHx_ENG_A_RX_GND_INACTIVE	BIT(13)
+#define IQS269_CHx_ENG_A_LOCAL_CAP_SIZE		BIT(12)
+#define IQS269_CHx_ENG_A_ATI_MODE_MASK		GENMASK(9, 8)
+#define IQS269_CHx_ENG_A_ATI_MODE_SHIFT		8
+#define IQS269_CHx_ENG_A_ATI_MODE_MAX		3
+#define IQS269_CHx_ENG_A_INV_LOGIC		BIT(7)
+#define IQS269_CHx_ENG_A_PROJ_BIAS_MASK		GENMASK(6, 5)
+#define IQS269_CHx_ENG_A_PROJ_BIAS_SHIFT	5
+#define IQS269_CHx_ENG_A_PROJ_BIAS_MAX		3
+#define IQS269_CHx_ENG_A_SENSE_MODE_MASK	GENMASK(3, 0)
+#define IQS269_CHx_ENG_A_SENSE_MODE_MAX		15
+
+#define IQS269_CHx_ENG_B_LOCAL_CAP_ENABLE	BIT(13)
+#define IQS269_CHx_ENG_B_SENSE_FREQ_MASK	GENMASK(10, 9)
+#define IQS269_CHx_ENG_B_SENSE_FREQ_SHIFT	9
+#define IQS269_CHx_ENG_B_SENSE_FREQ_MAX		3
+#define IQS269_CHx_ENG_B_STATIC_ENABLE		BIT(8)
+#define IQS269_CHx_ENG_B_ATI_BASE_MASK		GENMASK(7, 6)
+#define IQS269_CHx_ENG_B_ATI_BASE_75		0x00
+#define IQS269_CHx_ENG_B_ATI_BASE_100		0x40
+#define IQS269_CHx_ENG_B_ATI_BASE_150		0x80
+#define IQS269_CHx_ENG_B_ATI_BASE_200		0xC0
+#define IQS269_CHx_ENG_B_ATI_TARGET_MASK	GENMASK(5, 0)
+#define IQS269_CHx_ENG_B_ATI_TARGET_MAX		2016
+
+#define IQS269_CHx_WEIGHT_MAX			255
+#define IQS269_CHx_THRESH_MAX			255
+#define IQS269_CHx_HYST_DEEP_MASK		GENMASK(7, 4)
+#define IQS269_CHx_HYST_DEEP_SHIFT		4
+#define IQS269_CHx_HYST_TOUCH_MASK		GENMASK(3, 0)
+#define IQS269_CHx_HYST_MAX			15
+
+#define IQS269_CHx_HALL_INACTIVE		6
+#define IQS269_CHx_HALL_ACTIVE			7
+
+#define IQS269_HALL_PAD_R			BIT(0)
+#define IQS269_HALL_PAD_L			BIT(1)
+#define IQS269_HALL_PAD_INV			BIT(6)
+
+#define IQS269_HALL_UI				0xF5
+#define IQS269_HALL_UI_ENABLE			BIT(15)
+
+#define IQS269_MAX_REG				0xFF
+
+#define IQS269_NUM_CH				8
+#define IQS269_NUM_SL				2
+
+#define IQS269_ATI_POLL_SLEEP_US		(iqs269->delay_mult * 10000)
+#define IQS269_ATI_POLL_TIMEOUT_US		(iqs269->delay_mult * 500000)
+#define IQS269_ATI_STABLE_DELAY_MS		(iqs269->delay_mult * 150)
+
+#define IQS269_PWR_MODE_POLL_SLEEP_US		IQS269_ATI_POLL_SLEEP_US
+#define IQS269_PWR_MODE_POLL_TIMEOUT_US		IQS269_ATI_POLL_TIMEOUT_US
+
+#define iqs269_irq_wait()			usleep_range(100, 150)
+
+enum iqs269_local_cap_size {
+	IQS269_LOCAL_CAP_SIZE_0,
+	IQS269_LOCAL_CAP_SIZE_GLOBAL_ONLY,
+	IQS269_LOCAL_CAP_SIZE_GLOBAL_0pF5,
+};
+
+enum iqs269_st_offs {
+	IQS269_ST_OFFS_PROX,
+	IQS269_ST_OFFS_DIR,
+	IQS269_ST_OFFS_TOUCH,
+	IQS269_ST_OFFS_DEEP,
+};
+
+enum iqs269_th_offs {
+	IQS269_TH_OFFS_PROX,
+	IQS269_TH_OFFS_TOUCH,
+	IQS269_TH_OFFS_DEEP,
+};
+
+enum iqs269_event_id {
+	IQS269_EVENT_PROX_DN,
+	IQS269_EVENT_PROX_UP,
+	IQS269_EVENT_TOUCH_DN,
+	IQS269_EVENT_TOUCH_UP,
+	IQS269_EVENT_DEEP_DN,
+	IQS269_EVENT_DEEP_UP,
+};
+
+struct iqs269_switch_desc {
+	unsigned int code;
+	bool enabled;
+};
+
+struct iqs269_event_desc {
+	const char *name;
+	enum iqs269_st_offs st_offs;
+	enum iqs269_th_offs th_offs;
+	bool dir_up;
+	u8 mask;
+};
+
+static const struct iqs269_event_desc iqs269_events[] = {
+	[IQS269_EVENT_PROX_DN] = {
+		.name = "event-prox",
+		.st_offs = IQS269_ST_OFFS_PROX,
+		.th_offs = IQS269_TH_OFFS_PROX,
+		.mask = IQS269_EVENT_MASK_PROX,
+	},
+	[IQS269_EVENT_PROX_UP] = {
+		.name = "event-prox-alt",
+		.st_offs = IQS269_ST_OFFS_PROX,
+		.th_offs = IQS269_TH_OFFS_PROX,
+		.dir_up = true,
+		.mask = IQS269_EVENT_MASK_PROX,
+	},
+	[IQS269_EVENT_TOUCH_DN] = {
+		.name = "event-touch",
+		.st_offs = IQS269_ST_OFFS_TOUCH,
+		.th_offs = IQS269_TH_OFFS_TOUCH,
+		.mask = IQS269_EVENT_MASK_TOUCH,
+	},
+	[IQS269_EVENT_TOUCH_UP] = {
+		.name = "event-touch-alt",
+		.st_offs = IQS269_ST_OFFS_TOUCH,
+		.th_offs = IQS269_TH_OFFS_TOUCH,
+		.dir_up = true,
+		.mask = IQS269_EVENT_MASK_TOUCH,
+	},
+	[IQS269_EVENT_DEEP_DN] = {
+		.name = "event-deep",
+		.st_offs = IQS269_ST_OFFS_DEEP,
+		.th_offs = IQS269_TH_OFFS_DEEP,
+		.mask = IQS269_EVENT_MASK_DEEP,
+	},
+	[IQS269_EVENT_DEEP_UP] = {
+		.name = "event-deep-alt",
+		.st_offs = IQS269_ST_OFFS_DEEP,
+		.th_offs = IQS269_TH_OFFS_DEEP,
+		.dir_up = true,
+		.mask = IQS269_EVENT_MASK_DEEP,
+	},
+};
+
+struct iqs269_ver_info {
+	u8 prod_num;
+	u8 sw_num;
+	u8 hw_num;
+	u8 padding;
+} __packed;
+
+struct iqs269_sys_reg {
+	__be16 general;
+	u8 active;
+	u8 filter;
+	u8 reseed;
+	u8 event_mask;
+	u8 rate_np;
+	u8 rate_lp;
+	u8 rate_ulp;
+	u8 timeout_pwr;
+	u8 timeout_rdy;
+	u8 timeout_lta;
+	__be16 misc_a;
+	__be16 misc_b;
+	u8 blocking;
+	u8 padding;
+	u8 slider_select[IQS269_NUM_SL];
+	u8 timeout_tap;
+	u8 timeout_swipe;
+	u8 thresh_swipe;
+	u8 redo_ati;
+} __packed;
+
+struct iqs269_ch_reg {
+	u8 rx_enable;
+	u8 tx_enable;
+	__be16 engine_a;
+	__be16 engine_b;
+	__be16 ati_comp;
+	u8 thresh[3];
+	u8 hyst;
+	u8 assoc_select;
+	u8 assoc_weight;
+} __packed;
+
+struct iqs269_flags {
+	__be16 system;
+	u8 gesture;
+	u8 padding;
+	u8 states[4];
+} __packed;
+
+struct iqs269_private {
+	struct i2c_client *client;
+	struct regmap *regmap;
+	struct mutex lock;
+	struct iqs269_switch_desc switches[ARRAY_SIZE(iqs269_events)];
+	struct iqs269_ch_reg ch_reg[IQS269_NUM_CH];
+	struct iqs269_sys_reg sys_reg;
+	struct input_dev *keypad;
+	struct input_dev *slider[IQS269_NUM_SL];
+	unsigned int keycode[ARRAY_SIZE(iqs269_events) * IQS269_NUM_CH];
+	unsigned int suspend_mode;
+	unsigned int delay_mult;
+	unsigned int ch_num;
+	bool hall_enable;
+	bool ati_current;
+};
+
+static int iqs269_ati_mode_set(struct iqs269_private *iqs269,
+			       unsigned int ch_num, unsigned int mode)
+{
+	u16 engine_a;
+
+	if (ch_num >= IQS269_NUM_CH)
+		return -EINVAL;
+
+	if (mode > IQS269_CHx_ENG_A_ATI_MODE_MAX)
+		return -EINVAL;
+
+	mutex_lock(&iqs269->lock);
+
+	engine_a = be16_to_cpu(iqs269->ch_reg[ch_num].engine_a);
+
+	engine_a &= ~IQS269_CHx_ENG_A_ATI_MODE_MASK;
+	engine_a |= (mode << IQS269_CHx_ENG_A_ATI_MODE_SHIFT);
+
+	iqs269->ch_reg[ch_num].engine_a = cpu_to_be16(engine_a);
+	iqs269->ati_current = false;
+
+	mutex_unlock(&iqs269->lock);
+
+	return 0;
+}
+
+static int iqs269_ati_mode_get(struct iqs269_private *iqs269,
+			       unsigned int ch_num, unsigned int *mode)
+{
+	u16 engine_a;
+
+	if (ch_num >= IQS269_NUM_CH)
+		return -EINVAL;
+
+	mutex_lock(&iqs269->lock);
+	engine_a = be16_to_cpu(iqs269->ch_reg[ch_num].engine_a);
+	mutex_unlock(&iqs269->lock);
+
+	engine_a &= IQS269_CHx_ENG_A_ATI_MODE_MASK;
+	*mode = (engine_a >> IQS269_CHx_ENG_A_ATI_MODE_SHIFT);
+
+	return 0;
+}
+
+static int iqs269_ati_base_set(struct iqs269_private *iqs269,
+			       unsigned int ch_num, unsigned int base)
+{
+	u16 engine_b;
+
+	if (ch_num >= IQS269_NUM_CH)
+		return -EINVAL;
+
+	switch (base) {
+	case 75:
+		base = IQS269_CHx_ENG_B_ATI_BASE_75;
+		break;
+
+	case 100:
+		base = IQS269_CHx_ENG_B_ATI_BASE_100;
+		break;
+
+	case 150:
+		base = IQS269_CHx_ENG_B_ATI_BASE_150;
+		break;
+
+	case 200:
+		base = IQS269_CHx_ENG_B_ATI_BASE_200;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	mutex_lock(&iqs269->lock);
+
+	engine_b = be16_to_cpu(iqs269->ch_reg[ch_num].engine_b);
+
+	engine_b &= ~IQS269_CHx_ENG_B_ATI_BASE_MASK;
+	engine_b |= base;
+
+	iqs269->ch_reg[ch_num].engine_b = cpu_to_be16(engine_b);
+	iqs269->ati_current = false;
+
+	mutex_unlock(&iqs269->lock);
+
+	return 0;
+}
+
+static int iqs269_ati_base_get(struct iqs269_private *iqs269,
+			       unsigned int ch_num, unsigned int *base)
+{
+	u16 engine_b;
+
+	if (ch_num >= IQS269_NUM_CH)
+		return -EINVAL;
+
+	mutex_lock(&iqs269->lock);
+	engine_b = be16_to_cpu(iqs269->ch_reg[ch_num].engine_b);
+	mutex_unlock(&iqs269->lock);
+
+	switch (engine_b & IQS269_CHx_ENG_B_ATI_BASE_MASK) {
+	case IQS269_CHx_ENG_B_ATI_BASE_75:
+		*base = 75;
+		return 0;
+
+	case IQS269_CHx_ENG_B_ATI_BASE_100:
+		*base = 100;
+		return 0;
+
+	case IQS269_CHx_ENG_B_ATI_BASE_150:
+		*base = 150;
+		return 0;
+
+	case IQS269_CHx_ENG_B_ATI_BASE_200:
+		*base = 200;
+		return 0;
+
+	default:
+		return -EINVAL;
+	}
+}
+
+static int iqs269_ati_target_set(struct iqs269_private *iqs269,
+				 unsigned int ch_num, unsigned int target)
+{
+	u16 engine_b;
+
+	if (ch_num >= IQS269_NUM_CH)
+		return -EINVAL;
+
+	if (target > IQS269_CHx_ENG_B_ATI_TARGET_MAX)
+		return -EINVAL;
+
+	mutex_lock(&iqs269->lock);
+
+	engine_b = be16_to_cpu(iqs269->ch_reg[ch_num].engine_b);
+
+	engine_b &= ~IQS269_CHx_ENG_B_ATI_TARGET_MASK;
+	engine_b |= target / 32;
+
+	iqs269->ch_reg[ch_num].engine_b = cpu_to_be16(engine_b);
+	iqs269->ati_current = false;
+
+	mutex_unlock(&iqs269->lock);
+
+	return 0;
+}
+
+static int iqs269_ati_target_get(struct iqs269_private *iqs269,
+				 unsigned int ch_num, unsigned int *target)
+{
+	u16 engine_b;
+
+	if (ch_num >= IQS269_NUM_CH)
+		return -EINVAL;
+
+	mutex_lock(&iqs269->lock);
+	engine_b = be16_to_cpu(iqs269->ch_reg[ch_num].engine_b);
+	mutex_unlock(&iqs269->lock);
+
+	*target = (engine_b & IQS269_CHx_ENG_B_ATI_TARGET_MASK) * 32;
+
+	return 0;
+}
+
+static int iqs269_parse_mask(const struct fwnode_handle *fwnode,
+			     const char *propname, u8 *mask)
+{
+	unsigned int val[IQS269_NUM_CH];
+	int count, error, i;
+
+	count = fwnode_property_count_u32(fwnode, propname);
+	if (count < 0)
+		return 0;
+
+	if (count > IQS269_NUM_CH)
+		return -EINVAL;
+
+	error = fwnode_property_read_u32_array(fwnode, propname, val, count);
+	if (error)
+		return error;
+
+	*mask = 0;
+
+	for (i = 0; i < count; i++) {
+		if (val[i] >= IQS269_NUM_CH)
+			return -EINVAL;
+
+		*mask |= BIT(val[i]);
+	}
+
+	return 0;
+}
+
+static int iqs269_parse_chan(struct iqs269_private *iqs269,
+			     const struct fwnode_handle *ch_node)
+{
+	struct i2c_client *client = iqs269->client;
+	struct fwnode_handle *ev_node;
+	struct iqs269_ch_reg *ch_reg;
+	u16 engine_a, engine_b;
+	unsigned int reg, val;
+	int error, i;
+
+	error = fwnode_property_read_u32(ch_node, "reg", &reg);
+	if (error) {
+		dev_err(&client->dev, "Failed to read channel number: %d\n",
+			error);
+		return error;
+	} else if (reg >= IQS269_NUM_CH) {
+		dev_err(&client->dev, "Invalid channel number: %u\n", reg);
+		return -EINVAL;
+	}
+
+	iqs269->sys_reg.active |= BIT(reg);
+	if (!fwnode_property_present(ch_node, "azoteq,reseed-disable"))
+		iqs269->sys_reg.reseed |= BIT(reg);
+
+	if (fwnode_property_present(ch_node, "azoteq,blocking-enable"))
+		iqs269->sys_reg.blocking |= BIT(reg);
+
+	if (fwnode_property_present(ch_node, "azoteq,slider0-select"))
+		iqs269->sys_reg.slider_select[0] |= BIT(reg);
+
+	if (fwnode_property_present(ch_node, "azoteq,slider1-select"))
+		iqs269->sys_reg.slider_select[1] |= BIT(reg);
+
+	ch_reg = &iqs269->ch_reg[reg];
+
+	error = regmap_raw_read(iqs269->regmap,
+				IQS269_CHx_SETTINGS + reg * sizeof(*ch_reg) / 2,
+				ch_reg, sizeof(*ch_reg));
+	if (error)
+		return error;
+
+	error = iqs269_parse_mask(ch_node, "azoteq,rx-enable",
+				  &ch_reg->rx_enable);
+	if (error) {
+		dev_err(&client->dev, "Invalid channel %u RX enable mask: %d\n",
+			reg, error);
+		return error;
+	}
+
+	error = iqs269_parse_mask(ch_node, "azoteq,tx-enable",
+				  &ch_reg->tx_enable);
+	if (error) {
+		dev_err(&client->dev, "Invalid channel %u TX enable mask: %d\n",
+			reg, error);
+		return error;
+	}
+
+	engine_a = be16_to_cpu(ch_reg->engine_a);
+	engine_b = be16_to_cpu(ch_reg->engine_b);
+
+	engine_a |= IQS269_CHx_ENG_A_MEAS_CAP_SIZE;
+	if (fwnode_property_present(ch_node, "azoteq,meas-cap-decrease"))
+		engine_a &= ~IQS269_CHx_ENG_A_MEAS_CAP_SIZE;
+
+	engine_a |= IQS269_CHx_ENG_A_RX_GND_INACTIVE;
+	if (fwnode_property_present(ch_node, "azoteq,rx-float-inactive"))
+		engine_a &= ~IQS269_CHx_ENG_A_RX_GND_INACTIVE;
+
+	engine_a &= ~IQS269_CHx_ENG_A_LOCAL_CAP_SIZE;
+	engine_b &= ~IQS269_CHx_ENG_B_LOCAL_CAP_ENABLE;
+	if (!fwnode_property_read_u32(ch_node, "azoteq,local-cap-size", &val)) {
+		switch (val) {
+		case IQS269_LOCAL_CAP_SIZE_0:
+			break;
+
+		case IQS269_LOCAL_CAP_SIZE_GLOBAL_0pF5:
+			engine_a |= IQS269_CHx_ENG_A_LOCAL_CAP_SIZE;
+
+			/* fall through */
+
+		case IQS269_LOCAL_CAP_SIZE_GLOBAL_ONLY:
+			engine_b |= IQS269_CHx_ENG_B_LOCAL_CAP_ENABLE;
+			break;
+
+		default:
+			dev_err(&client->dev,
+				"Invalid channel %u local cap. size: %u\n", reg,
+				val);
+			return -EINVAL;
+		}
+	}
+
+	engine_a &= ~IQS269_CHx_ENG_A_INV_LOGIC;
+	if (fwnode_property_present(ch_node, "azoteq,invert-enable"))
+		engine_a |= IQS269_CHx_ENG_A_INV_LOGIC;
+
+	if (!fwnode_property_read_u32(ch_node, "azoteq,proj-bias", &val)) {
+		if (val > IQS269_CHx_ENG_A_PROJ_BIAS_MAX) {
+			dev_err(&client->dev,
+				"Invalid channel %u bias current: %u\n", reg,
+				val);
+			return -EINVAL;
+		}
+
+		engine_a &= ~IQS269_CHx_ENG_A_PROJ_BIAS_MASK;
+		engine_a |= (val << IQS269_CHx_ENG_A_PROJ_BIAS_SHIFT);
+	}
+
+	if (!fwnode_property_read_u32(ch_node, "azoteq,sense-mode", &val)) {
+		if (val > IQS269_CHx_ENG_A_SENSE_MODE_MAX) {
+			dev_err(&client->dev,
+				"Invalid channel %u sensing mode: %u\n", reg,
+				val);
+			return -EINVAL;
+		}
+
+		engine_a &= ~IQS269_CHx_ENG_A_SENSE_MODE_MASK;
+		engine_a |= val;
+	}
+
+	if (!fwnode_property_read_u32(ch_node, "azoteq,sense-freq", &val)) {
+		if (val > IQS269_CHx_ENG_B_SENSE_FREQ_MAX) {
+			dev_err(&client->dev,
+				"Invalid channel %u sensing frequency: %u\n",
+				reg, val);
+			return -EINVAL;
+		}
+
+		engine_b &= ~IQS269_CHx_ENG_B_SENSE_FREQ_MASK;
+		engine_b |= (val << IQS269_CHx_ENG_B_SENSE_FREQ_SHIFT);
+	}
+
+	engine_b &= ~IQS269_CHx_ENG_B_STATIC_ENABLE;
+	if (fwnode_property_present(ch_node, "azoteq,static-enable"))
+		engine_b |= IQS269_CHx_ENG_B_STATIC_ENABLE;
+
+	ch_reg->engine_a = cpu_to_be16(engine_a);
+	ch_reg->engine_b = cpu_to_be16(engine_b);
+
+	if (!fwnode_property_read_u32(ch_node, "azoteq,ati-mode", &val)) {
+		error = iqs269_ati_mode_set(iqs269, reg, val);
+		if (error) {
+			dev_err(&client->dev,
+				"Invalid channel %u ATI mode: %u\n", reg, val);
+			return error;
+		}
+	}
+
+	if (!fwnode_property_read_u32(ch_node, "azoteq,ati-base", &val)) {
+		error = iqs269_ati_base_set(iqs269, reg, val);
+		if (error) {
+			dev_err(&client->dev,
+				"Invalid channel %u ATI base: %u\n", reg, val);
+			return error;
+		}
+	}
+
+	if (!fwnode_property_read_u32(ch_node, "azoteq,ati-target", &val)) {
+		error = iqs269_ati_target_set(iqs269, reg, val);
+		if (error) {
+			dev_err(&client->dev,
+				"Invalid channel %u ATI target: %u\n", reg,
+				val);
+			return error;
+		}
+	}
+
+	error = iqs269_parse_mask(ch_node, "azoteq,assoc-select",
+				  &ch_reg->assoc_select);
+	if (error) {
+		dev_err(&client->dev, "Invalid channel %u association: %d\n",
+			reg, error);
+		return error;
+	}
+
+	if (!fwnode_property_read_u32(ch_node, "azoteq,assoc-weight", &val)) {
+		if (val > IQS269_CHx_WEIGHT_MAX) {
+			dev_err(&client->dev,
+				"Invalid channel %u associated weight: %u\n",
+				reg, val);
+			return -EINVAL;
+		}
+
+		ch_reg->assoc_weight = val;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(iqs269_events); i++) {
+		ev_node = fwnode_get_named_child_node(ch_node,
+						      iqs269_events[i].name);
+		if (!ev_node)
+			continue;
+
+		if (!fwnode_property_read_u32(ev_node, "azoteq,thresh", &val)) {
+			if (val > IQS269_CHx_THRESH_MAX) {
+				dev_err(&client->dev,
+					"Invalid channel %u threshold: %u\n",
+					reg, val);
+				return -EINVAL;
+			}
+
+			ch_reg->thresh[iqs269_events[i].th_offs] = val;
+		}
+
+		if (!fwnode_property_read_u32(ev_node, "azoteq,hyst", &val)) {
+			u8 *hyst = &ch_reg->hyst;
+
+			if (val > IQS269_CHx_HYST_MAX) {
+				dev_err(&client->dev,
+					"Invalid channel %u hysteresis: %u\n",
+					reg, val);
+				return -EINVAL;
+			}
+
+			if (i == IQS269_EVENT_DEEP_DN ||
+			    i == IQS269_EVENT_DEEP_UP) {
+				*hyst &= ~IQS269_CHx_HYST_DEEP_MASK;
+				*hyst |= (val << IQS269_CHx_HYST_DEEP_SHIFT);
+			} else if (i == IQS269_EVENT_TOUCH_DN ||
+				   i == IQS269_EVENT_TOUCH_UP) {
+				*hyst &= ~IQS269_CHx_HYST_TOUCH_MASK;
+				*hyst |= val;
+			}
+		}
+
+		if (fwnode_property_read_u32(ev_node, "linux,code", &val))
+			continue;
+
+		switch (reg) {
+		case IQS269_CHx_HALL_ACTIVE:
+			if (iqs269->hall_enable) {
+				iqs269->switches[i].code = val;
+				iqs269->switches[i].enabled = true;
+			}
+
+			/* fall through */
+
+		case IQS269_CHx_HALL_INACTIVE:
+			if (iqs269->hall_enable)
+				break;
+
+			/* fall through */
+
+		default:
+			iqs269->keycode[i * IQS269_NUM_CH + reg] = val;
+		}
+
+		iqs269->sys_reg.event_mask &= ~iqs269_events[i].mask;
+	}
+
+	return 0;
+}
+
+static int iqs269_parse_prop(struct iqs269_private *iqs269)
+{
+	struct iqs269_sys_reg *sys_reg = &iqs269->sys_reg;
+	struct i2c_client *client = iqs269->client;
+	struct fwnode_handle *ch_node;
+	u16 general, misc_a, misc_b;
+	unsigned int val;
+	int error;
+
+	iqs269->hall_enable = device_property_present(&client->dev,
+						      "azoteq,hall-enable");
+
+	if (!device_property_read_u32(&client->dev, "azoteq,suspend-mode",
+				      &val)) {
+		if (val > IQS269_SYS_SETTINGS_PWR_MODE_MAX) {
+			dev_err(&client->dev, "Invalid suspend mode: %u\n",
+				val);
+			return -EINVAL;
+		}
+
+		iqs269->suspend_mode = val;
+	}
+
+	error = regmap_raw_read(iqs269->regmap, IQS269_SYS_SETTINGS, sys_reg,
+				sizeof(*sys_reg));
+	if (error)
+		return error;
+
+	if (!device_property_read_u32(&client->dev, "azoteq,filt-str-lp-lta",
+				      &val)) {
+		if (val > IQS269_FILT_STR_MAX) {
+			dev_err(&client->dev, "Invalid filter strength: %u\n",
+				val);
+			return -EINVAL;
+		}
+
+		sys_reg->filter &= ~IQS269_FILT_STR_LP_LTA_MASK;
+		sys_reg->filter |= (val << IQS269_FILT_STR_LP_LTA_SHIFT);
+	}
+
+	if (!device_property_read_u32(&client->dev, "azoteq,filt-str-lp-cnt",
+				      &val)) {
+		if (val > IQS269_FILT_STR_MAX) {
+			dev_err(&client->dev, "Invalid filter strength: %u\n",
+				val);
+			return -EINVAL;
+		}
+
+		sys_reg->filter &= ~IQS269_FILT_STR_LP_CNT_MASK;
+		sys_reg->filter |= (val << IQS269_FILT_STR_LP_CNT_SHIFT);
+	}
+
+	if (!device_property_read_u32(&client->dev, "azoteq,filt-str-np-lta",
+				      &val)) {
+		if (val > IQS269_FILT_STR_MAX) {
+			dev_err(&client->dev, "Invalid filter strength: %u\n",
+				val);
+			return -EINVAL;
+		}
+
+		sys_reg->filter &= ~IQS269_FILT_STR_NP_LTA_MASK;
+		sys_reg->filter |= (val << IQS269_FILT_STR_NP_LTA_SHIFT);
+	}
+
+	if (!device_property_read_u32(&client->dev, "azoteq,filt-str-np-cnt",
+				      &val)) {
+		if (val > IQS269_FILT_STR_MAX) {
+			dev_err(&client->dev, "Invalid filter strength: %u\n",
+				val);
+			return -EINVAL;
+		}
+
+		sys_reg->filter &= ~IQS269_FILT_STR_NP_CNT_MASK;
+		sys_reg->filter |= val;
+	}
+
+	if (!device_property_read_u32(&client->dev, "azoteq,rate-np-ms",
+				      &val)) {
+		if (val > IQS269_RATE_NP_MS_MAX) {
+			dev_err(&client->dev, "Invalid report rate: %u\n", val);
+			return -EINVAL;
+		}
+
+		sys_reg->rate_np = val;
+	}
+
+	if (!device_property_read_u32(&client->dev, "azoteq,rate-lp-ms",
+				      &val)) {
+		if (val > IQS269_RATE_LP_MS_MAX) {
+			dev_err(&client->dev, "Invalid report rate: %u\n", val);
+			return -EINVAL;
+		}
+
+		sys_reg->rate_lp = val;
+	}
+
+	if (!device_property_read_u32(&client->dev, "azoteq,rate-ulp-ms",
+				      &val)) {
+		if (val > IQS269_RATE_ULP_MS_MAX) {
+			dev_err(&client->dev, "Invalid report rate: %u\n", val);
+			return -EINVAL;
+		}
+
+		sys_reg->rate_ulp = val / 16;
+	}
+
+	if (!device_property_read_u32(&client->dev, "azoteq,timeout-pwr-ms",
+				      &val)) {
+		if (val > IQS269_TIMEOUT_PWR_MS_MAX) {
+			dev_err(&client->dev, "Invalid timeout: %u\n", val);
+			return -EINVAL;
+		}
+
+		sys_reg->timeout_pwr = val / 512;
+	}
+
+	if (!device_property_read_u32(&client->dev, "azoteq,timeout-lta-ms",
+				      &val)) {
+		if (val > IQS269_TIMEOUT_LTA_MS_MAX) {
+			dev_err(&client->dev, "Invalid timeout: %u\n", val);
+			return -EINVAL;
+		}
+
+		sys_reg->timeout_lta = val / 512;
+	}
+
+	misc_a = be16_to_cpu(sys_reg->misc_a);
+	misc_b = be16_to_cpu(sys_reg->misc_b);
+
+	misc_a &= ~IQS269_MISC_A_ATI_BAND_DISABLE;
+	if (device_property_present(&client->dev, "azoteq,ati-band-disable"))
+		misc_a |= IQS269_MISC_A_ATI_BAND_DISABLE;
+
+	misc_a &= ~IQS269_MISC_A_ATI_LP_ONLY;
+	if (device_property_present(&client->dev, "azoteq,ati-lp-only"))
+		misc_a |= IQS269_MISC_A_ATI_LP_ONLY;
+
+	misc_a &= ~IQS269_MISC_A_ATI_BAND_TIGHTEN;
+	if (device_property_present(&client->dev, "azoteq,ati-band-tighten"))
+		misc_a |= IQS269_MISC_A_ATI_BAND_TIGHTEN;
+
+	misc_a &= ~IQS269_MISC_A_FILT_DISABLE;
+	if (device_property_present(&client->dev, "azoteq,filt-disable"))
+		misc_a |= IQS269_MISC_A_FILT_DISABLE;
+
+	if (!device_property_read_u32(&client->dev, "azoteq,gpio3-select",
+				      &val)) {
+		if (val >= IQS269_NUM_CH) {
+			dev_err(&client->dev, "Invalid GPIO3 selection: %u\n",
+				val);
+			return -EINVAL;
+		}
+
+		misc_a &= ~IQS269_MISC_A_GPIO3_SELECT_MASK;
+		misc_a |= (val << IQS269_MISC_A_GPIO3_SELECT_SHIFT);
+	}
+
+	misc_a &= ~IQS269_MISC_A_DUAL_DIR;
+	if (device_property_present(&client->dev, "azoteq,dual-direction"))
+		misc_a |= IQS269_MISC_A_DUAL_DIR;
+
+	if (!device_property_read_u32(&client->dev, "azoteq,tx-freq", &val)) {
+		if (val > IQS269_MISC_A_TX_FREQ_MAX) {
+			dev_err(&client->dev,
+				"Invalid excitation frequency: %u\n", val);
+			return -EINVAL;
+		}
+
+		misc_a &= ~IQS269_MISC_A_TX_FREQ_MASK;
+		misc_a |= (val << IQS269_MISC_A_TX_FREQ_SHIFT);
+	}
+
+	misc_a &= ~IQS269_MISC_A_GLOBAL_CAP_SIZE;
+	if (device_property_present(&client->dev, "azoteq,global-cap-increase"))
+		misc_a |= IQS269_MISC_A_GLOBAL_CAP_SIZE;
+
+	if (!device_property_read_u32(&client->dev, "azoteq,reseed-select",
+				      &val)) {
+		if (val > IQS269_MISC_B_RESEED_UI_SEL_MAX) {
+			dev_err(&client->dev, "Invalid reseed selection: %u\n",
+				val);
+			return -EINVAL;
+		}
+
+		misc_b &= ~IQS269_MISC_B_RESEED_UI_SEL_MASK;
+		misc_b |= (val << IQS269_MISC_B_RESEED_UI_SEL_SHIFT);
+	}
+
+	misc_b &= ~IQS269_MISC_B_TRACKING_UI_ENABLE;
+	if (device_property_present(&client->dev, "azoteq,tracking-enable"))
+		misc_b |= IQS269_MISC_B_TRACKING_UI_ENABLE;
+
+	if (!device_property_read_u32(&client->dev, "azoteq,filt-str-slider",
+				      &val)) {
+		if (val > IQS269_FILT_STR_MAX) {
+			dev_err(&client->dev, "Invalid filter strength: %u\n",
+				val);
+			return -EINVAL;
+		}
+
+		misc_b &= ~IQS269_MISC_B_FILT_STR_SLIDER;
+		misc_b |= val;
+	}
+
+	sys_reg->misc_a = cpu_to_be16(misc_a);
+	sys_reg->misc_b = cpu_to_be16(misc_b);
+
+	sys_reg->active = 0;
+	sys_reg->reseed = 0;
+
+	sys_reg->blocking = 0;
+
+	sys_reg->slider_select[0] = 0;
+	sys_reg->slider_select[1] = 0;
+
+	sys_reg->event_mask = ~((u8)IQS269_EVENT_MASK_SYS);
+
+	device_for_each_child_node(&client->dev, ch_node) {
+		error = iqs269_parse_chan(iqs269, ch_node);
+		if (error) {
+			fwnode_handle_put(ch_node);
+			return error;
+		}
+	}
+
+	/*
+	 * Volunteer all active channels to participate in ATI when REDO-ATI is
+	 * manually triggered.
+	 */
+	sys_reg->redo_ati = sys_reg->active;
+
+	general = be16_to_cpu(sys_reg->general);
+
+	if (device_property_present(&client->dev, "azoteq,clk-div")) {
+		general |= IQS269_SYS_SETTINGS_CLK_DIV;
+		iqs269->delay_mult = 4;
+	} else {
+		general &= ~IQS269_SYS_SETTINGS_CLK_DIV;
+		iqs269->delay_mult = 1;
+	}
+
+	/*
+	 * Configure the device to automatically switch between normal and low-
+	 * power modes as a function of sensing activity. Ultra-low-power mode,
+	 * if enabled, is reserved for suspend.
+	 */
+	general &= ~IQS269_SYS_SETTINGS_ULP_AUTO;
+	general &= ~IQS269_SYS_SETTINGS_DIS_AUTO;
+	general &= ~IQS269_SYS_SETTINGS_PWR_MODE_MASK;
+
+	if (!device_property_read_u32(&client->dev, "azoteq,ulp-update",
+				      &val)) {
+		if (val > IQS269_SYS_SETTINGS_ULP_UPDATE_MAX) {
+			dev_err(&client->dev, "Invalid update rate: %u\n", val);
+			return -EINVAL;
+		}
+
+		general &= ~IQS269_SYS_SETTINGS_ULP_UPDATE_MASK;
+		general |= (val << IQS269_SYS_SETTINGS_ULP_UPDATE_SHIFT);
+	}
+
+	general &= ~IQS269_SYS_SETTINGS_RESEED_OFFSET;
+	if (device_property_present(&client->dev, "azoteq,reseed-offset"))
+		general |= IQS269_SYS_SETTINGS_RESEED_OFFSET;
+
+	general |= IQS269_SYS_SETTINGS_EVENT_MODE;
+
+	/*
+	 * As per the datasheet, enable streaming during normal-power mode if
+	 * either slider is in use. In that case, the device returns to event
+	 * mode during low-power mode.
+	 */
+	if (sys_reg->slider_select[0] || sys_reg->slider_select[1])
+		general |= IQS269_SYS_SETTINGS_EVENT_MODE_LP;
+
+	general |= IQS269_SYS_SETTINGS_REDO_ATI;
+	general |= IQS269_SYS_SETTINGS_ACK_RESET;
+
+	sys_reg->general = cpu_to_be16(general);
+
+	return 0;
+}
+
+static int iqs269_dev_init(struct iqs269_private *iqs269)
+{
+	struct iqs269_sys_reg *sys_reg = &iqs269->sys_reg;
+	struct iqs269_ch_reg *ch_reg;
+	unsigned int val;
+	int error, i;
+
+	mutex_lock(&iqs269->lock);
+
+	error = regmap_update_bits(iqs269->regmap, IQS269_HALL_UI,
+				   IQS269_HALL_UI_ENABLE,
+				   iqs269->hall_enable ? ~0 : 0);
+	if (error)
+		goto err_mutex;
+
+	for (i = 0; i < IQS269_NUM_CH; i++) {
+		if (!(sys_reg->active & BIT(i)))
+			continue;
+
+		ch_reg = &iqs269->ch_reg[i];
+
+		error = regmap_raw_write(iqs269->regmap,
+					 IQS269_CHx_SETTINGS + i *
+					 sizeof(*ch_reg) / 2, ch_reg,
+					 sizeof(*ch_reg));
+		if (error)
+			goto err_mutex;
+	}
+
+	/*
+	 * The REDO-ATI and ATI channel selection fields must be written in the
+	 * same block write, so every field between registers 0x80 through 0x8B
+	 * (inclusive) must be written as well.
+	 */
+	error = regmap_raw_write(iqs269->regmap, IQS269_SYS_SETTINGS, sys_reg,
+				 sizeof(*sys_reg));
+	if (error)
+		goto err_mutex;
+
+	error = regmap_read_poll_timeout(iqs269->regmap, IQS269_SYS_FLAGS, val,
+					!(val & IQS269_SYS_FLAGS_IN_ATI),
+					 IQS269_ATI_POLL_SLEEP_US,
+					 IQS269_ATI_POLL_TIMEOUT_US);
+	if (error)
+		goto err_mutex;
+
+	msleep(IQS269_ATI_STABLE_DELAY_MS);
+	iqs269->ati_current = true;
+
+err_mutex:
+	mutex_unlock(&iqs269->lock);
+
+	return error;
+}
+
+static int iqs269_input_init(struct iqs269_private *iqs269)
+{
+	struct i2c_client *client = iqs269->client;
+	struct iqs269_flags flags;
+	unsigned int sw_code, keycode;
+	int error, i, j;
+	u8 dir_mask, state;
+
+	iqs269->keypad = devm_input_allocate_device(&client->dev);
+	if (!iqs269->keypad)
+		return -ENOMEM;
+
+	iqs269->keypad->keycodemax = ARRAY_SIZE(iqs269->keycode);
+	iqs269->keypad->keycode = iqs269->keycode;
+	iqs269->keypad->keycodesize = sizeof(*iqs269->keycode);
+
+	iqs269->keypad->name = "iqs269a_keypad";
+	iqs269->keypad->id.bustype = BUS_I2C;
+
+	if (iqs269->hall_enable) {
+		error = regmap_raw_read(iqs269->regmap, IQS269_SYS_FLAGS,
+					&flags, sizeof(flags));
+		if (error) {
+			dev_err(&client->dev,
+				"Failed to read initial status: %d\n", error);
+			return error;
+		}
+	}
+
+	for (i = 0; i < ARRAY_SIZE(iqs269_events); i++) {
+		dir_mask = flags.states[IQS269_ST_OFFS_DIR];
+		if (!iqs269_events[i].dir_up)
+			dir_mask = ~dir_mask;
+
+		state = flags.states[iqs269_events[i].st_offs] & dir_mask;
+
+		sw_code = iqs269->switches[i].code;
+
+		for (j = 0; j < IQS269_NUM_CH; j++) {
+			keycode = iqs269->keycode[i * IQS269_NUM_CH + j];
+
+			/*
+			 * Hall-effect sensing repurposes a pair of dedicated
+			 * channels, only one of which reports events.
+			 */
+			switch (j) {
+			case IQS269_CHx_HALL_ACTIVE:
+				if (iqs269->hall_enable &&
+				    iqs269->switches[i].enabled) {
+					input_set_capability(iqs269->keypad,
+							     EV_SW, sw_code);
+					input_report_switch(iqs269->keypad,
+							    sw_code,
+							    state & BIT(j));
+				}
+
+				/* fall through */
+
+			case IQS269_CHx_HALL_INACTIVE:
+				if (iqs269->hall_enable)
+					continue;
+
+				/* fall through */
+
+			default:
+				if (keycode != KEY_RESERVED)
+					input_set_capability(iqs269->keypad,
+							     EV_KEY, keycode);
+			}
+		}
+	}
+
+	input_sync(iqs269->keypad);
+
+	error = input_register_device(iqs269->keypad);
+	if (error) {
+		dev_err(&client->dev, "Failed to register keypad: %d\n", error);
+		return error;
+	}
+
+	for (i = 0; i < IQS269_NUM_SL; i++) {
+		if (!iqs269->sys_reg.slider_select[i])
+			continue;
+
+		iqs269->slider[i] = devm_input_allocate_device(&client->dev);
+		if (!iqs269->slider[i])
+			return -ENOMEM;
+
+		iqs269->slider[i]->name = i ? "iqs269a_slider_1"
+					    : "iqs269a_slider_0";
+		iqs269->slider[i]->id.bustype = BUS_I2C;
+
+		input_set_capability(iqs269->slider[i], EV_KEY, BTN_TOUCH);
+		input_set_abs_params(iqs269->slider[i], ABS_X, 0, 255, 0, 0);
+
+		error = input_register_device(iqs269->slider[i]);
+		if (error) {
+			dev_err(&client->dev,
+				"Failed to register slider %d: %d\n", i, error);
+			return error;
+		}
+	}
+
+	return 0;
+}
+
+static int iqs269_report(struct iqs269_private *iqs269)
+{
+	struct i2c_client *client = iqs269->client;
+	struct iqs269_flags flags;
+	unsigned int sw_code, keycode;
+	int error, i, j;
+	u8 slider_x[IQS269_NUM_SL];
+	u8 dir_mask, state;
+
+	error = regmap_raw_read(iqs269->regmap, IQS269_SYS_FLAGS, &flags,
+				sizeof(flags));
+	if (error) {
+		dev_err(&client->dev, "Failed to read device status: %d\n",
+			error);
+		return error;
+	}
+
+	/*
+	 * The device resets itself if its own watchdog bites, which can happen
+	 * in the event of an I2C communication error. In this case, the device
+	 * asserts a SHOW_RESET interrupt and all registers must be restored.
+	 */
+	if (be16_to_cpu(flags.system) & IQS269_SYS_FLAGS_SHOW_RESET) {
+		dev_err(&client->dev, "Unexpected device reset\n");
+
+		error = iqs269_dev_init(iqs269);
+		if (error)
+			dev_err(&client->dev,
+				"Failed to re-initialize device: %d\n", error);
+
+		return error;
+	}
+
+	error = regmap_raw_read(iqs269->regmap, IQS269_SLIDER_X, slider_x,
+				sizeof(slider_x));
+	if (error) {
+		dev_err(&client->dev, "Failed to read slider position: %d\n",
+			error);
+		return error;
+	}
+
+	for (i = 0; i < IQS269_NUM_SL; i++) {
+		if (!iqs269->sys_reg.slider_select[i])
+			continue;
+
+		/*
+		 * Report BTN_TOUCH if any channel that participates in the
+		 * slider is in a state of touch.
+		 */
+		if (flags.states[IQS269_ST_OFFS_TOUCH] &
+		    iqs269->sys_reg.slider_select[i]) {
+			input_report_key(iqs269->slider[i], BTN_TOUCH, 1);
+			input_report_abs(iqs269->slider[i], ABS_X, slider_x[i]);
+		} else {
+			input_report_key(iqs269->slider[i], BTN_TOUCH, 0);
+		}
+
+		input_sync(iqs269->slider[i]);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(iqs269_events); i++) {
+		dir_mask = flags.states[IQS269_ST_OFFS_DIR];
+		if (!iqs269_events[i].dir_up)
+			dir_mask = ~dir_mask;
+
+		state = flags.states[iqs269_events[i].st_offs] & dir_mask;
+
+		sw_code = iqs269->switches[i].code;
+
+		for (j = 0; j < IQS269_NUM_CH; j++) {
+			keycode = iqs269->keycode[i * IQS269_NUM_CH + j];
+
+			switch (j) {
+			case IQS269_CHx_HALL_ACTIVE:
+				if (iqs269->hall_enable &&
+				    iqs269->switches[i].enabled)
+					input_report_switch(iqs269->keypad,
+							    sw_code,
+							    state & BIT(j));
+
+				/* fall through */
+
+			case IQS269_CHx_HALL_INACTIVE:
+				if (iqs269->hall_enable)
+					continue;
+
+				/* fall through */
+
+			default:
+				input_report_key(iqs269->keypad, keycode,
+						 state & BIT(j));
+			}
+		}
+	}
+
+	input_sync(iqs269->keypad);
+
+	return 0;
+}
+
+static irqreturn_t iqs269_irq(int irq, void *context)
+{
+	struct iqs269_private *iqs269 = context;
+
+	if (iqs269_report(iqs269))
+		return IRQ_NONE;
+
+	/*
+	 * The device does not deassert its interrupt (RDY) pin until shortly
+	 * after receiving an I2C stop condition; the following delay ensures
+	 * the interrupt handler does not return before this time.
+	 */
+	iqs269_irq_wait();
+
+	return IRQ_HANDLED;
+}
+
+static ssize_t counts_show(struct device *dev,
+			   struct device_attribute *attr, char *buf)
+{
+	struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+	struct i2c_client *client = iqs269->client;
+	__le16 counts;
+	int error;
+
+	if (!iqs269->ati_current || iqs269->hall_enable)
+		return -EPERM;
+
+	/*
+	 * Unsolicited I2C communication prompts the device to assert its RDY
+	 * pin, so disable the interrupt line until the operation is finished
+	 * and RDY has been deasserted.
+	 */
+	disable_irq(client->irq);
+
+	error = regmap_raw_read(iqs269->regmap,
+				IQS269_CHx_COUNTS + iqs269->ch_num * 2,
+				&counts, sizeof(counts));
+
+	iqs269_irq_wait();
+	enable_irq(client->irq);
+
+	if (error)
+		return error;
+
+	return scnprintf(buf, PAGE_SIZE, "%u\n", le16_to_cpu(counts));
+}
+
+static ssize_t hall_bin_show(struct device *dev,
+			     struct device_attribute *attr, char *buf)
+{
+	struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+	struct i2c_client *client = iqs269->client;
+	unsigned int val;
+	int error;
+
+	disable_irq(client->irq);
+
+	error = regmap_read(iqs269->regmap, IQS269_CAL_DATA_A, &val);
+
+	iqs269_irq_wait();
+	enable_irq(client->irq);
+
+	if (error)
+		return error;
+
+	switch (iqs269->ch_reg[IQS269_CHx_HALL_ACTIVE].rx_enable &
+		iqs269->ch_reg[IQS269_CHx_HALL_INACTIVE].rx_enable) {
+	case IQS269_HALL_PAD_R:
+		val &= IQS269_CAL_DATA_A_HALL_BIN_R_MASK;
+		val >>= IQS269_CAL_DATA_A_HALL_BIN_R_SHIFT;
+		break;
+
+	case IQS269_HALL_PAD_L:
+		val &= IQS269_CAL_DATA_A_HALL_BIN_L_MASK;
+		val >>= IQS269_CAL_DATA_A_HALL_BIN_L_SHIFT;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return scnprintf(buf, PAGE_SIZE, "%u\n", val);
+}
+
+static ssize_t hall_enable_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+
+	return scnprintf(buf, PAGE_SIZE, "%u\n", iqs269->hall_enable);
+}
+
+static ssize_t hall_enable_store(struct device *dev,
+				 struct device_attribute *attr, const char *buf,
+				 size_t count)
+{
+	struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+	unsigned int val;
+	int error;
+
+	error = kstrtouint(buf, 10, &val);
+	if (error)
+		return error;
+
+	mutex_lock(&iqs269->lock);
+
+	iqs269->hall_enable = val;
+	iqs269->ati_current = false;
+
+	mutex_unlock(&iqs269->lock);
+
+	return count;
+}
+
+static ssize_t ch_number_show(struct device *dev,
+			      struct device_attribute *attr, char *buf)
+{
+	struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+
+	return scnprintf(buf, PAGE_SIZE, "%u\n", iqs269->ch_num);
+}
+
+static ssize_t ch_number_store(struct device *dev,
+			       struct device_attribute *attr, const char *buf,
+			       size_t count)
+{
+	struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+	unsigned int val;
+	int error;
+
+	error = kstrtouint(buf, 10, &val);
+	if (error)
+		return error;
+
+	if (val >= IQS269_NUM_CH)
+		return -EINVAL;
+
+	iqs269->ch_num = val;
+
+	return count;
+}
+
+static ssize_t rx_enable_show(struct device *dev,
+			      struct device_attribute *attr, char *buf)
+{
+	struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+
+	return scnprintf(buf, PAGE_SIZE, "%u\n",
+			 iqs269->ch_reg[iqs269->ch_num].rx_enable);
+}
+
+static ssize_t rx_enable_store(struct device *dev,
+			       struct device_attribute *attr, const char *buf,
+			       size_t count)
+{
+	struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+	unsigned int val;
+	int error;
+
+	error = kstrtouint(buf, 10, &val);
+	if (error)
+		return error;
+
+	if (val > 0xFF)
+		return -EINVAL;
+
+	mutex_lock(&iqs269->lock);
+
+	iqs269->ch_reg[iqs269->ch_num].rx_enable = val;
+	iqs269->ati_current = false;
+
+	mutex_unlock(&iqs269->lock);
+
+	return count;
+}
+
+static ssize_t ati_mode_show(struct device *dev,
+			     struct device_attribute *attr, char *buf)
+{
+	struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+	unsigned int val;
+	int error;
+
+	error = iqs269_ati_mode_get(iqs269, iqs269->ch_num, &val);
+	if (error)
+		return error;
+
+	return scnprintf(buf, PAGE_SIZE, "%u\n", val);
+}
+
+static ssize_t ati_mode_store(struct device *dev,
+			      struct device_attribute *attr, const char *buf,
+			      size_t count)
+{
+	struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+	unsigned int val;
+	int error;
+
+	error = kstrtouint(buf, 10, &val);
+	if (error)
+		return error;
+
+	error = iqs269_ati_mode_set(iqs269, iqs269->ch_num, val);
+	if (error)
+		return error;
+
+	return count;
+}
+
+static ssize_t ati_base_show(struct device *dev,
+			     struct device_attribute *attr, char *buf)
+{
+	struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+	unsigned int val;
+	int error;
+
+	error = iqs269_ati_base_get(iqs269, iqs269->ch_num, &val);
+	if (error)
+		return error;
+
+	return scnprintf(buf, PAGE_SIZE, "%u\n", val);
+}
+
+static ssize_t ati_base_store(struct device *dev,
+			      struct device_attribute *attr, const char *buf,
+			      size_t count)
+{
+	struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+	unsigned int val;
+	int error;
+
+	error = kstrtouint(buf, 10, &val);
+	if (error)
+		return error;
+
+	error = iqs269_ati_base_set(iqs269, iqs269->ch_num, val);
+	if (error)
+		return error;
+
+	return count;
+}
+
+static ssize_t ati_target_show(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+	unsigned int val;
+	int error;
+
+	error = iqs269_ati_target_get(iqs269, iqs269->ch_num, &val);
+	if (error)
+		return error;
+
+	return scnprintf(buf, PAGE_SIZE, "%u\n", val);
+}
+
+static ssize_t ati_target_store(struct device *dev,
+				struct device_attribute *attr, const char *buf,
+				size_t count)
+{
+	struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+	unsigned int val;
+	int error;
+
+	error = kstrtouint(buf, 10, &val);
+	if (error)
+		return error;
+
+	error = iqs269_ati_target_set(iqs269, iqs269->ch_num, val);
+	if (error)
+		return error;
+
+	return count;
+}
+
+static ssize_t ati_trigger_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+
+	return scnprintf(buf, PAGE_SIZE, "%u\n", iqs269->ati_current);
+}
+
+static ssize_t ati_trigger_store(struct device *dev,
+				 struct device_attribute *attr, const char *buf,
+				 size_t count)
+{
+	struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+	struct i2c_client *client = iqs269->client;
+	unsigned int val;
+	int error;
+
+	error = kstrtouint(buf, 10, &val);
+	if (error)
+		return error;
+
+	if (!val)
+		return count;
+
+	disable_irq(client->irq);
+
+	error = iqs269_dev_init(iqs269);
+
+	iqs269_irq_wait();
+	enable_irq(client->irq);
+
+	if (error)
+		return error;
+
+	return count;
+}
+
+static DEVICE_ATTR_RO(counts);
+static DEVICE_ATTR_RO(hall_bin);
+static DEVICE_ATTR_RW(hall_enable);
+static DEVICE_ATTR_RW(ch_number);
+static DEVICE_ATTR_RW(rx_enable);
+static DEVICE_ATTR_RW(ati_mode);
+static DEVICE_ATTR_RW(ati_base);
+static DEVICE_ATTR_RW(ati_target);
+static DEVICE_ATTR_RW(ati_trigger);
+
+static struct attribute *iqs269_attrs[] = {
+	&dev_attr_counts.attr,
+	&dev_attr_hall_bin.attr,
+	&dev_attr_hall_enable.attr,
+	&dev_attr_ch_number.attr,
+	&dev_attr_rx_enable.attr,
+	&dev_attr_ati_mode.attr,
+	&dev_attr_ati_base.attr,
+	&dev_attr_ati_target.attr,
+	&dev_attr_ati_trigger.attr,
+	NULL,
+};
+
+static const struct attribute_group iqs269_attr_group = {
+	.attrs = iqs269_attrs,
+};
+
+static const struct regmap_config iqs269_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 16,
+	.max_register = IQS269_MAX_REG,
+};
+
+static int iqs269_probe(struct i2c_client *client)
+{
+	struct iqs269_ver_info ver_info;
+	struct iqs269_private *iqs269;
+	int error;
+
+	iqs269 = devm_kzalloc(&client->dev, sizeof(*iqs269), GFP_KERNEL);
+	if (!iqs269)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, iqs269);
+	iqs269->client = client;
+
+	iqs269->regmap = devm_regmap_init_i2c(client, &iqs269_regmap_config);
+	if (IS_ERR(iqs269->regmap)) {
+		error = PTR_ERR(iqs269->regmap);
+		dev_err(&client->dev, "Failed to initialize register map: %d\n",
+			error);
+		return error;
+	}
+
+	mutex_init(&iqs269->lock);
+
+	error = regmap_raw_read(iqs269->regmap, IQS269_VER_INFO, &ver_info,
+				sizeof(ver_info));
+	if (error)
+		return error;
+
+	if (ver_info.prod_num != IQS269_VER_INFO_PROD_NUM) {
+		dev_err(&client->dev, "Unrecognized product number: 0x%02X\n",
+			ver_info.prod_num);
+		return -EINVAL;
+	}
+
+	error = iqs269_parse_prop(iqs269);
+	if (error)
+		return error;
+
+	error = iqs269_dev_init(iqs269);
+	if (error) {
+		dev_err(&client->dev, "Failed to initialize device: %d\n",
+			error);
+		return error;
+	}
+
+	error = iqs269_input_init(iqs269);
+	if (error)
+		return error;
+
+	error = devm_request_threaded_irq(&client->dev, client->irq,
+					  NULL, iqs269_irq, IRQF_ONESHOT,
+					  client->name, iqs269);
+	if (error) {
+		dev_err(&client->dev, "Failed to request IRQ: %d\n", error);
+		return error;
+	}
+
+	error = devm_device_add_group(&client->dev, &iqs269_attr_group);
+	if (error)
+		dev_err(&client->dev, "Failed to add attributes: %d\n", error);
+
+	return error;
+}
+
+static int __maybe_unused iqs269_suspend(struct device *dev)
+{
+	struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+	struct i2c_client *client = iqs269->client;
+	unsigned int val;
+	int error;
+
+	if (!iqs269->suspend_mode)
+		return 0;
+
+	disable_irq(client->irq);
+
+	/*
+	 * Automatic power mode switching must be disabled before the device is
+	 * forced into any particular power mode. In this case, the device will
+	 * transition into normal-power mode.
+	 */
+	error = regmap_update_bits(iqs269->regmap, IQS269_SYS_SETTINGS,
+				   IQS269_SYS_SETTINGS_DIS_AUTO, ~0);
+	if (error)
+		goto err_irq;
+
+	/*
+	 * The following check ensures the device has completed its transition
+	 * into normal-power mode before a manual mode switch is performed.
+	 */
+	error = regmap_read_poll_timeout(iqs269->regmap, IQS269_SYS_FLAGS, val,
+					!(val & IQS269_SYS_FLAGS_PWR_MODE_MASK),
+					 IQS269_PWR_MODE_POLL_SLEEP_US,
+					 IQS269_PWR_MODE_POLL_TIMEOUT_US);
+	if (error)
+		goto err_irq;
+
+	error = regmap_update_bits(iqs269->regmap, IQS269_SYS_SETTINGS,
+				   IQS269_SYS_SETTINGS_PWR_MODE_MASK,
+				   iqs269->suspend_mode <<
+				   IQS269_SYS_SETTINGS_PWR_MODE_SHIFT);
+	if (error)
+		goto err_irq;
+
+	/*
+	 * This last check ensures the device has completed its transition into
+	 * the desired power mode to prevent any spurious interrupts from being
+	 * triggered after iqs269_suspend has already returned.
+	 */
+	error = regmap_read_poll_timeout(iqs269->regmap, IQS269_SYS_FLAGS, val,
+					 (val & IQS269_SYS_FLAGS_PWR_MODE_MASK)
+					 == (iqs269->suspend_mode <<
+					     IQS269_SYS_FLAGS_PWR_MODE_SHIFT),
+					 IQS269_PWR_MODE_POLL_SLEEP_US,
+					 IQS269_PWR_MODE_POLL_TIMEOUT_US);
+
+err_irq:
+	iqs269_irq_wait();
+	enable_irq(client->irq);
+
+	return error;
+}
+
+static int __maybe_unused iqs269_resume(struct device *dev)
+{
+	struct iqs269_private *iqs269 = dev_get_drvdata(dev);
+	struct i2c_client *client = iqs269->client;
+	unsigned int val;
+	int error;
+
+	if (!iqs269->suspend_mode)
+		return 0;
+
+	disable_irq(client->irq);
+
+	error = regmap_update_bits(iqs269->regmap, IQS269_SYS_SETTINGS,
+				   IQS269_SYS_SETTINGS_PWR_MODE_MASK, 0);
+	if (error)
+		goto err_irq;
+
+	/*
+	 * This check ensures the device has returned to normal-power mode
+	 * before automatic power mode switching is re-enabled.
+	 */
+	error = regmap_read_poll_timeout(iqs269->regmap, IQS269_SYS_FLAGS, val,
+					!(val & IQS269_SYS_FLAGS_PWR_MODE_MASK),
+					 IQS269_PWR_MODE_POLL_SLEEP_US,
+					 IQS269_PWR_MODE_POLL_TIMEOUT_US);
+	if (error)
+		goto err_irq;
+
+	error = regmap_update_bits(iqs269->regmap, IQS269_SYS_SETTINGS,
+				   IQS269_SYS_SETTINGS_DIS_AUTO, 0);
+	if (error)
+		goto err_irq;
+
+	/*
+	 * This step reports any events that may have been "swallowed" as a
+	 * result of polling PWR_MODE (which automatically acknowledges any
+	 * pending interrupts).
+	 */
+	error = iqs269_report(iqs269);
+
+err_irq:
+	iqs269_irq_wait();
+	enable_irq(client->irq);
+
+	return error;
+}
+
+static SIMPLE_DEV_PM_OPS(iqs269_pm, iqs269_suspend, iqs269_resume);
+
+static const struct of_device_id iqs269_of_match[] = {
+	{ .compatible = "azoteq,iqs269a" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, iqs269_of_match);
+
+static struct i2c_driver iqs269_i2c_driver = {
+	.driver = {
+		.name = "iqs269a",
+		.of_match_table = iqs269_of_match,
+		.pm = &iqs269_pm,
+	},
+	.probe_new = iqs269_probe,
+};
+module_i2c_driver(iqs269_i2c_driver);
+
+MODULE_AUTHOR("Jeff LaBundy <jeff@labundy.com>");
+MODULE_DESCRIPTION("Azoteq IQS269A Capacitive Touch Controller");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/msm-vibrator.c b/drivers/input/misc/msm-vibrator.c
deleted file mode 100644
index b60f1aaee70531e42b401a91566b5ad143d24628..0000000000000000000000000000000000000000
--- a/drivers/input/misc/msm-vibrator.c
+++ /dev/null
@@ -1,281 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Qualcomm MSM vibrator driver
- *
- * Copyright (c) 2018 Brian Masney <masneyb@onstation.org>
- *
- * Based on qcom,pwm-vibrator.c from:
- * Copyright (c) 2018 Jonathan Marek <jonathan@marek.ca>
- *
- * Based on msm_pwm_vibrator.c from downstream Android sources:
- * Copyright (C) 2009-2014 LGE, Inc.
- */
-
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/gpio/consumer.h>
-#include <linux/input.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/consumer.h>
-
-#define REG_CMD_RCGR           0x00
-#define REG_CFG_RCGR           0x04
-#define REG_M                  0x08
-#define REG_N                  0x0C
-#define REG_D                  0x10
-#define REG_CBCR               0x24
-#define MMSS_CC_M_DEFAULT      1
-
-struct msm_vibrator {
-	struct input_dev *input;
-	struct mutex mutex;
-	struct work_struct worker;
-	void __iomem *base;
-	struct regulator *vcc;
-	struct clk *clk;
-	struct gpio_desc *enable_gpio;
-	u16 magnitude;
-	bool enabled;
-};
-
-static void msm_vibrator_write(struct msm_vibrator *vibrator, int offset,
-			       u32 value)
-{
-	writel(value, vibrator->base + offset);
-}
-
-static int msm_vibrator_start(struct msm_vibrator *vibrator)
-{
-	int d_reg_val, ret = 0;
-
-	mutex_lock(&vibrator->mutex);
-
-	if (!vibrator->enabled) {
-		ret = clk_set_rate(vibrator->clk, 24000);
-		if (ret) {
-			dev_err(&vibrator->input->dev,
-				"Failed to set clock rate: %d\n", ret);
-			goto unlock;
-		}
-
-		ret = clk_prepare_enable(vibrator->clk);
-		if (ret) {
-			dev_err(&vibrator->input->dev,
-				"Failed to enable clock: %d\n", ret);
-			goto unlock;
-		}
-
-		ret = regulator_enable(vibrator->vcc);
-		if (ret) {
-			dev_err(&vibrator->input->dev,
-				"Failed to enable regulator: %d\n", ret);
-			clk_disable(vibrator->clk);
-			goto unlock;
-		}
-
-		gpiod_set_value_cansleep(vibrator->enable_gpio, 1);
-
-		vibrator->enabled = true;
-	}
-
-	d_reg_val = 127 - ((126 * vibrator->magnitude) / 0xffff);
-	msm_vibrator_write(vibrator, REG_CFG_RCGR,
-			   (2 << 12) | /* dual edge mode */
-			   (0 << 8) |  /* cxo */
-			   (7 << 0));
-	msm_vibrator_write(vibrator, REG_M, 1);
-	msm_vibrator_write(vibrator, REG_N, 128);
-	msm_vibrator_write(vibrator, REG_D, d_reg_val);
-	msm_vibrator_write(vibrator, REG_CMD_RCGR, 1);
-	msm_vibrator_write(vibrator, REG_CBCR, 1);
-
-unlock:
-	mutex_unlock(&vibrator->mutex);
-
-	return ret;
-}
-
-static void msm_vibrator_stop(struct msm_vibrator *vibrator)
-{
-	mutex_lock(&vibrator->mutex);
-
-	if (vibrator->enabled) {
-		gpiod_set_value_cansleep(vibrator->enable_gpio, 0);
-		regulator_disable(vibrator->vcc);
-		clk_disable(vibrator->clk);
-		vibrator->enabled = false;
-	}
-
-	mutex_unlock(&vibrator->mutex);
-}
-
-static void msm_vibrator_worker(struct work_struct *work)
-{
-	struct msm_vibrator *vibrator = container_of(work,
-						     struct msm_vibrator,
-						     worker);
-
-	if (vibrator->magnitude)
-		msm_vibrator_start(vibrator);
-	else
-		msm_vibrator_stop(vibrator);
-}
-
-static int msm_vibrator_play_effect(struct input_dev *dev, void *data,
-				    struct ff_effect *effect)
-{
-	struct msm_vibrator *vibrator = input_get_drvdata(dev);
-
-	mutex_lock(&vibrator->mutex);
-
-	if (effect->u.rumble.strong_magnitude > 0)
-		vibrator->magnitude = effect->u.rumble.strong_magnitude;
-	else
-		vibrator->magnitude = effect->u.rumble.weak_magnitude;
-
-	mutex_unlock(&vibrator->mutex);
-
-	schedule_work(&vibrator->worker);
-
-	return 0;
-}
-
-static void msm_vibrator_close(struct input_dev *input)
-{
-	struct msm_vibrator *vibrator = input_get_drvdata(input);
-
-	cancel_work_sync(&vibrator->worker);
-	msm_vibrator_stop(vibrator);
-}
-
-static int msm_vibrator_probe(struct platform_device *pdev)
-{
-	struct msm_vibrator *vibrator;
-	struct resource *res;
-	int ret;
-
-	vibrator = devm_kzalloc(&pdev->dev, sizeof(*vibrator), GFP_KERNEL);
-	if (!vibrator)
-		return -ENOMEM;
-
-	vibrator->input = devm_input_allocate_device(&pdev->dev);
-	if (!vibrator->input)
-		return -ENOMEM;
-
-	vibrator->vcc = devm_regulator_get(&pdev->dev, "vcc");
-	if (IS_ERR(vibrator->vcc)) {
-		if (PTR_ERR(vibrator->vcc) != -EPROBE_DEFER)
-			dev_err(&pdev->dev, "Failed to get regulator: %ld\n",
-				PTR_ERR(vibrator->vcc));
-		return PTR_ERR(vibrator->vcc);
-	}
-
-	vibrator->enable_gpio = devm_gpiod_get(&pdev->dev, "enable",
-					       GPIOD_OUT_LOW);
-	if (IS_ERR(vibrator->enable_gpio)) {
-		if (PTR_ERR(vibrator->enable_gpio) != -EPROBE_DEFER)
-			dev_err(&pdev->dev, "Failed to get enable gpio: %ld\n",
-				PTR_ERR(vibrator->enable_gpio));
-		return PTR_ERR(vibrator->enable_gpio);
-	}
-
-	vibrator->clk = devm_clk_get(&pdev->dev, "pwm");
-	if (IS_ERR(vibrator->clk)) {
-		if (PTR_ERR(vibrator->clk) != -EPROBE_DEFER)
-			dev_err(&pdev->dev, "Failed to lookup pwm clock: %ld\n",
-				PTR_ERR(vibrator->clk));
-		return PTR_ERR(vibrator->clk);
-	}
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		dev_err(&pdev->dev, "Failed to get platform resource\n");
-		return -ENODEV;
-	}
-
-	vibrator->base = devm_ioremap(&pdev->dev, res->start,
-				     resource_size(res));
-	if (!vibrator->base) {
-		dev_err(&pdev->dev, "Failed to iomap resource.\n");
-		return -ENOMEM;
-	}
-
-	vibrator->enabled = false;
-	mutex_init(&vibrator->mutex);
-	INIT_WORK(&vibrator->worker, msm_vibrator_worker);
-
-	vibrator->input->name = "msm-vibrator";
-	vibrator->input->id.bustype = BUS_HOST;
-	vibrator->input->close = msm_vibrator_close;
-
-	input_set_drvdata(vibrator->input, vibrator);
-	input_set_capability(vibrator->input, EV_FF, FF_RUMBLE);
-
-	ret = input_ff_create_memless(vibrator->input, NULL,
-				      msm_vibrator_play_effect);
-	if (ret) {
-		dev_err(&pdev->dev, "Failed to create ff memless: %d", ret);
-		return ret;
-	}
-
-	ret = input_register_device(vibrator->input);
-	if (ret) {
-		dev_err(&pdev->dev, "Failed to register input device: %d", ret);
-		return ret;
-	}
-
-	platform_set_drvdata(pdev, vibrator);
-
-	return 0;
-}
-
-static int __maybe_unused msm_vibrator_suspend(struct device *dev)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	struct msm_vibrator *vibrator = platform_get_drvdata(pdev);
-
-	cancel_work_sync(&vibrator->worker);
-
-	if (vibrator->enabled)
-		msm_vibrator_stop(vibrator);
-
-	return 0;
-}
-
-static int __maybe_unused msm_vibrator_resume(struct device *dev)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	struct msm_vibrator *vibrator = platform_get_drvdata(pdev);
-
-	if (vibrator->enabled)
-		msm_vibrator_start(vibrator);
-
-	return 0;
-}
-
-static SIMPLE_DEV_PM_OPS(msm_vibrator_pm_ops, msm_vibrator_suspend,
-			 msm_vibrator_resume);
-
-static const struct of_device_id msm_vibrator_of_match[] = {
-	{ .compatible = "qcom,msm8226-vibrator" },
-	{ .compatible = "qcom,msm8974-vibrator" },
-	{},
-};
-MODULE_DEVICE_TABLE(of, msm_vibrator_of_match);
-
-static struct platform_driver msm_vibrator_driver = {
-	.probe	= msm_vibrator_probe,
-	.driver	= {
-		.name = "msm-vibrator",
-		.pm = &msm_vibrator_pm_ops,
-		.of_match_table = of_match_ptr(msm_vibrator_of_match),
-	},
-};
-module_platform_driver(msm_vibrator_driver);
-
-MODULE_AUTHOR("Brian Masney <masneyb@onstation.org>");
-MODULE_DESCRIPTION("Qualcomm MSM vibrator driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/xen-kbdfront.c b/drivers/input/misc/xen-kbdfront.c
index 24bc5c5d876fcd3909ecd060145f924fc76dd246..a1bba722b234ce37be43592f0457943406f2ce31 100644
--- a/drivers/input/misc/xen-kbdfront.c
+++ b/drivers/input/misc/xen-kbdfront.c
@@ -146,7 +146,7 @@ static void xenkbd_handle_mt_event(struct xenkbd_info *info,
 		break;
 
 	case XENKBD_MT_EV_UP:
-		input_mt_report_slot_state(info->mtouch, MT_TOOL_FINGER, false);
+		input_mt_report_slot_inactive(info->mtouch);
 		break;
 
 	case XENKBD_MT_EV_SYN:
diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c
index 8719da54038346b0441f74cd72fc4af7c48ed1a7..3f9354baac4b3e4a2c09176ea59c54f99bd9436c 100644
--- a/drivers/input/mouse/elan_i2c_core.c
+++ b/drivers/input/mouse/elan_i2c_core.c
@@ -938,7 +938,7 @@ static void elan_report_contact(struct elan_tp_data *data,
 		input_report_abs(input, ABS_MT_TOUCH_MINOR, minor);
 	} else {
 		input_mt_slot(input, contact_num);
-		input_mt_report_slot_state(input, MT_TOOL_FINGER, false);
+		input_mt_report_slot_inactive(input);
 	}
 }
 
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index 7e048b55746241de9e9d53021a87624282081735..7b08ff8ddf35708391904f62a0917b5d62f5444c 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -945,6 +945,7 @@ static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id *
 	}
 	i8042_pnp_id_to_string(dev->id, i8042_kbd_firmware_id,
 			       sizeof(i8042_kbd_firmware_id));
+	i8042_kbd_fwnode = dev_fwnode(&dev->dev);
 
 	/* Keyboard ports are always supposed to be wakeup-enabled */
 	device_set_wakeup_enable(&dev->dev, true);
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 20ff2bed3917a7d9e35d009ec539e396ec8d7607..0dddf273afd94b6b85557ae0a201e5d9a2961586 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -21,6 +21,7 @@
 #include <linux/i8042.h>
 #include <linux/slab.h>
 #include <linux/suspend.h>
+#include <linux/property.h>
 
 #include <asm/io.h>
 
@@ -124,6 +125,7 @@ MODULE_PARM_DESC(unmask_kbd_data, "Unconditional enable (may reveal sensitive da
 static bool i8042_bypass_aux_irq_test;
 static char i8042_kbd_firmware_id[128];
 static char i8042_aux_firmware_id[128];
+static struct fwnode_handle *i8042_kbd_fwnode;
 
 #include "i8042.h"
 
@@ -1335,6 +1337,7 @@ static int __init i8042_create_kbd_port(void)
 	strlcpy(serio->phys, I8042_KBD_PHYS_DESC, sizeof(serio->phys));
 	strlcpy(serio->firmware_id, i8042_kbd_firmware_id,
 		sizeof(serio->firmware_id));
+	set_primary_fwnode(&serio->dev, i8042_kbd_fwnode);
 
 	port->serio = serio;
 	port->irq = I8042_KBD_IRQ;
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index c071f7c407b6114946553db2a57b2680b57115d0..35c867b2d9a77b1012c8c06cfc8cc68302f4297a 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -201,6 +201,18 @@ config TOUCHSCREEN_CHIPONE_ICN8505
 	  To compile this driver as a module, choose M here: the
 	  module will be called chipone_icn8505.
 
+config TOUCHSCREEN_CY8CTMA140
+	tristate "cy8ctma140 touchscreen"
+	depends on I2C
+	help
+	  Say Y here if you have a Cypress CY8CTMA140 capacitive
+	  touchscreen also just known as "TMA140"
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called cy8ctma140.
+
 config TOUCHSCREEN_CY8CTMG110
 	tristate "cy8ctmg110 touchscreen"
 	depends on I2C
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 94c6162409b379724bf0fffc5bfd19c79b0d0974..30d1e1b42492924496602252b451accb867a81bd 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_TOUCHSCREEN_BU21013)	+= bu21013_ts.o
 obj-$(CONFIG_TOUCHSCREEN_BU21029)	+= bu21029_ts.o
 obj-$(CONFIG_TOUCHSCREEN_CHIPONE_ICN8318)	+= chipone_icn8318.o
 obj-$(CONFIG_TOUCHSCREEN_CHIPONE_ICN8505)	+= chipone_icn8505.o
+obj-$(CONFIG_TOUCHSCREEN_CY8CTMA140)	+= cy8ctma140.o
 obj-$(CONFIG_TOUCHSCREEN_CY8CTMG110)	+= cy8ctmg110_ts.o
 obj-$(CONFIG_TOUCHSCREEN_CYTTSP_CORE)	+= cyttsp_core.o
 obj-$(CONFIG_TOUCHSCREEN_CYTTSP_I2C)	+= cyttsp_i2c.o cyttsp_i2c_common.o
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index ae60442efda0dcc29988d16ac32e3488c4e107ea..a2189739e30f5d22a5a238573497006a13041d58 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -822,8 +822,7 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 *message)
 		 * have happened.
 		 */
 		if (status & MXT_T9_RELEASE) {
-			input_mt_report_slot_state(input_dev,
-						   MT_TOOL_FINGER, 0);
+			input_mt_report_slot_inactive(input_dev);
 			mxt_input_sync(data);
 		}
 
@@ -839,7 +838,7 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 *message)
 		input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, area);
 	} else {
 		/* Touch no longer active, close out slot */
-		input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 0);
+		input_mt_report_slot_inactive(input_dev);
 	}
 
 	data->update_input = true;
@@ -947,7 +946,7 @@ static void mxt_proc_t100_message(struct mxt_data *data, u8 *message)
 		dev_dbg(dev, "[%u] release\n", id);
 
 		/* close out slot */
-		input_mt_report_slot_state(input_dev, 0, 0);
+		input_mt_report_slot_inactive(input_dev);
 	}
 
 	data->update_input = true;
diff --git a/drivers/input/touchscreen/cy8ctma140.c b/drivers/input/touchscreen/cy8ctma140.c
new file mode 100644
index 0000000000000000000000000000000000000000..a9be29139cbff561e399a57dcb1567dbcfc31324
--- /dev/null
+++ b/drivers/input/touchscreen/cy8ctma140.c
@@ -0,0 +1,353 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Driver for Cypress CY8CTMA140 (TMA140) touchscreen
+ * (C) 2020 Linus Walleij <linus.walleij@linaro.org>
+ * (C) 2007 Cypress
+ * (C) 2007 Google, Inc.
+ *
+ * Inspired by the tma140_skomer.c driver in the Samsung GT-S7710 code
+ * drop. The GT-S7710 is codenamed "Skomer", the code also indicates
+ * that the same touchscreen was used in a product called "Lucas".
+ *
+ * The code drop for GT-S7710 also contains a firmware downloader and
+ * 15 (!) versions of the firmware drop from Cypress. But here we assume
+ * the firmware got downloaded to the touchscreen flash successfully and
+ * just use it to read the fingers. The shipped vendor driver does the
+ * same.
+ */
+
+#include <asm/unaligned.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/input.h>
+#include <linux/input/touchscreen.h>
+#include <linux/input/mt.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/regulator/consumer.h>
+#include <linux/delay.h>
+
+#define CY8CTMA140_NAME			"cy8ctma140"
+
+#define CY8CTMA140_MAX_FINGERS		4
+
+#define CY8CTMA140_GET_FINGERS		0x00
+#define CY8CTMA140_GET_FW_INFO		0x19
+
+/* This message also fits some bytes for touchkeys, if used */
+#define CY8CTMA140_PACKET_SIZE		31
+
+#define CY8CTMA140_INVALID_BUFFER_BIT	5
+
+struct cy8ctma140 {
+	struct input_dev *input;
+	struct touchscreen_properties props;
+	struct device *dev;
+	struct i2c_client *client;
+	struct regulator_bulk_data regulators[2];
+	u8 prev_fingers;
+	u8 prev_f1id;
+	u8 prev_f2id;
+};
+
+static void cy8ctma140_report(struct cy8ctma140 *ts, u8 *data, int n_fingers)
+{
+	static const u8 contact_offsets[] = { 0x03, 0x09, 0x10, 0x16 };
+	u8 *buf;
+	u16 x, y;
+	u8 w;
+	u8 id;
+	int slot;
+	int i;
+
+	for (i = 0; i < n_fingers; i++) {
+		buf = &data[contact_offsets[i]];
+
+		/*
+		 * Odd contacts have contact ID in the lower nibble of
+		 * the preceding byte, whereas even contacts have it in
+		 * the upper nibble of the following byte.
+		 */
+		id = i % 2 ? buf[-1] & 0x0f : buf[5] >> 4;
+		slot = input_mt_get_slot_by_key(ts->input, id);
+		if (slot < 0)
+			continue;
+
+		x = get_unaligned_be16(buf);
+		y = get_unaligned_be16(buf + 2);
+		w = buf[4];
+
+		dev_dbg(ts->dev, "finger %d: ID %02x (%d, %d) w: %d\n",
+			slot, id, x, y, w);
+
+		input_mt_slot(ts->input, slot);
+		input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, true);
+		touchscreen_report_pos(ts->input, &ts->props, x, y, true);
+		input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, w);
+	}
+
+	input_mt_sync_frame(ts->input);
+	input_sync(ts->input);
+}
+
+static irqreturn_t cy8ctma140_irq_thread(int irq, void *d)
+{
+	struct cy8ctma140 *ts = d;
+	u8 cmdbuf[] = { CY8CTMA140_GET_FINGERS };
+	u8 buf[CY8CTMA140_PACKET_SIZE];
+	struct i2c_msg msg[] = {
+		{
+			.addr = ts->client->addr,
+			.flags = 0,
+			.len = sizeof(cmdbuf),
+			.buf = cmdbuf,
+		}, {
+			.addr = ts->client->addr,
+			.flags = I2C_M_RD,
+			.len = sizeof(buf),
+			.buf = buf,
+		},
+	};
+	u8 n_fingers;
+	int ret;
+
+	ret = i2c_transfer(ts->client->adapter, msg, ARRAY_SIZE(msg));
+	if (ret != ARRAY_SIZE(msg)) {
+		if (ret < 0)
+			dev_err(ts->dev, "error reading message: %d\n", ret);
+		else
+			dev_err(ts->dev, "wrong number of messages\n");
+		goto out;
+	}
+
+	if (buf[1] & BIT(CY8CTMA140_INVALID_BUFFER_BIT)) {
+		dev_dbg(ts->dev, "invalid event\n");
+		goto out;
+	}
+
+	n_fingers = buf[2] & 0x0f;
+	if (n_fingers > CY8CTMA140_MAX_FINGERS) {
+		dev_err(ts->dev, "unexpected number of fingers: %d\n",
+			n_fingers);
+		goto out;
+	}
+
+	cy8ctma140_report(ts, buf, n_fingers);
+
+out:
+	return IRQ_HANDLED;
+}
+
+static int cy8ctma140_init(struct cy8ctma140 *ts)
+{
+	u8 addr[1];
+	u8 buf[5];
+	int ret;
+
+	addr[0] = CY8CTMA140_GET_FW_INFO;
+	ret = i2c_master_send(ts->client, addr, 1);
+	if (ret < 0) {
+		dev_err(ts->dev, "error sending FW info message\n");
+		return ret;
+	}
+	ret = i2c_master_recv(ts->client, buf, 5);
+	if (ret < 0) {
+		dev_err(ts->dev, "error receiving FW info message\n");
+		return ret;
+	}
+	if (ret != 5) {
+		dev_err(ts->dev, "got only %d bytes\n", ret);
+		return -EIO;
+	}
+
+	dev_dbg(ts->dev, "vendor %c%c, HW ID %.2d, FW ver %.4d\n",
+		buf[0], buf[1], buf[3], buf[4]);
+
+	return 0;
+}
+
+static int cy8ctma140_power_up(struct cy8ctma140 *ts)
+{
+	int error;
+
+	error = regulator_bulk_enable(ARRAY_SIZE(ts->regulators),
+				      ts->regulators);
+	if (error) {
+		dev_err(ts->dev, "failed to enable regulators\n");
+		return error;
+	}
+
+	msleep(250);
+
+	return 0;
+}
+
+static void cy8ctma140_power_down(struct cy8ctma140 *ts)
+{
+	regulator_bulk_disable(ARRAY_SIZE(ts->regulators),
+			       ts->regulators);
+}
+
+/* Called from the registered devm action */
+static void cy8ctma140_power_off_action(void *d)
+{
+	struct cy8ctma140 *ts = d;
+
+	cy8ctma140_power_down(ts);
+}
+
+static int cy8ctma140_probe(struct i2c_client *client,
+			    const struct i2c_device_id *id)
+{
+	struct cy8ctma140 *ts;
+	struct input_dev *input;
+	struct device *dev = &client->dev;
+	int error;
+
+	ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
+	if (!ts)
+		return -ENOMEM;
+
+	input = devm_input_allocate_device(dev);
+	if (!input)
+		return -ENOMEM;
+
+	ts->dev = dev;
+	ts->client = client;
+	ts->input = input;
+
+	input_set_capability(input, EV_ABS, ABS_MT_POSITION_X);
+	input_set_capability(input, EV_ABS, ABS_MT_POSITION_Y);
+	/* One byte for width 0..255 so this is the limit */
+	input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
+	/*
+	 * This sets up event max/min capabilities and fuzz.
+	 * Some DT properties are compulsory so we do not need
+	 * to provide defaults for X/Y max or pressure max.
+	 *
+	 * We just initialize a very simple MT touchscreen here,
+	 * some devices use the capability of this touchscreen to
+	 * provide touchkeys, and in that case this needs to be
+	 * extended to handle touchkey input.
+	 *
+	 * The firmware takes care of finger tracking and dropping
+	 * invalid ranges.
+	 */
+	touchscreen_parse_properties(input, true, &ts->props);
+	input_abs_set_fuzz(input, ABS_MT_POSITION_X, 0);
+	input_abs_set_fuzz(input, ABS_MT_POSITION_Y, 0);
+
+	error = input_mt_init_slots(input, CY8CTMA140_MAX_FINGERS,
+				  INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
+	if (error)
+		return error;
+
+	input->name = CY8CTMA140_NAME;
+	input->id.bustype = BUS_I2C;
+	input_set_drvdata(input, ts);
+
+	/*
+	 * VCPIN is the analog voltage supply
+	 * VDD is the digital voltage supply
+	 * since the voltage range of VDD overlaps that of VCPIN,
+	 * many designs to just supply both with a single voltage
+	 * source of ~3.3 V.
+	 */
+	ts->regulators[0].supply = "vcpin";
+	ts->regulators[1].supply = "vdd";
+	error = devm_regulator_bulk_get(dev, ARRAY_SIZE(ts->regulators),
+				      ts->regulators);
+	if (error) {
+		if (error != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get regulators %d\n",
+				error);
+		return error;
+	}
+
+	error = cy8ctma140_power_up(ts);
+	if (error)
+		return error;
+
+	error = devm_add_action_or_reset(dev, cy8ctma140_power_off_action, ts);
+	if (error) {
+		dev_err(dev, "failed to install power off handler\n");
+		return error;
+	}
+
+	error = devm_request_threaded_irq(dev, client->irq,
+					  NULL, cy8ctma140_irq_thread,
+					  IRQF_ONESHOT, CY8CTMA140_NAME, ts);
+	if (error) {
+		dev_err(dev, "irq %d busy? error %d\n", client->irq, error);
+		return error;
+	}
+
+	error = cy8ctma140_init(ts);
+	if (error)
+		return error;
+
+	error = input_register_device(input);
+	if (error)
+		return error;
+
+	i2c_set_clientdata(client, ts);
+
+	return 0;
+}
+
+static int __maybe_unused cy8ctma140_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct cy8ctma140 *ts = i2c_get_clientdata(client);
+
+	if (!device_may_wakeup(&client->dev))
+		cy8ctma140_power_down(ts);
+
+	return 0;
+}
+
+static int __maybe_unused cy8ctma140_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct cy8ctma140 *ts = i2c_get_clientdata(client);
+	int error;
+
+	if (!device_may_wakeup(&client->dev)) {
+		error = cy8ctma140_power_up(ts);
+		if (error)
+			return error;
+	}
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(cy8ctma140_pm, cy8ctma140_suspend, cy8ctma140_resume);
+
+static const struct i2c_device_id cy8ctma140_idtable[] = {
+	{ CY8CTMA140_NAME, 0 },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(i2c, cy8ctma140_idtable);
+
+static const struct of_device_id cy8ctma140_of_match[] = {
+	{ .compatible = "cypress,cy8ctma140", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, cy8ctma140_of_match);
+
+static struct i2c_driver cy8ctma140_driver = {
+	.driver		= {
+		.name	= CY8CTMA140_NAME,
+		.pm	= &cy8ctma140_pm,
+		.of_match_table = cy8ctma140_of_match,
+	},
+	.id_table	= cy8ctma140_idtable,
+	.probe		= cy8ctma140_probe,
+};
+module_i2c_driver(cy8ctma140_driver);
+
+MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
+MODULE_DESCRIPTION("CY8CTMA140 TouchScreen Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/input/touchscreen/cyttsp4_core.c b/drivers/input/touchscreen/cyttsp4_core.c
index 6bcffc930384a4f5fbd8cbf0d4c334b934bd470c..02a73d9a4defed6b066913c88cc40ebbfd1dd77f 100644
--- a/drivers/input/touchscreen/cyttsp4_core.c
+++ b/drivers/input/touchscreen/cyttsp4_core.c
@@ -744,8 +744,7 @@ static void cyttsp4_report_slot_liftoff(struct cyttsp4_mt_data *md,
 
 	for (t = 0; t < max_slots; t++) {
 		input_mt_slot(md->input, t);
-		input_mt_report_slot_state(md->input,
-			MT_TOOL_FINGER, false);
+		input_mt_report_slot_inactive(md->input);
 	}
 }
 
@@ -845,7 +844,7 @@ static void cyttsp4_final_sync(struct input_dev *input, int max_slots, int *ids)
 		if (ids[t])
 			continue;
 		input_mt_slot(input, t);
-		input_mt_report_slot_state(input, MT_TOOL_FINGER, false);
+		input_mt_report_slot_inactive(input);
 	}
 
 	input_sync(input);
diff --git a/drivers/input/touchscreen/cyttsp_core.c b/drivers/input/touchscreen/cyttsp_core.c
index 3f5d463dbeed6fa484a40d6e9c019313278bce35..697aa2c158f74e9e0aa591503420cfe312b5b728 100644
--- a/drivers/input/touchscreen/cyttsp_core.c
+++ b/drivers/input/touchscreen/cyttsp_core.c
@@ -340,7 +340,7 @@ static void cyttsp_report_tchdata(struct cyttsp *ts)
 			continue;
 
 		input_mt_slot(input, i);
-		input_mt_report_slot_state(input, MT_TOOL_FINGER, false);
+		input_mt_report_slot_inactive(input);
 	}
 
 	input_sync(input);
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index d2587724c52ada7256bec4da1dcd96798dedbf8f..3a4f18d3450d13ca33b5823dc3f81e61c48036df 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -38,6 +38,9 @@
 #define WORK_REGISTER_NUM_X		0x33
 #define WORK_REGISTER_NUM_Y		0x34
 
+#define PMOD_REGISTER_ACTIVE		0x00
+#define PMOD_REGISTER_HIBERNATE		0x03
+
 #define M09_REGISTER_THRESHOLD		0x80
 #define M09_REGISTER_GAIN		0x92
 #define M09_REGISTER_OFFSET		0x93
@@ -53,6 +56,7 @@
 
 #define WORK_REGISTER_OPMODE		0x3c
 #define FACTORY_REGISTER_OPMODE		0x01
+#define PMOD_REGISTER_OPMODE		0xa5
 
 #define TOUCH_EVENT_DOWN		0x00
 #define TOUCH_EVENT_UP			0x01
@@ -65,6 +69,12 @@
 #define EDT_RAW_DATA_RETRIES		100
 #define EDT_RAW_DATA_DELAY		1000 /* usec */
 
+enum edt_pmode {
+	EDT_PMODE_NOT_SUPPORTED,
+	EDT_PMODE_HIBERNATE,
+	EDT_PMODE_POWEROFF,
+};
+
 enum edt_ver {
 	EDT_M06,
 	EDT_M09,
@@ -103,6 +113,7 @@ struct edt_ft5x06_ts_data {
 
 	struct mutex mutex;
 	bool factory_mode;
+	enum edt_pmode suspend_mode;
 	int threshold;
 	int gain;
 	int offset;
@@ -527,6 +538,29 @@ static const struct attribute_group edt_ft5x06_attr_group = {
 	.attrs = edt_ft5x06_attrs,
 };
 
+static void edt_ft5x06_restore_reg_parameters(struct edt_ft5x06_ts_data *tsdata)
+{
+	struct edt_reg_addr *reg_addr = &tsdata->reg_addr;
+
+	edt_ft5x06_register_write(tsdata, reg_addr->reg_threshold,
+				  tsdata->threshold);
+	edt_ft5x06_register_write(tsdata, reg_addr->reg_gain,
+				  tsdata->gain);
+	if (reg_addr->reg_offset != NO_REGISTER)
+		edt_ft5x06_register_write(tsdata, reg_addr->reg_offset,
+					  tsdata->offset);
+	if (reg_addr->reg_offset_x != NO_REGISTER)
+		edt_ft5x06_register_write(tsdata, reg_addr->reg_offset_x,
+					  tsdata->offset_x);
+	if (reg_addr->reg_offset_y != NO_REGISTER)
+		edt_ft5x06_register_write(tsdata, reg_addr->reg_offset_y,
+					  tsdata->offset_y);
+	if (reg_addr->reg_report_rate != NO_REGISTER)
+		edt_ft5x06_register_write(tsdata, reg_addr->reg_report_rate,
+				  tsdata->report_rate);
+
+}
+
 #ifdef CONFIG_DEBUG_FS
 static int edt_ft5x06_factory_mode(struct edt_ft5x06_ts_data *tsdata)
 {
@@ -592,7 +626,6 @@ static int edt_ft5x06_work_mode(struct edt_ft5x06_ts_data *tsdata)
 {
 	struct i2c_client *client = tsdata->client;
 	int retries = EDT_SWITCH_MODE_RETRIES;
-	struct edt_reg_addr *reg_addr = &tsdata->reg_addr;
 	int ret;
 	int error;
 
@@ -624,24 +657,7 @@ static int edt_ft5x06_work_mode(struct edt_ft5x06_ts_data *tsdata)
 	kfree(tsdata->raw_buffer);
 	tsdata->raw_buffer = NULL;
 
-	/* restore parameters */
-	edt_ft5x06_register_write(tsdata, reg_addr->reg_threshold,
-				  tsdata->threshold);
-	edt_ft5x06_register_write(tsdata, reg_addr->reg_gain,
-				  tsdata->gain);
-	if (reg_addr->reg_offset != NO_REGISTER)
-		edt_ft5x06_register_write(tsdata, reg_addr->reg_offset,
-					  tsdata->offset);
-	if (reg_addr->reg_offset_x != NO_REGISTER)
-		edt_ft5x06_register_write(tsdata, reg_addr->reg_offset_x,
-					  tsdata->offset_x);
-	if (reg_addr->reg_offset_y != NO_REGISTER)
-		edt_ft5x06_register_write(tsdata, reg_addr->reg_offset_y,
-					  tsdata->offset_y);
-	if (reg_addr->reg_report_rate != NO_REGISTER)
-		edt_ft5x06_register_write(tsdata, reg_addr->reg_report_rate,
-				  tsdata->report_rate);
-
+	edt_ft5x06_restore_reg_parameters(tsdata);
 	enable_irq(client->irq);
 
 	return 0;
@@ -762,9 +778,8 @@ static const struct file_operations debugfs_raw_data_fops = {
 	.read = edt_ft5x06_debugfs_raw_data_read,
 };
 
-static void
-edt_ft5x06_ts_prepare_debugfs(struct edt_ft5x06_ts_data *tsdata,
-			      const char *debugfs_name)
+static void edt_ft5x06_ts_prepare_debugfs(struct edt_ft5x06_ts_data *tsdata,
+					  const char *debugfs_name)
 {
 	tsdata->debug_dir = debugfs_create_dir(debugfs_name, NULL);
 
@@ -777,8 +792,7 @@ edt_ft5x06_ts_prepare_debugfs(struct edt_ft5x06_ts_data *tsdata,
 			    tsdata->debug_dir, tsdata, &debugfs_raw_data_fops);
 }
 
-static void
-edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)
+static void edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)
 {
 	debugfs_remove_recursive(tsdata->debug_dir);
 	kfree(tsdata->raw_buffer);
@@ -786,14 +800,17 @@ edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)
 
 #else
 
-static inline void
-edt_ft5x06_ts_prepare_debugfs(struct edt_ft5x06_ts_data *tsdata,
-			      const char *debugfs_name)
+static int edt_ft5x06_factory_mode(struct edt_ft5x06_ts_data *tsdata)
+{
+	return -ENOSYS;
+}
+
+static void edt_ft5x06_ts_prepare_debugfs(struct edt_ft5x06_ts_data *tsdata,
+					  const char *debugfs_name)
 {
 }
 
-static inline void
-edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)
+static void edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)
 {
 }
 
@@ -938,19 +955,25 @@ static void edt_ft5x06_ts_get_defaults(struct device *dev,
 
 	error = device_property_read_u32(dev, "offset", &val);
 	if (!error) {
-		edt_ft5x06_register_write(tsdata, reg_addr->reg_offset, val);
+		if (reg_addr->reg_offset != NO_REGISTER)
+			edt_ft5x06_register_write(tsdata,
+						  reg_addr->reg_offset, val);
 		tsdata->offset = val;
 	}
 
 	error = device_property_read_u32(dev, "offset-x", &val);
 	if (!error) {
-		edt_ft5x06_register_write(tsdata, reg_addr->reg_offset_x, val);
+		if (reg_addr->reg_offset_x != NO_REGISTER)
+			edt_ft5x06_register_write(tsdata,
+						  reg_addr->reg_offset_x, val);
 		tsdata->offset_x = val;
 	}
 
 	error = device_property_read_u32(dev, "offset-y", &val);
 	if (!error) {
-		edt_ft5x06_register_write(tsdata, reg_addr->reg_offset_y, val);
+		if (reg_addr->reg_offset_y != NO_REGISTER)
+			edt_ft5x06_register_write(tsdata,
+						  reg_addr->reg_offset_y, val);
 		tsdata->offset_y = val;
 	}
 }
@@ -1114,6 +1137,19 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
 		return error;
 	}
 
+	/*
+	 * Check which sleep modes we can support. Power-off requieres the
+	 * reset-pin to ensure correct power-down/power-up behaviour. Start with
+	 * the EDT_PMODE_POWEROFF test since this is the deepest possible sleep
+	 * mode.
+	 */
+	if (tsdata->reset_gpio)
+		tsdata->suspend_mode = EDT_PMODE_POWEROFF;
+	else if (tsdata->wake_gpio)
+		tsdata->suspend_mode = EDT_PMODE_HIBERNATE;
+	else
+		tsdata->suspend_mode = EDT_PMODE_NOT_SUPPORTED;
+
 	if (tsdata->wake_gpio) {
 		usleep_range(5000, 6000);
 		gpiod_set_value_cansleep(tsdata->wake_gpio, 1);
@@ -1227,6 +1263,102 @@ static int edt_ft5x06_ts_remove(struct i2c_client *client)
 	return 0;
 }
 
+static int __maybe_unused edt_ft5x06_ts_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
+	struct gpio_desc *reset_gpio = tsdata->reset_gpio;
+	int ret;
+
+	if (device_may_wakeup(dev))
+		return 0;
+
+	if (tsdata->suspend_mode == EDT_PMODE_NOT_SUPPORTED)
+		return 0;
+
+	/* Enter hibernate mode. */
+	ret = edt_ft5x06_register_write(tsdata, PMOD_REGISTER_OPMODE,
+					PMOD_REGISTER_HIBERNATE);
+	if (ret)
+		dev_warn(dev, "Failed to set hibernate mode\n");
+
+	if (tsdata->suspend_mode == EDT_PMODE_HIBERNATE)
+		return 0;
+
+	/*
+	 * Power-off according the datasheet. Cut the power may leaf the irq
+	 * line in an undefined state depending on the host pull resistor
+	 * settings. Disable the irq to avoid adjusting each host till the
+	 * device is back in a full functional state.
+	 */
+	disable_irq(tsdata->client->irq);
+
+	gpiod_set_value_cansleep(reset_gpio, 1);
+	usleep_range(1000, 2000);
+
+	ret = regulator_disable(tsdata->vcc);
+	if (ret)
+		dev_warn(dev, "Failed to disable vcc\n");
+
+	return 0;
+}
+
+static int __maybe_unused edt_ft5x06_ts_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
+	int ret = 0;
+
+	if (device_may_wakeup(dev))
+		return 0;
+
+	if (tsdata->suspend_mode == EDT_PMODE_NOT_SUPPORTED)
+		return 0;
+
+	if (tsdata->suspend_mode == EDT_PMODE_POWEROFF) {
+		struct gpio_desc *reset_gpio = tsdata->reset_gpio;
+
+		/*
+		 * We can't check if the regulator is a dummy or a real
+		 * regulator. So we need to specify the 5ms reset time (T_rst)
+		 * here instead of the 100us T_rtp time. We also need to wait
+		 * 300ms in case it was a real supply and the power was cutted
+		 * of. Toggle the reset pin is also a way to exit the hibernate
+		 * mode.
+		 */
+		gpiod_set_value_cansleep(reset_gpio, 1);
+		usleep_range(5000, 6000);
+
+		ret = regulator_enable(tsdata->vcc);
+		if (ret) {
+			dev_err(dev, "Failed to enable vcc\n");
+			return ret;
+		}
+
+		usleep_range(1000, 2000);
+		gpiod_set_value_cansleep(reset_gpio, 0);
+		msleep(300);
+
+		edt_ft5x06_restore_reg_parameters(tsdata);
+		enable_irq(tsdata->client->irq);
+
+		if (tsdata->factory_mode)
+			ret = edt_ft5x06_factory_mode(tsdata);
+	} else {
+		struct gpio_desc *wake_gpio = tsdata->wake_gpio;
+
+		gpiod_set_value_cansleep(wake_gpio, 0);
+		usleep_range(5000, 6000);
+		gpiod_set_value_cansleep(wake_gpio, 1);
+	}
+
+
+	return ret;
+}
+
+static SIMPLE_DEV_PM_OPS(edt_ft5x06_ts_pm_ops,
+			 edt_ft5x06_ts_suspend, edt_ft5x06_ts_resume);
+
 static const struct edt_i2c_chip_data edt_ft5x06_data = {
 	.max_support_points = 5,
 };
@@ -1265,6 +1397,8 @@ static struct i2c_driver edt_ft5x06_ts_driver = {
 	.driver = {
 		.name = "edt_ft5x06",
 		.of_match_table = edt_ft5x06_of_match,
+		.pm = &edt_ft5x06_ts_pm_ops,
+		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
 	},
 	.id_table = edt_ft5x06_ts_id,
 	.probe    = edt_ft5x06_ts_probe,
diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c
index 2289f9638116c3beb93be701069561331852a800..233cb1085bbdd0f93469e2b405bb109f189d39ca 100644
--- a/drivers/input/touchscreen/elants_i2c.c
+++ b/drivers/input/touchscreen/elants_i2c.c
@@ -33,6 +33,7 @@
 #include <linux/slab.h>
 #include <linux/firmware.h>
 #include <linux/input/mt.h>
+#include <linux/input/touchscreen.h>
 #include <linux/acpi.h>
 #include <linux/of.h>
 #include <linux/gpio/consumer.h>
@@ -89,6 +90,7 @@
 /* FW read command, 0x53 0x?? 0x0, 0x01 */
 #define E_ELAN_INFO_FW_VER	0x00
 #define E_ELAN_INFO_BC_VER	0x10
+#define E_ELAN_INFO_REK		0xE0
 #define E_ELAN_INFO_TEST_VER	0xE0
 #define E_ELAN_INFO_FW_ID	0xF0
 #define E_INFO_OSR		0xD6
@@ -136,6 +138,7 @@ struct elants_data {
 	unsigned int y_res;
 	unsigned int x_max;
 	unsigned int y_max;
+	struct touchscreen_properties prop;
 
 	enum elants_state state;
 	enum elants_iap_mode iap_mode;
@@ -189,7 +192,8 @@ static int elants_i2c_read(struct i2c_client *client, void *data, size_t size)
 
 static int elants_i2c_execute_command(struct i2c_client *client,
 				      const u8 *cmd, size_t cmd_size,
-				      u8 *resp, size_t resp_size)
+				      u8 *resp, size_t resp_size,
+				      int retries, const char *cmd_name)
 {
 	struct i2c_msg msgs[2];
 	int ret;
@@ -209,30 +213,55 @@ static int elants_i2c_execute_command(struct i2c_client *client,
 		break;
 
 	default:
-		dev_err(&client->dev, "%s: invalid command %*ph\n",
-			__func__, (int)cmd_size, cmd);
+		dev_err(&client->dev, "(%s): invalid command: %*ph\n",
+			cmd_name, (int)cmd_size, cmd);
 		return -EINVAL;
 	}
 
-	msgs[0].addr = client->addr;
-	msgs[0].flags = client->flags & I2C_M_TEN;
-	msgs[0].len = cmd_size;
-	msgs[0].buf = (u8 *)cmd;
+	for (;;) {
+		msgs[0].addr = client->addr;
+		msgs[0].flags = client->flags & I2C_M_TEN;
+		msgs[0].len = cmd_size;
+		msgs[0].buf = (u8 *)cmd;
+
+		msgs[1].addr = client->addr;
+		msgs[1].flags = (client->flags & I2C_M_TEN) | I2C_M_RD;
+		msgs[1].flags |= I2C_M_RD;
+		msgs[1].len = resp_size;
+		msgs[1].buf = resp;
+
+		ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+		if (ret < 0) {
+			if (--retries > 0) {
+				dev_dbg(&client->dev,
+					"(%s) I2C transfer failed: %pe (retrying)\n",
+					cmd_name, ERR_PTR(ret));
+				continue;
+			}
 
-	msgs[1].addr = client->addr;
-	msgs[1].flags = client->flags & I2C_M_TEN;
-	msgs[1].flags |= I2C_M_RD;
-	msgs[1].len = resp_size;
-	msgs[1].buf = resp;
+			dev_err(&client->dev,
+				"(%s) I2C transfer failed: %pe\n",
+				cmd_name, ERR_PTR(ret));
+			return ret;
+		}
 
-	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
-	if (ret < 0)
-		return ret;
+		if (ret != ARRAY_SIZE(msgs) ||
+		    resp[FW_HDR_TYPE] != expected_response) {
+			if (--retries > 0) {
+				dev_dbg(&client->dev,
+					"(%s) unexpected response: %*ph (retrying)\n",
+					cmd_name, ret, resp);
+				continue;
+			}
 
-	if (ret != ARRAY_SIZE(msgs) || resp[FW_HDR_TYPE] != expected_response)
-		return -EIO;
+			dev_err(&client->dev,
+				"(%s) unexpected response: %*ph\n",
+				cmd_name, ret, resp);
+			return -EIO;
+		}
 
-	return 0;
+		return 0;
+	}
 }
 
 static int elants_i2c_calibrate(struct elants_data *ts)
@@ -305,27 +334,21 @@ static u16 elants_i2c_parse_version(u8 *buf)
 static int elants_i2c_query_hw_version(struct elants_data *ts)
 {
 	struct i2c_client *client = ts->client;
-	int error, retry_cnt;
+	int retry_cnt = MAX_RETRIES;
 	const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_FW_ID, 0x00, 0x01 };
 	u8 resp[HEADER_SIZE];
+	int error;
 
-	for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
+	while (retry_cnt--) {
 		error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
-						   resp, sizeof(resp));
-		if (!error) {
-			ts->hw_version = elants_i2c_parse_version(resp);
-			if (ts->hw_version != 0xffff)
-				return 0;
-		}
-
-		dev_dbg(&client->dev, "read fw id error=%d, buf=%*phC\n",
-			error, (int)sizeof(resp), resp);
-	}
+						   resp, sizeof(resp), 1,
+						   "read fw id");
+		if (error)
+			return error;
 
-	if (error) {
-		dev_err(&client->dev,
-			"Failed to read fw id: %d\n", error);
-		return error;
+		ts->hw_version = elants_i2c_parse_version(resp);
+		if (ts->hw_version != 0xffff)
+			return 0;
 	}
 
 	dev_err(&client->dev, "Invalid fw id: %#04x\n", ts->hw_version);
@@ -336,26 +359,27 @@ static int elants_i2c_query_hw_version(struct elants_data *ts)
 static int elants_i2c_query_fw_version(struct elants_data *ts)
 {
 	struct i2c_client *client = ts->client;
-	int error, retry_cnt;
+	int retry_cnt = MAX_RETRIES;
 	const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_FW_VER, 0x00, 0x01 };
 	u8 resp[HEADER_SIZE];
+	int error;
 
-	for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
+	while (retry_cnt--) {
 		error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
-						   resp, sizeof(resp));
-		if (!error) {
-			ts->fw_version = elants_i2c_parse_version(resp);
-			if (ts->fw_version != 0x0000 &&
-			    ts->fw_version != 0xffff)
-				return 0;
-		}
+						   resp, sizeof(resp), 1,
+						   "read fw version");
+		if (error)
+			return error;
+
+		ts->fw_version = elants_i2c_parse_version(resp);
+		if (ts->fw_version != 0x0000 && ts->fw_version != 0xffff)
+			return 0;
 
-		dev_dbg(&client->dev, "read fw version error=%d, buf=%*phC\n",
-			error, (int)sizeof(resp), resp);
+		dev_dbg(&client->dev, "(read fw version) resp %*phC\n",
+			(int)sizeof(resp), resp);
 	}
 
-	dev_err(&client->dev,
-		"Failed to read fw version or fw version is invalid\n");
+	dev_err(&client->dev, "Invalid fw ver: %#04x\n", ts->fw_version);
 
 	return -EINVAL;
 }
@@ -363,30 +387,24 @@ static int elants_i2c_query_fw_version(struct elants_data *ts)
 static int elants_i2c_query_test_version(struct elants_data *ts)
 {
 	struct i2c_client *client = ts->client;
-	int error, retry_cnt;
+	int error;
 	u16 version;
 	const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_TEST_VER, 0x00, 0x01 };
 	u8 resp[HEADER_SIZE];
 
-	for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
-		error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
-						   resp, sizeof(resp));
-		if (!error) {
-			version = elants_i2c_parse_version(resp);
-			ts->test_version = version >> 8;
-			ts->solution_version = version & 0xff;
-
-			return 0;
-		}
-
-		dev_dbg(&client->dev,
-			"read test version error rc=%d, buf=%*phC\n",
-			error, (int)sizeof(resp), resp);
+	error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
+					   resp, sizeof(resp), MAX_RETRIES,
+					   "read test version");
+	if (error) {
+		dev_err(&client->dev, "Failed to read test version\n");
+		return error;
 	}
 
-	dev_err(&client->dev, "Failed to read test version\n");
+	version = elants_i2c_parse_version(resp);
+	ts->test_version = version >> 8;
+	ts->solution_version = version & 0xff;
 
-	return -EINVAL;
+	return 0;
 }
 
 static int elants_i2c_query_bc_version(struct elants_data *ts)
@@ -398,13 +416,10 @@ static int elants_i2c_query_bc_version(struct elants_data *ts)
 	int error;
 
 	error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
-					   resp, sizeof(resp));
-	if (error) {
-		dev_err(&client->dev,
-			"read BC version error=%d, buf=%*phC\n",
-			error, (int)sizeof(resp), resp);
+					   resp, sizeof(resp), 1,
+					   "read BC version");
+	if (error)
 		return error;
-	}
 
 	version = elants_i2c_parse_version(resp);
 	ts->bc_version = version >> 8;
@@ -436,12 +451,10 @@ static int elants_i2c_query_ts_info(struct elants_data *ts)
 	error = elants_i2c_execute_command(client,
 					   get_resolution_cmd,
 					   sizeof(get_resolution_cmd),
-					   resp, sizeof(resp));
-	if (error) {
-		dev_err(&client->dev, "get resolution command failed: %d\n",
-			error);
+					   resp, sizeof(resp), 1,
+					   "get resolution");
+	if (error)
 		return error;
-	}
 
 	rows = resp[2] + resp[6] + resp[10];
 	cols = resp[3] + resp[7] + resp[11];
@@ -449,36 +462,29 @@ static int elants_i2c_query_ts_info(struct elants_data *ts)
 	/* Process mm_to_pixel information */
 	error = elants_i2c_execute_command(client,
 					   get_osr_cmd, sizeof(get_osr_cmd),
-					   resp, sizeof(resp));
-	if (error) {
-		dev_err(&client->dev, "get osr command failed: %d\n",
-			error);
+					   resp, sizeof(resp), 1, "get osr");
+	if (error)
 		return error;
-	}
 
 	osr = resp[3];
 
 	error = elants_i2c_execute_command(client,
 					   get_physical_scan_cmd,
 					   sizeof(get_physical_scan_cmd),
-					   resp, sizeof(resp));
-	if (error) {
-		dev_err(&client->dev, "get physical scan command failed: %d\n",
-			error);
+					   resp, sizeof(resp), 1,
+					   "get physical scan");
+	if (error)
 		return error;
-	}
 
 	phy_x = get_unaligned_be16(&resp[2]);
 
 	error = elants_i2c_execute_command(client,
 					   get_physical_drive_cmd,
 					   sizeof(get_physical_drive_cmd),
-					   resp, sizeof(resp));
-	if (error) {
-		dev_err(&client->dev, "get physical drive command failed: %d\n",
-			error);
+					   resp, sizeof(resp), 1,
+					   "get physical drive");
+	if (error)
 		return error;
-	}
 
 	phy_y = get_unaligned_be16(&resp[2]);
 
@@ -633,11 +639,10 @@ static int elants_i2c_validate_remark_id(struct elants_data *ts,
 
 	/* Compare TS Remark ID and FW Remark ID */
 	error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
-					resp, sizeof(resp));
-	if (error) {
-		dev_err(&client->dev, "failed to query Remark ID: %d\n", error);
+					   resp, sizeof(resp),
+					   1, "read Remark ID");
+	if (error)
 		return error;
-	}
 
 	ts_remark_id = get_unaligned_be16(&resp[3]);
 
@@ -875,8 +880,7 @@ static void elants_i2c_mt_event(struct elants_data *ts, u8 *buf)
 
 			input_mt_slot(input, i);
 			input_mt_report_slot_state(input, tool_type, true);
-			input_event(input, EV_ABS, ABS_MT_POSITION_X, x);
-			input_event(input, EV_ABS, ABS_MT_POSITION_Y, y);
+			touchscreen_report_pos(input, &ts->prop, x, y, true);
 			input_event(input, EV_ABS, ABS_MT_PRESSURE, p);
 			input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, w);
 
@@ -1017,7 +1021,7 @@ static irqreturn_t elants_i2c_irq(int irq, void *_dev)
  */
 static ssize_t calibrate_store(struct device *dev,
 			       struct device_attribute *attr,
-			      const char *buf, size_t count)
+			       const char *buf, size_t count)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct elants_data *ts = i2c_get_clientdata(client);
@@ -1063,8 +1067,28 @@ static ssize_t show_iap_mode(struct device *dev,
 				"Normal" : "Recovery");
 }
 
+static ssize_t show_calibration_count(struct device *dev,
+				      struct device_attribute *attr, char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_REK, 0x00, 0x01 };
+	u8 resp[HEADER_SIZE];
+	u16 rek_count;
+	int error;
+
+	error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
+					   resp, sizeof(resp), 1,
+					   "read ReK status");
+	if (error)
+		return sprintf(buf, "%d\n", error);
+
+	rek_count = get_unaligned_be16(&resp[2]);
+	return sprintf(buf, "0x%04x\n", rek_count);
+}
+
 static DEVICE_ATTR_WO(calibrate);
 static DEVICE_ATTR(iap_mode, S_IRUGO, show_iap_mode, NULL);
+static DEVICE_ATTR(calibration_count, S_IRUGO, show_calibration_count, NULL);
 static DEVICE_ATTR(update_fw, S_IWUSR, NULL, write_update_fw);
 
 struct elants_version_attribute {
@@ -1120,6 +1144,7 @@ static struct attribute *elants_attributes[] = {
 	&dev_attr_calibrate.attr,
 	&dev_attr_update_fw.attr,
 	&dev_attr_iap_mode.attr,
+	&dev_attr_calibration_count.attr,
 
 	&elants_ver_attr_fw_version.dattr.attr,
 	&elants_ver_attr_hw_version.dattr.attr,
@@ -1290,25 +1315,7 @@ static int elants_i2c_probe(struct i2c_client *client,
 	ts->input->name = "Elan Touchscreen";
 	ts->input->id.bustype = BUS_I2C;
 
-	__set_bit(BTN_TOUCH, ts->input->keybit);
-	__set_bit(EV_ABS, ts->input->evbit);
-	__set_bit(EV_KEY, ts->input->evbit);
-
-	/* Single touch input params setup */
-	input_set_abs_params(ts->input, ABS_X, 0, ts->x_max, 0, 0);
-	input_set_abs_params(ts->input, ABS_Y, 0, ts->y_max, 0, 0);
-	input_set_abs_params(ts->input, ABS_PRESSURE, 0, 255, 0, 0);
-	input_abs_set_res(ts->input, ABS_X, ts->x_res);
-	input_abs_set_res(ts->input, ABS_Y, ts->y_res);
-
 	/* Multitouch input params setup */
-	error = input_mt_init_slots(ts->input, MAX_CONTACT_NUM,
-				    INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
-	if (error) {
-		dev_err(&client->dev,
-			"failed to initialize MT slots: %d\n", error);
-		return error;
-	}
 
 	input_set_abs_params(ts->input, ABS_MT_POSITION_X, 0, ts->x_max, 0, 0);
 	input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, ts->y_max, 0, 0);
@@ -1320,6 +1327,16 @@ static int elants_i2c_probe(struct i2c_client *client,
 	input_abs_set_res(ts->input, ABS_MT_POSITION_Y, ts->y_res);
 	input_abs_set_res(ts->input, ABS_MT_TOUCH_MAJOR, 1);
 
+	touchscreen_parse_properties(ts->input, true, &ts->prop);
+
+	error = input_mt_init_slots(ts->input, MAX_CONTACT_NUM,
+				    INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
+	if (error) {
+		dev_err(&client->dev,
+			"failed to initialize MT slots: %d\n", error);
+		return error;
+	}
+
 	error = input_register_device(ts->input);
 	if (error) {
 		dev_err(&client->dev,
diff --git a/drivers/input/touchscreen/melfas_mip4.c b/drivers/input/touchscreen/melfas_mip4.c
index 247c3aaba2d8f30fbb3643d36c54e2e8e65e0e09..f67efdd040b2438c2df51138bdd4d022237dab9d 100644
--- a/drivers/input/touchscreen/melfas_mip4.c
+++ b/drivers/input/touchscreen/melfas_mip4.c
@@ -391,7 +391,7 @@ static void mip4_clear_input(struct mip4_ts *ts)
 	/* Screen */
 	for (i = 0; i < MIP4_MAX_FINGERS; i++) {
 		input_mt_slot(ts->input, i);
-		input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, 0);
+		input_mt_report_slot_inactive(ts->input);
 	}
 
 	/* Keys */
@@ -534,7 +534,7 @@ static void mip4_report_touch(struct mip4_ts *ts, u8 *packet)
 	} else {
 		/* Release event */
 		input_mt_slot(ts->input, id);
-		input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, 0);
+		input_mt_report_slot_inactive(ts->input);
 	}
 
 	input_mt_sync_frame(ts->input);
diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c
index 2ef1adaed9afb65201dcc2cdfe05103474bcbc8e..1f96657310b751f336e4218016a01a1dad02dc98 100644
--- a/drivers/input/touchscreen/mms114.c
+++ b/drivers/input/touchscreen/mms114.c
@@ -54,6 +54,7 @@
 enum mms_type {
 	TYPE_MMS114	= 114,
 	TYPE_MMS152	= 152,
+	TYPE_MMS345L	= 345,
 };
 
 struct mms114_data {
@@ -250,6 +251,15 @@ static int mms114_get_version(struct mms114_data *data)
 	int error;
 
 	switch (data->type) {
+	case TYPE_MMS345L:
+		error = __mms114_read_reg(data, MMS152_FW_REV, 3, buf);
+		if (error)
+			return error;
+
+		dev_info(dev, "TSP FW Rev: bootloader 0x%x / core 0x%x / config 0x%x\n",
+			 buf[0], buf[1], buf[2]);
+		break;
+
 	case TYPE_MMS152:
 		error = __mms114_read_reg(data, MMS152_FW_REV, 3, buf);
 		if (error)
@@ -287,8 +297,8 @@ static int mms114_setup_regs(struct mms114_data *data)
 	if (error < 0)
 		return error;
 
-	/* MMS152 has no configuration or power on registers */
-	if (data->type == TYPE_MMS152)
+	/* Only MMS114 has configuration and power on registers */
+	if (data->type != TYPE_MMS114)
 		return 0;
 
 	error = mms114_set_active(data, true);
@@ -547,7 +557,7 @@ static int __maybe_unused mms114_suspend(struct device *dev)
 	/* Release all touch */
 	for (id = 0; id < MMS114_MAX_TOUCH; id++) {
 		input_mt_slot(input_dev, id);
-		input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, false);
+		input_mt_report_slot_inactive(input_dev);
 	}
 
 	input_mt_report_pointer_emulation(input_dev, true);
@@ -597,6 +607,9 @@ static const struct of_device_id mms114_dt_match[] = {
 	}, {
 		.compatible = "melfas,mms152",
 		.data = (void *)TYPE_MMS152,
+	}, {
+		.compatible = "melfas,mms345l",
+		.data = (void *)TYPE_MMS345L,
 	},
 	{ }
 };
diff --git a/drivers/input/touchscreen/raspberrypi-ts.c b/drivers/input/touchscreen/raspberrypi-ts.c
index 0e2e08f3f433c73f63a07fc275057b096ebb216a..ef6aaed217cfb5094126e06c5ea932769f878bc7 100644
--- a/drivers/input/touchscreen/raspberrypi-ts.c
+++ b/drivers/input/touchscreen/raspberrypi-ts.c
@@ -100,7 +100,7 @@ static void rpi_ts_poll(struct input_dev *input)
 	released_ids = ts->known_ids & ~modified_ids;
 	for_each_set_bit(i, &released_ids, RPI_TS_MAX_SUPPORTED_POINTS) {
 		input_mt_slot(input, i);
-		input_mt_report_slot_state(input, MT_TOOL_FINGER, 0);
+		input_mt_report_slot_inactive(input);
 		modified_ids &= ~(BIT(i));
 	}
 	ts->known_ids = modified_ids;
diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index b6f95f20f92442678c4de31a6d7576dea0cb7056..b54cc64e4ea64f632f3382fee15bb6bda491a55b 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -198,7 +198,7 @@ static void stmfts_report_contact_release(struct stmfts_data *sdata,
 	u8 slot_id = (event[0] & STMFTS_MASK_TOUCH_ID) >> 4;
 
 	input_mt_slot(sdata->input, slot_id);
-	input_mt_report_slot_state(sdata->input, MT_TOOL_FINGER, false);
+	input_mt_report_slot_inactive(sdata->input);
 
 	input_sync(sdata->input);
 }
diff --git a/include/linux/input/gp2ap002a00f.h b/include/linux/input/gp2ap002a00f.h
deleted file mode 100644
index 3614a13a82978371b9332ae106ba84f612c07176..0000000000000000000000000000000000000000
--- a/include/linux/input/gp2ap002a00f.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _GP2AP002A00F_H_
-#define _GP2AP002A00F_H_
-
-#include <linux/i2c.h>
-
-#define GP2A_I2C_NAME "gp2ap002a00f"
-
-/**
- * struct gp2a_platform_data - Sharp gp2ap002a00f proximity platform data
- * @vout_gpio: The gpio connected to the object detected pin (VOUT)
- * @wakeup: Set to true if the proximity can wake the device from suspend
- * @hw_setup: Callback for setting up hardware such as gpios and vregs
- * @hw_shutdown: Callback for properly shutting down hardware
- */
-struct gp2a_platform_data {
-	int vout_gpio;
-	bool wakeup;
-	int (*hw_setup)(struct i2c_client *client);
-	int (*hw_shutdown)(struct i2c_client *client);
-};
-
-#endif
diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h
index 9e409bb1364214eb07c56934225c19d6da09b3f2..3b8580bd33c146badadfd0bde7101cba99d17c96 100644
--- a/include/linux/input/mt.h
+++ b/include/linux/input/mt.h
@@ -100,6 +100,11 @@ static inline bool input_is_mt_axis(int axis)
 bool input_mt_report_slot_state(struct input_dev *dev,
 				unsigned int tool_type, bool active);
 
+static inline void input_mt_report_slot_inactive(struct input_dev *dev)
+{
+	input_mt_report_slot_state(dev, 0, false);
+}
+
 void input_mt_report_finger_count(struct input_dev *dev, int count);
 void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count);
 void input_mt_drop_unused(struct input_dev *dev);