Input updates for 5.20 (6.0) merge window:
- changes to input core to properly queue synthetic events (such as autorepeat) and to release multitouch contacts when an input device is inhibited or suspended - reworked quirk handling in i8042 driver that consolidates multiple DMI tables into one and adds several quirks for TUXEDO line of laptops - update to mt6779 keypad to better reflect organization of the hardware - changes to mtk-pmic-keys driver preparing it to handle more variants - facelift of adp5588-keys driver - improvements to iqs7222 driver - adjustments to various DT binding documents for input devices - other assorted driver fixes. -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQST2eWILY88ieB2DOtAj56VGEWXnAUCYvFsGAAKCRBAj56VGEWX nMI6AQDQUwQpKtmCoDmxLTi/8Oy7qq0j9Sn8FNyWOaFykK3iTAD/eJNsY+PSn+M2 bPzg1bduYK/eqZkomMaL2dAytHpr9AM= =XmKz -----END PGP SIGNATURE----- Merge tag 'input-for-v5.20-rc0' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input Pull input updates from Dmitry Torokhov: - changes to input core to properly queue synthetic events (such as autorepeat) and to release multitouch contacts when an input device is inhibited or suspended - reworked quirk handling in i8042 driver that consolidates multiple DMI tables into one and adds several quirks for TUXEDO line of laptops - update to mt6779 keypad to better reflect organization of the hardware - changes to mtk-pmic-keys driver preparing it to handle more variants - facelift of adp5588-keys driver - improvements to iqs7222 driver - adjustments to various DT binding documents for input devices - other assorted driver fixes. * tag 'input-for-v5.20-rc0' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (54 commits) Input: adc-joystick - fix ordering in adc_joystick_probe() dt-bindings: input: ariel-pwrbutton: use spi-peripheral-props.yaml Input: deactivate MT slots when inhibiting or suspending devices Input: properly queue synthetic events dt-bindings: input: iqs7222: Use central 'linux,code' definition Input: i8042 - add dritek quirk for Acer Aspire One AO532 dt-bindings: input: gpio-keys: accept also interrupt-extended dt-bindings: input: gpio-keys: reference input.yaml and document properties dt-bindings: input: gpio-keys: enforce node names to match all properties dt-bindings: input: Convert adc-keys to DT schema dt-bindings: input: Centralize 'linux,input-type' definition dt-bindings: input: Use common 'linux,keycodes' definition dt-bindings: input: Centralize 'linux,code' definition dt-bindings: input: Increase maximum keycode value to 0x2ff Input: mt6779-keypad - implement row/column selection Input: mt6779-keypad - match hardware matrix organization Input: i8042 - add additional TUXEDO devices to i8042 quirk tables Input: goodix - switch use of acpi_gpio_get_*_resource() APIs Input: i8042 - add TUXEDO devices to i8042 quirk tables Input: i8042 - add debug output for quirks ...
This commit is contained in:
commit
2ae08b36c0
|
@ -45,6 +45,7 @@ additionalProperties: false
|
|||
patternProperties:
|
||||
"^axis@[0-9a-f]+$":
|
||||
type: object
|
||||
$ref: input.yaml#
|
||||
description: >
|
||||
Represents a joystick axis bound to the given ADC channel.
|
||||
For each entry in the io-channels list, one axis subnode with a matching
|
||||
|
@ -57,7 +58,6 @@ patternProperties:
|
|||
description: Index of an io-channels list entry bound to this axis.
|
||||
|
||||
linux,code:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: EV_ABS specific event code generated by the axis.
|
||||
|
||||
abs-range:
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
ADC attached resistor ladder buttons
|
||||
------------------------------------
|
||||
|
||||
Required properties:
|
||||
- compatible: "adc-keys"
|
||||
- io-channels: Phandle to an ADC channel
|
||||
- io-channel-names = "buttons";
|
||||
- keyup-threshold-microvolt: Voltage above or equal to which all the keys are
|
||||
considered up.
|
||||
|
||||
Optional properties:
|
||||
- poll-interval: Poll interval time in milliseconds
|
||||
- autorepeat: Boolean, Enable auto repeat feature of Linux input
|
||||
subsystem.
|
||||
|
||||
Each button (key) is represented as a sub-node of "adc-keys":
|
||||
|
||||
Required subnode-properties:
|
||||
- label: Descriptive name of the key.
|
||||
- linux,code: Keycode to emit.
|
||||
- press-threshold-microvolt: voltage above or equal to which this key is
|
||||
considered pressed.
|
||||
|
||||
No two values of press-threshold-microvolt may be the same.
|
||||
All values of press-threshold-microvolt must be less than
|
||||
keyup-threshold-microvolt.
|
||||
|
||||
Example:
|
||||
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
adc-keys {
|
||||
compatible = "adc-keys";
|
||||
io-channels = <&lradc 0>;
|
||||
io-channel-names = "buttons";
|
||||
keyup-threshold-microvolt = <2000000>;
|
||||
|
||||
button-up {
|
||||
label = "Volume Up";
|
||||
linux,code = <KEY_VOLUMEUP>;
|
||||
press-threshold-microvolt = <1500000>;
|
||||
};
|
||||
|
||||
button-down {
|
||||
label = "Volume Down";
|
||||
linux,code = <KEY_VOLUMEDOWN>;
|
||||
press-threshold-microvolt = <1000000>;
|
||||
};
|
||||
|
||||
button-enter {
|
||||
label = "Enter";
|
||||
linux,code = <KEY_ENTER>;
|
||||
press-threshold-microvolt = <500000>;
|
||||
};
|
||||
};
|
||||
|
||||
+--------------------------------+------------------------+
|
||||
| 2.000.000 <= value | no key pressed |
|
||||
+--------------------------------+------------------------+
|
||||
| 1.500.000 <= value < 2.000.000 | KEY_VOLUMEUP pressed |
|
||||
+--------------------------------+------------------------+
|
||||
| 1.000.000 <= value < 1.500.000 | KEY_VOLUMEDOWN pressed |
|
||||
+--------------------------------+------------------------+
|
||||
| 500.000 <= value < 1.000.000 | KEY_ENTER pressed |
|
||||
+--------------------------------+------------------------+
|
||||
| value < 500.000 | no key pressed |
|
||||
+--------------------------------+------------------------+
|
|
@ -0,0 +1,103 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/input/adc-keys.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: ADC attached resistor ladder buttons
|
||||
|
||||
maintainers:
|
||||
- Alexandre Belloni <alexandre.belloni@bootlin.com>
|
||||
|
||||
allOf:
|
||||
- $ref: input.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: adc-keys
|
||||
|
||||
io-channels:
|
||||
maxItems: 1
|
||||
|
||||
io-channel-names:
|
||||
const: buttons
|
||||
|
||||
keyup-threshold-microvolt:
|
||||
description:
|
||||
Voltage above or equal to which all the keys are considered up.
|
||||
|
||||
poll-interval: true
|
||||
autorepeat: true
|
||||
|
||||
patternProperties:
|
||||
'^button-':
|
||||
type: object
|
||||
$ref: input.yaml#
|
||||
additionalProperties: false
|
||||
description:
|
||||
Each button (key) is represented as a sub-node.
|
||||
|
||||
properties:
|
||||
label: true
|
||||
|
||||
linux,code: true
|
||||
|
||||
press-threshold-microvolt:
|
||||
description:
|
||||
Voltage above or equal to which this key is considered pressed. No
|
||||
two values of press-threshold-microvolt may be the same. All values
|
||||
of press-threshold-microvolt must be less than
|
||||
keyup-threshold-microvolt.
|
||||
|
||||
required:
|
||||
- linux,code
|
||||
- press-threshold-microvolt
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- io-channels
|
||||
- io-channel-names
|
||||
- keyup-threshold-microvolt
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/input/input.h>
|
||||
// +--------------------------------+------------------------+
|
||||
// | 2.000.000 <= value | no key pressed |
|
||||
// +--------------------------------+------------------------+
|
||||
// | 1.500.000 <= value < 2.000.000 | KEY_VOLUMEUP pressed |
|
||||
// +--------------------------------+------------------------+
|
||||
// | 1.000.000 <= value < 1.500.000 | KEY_VOLUMEDOWN pressed |
|
||||
// +--------------------------------+------------------------+
|
||||
// | 500.000 <= value < 1.000.000 | KEY_ENTER pressed |
|
||||
// +--------------------------------+------------------------+
|
||||
// | value < 500.000 | no key pressed |
|
||||
// +--------------------------------+------------------------+
|
||||
|
||||
adc-keys {
|
||||
compatible = "adc-keys";
|
||||
io-channels = <&lradc 0>;
|
||||
io-channel-names = "buttons";
|
||||
keyup-threshold-microvolt = <2000000>;
|
||||
|
||||
button-up {
|
||||
label = "Volume Up";
|
||||
linux,code = <KEY_VOLUMEUP>;
|
||||
press-threshold-microvolt = <1500000>;
|
||||
};
|
||||
|
||||
button-down {
|
||||
label = "Volume Down";
|
||||
linux,code = <KEY_VOLUMEDOWN>;
|
||||
press-threshold-microvolt = <1000000>;
|
||||
};
|
||||
|
||||
button-enter {
|
||||
label = "Enter";
|
||||
linux,code = <KEY_ENTER>;
|
||||
press-threshold-microvolt = <500000>;
|
||||
};
|
||||
};
|
||||
...
|
|
@ -44,14 +44,13 @@ properties:
|
|||
patternProperties:
|
||||
"^button-[0-9]+$":
|
||||
type: object
|
||||
$ref: input.yaml#
|
||||
properties:
|
||||
label:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description: Descriptive name of the key
|
||||
|
||||
linux,code:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Keycode to emit
|
||||
linux,code: true
|
||||
|
||||
channel:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
|
|
@ -17,6 +17,7 @@ description: |
|
|||
|
||||
allOf:
|
||||
- $ref: input.yaml#
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
|
|
|
@ -37,10 +37,6 @@ properties:
|
|||
device is temporarily held in hardware reset prior to initialization if
|
||||
this property is present.
|
||||
|
||||
azoteq,rf-filt-enable:
|
||||
type: boolean
|
||||
description: Enables the device's internal RF filter.
|
||||
|
||||
azoteq,max-counts:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1, 2, 3]
|
||||
|
@ -421,6 +417,7 @@ patternProperties:
|
|||
patternProperties:
|
||||
"^event-(prox|touch)$":
|
||||
type: object
|
||||
$ref: input.yaml#
|
||||
description:
|
||||
Represents a proximity or touch event reported by the channel.
|
||||
|
||||
|
@ -467,14 +464,9 @@ patternProperties:
|
|||
The IQS7222B does not feature channel-specific timeouts; the time-
|
||||
out specified for any one channel applies to all channels.
|
||||
|
||||
linux,code:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
Numeric key or switch code associated with the event. Specify
|
||||
KEY_RESERVED (0) to opt out of event reporting.
|
||||
linux,code: true
|
||||
|
||||
linux,input-type:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [1, 5]
|
||||
default: 1
|
||||
description:
|
||||
|
@ -537,9 +529,8 @@ patternProperties:
|
|||
|
||||
azoteq,bottom-speed:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
multipleOf: 4
|
||||
minimum: 0
|
||||
maximum: 1020
|
||||
maximum: 255
|
||||
description:
|
||||
Specifies the speed of movement after which coordinate filtering is
|
||||
linearly reduced.
|
||||
|
@ -575,14 +566,13 @@ patternProperties:
|
|||
patternProperties:
|
||||
"^event-(press|tap|(swipe|flick)-(pos|neg))$":
|
||||
type: object
|
||||
$ref: input.yaml#
|
||||
description:
|
||||
Represents a press or gesture (IQS7222A only) event reported by
|
||||
the slider.
|
||||
|
||||
properties:
|
||||
linux,code:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Numeric key code associated with the event.
|
||||
linux,code: true
|
||||
|
||||
azoteq,gesture-max-ms:
|
||||
multipleOf: 4
|
||||
|
@ -616,16 +606,15 @@ patternProperties:
|
|||
azoteq,gpio-select:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 1
|
||||
maxItems: 3
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 0
|
||||
maximum: 2
|
||||
description: |
|
||||
Specifies an individual GPIO mapped to a tap, swipe or flick
|
||||
gesture as follows:
|
||||
Specifies one or more GPIO mapped to the event as follows:
|
||||
0: GPIO0
|
||||
1: GPIO3 (reserved)
|
||||
2: GPIO4 (reserved)
|
||||
1: GPIO3 (IQS7222C only)
|
||||
2: GPIO4 (IQS7222C only)
|
||||
|
||||
Note that although multiple events can be mapped to a single
|
||||
GPIO, they must all be of the same type (proximity, touch or
|
||||
|
@ -710,6 +699,14 @@ allOf:
|
|||
multipleOf: 4
|
||||
maximum: 1020
|
||||
|
||||
patternProperties:
|
||||
"^event-(press|tap|(swipe|flick)-(pos|neg))$":
|
||||
properties:
|
||||
azoteq,gpio-select:
|
||||
maxItems: 1
|
||||
items:
|
||||
maximum: 0
|
||||
|
||||
else:
|
||||
patternProperties:
|
||||
"^channel-([0-9]|1[0-9])$":
|
||||
|
@ -726,8 +723,6 @@ allOf:
|
|||
|
||||
azoteq,gesture-dist: false
|
||||
|
||||
azoteq,gpio-select: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
|
|
@ -57,7 +57,7 @@ examples:
|
|||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mpr121@5a {
|
||||
touchkey@5a {
|
||||
compatible = "fsl,mpr121-touchkey";
|
||||
reg = <0x5a>;
|
||||
interrupt-parent = <&gpio1>;
|
||||
|
@ -77,7 +77,7 @@ examples:
|
|||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mpr121@5a {
|
||||
touchkey@5a {
|
||||
compatible = "fsl,mpr121-touchkey";
|
||||
reg = <0x5a>;
|
||||
poll-interval = <20>;
|
||||
|
|
|
@ -15,107 +15,106 @@ properties:
|
|||
- gpio-keys
|
||||
- gpio-keys-polled
|
||||
|
||||
autorepeat: true
|
||||
|
||||
label:
|
||||
description: Name of entire device
|
||||
|
||||
poll-interval: true
|
||||
|
||||
patternProperties:
|
||||
".*":
|
||||
if:
|
||||
type: object
|
||||
then:
|
||||
$ref: input.yaml#
|
||||
"^(button|event|key|switch|(button|event|key|switch)-[a-z0-9-]+|[a-z0-9-]+-(button|event|key|switch))$":
|
||||
$ref: input.yaml#
|
||||
|
||||
properties:
|
||||
gpios:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
label:
|
||||
description: Descriptive name of the key.
|
||||
|
||||
linux,code:
|
||||
description: Key / Axis code to emit.
|
||||
|
||||
linux,input-type:
|
||||
default: 1 # EV_KEY
|
||||
|
||||
linux,input-value:
|
||||
description: |
|
||||
If linux,input-type is EV_ABS or EV_REL then this
|
||||
value is sent for events this button generates when pressed.
|
||||
EV_ABS/EV_REL axis will generate an event with a value of 0
|
||||
when all buttons with linux,input-type == type and
|
||||
linux,code == axis are released. This value is interpreted
|
||||
as a signed 32 bit value, e.g. to make a button generate a
|
||||
value of -1 use:
|
||||
|
||||
linux,input-value = <0xffffffff>; /* -1 */
|
||||
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
||||
debounce-interval:
|
||||
description:
|
||||
Debouncing interval time in milliseconds. If not specified defaults to 5.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
||||
default: 5
|
||||
|
||||
wakeup-source:
|
||||
description: Button can wake-up the system.
|
||||
|
||||
wakeup-event-action:
|
||||
description: |
|
||||
Specifies whether the key should wake the system when asserted, when
|
||||
deasserted, or both. This property is only valid for keys that wake up the
|
||||
system (e.g., when the "wakeup-source" property is also provided).
|
||||
|
||||
Supported values are defined in linux-event-codes.h:
|
||||
|
||||
EV_ACT_ANY - both asserted and deasserted
|
||||
EV_ACT_ASSERTED - asserted
|
||||
EV_ACT_DEASSERTED - deasserted
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1, 2]
|
||||
|
||||
linux,can-disable:
|
||||
description:
|
||||
Indicates that button is connected to dedicated (not shared) interrupt
|
||||
which can be disabled to suppress events from the button.
|
||||
type: boolean
|
||||
|
||||
required:
|
||||
- linux,code
|
||||
|
||||
anyOf:
|
||||
- required:
|
||||
- interrupts
|
||||
- required:
|
||||
- interrupts-extended
|
||||
- required:
|
||||
- gpios
|
||||
|
||||
dependencies:
|
||||
wakeup-event-action: [ wakeup-source ]
|
||||
linux,input-value: [ gpios ]
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
allOf:
|
||||
- $ref: input.yaml#
|
||||
- if:
|
||||
properties:
|
||||
gpios:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
label:
|
||||
description: Descriptive name of the key.
|
||||
|
||||
linux,code:
|
||||
description: Key / Axis code to emit.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
||||
linux,input-type:
|
||||
description:
|
||||
Specify event type this button/key generates. If not specified defaults to
|
||||
<1> == EV_KEY.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
||||
default: 1
|
||||
|
||||
linux,input-value:
|
||||
description: |
|
||||
If linux,input-type is EV_ABS or EV_REL then this
|
||||
value is sent for events this button generates when pressed.
|
||||
EV_ABS/EV_REL axis will generate an event with a value of 0
|
||||
when all buttons with linux,input-type == type and
|
||||
linux,code == axis are released. This value is interpreted
|
||||
as a signed 32 bit value, e.g. to make a button generate a
|
||||
value of -1 use:
|
||||
|
||||
linux,input-value = <0xffffffff>; /* -1 */
|
||||
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
||||
debounce-interval:
|
||||
description:
|
||||
Debouncing interval time in milliseconds. If not specified defaults to 5.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
||||
default: 5
|
||||
|
||||
wakeup-source:
|
||||
description: Button can wake-up the system.
|
||||
|
||||
wakeup-event-action:
|
||||
description: |
|
||||
Specifies whether the key should wake the system when asserted, when
|
||||
deasserted, or both. This property is only valid for keys that wake up the
|
||||
system (e.g., when the "wakeup-source" property is also provided).
|
||||
|
||||
Supported values are defined in linux-event-codes.h:
|
||||
|
||||
EV_ACT_ANY - both asserted and deasserted
|
||||
EV_ACT_ASSERTED - asserted
|
||||
EV_ACT_DEASSERTED - deasserted
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1, 2]
|
||||
|
||||
linux,can-disable:
|
||||
description:
|
||||
Indicates that button is connected to dedicated (not shared) interrupt
|
||||
which can be disabled to suppress events from the button.
|
||||
type: boolean
|
||||
|
||||
compatible:
|
||||
const: gpio-keys-polled
|
||||
then:
|
||||
required:
|
||||
- linux,code
|
||||
|
||||
anyOf:
|
||||
- required:
|
||||
- interrupts
|
||||
- required:
|
||||
- gpios
|
||||
|
||||
dependencies:
|
||||
wakeup-event-action: [ wakeup-source ]
|
||||
linux,input-value: [ gpios ]
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
if:
|
||||
properties:
|
||||
compatible:
|
||||
const: gpio-keys-polled
|
||||
then:
|
||||
properties:
|
||||
poll-interval:
|
||||
description:
|
||||
Poll interval time in milliseconds
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
||||
required:
|
||||
- poll-interval
|
||||
- poll-interval
|
||||
else:
|
||||
properties:
|
||||
poll-interval: false
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
|
@ -127,13 +126,13 @@ examples:
|
|||
compatible = "gpio-keys";
|
||||
autorepeat;
|
||||
|
||||
up {
|
||||
key-up {
|
||||
label = "GPIO Key UP";
|
||||
linux,code = <103>;
|
||||
gpios = <&gpio1 0 1>;
|
||||
};
|
||||
|
||||
down {
|
||||
key-down {
|
||||
label = "GPIO Key DOWN";
|
||||
linux,code = <108>;
|
||||
interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
|
||||
|
|
|
@ -21,7 +21,26 @@ properties:
|
|||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 0xff
|
||||
maximum: 0x2ff
|
||||
|
||||
linux,code:
|
||||
description:
|
||||
Specifies a single numeric keycode value to be used for reporting
|
||||
button/switch events. Specify KEY_RESERVED (0) to opt out of event
|
||||
reporting.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
maximum: 0x2ff
|
||||
|
||||
linux,input-type:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum:
|
||||
- 1 # EV_KEY
|
||||
- 2 # EV_REL
|
||||
- 3 # EV_ABS
|
||||
- 5 # EV_SW
|
||||
description:
|
||||
Specifies whether the event is to be interpreted as a key, relative,
|
||||
absolute, or switch.
|
||||
|
||||
poll-interval:
|
||||
description: Poll interval time in milliseconds.
|
||||
|
@ -39,4 +58,7 @@ properties:
|
|||
reset automatically. Device with key pressed reset feature can specify
|
||||
this property.
|
||||
|
||||
dependencies:
|
||||
linux,input-type: [ "linux,code" ]
|
||||
|
||||
additionalProperties: true
|
||||
|
|
|
@ -370,6 +370,7 @@ patternProperties:
|
|||
patternProperties:
|
||||
"^event-prox(-alt)?$":
|
||||
type: object
|
||||
$ref: input.yaml#
|
||||
description:
|
||||
Represents a proximity event reported by the channel in response to
|
||||
a decrease in counts. Node names suffixed with '-alt' instead corre-
|
||||
|
@ -396,14 +397,13 @@ patternProperties:
|
|||
default: 10
|
||||
description: Specifies the threshold for the event.
|
||||
|
||||
linux,code:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Numeric key or switch code associated with the event.
|
||||
linux,code: true
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
"^event-touch(-alt)?$":
|
||||
type: object
|
||||
$ref: input.yaml#
|
||||
description: Represents a touch event reported by the channel.
|
||||
|
||||
properties:
|
||||
|
@ -421,14 +421,13 @@ patternProperties:
|
|||
default: 4
|
||||
description: Specifies the hysteresis for the event.
|
||||
|
||||
linux,code:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Numeric key or switch code associated with the event.
|
||||
linux,code: true
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
"^event-deep(-alt)?$":
|
||||
type: object
|
||||
$ref: input.yaml#
|
||||
description: Represents a deep-touch event reported by the channel.
|
||||
|
||||
properties:
|
||||
|
@ -446,9 +445,7 @@ patternProperties:
|
|||
default: 0
|
||||
description: Specifies the hysteresis for the event.
|
||||
|
||||
linux,code:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Numeric key or switch code associated with the event.
|
||||
linux,code: true
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
|
@ -475,7 +472,7 @@ examples:
|
|||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
iqs269a@44 {
|
||||
touch@44 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
|
|
|
@ -449,6 +449,7 @@ patternProperties:
|
|||
patternProperties:
|
||||
"^event-(prox|touch|deep)(-alt)?$":
|
||||
type: object
|
||||
$ref: input.yaml#
|
||||
description:
|
||||
Represents a proximity, touch or deep-touch event reported by the
|
||||
channel in response to a decrease in counts. Node names suffixed with
|
||||
|
@ -487,21 +488,15 @@ patternProperties:
|
|||
Specifies the hysteresis for the event (touch and deep-touch
|
||||
events only).
|
||||
|
||||
linux,code:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Numeric key or switch code associated with the event.
|
||||
linux,code: true
|
||||
|
||||
linux,input-type:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [1, 5]
|
||||
description:
|
||||
Specifies whether the event is to be interpreted as a key (1) or
|
||||
a switch (5). By default, Hall-channel events are interpreted as
|
||||
switches and all others are interpreted as keys.
|
||||
|
||||
dependencies:
|
||||
linux,input-type: ["linux,code"]
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
dependencies:
|
||||
|
@ -511,6 +506,7 @@ patternProperties:
|
|||
|
||||
"^trackpad-3x[2-3]$":
|
||||
type: object
|
||||
$ref: input.yaml#
|
||||
description:
|
||||
Represents all channels associated with the trackpad. The channels are
|
||||
collectively active if the trackpad is defined and inactive otherwise.
|
||||
|
@ -679,7 +675,6 @@ patternProperties:
|
|||
Specifies the raw count filter strength during low-power mode.
|
||||
|
||||
linux,keycodes:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 6
|
||||
description: |
|
||||
|
@ -751,7 +746,7 @@ examples:
|
|||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
iqs626a@44 {
|
||||
touch@44 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
|
|
|
@ -9,6 +9,9 @@ title: Azoteq IQS620A/621/622/624/625 Keys and Switches
|
|||
maintainers:
|
||||
- Jeff LaBundy <jeff@labundy.com>
|
||||
|
||||
allOf:
|
||||
- $ref: input.yaml#
|
||||
|
||||
description: |
|
||||
The Azoteq IQS620A, IQS621, IQS622, IQS624 and IQS625 multi-function sensors
|
||||
feature a variety of self-capacitive, mutual-inductive and Hall-effect sens-
|
||||
|
@ -30,7 +33,6 @@ properties:
|
|||
- azoteq,iqs625-keys
|
||||
|
||||
linux,keycodes:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 16
|
||||
description: |
|
||||
|
@ -89,15 +91,14 @@ properties:
|
|||
patternProperties:
|
||||
"^hall-switch-(north|south)$":
|
||||
type: object
|
||||
$ref: input.yaml#
|
||||
description:
|
||||
Represents north/south-field Hall-effect sensor touch or proximity
|
||||
events. Note that north/south-field orientation is reversed on the
|
||||
IQS620AXzCSR device due to its flip-chip package.
|
||||
|
||||
properties:
|
||||
linux,code:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Numeric switch code associated with the event.
|
||||
linux,code: true
|
||||
|
||||
azoteq,use-prox:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
|
|
|
@ -16,15 +16,15 @@ description: |
|
|||
The onkey controller is represented as a sub-node of the PMIC node on
|
||||
the device tree.
|
||||
|
||||
allOf:
|
||||
- $ref: input.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: maxim,max77650-onkey
|
||||
|
||||
linux,code:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
The key-code to be reported when the key is pressed. Defaults
|
||||
to KEY_POWER.
|
||||
default: 116 # KEY_POWER
|
||||
|
||||
maxim,onkey-slide:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
|
|
|
@ -112,7 +112,7 @@ examples:
|
|||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cap1188@28 {
|
||||
touch@28 {
|
||||
compatible = "microchip,cap1188";
|
||||
interrupt-parent = <&gpio1>;
|
||||
interrupts = <0 0>;
|
||||
|
|
|
@ -85,6 +85,14 @@ properties:
|
|||
minimum: 0
|
||||
maximum: 80
|
||||
|
||||
report-rate-hz:
|
||||
description: |
|
||||
Allows setting the scan rate in Hertz.
|
||||
M06 supports range from 30 to 140 Hz.
|
||||
M12 supports range from 1 to 255 Hz.
|
||||
minimum: 1
|
||||
maximum: 255
|
||||
|
||||
touchscreen-size-x: true
|
||||
touchscreen-size-y: true
|
||||
touchscreen-fuzz-x: true
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
#ifndef _INPUT_CORE_PRIVATE_H
|
||||
#define _INPUT_CORE_PRIVATE_H
|
||||
|
||||
/*
|
||||
* Functions and definitions that are private to input core,
|
||||
* should not be used by input drivers or handlers.
|
||||
*/
|
||||
|
||||
struct input_dev;
|
||||
|
||||
void input_mt_release_slots(struct input_dev *dev);
|
||||
void input_handle_event(struct input_dev *dev,
|
||||
unsigned int type, unsigned int code, int value);
|
||||
|
||||
#endif /* _INPUT_CORE_PRIVATE_H */
|
|
@ -8,6 +8,7 @@
|
|||
#include <linux/input/mt.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/slab.h>
|
||||
#include "input-core-private.h"
|
||||
|
||||
#define TRKID_SGN ((TRKID_MAX + 1) >> 1)
|
||||
|
||||
|
@ -259,10 +260,13 @@ static void __input_mt_drop_unused(struct input_dev *dev, struct input_mt *mt)
|
|||
{
|
||||
int i;
|
||||
|
||||
lockdep_assert_held(&dev->event_lock);
|
||||
|
||||
for (i = 0; i < mt->num_slots; i++) {
|
||||
if (!input_mt_is_used(mt, &mt->slots[i])) {
|
||||
input_mt_slot(dev, i);
|
||||
input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1);
|
||||
if (input_mt_is_active(&mt->slots[i]) &&
|
||||
!input_mt_is_used(mt, &mt->slots[i])) {
|
||||
input_handle_event(dev, EV_ABS, ABS_MT_SLOT, i);
|
||||
input_handle_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -278,12 +282,43 @@ void input_mt_drop_unused(struct input_dev *dev)
|
|||
struct input_mt *mt = dev->mt;
|
||||
|
||||
if (mt) {
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&dev->event_lock, flags);
|
||||
|
||||
__input_mt_drop_unused(dev, mt);
|
||||
mt->frame++;
|
||||
|
||||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(input_mt_drop_unused);
|
||||
|
||||
/**
|
||||
* input_mt_release_slots() - Deactivate all slots
|
||||
* @dev: input device with allocated MT slots
|
||||
*
|
||||
* Lift all active slots.
|
||||
*/
|
||||
void input_mt_release_slots(struct input_dev *dev)
|
||||
{
|
||||
struct input_mt *mt = dev->mt;
|
||||
|
||||
lockdep_assert_held(&dev->event_lock);
|
||||
|
||||
if (mt) {
|
||||
/* This will effectively mark all slots unused. */
|
||||
mt->frame++;
|
||||
|
||||
__input_mt_drop_unused(dev, mt);
|
||||
|
||||
if (test_bit(ABS_PRESSURE, dev->absbit))
|
||||
input_handle_event(dev, EV_ABS, ABS_PRESSURE, 0);
|
||||
|
||||
mt->frame++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* input_mt_sync_frame() - synchronize mt frame
|
||||
* @dev: input device with allocated MT slots
|
||||
|
@ -300,8 +335,13 @@ void input_mt_sync_frame(struct input_dev *dev)
|
|||
if (!mt)
|
||||
return;
|
||||
|
||||
if (mt->flags & INPUT_MT_DROP_UNUSED)
|
||||
if (mt->flags & INPUT_MT_DROP_UNUSED) {
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&dev->event_lock, flags);
|
||||
__input_mt_drop_unused(dev, mt);
|
||||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||
}
|
||||
|
||||
if ((mt->flags & INPUT_MT_POINTER) && !(mt->flags & INPUT_MT_SEMI_MT))
|
||||
use_count = true;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <linux/mutex.h>
|
||||
#include <linux/rcupdate.h>
|
||||
#include "input-compat.h"
|
||||
#include "input-core-private.h"
|
||||
#include "input-poller.h"
|
||||
|
||||
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
|
||||
|
@ -142,6 +143,8 @@ static void input_pass_values(struct input_dev *dev,
|
|||
struct input_handle *handle;
|
||||
struct input_value *v;
|
||||
|
||||
lockdep_assert_held(&dev->event_lock);
|
||||
|
||||
if (!count)
|
||||
return;
|
||||
|
||||
|
@ -174,44 +177,6 @@ static void input_pass_values(struct input_dev *dev,
|
|||
}
|
||||
}
|
||||
|
||||
static void input_pass_event(struct input_dev *dev,
|
||||
unsigned int type, unsigned int code, int value)
|
||||
{
|
||||
struct input_value vals[] = { { type, code, value } };
|
||||
|
||||
input_pass_values(dev, vals, ARRAY_SIZE(vals));
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate software autorepeat event. Note that we take
|
||||
* dev->event_lock here to avoid racing with input_event
|
||||
* which may cause keys get "stuck".
|
||||
*/
|
||||
static void input_repeat_key(struct timer_list *t)
|
||||
{
|
||||
struct input_dev *dev = from_timer(dev, t, timer);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&dev->event_lock, flags);
|
||||
|
||||
if (test_bit(dev->repeat_key, dev->key) &&
|
||||
is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) {
|
||||
struct input_value vals[] = {
|
||||
{ EV_KEY, dev->repeat_key, 2 },
|
||||
input_value_sync
|
||||
};
|
||||
|
||||
input_set_timestamp(dev, ktime_get());
|
||||
input_pass_values(dev, vals, ARRAY_SIZE(vals));
|
||||
|
||||
if (dev->rep[REP_PERIOD])
|
||||
mod_timer(&dev->timer, jiffies +
|
||||
msecs_to_jiffies(dev->rep[REP_PERIOD]));
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||
}
|
||||
|
||||
#define INPUT_IGNORE_EVENT 0
|
||||
#define INPUT_PASS_TO_HANDLERS 1
|
||||
#define INPUT_PASS_TO_DEVICE 2
|
||||
|
@ -275,6 +240,10 @@ static int input_get_disposition(struct input_dev *dev,
|
|||
int disposition = INPUT_IGNORE_EVENT;
|
||||
int value = *pval;
|
||||
|
||||
/* filter-out events from inhibited devices */
|
||||
if (dev->inhibited)
|
||||
return INPUT_IGNORE_EVENT;
|
||||
|
||||
switch (type) {
|
||||
|
||||
case EV_SYN:
|
||||
|
@ -375,19 +344,9 @@ static int input_get_disposition(struct input_dev *dev,
|
|||
return disposition;
|
||||
}
|
||||
|
||||
static void input_handle_event(struct input_dev *dev,
|
||||
unsigned int type, unsigned int code, int value)
|
||||
static void input_event_dispose(struct input_dev *dev, int disposition,
|
||||
unsigned int type, unsigned int code, int value)
|
||||
{
|
||||
int disposition;
|
||||
|
||||
/* filter-out events from inhibited devices */
|
||||
if (dev->inhibited)
|
||||
return;
|
||||
|
||||
disposition = input_get_disposition(dev, type, code, &value);
|
||||
if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN)
|
||||
add_input_randomness(type, code, value);
|
||||
|
||||
if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)
|
||||
dev->event(dev, type, code, value);
|
||||
|
||||
|
@ -426,7 +385,22 @@ static void input_handle_event(struct input_dev *dev,
|
|||
input_pass_values(dev, dev->vals, dev->num_vals);
|
||||
dev->num_vals = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void input_handle_event(struct input_dev *dev,
|
||||
unsigned int type, unsigned int code, int value)
|
||||
{
|
||||
int disposition;
|
||||
|
||||
lockdep_assert_held(&dev->event_lock);
|
||||
|
||||
disposition = input_get_disposition(dev, type, code, &value);
|
||||
if (disposition != INPUT_IGNORE_EVENT) {
|
||||
if (type != EV_SYN)
|
||||
add_input_randomness(type, code, value);
|
||||
|
||||
input_event_dispose(dev, disposition, type, code, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -613,7 +587,7 @@ static void __input_release_device(struct input_handle *handle)
|
|||
lockdep_is_held(&dev->mutex));
|
||||
if (grabber == handle) {
|
||||
rcu_assign_pointer(dev->grab, NULL);
|
||||
/* Make sure input_pass_event() notices that grab is gone */
|
||||
/* Make sure input_pass_values() notices that grab is gone */
|
||||
synchronize_rcu();
|
||||
|
||||
list_for_each_entry(handle, &dev->h_list, d_node)
|
||||
|
@ -736,7 +710,7 @@ void input_close_device(struct input_handle *handle)
|
|||
|
||||
if (!--handle->open) {
|
||||
/*
|
||||
* synchronize_rcu() makes sure that input_pass_event()
|
||||
* synchronize_rcu() makes sure that input_pass_values()
|
||||
* completed and that no more input events are delivered
|
||||
* through this handle
|
||||
*/
|
||||
|
@ -751,22 +725,21 @@ EXPORT_SYMBOL(input_close_device);
|
|||
* Simulate keyup events for all keys that are marked as pressed.
|
||||
* The function must be called with dev->event_lock held.
|
||||
*/
|
||||
static void input_dev_release_keys(struct input_dev *dev)
|
||||
static bool input_dev_release_keys(struct input_dev *dev)
|
||||
{
|
||||
bool need_sync = false;
|
||||
int code;
|
||||
|
||||
lockdep_assert_held(&dev->event_lock);
|
||||
|
||||
if (is_event_supported(EV_KEY, dev->evbit, EV_MAX)) {
|
||||
for_each_set_bit(code, dev->key, KEY_CNT) {
|
||||
input_pass_event(dev, EV_KEY, code, 0);
|
||||
input_handle_event(dev, EV_KEY, code, 0);
|
||||
need_sync = true;
|
||||
}
|
||||
|
||||
if (need_sync)
|
||||
input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
|
||||
|
||||
memset(dev->key, 0, sizeof(dev->key));
|
||||
}
|
||||
|
||||
return need_sync;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -793,7 +766,8 @@ static void input_disconnect_device(struct input_dev *dev)
|
|||
* generate events even after we done here but they will not
|
||||
* reach any handlers.
|
||||
*/
|
||||
input_dev_release_keys(dev);
|
||||
if (input_dev_release_keys(dev))
|
||||
input_handle_event(dev, EV_SYN, SYN_REPORT, 1);
|
||||
|
||||
list_for_each_entry(handle, &dev->h_list, d_node)
|
||||
handle->open = 0;
|
||||
|
@ -1004,12 +978,16 @@ int input_set_keycode(struct input_dev *dev,
|
|||
} else if (test_bit(EV_KEY, dev->evbit) &&
|
||||
!is_event_supported(old_keycode, dev->keybit, KEY_MAX) &&
|
||||
__test_and_clear_bit(old_keycode, dev->key)) {
|
||||
struct input_value vals[] = {
|
||||
{ EV_KEY, old_keycode, 0 },
|
||||
input_value_sync
|
||||
};
|
||||
|
||||
input_pass_values(dev, vals, ARRAY_SIZE(vals));
|
||||
/*
|
||||
* We have to use input_event_dispose() here directly instead
|
||||
* of input_handle_event() because the key we want to release
|
||||
* here is considered no longer supported by the device and
|
||||
* input_handle_event() will ignore it.
|
||||
*/
|
||||
input_event_dispose(dev, INPUT_PASS_TO_HANDLERS,
|
||||
EV_KEY, old_keycode, 0);
|
||||
input_event_dispose(dev, INPUT_PASS_TO_HANDLERS | INPUT_FLUSH,
|
||||
EV_SYN, SYN_REPORT, 1);
|
||||
}
|
||||
|
||||
out:
|
||||
|
@ -1784,7 +1762,8 @@ void input_reset_device(struct input_dev *dev)
|
|||
spin_lock_irqsave(&dev->event_lock, flags);
|
||||
|
||||
input_dev_toggle(dev, true);
|
||||
input_dev_release_keys(dev);
|
||||
if (input_dev_release_keys(dev))
|
||||
input_handle_event(dev, EV_SYN, SYN_REPORT, 1);
|
||||
|
||||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||
mutex_unlock(&dev->mutex);
|
||||
|
@ -1806,7 +1785,9 @@ static int input_inhibit_device(struct input_dev *dev)
|
|||
}
|
||||
|
||||
spin_lock_irq(&dev->event_lock);
|
||||
input_mt_release_slots(dev);
|
||||
input_dev_release_keys(dev);
|
||||
input_handle_event(dev, EV_SYN, SYN_REPORT, 1);
|
||||
input_dev_toggle(dev, false);
|
||||
spin_unlock_irq(&dev->event_lock);
|
||||
|
||||
|
@ -1857,7 +1838,8 @@ static int input_dev_suspend(struct device *dev)
|
|||
* Keys that are pressed now are unlikely to be
|
||||
* still pressed when we resume.
|
||||
*/
|
||||
input_dev_release_keys(input_dev);
|
||||
if (input_dev_release_keys(input_dev))
|
||||
input_handle_event(input_dev, EV_SYN, SYN_REPORT, 1);
|
||||
|
||||
/* Turn off LEDs and sounds, if any are active. */
|
||||
input_dev_toggle(input_dev, false);
|
||||
|
@ -1891,7 +1873,8 @@ static int input_dev_freeze(struct device *dev)
|
|||
* Keys that are pressed now are unlikely to be
|
||||
* still pressed when we resume.
|
||||
*/
|
||||
input_dev_release_keys(input_dev);
|
||||
if (input_dev_release_keys(input_dev))
|
||||
input_handle_event(input_dev, EV_SYN, SYN_REPORT, 1);
|
||||
|
||||
spin_unlock_irq(&input_dev->event_lock);
|
||||
|
||||
|
@ -2259,6 +2242,34 @@ static void devm_input_device_unregister(struct device *dev, void *res)
|
|||
__input_unregister_device(input);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate software autorepeat event. Note that we take
|
||||
* dev->event_lock here to avoid racing with input_event
|
||||
* which may cause keys get "stuck".
|
||||
*/
|
||||
static void input_repeat_key(struct timer_list *t)
|
||||
{
|
||||
struct input_dev *dev = from_timer(dev, t, timer);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&dev->event_lock, flags);
|
||||
|
||||
if (!dev->inhibited &&
|
||||
test_bit(dev->repeat_key, dev->key) &&
|
||||
is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) {
|
||||
|
||||
input_set_timestamp(dev, ktime_get());
|
||||
input_handle_event(dev, EV_KEY, dev->repeat_key, 2);
|
||||
input_handle_event(dev, EV_SYN, SYN_REPORT, 1);
|
||||
|
||||
if (dev->rep[REP_PERIOD])
|
||||
mod_timer(&dev->timer, jiffies +
|
||||
msecs_to_jiffies(dev->rep[REP_PERIOD]));
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* input_enable_softrepeat - enable software autorepeat
|
||||
* @dev: input device
|
||||
|
|
|
@ -222,13 +222,6 @@ static int adc_joystick_probe(struct platform_device *pdev)
|
|||
if (error)
|
||||
return error;
|
||||
|
||||
input_set_drvdata(input, joy);
|
||||
error = input_register_device(input);
|
||||
if (error) {
|
||||
dev_err(dev, "Unable to register input device\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
joy->buffer = iio_channel_get_all_cb(dev, adc_joystick_handle, joy);
|
||||
if (IS_ERR(joy->buffer)) {
|
||||
dev_err(dev, "Unable to allocate callback buffer\n");
|
||||
|
@ -241,6 +234,14 @@ static int adc_joystick_probe(struct platform_device *pdev)
|
|||
return error;
|
||||
}
|
||||
|
||||
input_set_drvdata(input, joy);
|
||||
|
||||
error = input_register_device(input);
|
||||
if (error) {
|
||||
dev_err(dev, "Unable to register input device\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -98,10 +98,8 @@ static int sensehat_joystick_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
dev_err(&pdev->dev, "Could not retrieve interrupt request");
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
}
|
||||
|
||||
error = devm_request_threaded_irq(&pdev->dev, irq,
|
||||
NULL, sensehat_joystick_report,
|
||||
|
|
|
@ -795,7 +795,7 @@ config KEYBOARD_MT6779
|
|||
|
||||
config KEYBOARD_MTK_PMIC
|
||||
tristate "MediaTek PMIC keys support"
|
||||
depends on MFD_MT6397
|
||||
depends on MFD_MT6397 || COMPILE_TEST
|
||||
help
|
||||
Say Y here if you want to use the pmic keys (powerkey/homekey).
|
||||
|
||||
|
|
|
@ -8,17 +8,19 @@
|
|||
* Copyright (C) 2008-2010 Analog Devices Inc.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/ktime.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/timekeeping.h>
|
||||
|
||||
#include <linux/platform_data/adp5588.h>
|
||||
|
||||
|
@ -36,18 +38,18 @@
|
|||
* asserted.
|
||||
*/
|
||||
#define WA_DELAYED_READOUT_REVID(rev) ((rev) < 4)
|
||||
#define WA_DELAYED_READOUT_TIME 25
|
||||
|
||||
struct adp5588_kpad {
|
||||
struct i2c_client *client;
|
||||
struct input_dev *input;
|
||||
struct delayed_work work;
|
||||
ktime_t irq_time;
|
||||
unsigned long delay;
|
||||
unsigned short keycode[ADP5588_KEYMAPSIZE];
|
||||
const struct adp5588_gpi_map *gpimap;
|
||||
unsigned short gpimapsize;
|
||||
#ifdef CONFIG_GPIOLIB
|
||||
unsigned char gpiomap[ADP5588_MAXGPIO];
|
||||
bool export_gpio;
|
||||
struct gpio_chip gc;
|
||||
struct mutex gpio_lock; /* Protect cached dir, dat_out */
|
||||
u8 dat_out[3];
|
||||
|
@ -179,6 +181,21 @@ static int adp5588_build_gpiomap(struct adp5588_kpad *kpad,
|
|||
return n_unused;
|
||||
}
|
||||
|
||||
static void adp5588_gpio_do_teardown(void *_kpad)
|
||||
{
|
||||
struct adp5588_kpad *kpad = _kpad;
|
||||
struct device *dev = &kpad->client->dev;
|
||||
const struct adp5588_kpad_platform_data *pdata = dev_get_platdata(dev);
|
||||
const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data;
|
||||
int error;
|
||||
|
||||
error = gpio_data->teardown(kpad->client,
|
||||
kpad->gc.base, kpad->gc.ngpio,
|
||||
gpio_data->context);
|
||||
if (error)
|
||||
dev_warn(&kpad->client->dev, "teardown failed %d\n", error);
|
||||
}
|
||||
|
||||
static int adp5588_gpio_add(struct adp5588_kpad *kpad)
|
||||
{
|
||||
struct device *dev = &kpad->client->dev;
|
||||
|
@ -195,8 +212,6 @@ static int adp5588_gpio_add(struct adp5588_kpad *kpad)
|
|||
return 0;
|
||||
}
|
||||
|
||||
kpad->export_gpio = true;
|
||||
|
||||
kpad->gc.direction_input = adp5588_gpio_direction_input;
|
||||
kpad->gc.direction_output = adp5588_gpio_direction_output;
|
||||
kpad->gc.get = adp5588_gpio_get_value;
|
||||
|
@ -210,9 +225,9 @@ static int adp5588_gpio_add(struct adp5588_kpad *kpad)
|
|||
|
||||
mutex_init(&kpad->gpio_lock);
|
||||
|
||||
error = gpiochip_add_data(&kpad->gc, kpad);
|
||||
error = devm_gpiochip_add_data(dev, &kpad->gc, kpad);
|
||||
if (error) {
|
||||
dev_err(dev, "gpiochip_add failed, err: %d\n", error);
|
||||
dev_err(dev, "gpiochip_add failed: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -227,41 +242,24 @@ static int adp5588_gpio_add(struct adp5588_kpad *kpad)
|
|||
kpad->gc.base, kpad->gc.ngpio,
|
||||
gpio_data->context);
|
||||
if (error)
|
||||
dev_warn(dev, "setup failed, %d\n", error);
|
||||
dev_warn(dev, "setup failed: %d\n", error);
|
||||
}
|
||||
|
||||
if (gpio_data->teardown) {
|
||||
error = devm_add_action(dev, adp5588_gpio_do_teardown, kpad);
|
||||
if (error)
|
||||
dev_warn(dev, "failed to schedule teardown: %d\n",
|
||||
error);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void adp5588_gpio_remove(struct adp5588_kpad *kpad)
|
||||
{
|
||||
struct device *dev = &kpad->client->dev;
|
||||
const struct adp5588_kpad_platform_data *pdata = dev_get_platdata(dev);
|
||||
const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data;
|
||||
int error;
|
||||
|
||||
if (!kpad->export_gpio)
|
||||
return;
|
||||
|
||||
if (gpio_data->teardown) {
|
||||
error = gpio_data->teardown(kpad->client,
|
||||
kpad->gc.base, kpad->gc.ngpio,
|
||||
gpio_data->context);
|
||||
if (error)
|
||||
dev_warn(dev, "teardown failed %d\n", error);
|
||||
}
|
||||
|
||||
gpiochip_remove(&kpad->gc);
|
||||
}
|
||||
#else
|
||||
static inline int adp5588_gpio_add(struct adp5588_kpad *kpad)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void adp5588_gpio_remove(struct adp5588_kpad *kpad)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static void adp5588_report_events(struct adp5588_kpad *kpad, int ev_cnt)
|
||||
|
@ -289,13 +287,36 @@ static void adp5588_report_events(struct adp5588_kpad *kpad, int ev_cnt)
|
|||
}
|
||||
}
|
||||
|
||||
static void adp5588_work(struct work_struct *work)
|
||||
static irqreturn_t adp5588_hard_irq(int irq, void *handle)
|
||||
{
|
||||
struct adp5588_kpad *kpad = container_of(work,
|
||||
struct adp5588_kpad, work.work);
|
||||
struct adp5588_kpad *kpad = handle;
|
||||
|
||||
kpad->irq_time = ktime_get();
|
||||
|
||||
return IRQ_WAKE_THREAD;
|
||||
}
|
||||
|
||||
static irqreturn_t adp5588_thread_irq(int irq, void *handle)
|
||||
{
|
||||
struct adp5588_kpad *kpad = handle;
|
||||
struct i2c_client *client = kpad->client;
|
||||
ktime_t target_time, now;
|
||||
unsigned long delay;
|
||||
int status, ev_cnt;
|
||||
|
||||
/*
|
||||
* Readout needs to wait for at least 25ms after the notification
|
||||
* for REVID < 4.
|
||||
*/
|
||||
if (kpad->delay) {
|
||||
target_time = ktime_add_ms(kpad->irq_time, kpad->delay);
|
||||
now = ktime_get();
|
||||
if (ktime_before(now, target_time)) {
|
||||
delay = ktime_to_us(ktime_sub(target_time, now));
|
||||
usleep_range(delay, delay + 1000);
|
||||
}
|
||||
}
|
||||
|
||||
status = adp5588_read(client, INT_STAT);
|
||||
|
||||
if (status & ADP5588_OVR_FLOW_INT) /* Unlikely and should never happen */
|
||||
|
@ -308,20 +329,8 @@ static void adp5588_work(struct work_struct *work)
|
|||
input_sync(kpad->input);
|
||||
}
|
||||
}
|
||||
|
||||
adp5588_write(client, INT_STAT, status); /* Status is W1C */
|
||||
}
|
||||
|
||||
static irqreturn_t adp5588_irq(int irq, void *handle)
|
||||
{
|
||||
struct adp5588_kpad *kpad = handle;
|
||||
|
||||
/*
|
||||
* use keventd context to read the event fifo registers
|
||||
* Schedule readout at least 25ms after notification for
|
||||
* REVID < 4
|
||||
*/
|
||||
|
||||
schedule_delayed_work(&kpad->work, kpad->delay);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
@ -496,30 +505,27 @@ static int adp5588_probe(struct i2c_client *client,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
kpad = kzalloc(sizeof(*kpad), GFP_KERNEL);
|
||||
input = input_allocate_device();
|
||||
if (!kpad || !input) {
|
||||
error = -ENOMEM;
|
||||
goto err_free_mem;
|
||||
}
|
||||
kpad = devm_kzalloc(&client->dev, sizeof(*kpad), GFP_KERNEL);
|
||||
if (!kpad)
|
||||
return -ENOMEM;
|
||||
|
||||
input = devm_input_allocate_device(&client->dev);
|
||||
if (!input)
|
||||
return -ENOMEM;
|
||||
|
||||
kpad->client = client;
|
||||
kpad->input = input;
|
||||
INIT_DELAYED_WORK(&kpad->work, adp5588_work);
|
||||
|
||||
ret = adp5588_read(client, DEV_ID);
|
||||
if (ret < 0) {
|
||||
error = ret;
|
||||
goto err_free_mem;
|
||||
}
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
revid = (u8) ret & ADP5588_DEVICE_ID_MASK;
|
||||
if (WA_DELAYED_READOUT_REVID(revid))
|
||||
kpad->delay = msecs_to_jiffies(30);
|
||||
kpad->delay = msecs_to_jiffies(WA_DELAYED_READOUT_TIME);
|
||||
|
||||
input->name = client->name;
|
||||
input->phys = "adp5588-keys/input0";
|
||||
input->dev.parent = &client->dev;
|
||||
|
||||
input_set_drvdata(input, kpad);
|
||||
|
||||
|
@ -556,95 +562,63 @@ static int adp5588_probe(struct i2c_client *client,
|
|||
|
||||
error = input_register_device(input);
|
||||
if (error) {
|
||||
dev_err(&client->dev, "unable to register input device\n");
|
||||
goto err_free_mem;
|
||||
dev_err(&client->dev, "unable to register input device: %d\n",
|
||||
error);
|
||||
return error;
|
||||
}
|
||||
|
||||
error = request_irq(client->irq, adp5588_irq,
|
||||
IRQF_TRIGGER_FALLING,
|
||||
client->dev.driver->name, kpad);
|
||||
error = devm_request_threaded_irq(&client->dev, client->irq,
|
||||
adp5588_hard_irq, adp5588_thread_irq,
|
||||
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
|
||||
client->dev.driver->name, kpad);
|
||||
if (error) {
|
||||
dev_err(&client->dev, "irq %d busy?\n", client->irq);
|
||||
goto err_unreg_dev;
|
||||
dev_err(&client->dev, "failed to request irq %d: %d\n",
|
||||
client->irq, error);
|
||||
return error;
|
||||
}
|
||||
|
||||
error = adp5588_setup(client);
|
||||
if (error)
|
||||
goto err_free_irq;
|
||||
return error;
|
||||
|
||||
if (kpad->gpimapsize)
|
||||
adp5588_report_switch_state(kpad);
|
||||
|
||||
error = adp5588_gpio_add(kpad);
|
||||
if (error)
|
||||
goto err_free_irq;
|
||||
|
||||
device_init_wakeup(&client->dev, 1);
|
||||
i2c_set_clientdata(client, kpad);
|
||||
return error;
|
||||
|
||||
dev_info(&client->dev, "Rev.%d keypad, irq %d\n", revid, client->irq);
|
||||
return 0;
|
||||
|
||||
err_free_irq:
|
||||
free_irq(client->irq, kpad);
|
||||
cancel_delayed_work_sync(&kpad->work);
|
||||
err_unreg_dev:
|
||||
input_unregister_device(input);
|
||||
input = NULL;
|
||||
err_free_mem:
|
||||
input_free_device(input);
|
||||
kfree(kpad);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int adp5588_remove(struct i2c_client *client)
|
||||
{
|
||||
struct adp5588_kpad *kpad = i2c_get_clientdata(client);
|
||||
|
||||
adp5588_write(client, CFG, 0);
|
||||
free_irq(client->irq, kpad);
|
||||
cancel_delayed_work_sync(&kpad->work);
|
||||
input_unregister_device(kpad->input);
|
||||
adp5588_gpio_remove(kpad);
|
||||
kfree(kpad);
|
||||
|
||||
/* all resources will be freed by devm */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int adp5588_suspend(struct device *dev)
|
||||
static int __maybe_unused adp5588_suspend(struct device *dev)
|
||||
{
|
||||
struct adp5588_kpad *kpad = dev_get_drvdata(dev);
|
||||
struct i2c_client *client = kpad->client;
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
|
||||
disable_irq(client->irq);
|
||||
cancel_delayed_work_sync(&kpad->work);
|
||||
|
||||
if (device_may_wakeup(&client->dev))
|
||||
enable_irq_wake(client->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int adp5588_resume(struct device *dev)
|
||||
static int __maybe_unused adp5588_resume(struct device *dev)
|
||||
{
|
||||
struct adp5588_kpad *kpad = dev_get_drvdata(dev);
|
||||
struct i2c_client *client = kpad->client;
|
||||
|
||||
if (device_may_wakeup(&client->dev))
|
||||
disable_irq_wake(client->irq);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
|
||||
enable_irq(client->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops adp5588_dev_pm_ops = {
|
||||
.suspend = adp5588_suspend,
|
||||
.resume = adp5588_resume,
|
||||
};
|
||||
#endif
|
||||
static SIMPLE_DEV_PM_OPS(adp5588_dev_pm_ops, adp5588_suspend, adp5588_resume);
|
||||
|
||||
static const struct i2c_device_id adp5588_id[] = {
|
||||
{ "adp5588-keys", 0 },
|
||||
|
@ -656,9 +630,7 @@ MODULE_DEVICE_TABLE(i2c, adp5588_id);
|
|||
static struct i2c_driver adp5588_driver = {
|
||||
.driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
#ifdef CONFIG_PM
|
||||
.pm = &adp5588_dev_pm_ops,
|
||||
#endif
|
||||
},
|
||||
.probe = adp5588_probe,
|
||||
.remove = adp5588_remove,
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
// expensive.
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/input.h>
|
||||
|
@ -518,6 +519,50 @@ static int cros_ec_keyb_register_bs(struct cros_ec_keyb *ckdev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void cros_ec_keyb_parse_vivaldi_physmap(struct cros_ec_keyb *ckdev)
|
||||
{
|
||||
u32 *physmap = ckdev->vdata.function_row_physmap;
|
||||
unsigned int row, col, scancode;
|
||||
int n_physmap;
|
||||
int error;
|
||||
int i;
|
||||
|
||||
n_physmap = device_property_count_u32(ckdev->dev,
|
||||
"function-row-physmap");
|
||||
if (n_physmap <= 0)
|
||||
return;
|
||||
|
||||
if (n_physmap >= VIVALDI_MAX_FUNCTION_ROW_KEYS) {
|
||||
dev_warn(ckdev->dev,
|
||||
"only up to %d top row keys is supported (%d specified)\n",
|
||||
VIVALDI_MAX_FUNCTION_ROW_KEYS, n_physmap);
|
||||
n_physmap = VIVALDI_MAX_FUNCTION_ROW_KEYS;
|
||||
}
|
||||
|
||||
error = device_property_read_u32_array(ckdev->dev,
|
||||
"function-row-physmap",
|
||||
physmap, n_physmap);
|
||||
if (error) {
|
||||
dev_warn(ckdev->dev,
|
||||
"failed to parse function-row-physmap property: %d\n",
|
||||
error);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert (in place) from row/column encoding to matrix "scancode"
|
||||
* used by the driver.
|
||||
*/
|
||||
for (i = 0; i < n_physmap; i++) {
|
||||
row = KEY_ROW(physmap[i]);
|
||||
col = KEY_COL(physmap[i]);
|
||||
scancode = MATRIX_SCAN_CODE(row, col, ckdev->row_shift);
|
||||
physmap[i] = scancode;
|
||||
}
|
||||
|
||||
ckdev->vdata.num_function_row_keys = n_physmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* cros_ec_keyb_register_matrix - Register matrix keys
|
||||
*
|
||||
|
@ -534,11 +579,6 @@ static int cros_ec_keyb_register_matrix(struct cros_ec_keyb *ckdev)
|
|||
struct input_dev *idev;
|
||||
const char *phys;
|
||||
int err;
|
||||
struct property *prop;
|
||||
const __be32 *p;
|
||||
u32 *physmap;
|
||||
u32 key_pos;
|
||||
unsigned int row, col, scancode, n_physmap;
|
||||
|
||||
err = matrix_keypad_parse_properties(dev, &ckdev->rows, &ckdev->cols);
|
||||
if (err)
|
||||
|
@ -573,7 +613,7 @@ static int cros_ec_keyb_register_matrix(struct cros_ec_keyb *ckdev)
|
|||
idev->id.product = 0;
|
||||
idev->dev.parent = dev;
|
||||
|
||||
ckdev->ghost_filter = of_property_read_bool(dev->of_node,
|
||||
ckdev->ghost_filter = device_property_read_bool(dev,
|
||||
"google,needs-ghost-filter");
|
||||
|
||||
err = matrix_keypad_build_keymap(NULL, NULL, ckdev->rows, ckdev->cols,
|
||||
|
@ -589,22 +629,7 @@ static int cros_ec_keyb_register_matrix(struct cros_ec_keyb *ckdev)
|
|||
input_set_drvdata(idev, ckdev);
|
||||
ckdev->idev = idev;
|
||||
cros_ec_keyb_compute_valid_keys(ckdev);
|
||||
|
||||
physmap = ckdev->vdata.function_row_physmap;
|
||||
n_physmap = 0;
|
||||
of_property_for_each_u32(dev->of_node, "function-row-physmap",
|
||||
prop, p, key_pos) {
|
||||
if (n_physmap == VIVALDI_MAX_FUNCTION_ROW_KEYS) {
|
||||
dev_warn(dev, "Only support up to %d top row keys\n",
|
||||
VIVALDI_MAX_FUNCTION_ROW_KEYS);
|
||||
break;
|
||||
}
|
||||
row = KEY_ROW(key_pos);
|
||||
col = KEY_COL(key_pos);
|
||||
scancode = MATRIX_SCAN_CODE(row, col, ckdev->row_shift);
|
||||
physmap[n_physmap++] = scancode;
|
||||
}
|
||||
ckdev->vdata.num_function_row_keys = n_physmap;
|
||||
cros_ec_keyb_parse_vivaldi_physmap(ckdev);
|
||||
|
||||
err = input_register_device(ckdev->idev);
|
||||
if (err) {
|
||||
|
@ -653,14 +678,19 @@ static const struct attribute_group cros_ec_keyb_attr_group = {
|
|||
|
||||
static int cros_ec_keyb_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent);
|
||||
struct cros_ec_device *ec;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct cros_ec_keyb *ckdev;
|
||||
bool buttons_switches_only = device_get_match_data(dev);
|
||||
int err;
|
||||
|
||||
if (!dev->of_node)
|
||||
return -ENODEV;
|
||||
/*
|
||||
* If the parent ec device has not been probed yet, defer the probe of
|
||||
* this keyboard/button driver until later.
|
||||
*/
|
||||
ec = dev_get_drvdata(pdev->dev.parent);
|
||||
if (!ec)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
ckdev = devm_kzalloc(dev, sizeof(*ckdev), GFP_KERNEL);
|
||||
if (!ckdev)
|
||||
|
@ -713,6 +743,14 @@ static int cros_ec_keyb_remove(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
static const struct acpi_device_id cros_ec_keyb_acpi_match[] = {
|
||||
{ "GOOG0007", true },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, cros_ec_keyb_acpi_match);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id cros_ec_keyb_of_match[] = {
|
||||
{ .compatible = "google,cros-ec-keyb" },
|
||||
|
@ -730,6 +768,7 @@ static struct platform_driver cros_ec_keyb_driver = {
|
|||
.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,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -17,6 +17,11 @@
|
|||
#define MTK_KPD_DEBOUNCE 0x0018
|
||||
#define MTK_KPD_DEBOUNCE_MASK GENMASK(13, 0)
|
||||
#define MTK_KPD_DEBOUNCE_MAX_MS 256
|
||||
#define MTK_KPD_SEL 0x0020
|
||||
#define MTK_KPD_SEL_COL GENMASK(15, 10)
|
||||
#define MTK_KPD_SEL_ROW GENMASK(9, 4)
|
||||
#define MTK_KPD_SEL_COLMASK(c) GENMASK((c) + 9, 10)
|
||||
#define MTK_KPD_SEL_ROWMASK(r) GENMASK((r) + 3, 4)
|
||||
#define MTK_KPD_NUM_MEMS 5
|
||||
#define MTK_KPD_NUM_BITS 136 /* 4*32+8 MEM5 only use 8 BITS */
|
||||
|
||||
|
@ -42,7 +47,7 @@ static irqreturn_t mt6779_keypad_irq_handler(int irq, void *dev_id)
|
|||
const unsigned short *keycode = keypad->input_dev->keycode;
|
||||
DECLARE_BITMAP(new_state, MTK_KPD_NUM_BITS);
|
||||
DECLARE_BITMAP(change, MTK_KPD_NUM_BITS);
|
||||
unsigned int bit_nr;
|
||||
unsigned int bit_nr, key;
|
||||
unsigned int row, col;
|
||||
unsigned int scancode;
|
||||
unsigned int row_shift = get_count_order(keypad->n_cols);
|
||||
|
@ -61,8 +66,10 @@ static irqreturn_t mt6779_keypad_irq_handler(int irq, void *dev_id)
|
|||
if (bit_nr % 32 >= 16)
|
||||
continue;
|
||||
|
||||
row = bit_nr / 32;
|
||||
col = bit_nr % 32;
|
||||
key = bit_nr / 32 * 16 + bit_nr % 32;
|
||||
row = key / 9;
|
||||
col = key % 9;
|
||||
|
||||
scancode = MATRIX_SCAN_CODE(row, col, row_shift);
|
||||
/* 1: not pressed, 0: pressed */
|
||||
pressed = !test_bit(bit_nr, new_state);
|
||||
|
@ -159,6 +166,11 @@ static int mt6779_keypad_pdrv_probe(struct platform_device *pdev)
|
|||
regmap_write(keypad->regmap, MTK_KPD_DEBOUNCE,
|
||||
(debounce * (1 << 5)) & MTK_KPD_DEBOUNCE_MASK);
|
||||
|
||||
regmap_update_bits(keypad->regmap, MTK_KPD_SEL, MTK_KPD_SEL_ROW,
|
||||
MTK_KPD_SEL_ROWMASK(keypad->n_rows));
|
||||
regmap_update_bits(keypad->regmap, MTK_KPD_SEL, MTK_KPD_SEL_COL,
|
||||
MTK_KPD_SEL_COLMASK(keypad->n_cols));
|
||||
|
||||
keypad->clk = devm_clk_get(&pdev->dev, "kpd");
|
||||
if (IS_ERR(keypad->clk))
|
||||
return PTR_ERR(keypad->clk);
|
||||
|
|
|
@ -18,17 +18,9 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#define MTK_PMIC_PWRKEY_RST_EN_MASK 0x1
|
||||
#define MTK_PMIC_PWRKEY_RST_EN_SHIFT 6
|
||||
#define MTK_PMIC_HOMEKEY_RST_EN_MASK 0x1
|
||||
#define MTK_PMIC_HOMEKEY_RST_EN_SHIFT 5
|
||||
#define MTK_PMIC_RST_DU_MASK 0x3
|
||||
#define MTK_PMIC_RST_DU_SHIFT 8
|
||||
|
||||
#define MTK_PMIC_PWRKEY_RST \
|
||||
(MTK_PMIC_PWRKEY_RST_EN_MASK << MTK_PMIC_PWRKEY_RST_EN_SHIFT)
|
||||
#define MTK_PMIC_HOMEKEY_RST \
|
||||
(MTK_PMIC_HOMEKEY_RST_EN_MASK << MTK_PMIC_HOMEKEY_RST_EN_SHIFT)
|
||||
#define MTK_PMIC_RST_DU_MASK GENMASK(9, 8)
|
||||
#define MTK_PMIC_PWRKEY_RST BIT(6)
|
||||
#define MTK_PMIC_HOMEKEY_RST BIT(5)
|
||||
|
||||
#define MTK_PMIC_PWRKEY_INDEX 0
|
||||
#define MTK_PMIC_HOMEKEY_INDEX 1
|
||||
|
@ -39,50 +31,58 @@ struct mtk_pmic_keys_regs {
|
|||
u32 deb_mask;
|
||||
u32 intsel_reg;
|
||||
u32 intsel_mask;
|
||||
u32 rst_en_mask;
|
||||
};
|
||||
|
||||
#define MTK_PMIC_KEYS_REGS(_deb_reg, _deb_mask, \
|
||||
_intsel_reg, _intsel_mask) \
|
||||
_intsel_reg, _intsel_mask, _rst_mask) \
|
||||
{ \
|
||||
.deb_reg = _deb_reg, \
|
||||
.deb_mask = _deb_mask, \
|
||||
.intsel_reg = _intsel_reg, \
|
||||
.intsel_mask = _intsel_mask, \
|
||||
.rst_en_mask = _rst_mask, \
|
||||
}
|
||||
|
||||
struct mtk_pmic_regs {
|
||||
const struct mtk_pmic_keys_regs keys_regs[MTK_PMIC_MAX_KEY_COUNT];
|
||||
u32 pmic_rst_reg;
|
||||
u32 rst_lprst_mask; /* Long-press reset timeout bitmask */
|
||||
};
|
||||
|
||||
static const struct mtk_pmic_regs mt6397_regs = {
|
||||
.keys_regs[MTK_PMIC_PWRKEY_INDEX] =
|
||||
MTK_PMIC_KEYS_REGS(MT6397_CHRSTATUS,
|
||||
0x8, MT6397_INT_RSV, 0x10),
|
||||
0x8, MT6397_INT_RSV, 0x10, MTK_PMIC_PWRKEY_RST),
|
||||
.keys_regs[MTK_PMIC_HOMEKEY_INDEX] =
|
||||
MTK_PMIC_KEYS_REGS(MT6397_OCSTATUS2,
|
||||
0x10, MT6397_INT_RSV, 0x8),
|
||||
0x10, MT6397_INT_RSV, 0x8, MTK_PMIC_HOMEKEY_RST),
|
||||
.pmic_rst_reg = MT6397_TOP_RST_MISC,
|
||||
.rst_lprst_mask = MTK_PMIC_RST_DU_MASK,
|
||||
};
|
||||
|
||||
static const struct mtk_pmic_regs mt6323_regs = {
|
||||
.keys_regs[MTK_PMIC_PWRKEY_INDEX] =
|
||||
MTK_PMIC_KEYS_REGS(MT6323_CHRSTATUS,
|
||||
0x2, MT6323_INT_MISC_CON, 0x10),
|
||||
0x2, MT6323_INT_MISC_CON, 0x10, MTK_PMIC_PWRKEY_RST),
|
||||
.keys_regs[MTK_PMIC_HOMEKEY_INDEX] =
|
||||
MTK_PMIC_KEYS_REGS(MT6323_CHRSTATUS,
|
||||
0x4, MT6323_INT_MISC_CON, 0x8),
|
||||
0x4, MT6323_INT_MISC_CON, 0x8, MTK_PMIC_HOMEKEY_RST),
|
||||
.pmic_rst_reg = MT6323_TOP_RST_MISC,
|
||||
.rst_lprst_mask = MTK_PMIC_RST_DU_MASK,
|
||||
};
|
||||
|
||||
static const struct mtk_pmic_regs mt6358_regs = {
|
||||
.keys_regs[MTK_PMIC_PWRKEY_INDEX] =
|
||||
MTK_PMIC_KEYS_REGS(MT6358_TOPSTATUS,
|
||||
0x2, MT6358_PSC_TOP_INT_CON0, 0x5),
|
||||
0x2, MT6358_PSC_TOP_INT_CON0, 0x5,
|
||||
MTK_PMIC_PWRKEY_RST),
|
||||
.keys_regs[MTK_PMIC_HOMEKEY_INDEX] =
|
||||
MTK_PMIC_KEYS_REGS(MT6358_TOPSTATUS,
|
||||
0x8, MT6358_PSC_TOP_INT_CON0, 0xa),
|
||||
0x8, MT6358_PSC_TOP_INT_CON0, 0xa,
|
||||
MTK_PMIC_HOMEKEY_RST),
|
||||
.pmic_rst_reg = MT6358_TOP_RST_MISC,
|
||||
.rst_lprst_mask = MTK_PMIC_RST_DU_MASK,
|
||||
};
|
||||
|
||||
struct mtk_pmic_keys_info {
|
||||
|
@ -108,53 +108,49 @@ enum mtk_pmic_keys_lp_mode {
|
|||
};
|
||||
|
||||
static void mtk_pmic_keys_lp_reset_setup(struct mtk_pmic_keys *keys,
|
||||
u32 pmic_rst_reg)
|
||||
const struct mtk_pmic_regs *regs)
|
||||
{
|
||||
int ret;
|
||||
const struct mtk_pmic_keys_regs *kregs_home, *kregs_pwr;
|
||||
u32 long_press_mode, long_press_debounce;
|
||||
u32 value, mask;
|
||||
int error;
|
||||
|
||||
ret = of_property_read_u32(keys->dev->of_node,
|
||||
"power-off-time-sec", &long_press_debounce);
|
||||
if (ret)
|
||||
kregs_home = keys->keys[MTK_PMIC_HOMEKEY_INDEX].regs;
|
||||
kregs_pwr = keys->keys[MTK_PMIC_PWRKEY_INDEX].regs;
|
||||
|
||||
error = of_property_read_u32(keys->dev->of_node, "power-off-time-sec",
|
||||
&long_press_debounce);
|
||||
if (error)
|
||||
long_press_debounce = 0;
|
||||
|
||||
regmap_update_bits(keys->regmap, pmic_rst_reg,
|
||||
MTK_PMIC_RST_DU_MASK << MTK_PMIC_RST_DU_SHIFT,
|
||||
long_press_debounce << MTK_PMIC_RST_DU_SHIFT);
|
||||
mask = regs->rst_lprst_mask;
|
||||
value = long_press_debounce << (ffs(regs->rst_lprst_mask) - 1);
|
||||
|
||||
ret = of_property_read_u32(keys->dev->of_node,
|
||||
"mediatek,long-press-mode", &long_press_mode);
|
||||
if (ret)
|
||||
error = of_property_read_u32(keys->dev->of_node,
|
||||
"mediatek,long-press-mode",
|
||||
&long_press_mode);
|
||||
if (error)
|
||||
long_press_mode = LP_DISABLE;
|
||||
|
||||
switch (long_press_mode) {
|
||||
case LP_ONEKEY:
|
||||
regmap_update_bits(keys->regmap, pmic_rst_reg,
|
||||
MTK_PMIC_PWRKEY_RST,
|
||||
MTK_PMIC_PWRKEY_RST);
|
||||
regmap_update_bits(keys->regmap, pmic_rst_reg,
|
||||
MTK_PMIC_HOMEKEY_RST,
|
||||
0);
|
||||
break;
|
||||
case LP_TWOKEY:
|
||||
regmap_update_bits(keys->regmap, pmic_rst_reg,
|
||||
MTK_PMIC_PWRKEY_RST,
|
||||
MTK_PMIC_PWRKEY_RST);
|
||||
regmap_update_bits(keys->regmap, pmic_rst_reg,
|
||||
MTK_PMIC_HOMEKEY_RST,
|
||||
MTK_PMIC_HOMEKEY_RST);
|
||||
break;
|
||||
value |= kregs_home->rst_en_mask;
|
||||
fallthrough;
|
||||
|
||||
case LP_ONEKEY:
|
||||
value |= kregs_pwr->rst_en_mask;
|
||||
fallthrough;
|
||||
|
||||
case LP_DISABLE:
|
||||
regmap_update_bits(keys->regmap, pmic_rst_reg,
|
||||
MTK_PMIC_PWRKEY_RST,
|
||||
0);
|
||||
regmap_update_bits(keys->regmap, pmic_rst_reg,
|
||||
MTK_PMIC_HOMEKEY_RST,
|
||||
0);
|
||||
mask |= kregs_home->rst_en_mask;
|
||||
mask |= kregs_pwr->rst_en_mask;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
regmap_update_bits(keys->regmap, regs->pmic_rst_reg, mask, value);
|
||||
}
|
||||
|
||||
static irqreturn_t mtk_pmic_keys_irq_handler_thread(int irq, void *data)
|
||||
|
@ -358,7 +354,7 @@ static int mtk_pmic_keys_probe(struct platform_device *pdev)
|
|||
return error;
|
||||
}
|
||||
|
||||
mtk_pmic_keys_lp_reset_setup(keys, mtk_pmic_regs->pmic_rst_reg);
|
||||
mtk_pmic_keys_lp_reset_setup(keys, mtk_pmic_regs);
|
||||
|
||||
platform_set_drvdata(pdev, keys);
|
||||
|
||||
|
|
|
@ -179,11 +179,9 @@ static irqreturn_t omap4_keypad_irq_thread_fn(int irq, void *dev_id)
|
|||
int error;
|
||||
u64 keys;
|
||||
|
||||
error = pm_runtime_get_sync(dev);
|
||||
if (error < 0) {
|
||||
pm_runtime_put_noidle(dev);
|
||||
error = pm_runtime_resume_and_get(dev);
|
||||
if (error)
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
low = kbd_readl(keypad_data, OMAP4_KBD_FULLCODE31_0);
|
||||
high = kbd_readl(keypad_data, OMAP4_KBD_FULLCODE63_32);
|
||||
|
@ -207,11 +205,9 @@ static int omap4_keypad_open(struct input_dev *input)
|
|||
struct device *dev = input->dev.parent;
|
||||
int error;
|
||||
|
||||
error = pm_runtime_get_sync(dev);
|
||||
if (error < 0) {
|
||||
pm_runtime_put_noidle(dev);
|
||||
error = pm_runtime_resume_and_get(dev);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
disable_irq(keypad_data->irq);
|
||||
|
||||
|
@ -254,9 +250,10 @@ static void omap4_keypad_close(struct input_dev *input)
|
|||
struct device *dev = input->dev.parent;
|
||||
int error;
|
||||
|
||||
error = pm_runtime_get_sync(dev);
|
||||
if (error < 0)
|
||||
pm_runtime_put_noidle(dev);
|
||||
error = pm_runtime_resume_and_get(dev);
|
||||
if (error)
|
||||
dev_err(dev, "%s: pm_runtime_resume_and_get() failed: %d\n",
|
||||
__func__, error);
|
||||
|
||||
disable_irq(keypad_data->irq);
|
||||
omap4_keypad_stop(keypad_data);
|
||||
|
@ -392,10 +389,9 @@ static int omap4_keypad_probe(struct platform_device *pdev)
|
|||
* Enable clocks for the keypad module so that we can read
|
||||
* revision register.
|
||||
*/
|
||||
error = pm_runtime_get_sync(dev);
|
||||
if (error < 0) {
|
||||
dev_err(dev, "pm_runtime_get_sync() failed\n");
|
||||
pm_runtime_put_noidle(dev);
|
||||
error = pm_runtime_resume_and_get(dev);
|
||||
if (error) {
|
||||
dev_err(dev, "pm_runtime_resume_and_get() failed\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
#define IQS7222_SLDR_SETUP_2_RES_MASK GENMASK(15, 8)
|
||||
#define IQS7222_SLDR_SETUP_2_RES_SHIFT 8
|
||||
#define IQS7222_SLDR_SETUP_2_TOP_SPEED_MASK GENMASK(7, 0)
|
||||
#define IQS7222_SLDR_SETUP_3_CHAN_SEL_MASK GENMASK(9, 0)
|
||||
|
||||
#define IQS7222_GPIO_SETUP_0_GPIO_EN BIT(0)
|
||||
|
||||
|
@ -54,6 +53,9 @@
|
|||
#define IQS7222_SYS_SETUP_ACK_RESET BIT(0)
|
||||
|
||||
#define IQS7222_EVENT_MASK_ATI BIT(12)
|
||||
#define IQS7222_EVENT_MASK_SLDR BIT(10)
|
||||
#define IQS7222_EVENT_MASK_TOUCH BIT(1)
|
||||
#define IQS7222_EVENT_MASK_PROX BIT(0)
|
||||
|
||||
#define IQS7222_COMMS_HOLD BIT(0)
|
||||
#define IQS7222_COMMS_ERROR 0xEEEE
|
||||
|
@ -92,11 +94,11 @@ enum iqs7222_reg_key_id {
|
|||
|
||||
enum iqs7222_reg_grp_id {
|
||||
IQS7222_REG_GRP_STAT,
|
||||
IQS7222_REG_GRP_FILT,
|
||||
IQS7222_REG_GRP_CYCLE,
|
||||
IQS7222_REG_GRP_GLBL,
|
||||
IQS7222_REG_GRP_BTN,
|
||||
IQS7222_REG_GRP_CHAN,
|
||||
IQS7222_REG_GRP_FILT,
|
||||
IQS7222_REG_GRP_SLDR,
|
||||
IQS7222_REG_GRP_GPIO,
|
||||
IQS7222_REG_GRP_SYS,
|
||||
|
@ -135,12 +137,12 @@ struct iqs7222_event_desc {
|
|||
static const struct iqs7222_event_desc iqs7222_kp_events[] = {
|
||||
{
|
||||
.name = "event-prox",
|
||||
.enable = BIT(0),
|
||||
.enable = IQS7222_EVENT_MASK_PROX,
|
||||
.reg_key = IQS7222_REG_KEY_PROX,
|
||||
},
|
||||
{
|
||||
.name = "event-touch",
|
||||
.enable = BIT(1),
|
||||
.enable = IQS7222_EVENT_MASK_TOUCH,
|
||||
.reg_key = IQS7222_REG_KEY_TOUCH,
|
||||
},
|
||||
};
|
||||
|
@ -555,13 +557,6 @@ static const struct iqs7222_prop_desc iqs7222_props[] = {
|
|||
.reg_width = 4,
|
||||
.label = "current reference trim",
|
||||
},
|
||||
{
|
||||
.name = "azoteq,rf-filt-enable",
|
||||
.reg_grp = IQS7222_REG_GRP_GLBL,
|
||||
.reg_offset = 0,
|
||||
.reg_shift = 15,
|
||||
.reg_width = 1,
|
||||
},
|
||||
{
|
||||
.name = "azoteq,max-counts",
|
||||
.reg_grp = IQS7222_REG_GRP_GLBL,
|
||||
|
@ -1272,9 +1267,22 @@ static int iqs7222_ati_trigger(struct iqs7222_private *iqs7222)
|
|||
struct i2c_client *client = iqs7222->client;
|
||||
ktime_t ati_timeout;
|
||||
u16 sys_status = 0;
|
||||
u16 sys_setup = iqs7222->sys_setup[0] & ~IQS7222_SYS_SETUP_ACK_RESET;
|
||||
u16 sys_setup;
|
||||
int error, i;
|
||||
|
||||
/*
|
||||
* The reserved fields of the system setup register may have changed
|
||||
* as a result of other registers having been written. As such, read
|
||||
* the register's latest value to avoid unexpected behavior when the
|
||||
* register is written in the loop that follows.
|
||||
*/
|
||||
error = iqs7222_read_word(iqs7222, IQS7222_SYS_SETUP, &sys_setup);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
sys_setup &= ~IQS7222_SYS_SETUP_INTF_MODE_MASK;
|
||||
sys_setup &= ~IQS7222_SYS_SETUP_PWR_MODE_MASK;
|
||||
|
||||
for (i = 0; i < IQS7222_NUM_RETRIES; i++) {
|
||||
/*
|
||||
* Trigger ATI from streaming and normal-power modes so that
|
||||
|
@ -1299,12 +1307,15 @@ static int iqs7222_ati_trigger(struct iqs7222_private *iqs7222)
|
|||
if (error)
|
||||
return error;
|
||||
|
||||
if (sys_status & IQS7222_SYS_STATUS_ATI_ACTIVE)
|
||||
continue;
|
||||
if (sys_status & IQS7222_SYS_STATUS_RESET)
|
||||
return 0;
|
||||
|
||||
if (sys_status & IQS7222_SYS_STATUS_ATI_ERROR)
|
||||
break;
|
||||
|
||||
if (sys_status & IQS7222_SYS_STATUS_ATI_ACTIVE)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Use stream-in-touch mode if either slider reports
|
||||
* absolute position.
|
||||
|
@ -1321,7 +1332,7 @@ static int iqs7222_ati_trigger(struct iqs7222_private *iqs7222)
|
|||
dev_err(&client->dev,
|
||||
"ATI attempt %d of %d failed with status 0x%02X, %s\n",
|
||||
i + 1, IQS7222_NUM_RETRIES, (u8)sys_status,
|
||||
i < IQS7222_NUM_RETRIES ? "retrying..." : "stopping");
|
||||
i + 1 < IQS7222_NUM_RETRIES ? "retrying" : "stopping");
|
||||
}
|
||||
|
||||
return -ETIMEDOUT;
|
||||
|
@ -1333,6 +1344,34 @@ static int iqs7222_dev_init(struct iqs7222_private *iqs7222, int dir)
|
|||
int comms_offset = dev_desc->comms_offset;
|
||||
int error, i, j, k;
|
||||
|
||||
/*
|
||||
* Acknowledge reset before writing any registers in case the device
|
||||
* suffers a spurious reset during initialization. Because this step
|
||||
* may change the reserved fields of the second filter beta register,
|
||||
* its cache must be updated.
|
||||
*
|
||||
* Writing the second filter beta register, in turn, may clobber the
|
||||
* system status register. As such, the filter beta register pair is
|
||||
* written first to protect against this hazard.
|
||||
*/
|
||||
if (dir == WRITE) {
|
||||
u16 reg = dev_desc->reg_grps[IQS7222_REG_GRP_FILT].base + 1;
|
||||
u16 filt_setup;
|
||||
|
||||
error = iqs7222_write_word(iqs7222, IQS7222_SYS_SETUP,
|
||||
iqs7222->sys_setup[0] |
|
||||
IQS7222_SYS_SETUP_ACK_RESET);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = iqs7222_read_word(iqs7222, reg, &filt_setup);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
iqs7222->filt_setup[1] &= GENMASK(7, 0);
|
||||
iqs7222->filt_setup[1] |= (filt_setup & ~GENMASK(7, 0));
|
||||
}
|
||||
|
||||
/*
|
||||
* Take advantage of the stop-bit disable function, if available, to
|
||||
* save the trouble of having to reopen a communication window after
|
||||
|
@ -1957,8 +1996,8 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
|
|||
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;
|
||||
u16 *event_mask = &iqs7222->sys_setup[dev_desc->event_offset];
|
||||
u16 *sldr_setup = iqs7222->sldr_setup[sldr_index];
|
||||
u16 *sys_setup = iqs7222->sys_setup;
|
||||
unsigned int chan_sel[4], val;
|
||||
|
||||
error = iqs7222_parse_props(iqs7222, &sldr_node, sldr_index,
|
||||
|
@ -2003,7 +2042,7 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
|
|||
reg_offset = dev_desc->sldr_res < U16_MAX ? 0 : 1;
|
||||
|
||||
sldr_setup[0] |= count;
|
||||
sldr_setup[3 + reg_offset] &= ~IQS7222_SLDR_SETUP_3_CHAN_SEL_MASK;
|
||||
sldr_setup[3 + reg_offset] &= ~GENMASK(ext_chan - 1, 0);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(chan_sel); i++) {
|
||||
sldr_setup[5 + reg_offset + i] = 0;
|
||||
|
@ -2081,17 +2120,19 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
|
|||
sldr_setup[0] |= dev_desc->wheel_enable;
|
||||
}
|
||||
|
||||
/*
|
||||
* The absence of a register offset makes it safe to assume the device
|
||||
* supports gestures, each of which is first disabled until explicitly
|
||||
* enabled.
|
||||
*/
|
||||
if (!reg_offset)
|
||||
for (i = 0; i < ARRAY_SIZE(iqs7222_sl_events); i++)
|
||||
sldr_setup[9] &= ~iqs7222_sl_events[i].enable;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(iqs7222_sl_events); i++) {
|
||||
const char *event_name = iqs7222_sl_events[i].name;
|
||||
struct fwnode_handle *event_node;
|
||||
|
||||
/*
|
||||
* The absence of a register offset means the remaining fields
|
||||
* in the group represent gesture settings.
|
||||
*/
|
||||
if (iqs7222_sl_events[i].enable && !reg_offset)
|
||||
sldr_setup[9] &= ~iqs7222_sl_events[i].enable;
|
||||
|
||||
event_node = fwnode_get_named_child_node(sldr_node, event_name);
|
||||
if (!event_node)
|
||||
continue;
|
||||
|
@ -2104,6 +2145,22 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
|
|||
if (error)
|
||||
return error;
|
||||
|
||||
/*
|
||||
* 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,
|
||||
i ? iqs7222_sl_events[i].enable
|
||||
: sldr_setup[3 + reg_offset],
|
||||
i ? 1568 + sldr_index * 30
|
||||
: sldr_setup[4 + reg_offset]);
|
||||
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) {
|
||||
|
@ -2115,26 +2172,20 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
|
|||
iqs7222->sl_code[sldr_index][i] = val;
|
||||
input_set_capability(iqs7222->keypad, EV_KEY, val);
|
||||
|
||||
/*
|
||||
* The press/release event is determined based on whether the
|
||||
* coordinate field reports 0xFFFF and has no explicit enable
|
||||
* control.
|
||||
*/
|
||||
if (!iqs7222_sl_events[i].enable || reg_offset)
|
||||
continue;
|
||||
|
||||
sldr_setup[9] |= iqs7222_sl_events[i].enable;
|
||||
|
||||
error = iqs7222_gpio_select(iqs7222, event_node,
|
||||
iqs7222_sl_events[i].enable,
|
||||
1568 + sldr_index * 30);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (!dev_desc->event_offset)
|
||||
continue;
|
||||
|
||||
sys_setup[dev_desc->event_offset] |= BIT(10 + sldr_index);
|
||||
/*
|
||||
* The press/release event is determined based on whether the
|
||||
* coordinate field reports 0xFFFF and solely relies on touch
|
||||
* or proximity interrupts to be unmasked.
|
||||
*/
|
||||
if (i && !reg_offset)
|
||||
*event_mask |= (IQS7222_EVENT_MASK_SLDR << sldr_index);
|
||||
else if (sldr_setup[4 + reg_offset] == dev_desc->touch_link)
|
||||
*event_mask |= IQS7222_EVENT_MASK_TOUCH;
|
||||
else
|
||||
*event_mask |= IQS7222_EVENT_MASK_PROX;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2227,11 +2278,6 @@ static int iqs7222_parse_all(struct iqs7222_private *iqs7222)
|
|||
return error;
|
||||
}
|
||||
|
||||
sys_setup[0] &= ~IQS7222_SYS_SETUP_INTF_MODE_MASK;
|
||||
sys_setup[0] &= ~IQS7222_SYS_SETUP_PWR_MODE_MASK;
|
||||
|
||||
sys_setup[0] |= IQS7222_SYS_SETUP_ACK_RESET;
|
||||
|
||||
return iqs7222_parse_props(iqs7222, NULL, 0, IQS7222_REG_GRP_SYS,
|
||||
IQS7222_REG_KEY_NONE);
|
||||
}
|
||||
|
@ -2299,29 +2345,37 @@ static int iqs7222_report(struct iqs7222_private *iqs7222)
|
|||
input_report_abs(iqs7222->keypad, iqs7222->sl_axis[i],
|
||||
sldr_pos);
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(iqs7222_sl_events); j++) {
|
||||
input_report_key(iqs7222->keypad, iqs7222->sl_code[i][0],
|
||||
sldr_pos < dev_desc->sldr_res);
|
||||
|
||||
/*
|
||||
* A maximum resolution indicates the device does not support
|
||||
* gestures, in which case the remaining fields are ignored.
|
||||
*/
|
||||
if (dev_desc->sldr_res == U16_MAX)
|
||||
continue;
|
||||
|
||||
if (!(le16_to_cpu(status[1]) & IQS7222_EVENT_MASK_SLDR << i))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Skip the press/release event, as it does not have separate
|
||||
* status fields and is handled separately.
|
||||
*/
|
||||
for (j = 1; j < ARRAY_SIZE(iqs7222_sl_events); j++) {
|
||||
u16 mask = iqs7222_sl_events[j].mask;
|
||||
u16 val = iqs7222_sl_events[j].val;
|
||||
|
||||
if (!iqs7222_sl_events[j].enable) {
|
||||
input_report_key(iqs7222->keypad,
|
||||
iqs7222->sl_code[i][j],
|
||||
sldr_pos < dev_desc->sldr_res);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* The remaining offsets represent gesture state, and
|
||||
* are discarded in the case of IQS7222C because only
|
||||
* absolute position is reported.
|
||||
*/
|
||||
if (num_stat < IQS7222_MAX_COLS_STAT)
|
||||
continue;
|
||||
|
||||
input_report_key(iqs7222->keypad,
|
||||
iqs7222->sl_code[i][j],
|
||||
(state & mask) == val);
|
||||
}
|
||||
|
||||
input_sync(iqs7222->keypad);
|
||||
|
||||
for (j = 1; j < ARRAY_SIZE(iqs7222_sl_events); j++)
|
||||
input_report_key(iqs7222->keypad,
|
||||
iqs7222->sl_code[i][j], 0);
|
||||
}
|
||||
|
||||
input_sync(iqs7222->keypad);
|
||||
|
|
|
@ -57,7 +57,7 @@ struct pip_app_resp_head {
|
|||
* The value of data_status can be the first byte of data or
|
||||
* the command status or the unsupported command code depending on the
|
||||
* requested command code.
|
||||
*/
|
||||
*/
|
||||
u8 data_status;
|
||||
} __packed;
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ struct gpio_mouse {
|
|||
|
||||
/*
|
||||
* Timer function which is run every scan_ms ms when the device is opened.
|
||||
* The dev input variable is set to the the input_dev pointer.
|
||||
* The dev input variable is set to the input_dev pointer.
|
||||
*/
|
||||
static void gpio_mouse_scan(struct input_dev *input)
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -24,6 +24,7 @@
|
|||
#include <linux/irq.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/ratelimit.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -47,6 +48,8 @@
|
|||
#define M09_REGISTER_NUM_X 0x94
|
||||
#define M09_REGISTER_NUM_Y 0x95
|
||||
|
||||
#define M12_REGISTER_REPORT_RATE 0x88
|
||||
|
||||
#define EV_REGISTER_THRESHOLD 0x40
|
||||
#define EV_REGISTER_GAIN 0x41
|
||||
#define EV_REGISTER_OFFSET_Y 0x45
|
||||
|
@ -127,9 +130,12 @@ struct edt_ft5x06_ts_data {
|
|||
int max_support_points;
|
||||
|
||||
char name[EDT_NAME_LEN];
|
||||
char fw_version[EDT_NAME_LEN];
|
||||
|
||||
struct edt_reg_addr reg_addr;
|
||||
enum edt_ver version;
|
||||
unsigned int crc_errors;
|
||||
unsigned int header_errors;
|
||||
};
|
||||
|
||||
struct edt_i2c_chip_data {
|
||||
|
@ -178,6 +184,7 @@ static bool edt_ft5x06_ts_check_crc(struct edt_ft5x06_ts_data *tsdata,
|
|||
crc ^= buf[i];
|
||||
|
||||
if (crc != buf[buflen-1]) {
|
||||
tsdata->crc_errors++;
|
||||
dev_err_ratelimited(&tsdata->client->dev,
|
||||
"crc error: 0x%02x expected, got 0x%02x\n",
|
||||
crc, buf[buflen-1]);
|
||||
|
@ -235,6 +242,7 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
|
|||
if (tsdata->version == EDT_M06) {
|
||||
if (rdbuf[0] != 0xaa || rdbuf[1] != 0xaa ||
|
||||
rdbuf[2] != datalen) {
|
||||
tsdata->header_errors++;
|
||||
dev_err_ratelimited(dev,
|
||||
"Unexpected header: %02x%02x%02x!\n",
|
||||
rdbuf[0], rdbuf[1], rdbuf[2]);
|
||||
|
@ -523,9 +531,55 @@ static EDT_ATTR(offset_y, S_IWUSR | S_IRUGO, NO_REGISTER, NO_REGISTER,
|
|||
/* m06: range 20 to 80, m09: range 0 to 30, m12: range 1 to 255... */
|
||||
static EDT_ATTR(threshold, S_IWUSR | S_IRUGO, WORK_REGISTER_THRESHOLD,
|
||||
M09_REGISTER_THRESHOLD, EV_REGISTER_THRESHOLD, 0, 255);
|
||||
/* m06: range 3 to 14, m12: (0x64: 100Hz) */
|
||||
/* m06: range 3 to 14, m12: range 1 to 255 */
|
||||
static EDT_ATTR(report_rate, S_IWUSR | S_IRUGO, WORK_REGISTER_REPORT_RATE,
|
||||
NO_REGISTER, NO_REGISTER, 0, 255);
|
||||
M12_REGISTER_REPORT_RATE, NO_REGISTER, 0, 255);
|
||||
|
||||
static ssize_t model_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
|
||||
|
||||
return sysfs_emit(buf, "%s\n", tsdata->name);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RO(model);
|
||||
|
||||
static ssize_t fw_version_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
|
||||
|
||||
return sysfs_emit(buf, "%s\n", tsdata->fw_version);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RO(fw_version);
|
||||
|
||||
/* m06 only */
|
||||
static ssize_t header_errors_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
|
||||
|
||||
return sysfs_emit(buf, "%d\n", tsdata->header_errors);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RO(header_errors);
|
||||
|
||||
/* m06 only */
|
||||
static ssize_t crc_errors_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
|
||||
|
||||
return sysfs_emit(buf, "%d\n", tsdata->crc_errors);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RO(crc_errors);
|
||||
|
||||
static struct attribute *edt_ft5x06_attrs[] = {
|
||||
&edt_ft5x06_attr_gain.dattr.attr,
|
||||
|
@ -534,6 +588,10 @@ static struct attribute *edt_ft5x06_attrs[] = {
|
|||
&edt_ft5x06_attr_offset_y.dattr.attr,
|
||||
&edt_ft5x06_attr_threshold.dattr.attr,
|
||||
&edt_ft5x06_attr_report_rate.dattr.attr,
|
||||
&dev_attr_model.attr,
|
||||
&dev_attr_fw_version.attr,
|
||||
&dev_attr_header_errors.attr,
|
||||
&dev_attr_crc_errors.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -820,13 +878,13 @@ static void edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)
|
|||
#endif /* CONFIG_DEBUGFS */
|
||||
|
||||
static int edt_ft5x06_ts_identify(struct i2c_client *client,
|
||||
struct edt_ft5x06_ts_data *tsdata,
|
||||
char *fw_version)
|
||||
struct edt_ft5x06_ts_data *tsdata)
|
||||
{
|
||||
u8 rdbuf[EDT_NAME_LEN];
|
||||
char *p;
|
||||
int error;
|
||||
char *model_name = tsdata->name;
|
||||
char *fw_version = tsdata->fw_version;
|
||||
|
||||
/* see what we find if we assume it is a M06 *
|
||||
* if we get less than EDT_NAME_LEN, we don't want
|
||||
|
@ -1030,7 +1088,8 @@ static void edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata)
|
|||
case EDT_M09:
|
||||
case EDT_M12:
|
||||
reg_addr->reg_threshold = M09_REGISTER_THRESHOLD;
|
||||
reg_addr->reg_report_rate = NO_REGISTER;
|
||||
reg_addr->reg_report_rate = tsdata->version == EDT_M12 ?
|
||||
M12_REGISTER_REPORT_RATE : NO_REGISTER;
|
||||
reg_addr->reg_gain = M09_REGISTER_GAIN;
|
||||
reg_addr->reg_offset = M09_REGISTER_OFFSET;
|
||||
reg_addr->reg_offset_x = NO_REGISTER;
|
||||
|
@ -1081,7 +1140,7 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
|
|||
struct input_dev *input;
|
||||
unsigned long irq_flags;
|
||||
int error;
|
||||
char fw_version[EDT_NAME_LEN];
|
||||
u32 report_rate;
|
||||
|
||||
dev_dbg(&client->dev, "probing for EDT FT5x06 I2C\n");
|
||||
|
||||
|
@ -1194,7 +1253,7 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
|
|||
tsdata->input = input;
|
||||
tsdata->factory_mode = false;
|
||||
|
||||
error = edt_ft5x06_ts_identify(client, tsdata, fw_version);
|
||||
error = edt_ft5x06_ts_identify(client, tsdata);
|
||||
if (error) {
|
||||
dev_err(&client->dev, "touchscreen probe failed\n");
|
||||
return error;
|
||||
|
@ -1210,9 +1269,30 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
|
|||
edt_ft5x06_ts_get_defaults(&client->dev, tsdata);
|
||||
edt_ft5x06_ts_get_parameters(tsdata);
|
||||
|
||||
if (tsdata->reg_addr.reg_report_rate != NO_REGISTER &&
|
||||
!device_property_read_u32(&client->dev,
|
||||
"report-rate-hz", &report_rate)) {
|
||||
if (tsdata->version == EDT_M06)
|
||||
tsdata->report_rate = clamp_val(report_rate, 30, 140);
|
||||
else
|
||||
tsdata->report_rate = clamp_val(report_rate, 1, 255);
|
||||
|
||||
if (report_rate != tsdata->report_rate)
|
||||
dev_warn(&client->dev,
|
||||
"report-rate %dHz is unsupported, use %dHz\n",
|
||||
report_rate, tsdata->report_rate);
|
||||
|
||||
if (tsdata->version == EDT_M06)
|
||||
tsdata->report_rate /= 10;
|
||||
|
||||
edt_ft5x06_register_write(tsdata,
|
||||
tsdata->reg_addr.reg_report_rate,
|
||||
tsdata->report_rate);
|
||||
}
|
||||
|
||||
dev_dbg(&client->dev,
|
||||
"Model \"%s\", Rev. \"%s\", %dx%d sensors\n",
|
||||
tsdata->name, fw_version, tsdata->num_x, tsdata->num_y);
|
||||
tsdata->name, tsdata->fw_version, tsdata->num_x, tsdata->num_y);
|
||||
|
||||
input->name = tsdata->name;
|
||||
input->id.bustype = BUS_I2C;
|
||||
|
|
|
@ -220,6 +220,7 @@ static int exc3000_vendor_data_request(struct exc3000_data *data, u8 *request,
|
|||
{
|
||||
u8 buf[EXC3000_LEN_VENDOR_REQUEST] = { 0x67, 0x00, 0x42, 0x00, 0x03 };
|
||||
int ret;
|
||||
unsigned long time_left;
|
||||
|
||||
mutex_lock(&data->query_lock);
|
||||
|
||||
|
@ -233,9 +234,9 @@ static int exc3000_vendor_data_request(struct exc3000_data *data, u8 *request,
|
|||
goto out_unlock;
|
||||
|
||||
if (response) {
|
||||
ret = wait_for_completion_timeout(&data->wait_event,
|
||||
timeout * HZ);
|
||||
if (ret <= 0) {
|
||||
time_left = wait_for_completion_timeout(&data->wait_event,
|
||||
timeout * HZ);
|
||||
if (time_left == 0) {
|
||||
ret = -ETIMEDOUT;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
|
|
@ -822,22 +822,16 @@ static int goodix_resource(struct acpi_resource *ares, void *data)
|
|||
struct device *dev = &ts->client->dev;
|
||||
struct acpi_resource_gpio *gpio;
|
||||
|
||||
switch (ares->type) {
|
||||
case ACPI_RESOURCE_TYPE_GPIO:
|
||||
gpio = &ares->data.gpio;
|
||||
if (gpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT) {
|
||||
if (ts->gpio_int_idx == -1) {
|
||||
ts->gpio_int_idx = ts->gpio_count;
|
||||
} else {
|
||||
dev_err(dev, "More then one GpioInt resource, ignoring ACPI GPIO resources\n");
|
||||
ts->gpio_int_idx = -2;
|
||||
}
|
||||
if (acpi_gpio_get_irq_resource(ares, &gpio)) {
|
||||
if (ts->gpio_int_idx == -1) {
|
||||
ts->gpio_int_idx = ts->gpio_count;
|
||||
} else {
|
||||
dev_err(dev, "More then one GpioInt resource, ignoring ACPI GPIO resources\n");
|
||||
ts->gpio_int_idx = -2;
|
||||
}
|
||||
ts->gpio_count++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (acpi_gpio_get_io_resource(ares, &gpio))
|
||||
ts->gpio_count++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -15,75 +15,75 @@
|
|||
|
||||
/* Register Map */
|
||||
|
||||
#define BT541_SWRESET_CMD 0x0000
|
||||
#define BT541_WAKEUP_CMD 0x0001
|
||||
#define ZINITIX_SWRESET_CMD 0x0000
|
||||
#define ZINITIX_WAKEUP_CMD 0x0001
|
||||
|
||||
#define BT541_IDLE_CMD 0x0004
|
||||
#define BT541_SLEEP_CMD 0x0005
|
||||
#define ZINITIX_IDLE_CMD 0x0004
|
||||
#define ZINITIX_SLEEP_CMD 0x0005
|
||||
|
||||
#define BT541_CLEAR_INT_STATUS_CMD 0x0003
|
||||
#define BT541_CALIBRATE_CMD 0x0006
|
||||
#define BT541_SAVE_STATUS_CMD 0x0007
|
||||
#define BT541_SAVE_CALIBRATION_CMD 0x0008
|
||||
#define BT541_RECALL_FACTORY_CMD 0x000f
|
||||
#define ZINITIX_CLEAR_INT_STATUS_CMD 0x0003
|
||||
#define ZINITIX_CALIBRATE_CMD 0x0006
|
||||
#define ZINITIX_SAVE_STATUS_CMD 0x0007
|
||||
#define ZINITIX_SAVE_CALIBRATION_CMD 0x0008
|
||||
#define ZINITIX_RECALL_FACTORY_CMD 0x000f
|
||||
|
||||
#define BT541_THRESHOLD 0x0020
|
||||
#define ZINITIX_THRESHOLD 0x0020
|
||||
|
||||
#define BT541_LARGE_PALM_REJECT_AREA_TH 0x003F
|
||||
#define ZINITIX_LARGE_PALM_REJECT_AREA_TH 0x003F
|
||||
|
||||
#define BT541_DEBUG_REG 0x0115 /* 0~7 */
|
||||
#define ZINITIX_DEBUG_REG 0x0115 /* 0~7 */
|
||||
|
||||
#define BT541_TOUCH_MODE 0x0010
|
||||
#define BT541_CHIP_REVISION 0x0011
|
||||
#define BT541_FIRMWARE_VERSION 0x0012
|
||||
#define ZINITIX_TOUCH_MODE 0x0010
|
||||
#define ZINITIX_CHIP_REVISION 0x0011
|
||||
#define ZINITIX_FIRMWARE_VERSION 0x0012
|
||||
|
||||
#define ZINITIX_USB_DETECT 0x116
|
||||
|
||||
#define BT541_MINOR_FW_VERSION 0x0121
|
||||
#define ZINITIX_MINOR_FW_VERSION 0x0121
|
||||
|
||||
#define BT541_VENDOR_ID 0x001C
|
||||
#define BT541_HW_ID 0x0014
|
||||
#define ZINITIX_VENDOR_ID 0x001C
|
||||
#define ZINITIX_HW_ID 0x0014
|
||||
|
||||
#define BT541_DATA_VERSION_REG 0x0013
|
||||
#define BT541_SUPPORTED_FINGER_NUM 0x0015
|
||||
#define BT541_EEPROM_INFO 0x0018
|
||||
#define BT541_INITIAL_TOUCH_MODE 0x0019
|
||||
#define ZINITIX_DATA_VERSION_REG 0x0013
|
||||
#define ZINITIX_SUPPORTED_FINGER_NUM 0x0015
|
||||
#define ZINITIX_EEPROM_INFO 0x0018
|
||||
#define ZINITIX_INITIAL_TOUCH_MODE 0x0019
|
||||
|
||||
#define BT541_TOTAL_NUMBER_OF_X 0x0060
|
||||
#define BT541_TOTAL_NUMBER_OF_Y 0x0061
|
||||
#define ZINITIX_TOTAL_NUMBER_OF_X 0x0060
|
||||
#define ZINITIX_TOTAL_NUMBER_OF_Y 0x0061
|
||||
|
||||
#define BT541_DELAY_RAW_FOR_HOST 0x007f
|
||||
#define ZINITIX_DELAY_RAW_FOR_HOST 0x007f
|
||||
|
||||
#define BT541_BUTTON_SUPPORTED_NUM 0x00B0
|
||||
#define BT541_BUTTON_SENSITIVITY 0x00B2
|
||||
#define BT541_DUMMY_BUTTON_SENSITIVITY 0X00C8
|
||||
#define ZINITIX_BUTTON_SUPPORTED_NUM 0x00B0
|
||||
#define ZINITIX_BUTTON_SENSITIVITY 0x00B2
|
||||
#define ZINITIX_DUMMY_BUTTON_SENSITIVITY 0X00C8
|
||||
|
||||
#define BT541_X_RESOLUTION 0x00C0
|
||||
#define BT541_Y_RESOLUTION 0x00C1
|
||||
#define ZINITIX_X_RESOLUTION 0x00C0
|
||||
#define ZINITIX_Y_RESOLUTION 0x00C1
|
||||
|
||||
#define BT541_POINT_STATUS_REG 0x0080
|
||||
#define BT541_ICON_STATUS_REG 0x00AA
|
||||
#define ZINITIX_POINT_STATUS_REG 0x0080
|
||||
#define ZINITIX_ICON_STATUS_REG 0x00AA
|
||||
|
||||
#define BT541_POINT_COORD_REG (BT541_POINT_STATUS_REG + 2)
|
||||
#define ZINITIX_POINT_COORD_REG (ZINITIX_POINT_STATUS_REG + 2)
|
||||
|
||||
#define BT541_AFE_FREQUENCY 0x0100
|
||||
#define BT541_DND_N_COUNT 0x0122
|
||||
#define BT541_DND_U_COUNT 0x0135
|
||||
#define ZINITIX_AFE_FREQUENCY 0x0100
|
||||
#define ZINITIX_DND_N_COUNT 0x0122
|
||||
#define ZINITIX_DND_U_COUNT 0x0135
|
||||
|
||||
#define BT541_RAWDATA_REG 0x0200
|
||||
#define ZINITIX_RAWDATA_REG 0x0200
|
||||
|
||||
#define BT541_EEPROM_INFO_REG 0x0018
|
||||
#define ZINITIX_EEPROM_INFO_REG 0x0018
|
||||
|
||||
#define BT541_INT_ENABLE_FLAG 0x00f0
|
||||
#define BT541_PERIODICAL_INTERRUPT_INTERVAL 0x00f1
|
||||
#define ZINITIX_INT_ENABLE_FLAG 0x00f0
|
||||
#define ZINITIX_PERIODICAL_INTERRUPT_INTERVAL 0x00f1
|
||||
|
||||
#define BT541_BTN_WIDTH 0x016d
|
||||
#define ZINITIX_BTN_WIDTH 0x016d
|
||||
|
||||
#define BT541_CHECKSUM_RESULT 0x012c
|
||||
#define ZINITIX_CHECKSUM_RESULT 0x012c
|
||||
|
||||
#define BT541_INIT_FLASH 0x01d0
|
||||
#define BT541_WRITE_FLASH 0x01d1
|
||||
#define BT541_READ_FLASH 0x01d2
|
||||
#define ZINITIX_INIT_FLASH 0x01d0
|
||||
#define ZINITIX_WRITE_FLASH 0x01d1
|
||||
#define ZINITIX_READ_FLASH 0x01d2
|
||||
|
||||
#define ZINITIX_INTERNAL_FLAG_02 0x011e
|
||||
#define ZINITIX_INTERNAL_FLAG_03 0x011f
|
||||
|
@ -196,13 +196,13 @@ static int zinitix_init_touch(struct bt541_ts_data *bt541)
|
|||
int i;
|
||||
int error;
|
||||
|
||||
error = zinitix_write_cmd(client, BT541_SWRESET_CMD);
|
||||
error = zinitix_write_cmd(client, ZINITIX_SWRESET_CMD);
|
||||
if (error) {
|
||||
dev_err(&client->dev, "Failed to write reset command\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
error = zinitix_write_u16(client, BT541_INT_ENABLE_FLAG, 0x0);
|
||||
error = zinitix_write_u16(client, ZINITIX_INT_ENABLE_FLAG, 0x0);
|
||||
if (error) {
|
||||
dev_err(&client->dev,
|
||||
"Failed to reset interrupt enable flag\n");
|
||||
|
@ -210,32 +210,32 @@ static int zinitix_init_touch(struct bt541_ts_data *bt541)
|
|||
}
|
||||
|
||||
/* initialize */
|
||||
error = zinitix_write_u16(client, BT541_X_RESOLUTION,
|
||||
error = zinitix_write_u16(client, ZINITIX_X_RESOLUTION,
|
||||
bt541->prop.max_x);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = zinitix_write_u16(client, BT541_Y_RESOLUTION,
|
||||
error = zinitix_write_u16(client, ZINITIX_Y_RESOLUTION,
|
||||
bt541->prop.max_y);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = zinitix_write_u16(client, BT541_SUPPORTED_FINGER_NUM,
|
||||
error = zinitix_write_u16(client, ZINITIX_SUPPORTED_FINGER_NUM,
|
||||
MAX_SUPPORTED_FINGER_NUM);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = zinitix_write_u16(client, BT541_INITIAL_TOUCH_MODE,
|
||||
error = zinitix_write_u16(client, ZINITIX_INITIAL_TOUCH_MODE,
|
||||
bt541->zinitix_mode);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = zinitix_write_u16(client, BT541_TOUCH_MODE,
|
||||
error = zinitix_write_u16(client, ZINITIX_TOUCH_MODE,
|
||||
bt541->zinitix_mode);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = zinitix_write_u16(client, BT541_INT_ENABLE_FLAG,
|
||||
error = zinitix_write_u16(client, ZINITIX_INT_ENABLE_FLAG,
|
||||
BIT_PT_CNT_CHANGE | BIT_DOWN | BIT_MOVE |
|
||||
BIT_UP);
|
||||
if (error)
|
||||
|
@ -243,7 +243,7 @@ static int zinitix_init_touch(struct bt541_ts_data *bt541)
|
|||
|
||||
/* clear queue */
|
||||
for (i = 0; i < 10; i++) {
|
||||
zinitix_write_cmd(client, BT541_CLEAR_INT_STATUS_CMD);
|
||||
zinitix_write_cmd(client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
|
@ -361,7 +361,7 @@ static irqreturn_t zinitix_ts_irq_handler(int irq, void *bt541_handler)
|
|||
|
||||
memset(&touch_event, 0, sizeof(struct touch_event));
|
||||
|
||||
error = zinitix_read_data(bt541->client, BT541_POINT_STATUS_REG,
|
||||
error = zinitix_read_data(bt541->client, ZINITIX_POINT_STATUS_REG,
|
||||
&touch_event, sizeof(struct touch_event));
|
||||
if (error) {
|
||||
dev_err(&client->dev, "Failed to read in touchpoint struct\n");
|
||||
|
@ -381,7 +381,7 @@ static irqreturn_t zinitix_ts_irq_handler(int irq, void *bt541_handler)
|
|||
input_sync(bt541->input_dev);
|
||||
|
||||
out:
|
||||
zinitix_write_cmd(bt541->client, BT541_CLEAR_INT_STATUS_CMD);
|
||||
zinitix_write_cmd(bt541->client, ZINITIX_CLEAR_INT_STATUS_CMD);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue