summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml4
-rw-r--r--Documentation/devicetree/bindings/input/azoteq,iqs7222.yaml25
-rw-r--r--Documentation/devicetree/bindings/input/gpio-beeper.txt13
-rw-r--r--Documentation/devicetree/bindings/input/gpio-beeper.yaml33
-rw-r--r--Documentation/devicetree/bindings/input/qcom,pm8921-pwrkey.yaml75
-rw-r--r--Documentation/devicetree/bindings/input/qcom,pm8xxx-pwrkey.txt46
-rw-r--r--Documentation/devicetree/bindings/input/ti,drv260x.txt50
-rw-r--r--Documentation/devicetree/bindings/input/ti,drv260x.yaml109
-rw-r--r--Documentation/devicetree/bindings/input/touchscreen/cypress,tt21000.yaml106
-rw-r--r--Documentation/devicetree/bindings/input/touchscreen/egalax-ts.txt4
-rw-r--r--Documentation/devicetree/bindings/input/touchscreen/himax,hx83112b.yaml63
-rw-r--r--Documentation/devicetree/bindings/input/touchscreen/hynitron,cstxxx.yaml65
-rw-r--r--Documentation/devicetree/bindings/input/touchscreen/mstar,msg2638.yaml8
-rw-r--r--Documentation/devicetree/bindings/vendor-prefixes.yaml2
-rw-r--r--MAINTAINERS9
-rw-r--r--arch/arm/boot/dts/imx6qdl-sabreauto.dtsi4
-rw-r--r--arch/arm/boot/dts/imx6qdl-sabresd.dtsi8
-rw-r--r--arch/arm/mach-s3c/mach-crag6410.c1
-rw-r--r--drivers/hid/hid-debug.c3
-rw-r--r--drivers/hid/hid-input.c3
-rw-r--r--drivers/hid/i2c-hid/i2c-hid-acpi.c5
-rw-r--r--drivers/hid/i2c-hid/i2c-hid-core.c24
-rw-r--r--drivers/iio/adc/twl4030-madc.c1
-rw-r--r--drivers/input/input.c3
-rw-r--r--drivers/input/joystick/Kconfig1
-rw-r--r--drivers/input/joystick/as5011.c5
-rw-r--r--drivers/input/joystick/psxpad-spi.c9
-rw-r--r--drivers/input/keyboard/Kconfig10
-rw-r--r--drivers/input/keyboard/adp5588-keys.c5
-rw-r--r--drivers/input/keyboard/adp5589-keys.c14
-rw-r--r--drivers/input/keyboard/cap11xx.c6
-rw-r--r--drivers/input/keyboard/cros_ec_keyb.c6
-rw-r--r--drivers/input/keyboard/cypress-sf.c10
-rw-r--r--drivers/input/keyboard/dlink-dir685-touchkeys.c9
-rw-r--r--drivers/input/keyboard/ep93xx_keypad.c10
-rw-r--r--drivers/input/keyboard/gpio_keys.c8
-rw-r--r--drivers/input/keyboard/ipaq-micro-keys.c10
-rw-r--r--drivers/input/keyboard/lm8323.c11
-rw-r--r--drivers/input/keyboard/lm8333.c5
-rw-r--r--drivers/input/keyboard/lpc32xx-keys.c8
-rw-r--r--drivers/input/keyboard/matrix_keypad.c11
-rw-r--r--drivers/input/keyboard/max7359_keypad.c11
-rw-r--r--drivers/input/keyboard/mcs_touchkey.c14
-rw-r--r--drivers/input/keyboard/mpr121_touchkey.c13
-rw-r--r--drivers/input/keyboard/mtk-pmic-keys.c10
-rw-r--r--drivers/input/keyboard/nomadik-ske-keypad.c8
-rw-r--r--drivers/input/keyboard/pmic8xxx-keypad.c8
-rw-r--r--drivers/input/keyboard/pxa27x_keypad.c8
-rw-r--r--drivers/input/keyboard/qt1050.c8
-rw-r--r--drivers/input/keyboard/qt1070.c11
-rw-r--r--drivers/input/keyboard/qt2160.c5
-rw-r--r--drivers/input/keyboard/sh_keysc.c8
-rw-r--r--drivers/input/keyboard/spear-keyboard.c9
-rw-r--r--drivers/input/keyboard/st-keyscan.c7
-rw-r--r--drivers/input/keyboard/stmpe-keypad.c1
-rw-r--r--drivers/input/keyboard/tc3589x-keypad.c8
-rw-r--r--drivers/input/keyboard/tca6416-keypad.c14
-rw-r--r--drivers/input/keyboard/tca8418_keypad.c5
-rw-r--r--drivers/input/keyboard/tegra-kbc.c7
-rw-r--r--drivers/input/keyboard/tm2-touchkey.c15
-rw-r--r--drivers/input/misc/Kconfig4
-rw-r--r--drivers/input/misc/ad714x-i2c.c5
-rw-r--r--drivers/input/misc/adxl34x-i2c.c5
-rw-r--r--drivers/input/misc/apanel.c5
-rw-r--r--drivers/input/misc/atmel_captouch.c9
-rw-r--r--drivers/input/misc/bma150.c5
-rw-r--r--drivers/input/misc/cma3000_d0x_i2c.c5
-rw-r--r--drivers/input/misc/da7280.c5
-rw-r--r--drivers/input/misc/drv260x.c5
-rw-r--r--drivers/input/misc/drv2665.c5
-rw-r--r--drivers/input/misc/drv2667.c5
-rw-r--r--drivers/input/misc/ibm-panel.c5
-rw-r--r--drivers/input/misc/iqs7222.c504
-rw-r--r--drivers/input/misc/kxtj9.c5
-rw-r--r--drivers/input/misc/max8997_haptic.c7
-rw-r--r--drivers/input/misc/mma8450.c5
-rw-r--r--drivers/input/misc/pcf8574_keypad.c4
-rw-r--r--drivers/input/mouse/cyapa.c5
-rw-r--r--drivers/input/mouse/elan_i2c_core.c20
-rw-r--r--drivers/input/mouse/synaptics_i2c.c5
-rw-r--r--drivers/input/rmi4/rmi_i2c.c5
-rw-r--r--drivers/input/rmi4/rmi_smbus.c5
-rw-r--r--drivers/input/touchscreen/Kconfig42
-rw-r--r--drivers/input/touchscreen/Makefile3
-rw-r--r--drivers/input/touchscreen/ad7879-i2c.c5
-rw-r--r--drivers/input/touchscreen/ar1021_i2c.c5
-rw-r--r--drivers/input/touchscreen/atmel_mxt_ts.c4
-rw-r--r--drivers/input/touchscreen/auo-pixcir-ts.c5
-rw-r--r--drivers/input/touchscreen/bu21013_ts.c5
-rw-r--r--drivers/input/touchscreen/bu21029_ts.c5
-rw-r--r--drivers/input/touchscreen/chipone_icn8318.c5
-rw-r--r--drivers/input/touchscreen/cy8ctma140.c5
-rw-r--r--drivers/input/touchscreen/cy8ctmg110_ts.c5
-rw-r--r--drivers/input/touchscreen/cyttsp4_i2c.c5
-rw-r--r--drivers/input/touchscreen/cyttsp5.c900
-rw-r--r--drivers/input/touchscreen/cyttsp_i2c.c5
-rw-r--r--drivers/input/touchscreen/edt-ft5x06.c6
-rw-r--r--drivers/input/touchscreen/eeti_ts.c5
-rw-r--r--drivers/input/touchscreen/egalax_ts.c54
-rw-r--r--drivers/input/touchscreen/ektf2127.c5
-rw-r--r--drivers/input/touchscreen/elants_i2c.c28
-rw-r--r--drivers/input/touchscreen/goodix.c5
-rw-r--r--drivers/input/touchscreen/hideep.c5
-rw-r--r--drivers/input/touchscreen/himax_hx83112b.c364
-rw-r--r--drivers/input/touchscreen/hycon-hy46xx.c5
-rw-r--r--drivers/input/touchscreen/hynitron_cstxxx.c498
-rw-r--r--drivers/input/touchscreen/ili210x.c6
-rw-r--r--drivers/input/touchscreen/ilitek_ts_i2c.c5
-rw-r--r--drivers/input/touchscreen/iqs5xx.c5
-rw-r--r--drivers/input/touchscreen/max11801_ts.c5
-rw-r--r--drivers/input/touchscreen/mcs5000_ts.c5
-rw-r--r--drivers/input/touchscreen/melfas_mip4.c4
-rw-r--r--drivers/input/touchscreen/migor_ts.c5
-rw-r--r--drivers/input/touchscreen/mms114.c5
-rw-r--r--drivers/input/touchscreen/msg2638.c197
-rw-r--r--drivers/input/touchscreen/pixcir_i2c_ts.c6
-rw-r--r--drivers/input/touchscreen/raydium_i2c_ts.c12
-rw-r--r--drivers/input/touchscreen/rohm_bu21023.c5
-rw-r--r--drivers/input/touchscreen/s6sy761.c5
-rw-r--r--drivers/input/touchscreen/silead.c6
-rw-r--r--drivers/input/touchscreen/sis_i2c.c5
-rw-r--r--drivers/input/touchscreen/st1232.c6
-rw-r--r--drivers/input/touchscreen/stmfts.c5
-rw-r--r--drivers/input/touchscreen/sx8654.c6
-rw-r--r--drivers/input/touchscreen/tps6507x-ts.c2
-rw-r--r--drivers/input/touchscreen/tsc2004.c5
-rw-r--r--drivers/input/touchscreen/tsc2007_core.c6
-rw-r--r--drivers/input/touchscreen/wacom_i2c.c5
-rw-r--r--drivers/input/touchscreen/wdt87xx_i2c.c5
-rw-r--r--drivers/input/touchscreen/zet6223.c5
-rw-r--r--drivers/input/touchscreen/zforce_ts.c5
-rw-r--r--include/linux/fixp-arith.h1
-rw-r--r--include/linux/mfd/max8997.h3
-rw-r--r--include/uapi/linux/input-event-codes.h3
134 files changed, 3098 insertions, 809 deletions
diff --git a/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml b/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml
index 5d631f7137e7..5efceb313879 100644
--- a/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml
+++ b/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml
@@ -16,7 +16,9 @@ properties:
- const: allwinner,sun4i-a10-lradc-keys
- const: allwinner,sun8i-a83t-r-lradc
- items:
- - const: allwinner,sun50i-a64-lradc
+ - enum:
+ - allwinner,suniv-f1c100s-lradc
+ - allwinner,sun50i-a64-lradc
- const: allwinner,sun8i-a83t-r-lradc
- const: allwinner,sun50i-r329-lradc
- items:
diff --git a/Documentation/devicetree/bindings/input/azoteq,iqs7222.yaml b/Documentation/devicetree/bindings/input/azoteq,iqs7222.yaml
index 02e605fac408..9ddba7f2e7aa 100644
--- a/Documentation/devicetree/bindings/input/azoteq,iqs7222.yaml
+++ b/Documentation/devicetree/bindings/input/azoteq,iqs7222.yaml
@@ -473,9 +473,6 @@ patternProperties:
Specifies whether the event is to be interpreted as a key (1)
or a switch (5).
- required:
- - linux,code
-
additionalProperties: false
dependencies:
@@ -501,7 +498,7 @@ patternProperties:
azoteq,slider-size:
$ref: /schemas/types.yaml#/definitions/uint32
- minimum: 0
+ minimum: 1
maximum: 65535
description:
Specifies the slider's one-dimensional resolution, equal to the
@@ -575,9 +572,9 @@ patternProperties:
linux,code: true
azoteq,gesture-max-ms:
- multipleOf: 4
+ multipleOf: 16
minimum: 0
- maximum: 1020
+ maximum: 4080
description:
Specifies the length of time (in ms) within which a tap, swipe
or flick gesture must be completed in order to be acknowledged
@@ -585,9 +582,9 @@ patternProperties:
gesture applies to all remaining swipe or flick gestures.
azoteq,gesture-min-ms:
- multipleOf: 4
+ multipleOf: 16
minimum: 0
- maximum: 124
+ maximum: 496
description:
Specifies the length of time (in ms) for which a tap gesture must
be held in order to be acknowledged by the device.
@@ -620,9 +617,6 @@ patternProperties:
GPIO, they must all be of the same type (proximity, touch or
slider gesture).
- required:
- - linux,code
-
additionalProperties: false
required:
@@ -693,6 +687,7 @@ allOf:
properties:
azoteq,slider-size:
multipleOf: 16
+ minimum: 16
maximum: 4080
azoteq,top-speed:
@@ -935,14 +930,14 @@ examples:
event-tap {
linux,code = <KEY_PLAYPAUSE>;
- azoteq,gesture-max-ms = <600>;
- azoteq,gesture-min-ms = <24>;
+ azoteq,gesture-max-ms = <400>;
+ azoteq,gesture-min-ms = <32>;
};
event-flick-pos {
linux,code = <KEY_NEXTSONG>;
- azoteq,gesture-max-ms = <600>;
- azoteq,gesture-dist = <816>;
+ azoteq,gesture-max-ms = <800>;
+ azoteq,gesture-dist = <800>;
};
event-flick-neg {
diff --git a/Documentation/devicetree/bindings/input/gpio-beeper.txt b/Documentation/devicetree/bindings/input/gpio-beeper.txt
deleted file mode 100644
index a5086e37fce6..000000000000
--- a/Documentation/devicetree/bindings/input/gpio-beeper.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-* GPIO beeper device tree bindings
-
-Register a beeper connected to GPIO pin.
-
-Required properties:
-- compatible: Should be "gpio-beeper".
-- gpios: From common gpio binding; gpio connection to beeper enable pin.
-
-Example:
- beeper: beeper {
- compatible = "gpio-beeper";
- gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>;
- };
diff --git a/Documentation/devicetree/bindings/input/gpio-beeper.yaml b/Documentation/devicetree/bindings/input/gpio-beeper.yaml
new file mode 100644
index 000000000000..290372add3d5
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/gpio-beeper.yaml
@@ -0,0 +1,33 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/gpio-beeper.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: GPIO controlled beeper
+
+maintainers:
+ - Fabio Estevam <festevam@denx.de>
+
+properties:
+ compatible:
+ const: gpio-beeper
+
+ gpios:
+ maxItems: 1
+ description:
+ GPIO that drives the beeper.
+
+required:
+ - compatible
+ - gpios
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+ beeper {
+ compatible = "gpio-beeper";
+ gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>;
+ };
diff --git a/Documentation/devicetree/bindings/input/qcom,pm8921-pwrkey.yaml b/Documentation/devicetree/bindings/input/qcom,pm8921-pwrkey.yaml
new file mode 100644
index 000000000000..12c74c083258
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/qcom,pm8921-pwrkey.yaml
@@ -0,0 +1,75 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/qcom,pm8921-pwrkey.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm PM8921 PMIC Power Key
+
+maintainers:
+ - Bjorn Andersson <andersson@kernel.org>
+
+allOf:
+ - $ref: input.yaml#
+
+properties:
+ compatible:
+ oneOf:
+ - enum:
+ - qcom,pm8921-pwrkey
+ - qcom,pm8058-pwrkey
+ - items:
+ - enum:
+ - qcom,pm8018-pwrkey
+ - const: qcom,pm8921-pwrkey
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ items:
+ - description: key release
+ - description: key press
+
+ debounce:
+ description:
+ Time in microseconds that key must be pressed or
+ released for state change interrupt to trigger.
+ $ref: /schemas/types.yaml#/definitions/uint32
+
+ pull-up:
+ description:
+ Presence of this property indicates that the KPDPWR_N
+ pin should be configured for pull up.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+required:
+ - compatible
+ - reg
+ - interrupts
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+ ssbi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pmic@0 {
+ reg = <0x0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pwrkey@1c {
+ compatible = "qcom,pm8921-pwrkey";
+ reg = <0x1c>;
+ interrupt-parent = <&pmicint>;
+ interrupts = <50 IRQ_TYPE_EDGE_RISING>, <51 IRQ_TYPE_EDGE_RISING>;
+ debounce = <15625>;
+ pull-up;
+ };
+ };
+ };
+...
diff --git a/Documentation/devicetree/bindings/input/qcom,pm8xxx-pwrkey.txt b/Documentation/devicetree/bindings/input/qcom,pm8xxx-pwrkey.txt
deleted file mode 100644
index 588536cc96ed..000000000000
--- a/Documentation/devicetree/bindings/input/qcom,pm8xxx-pwrkey.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-Qualcomm PM8xxx PMIC Power Key
-
-PROPERTIES
-
-- compatible:
- Usage: required
- Value type: <string>
- Definition: must be one of:
- "qcom,pm8058-pwrkey"
- "qcom,pm8921-pwrkey"
-
-- reg:
- Usage: required
- Value type: <prop-encoded-array>
- Definition: address of power key control register
-
-- interrupts:
- Usage: required
- Value type: <prop-encoded-array>
- Definition: the first interrupt specifies the key release interrupt
- and the second interrupt specifies the key press interrupt.
- The format of the specifier is defined by the binding
- document describing the node's interrupt parent.
-
-- debounce:
- Usage: optional
- Value type: <u32>
- Definition: time in microseconds that key must be pressed or release
- for state change interrupt to trigger.
-
-- pull-up:
- Usage: optional
- Value type: <empty>
- Definition: presence of this property indicates that the KPDPWR_N pin
- should be configured for pull up.
-
-EXAMPLE
-
- pwrkey@1c {
- compatible = "qcom,pm8921-pwrkey";
- reg = <0x1c>;
- interrupt-parent = <&pmicintc>;
- interrupts = <50 1>, <51 1>;
- debounce = <15625>;
- pull-up;
- };
diff --git a/Documentation/devicetree/bindings/input/ti,drv260x.txt b/Documentation/devicetree/bindings/input/ti,drv260x.txt
deleted file mode 100644
index 4c5312eaaa85..000000000000
--- a/Documentation/devicetree/bindings/input/ti,drv260x.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-* Texas Instruments - drv260x Haptics driver family
-
-Required properties:
- - compatible - One of:
- "ti,drv2604" - DRV2604
- "ti,drv2605" - DRV2605
- "ti,drv2605l" - DRV2605L
- - reg - I2C slave address
- - vbat-supply - Required supply regulator
- - mode - Power up mode of the chip (defined in include/dt-bindings/input/ti-drv260x.h)
- DRV260X_LRA_MODE - Linear Resonance Actuator mode (Piezoelectric)
- DRV260X_LRA_NO_CAL_MODE - This is a LRA Mode but there is no calibration
- sequence during init. And the device is configured for real
- time playback mode (RTP mode).
- DRV260X_ERM_MODE - Eccentric Rotating Mass mode (Rotary vibrator)
- - library-sel - These are ROM based waveforms pre-programmed into the IC.
- This should be set to set the library to use at power up.
- (defined in include/dt-bindings/input/ti-drv260x.h)
- DRV260X_LIB_EMPTY - Do not use a pre-programmed library
- DRV260X_ERM_LIB_A - Pre-programmed Library
- DRV260X_ERM_LIB_B - Pre-programmed Library
- DRV260X_ERM_LIB_C - Pre-programmed Library
- DRV260X_ERM_LIB_D - Pre-programmed Library
- DRV260X_ERM_LIB_E - Pre-programmed Library
- DRV260X_ERM_LIB_F - Pre-programmed Library
- DRV260X_LIB_LRA - Pre-programmed LRA Library
-
-Optional properties:
- - enable-gpio - gpio pin to enable/disable the device.
- - vib-rated-mv - The rated voltage of the actuator in millivolts.
- If this is not set then the value will be defaulted to
- 3.2 v.
- - vib-overdrive-mv - The overdrive voltage of the actuator in millivolts.
- If this is not set then the value will be defaulted to
- 3.2 v.
-Example:
-
-haptics: haptics@5a {
- compatible = "ti,drv2605l";
- reg = <0x5a>;
- vbat-supply = <&vbat>;
- enable-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>;
- mode = <DRV260X_LRA_MODE>;
- library-sel = <DRV260X_LIB_LRA>;
- vib-rated-mv = <3200>;
- vib-overdrive-mv = <3200>;
-}
-
-For more product information please see the link below:
-http://www.ti.com/product/drv2605
diff --git a/Documentation/devicetree/bindings/input/ti,drv260x.yaml b/Documentation/devicetree/bindings/input/ti,drv260x.yaml
new file mode 100644
index 000000000000..c6245c5b9e2e
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/ti,drv260x.yaml
@@ -0,0 +1,109 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/ti,drv260x.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments - drv260x Haptics driver family
+
+maintainers:
+ - Andrew Davis <afd@ti.com>
+
+properties:
+ compatible:
+ enum:
+ - ti,drv2604
+ - ti,drv2605
+ - ti,drv2605l
+
+ reg:
+ maxItems: 1
+
+ vbat-supply:
+ description: Power supply to the haptic motor
+
+ # TODO: Deprecate 'mode' in favor of differently named property
+ mode:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Power up mode of the chip
+ (defined in include/dt-bindings/input/ti-drv260x.h)
+
+ DRV260X_LRA_MODE
+ Linear Resonance Actuator mode (Piezoelectric)
+
+ DRV260X_LRA_NO_CAL_MODE
+ This is a LRA Mode but there is no calibration sequence during init.
+ And the device is configured for real time playback mode (RTP mode).
+
+ DRV260X_ERM_MODE
+ Eccentric Rotating Mass mode (Rotary vibrator)
+ enum: [ 0, 1, 2 ]
+
+ library-sel:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ These are ROM based waveforms pre-programmed into the IC.
+ This should be set to set the library to use at power up.
+ (defined in include/dt-bindings/input/ti-drv260x.h)
+
+ DRV260X_LIB_EMPTY - Do not use a pre-programmed library
+ DRV260X_ERM_LIB_A - Pre-programmed Library
+ DRV260X_ERM_LIB_B - Pre-programmed Library
+ DRV260X_ERM_LIB_C - Pre-programmed Library
+ DRV260X_ERM_LIB_D - Pre-programmed Library
+ DRV260X_ERM_LIB_E - Pre-programmed Library
+ DRV260X_ERM_LIB_F - Pre-programmed Library
+ DRV260X_LIB_LRA - Pre-programmed LRA Library
+ enum: [ 0, 1, 2, 3, 4, 5, 6, 7 ]
+
+ enable-gpio:
+ maxItems: 1
+ deprecated: true
+
+ enable-gpios:
+ maxItems: 1
+
+ vib-rated-mv:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ The rated voltage of the actuator in millivolts.
+ If this is not set then the value will be defaulted to 3200 mV.
+ default: 3200
+
+ vib-overdrive-mv:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ The overdrive voltage of the actuator in millivolts.
+ If this is not set then the value will be defaulted to 3200 mV.
+ default: 3200
+
+required:
+ - compatible
+ - reg
+ - enable-gpios
+ - mode
+ - library-sel
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/input/ti-drv260x.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ haptics@5a {
+ compatible = "ti,drv2605l";
+ reg = <0x5a>;
+ vbat-supply = <&vbat>;
+ enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
+ mode = <DRV260X_LRA_MODE>;
+ library-sel = <DRV260X_LIB_LRA>;
+ vib-rated-mv = <3200>;
+ vib-overdrive-mv = <3200>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/input/touchscreen/cypress,tt21000.yaml b/Documentation/devicetree/bindings/input/touchscreen/cypress,tt21000.yaml
new file mode 100644
index 000000000000..1959ec394768
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/cypress,tt21000.yaml
@@ -0,0 +1,106 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/touchscreen/cypress,tt21000.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Cypress TT21000 touchscreen controller
+
+description: The Cypress TT21000 series (also known as "CYTTSP5" after
+ the marketing name Cypress TrueTouch Standard Product series 5).
+
+maintainers:
+ - Alistair Francis <alistair@alistair23.me>
+
+allOf:
+ - $ref: touchscreen.yaml#
+
+properties:
+ compatible:
+ const: cypress,tt21000
+
+ reg:
+ maxItems: 1
+
+ '#address-cells':
+ const: 1
+
+ '#size-cells':
+ const: 0
+
+ interrupts:
+ maxItems: 1
+
+ vdd-supply:
+ description: Regulator for voltage.
+
+ reset-gpios:
+ maxItems: 1
+
+ linux,keycodes:
+ description: EV_ABS specific event code generated by the axis.
+
+patternProperties:
+ "^button@[0-9]+$":
+ type: object
+ $ref: ../input.yaml#
+ properties:
+ reg:
+ maxItems: 1
+ linux,keycodes:
+ description: Keycode to emit
+
+ required:
+ - reg
+ - linux,keycodes
+
+ additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - vdd-supply
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/input/linux-event-codes.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ touchscreen@24 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ compatible = "cypress,tt21000";
+ reg = <0x24>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&tp_reset_ds203>;
+ interrupt-parent = <&pio>;
+ interrupts = <1 5 IRQ_TYPE_LEVEL_LOW>;
+ reset-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>;
+ vdd-supply = <&reg_touch>;
+
+ button@0 {
+ reg = <0>;
+ linux,keycodes = <KEY_HOMEPAGE>;
+ };
+
+ button@1 {
+ reg = <1>;
+ linux,keycodes = <KEY_MENU>;
+ };
+
+ button@2 {
+ reg = <2>;
+ linux,keycodes = <KEY_BACK>;
+ };
+ };
+ };
+...
diff --git a/Documentation/devicetree/bindings/input/touchscreen/egalax-ts.txt b/Documentation/devicetree/bindings/input/touchscreen/egalax-ts.txt
index 92fb2620f5e2..ebbe93810574 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/egalax-ts.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/egalax-ts.txt
@@ -13,6 +13,6 @@ Example:
compatible = "eeti,egalax_ts";
reg = <0x04>;
interrupt-parent = <&gpio1>;
- interrupts = <9 2>;
- wakeup-gpios = <&gpio1 9 0>;
+ interrupts = <9 IRQ_TYPE_LEVEL_LOW>;
+ wakeup-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
};
diff --git a/Documentation/devicetree/bindings/input/touchscreen/himax,hx83112b.yaml b/Documentation/devicetree/bindings/input/touchscreen/himax,hx83112b.yaml
new file mode 100644
index 000000000000..be2ba185c086
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/himax,hx83112b.yaml
@@ -0,0 +1,63 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/touchscreen/himax,hx83112b.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Himax hx83112b touchscreen controller bindings
+
+maintainers:
+ - Job Noorman <job@noorman.info>
+
+allOf:
+ - $ref: touchscreen.yaml#
+
+properties:
+ compatible:
+ enum:
+ - himax,hx83112b
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ reset-gpios:
+ maxItems: 1
+
+ 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
+ - reset-gpios
+ - touchscreen-size-x
+ - touchscreen-size-y
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/gpio/gpio.h>
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ touchscreen@48 {
+ compatible = "himax,hx83112b";
+ reg = <0x48>;
+ interrupt-parent = <&tlmm>;
+ interrupts = <65 IRQ_TYPE_LEVEL_LOW>;
+ touchscreen-size-x = <1080>;
+ touchscreen-size-y = <2160>;
+ reset-gpios = <&tlmm 64 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/input/touchscreen/hynitron,cstxxx.yaml b/Documentation/devicetree/bindings/input/touchscreen/hynitron,cstxxx.yaml
new file mode 100644
index 000000000000..9cb5d4af00f7
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/hynitron,cstxxx.yaml
@@ -0,0 +1,65 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/touchscreen/hynitron,cstxxx.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Hynitron cstxxx series touchscreen controller
+
+description: |
+ Bindings for Hynitron cstxxx series multi-touch touchscreen
+ controllers.
+
+maintainers:
+ - Chris Morgan <macromorgan@hotmail.com>
+
+allOf:
+ - $ref: touchscreen.yaml#
+
+properties:
+ compatible:
+ enum:
+ - hynitron,cst340
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ reset-gpios:
+ maxItems: 1
+
+ touchscreen-size-x: true
+ touchscreen-size-y: true
+ touchscreen-inverted-x: true
+ touchscreen-inverted-y: true
+ touchscreen-swapped-x-y: true
+
+additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - reset-gpios
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ touchscreen@1a {
+ compatible = "hynitron,cst340";
+ reg = <0x1a>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
+ reset-gpios = <&gpio4 6 GPIO_ACTIVE_LOW>;
+ touchscreen-size-x = <640>;
+ touchscreen-size-y = <480>;
+ };
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/input/touchscreen/mstar,msg2638.yaml b/Documentation/devicetree/bindings/input/touchscreen/mstar,msg2638.yaml
index 3a42c23faf6f..af4f954de958 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/mstar,msg2638.yaml
+++ b/Documentation/devicetree/bindings/input/touchscreen/mstar,msg2638.yaml
@@ -14,7 +14,9 @@ allOf:
properties:
compatible:
- const: mstar,msg2638
+ enum:
+ - mstar,msg2138
+ - mstar,msg2638
reg:
const: 0x26
@@ -34,6 +36,10 @@ properties:
touchscreen-size-x: true
touchscreen-size-y: true
+ linux,keycodes:
+ minItems: 1
+ maxItems: 4
+
additionalProperties: false
required:
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 83ba9c4aac67..d5f1c4c1ef45 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -573,6 +573,8 @@ patternProperties:
description: Hycon Technology Corp.
"^hydis,.*":
description: Hydis Technologies
+ "^hynitron,.*":
+ description: Shanghai Hynitron Microelectronics Co. Ltd.
"^hynix,.*":
description: SK Hynix Inc.
"^hyundai,.*":
diff --git a/MAINTAINERS b/MAINTAINERS
index 9c9f0e298bbb..bfffbe8c35e2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9220,6 +9220,13 @@ W: http://www.highpoint-tech.com
F: Documentation/scsi/hptiop.rst
F: drivers/scsi/hptiop.c
+HIMAX HX83112B TOUCHSCREEN SUPPORT
+M: Job Noorman <job@noorman.info>
+L: linux-input@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/input/touchscreen/himax,hx83112b.yaml
+F: drivers/input/touchscreen/himax_hx83112b.c
+
HIPPI
M: Jes Sorensen <jes@trained-monkey.org>
L: linux-hippi@sunsite.dk
@@ -19024,7 +19031,7 @@ F: drivers/video/fbdev/sis/
F: include/video/sisfb.h
SIS I2C TOUCHSCREEN DRIVER
-M: Mika Penttilä <mika.penttila@nextfour.com>
+M: Mika Penttilä <mpenttil@redhat.com>
L: linux-input@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/input/touchscreen/sis_i2c.txt
diff --git a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
index 3dbb460ef102..eebcfe12142e 100644
--- a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
@@ -452,8 +452,8 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_egalax_int>;
interrupt-parent = <&gpio2>;
- interrupts = <28 IRQ_TYPE_EDGE_FALLING>;
- wakeup-gpios = <&gpio2 28 GPIO_ACTIVE_HIGH>;
+ interrupts = <28 IRQ_TYPE_LEVEL_LOW>;
+ wakeup-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>;
};
};
diff --git a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
index 37482a9023fc..09f4c2fa3ad6 100644
--- a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
@@ -311,8 +311,8 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c2_egalax_int>;
interrupt-parent = <&gpio6>;
- interrupts = <8 IRQ_TYPE_EDGE_FALLING>;
- wakeup-gpios = <&gpio6 8 GPIO_ACTIVE_HIGH>;
+ interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
+ wakeup-gpios = <&gpio6 8 GPIO_ACTIVE_LOW>;
};
ov5640: camera@3c {
@@ -450,8 +450,8 @@
compatible = "eeti,egalax_ts";
reg = <0x04>;
interrupt-parent = <&gpio6>;
- interrupts = <7 2>;
- wakeup-gpios = <&gpio6 7 0>;
+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+ wakeup-gpios = <&gpio6 7 GPIO_ACTIVE_LOW>;
};
magnetometer@e {
diff --git a/arch/arm/mach-s3c/mach-crag6410.c b/arch/arm/mach-s3c/mach-crag6410.c
index 9a45474d1bf7..2ecb85856e24 100644
--- a/arch/arm/mach-s3c/mach-crag6410.c
+++ b/arch/arm/mach-s3c/mach-crag6410.c
@@ -14,6 +14,7 @@
#include <linux/fb.h>
#include <linux/io.h>
#include <linux/init.h>
+#include <linux/input-event-codes.h>
#include <linux/gpio.h>
#include <linux/gpio/machine.h>
#include <linux/leds.h>
diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c
index 2ca6ab600bc9..e213bdde543a 100644
--- a/drivers/hid/hid-debug.c
+++ b/drivers/hid/hid-debug.c
@@ -971,6 +971,9 @@ static const char *keys[KEY_MAX + 1] = {
[KEY_ASSISTANT] = "Assistant",
[KEY_KBD_LAYOUT_NEXT] = "KbdLayoutNext",
[KEY_EMOJI_PICKER] = "EmojiPicker",
+ [KEY_CAMERA_ACCESS_ENABLE] = "CameraAccessEnable",
+ [KEY_CAMERA_ACCESS_DISABLE] = "CameraAccessDisable",
+ [KEY_CAMERA_ACCESS_TOGGLE] = "CameraAccessToggle",
[KEY_DICTATE] = "Dictate",
[KEY_BRIGHTNESS_MIN] = "BrightnessMin",
[KEY_BRIGHTNESS_MAX] = "BrightnessMax",
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 859aeb07542e..c6259d9e5ff6 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -1086,6 +1086,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break;
case 0x0cf: map_key_clear(KEY_VOICECOMMAND); break;
+ case 0x0d5: map_key_clear(KEY_CAMERA_ACCESS_ENABLE); break;
+ case 0x0d6: map_key_clear(KEY_CAMERA_ACCESS_DISABLE); break;
+ case 0x0d7: map_key_clear(KEY_CAMERA_ACCESS_TOGGLE); break;
case 0x0d8: map_key_clear(KEY_DICTATE); break;
case 0x0d9: map_key_clear(KEY_EMOJI_PICKER); break;
diff --git a/drivers/hid/i2c-hid/i2c-hid-acpi.c b/drivers/hid/i2c-hid/i2c-hid-acpi.c
index b96ae15e0ad9..375c77c3db74 100644
--- a/drivers/hid/i2c-hid/i2c-hid-acpi.c
+++ b/drivers/hid/i2c-hid/i2c-hid-acpi.c
@@ -105,11 +105,6 @@ static int i2c_hid_acpi_probe(struct i2c_client *client)
acpi_device_fix_up_power(adev);
- if (acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0) {
- device_set_wakeup_capable(dev, true);
- device_set_wakeup_enable(dev, false);
- }
-
return i2c_hid_core_probe(client, &ihid_acpi->ops,
hid_descriptor_address, 0);
}
diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c
index 0667b6022c3b..9050bd5e24ac 100644
--- a/drivers/hid/i2c-hid/i2c-hid-core.c
+++ b/drivers/hid/i2c-hid/i2c-hid-core.c
@@ -26,6 +26,7 @@
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/pm.h>
+#include <linux/pm_wakeirq.h>
#include <linux/device.h>
#include <linux/wait.h>
#include <linux/err.h>
@@ -112,7 +113,6 @@ struct i2c_hid {
wait_queue_head_t wait; /* For waiting the interrupt */
- bool irq_wake_enabled;
struct mutex reset_lock;
struct i2chid_ops *ops;
@@ -1099,7 +1099,6 @@ static int i2c_hid_core_suspend(struct device *dev)
struct i2c_hid *ihid = i2c_get_clientdata(client);
struct hid_device *hid = ihid->hid;
int ret;
- int wake_status;
ret = hid_driver_suspend(hid, PMSG_SUSPEND);
if (ret < 0)
@@ -1110,16 +1109,8 @@ static int i2c_hid_core_suspend(struct device *dev)
disable_irq(client->irq);
- if (device_may_wakeup(&client->dev)) {
- wake_status = enable_irq_wake(client->irq);
- if (!wake_status)
- ihid->irq_wake_enabled = true;
- else
- hid_warn(hid, "Failed to enable irq wake: %d\n",
- wake_status);
- } else {
+ if (!device_may_wakeup(&client->dev))
i2c_hid_core_power_down(ihid);
- }
return 0;
}
@@ -1130,18 +1121,9 @@ static int i2c_hid_core_resume(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct i2c_hid *ihid = i2c_get_clientdata(client);
struct hid_device *hid = ihid->hid;
- int wake_status;
- if (!device_may_wakeup(&client->dev)) {
+ if (!device_may_wakeup(&client->dev))
i2c_hid_core_power_up(ihid);
- } else if (ihid->irq_wake_enabled) {
- wake_status = disable_irq_wake(client->irq);
- if (!wake_status)
- ihid->irq_wake_enabled = false;
- else
- hid_warn(hid, "Failed to disable irq wake: %d\n",
- wake_status);
- }
enable_irq(client->irq);
diff --git a/drivers/iio/adc/twl4030-madc.c b/drivers/iio/adc/twl4030-madc.c
index f8f8aea15612..c279c4f2c9b7 100644
--- a/drivers/iio/adc/twl4030-madc.c
+++ b/drivers/iio/adc/twl4030-madc.c
@@ -30,6 +30,7 @@
#include <linux/types.h>
#include <linux/gfp.h>
#include <linux/err.h>
+#include <linux/of.h>
#include <linux/regulator/consumer.h>
#include <linux/iio/iio.h>
diff --git a/drivers/input/input.c b/drivers/input/input.c
index ebb2b7f0f8ff..783961df3626 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -21,6 +21,7 @@
#include <linux/seq_file.h>
#include <linux/poll.h>
#include <linux/device.h>
+#include <linux/kstrtox.h>
#include <linux/mutex.h>
#include <linux/rcupdate.h>
#include "input-compat.h"
@@ -1465,7 +1466,7 @@ static ssize_t inhibited_store(struct device *dev,
ssize_t rv;
bool inhibited;
- if (strtobool(buf, &inhibited))
+ if (kstrtobool(buf, &inhibited))
return -EINVAL;
if (inhibited)
diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig
index 9dcf3f51f2dd..04ca3d1c2816 100644
--- a/drivers/input/joystick/Kconfig
+++ b/drivers/input/joystick/Kconfig
@@ -46,6 +46,7 @@ config JOYSTICK_A3D
config JOYSTICK_ADC
tristate "Simple joystick connected over ADC"
depends on IIO
+ select IIO_BUFFER
select IIO_BUFFER_CB
help
Say Y here if you have a simple joystick connected over ADC.
diff --git a/drivers/input/joystick/as5011.c b/drivers/input/joystick/as5011.c
index 2beda29021a3..3b88f0b49e01 100644
--- a/drivers/input/joystick/as5011.c
+++ b/drivers/input/joystick/as5011.c
@@ -212,8 +212,7 @@ static int as5011_configure_chip(struct as5011_device *as5011,
return 0;
}
-static int as5011_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int as5011_probe(struct i2c_client *client)
{
const struct as5011_platform_data *plat_data;
struct as5011_device *as5011;
@@ -349,7 +348,7 @@ static struct i2c_driver as5011_driver = {
.driver = {
.name = "as5011",
},
- .probe = as5011_probe,
+ .probe_new = as5011_probe,
.remove = as5011_remove,
.id_table = as5011_id,
};
diff --git a/drivers/input/joystick/psxpad-spi.c b/drivers/input/joystick/psxpad-spi.c
index a32656064f39..de734a927b4d 100644
--- a/drivers/input/joystick/psxpad-spi.c
+++ b/drivers/input/joystick/psxpad-spi.c
@@ -44,6 +44,8 @@ static const u8 PSX_CMD_POLL[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
+
+#ifdef CONFIG_JOYSTICK_PSXPAD_SPI_FF
/* 0x01, 0x43, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 */
static const u8 PSX_CMD_ENTER_CFG[] = {
0x80, 0xC2, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00
@@ -56,6 +58,7 @@ static const u8 PSX_CMD_EXIT_CFG[] = {
static const u8 PSX_CMD_ENABLE_MOTOR[] = {
0x80, 0xB2, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0xFF
};
+#endif /* CONFIG_JOYSTICK_PSXPAD_SPI_FF */
struct psxpad {
struct spi_device *spi;
@@ -371,7 +374,7 @@ static int psxpad_spi_probe(struct spi_device *spi)
return 0;
}
-static int __maybe_unused psxpad_spi_suspend(struct device *dev)
+static int psxpad_spi_suspend(struct device *dev)
{
struct spi_device *spi = to_spi_device(dev);
struct psxpad *pad = spi_get_drvdata(spi);
@@ -381,7 +384,7 @@ static int __maybe_unused psxpad_spi_suspend(struct device *dev)
return 0;
}
-static SIMPLE_DEV_PM_OPS(psxpad_spi_pm, psxpad_spi_suspend, NULL);
+static DEFINE_SIMPLE_DEV_PM_OPS(psxpad_spi_pm, psxpad_spi_suspend, NULL);
static const struct spi_device_id psxpad_spi_id[] = {
{ "psxpad-spi", 0 },
@@ -392,7 +395,7 @@ MODULE_DEVICE_TABLE(spi, psxpad_spi_id);
static struct spi_driver psxpad_spi_driver = {
.driver = {
.name = "psxpad-spi",
- .pm = &psxpad_spi_pm,
+ .pm = pm_sleep_ptr(&psxpad_spi_pm),
},
.id_table = psxpad_spi_id,
.probe = psxpad_spi_probe,
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 00292118b79b..84490915ae4d 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -390,7 +390,7 @@ config KEYBOARD_LOCOMO
config KEYBOARD_LPC32XX
tristate "LPC32XX matrix key scanner support"
- depends on ARCH_LPC32XX && OF
+ depends on (ARCH_LPC32XX && OF) || COMPILE_TEST
select INPUT_MATRIXKMAP
help
Say Y here if you want to use NXP LPC32XX SoC key scanner interface,
@@ -487,7 +487,7 @@ config KEYBOARD_NEWTON
config KEYBOARD_NOMADIK
tristate "ST-Ericsson Nomadik SKE keyboard"
- depends on (ARCH_NOMADIK || ARCH_U8500)
+ depends on (ARCH_NOMADIK || ARCH_U8500 || COMPILE_TEST)
select INPUT_MATRIXKMAP
help
Say Y here if you want to use a keypad provided on the SKE controller
@@ -508,7 +508,7 @@ config KEYBOARD_NSPIRE
config KEYBOARD_TEGRA
tristate "NVIDIA Tegra internal matrix keyboard controller support"
- depends on ARCH_TEGRA && OF
+ depends on (ARCH_TEGRA && OF) || COMPILE_TEST
select INPUT_MATRIXKMAP
help
Say Y here if you want to use a matrix keyboard connected directly
@@ -542,7 +542,7 @@ config KEYBOARD_PINEPHONE
config KEYBOARD_PXA27x
tristate "PXA27x/PXA3xx keypad support"
- depends on PXA27x || PXA3xx || ARCH_MMP
+ depends on PXA27x || PXA3xx || ARCH_MMP || COMPILE_TEST
select INPUT_MATRIXKMAP
help
Enable support for PXA27x/PXA3xx keypad controller.
@@ -709,7 +709,7 @@ config KEYBOARD_OMAP4
config KEYBOARD_SPEAR
tristate "ST SPEAR keyboard support"
- depends on PLAT_SPEAR
+ depends on PLAT_SPEAR || COMPILE_TEST
select INPUT_MATRIXKMAP
help
Say Y here if you want to use the SPEAR keyboard.
diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c
index 7cd83c8e7110..72ae5ce72956 100644
--- a/drivers/input/keyboard/adp5588-keys.c
+++ b/drivers/input/keyboard/adp5588-keys.c
@@ -718,8 +718,7 @@ static void adp5588_disable_regulator(void *reg)
regulator_disable(reg);
}
-static int adp5588_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int adp5588_probe(struct i2c_client *client)
{
struct adp5588_kpad *kpad;
struct input_dev *input;
@@ -867,7 +866,7 @@ static struct i2c_driver adp5588_driver = {
.of_match_table = adp5588_of_match,
.pm = pm_sleep_ptr(&adp5588_dev_pm_ops),
},
- .probe = adp5588_probe,
+ .probe_new = adp5588_probe,
.remove = adp5588_remove,
.id_table = adp5588_id,
};
diff --git a/drivers/input/keyboard/adp5589-keys.c b/drivers/input/keyboard/adp5589-keys.c
index bdd264459a97..38d7073863a8 100644
--- a/drivers/input/keyboard/adp5589-keys.c
+++ b/drivers/input/keyboard/adp5589-keys.c
@@ -942,9 +942,9 @@ static void adp5589_clear_config(void *data)
adp5589_write(client, kpad->var->reg(ADP5589_GENERAL_CFG), 0);
}
-static int adp5589_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int adp5589_probe(struct i2c_client *client)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct adp5589_kpad *kpad;
const struct adp5589_kpad_platform_data *pdata =
dev_get_platdata(&client->dev);
@@ -1016,7 +1016,7 @@ static int adp5589_probe(struct i2c_client *client,
return 0;
}
-static int __maybe_unused adp5589_suspend(struct device *dev)
+static int adp5589_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct adp5589_kpad *kpad = i2c_get_clientdata(client);
@@ -1027,7 +1027,7 @@ static int __maybe_unused adp5589_suspend(struct device *dev)
return 0;
}
-static int __maybe_unused adp5589_resume(struct device *dev)
+static int adp5589_resume(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct adp5589_kpad *kpad = i2c_get_clientdata(client);
@@ -1038,7 +1038,7 @@ static int __maybe_unused adp5589_resume(struct device *dev)
return 0;
}
-static SIMPLE_DEV_PM_OPS(adp5589_dev_pm_ops, adp5589_suspend, adp5589_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(adp5589_dev_pm_ops, adp5589_suspend, adp5589_resume);
static const struct i2c_device_id adp5589_id[] = {
{"adp5589-keys", ADP5589},
@@ -1052,9 +1052,9 @@ MODULE_DEVICE_TABLE(i2c, adp5589_id);
static struct i2c_driver adp5589_driver = {
.driver = {
.name = KBUILD_MODNAME,
- .pm = &adp5589_dev_pm_ops,
+ .pm = pm_sleep_ptr(&adp5589_dev_pm_ops),
},
- .probe = adp5589_probe,
+ .probe_new = adp5589_probe,
.id_table = adp5589_id,
};
diff --git a/drivers/input/keyboard/cap11xx.c b/drivers/input/keyboard/cap11xx.c
index 7c85343cd32f..79afd0386e3f 100644
--- a/drivers/input/keyboard/cap11xx.c
+++ b/drivers/input/keyboard/cap11xx.c
@@ -321,9 +321,9 @@ static int cap11xx_init_leds(struct device *dev,
}
#endif
-static int cap11xx_i2c_probe(struct i2c_client *i2c_client,
- const struct i2c_device_id *id)
+static int cap11xx_i2c_probe(struct i2c_client *i2c_client)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(i2c_client);
struct device *dev = &i2c_client->dev;
struct cap11xx_priv *priv;
struct device_node *node;
@@ -503,7 +503,7 @@ static struct i2c_driver cap11xx_i2c_driver = {
.of_match_table = cap11xx_dt_ids,
},
.id_table = cap11xx_i2c_ids,
- .probe = cap11xx_i2c_probe,
+ .probe_new = cap11xx_i2c_probe,
};
module_i2c_driver(cap11xx_i2c_driver);
diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c
index c14136b733a9..6f435125ec03 100644
--- a/drivers/input/keyboard/cros_ec_keyb.c
+++ b/drivers/input/keyboard/cros_ec_keyb.c
@@ -415,7 +415,7 @@ static int cros_ec_keyb_query_switches(struct cros_ec_keyb *ckdev)
*
* Returns 0 if no error or -error upon error.
*/
-static __maybe_unused int cros_ec_keyb_resume(struct device *dev)
+static int cros_ec_keyb_resume(struct device *dev)
{
struct cros_ec_keyb *ckdev = dev_get_drvdata(dev);
@@ -760,7 +760,7 @@ static const struct of_device_id cros_ec_keyb_of_match[] = {
MODULE_DEVICE_TABLE(of, cros_ec_keyb_of_match);
#endif
-static SIMPLE_DEV_PM_OPS(cros_ec_keyb_pm_ops, NULL, cros_ec_keyb_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(cros_ec_keyb_pm_ops, NULL, cros_ec_keyb_resume);
static struct platform_driver cros_ec_keyb_driver = {
.probe = cros_ec_keyb_probe,
@@ -769,7 +769,7 @@ static struct platform_driver cros_ec_keyb_driver = {
.name = "cros-ec-keyb",
.of_match_table = of_match_ptr(cros_ec_keyb_of_match),
.acpi_match_table = ACPI_PTR(cros_ec_keyb_acpi_match),
- .pm = &cros_ec_keyb_pm_ops,
+ .pm = pm_sleep_ptr(&cros_ec_keyb_pm_ops),
},
};
diff --git a/drivers/input/keyboard/cypress-sf.c b/drivers/input/keyboard/cypress-sf.c
index 9a23eed6a4f4..686388f40317 100644
--- a/drivers/input/keyboard/cypress-sf.c
+++ b/drivers/input/keyboard/cypress-sf.c
@@ -168,7 +168,7 @@ static int cypress_sf_probe(struct i2c_client *client)
return 0;
};
-static int __maybe_unused cypress_sf_suspend(struct device *dev)
+static int cypress_sf_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct cypress_sf_data *touchkey = i2c_get_clientdata(client);
@@ -187,7 +187,7 @@ static int __maybe_unused cypress_sf_suspend(struct device *dev)
return 0;
}
-static int __maybe_unused cypress_sf_resume(struct device *dev)
+static int cypress_sf_resume(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct cypress_sf_data *touchkey = i2c_get_clientdata(client);
@@ -205,8 +205,8 @@ static int __maybe_unused cypress_sf_resume(struct device *dev)
return 0;
}
-static SIMPLE_DEV_PM_OPS(cypress_sf_pm_ops,
- cypress_sf_suspend, cypress_sf_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(cypress_sf_pm_ops,
+ cypress_sf_suspend, cypress_sf_resume);
static struct i2c_device_id cypress_sf_id_table[] = {
{ CYPRESS_SF_DEV_NAME, 0 },
@@ -225,7 +225,7 @@ MODULE_DEVICE_TABLE(of, cypress_sf_of_match);
static struct i2c_driver cypress_sf_driver = {
.driver = {
.name = CYPRESS_SF_DEV_NAME,
- .pm = &cypress_sf_pm_ops,
+ .pm = pm_sleep_ptr(&cypress_sf_pm_ops),
.of_match_table = of_match_ptr(cypress_sf_of_match),
},
.id_table = cypress_sf_id_table,
diff --git a/drivers/input/keyboard/dlink-dir685-touchkeys.c b/drivers/input/keyboard/dlink-dir685-touchkeys.c
index a69dcc3bd30c..ddba2bc861da 100644
--- a/drivers/input/keyboard/dlink-dir685-touchkeys.c
+++ b/drivers/input/keyboard/dlink-dir685-touchkeys.c
@@ -59,12 +59,11 @@ static irqreturn_t dir685_tk_irq_thread(int irq, void *data)
return IRQ_HANDLED;
}
-static int dir685_tk_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int dir685_tk_probe(struct i2c_client *client)
{
- struct dir685_touchkeys *tk;
+ static const u8 bl_data[] = { 0xa7, 0x40 };
struct device *dev = &client->dev;
- u8 bl_data[] = { 0xa7, 0x40 };
+ struct dir685_touchkeys *tk;
int err;
int i;
@@ -146,7 +145,7 @@ static struct i2c_driver dir685_tk_i2c_driver = {
.name = "dlink-dir685-touchkeys",
.of_match_table = of_match_ptr(dir685_tk_of_match),
},
- .probe = dir685_tk_probe,
+ .probe_new = dir685_tk_probe,
.id_table = dir685_tk_id,
};
module_i2c_driver(dir685_tk_i2c_driver);
diff --git a/drivers/input/keyboard/ep93xx_keypad.c b/drivers/input/keyboard/ep93xx_keypad.c
index f5bf7524722a..55075addcac2 100644
--- a/drivers/input/keyboard/ep93xx_keypad.c
+++ b/drivers/input/keyboard/ep93xx_keypad.c
@@ -178,7 +178,7 @@ static void ep93xx_keypad_close(struct input_dev *pdev)
}
-static int __maybe_unused ep93xx_keypad_suspend(struct device *dev)
+static int ep93xx_keypad_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct ep93xx_keypad *keypad = platform_get_drvdata(pdev);
@@ -196,7 +196,7 @@ static int __maybe_unused ep93xx_keypad_suspend(struct device *dev)
return 0;
}
-static int __maybe_unused ep93xx_keypad_resume(struct device *dev)
+static int ep93xx_keypad_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct ep93xx_keypad *keypad = platform_get_drvdata(pdev);
@@ -217,8 +217,8 @@ static int __maybe_unused ep93xx_keypad_resume(struct device *dev)
return 0;
}
-static SIMPLE_DEV_PM_OPS(ep93xx_keypad_pm_ops,
- ep93xx_keypad_suspend, ep93xx_keypad_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(ep93xx_keypad_pm_ops,
+ ep93xx_keypad_suspend, ep93xx_keypad_resume);
static void ep93xx_keypad_release_gpio_action(void *_pdev)
{
@@ -318,7 +318,7 @@ static int ep93xx_keypad_remove(struct platform_device *pdev)
static struct platform_driver ep93xx_keypad_driver = {
.driver = {
.name = "ep93xx-keypad",
- .pm = &ep93xx_keypad_pm_ops,
+ .pm = pm_sleep_ptr(&ep93xx_keypad_pm_ops),
},
.probe = ep93xx_keypad_probe,
.remove = ep93xx_keypad_remove,
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index a5dc4ab87fa1..5496482a38c1 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -992,7 +992,7 @@ gpio_keys_disable_wakeup(struct gpio_keys_drvdata *ddata)
}
}
-static int __maybe_unused gpio_keys_suspend(struct device *dev)
+static int gpio_keys_suspend(struct device *dev)
{
struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev);
struct input_dev *input = ddata->input;
@@ -1012,7 +1012,7 @@ static int __maybe_unused gpio_keys_suspend(struct device *dev)
return 0;
}
-static int __maybe_unused gpio_keys_resume(struct device *dev)
+static int gpio_keys_resume(struct device *dev)
{
struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev);
struct input_dev *input = ddata->input;
@@ -1034,7 +1034,7 @@ static int __maybe_unused gpio_keys_resume(struct device *dev)
return 0;
}
-static SIMPLE_DEV_PM_OPS(gpio_keys_pm_ops, gpio_keys_suspend, gpio_keys_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(gpio_keys_pm_ops, gpio_keys_suspend, gpio_keys_resume);
static void gpio_keys_shutdown(struct platform_device *pdev)
{
@@ -1050,7 +1050,7 @@ static struct platform_driver gpio_keys_device_driver = {
.shutdown = gpio_keys_shutdown,
.driver = {
.name = "gpio-keys",
- .pm = &gpio_keys_pm_ops,
+ .pm = pm_sleep_ptr(&gpio_keys_pm_ops),
.of_match_table = gpio_keys_of_match,
.dev_groups = gpio_keys_groups,
}
diff --git a/drivers/input/keyboard/ipaq-micro-keys.c b/drivers/input/keyboard/ipaq-micro-keys.c
index 13a66a8e3411..7b509bce2b33 100644
--- a/drivers/input/keyboard/ipaq-micro-keys.c
+++ b/drivers/input/keyboard/ipaq-micro-keys.c
@@ -124,7 +124,7 @@ static int micro_key_probe(struct platform_device *pdev)
return 0;
}
-static int __maybe_unused micro_key_suspend(struct device *dev)
+static int micro_key_suspend(struct device *dev)
{
struct ipaq_micro_keys *keys = dev_get_drvdata(dev);
@@ -133,7 +133,7 @@ static int __maybe_unused micro_key_suspend(struct device *dev)
return 0;
}
-static int __maybe_unused micro_key_resume(struct device *dev)
+static int micro_key_resume(struct device *dev)
{
struct ipaq_micro_keys *keys = dev_get_drvdata(dev);
struct input_dev *input = keys->input;
@@ -148,13 +148,13 @@ static int __maybe_unused micro_key_resume(struct device *dev)
return 0;
}
-static SIMPLE_DEV_PM_OPS(micro_key_dev_pm_ops,
- micro_key_suspend, micro_key_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(micro_key_dev_pm_ops,
+ micro_key_suspend, micro_key_resume);
static struct platform_driver micro_key_device_driver = {
.driver = {
.name = "ipaq-micro-keys",
- .pm = &micro_key_dev_pm_ops,
+ .pm = pm_sleep_ptr(&micro_key_dev_pm_ops),
},
.probe = micro_key_probe,
};
diff --git a/drivers/input/keyboard/lm8323.c b/drivers/input/keyboard/lm8323.c
index 407dd2ad6302..5df4d5a7ed9e 100644
--- a/drivers/input/keyboard/lm8323.c
+++ b/drivers/input/keyboard/lm8323.c
@@ -615,8 +615,7 @@ static ssize_t lm8323_set_disable(struct device *dev,
}
static DEVICE_ATTR(disable_kp, 0644, lm8323_show_disable, lm8323_set_disable);
-static int lm8323_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int lm8323_probe(struct i2c_client *client)
{
struct lm8323_platform_data *pdata = dev_get_platdata(&client->dev);
struct input_dev *idev;
@@ -771,7 +770,6 @@ static void lm8323_remove(struct i2c_client *client)
kfree(lm);
}
-#ifdef CONFIG_PM_SLEEP
/*
* We don't need to explicitly suspend the chip, as it already switches off
* when there's no activity.
@@ -815,9 +813,8 @@ static int lm8323_resume(struct device *dev)
return 0;
}
-#endif
-static SIMPLE_DEV_PM_OPS(lm8323_pm_ops, lm8323_suspend, lm8323_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(lm8323_pm_ops, lm8323_suspend, lm8323_resume);
static const struct i2c_device_id lm8323_id[] = {
{ "lm8323", 0 },
@@ -827,9 +824,9 @@ static const struct i2c_device_id lm8323_id[] = {
static struct i2c_driver lm8323_i2c_driver = {
.driver = {
.name = "lm8323",
- .pm = &lm8323_pm_ops,
+ .pm = pm_sleep_ptr(&lm8323_pm_ops),
},
- .probe = lm8323_probe,
+ .probe_new = lm8323_probe,
.remove = lm8323_remove,
.id_table = lm8323_id,
};
diff --git a/drivers/input/keyboard/lm8333.c b/drivers/input/keyboard/lm8333.c
index 3052cd6dedac..7457c3220f90 100644
--- a/drivers/input/keyboard/lm8333.c
+++ b/drivers/input/keyboard/lm8333.c
@@ -125,8 +125,7 @@ static irqreturn_t lm8333_irq_thread(int irq, void *data)
return IRQ_HANDLED;
}
-static int lm8333_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int lm8333_probe(struct i2c_client *client)
{
const struct lm8333_platform_data *pdata =
dev_get_platdata(&client->dev);
@@ -219,7 +218,7 @@ static struct i2c_driver lm8333_driver = {
.driver = {
.name = "lm8333",
},
- .probe = lm8333_probe,
+ .probe_new = lm8333_probe,
.remove = lm8333_remove,
.id_table = lm8333_id,
};
diff --git a/drivers/input/keyboard/lpc32xx-keys.c b/drivers/input/keyboard/lpc32xx-keys.c
index 943aeeb0de79..911e1181cd6f 100644
--- a/drivers/input/keyboard/lpc32xx-keys.c
+++ b/drivers/input/keyboard/lpc32xx-keys.c
@@ -264,7 +264,6 @@ static int lpc32xx_kscan_probe(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM_SLEEP
static int lpc32xx_kscan_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
@@ -302,10 +301,9 @@ static int lpc32xx_kscan_resume(struct device *dev)
mutex_unlock(&input->mutex);
return retval;
}
-#endif
-static SIMPLE_DEV_PM_OPS(lpc32xx_kscan_pm_ops, lpc32xx_kscan_suspend,
- lpc32xx_kscan_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(lpc32xx_kscan_pm_ops, lpc32xx_kscan_suspend,
+ lpc32xx_kscan_resume);
static const struct of_device_id lpc32xx_kscan_match[] = {
{ .compatible = "nxp,lpc3220-key" },
@@ -317,7 +315,7 @@ static struct platform_driver lpc32xx_kscan_driver = {
.probe = lpc32xx_kscan_probe,
.driver = {
.name = DRV_NAME,
- .pm = &lpc32xx_kscan_pm_ops,
+ .pm = pm_sleep_ptr(&lpc32xx_kscan_pm_ops),
.of_match_table = lpc32xx_kscan_match,
}
};
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index 7dd3f3eda834..203310727d88 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -127,6 +127,9 @@ static void matrix_keypad_scan(struct work_struct *work)
memset(new_state, 0, sizeof(new_state));
+ for (row = 0; row < pdata->num_row_gpios; row++)
+ gpio_direction_input(pdata->row_gpios[row]);
+
/* assert each column and read the row status out */
for (col = 0; col < pdata->num_col_gpios; col++) {
@@ -227,7 +230,6 @@ static void matrix_keypad_stop(struct input_dev *dev)
disable_row_irqs(keypad);
}
-#ifdef CONFIG_PM_SLEEP
static void matrix_keypad_enable_wakeup(struct matrix_keypad *keypad)
{
const struct matrix_keypad_platform_data *pdata = keypad->pdata;
@@ -296,10 +298,9 @@ static int matrix_keypad_resume(struct device *dev)
return 0;
}
-#endif
-static SIMPLE_DEV_PM_OPS(matrix_keypad_pm_ops,
- matrix_keypad_suspend, matrix_keypad_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(matrix_keypad_pm_ops,
+ matrix_keypad_suspend, matrix_keypad_resume);
static int matrix_keypad_init_gpio(struct platform_device *pdev,
struct matrix_keypad *keypad)
@@ -574,7 +575,7 @@ static struct platform_driver matrix_keypad_driver = {
.remove = matrix_keypad_remove,
.driver = {
.name = "matrix-keypad",
- .pm = &matrix_keypad_pm_ops,
+ .pm = pm_sleep_ptr(&matrix_keypad_pm_ops),
.of_match_table = of_match_ptr(matrix_keypad_dt_match),
},
};
diff --git a/drivers/input/keyboard/max7359_keypad.c b/drivers/input/keyboard/max7359_keypad.c
index 62ce93462955..b363749d02e2 100644
--- a/drivers/input/keyboard/max7359_keypad.c
+++ b/drivers/input/keyboard/max7359_keypad.c
@@ -155,8 +155,7 @@ static void max7359_initialize(struct i2c_client *client)
max7359_fall_deepsleep(client);
}
-static int max7359_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int max7359_probe(struct i2c_client *client)
{
const struct matrix_keymap_data *keymap_data =
dev_get_platdata(&client->dev);
@@ -243,7 +242,6 @@ static int max7359_probe(struct i2c_client *client,
return 0;
}
-#ifdef CONFIG_PM_SLEEP
static int max7359_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -268,9 +266,8 @@ static int max7359_resume(struct device *dev)
return 0;
}
-#endif
-static SIMPLE_DEV_PM_OPS(max7359_pm, max7359_suspend, max7359_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(max7359_pm, max7359_suspend, max7359_resume);
static const struct i2c_device_id max7359_ids[] = {
{ "max7359", 0 },
@@ -281,9 +278,9 @@ MODULE_DEVICE_TABLE(i2c, max7359_ids);
static struct i2c_driver max7359_i2c_driver = {
.driver = {
.name = "max7359",
- .pm = &max7359_pm,
+ .pm = pm_sleep_ptr(&max7359_pm),
},
- .probe = max7359_probe,
+ .probe_new = max7359_probe,
.id_table = max7359_ids,
};
diff --git a/drivers/input/keyboard/mcs_touchkey.c b/drivers/input/keyboard/mcs_touchkey.c
index ac1637a3389e..d414e19e4559 100644
--- a/drivers/input/keyboard/mcs_touchkey.c
+++ b/drivers/input/keyboard/mcs_touchkey.c
@@ -92,9 +92,9 @@ static irqreturn_t mcs_touchkey_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int mcs_touchkey_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int mcs_touchkey_probe(struct i2c_client *client)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(client);
const struct mcs_platform_data *pdata;
struct mcs_touchkey_data *data;
struct input_dev *input_dev;
@@ -213,7 +213,6 @@ static void mcs_touchkey_shutdown(struct i2c_client *client)
data->poweron(false);
}
-#ifdef CONFIG_PM_SLEEP
static int mcs_touchkey_suspend(struct device *dev)
{
struct mcs_touchkey_data *data = dev_get_drvdata(dev);
@@ -243,10 +242,9 @@ static int mcs_touchkey_resume(struct device *dev)
return 0;
}
-#endif
-static SIMPLE_DEV_PM_OPS(mcs_touchkey_pm_ops,
- mcs_touchkey_suspend, mcs_touchkey_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(mcs_touchkey_pm_ops,
+ mcs_touchkey_suspend, mcs_touchkey_resume);
static const struct i2c_device_id mcs_touchkey_id[] = {
{ "mcs5000_touchkey", MCS5000_TOUCHKEY },
@@ -258,9 +256,9 @@ MODULE_DEVICE_TABLE(i2c, mcs_touchkey_id);
static struct i2c_driver mcs_touchkey_driver = {
.driver = {
.name = "mcs_touchkey",
- .pm = &mcs_touchkey_pm_ops,
+ .pm = pm_sleep_ptr(&mcs_touchkey_pm_ops),
},
- .probe = mcs_touchkey_probe,
+ .probe_new = mcs_touchkey_probe,
.remove = mcs_touchkey_remove,
.shutdown = mcs_touchkey_shutdown,
.id_table = mcs_touchkey_id,
diff --git a/drivers/input/keyboard/mpr121_touchkey.c b/drivers/input/keyboard/mpr121_touchkey.c
index 230ab3d50b9e..74ad353462a3 100644
--- a/drivers/input/keyboard/mpr121_touchkey.c
+++ b/drivers/input/keyboard/mpr121_touchkey.c
@@ -230,8 +230,7 @@ err_i2c_write:
return ret;
}
-static int mpr_touchkey_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int mpr_touchkey_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct regulator *vdd_supply;
@@ -341,7 +340,7 @@ static int mpr_touchkey_probe(struct i2c_client *client,
return 0;
}
-static int __maybe_unused mpr_suspend(struct device *dev)
+static int mpr_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -353,7 +352,7 @@ static int __maybe_unused mpr_suspend(struct device *dev)
return 0;
}
-static int __maybe_unused mpr_resume(struct device *dev)
+static int mpr_resume(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct mpr121_touchkey *mpr121 = i2c_get_clientdata(client);
@@ -367,7 +366,7 @@ static int __maybe_unused mpr_resume(struct device *dev)
return 0;
}
-static SIMPLE_DEV_PM_OPS(mpr121_touchkey_pm_ops, mpr_suspend, mpr_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(mpr121_touchkey_pm_ops, mpr_suspend, mpr_resume);
static const struct i2c_device_id mpr121_id[] = {
{ "mpr121_touchkey", 0 },
@@ -386,11 +385,11 @@ MODULE_DEVICE_TABLE(of, mpr121_touchkey_dt_match_table);
static struct i2c_driver mpr_touchkey_driver = {
.driver = {
.name = "mpr121",
- .pm = &mpr121_touchkey_pm_ops,
+ .pm = pm_sleep_ptr(&mpr121_touchkey_pm_ops),
.of_match_table = of_match_ptr(mpr121_touchkey_dt_match_table),
},
.id_table = mpr121_id,
- .probe = mpr_touchkey_probe,
+ .probe_new = mpr_touchkey_probe,
};
module_i2c_driver(mpr_touchkey_driver);
diff --git a/drivers/input/keyboard/mtk-pmic-keys.c b/drivers/input/keyboard/mtk-pmic-keys.c
index 9b34da0ec260..3d4ffa25e3df 100644
--- a/drivers/input/keyboard/mtk-pmic-keys.c
+++ b/drivers/input/keyboard/mtk-pmic-keys.c
@@ -231,7 +231,7 @@ static int mtk_pmic_key_setup(struct mtk_pmic_keys *keys,
return 0;
}
-static int __maybe_unused mtk_pmic_keys_suspend(struct device *dev)
+static int mtk_pmic_keys_suspend(struct device *dev)
{
struct mtk_pmic_keys *keys = dev_get_drvdata(dev);
int index;
@@ -247,7 +247,7 @@ static int __maybe_unused mtk_pmic_keys_suspend(struct device *dev)
return 0;
}
-static int __maybe_unused mtk_pmic_keys_resume(struct device *dev)
+static int mtk_pmic_keys_resume(struct device *dev)
{
struct mtk_pmic_keys *keys = dev_get_drvdata(dev);
int index;
@@ -263,8 +263,8 @@ static int __maybe_unused mtk_pmic_keys_resume(struct device *dev)
return 0;
}
-static SIMPLE_DEV_PM_OPS(mtk_pmic_keys_pm_ops, mtk_pmic_keys_suspend,
- mtk_pmic_keys_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(mtk_pmic_keys_pm_ops, mtk_pmic_keys_suspend,
+ mtk_pmic_keys_resume);
static const struct of_device_id of_mtk_pmic_keys_match_tbl[] = {
{
@@ -387,7 +387,7 @@ static struct platform_driver pmic_keys_pdrv = {
.driver = {
.name = "mtk-pmic-keys",
.of_match_table = of_mtk_pmic_keys_match_tbl,
- .pm = &mtk_pmic_keys_pm_ops,
+ .pm = pm_sleep_ptr(&mtk_pmic_keys_pm_ops),
},
};
diff --git a/drivers/input/keyboard/nomadik-ske-keypad.c b/drivers/input/keyboard/nomadik-ske-keypad.c
index 0d55a95347f1..970f2a671c2e 100644
--- a/drivers/input/keyboard/nomadik-ske-keypad.c
+++ b/drivers/input/keyboard/nomadik-ske-keypad.c
@@ -388,7 +388,6 @@ static int ske_keypad_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM_SLEEP
static int ske_keypad_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
@@ -416,15 +415,14 @@ static int ske_keypad_resume(struct device *dev)
return 0;
}
-#endif
-static SIMPLE_DEV_PM_OPS(ske_keypad_dev_pm_ops,
- ske_keypad_suspend, ske_keypad_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(ske_keypad_dev_pm_ops,
+ ske_keypad_suspend, ske_keypad_resume);
static struct platform_driver ske_keypad_driver = {
.driver = {
.name = "nmk-ske-keypad",
- .pm = &ske_keypad_dev_pm_ops,
+ .pm = pm_sleep_ptr(&ske_keypad_dev_pm_ops),
},
.remove = ske_keypad_remove,
};
diff --git a/drivers/input/keyboard/pmic8xxx-keypad.c b/drivers/input/keyboard/pmic8xxx-keypad.c
index 4766c5048ce2..26a005f9ace3 100644
--- a/drivers/input/keyboard/pmic8xxx-keypad.c
+++ b/drivers/input/keyboard/pmic8xxx-keypad.c
@@ -621,7 +621,6 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM_SLEEP
static int pmic8xxx_kp_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
@@ -661,10 +660,9 @@ static int pmic8xxx_kp_resume(struct device *dev)
return 0;
}
-#endif
-static SIMPLE_DEV_PM_OPS(pm8xxx_kp_pm_ops,
- pmic8xxx_kp_suspend, pmic8xxx_kp_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(pm8xxx_kp_pm_ops,
+ pmic8xxx_kp_suspend, pmic8xxx_kp_resume);
static const struct of_device_id pm8xxx_match_table[] = {
{ .compatible = "qcom,pm8058-keypad" },
@@ -677,7 +675,7 @@ static struct platform_driver pmic8xxx_kp_driver = {
.probe = pmic8xxx_kp_probe,
.driver = {
.name = "pm8xxx-keypad",
- .pm = &pm8xxx_kp_pm_ops,
+ .pm = pm_sleep_ptr(&pm8xxx_kp_pm_ops),
.of_match_table = pm8xxx_match_table,
},
};
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c
index a7f8257c8a02..871f858d0ba7 100644
--- a/drivers/input/keyboard/pxa27x_keypad.c
+++ b/drivers/input/keyboard/pxa27x_keypad.c
@@ -660,7 +660,6 @@ static void pxa27x_keypad_close(struct input_dev *dev)
clk_disable_unprepare(keypad->clk);
}
-#ifdef CONFIG_PM_SLEEP
static int pxa27x_keypad_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
@@ -706,10 +705,9 @@ static int pxa27x_keypad_resume(struct device *dev)
return ret;
}
-#endif
-static SIMPLE_DEV_PM_OPS(pxa27x_keypad_pm_ops,
- pxa27x_keypad_suspend, pxa27x_keypad_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(pxa27x_keypad_pm_ops,
+ pxa27x_keypad_suspend, pxa27x_keypad_resume);
static int pxa27x_keypad_probe(struct platform_device *pdev)
@@ -830,7 +828,7 @@ static struct platform_driver pxa27x_keypad_driver = {
.driver = {
.name = "pxa27x-keypad",
.of_match_table = of_match_ptr(pxa27x_keypad_dt_match),
- .pm = &pxa27x_keypad_pm_ops,
+ .pm = pm_sleep_ptr(&pxa27x_keypad_pm_ops),
},
};
module_platform_driver(pxa27x_keypad_driver);
diff --git a/drivers/input/keyboard/qt1050.c b/drivers/input/keyboard/qt1050.c
index 403060d05c3b..317fe2b1f827 100644
--- a/drivers/input/keyboard/qt1050.c
+++ b/drivers/input/keyboard/qt1050.c
@@ -547,7 +547,7 @@ static int qt1050_probe(struct i2c_client *client)
return 0;
}
-static int __maybe_unused qt1050_suspend(struct device *dev)
+static int qt1050_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct qt1050_priv *ts = i2c_get_clientdata(client);
@@ -563,7 +563,7 @@ static int __maybe_unused qt1050_suspend(struct device *dev)
device_may_wakeup(dev) ? 125 : 0);
}
-static int __maybe_unused qt1050_resume(struct device *dev)
+static int qt1050_resume(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct qt1050_priv *ts = i2c_get_clientdata(client);
@@ -574,7 +574,7 @@ static int __maybe_unused qt1050_resume(struct device *dev)
return regmap_write(ts->regmap, QT1050_LPMODE, 2);
}
-static SIMPLE_DEV_PM_OPS(qt1050_pm_ops, qt1050_suspend, qt1050_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(qt1050_pm_ops, qt1050_suspend, qt1050_resume);
static const struct of_device_id __maybe_unused qt1050_of_match[] = {
{ .compatible = "microchip,qt1050", },
@@ -586,7 +586,7 @@ static struct i2c_driver qt1050_driver = {
.driver = {
.name = "qt1050",
.of_match_table = of_match_ptr(qt1050_of_match),
- .pm = &qt1050_pm_ops,
+ .pm = pm_sleep_ptr(&qt1050_pm_ops),
},
.probe_new = qt1050_probe,
};
diff --git a/drivers/input/keyboard/qt1070.c b/drivers/input/keyboard/qt1070.c
index 9fcce18b1d65..fabb50bde844 100644
--- a/drivers/input/keyboard/qt1070.c
+++ b/drivers/input/keyboard/qt1070.c
@@ -126,8 +126,7 @@ static irqreturn_t qt1070_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int qt1070_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int qt1070_probe(struct i2c_client *client)
{
struct qt1070_data *data;
struct input_dev *input;
@@ -227,7 +226,6 @@ static void qt1070_remove(struct i2c_client *client)
kfree(data);
}
-#ifdef CONFIG_PM_SLEEP
static int qt1070_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -249,9 +247,8 @@ static int qt1070_resume(struct device *dev)
return 0;
}
-#endif
-static SIMPLE_DEV_PM_OPS(qt1070_pm_ops, qt1070_suspend, qt1070_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(qt1070_pm_ops, qt1070_suspend, qt1070_resume);
static const struct i2c_device_id qt1070_id[] = {
{ "qt1070", 0 },
@@ -271,10 +268,10 @@ static struct i2c_driver qt1070_driver = {
.driver = {
.name = "qt1070",
.of_match_table = of_match_ptr(qt1070_of_match),
- .pm = &qt1070_pm_ops,
+ .pm = pm_sleep_ptr(&qt1070_pm_ops),
},
.id_table = qt1070_id,
- .probe = qt1070_probe,
+ .probe_new = qt1070_probe,
.remove = qt1070_remove,
};
diff --git a/drivers/input/keyboard/qt2160.c b/drivers/input/keyboard/qt2160.c
index 382b1519218c..04d2ee6ff577 100644
--- a/drivers/input/keyboard/qt2160.c
+++ b/drivers/input/keyboard/qt2160.c
@@ -338,8 +338,7 @@ static bool qt2160_identify(struct i2c_client *client)
return true;
}
-static int qt2160_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int qt2160_probe(struct i2c_client *client)
{
struct qt2160_data *qt2160;
struct input_dev *input;
@@ -461,7 +460,7 @@ static struct i2c_driver qt2160_driver = {
},
.id_table = qt2160_idtable,
- .probe = qt2160_probe,
+ .probe_new = qt2160_probe,
.remove = qt2160_remove,
};
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c
index c155adebf96e..2c00320f739f 100644
--- a/drivers/input/keyboard/sh_keysc.c
+++ b/drivers/input/keyboard/sh_keysc.c
@@ -283,7 +283,6 @@ static int sh_keysc_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM_SLEEP
static int sh_keysc_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
@@ -316,17 +315,16 @@ static int sh_keysc_resume(struct device *dev)
return 0;
}
-#endif
-static SIMPLE_DEV_PM_OPS(sh_keysc_dev_pm_ops,
- sh_keysc_suspend, sh_keysc_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(sh_keysc_dev_pm_ops,
+ sh_keysc_suspend, sh_keysc_resume);
static struct platform_driver sh_keysc_device_driver = {
.probe = sh_keysc_probe,
.remove = sh_keysc_remove,
.driver = {
.name = "sh_keysc",
- .pm = &sh_keysc_dev_pm_ops,
+ .pm = pm_sleep_ptr(&sh_keysc_dev_pm_ops),
}
};
module_platform_driver(sh_keysc_device_driver);
diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c
index 9838c79cb288..4bb7c533147c 100644
--- a/drivers/input/keyboard/spear-keyboard.c
+++ b/drivers/input/keyboard/spear-keyboard.c
@@ -284,7 +284,7 @@ static int spear_kbd_remove(struct platform_device *pdev)
return 0;
}
-static int __maybe_unused spear_kbd_suspend(struct device *dev)
+static int spear_kbd_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct spear_kbd *kbd = platform_get_drvdata(pdev);
@@ -337,7 +337,7 @@ static int __maybe_unused spear_kbd_suspend(struct device *dev)
return 0;
}
-static int __maybe_unused spear_kbd_resume(struct device *dev)
+static int spear_kbd_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct spear_kbd *kbd = platform_get_drvdata(pdev);
@@ -364,7 +364,8 @@ static int __maybe_unused spear_kbd_resume(struct device *dev)
return 0;
}
-static SIMPLE_DEV_PM_OPS(spear_kbd_pm_ops, spear_kbd_suspend, spear_kbd_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(spear_kbd_pm_ops,
+ spear_kbd_suspend, spear_kbd_resume);
#ifdef CONFIG_OF
static const struct of_device_id spear_kbd_id_table[] = {
@@ -379,7 +380,7 @@ static struct platform_driver spear_kbd_driver = {
.remove = spear_kbd_remove,
.driver = {
.name = "keyboard",
- .pm = &spear_kbd_pm_ops,
+ .pm = pm_sleep_ptr(&spear_kbd_pm_ops),
.of_match_table = of_match_ptr(spear_kbd_id_table),
},
};
diff --git a/drivers/input/keyboard/st-keyscan.c b/drivers/input/keyboard/st-keyscan.c
index a62bb8fff88c..13735a5e8391 100644
--- a/drivers/input/keyboard/st-keyscan.c
+++ b/drivers/input/keyboard/st-keyscan.c
@@ -212,7 +212,6 @@ static int keyscan_probe(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM_SLEEP
static int keyscan_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
@@ -247,9 +246,9 @@ static int keyscan_resume(struct device *dev)
mutex_unlock(&input->mutex);
return retval;
}
-#endif
-static SIMPLE_DEV_PM_OPS(keyscan_dev_pm_ops, keyscan_suspend, keyscan_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(keyscan_dev_pm_ops,
+ keyscan_suspend, keyscan_resume);
static const struct of_device_id keyscan_of_match[] = {
{ .compatible = "st,sti-keyscan" },
@@ -261,7 +260,7 @@ static struct platform_driver keyscan_device_driver = {
.probe = keyscan_probe,
.driver = {
.name = "st-keyscan",
- .pm = &keyscan_dev_pm_ops,
+ .pm = pm_sleep_ptr(&keyscan_dev_pm_ops),
.of_match_table = of_match_ptr(keyscan_of_match),
}
};
diff --git a/drivers/input/keyboard/stmpe-keypad.c b/drivers/input/keyboard/stmpe-keypad.c
index 7bf97285e30c..2c6c53290cc0 100644
--- a/drivers/input/keyboard/stmpe-keypad.c
+++ b/drivers/input/keyboard/stmpe-keypad.c
@@ -9,6 +9,7 @@
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/interrupt.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/input/matrix_keypad.h>
#include <linux/mfd/stmpe.h>
diff --git a/drivers/input/keyboard/tc3589x-keypad.c b/drivers/input/keyboard/tc3589x-keypad.c
index 78e55318ccd6..b0d86621c60a 100644
--- a/drivers/input/keyboard/tc3589x-keypad.c
+++ b/drivers/input/keyboard/tc3589x-keypad.c
@@ -455,7 +455,6 @@ static int tc3589x_keypad_probe(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM_SLEEP
static int tc3589x_keypad_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
@@ -492,15 +491,14 @@ static int tc3589x_keypad_resume(struct device *dev)
return 0;
}
-#endif
-static SIMPLE_DEV_PM_OPS(tc3589x_keypad_dev_pm_ops,
- tc3589x_keypad_suspend, tc3589x_keypad_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(tc3589x_keypad_dev_pm_ops,
+ tc3589x_keypad_suspend, tc3589x_keypad_resume);
static struct platform_driver tc3589x_keypad_driver = {
.driver = {
.name = "tc3589x-keypad",
- .pm = &tc3589x_keypad_dev_pm_ops,
+ .pm = pm_sleep_ptr(&tc3589x_keypad_dev_pm_ops),
},
.probe = tc3589x_keypad_probe,
};
diff --git a/drivers/input/keyboard/tca6416-keypad.c b/drivers/input/keyboard/tca6416-keypad.c
index afcdfbb002ff..673b905af6fe 100644
--- a/drivers/input/keyboard/tca6416-keypad.c
+++ b/drivers/input/keyboard/tca6416-keypad.c
@@ -194,9 +194,9 @@ static int tca6416_setup_registers(struct tca6416_keypad_chip *chip)
return 0;
}
-static int tca6416_keypad_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int tca6416_keypad_probe(struct i2c_client *client)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct tca6416_keys_platform_data *pdata;
struct tca6416_keypad_chip *chip;
struct input_dev *input;
@@ -320,7 +320,6 @@ static void tca6416_keypad_remove(struct i2c_client *client)
kfree(chip);
}
-#ifdef CONFIG_PM_SLEEP
static int tca6416_keypad_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -342,17 +341,16 @@ static int tca6416_keypad_resume(struct device *dev)
return 0;
}
-#endif
-static SIMPLE_DEV_PM_OPS(tca6416_keypad_dev_pm_ops,
- tca6416_keypad_suspend, tca6416_keypad_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(tca6416_keypad_dev_pm_ops,
+ tca6416_keypad_suspend, tca6416_keypad_resume);
static struct i2c_driver tca6416_keypad_driver = {
.driver = {
.name = "tca6416-keypad",
- .pm = &tca6416_keypad_dev_pm_ops,
+ .pm = pm_sleep_ptr(&tca6416_keypad_dev_pm_ops),
},
- .probe = tca6416_keypad_probe,
+ .probe_new = tca6416_keypad_probe,
.remove = tca6416_keypad_remove,
.id_table = tca6416_id,
};
diff --git a/drivers/input/keyboard/tca8418_keypad.c b/drivers/input/keyboard/tca8418_keypad.c
index 3bbd7e652533..3d7492f38337 100644
--- a/drivers/input/keyboard/tca8418_keypad.c
+++ b/drivers/input/keyboard/tca8418_keypad.c
@@ -259,8 +259,7 @@ static int tca8418_configure(struct tca8418_keypad *keypad_data,
return error;
}
-static int tca8418_keypad_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int tca8418_keypad_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct tca8418_keypad *keypad_data;
@@ -371,7 +370,7 @@ static struct i2c_driver tca8418_keypad_driver = {
.name = "tca8418_keypad",
.of_match_table = tca8418_dt_ids,
},
- .probe = tca8418_keypad_probe,
+ .probe_new = tca8418_keypad_probe,
.id_table = tca8418_id,
};
diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c
index 570fe18c0ce9..1eba06bcf27a 100644
--- a/drivers/input/keyboard/tegra-kbc.c
+++ b/drivers/input/keyboard/tegra-kbc.c
@@ -713,7 +713,6 @@ static int tegra_kbc_probe(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM_SLEEP
static void tegra_kbc_set_keypress_interrupt(struct tegra_kbc *kbc, bool enable)
{
u32 val;
@@ -802,15 +801,15 @@ static int tegra_kbc_resume(struct device *dev)
return err;
}
-#endif
-static SIMPLE_DEV_PM_OPS(tegra_kbc_pm_ops, tegra_kbc_suspend, tegra_kbc_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(tegra_kbc_pm_ops,
+ tegra_kbc_suspend, tegra_kbc_resume);
static struct platform_driver tegra_kbc_driver = {
.probe = tegra_kbc_probe,
.driver = {
.name = "tegra-kbc",
- .pm = &tegra_kbc_pm_ops,
+ .pm = pm_sleep_ptr(&tegra_kbc_pm_ops),
.of_match_table = tegra_kbc_of_match,
},
};
diff --git a/drivers/input/keyboard/tm2-touchkey.c b/drivers/input/keyboard/tm2-touchkey.c
index 632cd6c1c8d4..6627e65f06e5 100644
--- a/drivers/input/keyboard/tm2-touchkey.c
+++ b/drivers/input/keyboard/tm2-touchkey.c
@@ -181,8 +181,7 @@ out:
return IRQ_HANDLED;
}
-static int tm2_touchkey_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int tm2_touchkey_probe(struct i2c_client *client)
{
struct device_node *np = client->dev.of_node;
struct tm2_touchkey_data *touchkey;
@@ -298,7 +297,7 @@ static int tm2_touchkey_probe(struct i2c_client *client,
return 0;
}
-static int __maybe_unused tm2_touchkey_suspend(struct device *dev)
+static int tm2_touchkey_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct tm2_touchkey_data *touchkey = i2c_get_clientdata(client);
@@ -309,7 +308,7 @@ static int __maybe_unused tm2_touchkey_suspend(struct device *dev)
return 0;
}
-static int __maybe_unused tm2_touchkey_resume(struct device *dev)
+static int tm2_touchkey_resume(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct tm2_touchkey_data *touchkey = i2c_get_clientdata(client);
@@ -324,8 +323,8 @@ static int __maybe_unused tm2_touchkey_resume(struct device *dev)
return ret;
}
-static SIMPLE_DEV_PM_OPS(tm2_touchkey_pm_ops,
- tm2_touchkey_suspend, tm2_touchkey_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(tm2_touchkey_pm_ops,
+ tm2_touchkey_suspend, tm2_touchkey_resume);
static const struct i2c_device_id tm2_touchkey_id_table[] = {
{ TM2_TOUCHKEY_DEV_NAME, 0 },
@@ -354,10 +353,10 @@ MODULE_DEVICE_TABLE(of, tm2_touchkey_of_match);
static struct i2c_driver tm2_touchkey_driver = {
.driver = {
.name = TM2_TOUCHKEY_DEV_NAME,
- .pm = &tm2_touchkey_pm_ops,
+ .pm = pm_sleep_ptr(&tm2_touchkey_pm_ops),
.of_match_table = of_match_ptr(tm2_touchkey_of_match),
},
- .probe = tm2_touchkey_probe,
+ .probe_new = tm2_touchkey_probe,
.id_table = tm2_touchkey_id_table,
};
module_i2c_driver(tm2_touchkey_driver);
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 9f088900f863..f3cf189c419b 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -107,7 +107,7 @@ config INPUT_ATC260X_ONKEY
config INPUT_ATMEL_CAPTOUCH
tristate "Atmel Capacitive Touch Button Driver"
- depends on OF || COMPILE_TEST
+ depends on OF
depends on I2C
help
Say Y here if an Atmel Capacitive Touch Button device which
@@ -330,7 +330,7 @@ config INPUT_CPCAP_PWRBUTTON
config INPUT_WISTRON_BTNS
tristate "x86 Wistron laptop button interface"
- depends on X86_32
+ depends on X86_32 && !UML
select INPUT_SPARSEKMAP
select NEW_LEDS
select LEDS_CLASS
diff --git a/drivers/input/misc/ad714x-i2c.c b/drivers/input/misc/ad714x-i2c.c
index efeef135007a..5ef518a50e63 100644
--- a/drivers/input/misc/ad714x-i2c.c
+++ b/drivers/input/misc/ad714x-i2c.c
@@ -69,8 +69,7 @@ static int ad714x_i2c_read(struct ad714x_chip *chip,
return 0;
}
-static int ad714x_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int ad714x_i2c_probe(struct i2c_client *client)
{
struct ad714x_chip *chip;
@@ -99,7 +98,7 @@ static struct i2c_driver ad714x_i2c_driver = {
.name = "ad714x_captouch",
.pm = &ad714x_i2c_pm,
},
- .probe = ad714x_i2c_probe,
+ .probe_new = ad714x_i2c_probe,
.id_table = ad714x_id,
};
diff --git a/drivers/input/misc/adxl34x-i2c.c b/drivers/input/misc/adxl34x-i2c.c
index 5be636aaa94f..a8ceea36d80a 100644
--- a/drivers/input/misc/adxl34x-i2c.c
+++ b/drivers/input/misc/adxl34x-i2c.c
@@ -74,8 +74,7 @@ static const struct adxl34x_bus_ops adxl34x_i2c_bops = {
.read_block = adxl34x_i2c_read_block,
};
-static int adxl34x_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int adxl34x_i2c_probe(struct i2c_client *client)
{
struct adxl34x *ac;
int error;
@@ -159,7 +158,7 @@ static struct i2c_driver adxl34x_driver = {
.pm = &adxl34x_i2c_pm,
.of_match_table = adxl34x_of_id,
},
- .probe = adxl34x_i2c_probe,
+ .probe_new = adxl34x_i2c_probe,
.remove = adxl34x_i2c_remove,
.id_table = adxl34x_id,
};
diff --git a/drivers/input/misc/apanel.c b/drivers/input/misc/apanel.c
index 7276657ad7ca..f42d3219cdcc 100644
--- a/drivers/input/misc/apanel.c
+++ b/drivers/input/misc/apanel.c
@@ -120,8 +120,7 @@ static int mail_led_set(struct led_classdev *led,
return i2c_smbus_write_word_data(ap->client, 0x10, led_bits);
}
-static int apanel_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int apanel_probe(struct i2c_client *client)
{
struct apanel *ap;
struct input_dev *idev;
@@ -202,7 +201,7 @@ static struct i2c_driver apanel_driver = {
.driver = {
.name = APANEL,
},
- .probe = apanel_probe,
+ .probe_new = apanel_probe,
.shutdown = apanel_shutdown,
.id_table = apanel_id,
};
diff --git a/drivers/input/misc/atmel_captouch.c b/drivers/input/misc/atmel_captouch.c
index 051aded6815a..d9704b174d3a 100644
--- a/drivers/input/misc/atmel_captouch.c
+++ b/drivers/input/misc/atmel_captouch.c
@@ -161,8 +161,7 @@ out:
/*
* Probe function to setup the device, input system and interrupt
*/
-static int atmel_captouch_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int atmel_captouch_probe(struct i2c_client *client)
{
struct atmel_captouch_device *capdev;
struct device *dev = &client->dev;
@@ -249,7 +248,6 @@ static int atmel_captouch_probe(struct i2c_client *client,
return 0;
}
-#ifdef CONFIG_OF
static const struct of_device_id atmel_captouch_of_id[] = {
{
.compatible = "atmel,captouch",
@@ -257,7 +255,6 @@ static const struct of_device_id atmel_captouch_of_id[] = {
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, atmel_captouch_of_id);
-#endif
static const struct i2c_device_id atmel_captouch_id[] = {
{ "atmel_captouch", 0 },
@@ -266,11 +263,11 @@ static const struct i2c_device_id atmel_captouch_id[] = {
MODULE_DEVICE_TABLE(i2c, atmel_captouch_id);
static struct i2c_driver atmel_captouch_driver = {
- .probe = atmel_captouch_probe,
+ .probe_new = atmel_captouch_probe,
.id_table = atmel_captouch_id,
.driver = {
.name = "atmel_captouch",
- .of_match_table = of_match_ptr(atmel_captouch_of_id),
+ .of_match_table = atmel_captouch_of_id,
},
};
module_i2c_driver(atmel_captouch_driver);
diff --git a/drivers/input/misc/bma150.c b/drivers/input/misc/bma150.c
index 84fe394da7a6..3f9da5c3cb53 100644
--- a/drivers/input/misc/bma150.c
+++ b/drivers/input/misc/bma150.c
@@ -414,8 +414,7 @@ static int bma150_initialize(struct bma150_data *bma150,
return bma150_set_mode(bma150, BMA150_MODE_SLEEP);
}
-static int bma150_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int bma150_probe(struct i2c_client *client)
{
const struct bma150_platform_data *pdata =
dev_get_platdata(&client->dev);
@@ -552,7 +551,7 @@ static struct i2c_driver bma150_driver = {
},
.class = I2C_CLASS_HWMON,
.id_table = bma150_id,
- .probe = bma150_probe,
+ .probe_new = bma150_probe,
.remove = bma150_remove,
};
diff --git a/drivers/input/misc/cma3000_d0x_i2c.c b/drivers/input/misc/cma3000_d0x_i2c.c
index 3b23210c46b7..75442c1230b1 100644
--- a/drivers/input/misc/cma3000_d0x_i2c.c
+++ b/drivers/input/misc/cma3000_d0x_i2c.c
@@ -44,8 +44,7 @@ static const struct cma3000_bus_ops cma3000_i2c_bops = {
.write = cma3000_i2c_set,
};
-static int cma3000_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int cma3000_i2c_probe(struct i2c_client *client)
{
struct cma3000_accl_data *data;
@@ -100,7 +99,7 @@ static const struct i2c_device_id cma3000_i2c_id[] = {
MODULE_DEVICE_TABLE(i2c, cma3000_i2c_id);
static struct i2c_driver cma3000_i2c_driver = {
- .probe = cma3000_i2c_probe,
+ .probe_new = cma3000_i2c_probe,
.remove = cma3000_i2c_remove,
.id_table = cma3000_i2c_id,
.driver = {
diff --git a/drivers/input/misc/da7280.c b/drivers/input/misc/da7280.c
index b08610d6e575..dcdea33b1a8f 100644
--- a/drivers/input/misc/da7280.c
+++ b/drivers/input/misc/da7280.c
@@ -1140,8 +1140,7 @@ out_err:
return error;
}
-static int da7280_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int da7280_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct da7280_haptic *haptics;
@@ -1322,7 +1321,7 @@ static struct i2c_driver da7280_driver = {
.of_match_table = of_match_ptr(da7280_of_match),
.pm = &da7280_pm_ops,
},
- .probe = da7280_probe,
+ .probe_new = da7280_probe,
.id_table = da7280_i2c_id,
};
module_i2c_driver(da7280_driver);
diff --git a/drivers/input/misc/drv260x.c b/drivers/input/misc/drv260x.c
index 0efe56f49aa9..3a51ee5e935a 100644
--- a/drivers/input/misc/drv260x.c
+++ b/drivers/input/misc/drv260x.c
@@ -457,8 +457,7 @@ static const struct regmap_config drv260x_regmap_config = {
.cache_type = REGCACHE_NONE,
};
-static int drv260x_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int drv260x_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct drv260x_data *haptics;
@@ -654,7 +653,7 @@ static const struct of_device_id drv260x_of_match[] = {
MODULE_DEVICE_TABLE(of, drv260x_of_match);
static struct i2c_driver drv260x_driver = {
- .probe = drv260x_probe,
+ .probe_new = drv260x_probe,
.driver = {
.name = "drv260x-haptics",
.of_match_table = drv260x_of_match,
diff --git a/drivers/input/misc/drv2665.c b/drivers/input/misc/drv2665.c
index 21913e8085d7..c2a2ff980c06 100644
--- a/drivers/input/misc/drv2665.c
+++ b/drivers/input/misc/drv2665.c
@@ -156,8 +156,7 @@ static const struct regmap_config drv2665_regmap_config = {
.cache_type = REGCACHE_NONE,
};
-static int drv2665_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int drv2665_probe(struct i2c_client *client)
{
struct drv2665_data *haptics;
int error;
@@ -298,7 +297,7 @@ MODULE_DEVICE_TABLE(of, drv2665_of_match);
#endif
static struct i2c_driver drv2665_driver = {
- .probe = drv2665_probe,
+ .probe_new = drv2665_probe,
.driver = {
.name = "drv2665-haptics",
.of_match_table = of_match_ptr(drv2665_of_match),
diff --git a/drivers/input/misc/drv2667.c b/drivers/input/misc/drv2667.c
index 3f67b9b010bf..da7ac63dce4c 100644
--- a/drivers/input/misc/drv2667.c
+++ b/drivers/input/misc/drv2667.c
@@ -333,8 +333,7 @@ static const struct regmap_config drv2667_regmap_config = {
.cache_type = REGCACHE_NONE,
};
-static int drv2667_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int drv2667_probe(struct i2c_client *client)
{
struct drv2667_data *haptics;
int error;
@@ -475,7 +474,7 @@ MODULE_DEVICE_TABLE(of, drv2667_of_match);
#endif
static struct i2c_driver drv2667_driver = {
- .probe = drv2667_probe,
+ .probe_new = drv2667_probe,
.driver = {
.name = "drv2667-haptics",
.of_match_table = of_match_ptr(drv2667_of_match),
diff --git a/drivers/input/misc/ibm-panel.c b/drivers/input/misc/ibm-panel.c
index a8fba0054719..3969ffc1bc8d 100644
--- a/drivers/input/misc/ibm-panel.c
+++ b/drivers/input/misc/ibm-panel.c
@@ -119,8 +119,7 @@ static int ibm_panel_i2c_slave_cb(struct i2c_client *client,
return 0;
}
-static int ibm_panel_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int ibm_panel_probe(struct i2c_client *client)
{
struct ibm_panel *panel;
int i;
@@ -190,7 +189,7 @@ static struct i2c_driver ibm_panel_driver = {
.name = DEVICE_NAME,
.of_match_table = ibm_panel_match,
},
- .probe = ibm_panel_probe,
+ .probe_new = ibm_panel_probe,
.remove = ibm_panel_remove,
};
module_i2c_driver(ibm_panel_driver);
diff --git a/drivers/input/misc/iqs7222.c b/drivers/input/misc/iqs7222.c
index ddb863bf63ee..e47ab6c1177f 100644
--- a/drivers/input/misc/iqs7222.c
+++ b/drivers/input/misc/iqs7222.c
@@ -86,7 +86,9 @@ enum iqs7222_reg_key_id {
IQS7222_REG_KEY_TOUCH,
IQS7222_REG_KEY_DEBOUNCE,
IQS7222_REG_KEY_TAP,
+ IQS7222_REG_KEY_TAP_LEGACY,
IQS7222_REG_KEY_AXIAL,
+ IQS7222_REG_KEY_AXIAL_LEGACY,
IQS7222_REG_KEY_WHEEL,
IQS7222_REG_KEY_NO_WHEEL,
IQS7222_REG_KEY_RESERVED
@@ -105,14 +107,14 @@ enum iqs7222_reg_grp_id {
IQS7222_NUM_REG_GRPS
};
-static const char * const iqs7222_reg_grp_names[] = {
+static const char * const iqs7222_reg_grp_names[IQS7222_NUM_REG_GRPS] = {
[IQS7222_REG_GRP_CYCLE] = "cycle",
[IQS7222_REG_GRP_CHAN] = "channel",
[IQS7222_REG_GRP_SLDR] = "slider",
[IQS7222_REG_GRP_GPIO] = "gpio",
};
-static const unsigned int iqs7222_max_cols[] = {
+static const unsigned int iqs7222_max_cols[IQS7222_NUM_REG_GRPS] = {
[IQS7222_REG_GRP_STAT] = IQS7222_MAX_COLS_STAT,
[IQS7222_REG_GRP_CYCLE] = IQS7222_MAX_COLS_CYCLE,
[IQS7222_REG_GRP_GLBL] = IQS7222_MAX_COLS_GLBL,
@@ -202,6 +204,7 @@ struct iqs7222_dev_desc {
int allow_offset;
int event_offset;
int comms_offset;
+ bool legacy_gesture;
struct iqs7222_reg_grp_desc reg_grps[IQS7222_NUM_REG_GRPS];
};
@@ -209,12 +212,70 @@ static const struct iqs7222_dev_desc iqs7222_devs[] = {
{
.prod_num = IQS7222_PROD_NUM_A,
.fw_major = 1,
+ .fw_minor = 13,
+ .sldr_res = U8_MAX * 16,
+ .touch_link = 1768,
+ .allow_offset = 9,
+ .event_offset = 10,
+ .comms_offset = 12,
+ .reg_grps = {
+ [IQS7222_REG_GRP_STAT] = {
+ .base = IQS7222_SYS_STATUS,
+ .num_row = 1,
+ .num_col = 8,
+ },
+ [IQS7222_REG_GRP_CYCLE] = {
+ .base = 0x8000,
+ .num_row = 7,
+ .num_col = 3,
+ },
+ [IQS7222_REG_GRP_GLBL] = {
+ .base = 0x8700,
+ .num_row = 1,
+ .num_col = 3,
+ },
+ [IQS7222_REG_GRP_BTN] = {
+ .base = 0x9000,
+ .num_row = 12,
+ .num_col = 3,
+ },
+ [IQS7222_REG_GRP_CHAN] = {
+ .base = 0xA000,
+ .num_row = 12,
+ .num_col = 6,
+ },
+ [IQS7222_REG_GRP_FILT] = {
+ .base = 0xAC00,
+ .num_row = 1,
+ .num_col = 2,
+ },
+ [IQS7222_REG_GRP_SLDR] = {
+ .base = 0xB000,
+ .num_row = 2,
+ .num_col = 11,
+ },
+ [IQS7222_REG_GRP_GPIO] = {
+ .base = 0xC000,
+ .num_row = 1,
+ .num_col = 3,
+ },
+ [IQS7222_REG_GRP_SYS] = {
+ .base = IQS7222_SYS_SETUP,
+ .num_row = 1,
+ .num_col = 13,
+ },
+ },
+ },
+ {
+ .prod_num = IQS7222_PROD_NUM_A,
+ .fw_major = 1,
.fw_minor = 12,
.sldr_res = U8_MAX * 16,
.touch_link = 1768,
.allow_offset = 9,
.event_offset = 10,
.comms_offset = 12,
+ .legacy_gesture = true,
.reg_grps = {
[IQS7222_REG_GRP_STAT] = {
.base = IQS7222_SYS_STATUS,
@@ -874,6 +935,16 @@ static const struct iqs7222_prop_desc iqs7222_props[] = {
.reg_offset = 9,
.reg_shift = 8,
.reg_width = 8,
+ .val_pitch = 16,
+ .label = "maximum gesture time",
+ },
+ {
+ .name = "azoteq,gesture-max-ms",
+ .reg_grp = IQS7222_REG_GRP_SLDR,
+ .reg_key = IQS7222_REG_KEY_TAP_LEGACY,
+ .reg_offset = 9,
+ .reg_shift = 8,
+ .reg_width = 8,
.val_pitch = 4,
.label = "maximum gesture time",
},
@@ -884,6 +955,16 @@ static const struct iqs7222_prop_desc iqs7222_props[] = {
.reg_offset = 9,
.reg_shift = 3,
.reg_width = 5,
+ .val_pitch = 16,
+ .label = "minimum gesture time",
+ },
+ {
+ .name = "azoteq,gesture-min-ms",
+ .reg_grp = IQS7222_REG_GRP_SLDR,
+ .reg_key = IQS7222_REG_KEY_TAP_LEGACY,
+ .reg_offset = 9,
+ .reg_shift = 3,
+ .reg_width = 5,
.val_pitch = 4,
.label = "minimum gesture time",
},
@@ -898,12 +979,32 @@ static const struct iqs7222_prop_desc iqs7222_props[] = {
.label = "gesture distance",
},
{
+ .name = "azoteq,gesture-dist",
+ .reg_grp = IQS7222_REG_GRP_SLDR,
+ .reg_key = IQS7222_REG_KEY_AXIAL_LEGACY,
+ .reg_offset = 10,
+ .reg_shift = 8,
+ .reg_width = 8,
+ .val_pitch = 16,
+ .label = "gesture distance",
+ },
+ {
.name = "azoteq,gesture-max-ms",
.reg_grp = IQS7222_REG_GRP_SLDR,
.reg_key = IQS7222_REG_KEY_AXIAL,
.reg_offset = 10,
.reg_shift = 0,
.reg_width = 8,
+ .val_pitch = 16,
+ .label = "maximum gesture time",
+ },
+ {
+ .name = "azoteq,gesture-max-ms",
+ .reg_grp = IQS7222_REG_GRP_SLDR,
+ .reg_key = IQS7222_REG_KEY_AXIAL_LEGACY,
+ .reg_offset = 10,
+ .reg_shift = 0,
+ .reg_width = 8,
.val_pitch = 4,
.label = "maximum gesture time",
},
@@ -1567,56 +1668,17 @@ static int iqs7222_gpio_select(struct iqs7222_private *iqs7222,
}
static int iqs7222_parse_props(struct iqs7222_private *iqs7222,
- struct fwnode_handle **child_node,
- int child_index,
+ struct fwnode_handle *reg_grp_node,
+ int reg_grp_index,
enum iqs7222_reg_grp_id reg_grp,
enum iqs7222_reg_key_id reg_key)
{
- u16 *setup = iqs7222_setup(iqs7222, reg_grp, child_index);
+ u16 *setup = iqs7222_setup(iqs7222, reg_grp, reg_grp_index);
struct i2c_client *client = iqs7222->client;
- struct fwnode_handle *reg_grp_node;
- char reg_grp_name[16];
int i;
- switch (reg_grp) {
- case IQS7222_REG_GRP_CYCLE:
- case IQS7222_REG_GRP_CHAN:
- case IQS7222_REG_GRP_SLDR:
- case IQS7222_REG_GRP_GPIO:
- case IQS7222_REG_GRP_BTN:
- /*
- * These groups derive a child node and return it to the caller
- * for additional group-specific processing. In some cases, the
- * child node may have already been derived.
- */
- reg_grp_node = *child_node;
- if (reg_grp_node)
- break;
-
- snprintf(reg_grp_name, sizeof(reg_grp_name), "%s-%d",
- iqs7222_reg_grp_names[reg_grp], child_index);
-
- reg_grp_node = device_get_named_child_node(&client->dev,
- reg_grp_name);
- if (!reg_grp_node)
- return 0;
-
- *child_node = reg_grp_node;
- break;
-
- case IQS7222_REG_GRP_GLBL:
- case IQS7222_REG_GRP_FILT:
- case IQS7222_REG_GRP_SYS:
- /*
- * These groups are not organized beneath a child node, nor are
- * they subject to any additional processing by the caller.
- */
- reg_grp_node = dev_fwnode(&client->dev);
- break;
-
- default:
- return -EINVAL;
- }
+ if (!setup)
+ return 0;
for (i = 0; i < ARRAY_SIZE(iqs7222_props); i++) {
const char *name = iqs7222_props[i].name;
@@ -1686,11 +1748,66 @@ static int iqs7222_parse_props(struct iqs7222_private *iqs7222,
return 0;
}
-static int iqs7222_parse_cycle(struct iqs7222_private *iqs7222, int cycle_index)
+static int iqs7222_parse_event(struct iqs7222_private *iqs7222,
+ struct fwnode_handle *event_node,
+ int reg_grp_index,
+ enum iqs7222_reg_grp_id reg_grp,
+ enum iqs7222_reg_key_id reg_key,
+ u16 event_enable, u16 event_link,
+ unsigned int *event_type,
+ unsigned int *event_code)
+{
+ struct i2c_client *client = iqs7222->client;
+ int error;
+
+ error = iqs7222_parse_props(iqs7222, event_node, reg_grp_index,
+ reg_grp, reg_key);
+ if (error)
+ return error;
+
+ error = iqs7222_gpio_select(iqs7222, event_node, event_enable,
+ event_link);
+ if (error)
+ return error;
+
+ error = fwnode_property_read_u32(event_node, "linux,code", event_code);
+ if (error == -EINVAL) {
+ return 0;
+ } else if (error) {
+ dev_err(&client->dev, "Failed to read %s code: %d\n",
+ fwnode_get_name(event_node), error);
+ return error;
+ }
+
+ if (!event_type) {
+ input_set_capability(iqs7222->keypad, EV_KEY, *event_code);
+ return 0;
+ }
+
+ error = fwnode_property_read_u32(event_node, "linux,input-type",
+ event_type);
+ if (error == -EINVAL) {
+ *event_type = EV_KEY;
+ } else if (error) {
+ dev_err(&client->dev, "Failed to read %s input type: %d\n",
+ fwnode_get_name(event_node), error);
+ return error;
+ } else if (*event_type != EV_KEY && *event_type != EV_SW) {
+ dev_err(&client->dev, "Invalid %s input type: %d\n",
+ fwnode_get_name(event_node), *event_type);
+ return -EINVAL;
+ }
+
+ input_set_capability(iqs7222->keypad, *event_type, *event_code);
+
+ return 0;
+}
+
+static int iqs7222_parse_cycle(struct iqs7222_private *iqs7222,
+ struct fwnode_handle *cycle_node, int cycle_index)
{
u16 *cycle_setup = iqs7222->cycle_setup[cycle_index];
struct i2c_client *client = iqs7222->client;
- struct fwnode_handle *cycle_node = NULL;
unsigned int pins[9];
int error, count, i;
@@ -1698,17 +1815,7 @@ static int iqs7222_parse_cycle(struct iqs7222_private *iqs7222, int cycle_index)
* Each channel shares a cycle with one other channel; the mapping of
* channels to cycles is fixed. Properties defined for a cycle impact
* both channels tied to the cycle.
- */
- error = iqs7222_parse_props(iqs7222, &cycle_node, cycle_index,
- IQS7222_REG_GRP_CYCLE,
- IQS7222_REG_KEY_NONE);
- if (error)
- return error;
-
- if (!cycle_node)
- return 0;
-
- /*
+ *
* Unlike channels which are restricted to a select range of CRx pins
* based on channel number, any cycle can claim any of the device's 9
* CTx pins (CTx0-8).
@@ -1750,11 +1857,11 @@ static int iqs7222_parse_cycle(struct iqs7222_private *iqs7222, int cycle_index)
return 0;
}
-static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index)
+static int iqs7222_parse_chan(struct iqs7222_private *iqs7222,
+ struct fwnode_handle *chan_node, int chan_index)
{
const struct iqs7222_dev_desc *dev_desc = iqs7222->dev_desc;
struct i2c_client *client = iqs7222->client;
- struct fwnode_handle *chan_node = NULL;
int num_chan = dev_desc->reg_grps[IQS7222_REG_GRP_CHAN].num_row;
int ext_chan = rounddown(num_chan, 10);
int error, i;
@@ -1762,15 +1869,6 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index)
u16 *sys_setup = iqs7222->sys_setup;
unsigned int val;
- error = iqs7222_parse_props(iqs7222, &chan_node, chan_index,
- IQS7222_REG_GRP_CHAN,
- IQS7222_REG_KEY_NONE);
- if (error)
- return error;
-
- if (!chan_node)
- return 0;
-
if (dev_desc->allow_offset &&
fwnode_property_present(chan_node, "azoteq,ulp-allow"))
sys_setup[dev_desc->allow_offset] &= ~BIT(chan_index);
@@ -1810,8 +1908,9 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index)
chan_setup[0] |= IQS7222_CHAN_SETUP_0_REF_MODE_FOLLOW;
chan_setup[4] = val * 42 + 1048;
- if (!fwnode_property_read_u32(chan_node, "azoteq,ref-weight",
- &val)) {
+ error = fwnode_property_read_u32(chan_node, "azoteq,ref-weight",
+ &val);
+ if (!error) {
if (val > U16_MAX) {
dev_err(&client->dev,
"Invalid %s reference weight: %u\n",
@@ -1820,6 +1919,11 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index)
}
chan_setup[5] = val;
+ } else if (error != -EINVAL) {
+ dev_err(&client->dev,
+ "Failed to read %s reference weight: %d\n",
+ fwnode_get_name(chan_node), error);
+ return error;
}
/*
@@ -1892,21 +1996,10 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index)
if (!event_node)
continue;
- error = iqs7222_parse_props(iqs7222, &event_node, chan_index,
- IQS7222_REG_GRP_BTN,
- iqs7222_kp_events[i].reg_key);
- if (error)
- return error;
-
- error = iqs7222_gpio_select(iqs7222, event_node,
- BIT(chan_index),
- dev_desc->touch_link - (i ? 0 : 2));
- if (error)
- return error;
-
- if (!fwnode_property_read_u32(event_node,
- "azoteq,timeout-press-ms",
- &val)) {
+ error = fwnode_property_read_u32(event_node,
+ "azoteq,timeout-press-ms",
+ &val);
+ if (!error) {
/*
* The IQS7222B employs a global pair of press timeout
* registers as opposed to channel-specific registers.
@@ -1919,57 +2012,31 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index)
if (val > U8_MAX * 500) {
dev_err(&client->dev,
"Invalid %s press timeout: %u\n",
- fwnode_get_name(chan_node), val);
+ fwnode_get_name(event_node), val);
+ fwnode_handle_put(event_node);
return -EINVAL;
}
*setup &= ~(U8_MAX << i * 8);
*setup |= (val / 500 << i * 8);
- }
-
- error = fwnode_property_read_u32(event_node, "linux,code",
- &val);
- if (error) {
- dev_err(&client->dev, "Failed to read %s code: %d\n",
- fwnode_get_name(chan_node), error);
+ } else if (error != -EINVAL) {
+ dev_err(&client->dev,
+ "Failed to read %s press timeout: %d\n",
+ fwnode_get_name(event_node), error);
+ fwnode_handle_put(event_node);
return error;
}
- iqs7222->kp_code[chan_index][i] = val;
- iqs7222->kp_type[chan_index][i] = EV_KEY;
-
- if (fwnode_property_present(event_node, "linux,input-type")) {
- error = fwnode_property_read_u32(event_node,
- "linux,input-type",
- &val);
- if (error) {
- dev_err(&client->dev,
- "Failed to read %s input type: %d\n",
- fwnode_get_name(chan_node), error);
- return error;
- }
-
- if (val != EV_KEY && val != EV_SW) {
- dev_err(&client->dev,
- "Invalid %s input type: %u\n",
- fwnode_get_name(chan_node), val);
- return -EINVAL;
- }
-
- iqs7222->kp_type[chan_index][i] = val;
- }
-
- /*
- * Reference channels can opt out of event reporting by using
- * KEY_RESERVED in place of a true key or switch code.
- */
- if (iqs7222->kp_type[chan_index][i] == EV_KEY &&
- iqs7222->kp_code[chan_index][i] == KEY_RESERVED)
- continue;
-
- input_set_capability(iqs7222->keypad,
- iqs7222->kp_type[chan_index][i],
- iqs7222->kp_code[chan_index][i]);
+ error = iqs7222_parse_event(iqs7222, event_node, chan_index,
+ IQS7222_REG_GRP_BTN,
+ iqs7222_kp_events[i].reg_key,
+ BIT(chan_index),
+ dev_desc->touch_link - (i ? 0 : 2),
+ &iqs7222->kp_type[chan_index][i],
+ &iqs7222->kp_code[chan_index][i]);
+ fwnode_handle_put(event_node);
+ if (error)
+ return error;
if (!dev_desc->event_offset)
continue;
@@ -1981,16 +2048,16 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index)
* The following call handles a special pair of properties that apply
* to a channel node, but reside within the button (event) group.
*/
- return iqs7222_parse_props(iqs7222, &chan_node, chan_index,
+ return iqs7222_parse_props(iqs7222, chan_node, chan_index,
IQS7222_REG_GRP_BTN,
IQS7222_REG_KEY_DEBOUNCE);
}
-static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
+static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222,
+ struct fwnode_handle *sldr_node, int sldr_index)
{
const struct iqs7222_dev_desc *dev_desc = iqs7222->dev_desc;
struct i2c_client *client = iqs7222->client;
- struct fwnode_handle *sldr_node = NULL;
int num_chan = dev_desc->reg_grps[IQS7222_REG_GRP_CHAN].num_row;
int ext_chan = rounddown(num_chan, 10);
int count, error, reg_offset, i;
@@ -1998,15 +2065,6 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
u16 *sldr_setup = iqs7222->sldr_setup[sldr_index];
unsigned int chan_sel[4], val;
- error = iqs7222_parse_props(iqs7222, &sldr_node, sldr_index,
- IQS7222_REG_GRP_SLDR,
- IQS7222_REG_KEY_NONE);
- if (error)
- return error;
-
- if (!sldr_node)
- return 0;
-
/*
* Each slider can be spread across 3 to 4 channels. It is possible to
* select only 2 channels, but doing so prevents the slider from using
@@ -2065,8 +2123,9 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
if (fwnode_property_present(sldr_node, "azoteq,use-prox"))
sldr_setup[4 + reg_offset] -= 2;
- if (!fwnode_property_read_u32(sldr_node, "azoteq,slider-size", &val)) {
- if (!val || val > dev_desc->sldr_res) {
+ error = fwnode_property_read_u32(sldr_node, "azoteq,slider-size", &val);
+ if (!error) {
+ if (val > dev_desc->sldr_res) {
dev_err(&client->dev, "Invalid %s size: %u\n",
fwnode_get_name(sldr_node), val);
return -EINVAL;
@@ -2079,9 +2138,21 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
sldr_setup[2] |= (val / 16 <<
IQS7222_SLDR_SETUP_2_RES_SHIFT);
}
+ } else if (error != -EINVAL) {
+ dev_err(&client->dev, "Failed to read %s size: %d\n",
+ fwnode_get_name(sldr_node), error);
+ return error;
}
- if (!fwnode_property_read_u32(sldr_node, "azoteq,top-speed", &val)) {
+ if (!(reg_offset ? sldr_setup[3]
+ : sldr_setup[2] & IQS7222_SLDR_SETUP_2_RES_MASK)) {
+ dev_err(&client->dev, "Undefined %s size\n",
+ fwnode_get_name(sldr_node));
+ return -EINVAL;
+ }
+
+ error = fwnode_property_read_u32(sldr_node, "azoteq,top-speed", &val);
+ if (!error) {
if (val > (reg_offset ? U16_MAX : U8_MAX * 4)) {
dev_err(&client->dev, "Invalid %s top speed: %u\n",
fwnode_get_name(sldr_node), val);
@@ -2094,9 +2165,14 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
sldr_setup[2] &= ~IQS7222_SLDR_SETUP_2_TOP_SPEED_MASK;
sldr_setup[2] |= (val / 4);
}
+ } else if (error != -EINVAL) {
+ dev_err(&client->dev, "Failed to read %s top speed: %d\n",
+ fwnode_get_name(sldr_node), error);
+ return error;
}
- if (!fwnode_property_read_u32(sldr_node, "linux,axis", &val)) {
+ error = fwnode_property_read_u32(sldr_node, "linux,axis", &val);
+ if (!error) {
u16 sldr_max = sldr_setup[3] - 1;
if (!reg_offset) {
@@ -2110,6 +2186,10 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
input_set_abs_params(iqs7222->keypad, val, 0, sldr_max, 0, 0);
iqs7222->sl_axis[sldr_index] = val;
+ } else if (error != -EINVAL) {
+ dev_err(&client->dev, "Failed to read %s axis: %d\n",
+ fwnode_get_name(sldr_node), error);
+ return error;
}
if (dev_desc->wheel_enable) {
@@ -2130,46 +2210,47 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
for (i = 0; i < ARRAY_SIZE(iqs7222_sl_events); i++) {
const char *event_name = iqs7222_sl_events[i].name;
struct fwnode_handle *event_node;
+ enum iqs7222_reg_key_id reg_key;
event_node = fwnode_get_named_child_node(sldr_node, event_name);
if (!event_node)
continue;
- error = iqs7222_parse_props(iqs7222, &event_node, sldr_index,
- IQS7222_REG_GRP_SLDR,
- reg_offset ?
- IQS7222_REG_KEY_RESERVED :
- iqs7222_sl_events[i].reg_key);
- if (error)
- return error;
+ /*
+ * Depending on the device, gestures are either offered using
+ * one of two timing resolutions, or are not supported at all.
+ */
+ if (reg_offset)
+ reg_key = IQS7222_REG_KEY_RESERVED;
+ else if (dev_desc->legacy_gesture &&
+ iqs7222_sl_events[i].reg_key == IQS7222_REG_KEY_TAP)
+ reg_key = IQS7222_REG_KEY_TAP_LEGACY;
+ else if (dev_desc->legacy_gesture &&
+ iqs7222_sl_events[i].reg_key == IQS7222_REG_KEY_AXIAL)
+ reg_key = IQS7222_REG_KEY_AXIAL_LEGACY;
+ else
+ reg_key = iqs7222_sl_events[i].reg_key;
/*
* The press/release event does not expose a direct GPIO link,
* but one can be emulated by tying each of the participating
* channels to the same GPIO.
*/
- error = iqs7222_gpio_select(iqs7222, event_node,
+ error = iqs7222_parse_event(iqs7222, event_node, sldr_index,
+ IQS7222_REG_GRP_SLDR, reg_key,
i ? iqs7222_sl_events[i].enable
: sldr_setup[3 + reg_offset],
i ? 1568 + sldr_index * 30
- : sldr_setup[4 + reg_offset]);
+ : sldr_setup[4 + reg_offset],
+ NULL,
+ &iqs7222->sl_code[sldr_index][i]);
+ fwnode_handle_put(event_node);
if (error)
return error;
if (!reg_offset)
sldr_setup[9] |= iqs7222_sl_events[i].enable;
- error = fwnode_property_read_u32(event_node, "linux,code",
- &val);
- if (error) {
- dev_err(&client->dev, "Failed to read %s code: %d\n",
- fwnode_get_name(sldr_node), error);
- return error;
- }
-
- iqs7222->sl_code[sldr_index][i] = val;
- input_set_capability(iqs7222->keypad, EV_KEY, val);
-
if (!dev_desc->event_offset)
continue;
@@ -2190,19 +2271,63 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
* The following call handles a special pair of properties that shift
* to make room for a wheel enable control in the case of IQS7222C.
*/
- return iqs7222_parse_props(iqs7222, &sldr_node, sldr_index,
+ return iqs7222_parse_props(iqs7222, sldr_node, sldr_index,
IQS7222_REG_GRP_SLDR,
dev_desc->wheel_enable ?
IQS7222_REG_KEY_WHEEL :
IQS7222_REG_KEY_NO_WHEEL);
}
+static int (*iqs7222_parse_extra[IQS7222_NUM_REG_GRPS])
+ (struct iqs7222_private *iqs7222,
+ struct fwnode_handle *reg_grp_node,
+ int reg_grp_index) = {
+ [IQS7222_REG_GRP_CYCLE] = iqs7222_parse_cycle,
+ [IQS7222_REG_GRP_CHAN] = iqs7222_parse_chan,
+ [IQS7222_REG_GRP_SLDR] = iqs7222_parse_sldr,
+};
+
+static int iqs7222_parse_reg_grp(struct iqs7222_private *iqs7222,
+ enum iqs7222_reg_grp_id reg_grp,
+ int reg_grp_index)
+{
+ struct i2c_client *client = iqs7222->client;
+ struct fwnode_handle *reg_grp_node;
+ int error;
+
+ if (iqs7222_reg_grp_names[reg_grp]) {
+ char reg_grp_name[16];
+
+ snprintf(reg_grp_name, sizeof(reg_grp_name), "%s-%d",
+ iqs7222_reg_grp_names[reg_grp], reg_grp_index);
+
+ reg_grp_node = device_get_named_child_node(&client->dev,
+ reg_grp_name);
+ } else {
+ reg_grp_node = fwnode_handle_get(dev_fwnode(&client->dev));
+ }
+
+ if (!reg_grp_node)
+ return 0;
+
+ error = iqs7222_parse_props(iqs7222, reg_grp_node, reg_grp_index,
+ reg_grp, IQS7222_REG_KEY_NONE);
+
+ if (!error && iqs7222_parse_extra[reg_grp])
+ error = iqs7222_parse_extra[reg_grp](iqs7222, reg_grp_node,
+ reg_grp_index);
+
+ fwnode_handle_put(reg_grp_node);
+
+ return error;
+}
+
static int iqs7222_parse_all(struct iqs7222_private *iqs7222)
{
const struct iqs7222_dev_desc *dev_desc = iqs7222->dev_desc;
const struct iqs7222_reg_grp_desc *reg_grps = dev_desc->reg_grps;
u16 *sys_setup = iqs7222->sys_setup;
- int error, i;
+ int error, i, j;
if (dev_desc->allow_offset)
sys_setup[dev_desc->allow_offset] = U16_MAX;
@@ -2210,32 +2335,13 @@ static int iqs7222_parse_all(struct iqs7222_private *iqs7222)
if (dev_desc->event_offset)
sys_setup[dev_desc->event_offset] = IQS7222_EVENT_MASK_ATI;
- for (i = 0; i < reg_grps[IQS7222_REG_GRP_CYCLE].num_row; i++) {
- error = iqs7222_parse_cycle(iqs7222, i);
- if (error)
- return error;
- }
-
- error = iqs7222_parse_props(iqs7222, NULL, 0, IQS7222_REG_GRP_GLBL,
- IQS7222_REG_KEY_NONE);
- if (error)
- return error;
-
for (i = 0; i < reg_grps[IQS7222_REG_GRP_GPIO].num_row; i++) {
- struct fwnode_handle *gpio_node = NULL;
u16 *gpio_setup = iqs7222->gpio_setup[i];
- int j;
gpio_setup[0] &= ~IQS7222_GPIO_SETUP_0_GPIO_EN;
gpio_setup[1] = 0;
gpio_setup[2] = 0;
- error = iqs7222_parse_props(iqs7222, &gpio_node, i,
- IQS7222_REG_GRP_GPIO,
- IQS7222_REG_KEY_NONE);
- if (error)
- return error;
-
if (reg_grps[IQS7222_REG_GRP_GPIO].num_row == 1)
continue;
@@ -2258,29 +2364,21 @@ static int iqs7222_parse_all(struct iqs7222_private *iqs7222)
chan_setup[5] = 0;
}
- for (i = 0; i < reg_grps[IQS7222_REG_GRP_CHAN].num_row; i++) {
- error = iqs7222_parse_chan(iqs7222, i);
- if (error)
- return error;
- }
-
- error = iqs7222_parse_props(iqs7222, NULL, 0, IQS7222_REG_GRP_FILT,
- IQS7222_REG_KEY_NONE);
- if (error)
- return error;
-
for (i = 0; i < reg_grps[IQS7222_REG_GRP_SLDR].num_row; i++) {
u16 *sldr_setup = iqs7222->sldr_setup[i];
sldr_setup[0] &= ~IQS7222_SLDR_SETUP_0_CHAN_CNT_MASK;
+ }
- error = iqs7222_parse_sldr(iqs7222, i);
- if (error)
- return error;
+ for (i = 0; i < IQS7222_NUM_REG_GRPS; i++) {
+ for (j = 0; j < reg_grps[i].num_row; j++) {
+ error = iqs7222_parse_reg_grp(iqs7222, i, j);
+ if (error)
+ return error;
+ }
}
- return iqs7222_parse_props(iqs7222, NULL, 0, IQS7222_REG_GRP_SYS,
- IQS7222_REG_KEY_NONE);
+ return 0;
}
static int iqs7222_report(struct iqs7222_private *iqs7222)
diff --git a/drivers/input/misc/kxtj9.c b/drivers/input/misc/kxtj9.c
index bbb81617c2b2..7e73e6e0730f 100644
--- a/drivers/input/misc/kxtj9.c
+++ b/drivers/input/misc/kxtj9.c
@@ -385,8 +385,7 @@ out:
return retval;
}
-static int kxtj9_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int kxtj9_probe(struct i2c_client *client)
{
const struct kxtj9_platform_data *pdata =
dev_get_platdata(&client->dev);
@@ -539,7 +538,7 @@ static struct i2c_driver kxtj9_driver = {
.name = NAME,
.pm = &kxtj9_pm_ops,
},
- .probe = kxtj9_probe,
+ .probe_new = kxtj9_probe,
.id_table = kxtj9_id,
};
diff --git a/drivers/input/misc/max8997_haptic.c b/drivers/input/misc/max8997_haptic.c
index cd5e99ec1d3c..99cbc5ee89d1 100644
--- a/drivers/input/misc/max8997_haptic.c
+++ b/drivers/input/misc/max8997_haptic.c
@@ -278,8 +278,7 @@ static int max8997_haptic_probe(struct platform_device *pdev)
break;
case MAX8997_EXTERNAL_MODE:
- chip->pwm = pwm_request(haptic_pdata->pwm_channel_id,
- "max8997-haptic");
+ chip->pwm = pwm_get(&pdev->dev, NULL);
if (IS_ERR(chip->pwm)) {
error = PTR_ERR(chip->pwm);
dev_err(&pdev->dev,
@@ -344,7 +343,7 @@ err_put_regulator:
regulator_put(chip->regulator);
err_free_pwm:
if (chip->mode == MAX8997_EXTERNAL_MODE)
- pwm_free(chip->pwm);
+ pwm_put(chip->pwm);
err_free_mem:
input_free_device(input_dev);
kfree(chip);
@@ -360,7 +359,7 @@ static int max8997_haptic_remove(struct platform_device *pdev)
regulator_put(chip->regulator);
if (chip->mode == MAX8997_EXTERNAL_MODE)
- pwm_free(chip->pwm);
+ pwm_put(chip->pwm);
kfree(chip);
diff --git a/drivers/input/misc/mma8450.c b/drivers/input/misc/mma8450.c
index 1b5a5e19230a..b12152536976 100644
--- a/drivers/input/misc/mma8450.c
+++ b/drivers/input/misc/mma8450.c
@@ -146,8 +146,7 @@ static void mma8450_close(struct input_dev *input)
/*
* I2C init/probing/exit functions
*/
-static int mma8450_probe(struct i2c_client *c,
- const struct i2c_device_id *id)
+static int mma8450_probe(struct i2c_client *c)
{
struct input_dev *input;
int err;
@@ -203,7 +202,7 @@ static struct i2c_driver mma8450_driver = {
.name = MMA8450_DRV_NAME,
.of_match_table = mma8450_dt_ids,
},
- .probe = mma8450_probe,
+ .probe_new = mma8450_probe,
.id_table = mma8450_id,
};
diff --git a/drivers/input/misc/pcf8574_keypad.c b/drivers/input/misc/pcf8574_keypad.c
index cfd6640e4f82..fd1ff3f1cd92 100644
--- a/drivers/input/misc/pcf8574_keypad.c
+++ b/drivers/input/misc/pcf8574_keypad.c
@@ -80,7 +80,7 @@ static irqreturn_t pcf8574_kp_irq_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int pcf8574_kp_probe(struct i2c_client *client, const struct i2c_device_id *id)
+static int pcf8574_kp_probe(struct i2c_client *client)
{
int i, ret;
struct input_dev *idev;
@@ -209,7 +209,7 @@ static struct i2c_driver pcf8574_kp_driver = {
.pm = &pcf8574_kp_pm_ops,
#endif
},
- .probe = pcf8574_kp_probe,
+ .probe_new = pcf8574_kp_probe,
.remove = pcf8574_kp_remove,
.id_table = pcf8574_kp_id,
};
diff --git a/drivers/input/mouse/cyapa.c b/drivers/input/mouse/cyapa.c
index 77cc653edca2..7e88a6ec7989 100644
--- a/drivers/input/mouse/cyapa.c
+++ b/drivers/input/mouse/cyapa.c
@@ -1244,8 +1244,7 @@ static void cyapa_disable_regulator(void *data)
regulator_disable(cyapa->vcc);
}
-static int cyapa_probe(struct i2c_client *client,
- const struct i2c_device_id *dev_id)
+static int cyapa_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct cyapa *cyapa;
@@ -1490,7 +1489,7 @@ static struct i2c_driver cyapa_driver = {
.of_match_table = of_match_ptr(cyapa_of_match),
},
- .probe = cyapa_probe,
+ .probe_new = cyapa_probe,
.id_table = cyapa_id_table,
};
diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c
index d4eb59b55bf1..76729ada1582 100644
--- a/drivers/input/mouse/elan_i2c_core.c
+++ b/drivers/input/mouse/elan_i2c_core.c
@@ -33,6 +33,7 @@
#include <linux/jiffies.h>
#include <linux/completion.h>
#include <linux/of.h>
+#include <linux/pm_wakeirq.h>
#include <linux/property.h>
#include <linux/regulator/consumer.h>
#include <asm/unaligned.h>
@@ -86,8 +87,6 @@ struct elan_tp_data {
u16 fw_page_size;
u32 fw_signature_address;
- bool irq_wake;
-
u8 min_baseline;
u8 max_baseline;
bool baseline_ready;
@@ -1188,8 +1187,7 @@ static void elan_disable_regulator(void *_data)
regulator_disable(data->vcc);
}
-static int elan_probe(struct i2c_client *client,
- const struct i2c_device_id *dev_id)
+static int elan_probe(struct i2c_client *client)
{
const struct elan_transport_ops *transport_ops;
struct device *dev = &client->dev;
@@ -1327,13 +1325,6 @@ static int elan_probe(struct i2c_client *client,
}
}
- /*
- * Systems using device tree should set up wakeup via DTS,
- * the rest will configure device as wakeup source by default.
- */
- if (!dev->of_node)
- device_init_wakeup(dev, true);
-
return 0;
}
@@ -1356,8 +1347,6 @@ static int __maybe_unused elan_suspend(struct device *dev)
if (device_may_wakeup(dev)) {
ret = elan_sleep(data);
- /* Enable wake from IRQ */
- data->irq_wake = (enable_irq_wake(client->irq) == 0);
} else {
ret = elan_set_power(data, false);
if (ret)
@@ -1388,9 +1377,6 @@ static int __maybe_unused elan_resume(struct device *dev)
dev_err(dev, "error %d enabling regulator\n", error);
goto err;
}
- } else if (data->irq_wake) {
- disable_irq_wake(client->irq);
- data->irq_wake = false;
}
error = elan_set_power(data, true);
@@ -1438,7 +1424,7 @@ static struct i2c_driver elan_driver = {
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
.dev_groups = elan_sysfs_groups,
},
- .probe = elan_probe,
+ .probe_new = elan_probe,
.id_table = elan_id,
};
diff --git a/drivers/input/mouse/synaptics_i2c.c b/drivers/input/mouse/synaptics_i2c.c
index 987ee67a1045..6487c8c60d5e 100644
--- a/drivers/input/mouse/synaptics_i2c.c
+++ b/drivers/input/mouse/synaptics_i2c.c
@@ -521,8 +521,7 @@ static struct synaptics_i2c *synaptics_i2c_touch_create(struct i2c_client *clien
return touch;
}
-static int synaptics_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *dev_id)
+static int synaptics_i2c_probe(struct i2c_client *client)
{
int ret;
struct synaptics_i2c *touch;
@@ -651,7 +650,7 @@ static struct i2c_driver synaptics_i2c_driver = {
.pm = &synaptics_i2c_pm,
},
- .probe = synaptics_i2c_probe,
+ .probe_new = synaptics_i2c_probe,
.remove = synaptics_i2c_remove,
.id_table = synaptics_i2c_id_table,
diff --git a/drivers/input/rmi4/rmi_i2c.c b/drivers/input/rmi4/rmi_i2c.c
index 50305fcfbef5..f2b75c6d3224 100644
--- a/drivers/input/rmi4/rmi_i2c.c
+++ b/drivers/input/rmi4/rmi_i2c.c
@@ -198,8 +198,7 @@ static void rmi_i2c_unregister_transport(void *data)
rmi_unregister_transport_device(&rmi_i2c->xport);
}
-static int rmi_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int rmi_i2c_probe(struct i2c_client *client)
{
struct rmi_device_platform_data *pdata;
struct rmi_device_platform_data *client_pdata =
@@ -383,7 +382,7 @@ static struct i2c_driver rmi_i2c_driver = {
.of_match_table = of_match_ptr(rmi_i2c_of_match),
},
.id_table = rmi_id,
- .probe = rmi_i2c_probe,
+ .probe_new = rmi_i2c_probe,
};
module_i2c_driver(rmi_i2c_driver);
diff --git a/drivers/input/rmi4/rmi_smbus.c b/drivers/input/rmi4/rmi_smbus.c
index c130468541b7..8a9ee2bd7402 100644
--- a/drivers/input/rmi4/rmi_smbus.c
+++ b/drivers/input/rmi4/rmi_smbus.c
@@ -268,8 +268,7 @@ static const struct rmi_transport_ops rmi_smb_ops = {
.reset = rmi_smb_reset,
};
-static int rmi_smb_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int rmi_smb_probe(struct i2c_client *client)
{
struct rmi_device_platform_data *pdata = dev_get_platdata(&client->dev);
struct rmi_smb_xport *rmi_smb;
@@ -420,7 +419,7 @@ static struct i2c_driver rmi_smb_driver = {
.pm = &rmi_smb_pm,
},
.id_table = rmi_id,
- .probe = rmi_smb_probe,
+ .probe_new = rmi_smb_probe,
.remove = rmi_smb_remove,
};
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index dc90a3ea51ee..68d99a112e14 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -284,6 +284,22 @@ config TOUCHSCREEN_CYTTSP4_SPI
To compile this driver as a module, choose M here: the
module will be called cyttsp4_spi.
+config TOUCHSCREEN_CYTTSP5
+ tristate "Cypress TrueTouch Gen5 Touchscreen Driver"
+ depends on I2C
+ select REGMAP_I2C
+ select CRC_ITU_T
+ help
+ Driver for Parade TrueTouch Standard Product Generation 5
+ touchscreen controllers. I2C bus interface support only.
+
+ Say Y here if you have a Cypress Gen5 touchscreen.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called cyttsp5.
+
config TOUCHSCREEN_DA9034
tristate "Touchscreen support for Dialog Semiconductor DA9034"
depends on PMIC_DA903X
@@ -422,6 +438,18 @@ config TOUCHSCREEN_HYCON_HY46XX
To compile this driver as a module, choose M here: the
module will be called hycon-hy46xx.
+config TOUCHSCREEN_HYNITRON_CSTXXX
+ tristate "Hynitron touchscreen support"
+ depends on I2C
+ help
+ Say Y here if you have a touchscreen using a Hynitron
+ touchscreen controller.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called hynitron-cstxxx.
+
config TOUCHSCREEN_ILI210X
tristate "Ilitek ILI210X based touchscreen"
depends on I2C
@@ -1241,7 +1269,7 @@ config TOUCHSCREEN_STMFTS
config TOUCHSCREEN_STMPE
tristate "STMicroelectronics STMPE touchscreens"
depends on MFD_STMPE
- depends on (OF || COMPILE_TEST)
+ depends on OF
help
Say Y here if you want support for STMicroelectronics
STMPE touchscreen controllers.
@@ -1379,4 +1407,16 @@ config TOUCHSCREEN_ZINITIX
To compile this driver as a module, choose M here: the
module will be called zinitix.
+config TOUCHSCREEN_HIMAX_HX83112B
+ tristate "Himax hx83112b touchscreen driver"
+ depends on I2C
+ select REGMAP_I2C
+ help
+ Say Y here to enable support for Himax hx83112b touchscreens.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called himax_hx83112b.
+
endif
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 557f84fd2075..4968c370479a 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_TOUCHSCREEN_CYTTSP_SPI) += cyttsp_spi.o
obj-$(CONFIG_TOUCHSCREEN_CYTTSP4_CORE) += cyttsp4_core.o
obj-$(CONFIG_TOUCHSCREEN_CYTTSP4_I2C) += cyttsp4_i2c.o cyttsp_i2c_common.o
obj-$(CONFIG_TOUCHSCREEN_CYTTSP4_SPI) += cyttsp4_spi.o
+obj-$(CONFIG_TOUCHSCREEN_CYTTSP5) += cyttsp5.o
obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o
obj-$(CONFIG_TOUCHSCREEN_DA9052) += da9052_tsi.o
obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o
@@ -47,6 +48,7 @@ obj-$(CONFIG_TOUCHSCREEN_EXC3000) += exc3000.o
obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o
obj-$(CONFIG_TOUCHSCREEN_GOODIX) += goodix_ts.o
obj-$(CONFIG_TOUCHSCREEN_HIDEEP) += hideep.o
+obj-$(CONFIG_TOUCHSCREEN_HYNITRON_CSTXXX) += hynitron_cstxxx.o
obj-$(CONFIG_TOUCHSCREEN_ILI210X) += ili210x.o
obj-$(CONFIG_TOUCHSCREEN_ILITEK) += ilitek_ts_i2c.o
obj-$(CONFIG_TOUCHSCREEN_IMAGIS) += imagis.o
@@ -116,3 +118,4 @@ obj-$(CONFIG_TOUCHSCREEN_ROHM_BU21023) += rohm_bu21023.o
obj-$(CONFIG_TOUCHSCREEN_RASPBERRYPI_FW) += raspberrypi-ts.o
obj-$(CONFIG_TOUCHSCREEN_IQS5XX) += iqs5xx.o
obj-$(CONFIG_TOUCHSCREEN_ZINITIX) += zinitix.o
+obj-$(CONFIG_TOUCHSCREEN_HIMAX_HX83112B) += himax_hx83112b.o
diff --git a/drivers/input/touchscreen/ad7879-i2c.c b/drivers/input/touchscreen/ad7879-i2c.c
index 0f20a1fdcdba..dd8f31737bb8 100644
--- a/drivers/input/touchscreen/ad7879-i2c.c
+++ b/drivers/input/touchscreen/ad7879-i2c.c
@@ -23,8 +23,7 @@ static const struct regmap_config ad7879_i2c_regmap_config = {
.max_register = 15,
};
-static int ad7879_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int ad7879_i2c_probe(struct i2c_client *client)
{
struct regmap *regmap;
@@ -63,7 +62,7 @@ static struct i2c_driver ad7879_i2c_driver = {
.pm = &ad7879_pm_ops,
.of_match_table = of_match_ptr(ad7879_i2c_dt_ids),
},
- .probe = ad7879_i2c_probe,
+ .probe_new = ad7879_i2c_probe,
.id_table = ad7879_id,
};
diff --git a/drivers/input/touchscreen/ar1021_i2c.c b/drivers/input/touchscreen/ar1021_i2c.c
index dc6a85362a40..25bcc677e98b 100644
--- a/drivers/input/touchscreen/ar1021_i2c.c
+++ b/drivers/input/touchscreen/ar1021_i2c.c
@@ -87,8 +87,7 @@ static void ar1021_i2c_close(struct input_dev *dev)
disable_irq(client->irq);
}
-static int ar1021_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int ar1021_i2c_probe(struct i2c_client *client)
{
struct ar1021_i2c *ar1021;
struct input_dev *input;
@@ -182,7 +181,7 @@ static struct i2c_driver ar1021_i2c_driver = {
.of_match_table = ar1021_i2c_of_match,
},
- .probe = ar1021_i2c_probe,
+ .probe_new = ar1021_i2c_probe,
.id_table = ar1021_i2c_id,
};
module_i2c_driver(ar1021_i2c_driver);
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index ccecd1441f0b..39ef2664b852 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -3129,7 +3129,7 @@ static const struct dmi_system_id chromebook_T9_suspend_dmi[] = {
{ }
};
-static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
+static int mxt_probe(struct i2c_client *client)
{
struct mxt_data *data;
int error;
@@ -3377,7 +3377,7 @@ static struct i2c_driver mxt_driver = {
.acpi_match_table = ACPI_PTR(mxt_acpi_id),
.pm = &mxt_pm_ops,
},
- .probe = mxt_probe,
+ .probe_new = mxt_probe,
.remove = mxt_remove,
.id_table = mxt_id,
};
diff --git a/drivers/input/touchscreen/auo-pixcir-ts.c b/drivers/input/touchscreen/auo-pixcir-ts.c
index 2deae5a6823a..a4a1d58aeeac 100644
--- a/drivers/input/touchscreen/auo-pixcir-ts.c
+++ b/drivers/input/touchscreen/auo-pixcir-ts.c
@@ -482,8 +482,7 @@ static void auo_pixcir_reset(void *data)
gpiod_set_value_cansleep(ts->gpio_rst, 1);
}
-static int auo_pixcir_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int auo_pixcir_probe(struct i2c_client *client)
{
struct auo_pixcir_ts *ts;
struct input_dev *input_dev;
@@ -637,7 +636,7 @@ static struct i2c_driver auo_pixcir_driver = {
.pm = &auo_pixcir_pm_ops,
.of_match_table = of_match_ptr(auo_pixcir_ts_dt_idtable),
},
- .probe = auo_pixcir_probe,
+ .probe_new = auo_pixcir_probe,
.id_table = auo_pixcir_idtable,
};
diff --git a/drivers/input/touchscreen/bu21013_ts.c b/drivers/input/touchscreen/bu21013_ts.c
index 34f422e246ef..5a4dbd39a372 100644
--- a/drivers/input/touchscreen/bu21013_ts.c
+++ b/drivers/input/touchscreen/bu21013_ts.c
@@ -404,8 +404,7 @@ static void bu21013_disable_chip(void *_ts)
gpiod_set_value(ts->cs_gpiod, 0);
}
-static int bu21013_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int bu21013_probe(struct i2c_client *client)
{
struct bu21013_ts *ts;
struct input_dev *in_dev;
@@ -618,7 +617,7 @@ static struct i2c_driver bu21013_driver = {
.name = DRIVER_TP,
.pm = &bu21013_dev_pm_ops,
},
- .probe = bu21013_probe,
+ .probe_new = bu21013_probe,
.remove = bu21013_remove,
.id_table = bu21013_id,
};
diff --git a/drivers/input/touchscreen/bu21029_ts.c b/drivers/input/touchscreen/bu21029_ts.c
index 392950aa7856..215f4dc5105d 100644
--- a/drivers/input/touchscreen/bu21029_ts.c
+++ b/drivers/input/touchscreen/bu21029_ts.c
@@ -331,8 +331,7 @@ static void bu21029_stop_chip(struct input_dev *dev)
regulator_disable(bu21029->vdd);
}
-static int bu21029_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int bu21029_probe(struct i2c_client *client)
{
struct bu21029_ts_data *bu21029;
struct input_dev *in_dev;
@@ -475,7 +474,7 @@ static struct i2c_driver bu21029_driver = {
.pm = &bu21029_pm_ops,
},
.id_table = bu21029_ids,
- .probe = bu21029_probe,
+ .probe_new = bu21029_probe,
};
module_i2c_driver(bu21029_driver);
diff --git a/drivers/input/touchscreen/chipone_icn8318.c b/drivers/input/touchscreen/chipone_icn8318.c
index f2fb41fb031e..f6769e4bd4f2 100644
--- a/drivers/input/touchscreen/chipone_icn8318.c
+++ b/drivers/input/touchscreen/chipone_icn8318.c
@@ -176,8 +176,7 @@ static int icn8318_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(icn8318_pm_ops, icn8318_suspend, icn8318_resume);
-static int icn8318_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int icn8318_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct icn8318_data *data;
@@ -267,7 +266,7 @@ static struct i2c_driver icn8318_driver = {
.pm = &icn8318_pm_ops,
.of_match_table = icn8318_of_match,
},
- .probe = icn8318_probe,
+ .probe_new = icn8318_probe,
.id_table = icn8318_i2c_id,
};
diff --git a/drivers/input/touchscreen/cy8ctma140.c b/drivers/input/touchscreen/cy8ctma140.c
index a9be29139cbf..3a91d948b7f6 100644
--- a/drivers/input/touchscreen/cy8ctma140.c
+++ b/drivers/input/touchscreen/cy8ctma140.c
@@ -198,8 +198,7 @@ static void cy8ctma140_power_off_action(void *d)
cy8ctma140_power_down(ts);
}
-static int cy8ctma140_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int cy8ctma140_probe(struct i2c_client *client)
{
struct cy8ctma140 *ts;
struct input_dev *input;
@@ -344,7 +343,7 @@ static struct i2c_driver cy8ctma140_driver = {
.of_match_table = cy8ctma140_of_match,
},
.id_table = cy8ctma140_idtable,
- .probe = cy8ctma140_probe,
+ .probe_new = cy8ctma140_probe,
};
module_i2c_driver(cy8ctma140_driver);
diff --git a/drivers/input/touchscreen/cy8ctmg110_ts.c b/drivers/input/touchscreen/cy8ctmg110_ts.c
index 495ef156cf43..7c2b7309dbaf 100644
--- a/drivers/input/touchscreen/cy8ctmg110_ts.c
+++ b/drivers/input/touchscreen/cy8ctmg110_ts.c
@@ -168,8 +168,7 @@ static void cy8ctmg110_shut_off(void *_ts)
cy8ctmg110_power(ts, false);
}
-static int cy8ctmg110_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int cy8ctmg110_probe(struct i2c_client *client)
{
struct cy8ctmg110 *ts;
struct input_dev *input_dev;
@@ -279,7 +278,7 @@ static struct i2c_driver cy8ctmg110_driver = {
.pm = &cy8ctmg110_pm,
},
.id_table = cy8ctmg110_idtable,
- .probe = cy8ctmg110_probe,
+ .probe_new = cy8ctmg110_probe,
};
module_i2c_driver(cy8ctmg110_driver);
diff --git a/drivers/input/touchscreen/cyttsp4_i2c.c b/drivers/input/touchscreen/cyttsp4_i2c.c
index 28ae7c15397a..c260bab0c62c 100644
--- a/drivers/input/touchscreen/cyttsp4_i2c.c
+++ b/drivers/input/touchscreen/cyttsp4_i2c.c
@@ -27,8 +27,7 @@ static const struct cyttsp4_bus_ops cyttsp4_i2c_bus_ops = {
.read = cyttsp_i2c_read_block_data,
};
-static int cyttsp4_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int cyttsp4_i2c_probe(struct i2c_client *client)
{
struct cyttsp4 *ts;
@@ -61,7 +60,7 @@ static struct i2c_driver cyttsp4_i2c_driver = {
.name = CYTTSP4_I2C_NAME,
.pm = &cyttsp4_pm_ops,
},
- .probe = cyttsp4_i2c_probe,
+ .probe_new = cyttsp4_i2c_probe,
.remove = cyttsp4_i2c_remove,
.id_table = cyttsp4_i2c_id,
};
diff --git a/drivers/input/touchscreen/cyttsp5.c b/drivers/input/touchscreen/cyttsp5.c
new file mode 100644
index 000000000000..4a23d6231382
--- /dev/null
+++ b/drivers/input/touchscreen/cyttsp5.c
@@ -0,0 +1,900 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Parade TrueTouch(TM) Standard Product V5 Module.
+ *
+ * Copyright (C) 2015 Parade Technologies
+ * Copyright (C) 2012-2015 Cypress Semiconductor
+ * Copyright (C) 2018 Bootlin
+ *
+ * Authors: Mylène Josserand <mylene.josserand@bootlin.com>
+ * Alistair Francis <alistair@alistair23.me>
+ */
+
+#include <linux/crc-itu-t.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/gpio/consumer.h>
+#include <linux/input/mt.h>
+#include <linux/input/touchscreen.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <asm/unaligned.h>
+
+#define CYTTSP5_NAME "cyttsp5"
+#define CY_I2C_DATA_SIZE (2 * 256)
+#define HID_VERSION 0x0100
+#define CY_MAX_INPUT 512
+#define CYTTSP5_PREALLOCATED_CMD_BUFFER 32
+#define CY_BITS_PER_BTN 1
+#define CY_NUM_BTN_EVENT_ID GENMASK(CY_BITS_PER_BTN, 0)
+
+#define MAX_AREA 255
+#define HID_OUTPUT_BL_SOP 0x1
+#define HID_OUTPUT_BL_EOP 0x17
+#define HID_OUTPUT_BL_LAUNCH_APP 0x3B
+#define HID_OUTPUT_BL_LAUNCH_APP_SIZE 11
+#define HID_OUTPUT_GET_SYSINFO 0x2
+#define HID_OUTPUT_GET_SYSINFO_SIZE 5
+#define HID_OUTPUT_MAX_CMD_SIZE 12
+
+#define HID_DESC_REG 0x1
+#define HID_INPUT_REG 0x3
+#define HID_OUTPUT_REG 0x4
+
+#define REPORT_ID_TOUCH 0x1
+#define REPORT_ID_BTN 0x3
+#define REPORT_SIZE_5 5
+#define REPORT_SIZE_8 8
+#define REPORT_SIZE_16 16
+
+/* Touch reports offsets */
+/* Header offsets */
+#define TOUCH_REPORT_DESC_HDR_CONTACTCOUNT 16
+/* Record offsets */
+#define TOUCH_REPORT_DESC_CONTACTID 8
+#define TOUCH_REPORT_DESC_X 16
+#define TOUCH_REPORT_DESC_Y 32
+#define TOUCH_REPORT_DESC_P 48
+#define TOUCH_REPORT_DESC_MAJ 56
+#define TOUCH_REPORT_DESC_MIN 64
+
+/* HID */
+#define HID_TOUCH_REPORT_ID 0x1
+#define HID_BTN_REPORT_ID 0x3
+#define HID_APP_RESPONSE_REPORT_ID 0x1F
+#define HID_APP_OUTPUT_REPORT_ID 0x2F
+#define HID_BL_RESPONSE_REPORT_ID 0x30
+#define HID_BL_OUTPUT_REPORT_ID 0x40
+
+#define HID_OUTPUT_RESPONSE_REPORT_OFFSET 2
+#define HID_OUTPUT_RESPONSE_CMD_OFFSET 4
+#define HID_OUTPUT_RESPONSE_CMD_MASK GENMASK(6, 0)
+
+#define HID_SYSINFO_SENSING_OFFSET 33
+#define HID_SYSINFO_BTN_OFFSET 48
+#define HID_SYSINFO_BTN_MASK GENMASK(7, 0)
+#define HID_SYSINFO_MAX_BTN 8
+
+#define CY_HID_OUTPUT_TIMEOUT_MS 200
+#define CY_HID_OUTPUT_GET_SYSINFO_TIMEOUT_MS 3000
+#define CY_HID_GET_HID_DESCRIPTOR_TIMEOUT_MS 4000
+
+/* maximum number of concurrent tracks */
+#define TOUCH_REPORT_SIZE 10
+#define TOUCH_INPUT_HEADER_SIZE 7
+#define BTN_REPORT_SIZE 9
+#define BTN_INPUT_HEADER_SIZE 5
+
+#define MAX_CY_TCH_T_IDS 32
+
+/* All usage pages for Touch Report */
+#define TOUCH_REPORT_USAGE_PG_X 0x00010030
+#define TOUCH_REPORT_USAGE_PG_Y 0x00010031
+#define TOUCH_REPORT_USAGE_PG_P 0x000D0030
+#define TOUCH_REPORT_USAGE_PG_CONTACTID 0x000D0051
+#define TOUCH_REPORT_USAGE_PG_CONTACTCOUNT 0x000D0054
+#define TOUCH_REPORT_USAGE_PG_MAJ 0xFF010062
+#define TOUCH_REPORT_USAGE_PG_MIN 0xFF010063
+#define TOUCH_COL_USAGE_PG 0x000D0022
+
+/* System Information interface definitions */
+struct cyttsp5_sensing_conf_data_dev {
+ u8 electrodes_x;
+ u8 electrodes_y;
+ __le16 len_x;
+ __le16 len_y;
+ __le16 res_x;
+ __le16 res_y;
+ __le16 max_z;
+ u8 origin_x;
+ u8 origin_y;
+ u8 btn;
+ u8 scan_mode;
+ u8 max_num_of_tch_per_refresh_cycle;
+} __packed;
+
+struct cyttsp5_sensing_conf_data {
+ u16 res_x;
+ u16 res_y;
+ u16 max_z;
+ u16 len_x;
+ u16 len_y;
+ u8 origin_x;
+ u8 origin_y;
+ u8 max_tch;
+};
+
+enum cyttsp5_tch_abs { /* for ordering within the extracted touch data array */
+ CY_TCH_X, /* X */
+ CY_TCH_Y, /* Y */
+ CY_TCH_P, /* P (Z) */
+ CY_TCH_T, /* TOUCH ID */
+ CY_TCH_MAJ, /* TOUCH_MAJOR */
+ CY_TCH_MIN, /* TOUCH_MINOR */
+ CY_TCH_NUM_ABS
+};
+
+struct cyttsp5_tch_abs_params {
+ size_t ofs; /* abs byte offset */
+ size_t size; /* size in bits */
+ size_t min; /* min value */
+ size_t max; /* max value */
+ size_t bofs; /* bit offset */
+};
+
+struct cyttsp5_touch {
+ int abs[CY_TCH_NUM_ABS];
+};
+
+struct cyttsp5_sysinfo {
+ struct cyttsp5_sensing_conf_data sensing_conf_data;
+ int num_btns;
+ struct cyttsp5_tch_abs_params tch_hdr;
+ struct cyttsp5_tch_abs_params tch_abs[CY_TCH_NUM_ABS];
+ u32 key_code[HID_SYSINFO_MAX_BTN];
+};
+
+struct cyttsp5_hid_desc {
+ __le16 hid_desc_len;
+ u8 packet_id;
+ u8 reserved_byte;
+ __le16 bcd_version;
+ __le16 report_desc_len;
+ __le16 report_desc_register;
+ __le16 input_register;
+ __le16 max_input_len;
+ __le16 output_register;
+ __le16 max_output_len;
+ __le16 command_register;
+ __le16 data_register;
+ __le16 vendor_id;
+ __le16 product_id;
+ __le16 version_id;
+ u8 reserved[4];
+} __packed;
+
+struct cyttsp5 {
+ struct device *dev;
+ struct completion cmd_done;
+ struct cyttsp5_sysinfo sysinfo;
+ struct cyttsp5_hid_desc hid_desc;
+ u8 cmd_buf[CYTTSP5_PREALLOCATED_CMD_BUFFER];
+ u8 input_buf[CY_MAX_INPUT];
+ u8 response_buf[CY_MAX_INPUT];
+ struct gpio_desc *reset_gpio;
+ struct input_dev *input;
+ char phys[NAME_MAX];
+ int num_prv_rec;
+ struct regmap *regmap;
+ struct touchscreen_properties prop;
+ struct regulator *vdd;
+};
+
+/*
+ * For what is understood in the datasheet, the register does not
+ * matter. For consistency, use the Input Register address
+ * but it does mean anything to the device. The important data
+ * to send is the I2C address
+ */
+static int cyttsp5_read(struct cyttsp5 *ts, u8 *buf, u32 max)
+{
+ int error;
+ u32 size;
+ u8 temp[2];
+
+ /* Read the frame to retrieve the size */
+ error = regmap_bulk_read(ts->regmap, HID_INPUT_REG, temp, sizeof(temp));
+ if (error)
+ return error;
+
+ size = get_unaligned_le16(temp);
+ if (!size || size == 2)
+ return 0;
+
+ if (size > max)
+ return -EINVAL;
+
+ /* Get the real value */
+ return regmap_bulk_read(ts->regmap, HID_INPUT_REG, buf, size);
+}
+
+static int cyttsp5_write(struct cyttsp5 *ts, unsigned int reg, u8 *data,
+ size_t size)
+{
+ u8 cmd[HID_OUTPUT_MAX_CMD_SIZE];
+
+ if (size + 1 > HID_OUTPUT_MAX_CMD_SIZE)
+ return -E2BIG;
+
+ /* High bytes of register address needed as first byte of cmd */
+ cmd[0] = (reg >> 8) & 0xFF;
+
+ /* Copy the rest of the data */
+ if (data)
+ memcpy(&cmd[1], data, size);
+
+ /*
+ * The hardware wants to receive a frame with the address register
+ * contained in the first two bytes. As the regmap_write function
+ * add the register adresse in the frame, we use the low byte as
+ * first frame byte for the address register and the first
+ * data byte is the high register + left of the cmd to send
+ */
+ return regmap_bulk_write(ts->regmap, reg & 0xFF, cmd, size + 1);
+}
+
+static void cyttsp5_get_touch_axis(int *axis, int size, int max, u8 *xy_data,
+ int bofs)
+{
+ int nbyte;
+
+ for (nbyte = 0, *axis = 0; nbyte < size; nbyte++)
+ *axis += ((xy_data[nbyte] >> bofs) << (nbyte * 8));
+
+ *axis &= max - 1;
+}
+
+static void cyttsp5_get_touch_record(struct cyttsp5 *ts,
+ struct cyttsp5_touch *touch, u8 *xy_data)
+{
+ struct cyttsp5_sysinfo *si = &ts->sysinfo;
+ enum cyttsp5_tch_abs abs;
+
+ for (abs = CY_TCH_X; abs < CY_TCH_NUM_ABS; abs++)
+ cyttsp5_get_touch_axis(&touch->abs[abs],
+ si->tch_abs[abs].size,
+ si->tch_abs[abs].max,
+ xy_data + si->tch_abs[abs].ofs,
+ si->tch_abs[abs].bofs);
+}
+
+static void cyttsp5_get_mt_touches(struct cyttsp5 *ts,
+ struct cyttsp5_touch *tch, int num_cur_tch)
+{
+ struct cyttsp5_sysinfo *si = &ts->sysinfo;
+ int i, t = 0, offset = 0;
+ DECLARE_BITMAP(ids, MAX_CY_TCH_T_IDS);
+ u8 *tch_addr;
+ int tmp;
+
+ bitmap_zero(ids, MAX_CY_TCH_T_IDS);
+ memset(tch->abs, 0, sizeof(tch->abs));
+
+ switch (ts->input_buf[2]) {
+ case HID_TOUCH_REPORT_ID:
+ offset = TOUCH_INPUT_HEADER_SIZE;
+ break;
+ case HID_BTN_REPORT_ID:
+ offset = BTN_INPUT_HEADER_SIZE;
+ break;
+ }
+
+ for (i = 0; i < num_cur_tch; i++) {
+ tch_addr = ts->input_buf + offset + (i * TOUCH_REPORT_SIZE);
+ cyttsp5_get_touch_record(ts, tch, tch_addr);
+
+ /* Convert MAJOR/MINOR from mm to resolution */
+ tmp = tch->abs[CY_TCH_MAJ] * 100 * si->sensing_conf_data.res_x;
+ tch->abs[CY_TCH_MAJ] = tmp / si->sensing_conf_data.len_x;
+ tmp = tch->abs[CY_TCH_MIN] * 100 * si->sensing_conf_data.res_x;
+ tch->abs[CY_TCH_MIN] = tmp / si->sensing_conf_data.len_x;
+
+ t = tch->abs[CY_TCH_T];
+ input_mt_slot(ts->input, t);
+ input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, true);
+ __set_bit(t, ids);
+
+ /* position and pressure fields */
+ touchscreen_report_pos(ts->input, &ts->prop,
+ tch->abs[CY_TCH_X], tch->abs[CY_TCH_Y],
+ true);
+ input_report_abs(ts->input, ABS_MT_PRESSURE,
+ tch->abs[CY_TCH_P]);
+
+ /* Get the extended touch fields */
+ input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR,
+ tch->abs[CY_TCH_MAJ]);
+ input_report_abs(ts->input, ABS_MT_TOUCH_MINOR,
+ tch->abs[CY_TCH_MIN]);
+ }
+
+ ts->num_prv_rec = num_cur_tch;
+}
+
+static int cyttsp5_mt_attention(struct device *dev)
+{
+ struct cyttsp5 *ts = dev_get_drvdata(dev);
+ struct cyttsp5_sysinfo *si = &ts->sysinfo;
+ int max_tch = si->sensing_conf_data.max_tch;
+ struct cyttsp5_touch tch;
+ int num_cur_tch;
+
+ cyttsp5_get_touch_axis(&num_cur_tch, si->tch_hdr.size,
+ si->tch_hdr.max,
+ ts->input_buf + 3 + si->tch_hdr.ofs,
+ si->tch_hdr.bofs);
+
+ if (num_cur_tch > max_tch) {
+ dev_err(dev, "Num touch err detected (n=%d)\n", num_cur_tch);
+ num_cur_tch = max_tch;
+ }
+
+ if (num_cur_tch == 0 && ts->num_prv_rec == 0)
+ return 0;
+
+ /* extract xy_data for all currently reported touches */
+ if (num_cur_tch)
+ cyttsp5_get_mt_touches(ts, &tch, num_cur_tch);
+
+ input_mt_sync_frame(ts->input);
+ input_sync(ts->input);
+
+ return 0;
+}
+
+static int cyttsp5_setup_input_device(struct device *dev)
+{
+ struct cyttsp5 *ts = dev_get_drvdata(dev);
+ struct cyttsp5_sysinfo *si = &ts->sysinfo;
+ int max_x, max_y, max_p;
+ int max_x_tmp, max_y_tmp;
+ int error;
+
+ max_x_tmp = si->sensing_conf_data.res_x;
+ max_y_tmp = si->sensing_conf_data.res_y;
+ max_x = max_x_tmp - 1;
+ max_y = max_y_tmp - 1;
+ max_p = si->sensing_conf_data.max_z;
+
+ input_set_abs_params(ts->input, ABS_MT_POSITION_X, 0, max_x, 0, 0);
+ input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, max_y, 0, 0);
+ input_set_abs_params(ts->input, ABS_MT_PRESSURE, 0, max_p, 0, 0);
+
+ input_set_abs_params(ts->input, ABS_MT_TOUCH_MAJOR, 0, MAX_AREA, 0, 0);
+ input_set_abs_params(ts->input, ABS_MT_TOUCH_MINOR, 0, MAX_AREA, 0, 0);
+
+ error = input_mt_init_slots(ts->input, si->tch_abs[CY_TCH_T].max,
+ INPUT_MT_DROP_UNUSED | INPUT_MT_DIRECT);
+ if (error)
+ return error;
+
+ error = input_register_device(ts->input);
+ if (error) {
+ dev_err(dev, "failed to register input device: %d\n", error);
+ return error;
+ }
+
+ return error;
+}
+
+static int cyttsp5_parse_dt_key_code(struct device *dev)
+{
+ struct cyttsp5 *ts = dev_get_drvdata(dev);
+ struct cyttsp5_sysinfo *si = &ts->sysinfo;
+
+ if (!si->num_btns)
+ return 0;
+
+ /* Initialize the button to RESERVED */
+ memset32(si->key_code, KEY_RESERVED, si->num_btns);
+
+ return device_property_read_u32_array(dev, "linux,keycodes",
+ si->key_code, si->num_btns);
+}
+
+static int cyttsp5_btn_attention(struct device *dev)
+{
+ struct cyttsp5 *ts = dev_get_drvdata(dev);
+ struct cyttsp5_sysinfo *si = &ts->sysinfo;
+ int cur_btn, offset = 0;
+ int cur_btn_state;
+
+ switch (ts->input_buf[2]) {
+ case HID_TOUCH_REPORT_ID:
+ offset = TOUCH_INPUT_HEADER_SIZE;
+ break;
+ case HID_BTN_REPORT_ID:
+ offset = BTN_INPUT_HEADER_SIZE;
+ break;
+ }
+
+ if (ts->input_buf[2] != HID_BTN_REPORT_ID)
+ return 0;
+
+ /* extract button press/release touch information */
+ for (cur_btn = 0; cur_btn < si->num_btns; cur_btn++) {
+ /* Get current button state */
+ cur_btn_state = (ts->input_buf[offset] >> (cur_btn * CY_BITS_PER_BTN))
+ & CY_NUM_BTN_EVENT_ID;
+
+ input_report_key(ts->input, si->key_code[cur_btn],
+ cur_btn_state);
+ input_sync(ts->input);
+ }
+
+ return 0;
+}
+
+static int cyttsp5_validate_cmd_response(struct cyttsp5 *ts, u8 code)
+{
+ u16 size, crc;
+ u8 status, report_id;
+ int command_code;
+
+ size = get_unaligned_le16(&ts->response_buf[0]);
+ if (!size)
+ return 0;
+
+ report_id = ts->response_buf[HID_OUTPUT_RESPONSE_REPORT_OFFSET];
+
+ switch (report_id) {
+ case HID_BL_RESPONSE_REPORT_ID:
+ if (ts->response_buf[4] != HID_OUTPUT_BL_SOP) {
+ dev_err(ts->dev, "HID output response, wrong SOP\n");
+ return -EPROTO;
+ }
+
+ if (ts->response_buf[size - 1] != HID_OUTPUT_BL_EOP) {
+ dev_err(ts->dev, "HID output response, wrong EOP\n");
+ return -EPROTO;
+ }
+
+ crc = crc_itu_t(0xFFFF, &ts->response_buf[4], size - 7);
+ if (get_unaligned_le16(&ts->response_buf[size - 3]) != crc) {
+ dev_err(ts->dev,
+ "HID output response, wrong CRC 0x%X\n",
+ crc);
+ return -EPROTO;
+ }
+
+ status = ts->response_buf[5];
+ if (status) {
+ dev_err(ts->dev, "HID output response, ERROR:%d\n",
+ status);
+ return -EPROTO;
+ }
+ break;
+
+ case HID_APP_RESPONSE_REPORT_ID:
+ command_code = ts->response_buf[HID_OUTPUT_RESPONSE_CMD_OFFSET]
+ & HID_OUTPUT_RESPONSE_CMD_MASK;
+ if (command_code != code) {
+ dev_err(ts->dev,
+ "HID output response, wrong command_code:%X\n",
+ command_code);
+ return -EPROTO;
+ }
+ break;
+ }
+
+ return 0;
+}
+
+static void cyttsp5_si_get_btn_data(struct cyttsp5 *ts)
+{
+ struct cyttsp5_sysinfo *si = &ts->sysinfo;
+ unsigned int btns = ts->response_buf[HID_SYSINFO_BTN_OFFSET] &
+ HID_SYSINFO_BTN_MASK;
+
+ si->num_btns = hweight8(btns);
+}
+
+static int cyttsp5_get_sysinfo_regs(struct cyttsp5 *ts)
+{
+ struct cyttsp5_sensing_conf_data *scd = &ts->sysinfo.sensing_conf_data;
+ struct cyttsp5_sensing_conf_data_dev *scd_dev =
+ (struct cyttsp5_sensing_conf_data_dev *)
+ &ts->response_buf[HID_SYSINFO_SENSING_OFFSET];
+
+ cyttsp5_si_get_btn_data(ts);
+
+ scd->max_tch = scd_dev->max_num_of_tch_per_refresh_cycle;
+ scd->res_x = get_unaligned_le16(&scd_dev->res_x);
+ scd->res_y = get_unaligned_le16(&scd_dev->res_y);
+ scd->max_z = get_unaligned_le16(&scd_dev->max_z);
+ scd->len_x = get_unaligned_le16(&scd_dev->len_x);
+ scd->len_y = get_unaligned_le16(&scd_dev->len_y);
+
+ return 0;
+}
+
+static int cyttsp5_hid_output_get_sysinfo(struct cyttsp5 *ts)
+{
+ int rc;
+ u8 cmd[HID_OUTPUT_GET_SYSINFO_SIZE];
+
+ /* HI bytes of Output register address */
+ put_unaligned_le16(HID_OUTPUT_GET_SYSINFO_SIZE, cmd);
+ cmd[2] = HID_APP_OUTPUT_REPORT_ID;
+ cmd[3] = 0x0; /* Reserved */
+ cmd[4] = HID_OUTPUT_GET_SYSINFO;
+
+ rc = cyttsp5_write(ts, HID_OUTPUT_REG, cmd,
+ HID_OUTPUT_GET_SYSINFO_SIZE);
+ if (rc) {
+ dev_err(ts->dev, "Failed to write command %d", rc);
+ return rc;
+ }
+
+ rc = wait_for_completion_interruptible_timeout(&ts->cmd_done,
+ msecs_to_jiffies(CY_HID_OUTPUT_GET_SYSINFO_TIMEOUT_MS));
+ if (rc <= 0) {
+ dev_err(ts->dev, "HID output cmd execution timed out\n");
+ rc = -ETIMEDOUT;
+ return rc;
+ }
+
+ rc = cyttsp5_validate_cmd_response(ts, HID_OUTPUT_GET_SYSINFO);
+ if (rc) {
+ dev_err(ts->dev, "Validation of the response failed\n");
+ return rc;
+ }
+
+ return cyttsp5_get_sysinfo_regs(ts);
+}
+
+static int cyttsp5_hid_output_bl_launch_app(struct cyttsp5 *ts)
+{
+ int rc;
+ u8 cmd[HID_OUTPUT_BL_LAUNCH_APP];
+ u16 crc;
+
+ put_unaligned_le16(HID_OUTPUT_BL_LAUNCH_APP_SIZE, cmd);
+ cmd[2] = HID_BL_OUTPUT_REPORT_ID;
+ cmd[3] = 0x0; /* Reserved */
+ cmd[4] = HID_OUTPUT_BL_SOP;
+ cmd[5] = HID_OUTPUT_BL_LAUNCH_APP;
+ put_unaligned_le16(0x00, &cmd[6]);
+ crc = crc_itu_t(0xFFFF, &cmd[4], 4);
+ put_unaligned_le16(crc, &cmd[8]);
+ cmd[10] = HID_OUTPUT_BL_EOP;
+
+ rc = cyttsp5_write(ts, HID_OUTPUT_REG, cmd,
+ HID_OUTPUT_BL_LAUNCH_APP_SIZE);
+ if (rc) {
+ dev_err(ts->dev, "Failed to write command %d", rc);
+ return rc;
+ }
+
+ rc = wait_for_completion_interruptible_timeout(&ts->cmd_done,
+ msecs_to_jiffies(CY_HID_OUTPUT_TIMEOUT_MS));
+ if (rc <= 0) {
+ dev_err(ts->dev, "HID output cmd execution timed out\n");
+ rc = -ETIMEDOUT;
+ return rc;
+ }
+
+ rc = cyttsp5_validate_cmd_response(ts, HID_OUTPUT_BL_LAUNCH_APP);
+ if (rc) {
+ dev_err(ts->dev, "Validation of the response failed\n");
+ return rc;
+ }
+
+ return 0;
+}
+
+static int cyttsp5_get_hid_descriptor(struct cyttsp5 *ts,
+ struct cyttsp5_hid_desc *desc)
+{
+ struct device *dev = ts->dev;
+ __le16 hid_desc_register = cpu_to_le16(HID_DESC_REG);
+ int rc;
+ u8 cmd[2];
+
+ /* Set HID descriptor register */
+ memcpy(cmd, &hid_desc_register, sizeof(hid_desc_register));
+
+ rc = cyttsp5_write(ts, HID_DESC_REG, NULL, 0);
+ if (rc) {
+ dev_err(dev, "Failed to get HID descriptor, rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = wait_for_completion_interruptible_timeout(&ts->cmd_done,
+ msecs_to_jiffies(CY_HID_GET_HID_DESCRIPTOR_TIMEOUT_MS));
+ if (rc <= 0) {
+ dev_err(ts->dev, "HID get descriptor timed out\n");
+ rc = -ETIMEDOUT;
+ return rc;
+ }
+
+ memcpy(desc, ts->response_buf, sizeof(*desc));
+
+ /* Check HID descriptor length and version */
+ if (le16_to_cpu(desc->hid_desc_len) != sizeof(*desc) ||
+ le16_to_cpu(desc->bcd_version) != HID_VERSION) {
+ dev_err(dev, "Unsupported HID version\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int fill_tch_abs(struct cyttsp5_tch_abs_params *tch_abs, int report_size,
+ int offset)
+{
+ tch_abs->ofs = offset / 8;
+ tch_abs->size = report_size / 8;
+ if (report_size % 8)
+ tch_abs->size += 1;
+ tch_abs->min = 0;
+ tch_abs->max = 1 << report_size;
+ tch_abs->bofs = offset - (tch_abs->ofs << 3);
+
+ return 0;
+}
+
+static irqreturn_t cyttsp5_handle_irq(int irq, void *handle)
+{
+ struct cyttsp5 *ts = handle;
+ int report_id;
+ int size;
+ int error;
+
+ error = cyttsp5_read(ts, ts->input_buf, CY_MAX_INPUT);
+ if (error)
+ return IRQ_HANDLED;
+
+ size = get_unaligned_le16(&ts->input_buf[0]);
+ if (size == 0) {
+ /* reset */
+ report_id = 0;
+ size = 2;
+ } else {
+ report_id = ts->input_buf[2];
+ }
+
+ switch (report_id) {
+ case HID_TOUCH_REPORT_ID:
+ cyttsp5_mt_attention(ts->dev);
+ break;
+ case HID_BTN_REPORT_ID:
+ cyttsp5_btn_attention(ts->dev);
+ break;
+ default:
+ /* It is not an input but a command response */
+ memcpy(ts->response_buf, ts->input_buf, size);
+ complete(&ts->cmd_done);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int cyttsp5_deassert_int(struct cyttsp5 *ts)
+{
+ u16 size;
+ u8 buf[2];
+ int error;
+
+ error = regmap_bulk_read(ts->regmap, HID_INPUT_REG, buf, sizeof(buf));
+ if (error < 0)
+ return error;
+
+ size = get_unaligned_le16(&buf[0]);
+ if (size == 2 || size == 0)
+ return 0;
+
+ return -EINVAL;
+}
+
+static int cyttsp5_fill_all_touch(struct cyttsp5 *ts)
+{
+ struct cyttsp5_sysinfo *si = &ts->sysinfo;
+
+ fill_tch_abs(&si->tch_abs[CY_TCH_X], REPORT_SIZE_16,
+ TOUCH_REPORT_DESC_X);
+ fill_tch_abs(&si->tch_abs[CY_TCH_Y], REPORT_SIZE_16,
+ TOUCH_REPORT_DESC_Y);
+ fill_tch_abs(&si->tch_abs[CY_TCH_P], REPORT_SIZE_8,
+ TOUCH_REPORT_DESC_P);
+ fill_tch_abs(&si->tch_abs[CY_TCH_T], REPORT_SIZE_5,
+ TOUCH_REPORT_DESC_CONTACTID);
+ fill_tch_abs(&si->tch_hdr, REPORT_SIZE_5,
+ TOUCH_REPORT_DESC_HDR_CONTACTCOUNT);
+ fill_tch_abs(&si->tch_abs[CY_TCH_MAJ], REPORT_SIZE_8,
+ TOUCH_REPORT_DESC_MAJ);
+ fill_tch_abs(&si->tch_abs[CY_TCH_MIN], REPORT_SIZE_8,
+ TOUCH_REPORT_DESC_MIN);
+
+ return 0;
+}
+
+static int cyttsp5_startup(struct cyttsp5 *ts)
+{
+ int error;
+
+ error = cyttsp5_deassert_int(ts);
+ if (error) {
+ dev_err(ts->dev, "Error on deassert int r=%d\n", error);
+ return -ENODEV;
+ }
+
+ /*
+ * Launch the application as the device starts in bootloader mode
+ * because of a power-on-reset
+ */
+ error = cyttsp5_hid_output_bl_launch_app(ts);
+ if (error < 0) {
+ dev_err(ts->dev, "Error on launch app r=%d\n", error);
+ return error;
+ }
+
+ error = cyttsp5_get_hid_descriptor(ts, &ts->hid_desc);
+ if (error < 0) {
+ dev_err(ts->dev, "Error on getting HID descriptor r=%d\n", error);
+ return error;
+ }
+
+ error = cyttsp5_fill_all_touch(ts);
+ if (error < 0) {
+ dev_err(ts->dev, "Error on report descriptor r=%d\n", error);
+ return error;
+ }
+
+ error = cyttsp5_hid_output_get_sysinfo(ts);
+ if (error) {
+ dev_err(ts->dev, "Error on getting sysinfo r=%d\n", error);
+ return error;
+ }
+
+ return error;
+}
+
+static void cyttsp5_cleanup(void *data)
+{
+ struct cyttsp5 *ts = data;
+
+ regulator_disable(ts->vdd);
+}
+
+static int cyttsp5_probe(struct device *dev, struct regmap *regmap, int irq,
+ const char *name)
+{
+ struct cyttsp5 *ts;
+ struct cyttsp5_sysinfo *si;
+ int error, i;
+
+ ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
+ if (!ts)
+ return -ENOMEM;
+
+ /* Initialize device info */
+ ts->regmap = regmap;
+ ts->dev = dev;
+ si = &ts->sysinfo;
+ dev_set_drvdata(dev, ts);
+
+ init_completion(&ts->cmd_done);
+
+ /* Power up the device */
+ ts->vdd = devm_regulator_get(dev, "vdd");
+ if (IS_ERR(ts->vdd)) {
+ error = PTR_ERR(ts->vdd);
+ return error;
+ }
+
+ error = devm_add_action_or_reset(dev, cyttsp5_cleanup, ts);
+ if (error)
+ return error;
+
+ error = regulator_enable(ts->vdd);
+ if (error)
+ return error;
+
+ ts->input = devm_input_allocate_device(dev);
+ if (!ts->input) {
+ dev_err(dev, "Error, failed to allocate input device\n");
+ return -ENODEV;
+ }
+
+ ts->input->name = "cyttsp5";
+ scnprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(dev));
+ ts->input->phys = ts->phys;
+ input_set_drvdata(ts->input, ts);
+
+ /* Reset the gpio to be in a reset state */
+ ts->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
+ if (IS_ERR(ts->reset_gpio)) {
+ error = PTR_ERR(ts->reset_gpio);
+ dev_err(dev, "Failed to request reset gpio, error %d\n", error);
+ return error;
+ }
+ gpiod_set_value_cansleep(ts->reset_gpio, 0);
+
+ /* Need a delay to have device up */
+ msleep(20);
+
+ error = devm_request_threaded_irq(dev, irq, NULL, cyttsp5_handle_irq,
+ IRQF_ONESHOT, name, ts);
+ if (error) {
+ dev_err(dev, "unable to request IRQ\n");
+ return error;
+ }
+
+ error = cyttsp5_startup(ts);
+ if (error) {
+ dev_err(ts->dev, "Fail initial startup r=%d\n", error);
+ return error;
+ }
+
+ error = cyttsp5_parse_dt_key_code(dev);
+ if (error < 0) {
+ dev_err(ts->dev, "Error while parsing dts %d\n", error);
+ return error;
+ }
+
+ touchscreen_parse_properties(ts->input, true, &ts->prop);
+
+ __set_bit(EV_KEY, ts->input->evbit);
+ for (i = 0; i < si->num_btns; i++)
+ __set_bit(si->key_code[i], ts->input->keybit);
+
+ return cyttsp5_setup_input_device(dev);
+}
+
+static int cyttsp5_i2c_probe(struct i2c_client *client)
+{
+ struct regmap *regmap;
+ static const struct regmap_config config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ };
+
+ regmap = devm_regmap_init_i2c(client, &config);
+ if (IS_ERR(regmap)) {
+ dev_err(&client->dev, "regmap allocation failed: %ld\n",
+ PTR_ERR(regmap));
+ return PTR_ERR(regmap);
+ }
+
+ return cyttsp5_probe(&client->dev, regmap, client->irq, client->name);
+}
+
+static const struct of_device_id cyttsp5_of_match[] = {
+ { .compatible = "cypress,tt21000", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, cyttsp5_of_match);
+
+static const struct i2c_device_id cyttsp5_i2c_id[] = {
+ { CYTTSP5_NAME, 0, },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, cyttsp5_i2c_id);
+
+static struct i2c_driver cyttsp5_i2c_driver = {
+ .driver = {
+ .name = CYTTSP5_NAME,
+ .of_match_table = cyttsp5_of_match,
+ },
+ .probe_new = cyttsp5_i2c_probe,
+ .id_table = cyttsp5_i2c_id,
+};
+module_i2c_driver(cyttsp5_i2c_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Touchscreen driver for Cypress TrueTouch Gen 5 Product");
+MODULE_AUTHOR("Mylène Josserand <mylene.josserand@bootlin.com>");
diff --git a/drivers/input/touchscreen/cyttsp_i2c.c b/drivers/input/touchscreen/cyttsp_i2c.c
index 4c8473d327ab..0155a1626adf 100644
--- a/drivers/input/touchscreen/cyttsp_i2c.c
+++ b/drivers/input/touchscreen/cyttsp_i2c.c
@@ -28,8 +28,7 @@ static const struct cyttsp_bus_ops cyttsp_i2c_bus_ops = {
.read = cyttsp_i2c_read_block_data,
};
-static int cyttsp_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int cyttsp_i2c_probe(struct i2c_client *client)
{
struct cyttsp *ts;
@@ -67,7 +66,7 @@ static struct i2c_driver cyttsp_i2c_driver = {
.pm = &cyttsp_pm_ops,
.of_match_table = cyttsp_of_i2c_match,
},
- .probe = cyttsp_i2c_probe,
+ .probe_new = cyttsp_i2c_probe,
.id_table = cyttsp_i2c_id,
};
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index 9ac1378610bc..ddd0f1f62458 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -1131,9 +1131,9 @@ static void edt_ft5x06_disable_regulators(void *arg)
regulator_disable(data->iovcc);
}
-static int edt_ft5x06_ts_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int edt_ft5x06_ts_probe(struct i2c_client *client)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(client);
const struct edt_i2c_chip_data *chip_data;
struct edt_ft5x06_ts_data *tsdata;
u8 buf[2] = { 0xfc, 0x00 };
@@ -1504,7 +1504,7 @@ static struct i2c_driver edt_ft5x06_ts_driver = {
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
},
.id_table = edt_ft5x06_ts_id,
- .probe = edt_ft5x06_ts_probe,
+ .probe_new = edt_ft5x06_ts_probe,
.remove = edt_ft5x06_ts_remove,
};
diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c
index a639ba7e56ea..c8ab03f49227 100644
--- a/drivers/input/touchscreen/eeti_ts.c
+++ b/drivers/input/touchscreen/eeti_ts.c
@@ -158,8 +158,7 @@ static void eeti_ts_close(struct input_dev *dev)
eeti_ts_stop(eeti);
}
-static int eeti_ts_probe(struct i2c_client *client,
- const struct i2c_device_id *idp)
+static int eeti_ts_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct eeti_ts *eeti;
@@ -292,7 +291,7 @@ static struct i2c_driver eeti_ts_driver = {
.pm = &eeti_ts_pm,
.of_match_table = of_match_ptr(of_eeti_ts_match),
},
- .probe = eeti_ts_probe,
+ .probe_new = eeti_ts_probe,
.id_table = eeti_ts_id,
};
diff --git a/drivers/input/touchscreen/egalax_ts.c b/drivers/input/touchscreen/egalax_ts.c
index 83ac8c128192..742d47a75ac1 100644
--- a/drivers/input/touchscreen/egalax_ts.c
+++ b/drivers/input/touchscreen/egalax_ts.c
@@ -14,17 +14,17 @@
- auto idle mode support
*/
+#include <linux/err.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/irq.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/bitops.h>
#include <linux/input/mt.h>
-#include <linux/of_gpio.h>
/*
* Mouse Mode: some panel may configure the controller to mouse mode,
@@ -119,32 +119,26 @@ static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id)
/* wake up controller by an falling edge of interrupt gpio. */
static int egalax_wake_up_device(struct i2c_client *client)
{
- struct device_node *np = client->dev.of_node;
- int gpio;
+ struct gpio_desc *gpio;
int ret;
- if (!np)
- return -ENODEV;
-
- gpio = of_get_named_gpio(np, "wakeup-gpios", 0);
- if (!gpio_is_valid(gpio))
- return -ENODEV;
-
- ret = gpio_request(gpio, "egalax_irq");
- if (ret < 0) {
- dev_err(&client->dev,
- "request gpio failed, cannot wake up controller: %d\n",
- ret);
+ /* wake up controller via an falling edge on IRQ gpio. */
+ gpio = gpiod_get(&client->dev, "wakeup", GPIOD_OUT_HIGH);
+ ret = PTR_ERR_OR_ZERO(gpio);
+ if (ret) {
+ if (ret != -EPROBE_DEFER)
+ dev_err(&client->dev,
+ "failed to request wakeup gpio, cannot wake up controller: %d\n",
+ ret);
return ret;
}
- /* wake up controller via an falling edge on IRQ gpio. */
- gpio_direction_output(gpio, 0);
- gpio_set_value(gpio, 1);
+ /* release the line */
+ gpiod_set_value_cansleep(gpio, 0);
- /* controller should be waken up, return irq. */
- gpio_direction_input(gpio);
- gpio_free(gpio);
+ /* controller should be woken up, return irq. */
+ gpiod_direction_input(gpio);
+ gpiod_put(gpio);
return 0;
}
@@ -161,8 +155,7 @@ static int egalax_firmware_version(struct i2c_client *client)
return 0;
}
-static int egalax_ts_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int egalax_ts_probe(struct i2c_client *client)
{
struct egalax_ts *ts;
struct input_dev *input_dev;
@@ -185,10 +178,8 @@ static int egalax_ts_probe(struct i2c_client *client,
/* controller may be in sleep, wake it up. */
error = egalax_wake_up_device(client);
- if (error) {
- dev_err(&client->dev, "Failed to wake up the controller\n");
+ if (error)
return error;
- }
error = egalax_firmware_version(client);
if (error < 0) {
@@ -211,10 +202,9 @@ static int egalax_ts_probe(struct i2c_client *client,
ABS_MT_POSITION_Y, 0, EGALAX_MAX_Y, 0, 0);
input_mt_init_slots(input_dev, MAX_SUPPORT_POINTS, 0);
- error = devm_request_threaded_irq(&client->dev, client->irq, NULL,
- egalax_ts_interrupt,
- IRQF_TRIGGER_LOW | IRQF_ONESHOT,
- "egalax_ts", ts);
+ error = devm_request_threaded_irq(&client->dev, client->irq,
+ NULL, egalax_ts_interrupt,
+ IRQF_ONESHOT, "egalax_ts", ts);
if (error < 0) {
dev_err(&client->dev, "Failed to register interrupt\n");
return error;
@@ -273,7 +263,7 @@ static struct i2c_driver egalax_ts_driver = {
.of_match_table = egalax_ts_dt_ids,
},
.id_table = egalax_ts_id,
- .probe = egalax_ts_probe,
+ .probe_new = egalax_ts_probe,
};
module_i2c_driver(egalax_ts_driver);
diff --git a/drivers/input/touchscreen/ektf2127.c b/drivers/input/touchscreen/ektf2127.c
index 2d01a8cbfcc6..328841eaa1b7 100644
--- a/drivers/input/touchscreen/ektf2127.c
+++ b/drivers/input/touchscreen/ektf2127.c
@@ -244,8 +244,7 @@ static int ektf2127_query_dimension(struct i2c_client *client, bool width)
return (((buf[3] & 0xf0) << 4) | buf[2]) - 1;
}
-static int ektf2127_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int ektf2127_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct ektf2127_ts *ts;
@@ -352,7 +351,7 @@ static struct i2c_driver ektf2127_driver = {
.pm = &ektf2127_pm_ops,
.of_match_table = of_match_ptr(ektf2127_of_match),
},
- .probe = ektf2127_probe,
+ .probe_new = ektf2127_probe,
.id_table = ektf2127_i2c_id,
};
module_i2c_driver(ektf2127_driver);
diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c
index 879a4d984c90..5452b50f8a77 100644
--- a/drivers/input/touchscreen/elants_i2c.c
+++ b/drivers/input/touchscreen/elants_i2c.c
@@ -36,6 +36,7 @@
#include <linux/input/touchscreen.h>
#include <linux/acpi.h>
#include <linux/of.h>
+#include <linux/pm_wakeirq.h>
#include <linux/gpio/consumer.h>
#include <linux/regulator/consumer.h>
#include <linux/uuid.h>
@@ -114,7 +115,7 @@
/* calibration timeout definition */
#define ELAN_CALI_TIMEOUT_MSEC 12000
-#define ELAN_POWERON_DELAY_USEC 500
+#define ELAN_POWERON_DELAY_USEC 5000
#define ELAN_RESET_DELAY_MSEC 20
/* FW boot code version */
@@ -180,7 +181,6 @@ struct elants_data {
u8 cmd_resp[HEADER_SIZE];
struct completion cmd_done;
- bool wake_irq_enabled;
bool keep_power_in_suspend;
/* Must be last to be used for DMA operations */
@@ -1329,14 +1329,12 @@ static int elants_i2c_power_on(struct elants_data *ts)
if (IS_ERR_OR_NULL(ts->reset_gpio))
return 0;
- gpiod_set_value_cansleep(ts->reset_gpio, 1);
-
error = regulator_enable(ts->vcc33);
if (error) {
dev_err(&ts->client->dev,
"failed to enable vcc33 regulator: %d\n",
error);
- goto release_reset_gpio;
+ return error;
}
error = regulator_enable(ts->vccio);
@@ -1345,19 +1343,16 @@ static int elants_i2c_power_on(struct elants_data *ts)
"failed to enable vccio regulator: %d\n",
error);
regulator_disable(ts->vcc33);
- goto release_reset_gpio;
+ return error;
}
/*
* We need to wait a bit after powering on controller before
* we are allowed to release reset GPIO.
*/
- udelay(ELAN_POWERON_DELAY_USEC);
+ usleep_range(ELAN_POWERON_DELAY_USEC, ELAN_POWERON_DELAY_USEC + 100);
-release_reset_gpio:
gpiod_set_value_cansleep(ts->reset_gpio, 0);
- if (error)
- return error;
msleep(ELAN_RESET_DELAY_MSEC);
@@ -1462,7 +1457,7 @@ static int elants_i2c_probe(struct i2c_client *client)
return error;
}
- ts->reset_gpio = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_LOW);
+ ts->reset_gpio = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(ts->reset_gpio)) {
error = PTR_ERR(ts->reset_gpio);
@@ -1567,13 +1562,6 @@ static int elants_i2c_probe(struct i2c_client *client)
return error;
}
- /*
- * Systems using device tree should set up wakeup via DTS,
- * the rest will configure device as wakeup source by default.
- */
- if (!client->dev.of_node)
- device_init_wakeup(&client->dev, true);
-
error = devm_device_add_group(&client->dev, &elants_attribute_group);
if (error) {
dev_err(&client->dev, "failed to create sysfs attributes: %d\n",
@@ -1605,7 +1593,7 @@ static int __maybe_unused elants_i2c_suspend(struct device *dev)
* The device will automatically enter idle mode
* that has reduced power consumption.
*/
- ts->wake_irq_enabled = (enable_irq_wake(client->irq) == 0);
+ return 0;
} else if (ts->keep_power_in_suspend) {
for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
error = elants_i2c_send(client, set_sleep_cmd,
@@ -1634,8 +1622,6 @@ static int __maybe_unused elants_i2c_resume(struct device *dev)
int error;
if (device_may_wakeup(dev)) {
- if (ts->wake_irq_enabled)
- disable_irq_wake(client->irq);
elants_i2c_sw_reset(client);
} else if (ts->keep_power_in_suspend) {
for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c
index c281e49826c2..8a0a8078de8f 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -1282,8 +1282,7 @@ static void goodix_disable_regulators(void *arg)
regulator_disable(ts->avdd28);
}
-static int goodix_ts_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int goodix_ts_probe(struct i2c_client *client)
{
struct goodix_ts_data *ts;
const char *cfg_name;
@@ -1537,7 +1536,7 @@ MODULE_DEVICE_TABLE(of, goodix_of_match);
#endif
static struct i2c_driver goodix_ts_driver = {
- .probe = goodix_ts_probe,
+ .probe_new = goodix_ts_probe,
.remove = goodix_ts_remove,
.id_table = goodix_ts_id,
.driver = {
diff --git a/drivers/input/touchscreen/hideep.c b/drivers/input/touchscreen/hideep.c
index e9547ee29756..ff4bb4c14898 100644
--- a/drivers/input/touchscreen/hideep.c
+++ b/drivers/input/touchscreen/hideep.c
@@ -997,8 +997,7 @@ static const struct regmap_config hideep_regmap_config = {
.max_register = 0xffff,
};
-static int hideep_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int hideep_probe(struct i2c_client *client)
{
struct hideep_ts *ts;
int error;
@@ -1112,7 +1111,7 @@ static struct i2c_driver hideep_driver = {
.pm = &hideep_pm_ops,
},
.id_table = hideep_i2c_id,
- .probe = hideep_probe,
+ .probe_new = hideep_probe,
};
module_i2c_driver(hideep_driver);
diff --git a/drivers/input/touchscreen/himax_hx83112b.c b/drivers/input/touchscreen/himax_hx83112b.c
new file mode 100644
index 000000000000..e96150d80a48
--- /dev/null
+++ b/drivers/input/touchscreen/himax_hx83112b.c
@@ -0,0 +1,364 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Driver for Himax hx83112b touchscreens
+ *
+ * Copyright (C) 2022 Job Noorman <job@noorman.info>
+ *
+ * This code is based on "Himax Android Driver Sample Code for QCT platform":
+ *
+ * Copyright (C) 2017 Himax Corporation.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/input/mt.h>
+#include <linux/input/touchscreen.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/regmap.h>
+
+#define HIMAX_ID_83112B 0x83112b
+
+#define HIMAX_MAX_POINTS 10
+
+#define HIMAX_REG_CFG_SET_ADDR 0x00
+#define HIMAX_REG_CFG_INIT_READ 0x0c
+#define HIMAX_REG_CFG_READ_VALUE 0x08
+#define HIMAX_REG_READ_EVENT 0x30
+
+#define HIMAX_CFG_PRODUCT_ID 0x900000d0
+
+#define HIMAX_INVALID_COORD 0xffff
+
+struct himax_event_point {
+ __be16 x;
+ __be16 y;
+} __packed;
+
+struct himax_event {
+ struct himax_event_point points[HIMAX_MAX_POINTS];
+ u8 majors[HIMAX_MAX_POINTS];
+ u8 pad0[2];
+ u8 num_points;
+ u8 pad1[2];
+ u8 checksum_fix;
+} __packed;
+
+static_assert(sizeof(struct himax_event) == 56);
+
+struct himax_ts_data {
+ struct gpio_desc *gpiod_rst;
+ struct input_dev *input_dev;
+ struct i2c_client *client;
+ struct regmap *regmap;
+ struct touchscreen_properties props;
+};
+
+static const struct regmap_config himax_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 32,
+ .val_format_endian = REGMAP_ENDIAN_LITTLE,
+};
+
+static int himax_read_config(struct himax_ts_data *ts, u32 address, u32 *dst)
+{
+ int error;
+
+ error = regmap_write(ts->regmap, HIMAX_REG_CFG_SET_ADDR, address);
+ if (error)
+ return error;
+
+ error = regmap_write(ts->regmap, HIMAX_REG_CFG_INIT_READ, 0x0);
+ if (error)
+ return error;
+
+ error = regmap_read(ts->regmap, HIMAX_REG_CFG_READ_VALUE, dst);
+ if (error)
+ return error;
+
+ return 0;
+}
+
+static void himax_reset(struct himax_ts_data *ts)
+{
+ gpiod_set_value_cansleep(ts->gpiod_rst, 1);
+
+ /* Delay copied from downstream driver */
+ msleep(20);
+ gpiod_set_value_cansleep(ts->gpiod_rst, 0);
+
+ /*
+ * The downstream driver doesn't contain this delay but is seems safer
+ * to include it. The range is just a guess that seems to work well.
+ */
+ usleep_range(1000, 1100);
+}
+
+static int himax_read_product_id(struct himax_ts_data *ts, u32 *product_id)
+{
+ int error;
+
+ error = himax_read_config(ts, HIMAX_CFG_PRODUCT_ID, product_id);
+ if (error)
+ return error;
+
+ *product_id >>= 8;
+ return 0;
+}
+
+static int himax_check_product_id(struct himax_ts_data *ts)
+{
+ int error;
+ u32 product_id;
+
+ error = himax_read_product_id(ts, &product_id);
+ if (error)
+ return error;
+
+ dev_dbg(&ts->client->dev, "Product id: %x\n", product_id);
+
+ switch (product_id) {
+ case HIMAX_ID_83112B:
+ return 0;
+
+ default:
+ dev_err(&ts->client->dev,
+ "Unknown product id: %x\n", product_id);
+ return -EINVAL;
+ }
+}
+
+static int himax_input_register(struct himax_ts_data *ts)
+{
+ int error;
+
+ ts->input_dev = devm_input_allocate_device(&ts->client->dev);
+ if (!ts->input_dev) {
+ dev_err(&ts->client->dev, "Failed to allocate input device\n");
+ return -ENOMEM;
+ }
+
+ ts->input_dev->name = "Himax Touchscreen";
+
+ input_set_capability(ts->input_dev, EV_ABS, ABS_MT_POSITION_X);
+ input_set_capability(ts->input_dev, EV_ABS, ABS_MT_POSITION_Y);
+ input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 200, 0, 0);
+ input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 200, 0, 0);
+
+ touchscreen_parse_properties(ts->input_dev, true, &ts->props);
+
+ error = input_mt_init_slots(ts->input_dev, HIMAX_MAX_POINTS,
+ INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
+ if (error) {
+ dev_err(&ts->client->dev,
+ "Failed to initialize MT slots: %d\n", error);
+ return error;
+ }
+
+ error = input_register_device(ts->input_dev);
+ if (error) {
+ dev_err(&ts->client->dev,
+ "Failed to register input device: %d\n", error);
+ return error;
+ }
+
+ return 0;
+}
+
+static u8 himax_event_get_num_points(const struct himax_event *event)
+{
+ if (event->num_points == 0xff)
+ return 0;
+ else
+ return event->num_points & 0x0f;
+}
+
+static bool himax_process_event_point(struct himax_ts_data *ts,
+ const struct himax_event *event,
+ int point_index)
+{
+ const struct himax_event_point *point = &event->points[point_index];
+ u16 x = be16_to_cpu(point->x);
+ u16 y = be16_to_cpu(point->y);
+ u8 w = event->majors[point_index];
+
+ if (x == HIMAX_INVALID_COORD || y == HIMAX_INVALID_COORD)
+ return false;
+
+ input_mt_slot(ts->input_dev, point_index);
+ input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
+ touchscreen_report_pos(ts->input_dev, &ts->props, x, y, true);
+ input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, w);
+ input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w);
+ return true;
+}
+
+static void himax_process_event(struct himax_ts_data *ts,
+ const struct himax_event *event)
+{
+ int i;
+ int num_points_left = himax_event_get_num_points(event);
+
+ for (i = 0; i < HIMAX_MAX_POINTS && num_points_left > 0; i++) {
+ if (himax_process_event_point(ts, event, i))
+ num_points_left--;
+ }
+
+ input_mt_sync_frame(ts->input_dev);
+ input_sync(ts->input_dev);
+}
+
+static bool himax_verify_checksum(struct himax_ts_data *ts,
+ const struct himax_event *event)
+{
+ u8 *data = (u8 *)event;
+ int i;
+ u16 checksum = 0;
+
+ for (i = 0; i < sizeof(*event); i++)
+ checksum += data[i];
+
+ if ((checksum & 0x00ff) != 0) {
+ dev_err(&ts->client->dev, "Wrong event checksum: %04x\n",
+ checksum);
+ return false;
+ }
+
+ return true;
+}
+
+static int himax_handle_input(struct himax_ts_data *ts)
+{
+ int error;
+ struct himax_event event;
+
+ error = regmap_raw_read(ts->regmap, HIMAX_REG_READ_EVENT, &event,
+ sizeof(event));
+ if (error) {
+ dev_err(&ts->client->dev, "Failed to read input event: %d\n",
+ error);
+ return error;
+ }
+
+ /*
+ * Only process the current event when it has a valid checksum but
+ * don't consider it a fatal error when it doesn't.
+ */
+ if (himax_verify_checksum(ts, &event))
+ himax_process_event(ts, &event);
+
+ return 0;
+}
+
+static irqreturn_t himax_irq_handler(int irq, void *dev_id)
+{
+ int error;
+ struct himax_ts_data *ts = dev_id;
+
+ error = himax_handle_input(ts);
+ if (error)
+ return IRQ_NONE;
+
+ return IRQ_HANDLED;
+}
+
+static int himax_probe(struct i2c_client *client)
+{
+ int error;
+ struct device *dev = &client->dev;
+ struct himax_ts_data *ts;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ dev_err(dev, "I2C check functionality failed\n");
+ return -ENXIO;
+ }
+
+ ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
+ if (!ts)
+ return -ENOMEM;
+
+ i2c_set_clientdata(client, ts);
+ ts->client = client;
+
+ ts->regmap = devm_regmap_init_i2c(client, &himax_regmap_config);
+ error = PTR_ERR_OR_ZERO(ts->regmap);
+ if (error) {
+ dev_err(dev, "Failed to initialize regmap: %d\n", error);
+ return error;
+ }
+
+ ts->gpiod_rst = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
+ error = PTR_ERR_OR_ZERO(ts->gpiod_rst);
+ if (error) {
+ dev_err(dev, "Failed to get reset GPIO: %d\n", error);
+ return error;
+ }
+
+ himax_reset(ts);
+
+ error = himax_check_product_id(ts);
+ if (error)
+ return error;
+
+ error = himax_input_register(ts);
+ if (error)
+ return error;
+
+ error = devm_request_threaded_irq(dev, client->irq, NULL,
+ himax_irq_handler, IRQF_ONESHOT,
+ client->name, ts);
+ if (error)
+ return error;
+
+ return 0;
+}
+
+static int himax_suspend(struct device *dev)
+{
+ struct himax_ts_data *ts = dev_get_drvdata(dev);
+
+ disable_irq(ts->client->irq);
+ return 0;
+}
+
+static int himax_resume(struct device *dev)
+{
+ struct himax_ts_data *ts = dev_get_drvdata(dev);
+
+ enable_irq(ts->client->irq);
+ return 0;
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(himax_pm_ops, himax_suspend, himax_resume);
+
+static const struct i2c_device_id himax_ts_id[] = {
+ { "hx83112b", 0 },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(i2c, himax_ts_id);
+
+#ifdef CONFIG_OF
+static const struct of_device_id himax_of_match[] = {
+ { .compatible = "himax,hx83112b" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, himax_of_match);
+#endif
+
+static struct i2c_driver himax_ts_driver = {
+ .probe_new = himax_probe,
+ .id_table = himax_ts_id,
+ .driver = {
+ .name = "Himax-hx83112b-TS",
+ .of_match_table = of_match_ptr(himax_of_match),
+ .pm = pm_sleep_ptr(&himax_pm_ops),
+ },
+};
+module_i2c_driver(himax_ts_driver);
+
+MODULE_AUTHOR("Job Noorman <job@noorman.info>");
+MODULE_DESCRIPTION("Himax hx83112b touchscreen driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/hycon-hy46xx.c b/drivers/input/touchscreen/hycon-hy46xx.c
index 891d0430083e..8f4989aba9a4 100644
--- a/drivers/input/touchscreen/hycon-hy46xx.c
+++ b/drivers/input/touchscreen/hycon-hy46xx.c
@@ -439,8 +439,7 @@ static void hycon_hy46xx_disable_regulator(void *arg)
regulator_disable(data->vcc);
}
-static int hycon_hy46xx_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int hycon_hy46xx_probe(struct i2c_client *client)
{
struct hycon_hy46xx_data *tsdata;
struct input_dev *input;
@@ -581,7 +580,7 @@ static struct i2c_driver hycon_hy46xx_driver = {
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
},
.id_table = hycon_hy46xx_id,
- .probe = hycon_hy46xx_probe,
+ .probe_new = hycon_hy46xx_probe,
};
module_i2c_driver(hycon_hy46xx_driver);
diff --git a/drivers/input/touchscreen/hynitron_cstxxx.c b/drivers/input/touchscreen/hynitron_cstxxx.c
new file mode 100644
index 000000000000..e86c85addb38
--- /dev/null
+++ b/drivers/input/touchscreen/hynitron_cstxxx.c
@@ -0,0 +1,498 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Driver for Hynitron cstxxx Touchscreen
+ *
+ * Copyright (c) 2022 Chris Morgan <macromorgan@hotmail.com>
+ *
+ * This code is based on hynitron_core.c authored by Hynitron.
+ * Note that no datasheet was available, so much of these registers
+ * are undocumented. This is essentially a cleaned-up version of the
+ * vendor driver with support removed for hardware I cannot test and
+ * device-specific functions replated with generic functions wherever
+ * possible.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/input/mt.h>
+#include <linux/input/touchscreen.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/property.h>
+#include <asm/unaligned.h>
+
+/* Per chip data */
+struct hynitron_ts_chip_data {
+ unsigned int max_touch_num;
+ u32 ic_chkcode;
+ int (*firmware_info)(struct i2c_client *client);
+ int (*bootloader_enter)(struct i2c_client *client);
+ int (*init_input)(struct i2c_client *client);
+ void (*report_touch)(struct i2c_client *client);
+};
+
+/* Data generic to all (supported and non-supported) controllers. */
+struct hynitron_ts_data {
+ const struct hynitron_ts_chip_data *chip;
+ struct i2c_client *client;
+ struct input_dev *input_dev;
+ struct touchscreen_properties prop;
+ struct gpio_desc *reset_gpio;
+};
+
+/*
+ * Since I have no datasheet, these values are guessed and/or assumed
+ * based on observation and testing.
+ */
+#define CST3XX_FIRMWARE_INFO_START_CMD 0x01d1
+#define CST3XX_FIRMWARE_INFO_END_CMD 0x09d1
+#define CST3XX_FIRMWARE_CHK_CODE_REG 0xfcd1
+#define CST3XX_FIRMWARE_VERSION_REG 0x08d2
+#define CST3XX_FIRMWARE_VER_INVALID_VAL 0xa5a5a5a5
+
+#define CST3XX_BOOTLDR_PROG_CMD 0xaa01a0
+#define CST3XX_BOOTLDR_PROG_CHK_REG 0x02a0
+#define CST3XX_BOOTLDR_CHK_VAL 0xac
+
+#define CST3XX_TOUCH_DATA_PART_REG 0x00d0
+#define CST3XX_TOUCH_DATA_FULL_REG 0x07d0
+#define CST3XX_TOUCH_DATA_CHK_VAL 0xab
+#define CST3XX_TOUCH_DATA_TOUCH_VAL 0x03
+#define CST3XX_TOUCH_DATA_STOP_CMD 0xab00d0
+#define CST3XX_TOUCH_COUNT_MASK GENMASK(6, 0)
+
+
+/*
+ * Hard coded reset delay value of 20ms not IC dependent in
+ * vendor driver.
+ */
+static void hyn_reset_proc(struct i2c_client *client, int delay)
+{
+ struct hynitron_ts_data *ts_data = i2c_get_clientdata(client);
+
+ gpiod_set_value_cansleep(ts_data->reset_gpio, 1);
+ msleep(20);
+ gpiod_set_value_cansleep(ts_data->reset_gpio, 0);
+ if (delay)
+ fsleep(delay * 1000);
+}
+
+static irqreturn_t hyn_interrupt_handler(int irq, void *dev_id)
+{
+ struct i2c_client *client = dev_id;
+ struct hynitron_ts_data *ts_data = i2c_get_clientdata(client);
+
+ ts_data->chip->report_touch(client);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * The vendor driver would retry twice before failing to read or write
+ * to the i2c device.
+ */
+
+static int cst3xx_i2c_write(struct i2c_client *client,
+ unsigned char *buf, int len)
+{
+ int ret;
+ int retries = 0;
+
+ while (retries < 2) {
+ ret = i2c_master_send(client, buf, len);
+ if (ret == len)
+ return 0;
+ if (ret <= 0)
+ retries++;
+ else
+ break;
+ }
+
+ return ret < 0 ? ret : -EIO;
+}
+
+static int cst3xx_i2c_read_register(struct i2c_client *client, u16 reg,
+ u8 *val, u16 len)
+{
+ __le16 buf = cpu_to_le16(reg);
+ struct i2c_msg msgs[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 2,
+ .buf = (u8 *)&buf,
+ },
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = len,
+ .buf = val,
+ }
+ };
+ int err;
+ int ret;
+
+ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+ if (ret == ARRAY_SIZE(msgs))
+ return 0;
+
+ err = ret < 0 ? ret : -EIO;
+ dev_err(&client->dev, "Error reading %d bytes from 0x%04x: %d (%d)\n",
+ len, reg, err, ret);
+
+ return err;
+}
+
+static int cst3xx_firmware_info(struct i2c_client *client)
+{
+ struct hynitron_ts_data *ts_data = i2c_get_clientdata(client);
+ int err;
+ u32 tmp;
+ unsigned char buf[4];
+
+ /*
+ * Tests suggest this command needed to read firmware regs.
+ */
+ put_unaligned_le16(CST3XX_FIRMWARE_INFO_START_CMD, buf);
+ err = cst3xx_i2c_write(client, buf, 2);
+ if (err)
+ return err;
+
+ usleep_range(10000, 11000);
+
+ /*
+ * Read register for check-code to determine if device detected
+ * correctly.
+ */
+ err = cst3xx_i2c_read_register(client, CST3XX_FIRMWARE_CHK_CODE_REG,
+ buf, 4);
+ if (err)
+ return err;
+
+ tmp = get_unaligned_le32(buf);
+ if ((tmp & 0xffff0000) != ts_data->chip->ic_chkcode) {
+ dev_err(&client->dev, "%s ic mismatch, chkcode is %u\n",
+ __func__, tmp);
+ return -ENODEV;
+ }
+
+ usleep_range(10000, 11000);
+
+ /* Read firmware version and test if firmware missing. */
+ err = cst3xx_i2c_read_register(client, CST3XX_FIRMWARE_VERSION_REG,
+ buf, 4);
+ if (err)
+ return err;
+
+ tmp = get_unaligned_le32(buf);
+ if (tmp == CST3XX_FIRMWARE_VER_INVALID_VAL) {
+ dev_err(&client->dev, "Device firmware missing\n");
+ return -ENODEV;
+ }
+
+ /*
+ * Tests suggest cmd required to exit reading firmware regs.
+ */
+ put_unaligned_le16(CST3XX_FIRMWARE_INFO_END_CMD, buf);
+ err = cst3xx_i2c_write(client, buf, 2);
+ if (err)
+ return err;
+
+ usleep_range(5000, 6000);
+
+ return 0;
+}
+
+static int cst3xx_bootloader_enter(struct i2c_client *client)
+{
+ int err;
+ u8 retry;
+ u32 tmp = 0;
+ unsigned char buf[3];
+
+ for (retry = 0; retry < 5; retry++) {
+ hyn_reset_proc(client, (7 + retry));
+ /* set cmd to enter program mode */
+ put_unaligned_le24(CST3XX_BOOTLDR_PROG_CMD, buf);
+ err = cst3xx_i2c_write(client, buf, 3);
+ if (err)
+ continue;
+
+ usleep_range(2000, 2500);
+
+ /* check whether in program mode */
+ err = cst3xx_i2c_read_register(client,
+ CST3XX_BOOTLDR_PROG_CHK_REG,
+ buf, 1);
+ if (err)
+ continue;
+
+ tmp = get_unaligned(buf);
+ if (tmp == CST3XX_BOOTLDR_CHK_VAL)
+ break;
+ }
+
+ if (tmp != CST3XX_BOOTLDR_CHK_VAL) {
+ dev_err(&client->dev, "%s unable to enter bootloader mode\n",
+ __func__);
+ return -ENODEV;
+ }
+
+ hyn_reset_proc(client, 40);
+
+ return 0;
+}
+
+static void cst3xx_report_contact(struct hynitron_ts_data *ts_data,
+ u8 id, unsigned int x, unsigned int y, u8 w)
+{
+ input_mt_slot(ts_data->input_dev, id);
+ input_mt_report_slot_state(ts_data->input_dev, MT_TOOL_FINGER, 1);
+ touchscreen_report_pos(ts_data->input_dev, &ts_data->prop, x, y, true);
+ input_report_abs(ts_data->input_dev, ABS_MT_TOUCH_MAJOR, w);
+}
+
+static int cst3xx_finish_touch_read(struct i2c_client *client)
+{
+ unsigned char buf[3];
+ int err;
+
+ put_unaligned_le24(CST3XX_TOUCH_DATA_STOP_CMD, buf);
+ err = cst3xx_i2c_write(client, buf, 3);
+ if (err) {
+ dev_err(&client->dev,
+ "send read touch info ending failed: %d\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+/*
+ * Handle events from IRQ. Note that for cst3xx it appears that IRQ
+ * fires continuously while touched, otherwise once every 1500ms
+ * when not touched (assume touchscreen waking up periodically).
+ * Note buffer is sized for 5 fingers, if more needed buffer must
+ * be increased. The buffer contains 5 bytes for each touch point,
+ * a touch count byte, a check byte, and then a second check byte after
+ * all other touch points.
+ *
+ * For example 1 touch would look like this:
+ * touch1[5]:touch_count[1]:chk_byte[1]
+ *
+ * 3 touches would look like this:
+ * touch1[5]:touch_count[1]:chk_byte[1]:touch2[5]:touch3[5]:chk_byte[1]
+ */
+static void cst3xx_touch_report(struct i2c_client *client)
+{
+ struct hynitron_ts_data *ts_data = i2c_get_clientdata(client);
+ u8 buf[28];
+ u8 finger_id, sw, w;
+ unsigned int x, y;
+ unsigned int touch_cnt, end_byte;
+ unsigned int idx = 0;
+ unsigned int i;
+ int err;
+
+ /* Read and validate the first bits of input data. */
+ err = cst3xx_i2c_read_register(client, CST3XX_TOUCH_DATA_PART_REG,
+ buf, 28);
+ if (err ||
+ buf[6] != CST3XX_TOUCH_DATA_CHK_VAL ||
+ buf[0] == CST3XX_TOUCH_DATA_CHK_VAL) {
+ dev_err(&client->dev, "cst3xx touch read failure\n");
+ return;
+ }
+
+ /* Report to the device we're done reading the touch data. */
+ err = cst3xx_finish_touch_read(client);
+ if (err)
+ return;
+
+ touch_cnt = buf[5] & CST3XX_TOUCH_COUNT_MASK;
+ /*
+ * Check the check bit of the last touch slot. The check bit is
+ * always present after touch point 1 for valid data, and then
+ * appears as the last byte after all other touch data.
+ */
+ if (touch_cnt > 1) {
+ end_byte = touch_cnt * 5 + 2;
+ if (buf[end_byte] != CST3XX_TOUCH_DATA_CHK_VAL) {
+ dev_err(&client->dev, "cst3xx touch read failure\n");
+ return;
+ }
+ }
+
+ /* Parse through the buffer to capture touch data. */
+ for (i = 0; i < touch_cnt; i++) {
+ x = ((buf[idx + 1] << 4) | ((buf[idx + 3] >> 4) & 0x0f));
+ y = ((buf[idx + 2] << 4) | (buf[idx + 3] & 0x0f));
+ w = (buf[idx + 4] >> 3);
+ sw = (buf[idx] & 0x0f) >> 1;
+ finger_id = (buf[idx] >> 4) & 0x0f;
+
+ /* Sanity check we don't have more fingers than we expect */
+ if (ts_data->chip->max_touch_num < finger_id) {
+ dev_err(&client->dev, "cst3xx touch read failure\n");
+ break;
+ }
+
+ /* sw value of 0 means no touch, 0x03 means touch */
+ if (sw == CST3XX_TOUCH_DATA_TOUCH_VAL)
+ cst3xx_report_contact(ts_data, finger_id, x, y, w);
+
+ idx += 5;
+
+ /* Skip the 2 bytes between point 1 and point 2 */
+ if (i == 0)
+ idx += 2;
+ }
+
+ input_mt_sync_frame(ts_data->input_dev);
+ input_sync(ts_data->input_dev);
+}
+
+static int cst3xx_input_dev_int(struct i2c_client *client)
+{
+ struct hynitron_ts_data *ts_data = i2c_get_clientdata(client);
+ int err;
+
+ ts_data->input_dev = devm_input_allocate_device(&client->dev);
+ if (!ts_data->input_dev) {
+ dev_err(&client->dev, "Failed to allocate input device\n");
+ return -ENOMEM;
+ }
+
+ ts_data->input_dev->name = "Hynitron cst3xx Touchscreen";
+ ts_data->input_dev->phys = "input/ts";
+ ts_data->input_dev->id.bustype = BUS_I2C;
+
+ input_set_drvdata(ts_data->input_dev, ts_data);
+
+ input_set_capability(ts_data->input_dev, EV_ABS, ABS_MT_POSITION_X);
+ input_set_capability(ts_data->input_dev, EV_ABS, ABS_MT_POSITION_Y);
+ input_set_abs_params(ts_data->input_dev, ABS_MT_TOUCH_MAJOR,
+ 0, 255, 0, 0);
+
+ touchscreen_parse_properties(ts_data->input_dev, true, &ts_data->prop);
+
+ if (!ts_data->prop.max_x || !ts_data->prop.max_y) {
+ dev_err(&client->dev,
+ "Invalid x/y (%d, %d), using defaults\n",
+ ts_data->prop.max_x, ts_data->prop.max_y);
+ ts_data->prop.max_x = 1152;
+ ts_data->prop.max_y = 1920;
+ input_abs_set_max(ts_data->input_dev,
+ ABS_MT_POSITION_X, ts_data->prop.max_x);
+ input_abs_set_max(ts_data->input_dev,
+ ABS_MT_POSITION_Y, ts_data->prop.max_y);
+ }
+
+ err = input_mt_init_slots(ts_data->input_dev,
+ ts_data->chip->max_touch_num,
+ INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
+ if (err) {
+ dev_err(&client->dev,
+ "Failed to initialize input slots: %d\n", err);
+ return err;
+ }
+
+ err = input_register_device(ts_data->input_dev);
+ if (err) {
+ dev_err(&client->dev,
+ "Input device registration failed: %d\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+static int hyn_probe(struct i2c_client *client)
+{
+ struct hynitron_ts_data *ts_data;
+ int err;
+
+ ts_data = devm_kzalloc(&client->dev, sizeof(*ts_data), GFP_KERNEL);
+ if (!ts_data)
+ return -ENOMEM;
+
+ ts_data->client = client;
+ i2c_set_clientdata(client, ts_data);
+
+ ts_data->chip = device_get_match_data(&client->dev);
+ if (!ts_data->chip)
+ return -EINVAL;
+
+ ts_data->reset_gpio = devm_gpiod_get(&client->dev,
+ "reset", GPIOD_OUT_LOW);
+ err = PTR_ERR_OR_ZERO(ts_data->reset_gpio);
+ if (err) {
+ dev_err(&client->dev, "request reset gpio failed: %d\n", err);
+ return err;
+ }
+
+ hyn_reset_proc(client, 60);
+
+ err = ts_data->chip->bootloader_enter(client);
+ if (err < 0)
+ return err;
+
+ err = ts_data->chip->init_input(client);
+ if (err < 0)
+ return err;
+
+ err = ts_data->chip->firmware_info(client);
+ if (err < 0)
+ return err;
+
+ err = devm_request_threaded_irq(&client->dev, client->irq,
+ NULL, hyn_interrupt_handler,
+ IRQF_ONESHOT,
+ "Hynitron Touch Int", client);
+ if (err) {
+ dev_err(&client->dev, "failed to request IRQ: %d\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+static const struct hynitron_ts_chip_data cst3xx_data = {
+ .max_touch_num = 5,
+ .ic_chkcode = 0xcaca0000,
+ .firmware_info = &cst3xx_firmware_info,
+ .bootloader_enter = &cst3xx_bootloader_enter,
+ .init_input = &cst3xx_input_dev_int,
+ .report_touch = &cst3xx_touch_report,
+};
+
+static const struct i2c_device_id hyn_tpd_id[] = {
+ { .name = "hynitron_ts", 0 },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(i2c, hyn_tpd_id);
+
+static const struct of_device_id hyn_dt_match[] = {
+ { .compatible = "hynitron,cst340", .data = &cst3xx_data },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, hyn_dt_match);
+
+static struct i2c_driver hynitron_i2c_driver = {
+ .driver = {
+ .name = "Hynitron-TS",
+ .of_match_table = hyn_dt_match,
+ .probe_type = PROBE_PREFER_ASYNCHRONOUS,
+ },
+ .id_table = hyn_tpd_id,
+ .probe_new = hyn_probe,
+};
+
+module_i2c_driver(hynitron_i2c_driver);
+
+MODULE_AUTHOR("Chris Morgan");
+MODULE_DESCRIPTION("Hynitron Touchscreen Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c
index e9bd36adbe47..4897fafa4204 100644
--- a/drivers/input/touchscreen/ili210x.c
+++ b/drivers/input/touchscreen/ili210x.c
@@ -913,9 +913,9 @@ static void ili210x_stop(void *data)
priv->stop = true;
}
-static int ili210x_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int ili210x_i2c_probe(struct i2c_client *client)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct device *dev = &client->dev;
const struct ili2xxx_chip *chip;
struct ili210x *priv;
@@ -1043,7 +1043,7 @@ static struct i2c_driver ili210x_ts_driver = {
.of_match_table = ili210x_dt_ids,
},
.id_table = ili210x_i2c_id,
- .probe = ili210x_i2c_probe,
+ .probe_new = ili210x_i2c_probe,
};
module_i2c_driver(ili210x_ts_driver);
diff --git a/drivers/input/touchscreen/ilitek_ts_i2c.c b/drivers/input/touchscreen/ilitek_ts_i2c.c
index c5d259c76adc..e6ade3775a8a 100644
--- a/drivers/input/touchscreen/ilitek_ts_i2c.c
+++ b/drivers/input/touchscreen/ilitek_ts_i2c.c
@@ -542,8 +542,7 @@ static struct attribute_group ilitek_attrs_group = {
.attrs = ilitek_sysfs_attrs,
};
-static int ilitek_ts_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int ilitek_ts_i2c_probe(struct i2c_client *client)
{
struct ilitek_ts_data *ts;
struct device *dev = &client->dev;
@@ -680,7 +679,7 @@ static struct i2c_driver ilitek_ts_i2c_driver = {
.of_match_table = of_match_ptr(ilitek_ts_i2c_match),
.acpi_match_table = ACPI_PTR(ilitekts_acpi_id),
},
- .probe = ilitek_ts_i2c_probe,
+ .probe_new = ilitek_ts_i2c_probe,
.id_table = ilitek_ts_i2c_id,
};
module_i2c_driver(ilitek_ts_i2c_driver);
diff --git a/drivers/input/touchscreen/iqs5xx.c b/drivers/input/touchscreen/iqs5xx.c
index 34c4cca57d13..dc3137a34f35 100644
--- a/drivers/input/touchscreen/iqs5xx.c
+++ b/drivers/input/touchscreen/iqs5xx.c
@@ -1019,8 +1019,7 @@ static int __maybe_unused iqs5xx_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(iqs5xx_pm, iqs5xx_suspend, iqs5xx_resume);
-static int iqs5xx_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int iqs5xx_probe(struct i2c_client *client)
{
struct iqs5xx_private *iqs5xx;
int error;
@@ -1094,7 +1093,7 @@ static struct i2c_driver iqs5xx_i2c_driver = {
.pm = &iqs5xx_pm,
},
.id_table = iqs5xx_id,
- .probe = iqs5xx_probe,
+ .probe_new = iqs5xx_probe,
};
module_i2c_driver(iqs5xx_i2c_driver);
diff --git a/drivers/input/touchscreen/max11801_ts.c b/drivers/input/touchscreen/max11801_ts.c
index f15713aaebc2..461023fd6a09 100644
--- a/drivers/input/touchscreen/max11801_ts.c
+++ b/drivers/input/touchscreen/max11801_ts.c
@@ -168,8 +168,7 @@ static void max11801_ts_phy_init(struct max11801_data *data)
max11801_write_reg(client, OP_MODE_CONF_REG, 0x36);
}
-static int max11801_ts_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int max11801_ts_probe(struct i2c_client *client)
{
struct max11801_data *data;
struct input_dev *input_dev;
@@ -231,7 +230,7 @@ static struct i2c_driver max11801_ts_driver = {
.of_match_table = max11801_ts_dt_ids,
},
.id_table = max11801_ts_id,
- .probe = max11801_ts_probe,
+ .probe_new = max11801_ts_probe,
};
module_i2c_driver(max11801_ts_driver);
diff --git a/drivers/input/touchscreen/mcs5000_ts.c b/drivers/input/touchscreen/mcs5000_ts.c
index 5376d8f740ab..ea9517cad695 100644
--- a/drivers/input/touchscreen/mcs5000_ts.c
+++ b/drivers/input/touchscreen/mcs5000_ts.c
@@ -180,8 +180,7 @@ static void mcs5000_ts_phys_init(struct mcs5000_ts_data *data,
OP_MODE_ACTIVE | REPORT_RATE_80);
}
-static int mcs5000_ts_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int mcs5000_ts_probe(struct i2c_client *client)
{
const struct mcs_platform_data *pdata;
struct mcs5000_ts_data *data;
@@ -272,7 +271,7 @@ static const struct i2c_device_id mcs5000_ts_id[] = {
MODULE_DEVICE_TABLE(i2c, mcs5000_ts_id);
static struct i2c_driver mcs5000_ts_driver = {
- .probe = mcs5000_ts_probe,
+ .probe_new = mcs5000_ts_probe,
.driver = {
.name = "mcs5000_ts",
.pm = &mcs5000_ts_pm,
diff --git a/drivers/input/touchscreen/melfas_mip4.c b/drivers/input/touchscreen/melfas_mip4.c
index 83f4be05e27b..4ee8ed4c930c 100644
--- a/drivers/input/touchscreen/melfas_mip4.c
+++ b/drivers/input/touchscreen/melfas_mip4.c
@@ -1424,7 +1424,7 @@ static const struct attribute_group mip4_attr_group = {
.attrs = mip4_attrs,
};
-static int mip4_probe(struct i2c_client *client, const struct i2c_device_id *id)
+static int mip4_probe(struct i2c_client *client)
{
struct mip4_ts *ts;
struct input_dev *input;
@@ -1590,7 +1590,7 @@ MODULE_DEVICE_TABLE(i2c, mip4_i2c_ids);
static struct i2c_driver mip4_driver = {
.id_table = mip4_i2c_ids,
- .probe = mip4_probe,
+ .probe_new = mip4_probe,
.driver = {
.name = MIP4_DEVICE_NAME,
.of_match_table = of_match_ptr(mip4_of_match),
diff --git a/drivers/input/touchscreen/migor_ts.c b/drivers/input/touchscreen/migor_ts.c
index 79cd660d879e..ff0f605f3a3a 100644
--- a/drivers/input/touchscreen/migor_ts.c
+++ b/drivers/input/touchscreen/migor_ts.c
@@ -116,8 +116,7 @@ static void migor_ts_close(struct input_dev *dev)
enable_irq(priv->irq);
}
-static int migor_ts_probe(struct i2c_client *client,
- const struct i2c_device_id *idp)
+static int migor_ts_probe(struct i2c_client *client)
{
struct migor_ts_priv *priv;
struct input_dev *input;
@@ -222,7 +221,7 @@ static struct i2c_driver migor_ts_driver = {
.name = "migor_ts",
.pm = &migor_ts_pm,
},
- .probe = migor_ts_probe,
+ .probe_new = migor_ts_probe,
.remove = migor_ts_remove,
.id_table = migor_ts_id,
};
diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c
index 9fa3b0e421be..758b669391a7 100644
--- a/drivers/input/touchscreen/mms114.c
+++ b/drivers/input/touchscreen/mms114.c
@@ -440,8 +440,7 @@ static int mms114_parse_legacy_bindings(struct mms114_data *data)
return 0;
}
-static int mms114_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int mms114_probe(struct i2c_client *client)
{
struct mms114_data *data;
struct input_dev *input_dev;
@@ -639,7 +638,7 @@ static struct i2c_driver mms114_driver = {
.pm = &mms114_pm_ops,
.of_match_table = of_match_ptr(mms114_dt_match),
},
- .probe = mms114_probe,
+ .probe_new = mms114_probe,
.id_table = mms114_id,
};
diff --git a/drivers/input/touchscreen/msg2638.c b/drivers/input/touchscreen/msg2638.c
index 75536bc88969..4c0816b09d33 100644
--- a/drivers/input/touchscreen/msg2638.c
+++ b/drivers/input/touchscreen/msg2638.c
@@ -21,28 +21,49 @@
#include <linux/kernel.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
+#include <linux/property.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#define MODE_DATA_RAW 0x5A
-#define MAX_SUPPORTED_FINGER_NUM 5
+#define MSG2138_MAX_FINGERS 2
+#define MSG2638_MAX_FINGERS 5
+
+#define MAX_BUTTONS 4
#define CHIP_ON_DELAY_MS 15
#define FIRMWARE_ON_DELAY_MS 50
#define RESET_DELAY_MIN_US 10000
#define RESET_DELAY_MAX_US 11000
-struct packet {
+struct msg_chip_data {
+ irq_handler_t irq_handler;
+ unsigned int max_fingers;
+};
+
+struct msg2138_packet {
+ u8 xy_hi; /* higher bits of x and y coordinates */
+ u8 x_low;
+ u8 y_low;
+};
+
+struct msg2138_touch_event {
+ u8 magic;
+ struct msg2138_packet pkt[MSG2138_MAX_FINGERS];
+ u8 checksum;
+};
+
+struct msg2638_packet {
u8 xy_hi; /* higher bits of x and y coordinates */
u8 x_low;
u8 y_low;
u8 pressure;
};
-struct touch_event {
+struct msg2638_touch_event {
u8 mode;
- struct packet pkt[MAX_SUPPORTED_FINGER_NUM];
+ struct msg2638_packet pkt[MSG2638_MAX_FINGERS];
u8 proximity;
u8 checksum;
};
@@ -53,6 +74,9 @@ struct msg2638_ts_data {
struct touchscreen_properties prop;
struct regulator_bulk_data supplies[2];
struct gpio_desc *reset_gpiod;
+ int max_fingers;
+ u32 keycodes[MAX_BUTTONS];
+ int num_keycodes;
};
static u8 msg2638_checksum(u8 *data, u32 length)
@@ -66,12 +90,102 @@ static u8 msg2638_checksum(u8 *data, u32 length)
return (u8)((-sum) & 0xFF);
}
+static void msg2138_report_keys(struct msg2638_ts_data *msg2638, u8 keys)
+{
+ int i;
+
+ /* keys can be 0x00 or 0xff when all keys have been released */
+ if (keys == 0xff)
+ keys = 0;
+
+ for (i = 0; i < msg2638->num_keycodes; ++i)
+ input_report_key(msg2638->input_dev, msg2638->keycodes[i],
+ keys & BIT(i));
+}
+
+static irqreturn_t msg2138_ts_irq_handler(int irq, void *msg2638_handler)
+{
+ struct msg2638_ts_data *msg2638 = msg2638_handler;
+ struct i2c_client *client = msg2638->client;
+ struct input_dev *input = msg2638->input_dev;
+ struct msg2138_touch_event touch_event;
+ u32 len = sizeof(touch_event);
+ struct i2c_msg msg[] = {
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = sizeof(touch_event),
+ .buf = (u8 *)&touch_event,
+ },
+ };
+ struct msg2138_packet *p0, *p1;
+ u16 x, y, delta_x, delta_y;
+ int ret;
+
+ ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
+ if (ret != ARRAY_SIZE(msg)) {
+ dev_err(&client->dev,
+ "Failed I2C transfer in irq handler: %d\n",
+ ret < 0 ? ret : -EIO);
+ goto out;
+ }
+
+ if (msg2638_checksum((u8 *)&touch_event, len - 1) !=
+ touch_event.checksum) {
+ dev_err(&client->dev, "Failed checksum!\n");
+ goto out;
+ }
+
+ p0 = &touch_event.pkt[0];
+ p1 = &touch_event.pkt[1];
+
+ /* Ignore non-pressed finger data, but check for key code */
+ if (p0->xy_hi == 0xFF && p0->x_low == 0xFF && p0->y_low == 0xFF) {
+ if (p1->xy_hi == 0xFF && p1->y_low == 0xFF)
+ msg2138_report_keys(msg2638, p1->x_low);
+ goto report;
+ }
+
+ x = ((p0->xy_hi & 0xF0) << 4) | p0->x_low;
+ y = ((p0->xy_hi & 0x0F) << 8) | p0->y_low;
+
+ input_mt_slot(input, 0);
+ input_mt_report_slot_state(input, MT_TOOL_FINGER, true);
+ touchscreen_report_pos(input, &msg2638->prop, x, y, true);
+
+ /* Ignore non-pressed finger data */
+ if (p1->xy_hi == 0xFF && p1->x_low == 0xFF && p1->y_low == 0xFF)
+ goto report;
+
+ /* Second finger is reported as a delta position */
+ delta_x = ((p1->xy_hi & 0xF0) << 4) | p1->x_low;
+ delta_y = ((p1->xy_hi & 0x0F) << 8) | p1->y_low;
+
+ /* Ignore second finger if both deltas equal 0 */
+ if (delta_x == 0 && delta_y == 0)
+ goto report;
+
+ x += delta_x;
+ y += delta_y;
+
+ input_mt_slot(input, 1);
+ input_mt_report_slot_state(input, MT_TOOL_FINGER, true);
+ touchscreen_report_pos(input, &msg2638->prop, x, y, true);
+
+report:
+ input_mt_sync_frame(msg2638->input_dev);
+ input_sync(msg2638->input_dev);
+
+out:
+ return IRQ_HANDLED;
+}
+
static irqreturn_t msg2638_ts_irq_handler(int irq, void *msg2638_handler)
{
struct msg2638_ts_data *msg2638 = msg2638_handler;
struct i2c_client *client = msg2638->client;
struct input_dev *input = msg2638->input_dev;
- struct touch_event touch_event;
+ struct msg2638_touch_event touch_event;
u32 len = sizeof(touch_event);
struct i2c_msg msg[] = {
{
@@ -81,7 +195,7 @@ static irqreturn_t msg2638_ts_irq_handler(int irq, void *msg2638_handler)
.buf = (u8 *)&touch_event,
},
};
- struct packet *p;
+ struct msg2638_packet *p;
u16 x, y;
int ret;
int i;
@@ -103,7 +217,7 @@ static irqreturn_t msg2638_ts_irq_handler(int irq, void *msg2638_handler)
goto out;
}
- for (i = 0; i < MAX_SUPPORTED_FINGER_NUM; i++) {
+ for (i = 0; i < msg2638->max_fingers; i++) {
p = &touch_event.pkt[i];
/* Ignore non-pressed finger data */
@@ -190,6 +304,7 @@ static int msg2638_init_input_dev(struct msg2638_ts_data *msg2638)
struct device *dev = &msg2638->client->dev;
struct input_dev *input_dev;
int error;
+ int i;
input_dev = devm_input_allocate_device(dev);
if (!input_dev) {
@@ -206,6 +321,15 @@ static int msg2638_init_input_dev(struct msg2638_ts_data *msg2638)
input_dev->open = msg2638_input_open;
input_dev->close = msg2638_input_close;
+ if (msg2638->num_keycodes) {
+ input_dev->keycode = msg2638->keycodes;
+ input_dev->keycodemax = msg2638->num_keycodes;
+ input_dev->keycodesize = sizeof(msg2638->keycodes[0]);
+ for (i = 0; i < msg2638->num_keycodes; i++)
+ input_set_capability(input_dev,
+ EV_KEY, msg2638->keycodes[i]);
+ }
+
input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_X);
input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_Y);
@@ -215,7 +339,7 @@ static int msg2638_init_input_dev(struct msg2638_ts_data *msg2638)
return -EINVAL;
}
- error = input_mt_init_slots(input_dev, MAX_SUPPORTED_FINGER_NUM,
+ error = input_mt_init_slots(input_dev, msg2638->max_fingers,
INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
if (error) {
dev_err(dev, "Failed to initialize MT slots: %d\n", error);
@@ -233,6 +357,7 @@ static int msg2638_init_input_dev(struct msg2638_ts_data *msg2638)
static int msg2638_ts_probe(struct i2c_client *client)
{
+ const struct msg_chip_data *chip_data;
struct device *dev = &client->dev;
struct msg2638_ts_data *msg2638;
int error;
@@ -249,6 +374,14 @@ static int msg2638_ts_probe(struct i2c_client *client)
msg2638->client = client;
i2c_set_clientdata(client, msg2638);
+ chip_data = device_get_match_data(&client->dev);
+ if (!chip_data || !chip_data->max_fingers) {
+ dev_err(dev, "Invalid or missing chip data\n");
+ return -EINVAL;
+ }
+
+ msg2638->max_fingers = chip_data->max_fingers;
+
msg2638->supplies[0].supply = "vdd";
msg2638->supplies[1].supply = "vddio";
error = devm_regulator_bulk_get(dev, ARRAY_SIZE(msg2638->supplies),
@@ -265,14 +398,33 @@ static int msg2638_ts_probe(struct i2c_client *client)
return error;
}
- error = msg2638_init_input_dev(msg2638);
- if (error) {
- dev_err(dev, "Failed to initialize input device: %d\n", error);
- return error;
+ msg2638->num_keycodes = device_property_count_u32(dev,
+ "linux,keycodes");
+ if (msg2638->num_keycodes == -EINVAL) {
+ msg2638->num_keycodes = 0;
+ } else if (msg2638->num_keycodes < 0) {
+ dev_err(dev, "Unable to parse linux,keycodes property: %d\n",
+ msg2638->num_keycodes);
+ return msg2638->num_keycodes;
+ } else if (msg2638->num_keycodes > ARRAY_SIZE(msg2638->keycodes)) {
+ dev_warn(dev, "Found %d linux,keycodes but max is %zd, ignoring the rest\n",
+ msg2638->num_keycodes, ARRAY_SIZE(msg2638->keycodes));
+ msg2638->num_keycodes = ARRAY_SIZE(msg2638->keycodes);
+ }
+
+ if (msg2638->num_keycodes > 0) {
+ error = device_property_read_u32_array(dev, "linux,keycodes",
+ msg2638->keycodes,
+ msg2638->num_keycodes);
+ if (error) {
+ dev_err(dev, "Unable to read linux,keycodes values: %d\n",
+ error);
+ return error;
+ }
}
error = devm_request_threaded_irq(dev, client->irq,
- NULL, msg2638_ts_irq_handler,
+ NULL, chip_data->irq_handler,
IRQF_ONESHOT | IRQF_NO_AUTOEN,
client->name, msg2638);
if (error) {
@@ -280,6 +432,12 @@ static int msg2638_ts_probe(struct i2c_client *client)
return error;
}
+ error = msg2638_init_input_dev(msg2638);
+ if (error) {
+ dev_err(dev, "Failed to initialize input device: %d\n", error);
+ return error;
+ }
+
return 0;
}
@@ -316,8 +474,19 @@ static int __maybe_unused msg2638_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(msg2638_pm_ops, msg2638_suspend, msg2638_resume);
+static const struct msg_chip_data msg2138_data = {
+ .irq_handler = msg2138_ts_irq_handler,
+ .max_fingers = MSG2138_MAX_FINGERS,
+};
+
+static const struct msg_chip_data msg2638_data = {
+ .irq_handler = msg2638_ts_irq_handler,
+ .max_fingers = MSG2638_MAX_FINGERS,
+};
+
static const struct of_device_id msg2638_of_match[] = {
- { .compatible = "mstar,msg2638" },
+ { .compatible = "mstar,msg2138", .data = &msg2138_data },
+ { .compatible = "mstar,msg2638", .data = &msg2638_data },
{ }
};
MODULE_DEVICE_TABLE(of, msg2638_of_match);
diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c
index dc148b4bed74..7959947a3458 100644
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -462,9 +462,9 @@ unlock:
static SIMPLE_DEV_PM_OPS(pixcir_dev_pm_ops,
pixcir_i2c_ts_suspend, pixcir_i2c_ts_resume);
-static int pixcir_i2c_ts_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int pixcir_i2c_ts_probe(struct i2c_client *client)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct device *dev = &client->dev;
struct pixcir_i2c_ts_data *tsdata;
struct input_dev *input;
@@ -617,7 +617,7 @@ static struct i2c_driver pixcir_i2c_ts_driver = {
.pm = &pixcir_dev_pm_ops,
.of_match_table = of_match_ptr(pixcir_of_match),
},
- .probe = pixcir_i2c_ts_probe,
+ .probe_new = pixcir_i2c_ts_probe,
.id_table = pixcir_i2c_ts_id,
};
diff --git a/drivers/input/touchscreen/raydium_i2c_ts.c b/drivers/input/touchscreen/raydium_i2c_ts.c
index 3d9c5758d8a4..d690a17240c2 100644
--- a/drivers/input/touchscreen/raydium_i2c_ts.c
+++ b/drivers/input/touchscreen/raydium_i2c_ts.c
@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/pm_wakeirq.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <asm/unaligned.h>
@@ -134,8 +135,6 @@ struct raydium_data {
u8 pkg_size;
enum raydium_boot_mode boot_mode;
-
- bool wake_irq_enabled;
};
/*
@@ -1066,8 +1065,7 @@ static void raydium_i2c_power_off(void *_data)
}
}
-static int raydium_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int raydium_i2c_probe(struct i2c_client *client)
{
union i2c_smbus_data dummy;
struct raydium_data *ts;
@@ -1224,8 +1222,6 @@ static int __maybe_unused raydium_i2c_suspend(struct device *dev)
if (device_may_wakeup(dev)) {
raydium_enter_sleep(client);
-
- ts->wake_irq_enabled = (enable_irq_wake(client->irq) == 0);
} else {
raydium_i2c_power_off(ts);
}
@@ -1239,8 +1235,6 @@ static int __maybe_unused raydium_i2c_resume(struct device *dev)
struct raydium_data *ts = i2c_get_clientdata(client);
if (device_may_wakeup(dev)) {
- if (ts->wake_irq_enabled)
- disable_irq_wake(client->irq);
raydium_i2c_sw_reset(client);
} else {
raydium_i2c_power_on(ts);
@@ -1279,7 +1273,7 @@ MODULE_DEVICE_TABLE(of, raydium_of_match);
#endif
static struct i2c_driver raydium_i2c_driver = {
- .probe = raydium_i2c_probe,
+ .probe_new = raydium_i2c_probe,
.id_table = raydium_i2c_id,
.driver = {
.name = "raydium_ts",
diff --git a/drivers/input/touchscreen/rohm_bu21023.c b/drivers/input/touchscreen/rohm_bu21023.c
index 730596d599d8..833422e5fd6d 100644
--- a/drivers/input/touchscreen/rohm_bu21023.c
+++ b/drivers/input/touchscreen/rohm_bu21023.c
@@ -1095,8 +1095,7 @@ static void rohm_ts_close(struct input_dev *input_dev)
ts->initialized = false;
}
-static int rohm_bu21023_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int rohm_bu21023_i2c_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct rohm_ts_data *ts;
@@ -1184,7 +1183,7 @@ static struct i2c_driver rohm_bu21023_i2c_driver = {
.driver = {
.name = BU21023_NAME,
},
- .probe = rohm_bu21023_i2c_probe,
+ .probe_new = rohm_bu21023_i2c_probe,
.id_table = rohm_bu21023_i2c_id,
};
module_i2c_driver(rohm_bu21023_i2c_driver);
diff --git a/drivers/input/touchscreen/s6sy761.c b/drivers/input/touchscreen/s6sy761.c
index 1a7d00289b4c..cc417c03aaca 100644
--- a/drivers/input/touchscreen/s6sy761.c
+++ b/drivers/input/touchscreen/s6sy761.c
@@ -389,8 +389,7 @@ static void s6sy761_power_off(void *data)
sdata->regulators);
}
-static int s6sy761_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int s6sy761_probe(struct i2c_client *client)
{
struct s6sy761_data *sdata;
unsigned int max_x, max_y;
@@ -540,7 +539,7 @@ static struct i2c_driver s6sy761_driver = {
.of_match_table = of_match_ptr(s6sy761_of_match),
.pm = &s6sy761_pm_ops,
},
- .probe = s6sy761_probe,
+ .probe_new = s6sy761_probe,
.remove = s6sy761_remove,
.id_table = s6sy761_id,
};
diff --git a/drivers/input/touchscreen/silead.c b/drivers/input/touchscreen/silead.c
index 3eef8c01090f..8a7351c4414c 100644
--- a/drivers/input/touchscreen/silead.c
+++ b/drivers/input/touchscreen/silead.c
@@ -652,9 +652,9 @@ static void silead_disable_regulator(void *arg)
regulator_bulk_disable(ARRAY_SIZE(data->regulators), data->regulators);
}
-static int silead_ts_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int silead_ts_probe(struct i2c_client *client)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct silead_ts_data *data;
struct device *dev = &client->dev;
int error;
@@ -826,7 +826,7 @@ MODULE_DEVICE_TABLE(of, silead_ts_of_match);
#endif
static struct i2c_driver silead_ts_driver = {
- .probe = silead_ts_probe,
+ .probe_new = silead_ts_probe,
.id_table = silead_ts_id,
.driver = {
.name = SILEAD_TS_NAME,
diff --git a/drivers/input/touchscreen/sis_i2c.c b/drivers/input/touchscreen/sis_i2c.c
index 6274555f1673..5a493b15b25d 100644
--- a/drivers/input/touchscreen/sis_i2c.c
+++ b/drivers/input/touchscreen/sis_i2c.c
@@ -296,8 +296,7 @@ static void sis_ts_reset(struct sis_ts_data *ts)
}
}
-static int sis_ts_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int sis_ts_probe(struct i2c_client *client)
{
struct sis_ts_data *ts;
struct input_dev *input;
@@ -394,7 +393,7 @@ static struct i2c_driver sis_ts_driver = {
.name = SIS_I2C_NAME,
.of_match_table = of_match_ptr(sis_ts_dt_ids),
},
- .probe = sis_ts_probe,
+ .probe_new = sis_ts_probe,
.id_table = sis_ts_id,
};
module_i2c_driver(sis_ts_driver);
diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c
index e38ba3e4f183..bd68633dc6c0 100644
--- a/drivers/input/touchscreen/st1232.c
+++ b/drivers/input/touchscreen/st1232.c
@@ -220,9 +220,9 @@ static const struct st_chip_info st1633_chip_info = {
.max_fingers = 5,
};
-static int st1232_ts_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int st1232_ts_probe(struct i2c_client *client)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(client);
const struct st_chip_info *match;
struct st1232_ts_data *ts;
struct input_dev *input_dev;
@@ -384,7 +384,7 @@ static const struct of_device_id st1232_ts_dt_ids[] = {
MODULE_DEVICE_TABLE(of, st1232_ts_dt_ids);
static struct i2c_driver st1232_ts_driver = {
- .probe = st1232_ts_probe,
+ .probe_new = st1232_ts_probe,
.id_table = st1232_ts_id,
.driver = {
.name = ST1232_TS_NAME,
diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index d5bd170808fb..d092e89d40e8 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -624,8 +624,7 @@ static int stmfts_enable_led(struct stmfts_data *sdata)
return 0;
}
-static int stmfts_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int stmfts_probe(struct i2c_client *client)
{
int err;
struct stmfts_data *sdata;
@@ -809,7 +808,7 @@ static struct i2c_driver stmfts_driver = {
.pm = &stmfts_pm_ops,
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
},
- .probe = stmfts_probe,
+ .probe_new = stmfts_probe,
.remove = stmfts_remove,
.id_table = stmfts_id,
};
diff --git a/drivers/input/touchscreen/sx8654.c b/drivers/input/touchscreen/sx8654.c
index de85e57b2486..52ae73035830 100644
--- a/drivers/input/touchscreen/sx8654.c
+++ b/drivers/input/touchscreen/sx8654.c
@@ -306,9 +306,9 @@ static void sx8654_close(struct input_dev *dev)
}
}
-static int sx8654_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int sx8654_probe(struct i2c_client *client)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(client);
struct sx8654 *sx8654;
struct input_dev *input;
int error;
@@ -470,7 +470,7 @@ static struct i2c_driver sx8654_driver = {
.of_match_table = of_match_ptr(sx8654_of_match),
},
.id_table = sx8654_id_table,
- .probe = sx8654_probe,
+ .probe_new = sx8654_probe,
};
module_i2c_driver(sx8654_driver);
diff --git a/drivers/input/touchscreen/tps6507x-ts.c b/drivers/input/touchscreen/tps6507x-ts.c
index 357a3108f2e5..f48871767763 100644
--- a/drivers/input/touchscreen/tps6507x-ts.c
+++ b/drivers/input/touchscreen/tps6507x-ts.c
@@ -119,7 +119,6 @@ err:
static s32 tps6507x_adc_standby(struct tps6507x_ts *tsc)
{
s32 ret;
- s32 loops = 0;
u8 val;
ret = tps6507x_write_u8(tsc, TPS6507X_REG_ADCONFIG,
@@ -141,7 +140,6 @@ static s32 tps6507x_adc_standby(struct tps6507x_ts *tsc)
ret = tps6507x_read_u8(tsc, TPS6507X_REG_INT, &val);
if (ret)
return ret;
- loops++;
}
return ret;
diff --git a/drivers/input/touchscreen/tsc2004.c b/drivers/input/touchscreen/tsc2004.c
index a9565353ee98..575768b587bb 100644
--- a/drivers/input/touchscreen/tsc2004.c
+++ b/drivers/input/touchscreen/tsc2004.c
@@ -34,8 +34,7 @@ static int tsc2004_cmd(struct device *dev, u8 cmd)
return 0;
}
-static int tsc2004_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int tsc2004_probe(struct i2c_client *i2c)
{
return tsc200x_probe(&i2c->dev, i2c->irq, &tsc2004_input_id,
@@ -69,7 +68,7 @@ static struct i2c_driver tsc2004_driver = {
.pm = &tsc200x_pm_ops,
},
.id_table = tsc2004_idtable,
- .probe = tsc2004_probe,
+ .probe_new = tsc2004_probe,
.remove = tsc2004_remove,
};
module_i2c_driver(tsc2004_driver);
diff --git a/drivers/input/touchscreen/tsc2007_core.c b/drivers/input/touchscreen/tsc2007_core.c
index 3e871d182c40..3c793fb70a0e 100644
--- a/drivers/input/touchscreen/tsc2007_core.c
+++ b/drivers/input/touchscreen/tsc2007_core.c
@@ -302,9 +302,9 @@ static void tsc2007_call_exit_platform_hw(void *data)
pdata->exit_platform_hw();
}
-static int tsc2007_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int tsc2007_probe(struct i2c_client *client)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(client);
const struct tsc2007_platform_data *pdata =
dev_get_platdata(&client->dev);
struct tsc2007 *ts;
@@ -431,7 +431,7 @@ static struct i2c_driver tsc2007_driver = {
.of_match_table = tsc2007_of_match,
},
.id_table = tsc2007_idtable,
- .probe = tsc2007_probe,
+ .probe_new = tsc2007_probe,
};
module_i2c_driver(tsc2007_driver);
diff --git a/drivers/input/touchscreen/wacom_i2c.c b/drivers/input/touchscreen/wacom_i2c.c
index 141754b2764c..c9188ee00c62 100644
--- a/drivers/input/touchscreen/wacom_i2c.c
+++ b/drivers/input/touchscreen/wacom_i2c.c
@@ -162,8 +162,7 @@ static void wacom_i2c_close(struct input_dev *dev)
disable_irq(client->irq);
}
-static int wacom_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int wacom_i2c_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct wacom_i2c *wac_i2c;
@@ -265,7 +264,7 @@ static struct i2c_driver wacom_i2c_driver = {
.pm = &wacom_i2c_pm,
},
- .probe = wacom_i2c_probe,
+ .probe_new = wacom_i2c_probe,
.id_table = wacom_i2c_id,
};
module_i2c_driver(wacom_i2c_driver);
diff --git a/drivers/input/touchscreen/wdt87xx_i2c.c b/drivers/input/touchscreen/wdt87xx_i2c.c
index 166edeb77776..3f87db5cdca4 100644
--- a/drivers/input/touchscreen/wdt87xx_i2c.c
+++ b/drivers/input/touchscreen/wdt87xx_i2c.c
@@ -1064,8 +1064,7 @@ static int wdt87xx_ts_create_input_device(struct wdt87xx_data *wdt)
return 0;
}
-static int wdt87xx_ts_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int wdt87xx_ts_probe(struct i2c_client *client)
{
struct wdt87xx_data *wdt;
int error;
@@ -1170,7 +1169,7 @@ static const struct acpi_device_id wdt87xx_acpi_id[] = {
MODULE_DEVICE_TABLE(acpi, wdt87xx_acpi_id);
static struct i2c_driver wdt87xx_driver = {
- .probe = wdt87xx_ts_probe,
+ .probe_new = wdt87xx_ts_probe,
.id_table = wdt87xx_dev_id,
.driver = {
.name = WDT87XX_NAME,
diff --git a/drivers/input/touchscreen/zet6223.c b/drivers/input/touchscreen/zet6223.c
index 3b6f7ee1e38f..bfa0c637d569 100644
--- a/drivers/input/touchscreen/zet6223.c
+++ b/drivers/input/touchscreen/zet6223.c
@@ -167,8 +167,7 @@ static int zet6223_query_device(struct zet6223_ts *ts)
return 0;
}
-static int zet6223_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int zet6223_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct zet6223_ts *ts;
@@ -249,7 +248,7 @@ static struct i2c_driver zet6223_driver = {
.name = "zet6223",
.of_match_table = zet6223_of_match,
},
- .probe = zet6223_probe,
+ .probe_new = zet6223_probe,
.id_table = zet6223_id
};
module_i2c_driver(zet6223_driver);
diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c
index 495629628af6..24e78ca83fa3 100644
--- a/drivers/input/touchscreen/zforce_ts.c
+++ b/drivers/input/touchscreen/zforce_ts.c
@@ -732,8 +732,7 @@ static struct zforce_ts_platdata *zforce_parse_dt(struct device *dev)
return pdata;
}
-static int zforce_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int zforce_probe(struct i2c_client *client)
{
const struct zforce_ts_platdata *pdata = dev_get_platdata(&client->dev);
struct zforce_ts *ts;
@@ -945,7 +944,7 @@ static struct i2c_driver zforce_driver = {
.pm = &zforce_pm_ops,
.of_match_table = of_match_ptr(zforce_dt_idtable),
},
- .probe = zforce_probe,
+ .probe_new = zforce_probe,
.id_table = zforce_idtable,
};
diff --git a/include/linux/fixp-arith.h b/include/linux/fixp-arith.h
index 281cb4f83dbe..e485fb0c1201 100644
--- a/include/linux/fixp-arith.h
+++ b/include/linux/fixp-arith.h
@@ -2,6 +2,7 @@
#ifndef _FIXP_ARITH_H
#define _FIXP_ARITH_H
+#include <linux/bug.h>
#include <linux/math64.h>
/*
diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h
index 6c98edcf4b0b..6193905abbb5 100644
--- a/include/linux/mfd/max8997.h
+++ b/include/linux/mfd/max8997.h
@@ -110,8 +110,6 @@ enum max8997_haptic_pwm_divisor {
/**
* max8997_haptic_platform_data
- * @pwm_channel_id: channel number of PWM device
- * valid for MAX8997_EXTERNAL_MODE
* @pwm_period: period in nano second for PWM device
* valid for MAX8997_EXTERNAL_MODE
* @type: motor type
@@ -128,7 +126,6 @@ enum max8997_haptic_pwm_divisor {
* [0 - 255]: available period
*/
struct max8997_haptic_platform_data {
- unsigned int pwm_channel_id;
unsigned int pwm_period;
enum max8997_haptic_motor_type type;
diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h
index 7ad931a32970..022a520e31fc 100644
--- a/include/uapi/linux/input-event-codes.h
+++ b/include/uapi/linux/input-event-codes.h
@@ -614,6 +614,9 @@
#define KEY_KBD_LAYOUT_NEXT 0x248 /* AC Next Keyboard Layout Select */
#define KEY_EMOJI_PICKER 0x249 /* Show/hide emoji picker (HUTRR101) */
#define KEY_DICTATE 0x24a /* Start or Stop Voice Dictation Session (HUTRR99) */
+#define KEY_CAMERA_ACCESS_ENABLE 0x24b /* Enables programmatic access to camera devices. (HUTRR72) */
+#define KEY_CAMERA_ACCESS_DISABLE 0x24c /* Disables programmatic access to camera devices. (HUTRR72) */
+#define KEY_CAMERA_ACCESS_TOGGLE 0x24d /* Toggles the current state of the camera access control. (HUTRR72) */
#define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */
#define KEY_BRIGHTNESS_MAX 0x251 /* Set Brightness to Maximum */