mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-05-24 10:39:52 +00:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input updates from Dmitry Torokhov: - a new driver for SparkFun Qwiic Joystick - pm8941-pwrkey driver now supports PMK8350 - a bunch of assorted driver fixes * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (44 commits) Input: joydev - prevent use of not validated data in JSIOCSBTNMAP ioctl Input: hideep - fix the uninitialized use in hideep_nvm_unlock() Input: trackpoint - use kobj_to_dev() Input: atkbd - use kobj_to_dev() Input: tsc200x-core - use kobj_to_dev() Input: ims-pcu - use kobj_to_dev() Input: cros_ec_keyb - use kobj_to_dev() API dt-bindings: input: touchscreen: st1232: Convert to json-schema Input: i8042 - fix typos in comments Input: add SparkFun Qwiic Joystick driver dt-bindings: Add vendor prefix and bindings for Qwiic Joystick Input: cy8ctmg110_ts - switch to using gpiod API Input: cy8ctmg110_ts - switch to using managed resources Input: cy8ctmg110_ts - use endian helpers when converting data on wire Input: cy8ctmg110_ts - let I2C core configure wake interrupt Input: cy8ctmg110_ts - do not hardcode as wakeup source Input: cy8ctmg110_ts - do not hard code interrupt trigger Input: cy8ctmg110_ts - rely on platform code to supply interrupt Input: resistive-adc-touch - fix uninitialized variable 'press' Input: pm8941-pwrkey - add support for PMK8350 PON_HLOS PMIC peripheral ...
This commit is contained in:
commit
1f89a590b2
39 changed files with 834 additions and 392 deletions
|
@ -1,12 +0,0 @@
|
||||||
* Freescale MMA8450 3-Axis Accelerometer
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
- compatible : "fsl,mma8450".
|
|
||||||
- reg: the I2C address of MMA8450
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
accelerometer: mma8450@1c {
|
|
||||||
compatible = "fsl,mma8450";
|
|
||||||
reg = <0x1c>;
|
|
||||||
};
|
|
|
@ -8,6 +8,8 @@ PROPERTIES
|
||||||
Definition: must be one of:
|
Definition: must be one of:
|
||||||
"qcom,pm8941-pwrkey"
|
"qcom,pm8941-pwrkey"
|
||||||
"qcom,pm8941-resin"
|
"qcom,pm8941-resin"
|
||||||
|
"qcom,pmk8350-pwrkey"
|
||||||
|
"qcom,pmk8350-resin"
|
||||||
|
|
||||||
- reg:
|
- reg:
|
||||||
Usage: required
|
Usage: required
|
||||||
|
|
|
@ -0,0 +1,148 @@
|
||||||
|
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/input/touchscreen/cypress,cy8ctma340.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: Cypress CY8CTMA340 series touchscreen controller bindings
|
||||||
|
|
||||||
|
description: The Cypress CY8CTMA340 series (also known as "CYTTSP" after
|
||||||
|
the marketing name Cypress TrueTouch Standard Product) touchscreens can
|
||||||
|
be connected to either I2C or SPI buses.
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Javier Martinez Canillas <javier@dowhile0.org>
|
||||||
|
- Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
|
||||||
|
allOf:
|
||||||
|
- $ref: touchscreen.yaml#
|
||||||
|
|
||||||
|
properties:
|
||||||
|
$nodename:
|
||||||
|
pattern: "^touchscreen(@.*)?$"
|
||||||
|
|
||||||
|
compatible:
|
||||||
|
oneOf:
|
||||||
|
- const: cypress,cy8ctma340
|
||||||
|
- const: cypress,cy8ctst341
|
||||||
|
- const: cypress,cyttsp-spi
|
||||||
|
description: Legacy compatible for SPI connected CY8CTMA340
|
||||||
|
deprecated: true
|
||||||
|
- const: cypress,cyttsp-i2c
|
||||||
|
description: Legacy compatible for I2C connected CY8CTMA340
|
||||||
|
deprecated: true
|
||||||
|
|
||||||
|
reg:
|
||||||
|
description: I2C address when used on the I2C bus, or the SPI chip
|
||||||
|
select index when used on the SPI bus
|
||||||
|
|
||||||
|
clock-frequency:
|
||||||
|
description: I2C client clock frequency, defined for host when using
|
||||||
|
the device on the I2C bus
|
||||||
|
minimum: 0
|
||||||
|
maximum: 400000
|
||||||
|
|
||||||
|
spi-max-frequency:
|
||||||
|
description: SPI clock frequency, defined for host, defined when using
|
||||||
|
the device on the SPI bus. The throughput is maximum 2 Mbps so the
|
||||||
|
typical value is 2000000, if higher rates are used the total throughput
|
||||||
|
needs to be restricted to 2 Mbps.
|
||||||
|
minimum: 0
|
||||||
|
maximum: 6000000
|
||||||
|
|
||||||
|
interrupts:
|
||||||
|
description: Interrupt to host
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
vcpin-supply:
|
||||||
|
description: Analog power supply regulator on VCPIN pin
|
||||||
|
|
||||||
|
vdd-supply:
|
||||||
|
description: Digital power supply regulator on VDD pin
|
||||||
|
|
||||||
|
reset-gpios:
|
||||||
|
description: Reset line for the touchscreen, should be tagged
|
||||||
|
as GPIO_ACTIVE_LOW
|
||||||
|
|
||||||
|
bootloader-key:
|
||||||
|
description: the 8-byte bootloader key that is required to switch
|
||||||
|
the chip from bootloader mode (default mode) to application mode
|
||||||
|
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||||
|
minItems: 8
|
||||||
|
maxItems: 8
|
||||||
|
|
||||||
|
touchscreen-size-x: true
|
||||||
|
touchscreen-size-y: true
|
||||||
|
touchscreen-fuzz-x: true
|
||||||
|
touchscreen-fuzz-y: true
|
||||||
|
|
||||||
|
active-distance:
|
||||||
|
description: the distance in pixels beyond which a touch must move
|
||||||
|
before movement is detected and reported by the device
|
||||||
|
$ref: /schemas/types.yaml#/definitions/uint32
|
||||||
|
minimum: 0
|
||||||
|
maximum: 15
|
||||||
|
|
||||||
|
active-interval-ms:
|
||||||
|
description: the minimum period in ms between consecutive
|
||||||
|
scanning/processing cycles when the chip is in active mode
|
||||||
|
minimum: 0
|
||||||
|
maximum: 255
|
||||||
|
|
||||||
|
lowpower-interval-ms:
|
||||||
|
description: the minimum period in ms between consecutive
|
||||||
|
scanning/processing cycles when the chip is in low-power mode
|
||||||
|
minimum: 0
|
||||||
|
maximum: 2550
|
||||||
|
|
||||||
|
touch-timeout-ms:
|
||||||
|
description: minimum time in ms spent in the active power state while no
|
||||||
|
touches are detected before entering low-power mode
|
||||||
|
minimum: 0
|
||||||
|
maximum: 2550
|
||||||
|
|
||||||
|
use-handshake:
|
||||||
|
description: enable register-based handshake (boolean). This should only
|
||||||
|
be used if the chip is configured to use 'blocking communication with
|
||||||
|
timeout' (in this case the device generates an interrupt at the end of
|
||||||
|
every scanning/processing cycle)
|
||||||
|
$ref: /schemas/types.yaml#/definitions/flag
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
- interrupts
|
||||||
|
- bootloader-key
|
||||||
|
- touchscreen-size-x
|
||||||
|
- touchscreen-size-y
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
#include <dt-bindings/interrupt-controller/irq.h>
|
||||||
|
#include <dt-bindings/gpio/gpio.h>
|
||||||
|
spi {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
num-cs = <1>;
|
||||||
|
cs-gpios = <&gpio 2 GPIO_ACTIVE_HIGH>;
|
||||||
|
|
||||||
|
touchscreen@0 {
|
||||||
|
compatible = "cypress,cy8ctma340";
|
||||||
|
reg = <0>;
|
||||||
|
interrupt-parent = <&gpio>;
|
||||||
|
interrupts = <20 IRQ_TYPE_EDGE_FALLING>;
|
||||||
|
reset-gpios = <&gpio 21 GPIO_ACTIVE_LOW>;
|
||||||
|
vdd-supply = <&ldo_aux1_reg>;
|
||||||
|
vcpin-supply = <&ldo_aux2_reg>;
|
||||||
|
bootloader-key = /bits/ 8 <0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07>;
|
||||||
|
touchscreen-size-x = <480>;
|
||||||
|
touchscreen-size-y = <800>;
|
||||||
|
active-interval-ms = <0>;
|
||||||
|
touch-timeout-ms = <255>;
|
||||||
|
lowpower-interval-ms = <10>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
...
|
|
@ -1,93 +0,0 @@
|
||||||
* Cypress cyttsp touchscreen controller
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
- compatible : must be "cypress,cyttsp-i2c" or "cypress,cyttsp-spi"
|
|
||||||
- reg : Device I2C address or SPI chip select number
|
|
||||||
- spi-max-frequency : Maximum SPI clocking speed of the device (for cyttsp-spi)
|
|
||||||
- interrupts : (gpio) interrupt to which the chip is connected
|
|
||||||
(see interrupt binding[0]).
|
|
||||||
- bootloader-key : the 8-byte bootloader key that is required to switch
|
|
||||||
the chip from bootloader mode (default mode) to
|
|
||||||
application mode.
|
|
||||||
This property has to be specified as an array of 8
|
|
||||||
'/bits/ 8' values.
|
|
||||||
|
|
||||||
Optional properties:
|
|
||||||
- reset-gpios : the reset gpio the chip is connected to
|
|
||||||
(see GPIO binding[1] for more details).
|
|
||||||
- touchscreen-size-x : horizontal resolution of touchscreen (in pixels)
|
|
||||||
- touchscreen-size-y : vertical resolution of touchscreen (in pixels)
|
|
||||||
- touchscreen-fuzz-x : horizontal noise value of the absolute input device
|
|
||||||
(in pixels)
|
|
||||||
- touchscreen-fuzz-y : vertical noise value of the absolute input device
|
|
||||||
(in pixels)
|
|
||||||
- active-distance : the distance in pixels beyond which a touch must move
|
|
||||||
before movement is detected and reported by the device.
|
|
||||||
Valid values: 0-15.
|
|
||||||
- active-interval-ms : the minimum period in ms between consecutive
|
|
||||||
scanning/processing cycles when the chip is in active mode.
|
|
||||||
Valid values: 0-255.
|
|
||||||
- lowpower-interval-ms : the minimum period in ms between consecutive
|
|
||||||
scanning/processing cycles when the chip is in low-power mode.
|
|
||||||
Valid values: 0-2550
|
|
||||||
- touch-timeout-ms : minimum time in ms spent in the active power state while no
|
|
||||||
touches are detected before entering low-power mode.
|
|
||||||
Valid values: 0-2550
|
|
||||||
- use-handshake : enable register-based handshake (boolean). This should
|
|
||||||
only be used if the chip is configured to use 'blocking
|
|
||||||
communication with timeout' (in this case the device
|
|
||||||
generates an interrupt at the end of every
|
|
||||||
scanning/processing cycle).
|
|
||||||
|
|
||||||
[0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
|
|
||||||
[1]: Documentation/devicetree/bindings/gpio/gpio.txt
|
|
||||||
|
|
||||||
Example:
|
|
||||||
&i2c1 {
|
|
||||||
/* ... */
|
|
||||||
cyttsp@a {
|
|
||||||
compatible = "cypress,cyttsp-i2c";
|
|
||||||
reg = <0xa>;
|
|
||||||
interrupt-parent = <&gpio0>;
|
|
||||||
interrupts = <28 0>;
|
|
||||||
reset-gpios = <&gpio3 4 GPIO_ACTIVE_LOW>;
|
|
||||||
|
|
||||||
touchscreen-size-x = <800>;
|
|
||||||
touchscreen-size-y = <480>;
|
|
||||||
touchscreen-fuzz-x = <4>;
|
|
||||||
touchscreen-fuzz-y = <7>;
|
|
||||||
|
|
||||||
bootloader-key = /bits/ 8 <0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08>;
|
|
||||||
active-distance = <8>;
|
|
||||||
active-interval-ms = <0>;
|
|
||||||
lowpower-interval-ms = <200>;
|
|
||||||
touch-timeout-ms = <100>;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ... */
|
|
||||||
};
|
|
||||||
|
|
||||||
&mcspi1 {
|
|
||||||
/* ... */
|
|
||||||
cyttsp@0 {
|
|
||||||
compatible = "cypress,cyttsp-spi";
|
|
||||||
spi-max-frequency = <6000000>;
|
|
||||||
reg = <0>;
|
|
||||||
interrupt-parent = <&gpio0>;
|
|
||||||
interrupts = <28 0>;
|
|
||||||
reset-gpios = <&gpio3 4 GPIO_ACTIVE_LOW>;
|
|
||||||
|
|
||||||
touchscreen-size-x = <800>;
|
|
||||||
touchscreen-size-y = <480>;
|
|
||||||
touchscreen-fuzz-x = <4>;
|
|
||||||
touchscreen-fuzz-y = <7>;
|
|
||||||
|
|
||||||
bootloader-key = /bits/ 8 <0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08>;
|
|
||||||
active-distance = <8>;
|
|
||||||
active-interval-ms = <0>;
|
|
||||||
lowpower-interval-ms = <200>;
|
|
||||||
touch-timeout-ms = <100>;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ... */
|
|
||||||
};
|
|
|
@ -56,6 +56,7 @@ properties:
|
||||||
wakeup-source: true
|
wakeup-source: true
|
||||||
|
|
||||||
vcc-supply: true
|
vcc-supply: true
|
||||||
|
iovcc-supply: true
|
||||||
|
|
||||||
gain:
|
gain:
|
||||||
description: Allows setting the sensitivity in the range from 0 to 31.
|
description: Allows setting the sensitivity in the range from 0 to 31.
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
Generic resistive touchscreen ADC
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
|
|
||||||
- compatible: must be "resistive-adc-touch"
|
|
||||||
The device must be connected to an ADC device that provides channels for
|
|
||||||
position measurement and optional pressure.
|
|
||||||
Refer to
|
|
||||||
https://github.com/devicetree-org/dt-schema/blob/master/schemas/iio/iio-consumer.yaml
|
|
||||||
for details
|
|
||||||
|
|
||||||
- iio-channels: must have at least two channels connected to an ADC device.
|
|
||||||
These should correspond to the channels exposed by the ADC device and should
|
|
||||||
have the right index as the ADC device registers them. These channels
|
|
||||||
represent the relative position on the "x" and "y" axes.
|
|
||||||
- iio-channel-names: must have all the channels' names. Mandatory channels
|
|
||||||
are "x" and "y".
|
|
||||||
|
|
||||||
Optional properties:
|
|
||||||
- iio-channels: The third channel named "pressure" is optional and can be
|
|
||||||
used if the ADC device also measures pressure besides position.
|
|
||||||
If this channel is missing, pressure will be ignored and the touchscreen
|
|
||||||
will only report position.
|
|
||||||
- iio-channel-names: optional channel named "pressure".
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
resistive_touch: resistive_touch {
|
|
||||||
compatible = "resistive-adc-touch";
|
|
||||||
touchscreen-min-pressure = <50000>;
|
|
||||||
io-channels = <&adc 24>, <&adc 25>, <&adc 26>;
|
|
||||||
io-channel-names = "x", "y", "pressure";
|
|
||||||
};
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/input/touchscreen/resistive-adc-touch.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: Generic resistive touchscreen ADC
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Oleksij Rempel <o.rempel@pengutronix.de>
|
||||||
|
|
||||||
|
description: |
|
||||||
|
Generic ADC based resistive touchscreen controller
|
||||||
|
The device must be connected to an ADC device that provides channels for
|
||||||
|
position measurement and optional pressure.
|
||||||
|
|
||||||
|
allOf:
|
||||||
|
- $ref: touchscreen.yaml#
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
const: resistive-adc-touch
|
||||||
|
|
||||||
|
io-channels:
|
||||||
|
minItems: 2
|
||||||
|
items:
|
||||||
|
- description: x
|
||||||
|
- description: y
|
||||||
|
- description: pressure (optional)
|
||||||
|
- description: z1 (optional)
|
||||||
|
- description: z2 (optional)
|
||||||
|
|
||||||
|
io-channel-names:
|
||||||
|
oneOf:
|
||||||
|
- items:
|
||||||
|
- enum: [x, y]
|
||||||
|
- enum: [x, y]
|
||||||
|
- items:
|
||||||
|
- enum: [x, y, pressure]
|
||||||
|
- enum: [x, y, pressure]
|
||||||
|
- enum: [x, y, pressure]
|
||||||
|
- items:
|
||||||
|
- enum: [x, y, z1, z2]
|
||||||
|
- enum: [x, y, z1, z2]
|
||||||
|
- enum: [x, y, z1, z2]
|
||||||
|
- enum: [x, y, z1, z2]
|
||||||
|
|
||||||
|
touchscreen-size-x: true
|
||||||
|
touchscreen-size-y: true
|
||||||
|
touchscreen-fuzz-x: true
|
||||||
|
touchscreen-fuzz-y: true
|
||||||
|
touchscreen-inverted-x: true
|
||||||
|
touchscreen-inverted-y: true
|
||||||
|
touchscreen-swapped-x-y: true
|
||||||
|
touchscreen-min-pressure: true
|
||||||
|
touchscreen-x-plate-ohms: true
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- io-channels
|
||||||
|
- io-channel-names
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
touchscreen {
|
||||||
|
compatible = "resistive-adc-touch";
|
||||||
|
io-channels = <&adc 24>, <&adc 25>;
|
||||||
|
io-channel-names = "y", "x";
|
||||||
|
};
|
||||||
|
- |
|
||||||
|
touchscreen {
|
||||||
|
compatible = "resistive-adc-touch";
|
||||||
|
touchscreen-min-pressure = <50000>;
|
||||||
|
io-channels = <&adc 24>, <&adc 25>, <&adc 26>;
|
||||||
|
io-channel-names = "y", "pressure", "x";
|
||||||
|
};
|
||||||
|
- |
|
||||||
|
touchscreen {
|
||||||
|
compatible = "resistive-adc-touch";
|
||||||
|
touchscreen-min-pressure = <50000>;
|
||||||
|
io-channels = <&adc 1>, <&adc 2>, <&adc 3>, <&adc 4>;
|
||||||
|
io-channel-names = "x", "z1", "z2", "y";
|
||||||
|
touchscreen-x-plate-ohms = <800>;
|
||||||
|
};
|
|
@ -0,0 +1,50 @@
|
||||||
|
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/input/touchscreen/sitronix,st1232.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: Sitronix st1232 or st1633 touchscreen controller
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Bastian Hecht <hechtb@gmail.com>
|
||||||
|
|
||||||
|
allOf:
|
||||||
|
- $ref: touchscreen.yaml#
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
enum:
|
||||||
|
- sitronix,st1232
|
||||||
|
- sitronix,st1633
|
||||||
|
|
||||||
|
reg:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
interrupts:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
gpios:
|
||||||
|
description: A phandle to the reset GPIO
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
- interrupts
|
||||||
|
|
||||||
|
unevaluatedProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
i2c {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
touchscreen@55 {
|
||||||
|
compatible = "sitronix,st1232";
|
||||||
|
reg = <0x55>;
|
||||||
|
interrupts = <2 0>;
|
||||||
|
gpios = <&gpio1 166 0>;
|
||||||
|
};
|
||||||
|
};
|
|
@ -1,28 +0,0 @@
|
||||||
* Sitronix st1232 or st1633 touchscreen controller
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
- compatible: must contain one of
|
|
||||||
* "sitronix,st1232"
|
|
||||||
* "sitronix,st1633"
|
|
||||||
- reg: I2C address of the chip
|
|
||||||
- interrupts: interrupt to which the chip is connected
|
|
||||||
|
|
||||||
Optional properties:
|
|
||||||
- gpios: a phandle to the reset GPIO
|
|
||||||
|
|
||||||
For additional optional properties see: touchscreen.txt
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
i2c@00000000 {
|
|
||||||
/* ... */
|
|
||||||
|
|
||||||
touchscreen@55 {
|
|
||||||
compatible = "sitronix,st1232";
|
|
||||||
reg = <0x55>;
|
|
||||||
interrupts = <2 0>;
|
|
||||||
gpios = <&gpio1 166 0>;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ... */
|
|
||||||
};
|
|
|
@ -74,6 +74,12 @@ properties:
|
||||||
touchscreen-y-mm:
|
touchscreen-y-mm:
|
||||||
description: vertical length in mm of the touchscreen
|
description: vertical length in mm of the touchscreen
|
||||||
|
|
||||||
|
touchscreen-x-plate-ohms:
|
||||||
|
description: Resistance of the X-plate in Ohms
|
||||||
|
|
||||||
|
touchscreen-y-plate-ohms:
|
||||||
|
description: Resistance of the Y-plate in Ohms
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
touchscreen-size-x: [ touchscreen-size-y ]
|
touchscreen-size-x: [ touchscreen-size-y ]
|
||||||
touchscreen-size-y: [ touchscreen-size-x ]
|
touchscreen-size-y: [ touchscreen-size-x ]
|
||||||
|
|
|
@ -272,6 +272,8 @@ properties:
|
||||||
# Socionext SynQuacer TPM MMIO module
|
# Socionext SynQuacer TPM MMIO module
|
||||||
- socionext,synquacer-tpm-mmio
|
- socionext,synquacer-tpm-mmio
|
||||||
# i2c serial eeprom (24cxx)
|
# i2c serial eeprom (24cxx)
|
||||||
|
- sparkfun,qwiic-joystick
|
||||||
|
# SparkFun Qwiic Joystick (COM-15168) with i2c interface
|
||||||
- st,24c256
|
- st,24c256
|
||||||
# Ambient Light Sensor with SMBUS/Two Wire Serial Interface
|
# Ambient Light Sensor with SMBUS/Two Wire Serial Interface
|
||||||
- taos,tsl2550
|
- taos,tsl2550
|
||||||
|
|
|
@ -1080,6 +1080,8 @@ patternProperties:
|
||||||
description: Sony Corporation
|
description: Sony Corporation
|
||||||
"^spansion,.*":
|
"^spansion,.*":
|
||||||
description: Spansion Inc.
|
description: Spansion Inc.
|
||||||
|
"^sparkfun,.*":
|
||||||
|
description: SparkFun Electronics
|
||||||
"^sprd,.*":
|
"^sprd,.*":
|
||||||
description: Spreadtrum Communications Inc.
|
description: Spreadtrum Communications Inc.
|
||||||
"^sst,.*":
|
"^sst,.*":
|
||||||
|
|
|
@ -5051,11 +5051,10 @@ S: Maintained
|
||||||
F: drivers/input/touchscreen/cy8ctma140.c
|
F: drivers/input/touchscreen/cy8ctma140.c
|
||||||
|
|
||||||
CYTTSP TOUCHSCREEN DRIVER
|
CYTTSP TOUCHSCREEN DRIVER
|
||||||
M: Ferruh Yigit <fery@cypress.com>
|
M: Linus Walleij <linus.walleij@linaro.org>
|
||||||
L: linux-input@vger.kernel.org
|
L: linux-input@vger.kernel.org
|
||||||
S: Supported
|
S: Maintained
|
||||||
F: drivers/input/touchscreen/cyttsp*
|
F: drivers/input/touchscreen/cyttsp*
|
||||||
F: include/linux/input/cyttsp.h
|
|
||||||
|
|
||||||
D-LINK DIR-685 TOUCHKEYS DRIVER
|
D-LINK DIR-685 TOUCHKEYS DRIVER
|
||||||
M: Linus Walleij <linus.walleij@linaro.org>
|
M: Linus Walleij <linus.walleij@linaro.org>
|
||||||
|
|
|
@ -7,9 +7,6 @@
|
||||||
* Input driver event debug module - dumps all events into syslog
|
* Input driver event debug module - dumps all events into syslog
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||||
|
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
|
|
@ -499,7 +499,7 @@ static int joydev_handle_JSIOCSBTNMAP(struct joydev *joydev,
|
||||||
memcpy(joydev->keypam, keypam, len);
|
memcpy(joydev->keypam, keypam, len);
|
||||||
|
|
||||||
for (i = 0; i < joydev->nkey; i++)
|
for (i = 0; i < joydev->nkey; i++)
|
||||||
joydev->keymap[keypam[i] - BTN_MISC] = i;
|
joydev->keymap[joydev->keypam[i] - BTN_MISC] = i;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
kfree(keypam);
|
kfree(keypam);
|
||||||
|
|
|
@ -372,6 +372,15 @@ config JOYSTICK_PXRC
|
||||||
To compile this driver as a module, choose M here: the
|
To compile this driver as a module, choose M here: the
|
||||||
module will be called pxrc.
|
module will be called pxrc.
|
||||||
|
|
||||||
|
config JOYSTICK_QWIIC
|
||||||
|
tristate "SparkFun Qwiic Joystick"
|
||||||
|
depends on I2C
|
||||||
|
help
|
||||||
|
Say Y here if you want to use the SparkFun Qwiic Joystick.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here: the
|
||||||
|
module will be called qwiic-joystick.
|
||||||
|
|
||||||
config JOYSTICK_FSIA6B
|
config JOYSTICK_FSIA6B
|
||||||
tristate "FlySky FS-iA6B RC Receiver"
|
tristate "FlySky FS-iA6B RC Receiver"
|
||||||
select SERIO
|
select SERIO
|
||||||
|
|
|
@ -27,6 +27,7 @@ obj-$(CONFIG_JOYSTICK_MAPLE) += maplecontrol.o
|
||||||
obj-$(CONFIG_JOYSTICK_N64) += n64joy.o
|
obj-$(CONFIG_JOYSTICK_N64) += n64joy.o
|
||||||
obj-$(CONFIG_JOYSTICK_PSXPAD_SPI) += psxpad-spi.o
|
obj-$(CONFIG_JOYSTICK_PSXPAD_SPI) += psxpad-spi.o
|
||||||
obj-$(CONFIG_JOYSTICK_PXRC) += pxrc.o
|
obj-$(CONFIG_JOYSTICK_PXRC) += pxrc.o
|
||||||
|
obj-$(CONFIG_JOYSTICK_QWIIC) += qwiic-joystick.o
|
||||||
obj-$(CONFIG_JOYSTICK_SIDEWINDER) += sidewinder.o
|
obj-$(CONFIG_JOYSTICK_SIDEWINDER) += sidewinder.o
|
||||||
obj-$(CONFIG_JOYSTICK_SPACEBALL) += spaceball.o
|
obj-$(CONFIG_JOYSTICK_SPACEBALL) += spaceball.o
|
||||||
obj-$(CONFIG_JOYSTICK_SPACEORB) += spaceorb.o
|
obj-$(CONFIG_JOYSTICK_SPACEORB) += spaceorb.o
|
||||||
|
|
146
drivers/input/joystick/qwiic-joystick.c
Normal file
146
drivers/input/joystick/qwiic-joystick.c
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Oleh Kravchenko <oleg@kaa.org.ua>
|
||||||
|
*
|
||||||
|
* SparkFun Qwiic Joystick
|
||||||
|
* Product page:https://www.sparkfun.com/products/15168
|
||||||
|
* Firmware and hardware sources:https://github.com/sparkfun/Qwiic_Joystick
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/bits.h>
|
||||||
|
#include <linux/i2c.h>
|
||||||
|
#include <linux/input.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
|
||||||
|
#define DRV_NAME "qwiic-joystick"
|
||||||
|
|
||||||
|
#define QWIIC_JSK_REG_VERS 1
|
||||||
|
#define QWIIC_JSK_REG_DATA 3
|
||||||
|
|
||||||
|
#define QWIIC_JSK_MAX_AXIS GENMASK(9, 0)
|
||||||
|
#define QWIIC_JSK_FUZZ 2
|
||||||
|
#define QWIIC_JSK_FLAT 2
|
||||||
|
#define QWIIC_JSK_POLL_INTERVAL 16
|
||||||
|
#define QWIIC_JSK_POLL_MIN 8
|
||||||
|
#define QWIIC_JSK_POLL_MAX 32
|
||||||
|
|
||||||
|
struct qwiic_jsk {
|
||||||
|
char phys[32];
|
||||||
|
struct input_dev *dev;
|
||||||
|
struct i2c_client *client;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct qwiic_ver {
|
||||||
|
u8 major;
|
||||||
|
u8 minor;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct qwiic_data {
|
||||||
|
__be16 x;
|
||||||
|
__be16 y;
|
||||||
|
u8 thumb;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void qwiic_poll(struct input_dev *input)
|
||||||
|
{
|
||||||
|
struct qwiic_jsk *priv = input_get_drvdata(input);
|
||||||
|
struct qwiic_data data;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = i2c_smbus_read_i2c_block_data(priv->client, QWIIC_JSK_REG_DATA,
|
||||||
|
sizeof(data), (u8 *)&data);
|
||||||
|
if (err != sizeof(data))
|
||||||
|
return;
|
||||||
|
|
||||||
|
input_report_abs(input, ABS_X, be16_to_cpu(data.x) >> 6);
|
||||||
|
input_report_abs(input, ABS_Y, be16_to_cpu(data.y) >> 6);
|
||||||
|
input_report_key(input, BTN_THUMBL, !data.thumb);
|
||||||
|
input_sync(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int qwiic_probe(struct i2c_client *client)
|
||||||
|
{
|
||||||
|
struct qwiic_jsk *priv;
|
||||||
|
struct qwiic_ver vers;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = i2c_smbus_read_i2c_block_data(client, QWIIC_JSK_REG_VERS,
|
||||||
|
sizeof(vers), (u8 *)&vers);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
if (err != sizeof(vers))
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
dev_dbg(&client->dev, "SparkFun Qwiic Joystick, FW: %u.%u\n",
|
||||||
|
vers.major, vers.minor);
|
||||||
|
|
||||||
|
priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
|
||||||
|
if (!priv)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
priv->client = client;
|
||||||
|
snprintf(priv->phys, sizeof(priv->phys),
|
||||||
|
"i2c/%s", dev_name(&client->dev));
|
||||||
|
i2c_set_clientdata(client, priv);
|
||||||
|
|
||||||
|
priv->dev = devm_input_allocate_device(&client->dev);
|
||||||
|
if (!priv->dev)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
priv->dev->id.bustype = BUS_I2C;
|
||||||
|
priv->dev->name = "SparkFun Qwiic Joystick";
|
||||||
|
priv->dev->phys = priv->phys;
|
||||||
|
input_set_drvdata(priv->dev, priv);
|
||||||
|
|
||||||
|
input_set_abs_params(priv->dev, ABS_X, 0, QWIIC_JSK_MAX_AXIS,
|
||||||
|
QWIIC_JSK_FUZZ, QWIIC_JSK_FLAT);
|
||||||
|
input_set_abs_params(priv->dev, ABS_Y, 0, QWIIC_JSK_MAX_AXIS,
|
||||||
|
QWIIC_JSK_FUZZ, QWIIC_JSK_FLAT);
|
||||||
|
input_set_capability(priv->dev, EV_KEY, BTN_THUMBL);
|
||||||
|
|
||||||
|
err = input_setup_polling(priv->dev, qwiic_poll);
|
||||||
|
if (err) {
|
||||||
|
dev_err(&client->dev, "failed to set up polling: %d\n", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
input_set_poll_interval(priv->dev, QWIIC_JSK_POLL_INTERVAL);
|
||||||
|
input_set_min_poll_interval(priv->dev, QWIIC_JSK_POLL_MIN);
|
||||||
|
input_set_max_poll_interval(priv->dev, QWIIC_JSK_POLL_MAX);
|
||||||
|
|
||||||
|
err = input_register_device(priv->dev);
|
||||||
|
if (err) {
|
||||||
|
dev_err(&client->dev, "failed to register joystick: %d\n", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_OF
|
||||||
|
static const struct of_device_id of_qwiic_match[] = {
|
||||||
|
{ .compatible = "sparkfun,qwiic-joystick", },
|
||||||
|
{ },
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, of_qwiic_match);
|
||||||
|
#endif /* CONFIG_OF */
|
||||||
|
|
||||||
|
static const struct i2c_device_id qwiic_id_table[] = {
|
||||||
|
{ KBUILD_MODNAME, 0 },
|
||||||
|
{ },
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(i2c, qwiic_id_table);
|
||||||
|
|
||||||
|
static struct i2c_driver qwiic_driver = {
|
||||||
|
.driver = {
|
||||||
|
.name = DRV_NAME,
|
||||||
|
.of_match_table = of_match_ptr(of_qwiic_match),
|
||||||
|
},
|
||||||
|
.id_table = qwiic_id_table,
|
||||||
|
.probe_new = qwiic_probe,
|
||||||
|
};
|
||||||
|
module_i2c_driver(qwiic_driver);
|
||||||
|
|
||||||
|
MODULE_AUTHOR("Oleh Kravchenko <oleg@kaa.org.ua>");
|
||||||
|
MODULE_DESCRIPTION("SparkFun Qwiic Joystick driver");
|
||||||
|
MODULE_LICENSE("GPL v2");
|
|
@ -79,6 +79,7 @@
|
||||||
#define MAP_DPAD_TO_BUTTONS (1 << 0)
|
#define MAP_DPAD_TO_BUTTONS (1 << 0)
|
||||||
#define MAP_TRIGGERS_TO_BUTTONS (1 << 1)
|
#define MAP_TRIGGERS_TO_BUTTONS (1 << 1)
|
||||||
#define MAP_STICKS_TO_NULL (1 << 2)
|
#define MAP_STICKS_TO_NULL (1 << 2)
|
||||||
|
#define MAP_SELECT_BUTTON (1 << 3)
|
||||||
#define DANCEPAD_MAP_CONFIG (MAP_DPAD_TO_BUTTONS | \
|
#define DANCEPAD_MAP_CONFIG (MAP_DPAD_TO_BUTTONS | \
|
||||||
MAP_TRIGGERS_TO_BUTTONS | MAP_STICKS_TO_NULL)
|
MAP_TRIGGERS_TO_BUTTONS | MAP_STICKS_TO_NULL)
|
||||||
|
|
||||||
|
@ -130,6 +131,7 @@ static const struct xpad_device {
|
||||||
{ 0x045e, 0x02e3, "Microsoft X-Box One Elite pad", 0, XTYPE_XBOXONE },
|
{ 0x045e, 0x02e3, "Microsoft X-Box One Elite pad", 0, XTYPE_XBOXONE },
|
||||||
{ 0x045e, 0x02ea, "Microsoft X-Box One S pad", 0, XTYPE_XBOXONE },
|
{ 0x045e, 0x02ea, "Microsoft X-Box One S pad", 0, XTYPE_XBOXONE },
|
||||||
{ 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
|
{ 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
|
||||||
|
{ 0x045e, 0x0b12, "Microsoft Xbox One X pad", MAP_SELECT_BUTTON, XTYPE_XBOXONE },
|
||||||
{ 0x046d, 0xc21d, "Logitech Gamepad F310", 0, XTYPE_XBOX360 },
|
{ 0x046d, 0xc21d, "Logitech Gamepad F310", 0, XTYPE_XBOX360 },
|
||||||
{ 0x046d, 0xc21e, "Logitech Gamepad F510", 0, XTYPE_XBOX360 },
|
{ 0x046d, 0xc21e, "Logitech Gamepad F510", 0, XTYPE_XBOX360 },
|
||||||
{ 0x046d, 0xc21f, "Logitech Gamepad F710", 0, XTYPE_XBOX360 },
|
{ 0x046d, 0xc21f, "Logitech Gamepad F710", 0, XTYPE_XBOX360 },
|
||||||
|
@ -864,6 +866,8 @@ static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char
|
||||||
/* menu/view buttons */
|
/* menu/view buttons */
|
||||||
input_report_key(dev, BTN_START, data[4] & 0x04);
|
input_report_key(dev, BTN_START, data[4] & 0x04);
|
||||||
input_report_key(dev, BTN_SELECT, data[4] & 0x08);
|
input_report_key(dev, BTN_SELECT, data[4] & 0x08);
|
||||||
|
if (xpad->mapping & MAP_SELECT_BUTTON)
|
||||||
|
input_report_key(dev, KEY_RECORD, data[22] & 0x01);
|
||||||
|
|
||||||
/* buttons A,B,X,Y */
|
/* buttons A,B,X,Y */
|
||||||
input_report_key(dev, BTN_A, data[4] & 0x10);
|
input_report_key(dev, BTN_A, data[4] & 0x10);
|
||||||
|
@ -1674,6 +1678,8 @@ static int xpad_init_input(struct usb_xpad *xpad)
|
||||||
xpad->xtype == XTYPE_XBOXONE) {
|
xpad->xtype == XTYPE_XBOXONE) {
|
||||||
for (i = 0; xpad360_btn[i] >= 0; i++)
|
for (i = 0; xpad360_btn[i] >= 0; i++)
|
||||||
input_set_capability(input_dev, EV_KEY, xpad360_btn[i]);
|
input_set_capability(input_dev, EV_KEY, xpad360_btn[i]);
|
||||||
|
if (xpad->mapping & MAP_SELECT_BUTTON)
|
||||||
|
input_set_capability(input_dev, EV_KEY, KEY_RECORD);
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; xpad_btn[i] >= 0; i++)
|
for (i = 0; xpad_btn[i] >= 0; i++)
|
||||||
input_set_capability(input_dev, EV_KEY, xpad_btn[i]);
|
input_set_capability(input_dev, EV_KEY, xpad_btn[i]);
|
||||||
|
|
|
@ -324,7 +324,7 @@ static ssize_t atkbd_show_function_row_physmap(struct atkbd *atkbd, char *buf)
|
||||||
static umode_t atkbd_attr_is_visible(struct kobject *kobj,
|
static umode_t atkbd_attr_is_visible(struct kobject *kobj,
|
||||||
struct attribute *attr, int i)
|
struct attribute *attr, int i)
|
||||||
{
|
{
|
||||||
struct device *dev = container_of(kobj, struct device, kobj);
|
struct device *dev = kobj_to_dev(kobj);
|
||||||
struct serio *serio = to_serio_port(dev);
|
struct serio *serio = to_serio_port(dev);
|
||||||
struct atkbd *atkbd = serio_get_drvdata(serio);
|
struct atkbd *atkbd = serio_get_drvdata(serio);
|
||||||
|
|
||||||
|
|
|
@ -644,7 +644,7 @@ static umode_t cros_ec_keyb_attr_is_visible(struct kobject *kobj,
|
||||||
struct attribute *attr,
|
struct attribute *attr,
|
||||||
int n)
|
int n)
|
||||||
{
|
{
|
||||||
struct device *dev = container_of(kobj, struct device, kobj);
|
struct device *dev = kobj_to_dev(kobj);
|
||||||
struct cros_ec_keyb *ckdev = dev_get_drvdata(dev);
|
struct cros_ec_keyb *ckdev = dev_get_drvdata(dev);
|
||||||
|
|
||||||
if (attr == &dev_attr_function_row_physmap.attr &&
|
if (attr == &dev_attr_function_row_physmap.attr &&
|
||||||
|
|
|
@ -512,6 +512,7 @@ static int hil_dev_connect(struct serio *serio, struct serio_driver *drv)
|
||||||
HIL_IDD_NUM_AXES_PER_SET(*idd)) {
|
HIL_IDD_NUM_AXES_PER_SET(*idd)) {
|
||||||
printk(KERN_INFO PREFIX
|
printk(KERN_INFO PREFIX
|
||||||
"combo devices are not supported.\n");
|
"combo devices are not supported.\n");
|
||||||
|
error = -EINVAL;
|
||||||
goto bail1;
|
goto bail1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -647,8 +647,8 @@ static int __ims_pcu_execute_command(struct ims_pcu *pcu,
|
||||||
#define IMS_PCU_BL_DATA_OFFSET 3
|
#define IMS_PCU_BL_DATA_OFFSET 3
|
||||||
|
|
||||||
static int __ims_pcu_execute_bl_command(struct ims_pcu *pcu,
|
static int __ims_pcu_execute_bl_command(struct ims_pcu *pcu,
|
||||||
u8 command, const void *data, size_t len,
|
u8 command, const void *data, size_t len,
|
||||||
u8 expected_response, int response_time)
|
u8 expected_response, int response_time)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
@ -1228,7 +1228,7 @@ static struct attribute *ims_pcu_attrs[] = {
|
||||||
static umode_t ims_pcu_is_attr_visible(struct kobject *kobj,
|
static umode_t ims_pcu_is_attr_visible(struct kobject *kobj,
|
||||||
struct attribute *attr, int n)
|
struct attribute *attr, int n)
|
||||||
{
|
{
|
||||||
struct device *dev = container_of(kobj, struct device, kobj);
|
struct device *dev = kobj_to_dev(kobj);
|
||||||
struct usb_interface *intf = to_usb_interface(dev);
|
struct usb_interface *intf = to_usb_interface(dev);
|
||||||
struct ims_pcu *pcu = usb_get_intfdata(intf);
|
struct ims_pcu *pcu = usb_get_intfdata(intf);
|
||||||
umode_t mode = attr->mode;
|
umode_t mode = attr->mode;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
|
* Copyright (c) 2010-2011, 2020-2021, The Linux Foundation. All rights reserved.
|
||||||
* Copyright (c) 2014, Sony Mobile Communications Inc.
|
* Copyright (c) 2014, Sony Mobile Communications Inc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -22,6 +22,8 @@
|
||||||
#define PON_RT_STS 0x10
|
#define PON_RT_STS 0x10
|
||||||
#define PON_KPDPWR_N_SET BIT(0)
|
#define PON_KPDPWR_N_SET BIT(0)
|
||||||
#define PON_RESIN_N_SET BIT(1)
|
#define PON_RESIN_N_SET BIT(1)
|
||||||
|
#define PON_GEN3_RESIN_N_SET BIT(6)
|
||||||
|
#define PON_GEN3_KPDPWR_N_SET BIT(7)
|
||||||
|
|
||||||
#define PON_PS_HOLD_RST_CTL 0x5a
|
#define PON_PS_HOLD_RST_CTL 0x5a
|
||||||
#define PON_PS_HOLD_RST_CTL2 0x5b
|
#define PON_PS_HOLD_RST_CTL2 0x5b
|
||||||
|
@ -38,8 +40,12 @@
|
||||||
#define PON_DBC_DELAY_MASK 0x7
|
#define PON_DBC_DELAY_MASK 0x7
|
||||||
|
|
||||||
struct pm8941_data {
|
struct pm8941_data {
|
||||||
unsigned int pull_up_bit;
|
unsigned int pull_up_bit;
|
||||||
unsigned int status_bit;
|
unsigned int status_bit;
|
||||||
|
bool supports_ps_hold_poff_config;
|
||||||
|
bool supports_debounce_config;
|
||||||
|
const char *name;
|
||||||
|
const char *phys;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pm8941_pwrkey {
|
struct pm8941_pwrkey {
|
||||||
|
@ -231,34 +237,40 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
input_set_capability(pwrkey->input, EV_KEY, pwrkey->code);
|
input_set_capability(pwrkey->input, EV_KEY, pwrkey->code);
|
||||||
|
|
||||||
pwrkey->input->name = "pm8941_pwrkey";
|
pwrkey->input->name = pwrkey->data->name;
|
||||||
pwrkey->input->phys = "pm8941_pwrkey/input0";
|
pwrkey->input->phys = pwrkey->data->phys;
|
||||||
|
|
||||||
req_delay = (req_delay << 6) / USEC_PER_SEC;
|
if (pwrkey->data->supports_debounce_config) {
|
||||||
req_delay = ilog2(req_delay);
|
req_delay = (req_delay << 6) / USEC_PER_SEC;
|
||||||
|
req_delay = ilog2(req_delay);
|
||||||
|
|
||||||
error = regmap_update_bits(pwrkey->regmap,
|
error = regmap_update_bits(pwrkey->regmap,
|
||||||
pwrkey->baseaddr + PON_DBC_CTL,
|
pwrkey->baseaddr + PON_DBC_CTL,
|
||||||
PON_DBC_DELAY_MASK,
|
PON_DBC_DELAY_MASK,
|
||||||
req_delay);
|
req_delay);
|
||||||
if (error) {
|
if (error) {
|
||||||
dev_err(&pdev->dev, "failed to set debounce: %d\n", error);
|
dev_err(&pdev->dev, "failed to set debounce: %d\n",
|
||||||
return error;
|
error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
error = regmap_update_bits(pwrkey->regmap,
|
if (pwrkey->data->pull_up_bit) {
|
||||||
pwrkey->baseaddr + PON_PULL_CTL,
|
error = regmap_update_bits(pwrkey->regmap,
|
||||||
pwrkey->data->pull_up_bit,
|
pwrkey->baseaddr + PON_PULL_CTL,
|
||||||
pull_up ? pwrkey->data->pull_up_bit : 0);
|
pwrkey->data->pull_up_bit,
|
||||||
if (error) {
|
pull_up ? pwrkey->data->pull_up_bit :
|
||||||
dev_err(&pdev->dev, "failed to set pull: %d\n", error);
|
0);
|
||||||
return error;
|
if (error) {
|
||||||
|
dev_err(&pdev->dev, "failed to set pull: %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
error = devm_request_threaded_irq(&pdev->dev, pwrkey->irq,
|
error = devm_request_threaded_irq(&pdev->dev, pwrkey->irq,
|
||||||
NULL, pm8941_pwrkey_irq,
|
NULL, pm8941_pwrkey_irq,
|
||||||
IRQF_ONESHOT,
|
IRQF_ONESHOT,
|
||||||
"pm8941_pwrkey", pwrkey);
|
pwrkey->data->name, pwrkey);
|
||||||
if (error) {
|
if (error) {
|
||||||
dev_err(&pdev->dev, "failed requesting IRQ: %d\n", error);
|
dev_err(&pdev->dev, "failed requesting IRQ: %d\n", error);
|
||||||
return error;
|
return error;
|
||||||
|
@ -271,12 +283,14 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev)
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
pwrkey->reboot_notifier.notifier_call = pm8941_reboot_notify,
|
if (pwrkey->data->supports_ps_hold_poff_config) {
|
||||||
error = register_reboot_notifier(&pwrkey->reboot_notifier);
|
pwrkey->reboot_notifier.notifier_call = pm8941_reboot_notify,
|
||||||
if (error) {
|
error = register_reboot_notifier(&pwrkey->reboot_notifier);
|
||||||
dev_err(&pdev->dev, "failed to register reboot notifier: %d\n",
|
if (error) {
|
||||||
error);
|
dev_err(&pdev->dev, "failed to register reboot notifier: %d\n",
|
||||||
return error;
|
error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
platform_set_drvdata(pdev, pwrkey);
|
platform_set_drvdata(pdev, pwrkey);
|
||||||
|
@ -289,7 +303,8 @@ static int pm8941_pwrkey_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct pm8941_pwrkey *pwrkey = platform_get_drvdata(pdev);
|
struct pm8941_pwrkey *pwrkey = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
unregister_reboot_notifier(&pwrkey->reboot_notifier);
|
if (pwrkey->data->supports_ps_hold_poff_config)
|
||||||
|
unregister_reboot_notifier(&pwrkey->reboot_notifier);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -297,16 +312,42 @@ static int pm8941_pwrkey_remove(struct platform_device *pdev)
|
||||||
static const struct pm8941_data pwrkey_data = {
|
static const struct pm8941_data pwrkey_data = {
|
||||||
.pull_up_bit = PON_KPDPWR_PULL_UP,
|
.pull_up_bit = PON_KPDPWR_PULL_UP,
|
||||||
.status_bit = PON_KPDPWR_N_SET,
|
.status_bit = PON_KPDPWR_N_SET,
|
||||||
|
.name = "pm8941_pwrkey",
|
||||||
|
.phys = "pm8941_pwrkey/input0",
|
||||||
|
.supports_ps_hold_poff_config = true,
|
||||||
|
.supports_debounce_config = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct pm8941_data resin_data = {
|
static const struct pm8941_data resin_data = {
|
||||||
.pull_up_bit = PON_RESIN_PULL_UP,
|
.pull_up_bit = PON_RESIN_PULL_UP,
|
||||||
.status_bit = PON_RESIN_N_SET,
|
.status_bit = PON_RESIN_N_SET,
|
||||||
|
.name = "pm8941_resin",
|
||||||
|
.phys = "pm8941_resin/input0",
|
||||||
|
.supports_ps_hold_poff_config = true,
|
||||||
|
.supports_debounce_config = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct pm8941_data pon_gen3_pwrkey_data = {
|
||||||
|
.status_bit = PON_GEN3_KPDPWR_N_SET,
|
||||||
|
.name = "pmic_pwrkey",
|
||||||
|
.phys = "pmic_pwrkey/input0",
|
||||||
|
.supports_ps_hold_poff_config = false,
|
||||||
|
.supports_debounce_config = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct pm8941_data pon_gen3_resin_data = {
|
||||||
|
.status_bit = PON_GEN3_RESIN_N_SET,
|
||||||
|
.name = "pmic_resin",
|
||||||
|
.phys = "pmic_resin/input0",
|
||||||
|
.supports_ps_hold_poff_config = false,
|
||||||
|
.supports_debounce_config = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct of_device_id pm8941_pwr_key_id_table[] = {
|
static const struct of_device_id pm8941_pwr_key_id_table[] = {
|
||||||
{ .compatible = "qcom,pm8941-pwrkey", .data = &pwrkey_data },
|
{ .compatible = "qcom,pm8941-pwrkey", .data = &pwrkey_data },
|
||||||
{ .compatible = "qcom,pm8941-resin", .data = &resin_data },
|
{ .compatible = "qcom,pm8941-resin", .data = &resin_data },
|
||||||
|
{ .compatible = "qcom,pmk8350-pwrkey", .data = &pon_gen3_pwrkey_data },
|
||||||
|
{ .compatible = "qcom,pmk8350-resin", .data = &pon_gen3_resin_data },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, pm8941_pwr_key_id_table);
|
MODULE_DEVICE_TABLE(of, pm8941_pwr_key_id_table);
|
||||||
|
|
|
@ -214,7 +214,7 @@ static bool trackpoint_is_attr_available(struct psmouse *psmouse,
|
||||||
static umode_t trackpoint_is_attr_visible(struct kobject *kobj,
|
static umode_t trackpoint_is_attr_visible(struct kobject *kobj,
|
||||||
struct attribute *attr, int n)
|
struct attribute *attr, int n)
|
||||||
{
|
{
|
||||||
struct device *dev = container_of(kobj, struct device, kobj);
|
struct device *dev = kobj_to_dev(kobj);
|
||||||
struct serio *serio = to_serio_port(dev);
|
struct serio *serio = to_serio_port(dev);
|
||||||
struct psmouse *psmouse = serio_get_drvdata(serio);
|
struct psmouse *psmouse = serio_get_drvdata(serio);
|
||||||
|
|
||||||
|
|
|
@ -139,7 +139,7 @@ static DEFINE_SPINLOCK(i8042_lock);
|
||||||
/*
|
/*
|
||||||
* Writers to AUX and KBD ports as well as users issuing i8042_command
|
* Writers to AUX and KBD ports as well as users issuing i8042_command
|
||||||
* directly should acquire i8042_mutex (by means of calling
|
* directly should acquire i8042_mutex (by means of calling
|
||||||
* i8042_lock_chip() and i8042_unlock_ship() helpers) to ensure that
|
* i8042_lock_chip() and i8042_unlock_chip() helpers) to ensure that
|
||||||
* they do not disturb each other (unfortunately in many i8042
|
* they do not disturb each other (unfortunately in many i8042
|
||||||
* implementations write to one of the ports will immediately abort
|
* implementations write to one of the ports will immediately abort
|
||||||
* command that is being processed by another port).
|
* command that is being processed by another port).
|
||||||
|
@ -979,7 +979,7 @@ static int i8042_controller_selftest(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* i8042_controller init initializes the i8042 controller, and,
|
* i8042_controller_init initializes the i8042 controller, and,
|
||||||
* most importantly, sets it into non-xlated mode if that's
|
* most importantly, sets it into non-xlated mode if that's
|
||||||
* desired.
|
* desired.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -7,15 +7,14 @@
|
||||||
* Some cleanups by Alan Cox <alan@linux.intel.com>
|
* Some cleanups by Alan Cox <alan@linux.intel.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/input.h>
|
|
||||||
#include <linux/slab.h>
|
|
||||||
#include <linux/interrupt.h>
|
|
||||||
#include <linux/io.h>
|
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/gpio.h>
|
#include <linux/input.h>
|
||||||
#include <linux/input/cy8ctmg110_pdata.h>
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/gpio/consumer.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <asm/byteorder.h>
|
||||||
|
|
||||||
#define CY8CTMG110_DRIVER_NAME "cy8ctmg110"
|
#define CY8CTMG110_DRIVER_NAME "cy8ctmg110"
|
||||||
|
|
||||||
|
@ -45,18 +44,18 @@ struct cy8ctmg110 {
|
||||||
struct input_dev *input;
|
struct input_dev *input;
|
||||||
char phys[32];
|
char phys[32];
|
||||||
struct i2c_client *client;
|
struct i2c_client *client;
|
||||||
int reset_pin;
|
struct gpio_desc *reset_gpio;
|
||||||
int irq_pin;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* cy8ctmg110_power is the routine that is called when touch hardware
|
* cy8ctmg110_power is the routine that is called when touch hardware
|
||||||
* will powered off or on.
|
* is being powered off or on. When powering on this routine de-asserts
|
||||||
|
* the RESET line, when powering off reset line is asserted.
|
||||||
*/
|
*/
|
||||||
static void cy8ctmg110_power(struct cy8ctmg110 *ts, bool poweron)
|
static void cy8ctmg110_power(struct cy8ctmg110 *ts, bool poweron)
|
||||||
{
|
{
|
||||||
if (ts->reset_pin)
|
if (ts->reset_gpio)
|
||||||
gpio_direction_output(ts->reset_pin, 1 - poweron);
|
gpiod_set_value_cansleep(ts->reset_gpio, !poweron);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cy8ctmg110_write_regs(struct cy8ctmg110 *tsc, unsigned char reg,
|
static int cy8ctmg110_write_regs(struct cy8ctmg110 *tsc, unsigned char reg,
|
||||||
|
@ -112,7 +111,6 @@ static int cy8ctmg110_touch_pos(struct cy8ctmg110 *tsc)
|
||||||
{
|
{
|
||||||
struct input_dev *input = tsc->input;
|
struct input_dev *input = tsc->input;
|
||||||
unsigned char reg_p[CY8CTMG110_REG_MAX];
|
unsigned char reg_p[CY8CTMG110_REG_MAX];
|
||||||
int x, y;
|
|
||||||
|
|
||||||
memset(reg_p, 0, CY8CTMG110_REG_MAX);
|
memset(reg_p, 0, CY8CTMG110_REG_MAX);
|
||||||
|
|
||||||
|
@ -120,16 +118,15 @@ static int cy8ctmg110_touch_pos(struct cy8ctmg110 *tsc)
|
||||||
if (cy8ctmg110_read_regs(tsc, reg_p, 9, CY8CTMG110_TOUCH_X1) != 0)
|
if (cy8ctmg110_read_regs(tsc, reg_p, 9, CY8CTMG110_TOUCH_X1) != 0)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
y = reg_p[2] << 8 | reg_p[3];
|
|
||||||
x = reg_p[0] << 8 | reg_p[1];
|
|
||||||
|
|
||||||
/* Number of touch */
|
/* Number of touch */
|
||||||
if (reg_p[8] == 0) {
|
if (reg_p[8] == 0) {
|
||||||
input_report_key(input, BTN_TOUCH, 0);
|
input_report_key(input, BTN_TOUCH, 0);
|
||||||
} else {
|
} else {
|
||||||
input_report_key(input, BTN_TOUCH, 1);
|
input_report_key(input, BTN_TOUCH, 1);
|
||||||
input_report_abs(input, ABS_X, x);
|
input_report_abs(input, ABS_X,
|
||||||
input_report_abs(input, ABS_Y, y);
|
be16_to_cpup((__be16 *)(reg_p + 0)));
|
||||||
|
input_report_abs(input, ABS_Y,
|
||||||
|
be16_to_cpup((__be16 *)(reg_p + 2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
input_sync(input);
|
input_sync(input);
|
||||||
|
@ -163,35 +160,35 @@ static irqreturn_t cy8ctmg110_irq_thread(int irq, void *dev_id)
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cy8ctmg110_shut_off(void *_ts)
|
||||||
|
{
|
||||||
|
struct cy8ctmg110 *ts = _ts;
|
||||||
|
|
||||||
|
cy8ctmg110_set_sleepmode(ts, true);
|
||||||
|
cy8ctmg110_power(ts, false);
|
||||||
|
}
|
||||||
|
|
||||||
static int cy8ctmg110_probe(struct i2c_client *client,
|
static int cy8ctmg110_probe(struct i2c_client *client,
|
||||||
const struct i2c_device_id *id)
|
const struct i2c_device_id *id)
|
||||||
{
|
{
|
||||||
const struct cy8ctmg110_pdata *pdata = dev_get_platdata(&client->dev);
|
|
||||||
struct cy8ctmg110 *ts;
|
struct cy8ctmg110 *ts;
|
||||||
struct input_dev *input_dev;
|
struct input_dev *input_dev;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* No pdata no way forward */
|
|
||||||
if (pdata == NULL) {
|
|
||||||
dev_err(&client->dev, "no pdata\n");
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!i2c_check_functionality(client->adapter,
|
if (!i2c_check_functionality(client->adapter,
|
||||||
I2C_FUNC_SMBUS_READ_WORD_DATA))
|
I2C_FUNC_SMBUS_READ_WORD_DATA))
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
ts = kzalloc(sizeof(struct cy8ctmg110), GFP_KERNEL);
|
ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL);
|
||||||
input_dev = input_allocate_device();
|
if (!ts)
|
||||||
if (!ts || !input_dev) {
|
return -ENOMEM;
|
||||||
err = -ENOMEM;
|
|
||||||
goto err_free_mem;
|
input_dev = devm_input_allocate_device(&client->dev);
|
||||||
}
|
if (!input_dev)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
ts->client = client;
|
ts->client = client;
|
||||||
ts->input = input_dev;
|
ts->input = input_dev;
|
||||||
ts->reset_pin = pdata->reset_pin;
|
|
||||||
ts->irq_pin = pdata->irq_pin;
|
|
||||||
|
|
||||||
snprintf(ts->phys, sizeof(ts->phys),
|
snprintf(ts->phys, sizeof(ts->phys),
|
||||||
"%s/input0", dev_name(&client->dev));
|
"%s/input0", dev_name(&client->dev));
|
||||||
|
@ -199,84 +196,46 @@ static int cy8ctmg110_probe(struct i2c_client *client,
|
||||||
input_dev->name = CY8CTMG110_DRIVER_NAME " Touchscreen";
|
input_dev->name = CY8CTMG110_DRIVER_NAME " Touchscreen";
|
||||||
input_dev->phys = ts->phys;
|
input_dev->phys = ts->phys;
|
||||||
input_dev->id.bustype = BUS_I2C;
|
input_dev->id.bustype = BUS_I2C;
|
||||||
input_dev->dev.parent = &client->dev;
|
|
||||||
|
|
||||||
input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
|
|
||||||
input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
|
|
||||||
|
|
||||||
|
input_set_capability(input_dev, EV_KEY, BTN_TOUCH);
|
||||||
input_set_abs_params(input_dev, ABS_X,
|
input_set_abs_params(input_dev, ABS_X,
|
||||||
CY8CTMG110_X_MIN, CY8CTMG110_X_MAX, 4, 0);
|
CY8CTMG110_X_MIN, CY8CTMG110_X_MAX, 4, 0);
|
||||||
input_set_abs_params(input_dev, ABS_Y,
|
input_set_abs_params(input_dev, ABS_Y,
|
||||||
CY8CTMG110_Y_MIN, CY8CTMG110_Y_MAX, 4, 0);
|
CY8CTMG110_Y_MIN, CY8CTMG110_Y_MAX, 4, 0);
|
||||||
|
|
||||||
if (ts->reset_pin) {
|
/* Request and assert reset line */
|
||||||
err = gpio_request(ts->reset_pin, NULL);
|
ts->reset_gpio = devm_gpiod_get_optional(&client->dev, NULL,
|
||||||
if (err) {
|
GPIOD_OUT_HIGH);
|
||||||
dev_err(&client->dev,
|
if (IS_ERR(ts->reset_gpio)) {
|
||||||
"Unable to request GPIO pin %d.\n",
|
err = PTR_ERR(ts->reset_gpio);
|
||||||
ts->reset_pin);
|
dev_err(&client->dev,
|
||||||
goto err_free_mem;
|
"Unable to request reset GPIO: %d\n", err);
|
||||||
}
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
cy8ctmg110_power(ts, true);
|
cy8ctmg110_power(ts, true);
|
||||||
cy8ctmg110_set_sleepmode(ts, false);
|
cy8ctmg110_set_sleepmode(ts, false);
|
||||||
|
|
||||||
err = gpio_request(ts->irq_pin, "touch_irq_key");
|
err = devm_add_action_or_reset(&client->dev, cy8ctmg110_shut_off, ts);
|
||||||
if (err < 0) {
|
if (err)
|
||||||
dev_err(&client->dev,
|
return err;
|
||||||
"Failed to request GPIO %d, error %d\n",
|
|
||||||
ts->irq_pin, err);
|
|
||||||
goto err_shutoff_device;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = gpio_direction_input(ts->irq_pin);
|
err = devm_request_threaded_irq(&client->dev, client->irq,
|
||||||
if (err < 0) {
|
NULL, cy8ctmg110_irq_thread,
|
||||||
dev_err(&client->dev,
|
IRQF_ONESHOT, "touch_reset_key", ts);
|
||||||
"Failed to configure input direction for GPIO %d, error %d\n",
|
if (err) {
|
||||||
ts->irq_pin, err);
|
|
||||||
goto err_free_irq_gpio;
|
|
||||||
}
|
|
||||||
|
|
||||||
client->irq = gpio_to_irq(ts->irq_pin);
|
|
||||||
if (client->irq < 0) {
|
|
||||||
err = client->irq;
|
|
||||||
dev_err(&client->dev,
|
|
||||||
"Unable to get irq number for GPIO %d, error %d\n",
|
|
||||||
ts->irq_pin, err);
|
|
||||||
goto err_free_irq_gpio;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = request_threaded_irq(client->irq, NULL, cy8ctmg110_irq_thread,
|
|
||||||
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
|
|
||||||
"touch_reset_key", ts);
|
|
||||||
if (err < 0) {
|
|
||||||
dev_err(&client->dev,
|
dev_err(&client->dev,
|
||||||
"irq %d busy? error %d\n", client->irq, err);
|
"irq %d busy? error %d\n", client->irq, err);
|
||||||
goto err_free_irq_gpio;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = input_register_device(input_dev);
|
err = input_register_device(input_dev);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_free_irq;
|
return err;
|
||||||
|
|
||||||
i2c_set_clientdata(client, ts);
|
i2c_set_clientdata(client, ts);
|
||||||
device_init_wakeup(&client->dev, 1);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err_free_irq:
|
return 0;
|
||||||
free_irq(client->irq, ts);
|
|
||||||
err_free_irq_gpio:
|
|
||||||
gpio_free(ts->irq_pin);
|
|
||||||
err_shutoff_device:
|
|
||||||
cy8ctmg110_set_sleepmode(ts, true);
|
|
||||||
cy8ctmg110_power(ts, false);
|
|
||||||
if (ts->reset_pin)
|
|
||||||
gpio_free(ts->reset_pin);
|
|
||||||
err_free_mem:
|
|
||||||
input_free_device(input_dev);
|
|
||||||
kfree(ts);
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __maybe_unused cy8ctmg110_suspend(struct device *dev)
|
static int __maybe_unused cy8ctmg110_suspend(struct device *dev)
|
||||||
|
@ -284,12 +243,11 @@ static int __maybe_unused cy8ctmg110_suspend(struct device *dev)
|
||||||
struct i2c_client *client = to_i2c_client(dev);
|
struct i2c_client *client = to_i2c_client(dev);
|
||||||
struct cy8ctmg110 *ts = i2c_get_clientdata(client);
|
struct cy8ctmg110 *ts = i2c_get_clientdata(client);
|
||||||
|
|
||||||
if (device_may_wakeup(&client->dev))
|
if (!device_may_wakeup(&client->dev)) {
|
||||||
enable_irq_wake(client->irq);
|
|
||||||
else {
|
|
||||||
cy8ctmg110_set_sleepmode(ts, true);
|
cy8ctmg110_set_sleepmode(ts, true);
|
||||||
cy8ctmg110_power(ts, false);
|
cy8ctmg110_power(ts, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,34 +256,16 @@ static int __maybe_unused cy8ctmg110_resume(struct device *dev)
|
||||||
struct i2c_client *client = to_i2c_client(dev);
|
struct i2c_client *client = to_i2c_client(dev);
|
||||||
struct cy8ctmg110 *ts = i2c_get_clientdata(client);
|
struct cy8ctmg110 *ts = i2c_get_clientdata(client);
|
||||||
|
|
||||||
if (device_may_wakeup(&client->dev))
|
if (!device_may_wakeup(&client->dev)) {
|
||||||
disable_irq_wake(client->irq);
|
|
||||||
else {
|
|
||||||
cy8ctmg110_power(ts, true);
|
cy8ctmg110_power(ts, true);
|
||||||
cy8ctmg110_set_sleepmode(ts, false);
|
cy8ctmg110_set_sleepmode(ts, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SIMPLE_DEV_PM_OPS(cy8ctmg110_pm, cy8ctmg110_suspend, cy8ctmg110_resume);
|
static SIMPLE_DEV_PM_OPS(cy8ctmg110_pm, cy8ctmg110_suspend, cy8ctmg110_resume);
|
||||||
|
|
||||||
static int cy8ctmg110_remove(struct i2c_client *client)
|
|
||||||
{
|
|
||||||
struct cy8ctmg110 *ts = i2c_get_clientdata(client);
|
|
||||||
|
|
||||||
cy8ctmg110_set_sleepmode(ts, true);
|
|
||||||
cy8ctmg110_power(ts, false);
|
|
||||||
|
|
||||||
free_irq(client->irq, ts);
|
|
||||||
input_unregister_device(ts->input);
|
|
||||||
gpio_free(ts->irq_pin);
|
|
||||||
if (ts->reset_pin)
|
|
||||||
gpio_free(ts->reset_pin);
|
|
||||||
kfree(ts);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct i2c_device_id cy8ctmg110_idtable[] = {
|
static const struct i2c_device_id cy8ctmg110_idtable[] = {
|
||||||
{ CY8CTMG110_DRIVER_NAME, 1 },
|
{ CY8CTMG110_DRIVER_NAME, 1 },
|
||||||
{ }
|
{ }
|
||||||
|
@ -340,7 +280,6 @@ static struct i2c_driver cy8ctmg110_driver = {
|
||||||
},
|
},
|
||||||
.id_table = cy8ctmg110_idtable,
|
.id_table = cy8ctmg110_idtable,
|
||||||
.probe = cy8ctmg110_probe,
|
.probe = cy8ctmg110_probe,
|
||||||
.remove = cy8ctmg110_remove,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module_i2c_driver(cy8ctmg110_driver);
|
module_i2c_driver(cy8ctmg110_driver);
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/property.h>
|
#include <linux/property.h>
|
||||||
#include <linux/gpio/consumer.h>
|
#include <linux/gpio/consumer.h>
|
||||||
|
#include <linux/regulator/consumer.h>
|
||||||
|
|
||||||
#include "cyttsp_core.h"
|
#include "cyttsp_core.h"
|
||||||
|
|
||||||
|
@ -45,8 +46,15 @@
|
||||||
#define CY_MAXZ 255
|
#define CY_MAXZ 255
|
||||||
#define CY_DELAY_DFLT 20 /* ms */
|
#define CY_DELAY_DFLT 20 /* ms */
|
||||||
#define CY_DELAY_MAX 500
|
#define CY_DELAY_MAX 500
|
||||||
#define CY_ACT_DIST_DFLT 0xF8
|
/* Active distance in pixels for a gesture to be reported */
|
||||||
|
#define CY_ACT_DIST_DFLT 0xF8 /* pixels */
|
||||||
#define CY_ACT_DIST_MASK 0x0F
|
#define CY_ACT_DIST_MASK 0x0F
|
||||||
|
/* Active Power state scanning/processing refresh interval */
|
||||||
|
#define CY_ACT_INTRVL_DFLT 0x00 /* ms */
|
||||||
|
/* Low Power state scanning/processing refresh interval */
|
||||||
|
#define CY_LP_INTRVL_DFLT 0x0A /* ms */
|
||||||
|
/* touch timeout for the Active power */
|
||||||
|
#define CY_TCH_TMOUT_DFLT 0xFF /* ms */
|
||||||
#define CY_HNDSHK_BIT 0x80
|
#define CY_HNDSHK_BIT 0x80
|
||||||
/* device mode bits */
|
/* device mode bits */
|
||||||
#define CY_OPERATE_MODE 0x00
|
#define CY_OPERATE_MODE 0x00
|
||||||
|
@ -608,6 +616,14 @@ static int cyttsp_parse_properties(struct cyttsp *ts)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cyttsp_disable_regulators(void *_ts)
|
||||||
|
{
|
||||||
|
struct cyttsp *ts = _ts;
|
||||||
|
|
||||||
|
regulator_bulk_disable(ARRAY_SIZE(ts->regulators),
|
||||||
|
ts->regulators);
|
||||||
|
}
|
||||||
|
|
||||||
struct cyttsp *cyttsp_probe(const struct cyttsp_bus_ops *bus_ops,
|
struct cyttsp *cyttsp_probe(const struct cyttsp_bus_ops *bus_ops,
|
||||||
struct device *dev, int irq, size_t xfer_buf_size)
|
struct device *dev, int irq, size_t xfer_buf_size)
|
||||||
{
|
{
|
||||||
|
@ -628,6 +644,32 @@ struct cyttsp *cyttsp_probe(const struct cyttsp_bus_ops *bus_ops,
|
||||||
ts->bus_ops = bus_ops;
|
ts->bus_ops = bus_ops;
|
||||||
ts->irq = irq;
|
ts->irq = irq;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VCPIN is the analog voltage supply
|
||||||
|
* VDD is the digital voltage supply
|
||||||
|
*/
|
||||||
|
ts->regulators[0].supply = "vcpin";
|
||||||
|
ts->regulators[1].supply = "vdd";
|
||||||
|
error = devm_regulator_bulk_get(dev, ARRAY_SIZE(ts->regulators),
|
||||||
|
ts->regulators);
|
||||||
|
if (error) {
|
||||||
|
dev_err(dev, "Failed to get regulators: %d\n", error);
|
||||||
|
return ERR_PTR(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
error = regulator_bulk_enable(ARRAY_SIZE(ts->regulators),
|
||||||
|
ts->regulators);
|
||||||
|
if (error) {
|
||||||
|
dev_err(dev, "Cannot enable regulators: %d\n", error);
|
||||||
|
return ERR_PTR(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
error = devm_add_action_or_reset(dev, cyttsp_disable_regulators, ts);
|
||||||
|
if (error) {
|
||||||
|
dev_err(dev, "failed to install chip disable handler\n");
|
||||||
|
return ERR_PTR(error);
|
||||||
|
}
|
||||||
|
|
||||||
ts->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
|
ts->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
|
||||||
if (IS_ERR(ts->reset_gpio)) {
|
if (IS_ERR(ts->reset_gpio)) {
|
||||||
error = PTR_ERR(ts->reset_gpio);
|
error = PTR_ERR(ts->reset_gpio);
|
||||||
|
@ -664,8 +706,7 @@ struct cyttsp *cyttsp_probe(const struct cyttsp_bus_ops *bus_ops,
|
||||||
}
|
}
|
||||||
|
|
||||||
error = devm_request_threaded_irq(dev, ts->irq, NULL, cyttsp_irq,
|
error = devm_request_threaded_irq(dev, ts->irq, NULL, cyttsp_irq,
|
||||||
IRQF_TRIGGER_FALLING | IRQF_ONESHOT |
|
IRQF_ONESHOT | IRQF_NO_AUTOEN,
|
||||||
IRQF_NO_AUTOEN,
|
|
||||||
"cyttsp", ts);
|
"cyttsp", ts);
|
||||||
if (error) {
|
if (error) {
|
||||||
dev_err(ts->dev, "failed to request IRQ %d, err: %d\n",
|
dev_err(ts->dev, "failed to request IRQ %d, err: %d\n",
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/input/cyttsp.h>
|
#include <linux/regulator/consumer.h>
|
||||||
|
|
||||||
#define CY_NUM_RETRY 16 /* max number of retries for read ops */
|
#define CY_NUM_RETRY 16 /* max number of retries for read ops */
|
||||||
|
|
||||||
|
@ -122,6 +122,7 @@ struct cyttsp {
|
||||||
enum cyttsp_state state;
|
enum cyttsp_state state;
|
||||||
bool suspended;
|
bool suspended;
|
||||||
|
|
||||||
|
struct regulator_bulk_data regulators[2];
|
||||||
struct gpio_desc *reset_gpio;
|
struct gpio_desc *reset_gpio;
|
||||||
bool use_hndshk;
|
bool use_hndshk;
|
||||||
u8 act_dist;
|
u8 act_dist;
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
|
|
||||||
|
#define CY_I2C_NAME "cyttsp-i2c"
|
||||||
|
|
||||||
#define CY_I2C_DATA_SIZE 128
|
#define CY_I2C_DATA_SIZE 128
|
||||||
|
|
||||||
static const struct cyttsp_bus_ops cyttsp_i2c_bus_ops = {
|
static const struct cyttsp_bus_ops cyttsp_i2c_bus_ops = {
|
||||||
|
@ -52,10 +54,18 @@ static const struct i2c_device_id cyttsp_i2c_id[] = {
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(i2c, cyttsp_i2c_id);
|
MODULE_DEVICE_TABLE(i2c, cyttsp_i2c_id);
|
||||||
|
|
||||||
|
static const struct of_device_id cyttsp_of_i2c_match[] = {
|
||||||
|
{ .compatible = "cypress,cy8ctma340", },
|
||||||
|
{ .compatible = "cypress,cy8ctst341", },
|
||||||
|
{ /* sentinel */ }
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, cyttsp_of_i2c_match);
|
||||||
|
|
||||||
static struct i2c_driver cyttsp_i2c_driver = {
|
static struct i2c_driver cyttsp_i2c_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = CY_I2C_NAME,
|
.name = CY_I2C_NAME,
|
||||||
.pm = &cyttsp_pm_ops,
|
.pm = &cyttsp_pm_ops,
|
||||||
|
.of_match_table = cyttsp_of_i2c_match,
|
||||||
},
|
},
|
||||||
.probe = cyttsp_i2c_probe,
|
.probe = cyttsp_i2c_probe,
|
||||||
.id_table = cyttsp_i2c_id,
|
.id_table = cyttsp_i2c_id,
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
#include <linux/spi/spi.h>
|
#include <linux/spi/spi.h>
|
||||||
|
|
||||||
|
#define CY_SPI_NAME "cyttsp-spi"
|
||||||
|
|
||||||
#define CY_SPI_WR_OP 0x00 /* r/~w */
|
#define CY_SPI_WR_OP 0x00 /* r/~w */
|
||||||
#define CY_SPI_RD_OP 0x01
|
#define CY_SPI_RD_OP 0x01
|
||||||
#define CY_SPI_CMD_BYTES 4
|
#define CY_SPI_CMD_BYTES 4
|
||||||
|
@ -160,10 +162,18 @@ static int cyttsp_spi_probe(struct spi_device *spi)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct of_device_id cyttsp_of_spi_match[] = {
|
||||||
|
{ .compatible = "cypress,cy8ctma340", },
|
||||||
|
{ .compatible = "cypress,cy8ctst341", },
|
||||||
|
{ /* sentinel */ }
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, cyttsp_of_spi_match);
|
||||||
|
|
||||||
static struct spi_driver cyttsp_spi_driver = {
|
static struct spi_driver cyttsp_spi_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = CY_SPI_NAME,
|
.name = CY_SPI_NAME,
|
||||||
.pm = &cyttsp_pm_ops,
|
.pm = &cyttsp_pm_ops,
|
||||||
|
.of_match_table = cyttsp_of_spi_match,
|
||||||
},
|
},
|
||||||
.probe = cyttsp_spi_probe,
|
.probe = cyttsp_spi_probe,
|
||||||
};
|
};
|
||||||
|
|
|
@ -104,6 +104,7 @@ struct edt_ft5x06_ts_data {
|
||||||
u16 num_x;
|
u16 num_x;
|
||||||
u16 num_y;
|
u16 num_y;
|
||||||
struct regulator *vcc;
|
struct regulator *vcc;
|
||||||
|
struct regulator *iovcc;
|
||||||
|
|
||||||
struct gpio_desc *reset_gpio;
|
struct gpio_desc *reset_gpio;
|
||||||
struct gpio_desc *wake_gpio;
|
struct gpio_desc *wake_gpio;
|
||||||
|
@ -1062,11 +1063,12 @@ static void edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void edt_ft5x06_disable_regulator(void *arg)
|
static void edt_ft5x06_disable_regulators(void *arg)
|
||||||
{
|
{
|
||||||
struct edt_ft5x06_ts_data *data = arg;
|
struct edt_ft5x06_ts_data *data = arg;
|
||||||
|
|
||||||
regulator_disable(data->vcc);
|
regulator_disable(data->vcc);
|
||||||
|
regulator_disable(data->iovcc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int edt_ft5x06_ts_probe(struct i2c_client *client,
|
static int edt_ft5x06_ts_probe(struct i2c_client *client,
|
||||||
|
@ -1107,14 +1109,33 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tsdata->iovcc = devm_regulator_get(&client->dev, "iovcc");
|
||||||
|
if (IS_ERR(tsdata->iovcc)) {
|
||||||
|
error = PTR_ERR(tsdata->iovcc);
|
||||||
|
if (error != -EPROBE_DEFER)
|
||||||
|
dev_err(&client->dev,
|
||||||
|
"failed to request iovcc regulator: %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = regulator_enable(tsdata->iovcc);
|
||||||
|
if (error < 0) {
|
||||||
|
dev_err(&client->dev, "failed to enable iovcc: %d\n", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Delay enabling VCC for > 10us (T_ivd) after IOVCC */
|
||||||
|
usleep_range(10, 100);
|
||||||
|
|
||||||
error = regulator_enable(tsdata->vcc);
|
error = regulator_enable(tsdata->vcc);
|
||||||
if (error < 0) {
|
if (error < 0) {
|
||||||
dev_err(&client->dev, "failed to enable vcc: %d\n", error);
|
dev_err(&client->dev, "failed to enable vcc: %d\n", error);
|
||||||
|
regulator_disable(tsdata->iovcc);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = devm_add_action_or_reset(&client->dev,
|
error = devm_add_action_or_reset(&client->dev,
|
||||||
edt_ft5x06_disable_regulator,
|
edt_ft5x06_disable_regulators,
|
||||||
tsdata);
|
tsdata);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
@ -1289,6 +1310,9 @@ static int __maybe_unused edt_ft5x06_ts_suspend(struct device *dev)
|
||||||
ret = regulator_disable(tsdata->vcc);
|
ret = regulator_disable(tsdata->vcc);
|
||||||
if (ret)
|
if (ret)
|
||||||
dev_warn(dev, "Failed to disable vcc\n");
|
dev_warn(dev, "Failed to disable vcc\n");
|
||||||
|
ret = regulator_disable(tsdata->iovcc);
|
||||||
|
if (ret)
|
||||||
|
dev_warn(dev, "Failed to disable iovcc\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1319,9 +1343,19 @@ static int __maybe_unused edt_ft5x06_ts_resume(struct device *dev)
|
||||||
gpiod_set_value_cansleep(reset_gpio, 1);
|
gpiod_set_value_cansleep(reset_gpio, 1);
|
||||||
usleep_range(5000, 6000);
|
usleep_range(5000, 6000);
|
||||||
|
|
||||||
|
ret = regulator_enable(tsdata->iovcc);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(dev, "Failed to enable iovcc\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Delay enabling VCC for > 10us (T_ivd) after IOVCC */
|
||||||
|
usleep_range(10, 100);
|
||||||
|
|
||||||
ret = regulator_enable(tsdata->vcc);
|
ret = regulator_enable(tsdata->vcc);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(dev, "Failed to enable vcc\n");
|
dev_err(dev, "Failed to enable vcc\n");
|
||||||
|
regulator_disable(tsdata->iovcc);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1369,8 +1369,7 @@ static bool elants_acpi_is_hid_device(struct device *dev)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int elants_i2c_probe(struct i2c_client *client,
|
static int elants_i2c_probe(struct i2c_client *client)
|
||||||
const struct i2c_device_id *id)
|
|
||||||
{
|
{
|
||||||
union i2c_smbus_data dummy;
|
union i2c_smbus_data dummy;
|
||||||
struct elants_data *ts;
|
struct elants_data *ts;
|
||||||
|
@ -1396,7 +1395,7 @@ static int elants_i2c_probe(struct i2c_client *client,
|
||||||
init_completion(&ts->cmd_done);
|
init_completion(&ts->cmd_done);
|
||||||
|
|
||||||
ts->client = client;
|
ts->client = client;
|
||||||
ts->chip_id = (enum elants_chip_id)id->driver_data;
|
ts->chip_id = (enum elants_chip_id)(uintptr_t)device_get_match_data(&client->dev);
|
||||||
i2c_set_clientdata(client, ts);
|
i2c_set_clientdata(client, ts);
|
||||||
|
|
||||||
ts->vcc33 = devm_regulator_get(&client->dev, "vcc33");
|
ts->vcc33 = devm_regulator_get(&client->dev, "vcc33");
|
||||||
|
@ -1636,15 +1635,15 @@ MODULE_DEVICE_TABLE(acpi, elants_acpi_id);
|
||||||
|
|
||||||
#ifdef CONFIG_OF
|
#ifdef CONFIG_OF
|
||||||
static const struct of_device_id elants_of_match[] = {
|
static const struct of_device_id elants_of_match[] = {
|
||||||
{ .compatible = "elan,ekth3500" },
|
{ .compatible = "elan,ekth3500", .data = (void *)EKTH3500 },
|
||||||
{ .compatible = "elan,ektf3624" },
|
{ .compatible = "elan,ektf3624", .data = (void *)EKTF3624 },
|
||||||
{ /* sentinel */ }
|
{ /* sentinel */ }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, elants_of_match);
|
MODULE_DEVICE_TABLE(of, elants_of_match);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static struct i2c_driver elants_i2c_driver = {
|
static struct i2c_driver elants_i2c_driver = {
|
||||||
.probe = elants_i2c_probe,
|
.probe_new = elants_i2c_probe,
|
||||||
.id_table = elants_i2c_id,
|
.id_table = elants_i2c_id,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = DEVICE_NAME,
|
.name = DEVICE_NAME,
|
||||||
|
|
|
@ -361,13 +361,16 @@ static int hideep_enter_pgm(struct hideep_ts *ts)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hideep_nvm_unlock(struct hideep_ts *ts)
|
static int hideep_nvm_unlock(struct hideep_ts *ts)
|
||||||
{
|
{
|
||||||
u32 unmask_code;
|
u32 unmask_code;
|
||||||
|
int error;
|
||||||
|
|
||||||
hideep_pgm_w_reg(ts, HIDEEP_FLASH_CFG, HIDEEP_NVM_SFR_RPAGE);
|
hideep_pgm_w_reg(ts, HIDEEP_FLASH_CFG, HIDEEP_NVM_SFR_RPAGE);
|
||||||
hideep_pgm_r_reg(ts, 0x0000000C, &unmask_code);
|
error = hideep_pgm_r_reg(ts, 0x0000000C, &unmask_code);
|
||||||
hideep_pgm_w_reg(ts, HIDEEP_FLASH_CFG, HIDEEP_NVM_DEFAULT_PAGE);
|
hideep_pgm_w_reg(ts, HIDEEP_FLASH_CFG, HIDEEP_NVM_DEFAULT_PAGE);
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
|
||||||
/* make it unprotected code */
|
/* make it unprotected code */
|
||||||
unmask_code &= ~HIDEEP_PROT_MODE;
|
unmask_code &= ~HIDEEP_PROT_MODE;
|
||||||
|
@ -384,6 +387,8 @@ static void hideep_nvm_unlock(struct hideep_ts *ts)
|
||||||
NVM_W_SFR(HIDEEP_NVM_MASK_OFS, ts->nvm_mask);
|
NVM_W_SFR(HIDEEP_NVM_MASK_OFS, ts->nvm_mask);
|
||||||
SET_FLASH_HWCONTROL();
|
SET_FLASH_HWCONTROL();
|
||||||
hideep_pgm_w_reg(ts, HIDEEP_FLASH_CFG, HIDEEP_NVM_DEFAULT_PAGE);
|
hideep_pgm_w_reg(ts, HIDEEP_FLASH_CFG, HIDEEP_NVM_DEFAULT_PAGE);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hideep_check_status(struct hideep_ts *ts)
|
static int hideep_check_status(struct hideep_ts *ts)
|
||||||
|
@ -462,7 +467,9 @@ static int hideep_program_nvm(struct hideep_ts *ts,
|
||||||
u32 addr = 0;
|
u32 addr = 0;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
hideep_nvm_unlock(ts);
|
error = hideep_nvm_unlock(ts);
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
|
||||||
while (ucode_len > 0) {
|
while (ucode_len > 0) {
|
||||||
xfer_len = min_t(size_t, ucode_len, HIDEEP_NVM_PAGE_SIZE);
|
xfer_len = min_t(size_t, ucode_len, HIDEEP_NVM_PAGE_SIZE);
|
||||||
|
|
|
@ -13,44 +13,78 @@
|
||||||
#include <linux/input/touchscreen.h>
|
#include <linux/input/touchscreen.h>
|
||||||
#include <linux/iio/consumer.h>
|
#include <linux/iio/consumer.h>
|
||||||
#include <linux/iio/iio.h>
|
#include <linux/iio/iio.h>
|
||||||
|
#include <linux/mod_devicetable.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/of.h>
|
|
||||||
#include <linux/of_device.h>
|
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/property.h>
|
||||||
|
|
||||||
#define DRIVER_NAME "resistive-adc-touch"
|
#define DRIVER_NAME "resistive-adc-touch"
|
||||||
#define GRTS_DEFAULT_PRESSURE_MIN 50000
|
#define GRTS_DEFAULT_PRESSURE_MIN 50000
|
||||||
|
#define GRTS_DEFAULT_PRESSURE_MAX 65535
|
||||||
#define GRTS_MAX_POS_MASK GENMASK(11, 0)
|
#define GRTS_MAX_POS_MASK GENMASK(11, 0)
|
||||||
|
#define GRTS_MAX_CHANNELS 4
|
||||||
|
|
||||||
|
enum grts_ch_type {
|
||||||
|
GRTS_CH_X,
|
||||||
|
GRTS_CH_Y,
|
||||||
|
GRTS_CH_PRESSURE,
|
||||||
|
GRTS_CH_Z1,
|
||||||
|
GRTS_CH_Z2,
|
||||||
|
GRTS_CH_MAX = GRTS_CH_Z2 + 1
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct grts_state - generic resistive touch screen information struct
|
* struct grts_state - generic resistive touch screen information struct
|
||||||
|
* @x_plate_ohms: resistance of the X plate
|
||||||
* @pressure_min: number representing the minimum for the pressure
|
* @pressure_min: number representing the minimum for the pressure
|
||||||
* @pressure: are we getting pressure info or not
|
* @pressure: are we getting pressure info or not
|
||||||
* @iio_chans: list of channels acquired
|
* @iio_chans: list of channels acquired
|
||||||
* @iio_cb: iio_callback buffer for the data
|
* @iio_cb: iio_callback buffer for the data
|
||||||
* @input: the input device structure that we register
|
* @input: the input device structure that we register
|
||||||
* @prop: touchscreen properties struct
|
* @prop: touchscreen properties struct
|
||||||
|
* @ch_map: map of channels that are defined for the touchscreen
|
||||||
*/
|
*/
|
||||||
struct grts_state {
|
struct grts_state {
|
||||||
|
u32 x_plate_ohms;
|
||||||
u32 pressure_min;
|
u32 pressure_min;
|
||||||
bool pressure;
|
bool pressure;
|
||||||
struct iio_channel *iio_chans;
|
struct iio_channel *iio_chans;
|
||||||
struct iio_cb_buffer *iio_cb;
|
struct iio_cb_buffer *iio_cb;
|
||||||
struct input_dev *input;
|
struct input_dev *input;
|
||||||
struct touchscreen_properties prop;
|
struct touchscreen_properties prop;
|
||||||
|
u8 ch_map[GRTS_CH_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
static int grts_cb(const void *data, void *private)
|
static int grts_cb(const void *data, void *private)
|
||||||
{
|
{
|
||||||
const u16 *touch_info = data;
|
const u16 *touch_info = data;
|
||||||
struct grts_state *st = private;
|
struct grts_state *st = private;
|
||||||
unsigned int x, y, press = 0x0;
|
unsigned int x, y, press = 0;
|
||||||
|
|
||||||
/* channel data coming in buffer in the order below */
|
x = touch_info[st->ch_map[GRTS_CH_X]];
|
||||||
x = touch_info[0];
|
y = touch_info[st->ch_map[GRTS_CH_Y]];
|
||||||
y = touch_info[1];
|
|
||||||
if (st->pressure)
|
if (st->ch_map[GRTS_CH_PRESSURE] < GRTS_MAX_CHANNELS) {
|
||||||
press = touch_info[2];
|
press = touch_info[st->ch_map[GRTS_CH_PRESSURE]];
|
||||||
|
} else if (st->ch_map[GRTS_CH_Z1] < GRTS_MAX_CHANNELS) {
|
||||||
|
unsigned int z1 = touch_info[st->ch_map[GRTS_CH_Z1]];
|
||||||
|
unsigned int z2 = touch_info[st->ch_map[GRTS_CH_Z2]];
|
||||||
|
unsigned int Rt;
|
||||||
|
|
||||||
|
Rt = z2;
|
||||||
|
Rt -= z1;
|
||||||
|
Rt *= st->x_plate_ohms;
|
||||||
|
Rt = DIV_ROUND_CLOSEST(Rt, 16);
|
||||||
|
Rt *= x;
|
||||||
|
Rt /= z1;
|
||||||
|
Rt = DIV_ROUND_CLOSEST(Rt, 256);
|
||||||
|
/*
|
||||||
|
* On increased pressure the resistance (Rt) is decreasing
|
||||||
|
* so, convert values to make it looks as real pressure.
|
||||||
|
*/
|
||||||
|
if (Rt < GRTS_DEFAULT_PRESSURE_MAX)
|
||||||
|
press = GRTS_DEFAULT_PRESSURE_MAX - Rt;
|
||||||
|
}
|
||||||
|
|
||||||
if ((!x && !y) || (st->pressure && (press < st->pressure_min))) {
|
if ((!x && !y) || (st->pressure && (press < st->pressure_min))) {
|
||||||
/* report end of touch */
|
/* report end of touch */
|
||||||
|
@ -94,12 +128,77 @@ static void grts_disable(void *data)
|
||||||
iio_channel_release_all_cb(data);
|
iio_channel_release_all_cb(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int grts_map_channel(struct grts_state *st, struct device *dev,
|
||||||
|
enum grts_ch_type type, const char *name,
|
||||||
|
bool optional)
|
||||||
|
{
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
idx = device_property_match_string(dev, "io-channel-names", name);
|
||||||
|
if (idx < 0) {
|
||||||
|
if (!optional)
|
||||||
|
return idx;
|
||||||
|
idx = GRTS_MAX_CHANNELS;
|
||||||
|
} else if (idx >= GRTS_MAX_CHANNELS) {
|
||||||
|
return -EOVERFLOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
st->ch_map[type] = idx;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int grts_get_properties(struct grts_state *st, struct device *dev)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
|
||||||
|
error = grts_map_channel(st, dev, GRTS_CH_X, "x", false);
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
error = grts_map_channel(st, dev, GRTS_CH_Y, "y", false);
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
/* pressure is optional */
|
||||||
|
error = grts_map_channel(st, dev, GRTS_CH_PRESSURE, "pressure", true);
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
if (st->ch_map[GRTS_CH_PRESSURE] < GRTS_MAX_CHANNELS) {
|
||||||
|
st->pressure = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if no pressure is defined, try optional z1 + z2 */
|
||||||
|
error = grts_map_channel(st, dev, GRTS_CH_Z1, "z1", true);
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
if (st->ch_map[GRTS_CH_Z1] >= GRTS_MAX_CHANNELS)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* if z1 is provided z2 is not optional */
|
||||||
|
error = grts_map_channel(st, dev, GRTS_CH_Z2, "z2", true);
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
error = device_property_read_u32(dev,
|
||||||
|
"touchscreen-x-plate-ohms",
|
||||||
|
&st->x_plate_ohms);
|
||||||
|
if (error) {
|
||||||
|
dev_err(dev, "can't get touchscreen-x-plate-ohms property\n");
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
st->pressure = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int grts_probe(struct platform_device *pdev)
|
static int grts_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct grts_state *st;
|
struct grts_state *st;
|
||||||
struct input_dev *input;
|
struct input_dev *input;
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct iio_channel *chan;
|
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
st = devm_kzalloc(dev, sizeof(struct grts_state), GFP_KERNEL);
|
st = devm_kzalloc(dev, sizeof(struct grts_state), GFP_KERNEL);
|
||||||
|
@ -115,12 +214,13 @@ static int grts_probe(struct platform_device *pdev)
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
chan = &st->iio_chans[0];
|
if (!device_property_present(dev, "io-channel-names"))
|
||||||
st->pressure = false;
|
return -ENODEV;
|
||||||
while (chan && chan->indio_dev) {
|
|
||||||
if (!strcmp(chan->channel->datasheet_name, "pressure"))
|
error = grts_get_properties(st, dev);
|
||||||
st->pressure = true;
|
if (error) {
|
||||||
chan++;
|
dev_err(dev, "Failed to parse properties\n");
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (st->pressure) {
|
if (st->pressure) {
|
||||||
|
@ -148,7 +248,7 @@ static int grts_probe(struct platform_device *pdev)
|
||||||
input_set_abs_params(input, ABS_Y, 0, GRTS_MAX_POS_MASK - 1, 0, 0);
|
input_set_abs_params(input, ABS_Y, 0, GRTS_MAX_POS_MASK - 1, 0, 0);
|
||||||
if (st->pressure)
|
if (st->pressure)
|
||||||
input_set_abs_params(input, ABS_PRESSURE, st->pressure_min,
|
input_set_abs_params(input, ABS_PRESSURE, st->pressure_min,
|
||||||
0xffff, 0, 0);
|
GRTS_DEFAULT_PRESSURE_MAX, 0, 0);
|
||||||
|
|
||||||
input_set_capability(input, EV_KEY, BTN_TOUCH);
|
input_set_capability(input, EV_KEY, BTN_TOUCH);
|
||||||
|
|
||||||
|
@ -193,7 +293,7 @@ static struct platform_driver grts_driver = {
|
||||||
.probe = grts_probe,
|
.probe = grts_probe,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = DRIVER_NAME,
|
.name = DRIVER_NAME,
|
||||||
.of_match_table = of_match_ptr(grts_of_match),
|
.of_match_table = grts_of_match,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -338,7 +338,7 @@ static struct attribute *tsc200x_attrs[] = {
|
||||||
static umode_t tsc200x_attr_is_visible(struct kobject *kobj,
|
static umode_t tsc200x_attr_is_visible(struct kobject *kobj,
|
||||||
struct attribute *attr, int n)
|
struct attribute *attr, int n)
|
||||||
{
|
{
|
||||||
struct device *dev = container_of(kobj, struct device, kobj);
|
struct device *dev = kobj_to_dev(kobj);
|
||||||
struct tsc200x *ts = dev_get_drvdata(dev);
|
struct tsc200x *ts = dev_get_drvdata(dev);
|
||||||
umode_t mode = attr->mode;
|
umode_t mode = attr->mode;
|
||||||
|
|
||||||
|
|
|
@ -251,7 +251,7 @@ static int e2i_init(struct usbtouch_usb *usbtouch)
|
||||||
int ret;
|
int ret;
|
||||||
struct usb_device *udev = interface_to_usbdev(usbtouch->interface);
|
struct usb_device *udev = interface_to_usbdev(usbtouch->interface);
|
||||||
|
|
||||||
ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
|
ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||||
0x01, 0x02, 0x0000, 0x0081,
|
0x01, 0x02, 0x0000, 0x0081,
|
||||||
NULL, 0, USB_CTRL_SET_TIMEOUT);
|
NULL, 0, USB_CTRL_SET_TIMEOUT);
|
||||||
|
|
||||||
|
@ -531,7 +531,7 @@ static int mtouch_init(struct usbtouch_usb *usbtouch)
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
|
ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||||
MTOUCHUSB_RESET,
|
MTOUCHUSB_RESET,
|
||||||
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||||
1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
|
1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
|
||||||
|
@ -543,7 +543,7 @@ static int mtouch_init(struct usbtouch_usb *usbtouch)
|
||||||
msleep(150);
|
msleep(150);
|
||||||
|
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
|
ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||||
MTOUCHUSB_ASYNC_REPORT,
|
MTOUCHUSB_ASYNC_REPORT,
|
||||||
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||||
1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT);
|
1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT);
|
||||||
|
@ -722,7 +722,7 @@ static int dmc_tsc10_init(struct usbtouch_usb *usbtouch)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* start sending data */
|
/* start sending data */
|
||||||
ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0),
|
ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
|
||||||
TSC10_CMD_DATA1,
|
TSC10_CMD_DATA1,
|
||||||
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||||
0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
|
0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
struct cy8ctmg110_pdata
|
struct cy8ctmg110_pdata
|
||||||
{
|
{
|
||||||
int reset_pin; /* Reset pin is wired to this GPIO (optional) */
|
int reset_pin; /* Reset pin is wired to this GPIO (optional) */
|
||||||
int irq_pin; /* IRQ pin is wired to this GPIO */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
||||||
/*
|
|
||||||
* Header file for:
|
|
||||||
* Cypress TrueTouch(TM) Standard Product (TTSP) touchscreen drivers.
|
|
||||||
* For use with Cypress Txx3xx parts.
|
|
||||||
* Supported parts include:
|
|
||||||
* CY8CTST341
|
|
||||||
* CY8CTMA340
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009, 2010, 2011 Cypress Semiconductor, Inc.
|
|
||||||
* Copyright (C) 2012 Javier Martinez Canillas <javier@dowhile0.org>
|
|
||||||
*
|
|
||||||
* Contact Cypress Semiconductor at www.cypress.com (kev@cypress.com)
|
|
||||||
*/
|
|
||||||
#ifndef _CYTTSP_H_
|
|
||||||
#define _CYTTSP_H_
|
|
||||||
|
|
||||||
#define CY_SPI_NAME "cyttsp-spi"
|
|
||||||
#define CY_I2C_NAME "cyttsp-i2c"
|
|
||||||
/* Active Power state scanning/processing refresh interval */
|
|
||||||
#define CY_ACT_INTRVL_DFLT 0x00 /* ms */
|
|
||||||
/* touch timeout for the Active power */
|
|
||||||
#define CY_TCH_TMOUT_DFLT 0xFF /* ms */
|
|
||||||
/* Low Power state scanning/processing refresh interval */
|
|
||||||
#define CY_LP_INTRVL_DFLT 0x0A /* ms */
|
|
||||||
/* Active distance in pixels for a gesture to be reported */
|
|
||||||
#define CY_ACT_DIST_DFLT 0xF8 /* pixels */
|
|
||||||
|
|
||||||
#endif /* _CYTTSP_H_ */
|
|
Loading…
Add table
Reference in a new issue