Commit 2ae08b36 authored by Linus Torvalds's avatar Linus Torvalds

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
  ...
parents 21f9c8a1 8bb5e7f4
...@@ -45,6 +45,7 @@ additionalProperties: false ...@@ -45,6 +45,7 @@ additionalProperties: false
patternProperties: patternProperties:
"^axis@[0-9a-f]+$": "^axis@[0-9a-f]+$":
type: object type: object
$ref: input.yaml#
description: > description: >
Represents a joystick axis bound to the given ADC channel. Represents a joystick axis bound to the given ADC channel.
For each entry in the io-channels list, one axis subnode with a matching For each entry in the io-channels list, one axis subnode with a matching
...@@ -57,7 +58,6 @@ patternProperties: ...@@ -57,7 +58,6 @@ patternProperties:
description: Index of an io-channels list entry bound to this axis. description: Index of an io-channels list entry bound to this axis.
linux,code: linux,code:
$ref: /schemas/types.yaml#/definitions/uint32
description: EV_ABS specific event code generated by the axis. description: EV_ABS specific event code generated by the axis.
abs-range: abs-range:
......
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 |
+--------------------------------+------------------------+
# 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: ...@@ -44,14 +44,13 @@ properties:
patternProperties: patternProperties:
"^button-[0-9]+$": "^button-[0-9]+$":
type: object type: object
$ref: input.yaml#
properties: properties:
label: label:
$ref: /schemas/types.yaml#/definitions/string $ref: /schemas/types.yaml#/definitions/string
description: Descriptive name of the key description: Descriptive name of the key
linux,code: linux,code: true
$ref: /schemas/types.yaml#/definitions/uint32
description: Keycode to emit
channel: channel:
$ref: /schemas/types.yaml#/definitions/uint32 $ref: /schemas/types.yaml#/definitions/uint32
......
...@@ -17,6 +17,7 @@ description: | ...@@ -17,6 +17,7 @@ description: |
allOf: allOf:
- $ref: input.yaml# - $ref: input.yaml#
- $ref: /schemas/spi/spi-peripheral-props.yaml#
properties: properties:
compatible: compatible:
......
...@@ -37,10 +37,6 @@ properties: ...@@ -37,10 +37,6 @@ properties:
device is temporarily held in hardware reset prior to initialization if device is temporarily held in hardware reset prior to initialization if
this property is present. this property is present.
azoteq,rf-filt-enable:
type: boolean
description: Enables the device's internal RF filter.
azoteq,max-counts: azoteq,max-counts:
$ref: /schemas/types.yaml#/definitions/uint32 $ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1, 2, 3] enum: [0, 1, 2, 3]
...@@ -421,6 +417,7 @@ patternProperties: ...@@ -421,6 +417,7 @@ patternProperties:
patternProperties: patternProperties:
"^event-(prox|touch)$": "^event-(prox|touch)$":
type: object type: object
$ref: input.yaml#
description: description:
Represents a proximity or touch event reported by the channel. Represents a proximity or touch event reported by the channel.
...@@ -467,14 +464,9 @@ patternProperties: ...@@ -467,14 +464,9 @@ patternProperties:
The IQS7222B does not feature channel-specific timeouts; the time- The IQS7222B does not feature channel-specific timeouts; the time-
out specified for any one channel applies to all channels. out specified for any one channel applies to all channels.
linux,code: linux,code: true
$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,input-type: linux,input-type:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [1, 5] enum: [1, 5]
default: 1 default: 1
description: description:
...@@ -537,9 +529,8 @@ patternProperties: ...@@ -537,9 +529,8 @@ patternProperties:
azoteq,bottom-speed: azoteq,bottom-speed:
$ref: /schemas/types.yaml#/definitions/uint32 $ref: /schemas/types.yaml#/definitions/uint32
multipleOf: 4
minimum: 0 minimum: 0
maximum: 1020 maximum: 255
description: description:
Specifies the speed of movement after which coordinate filtering is Specifies the speed of movement after which coordinate filtering is
linearly reduced. linearly reduced.
...@@ -575,14 +566,13 @@ patternProperties: ...@@ -575,14 +566,13 @@ patternProperties:
patternProperties: patternProperties:
"^event-(press|tap|(swipe|flick)-(pos|neg))$": "^event-(press|tap|(swipe|flick)-(pos|neg))$":
type: object type: object
$ref: input.yaml#
description: description:
Represents a press or gesture (IQS7222A only) event reported by Represents a press or gesture (IQS7222A only) event reported by
the slider. the slider.
properties: properties:
linux,code: linux,code: true
$ref: /schemas/types.yaml#/definitions/uint32
description: Numeric key code associated with the event.
azoteq,gesture-max-ms: azoteq,gesture-max-ms:
multipleOf: 4 multipleOf: 4
...@@ -616,16 +606,15 @@ patternProperties: ...@@ -616,16 +606,15 @@ patternProperties:
azoteq,gpio-select: azoteq,gpio-select:
$ref: /schemas/types.yaml#/definitions/uint32-array $ref: /schemas/types.yaml#/definitions/uint32-array
minItems: 1 minItems: 1
maxItems: 1 maxItems: 3
items: items:
minimum: 0 minimum: 0
maximum: 0 maximum: 2
description: | description: |
Specifies an individual GPIO mapped to a tap, swipe or flick Specifies one or more GPIO mapped to the event as follows:
gesture as follows:
0: GPIO0 0: GPIO0
1: GPIO3 (reserved) 1: GPIO3 (IQS7222C only)
2: GPIO4 (reserved) 2: GPIO4 (IQS7222C only)
Note that although multiple events can be mapped to a single Note that although multiple events can be mapped to a single
GPIO, they must all be of the same type (proximity, touch or GPIO, they must all be of the same type (proximity, touch or
...@@ -710,6 +699,14 @@ allOf: ...@@ -710,6 +699,14 @@ allOf:
multipleOf: 4 multipleOf: 4
maximum: 1020 maximum: 1020
patternProperties:
"^event-(press|tap|(swipe|flick)-(pos|neg))$":
properties:
azoteq,gpio-select:
maxItems: 1
items:
maximum: 0
else: else:
patternProperties: patternProperties:
"^channel-([0-9]|1[0-9])$": "^channel-([0-9]|1[0-9])$":
...@@ -726,8 +723,6 @@ allOf: ...@@ -726,8 +723,6 @@ allOf:
azoteq,gesture-dist: false azoteq,gesture-dist: false
azoteq,gpio-select: false
required: required:
- compatible - compatible
- reg - reg
......
...@@ -57,7 +57,7 @@ examples: ...@@ -57,7 +57,7 @@ examples:
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
mpr121@5a { touchkey@5a {
compatible = "fsl,mpr121-touchkey"; compatible = "fsl,mpr121-touchkey";
reg = <0x5a>; reg = <0x5a>;
interrupt-parent = <&gpio1>; interrupt-parent = <&gpio1>;
...@@ -77,7 +77,7 @@ examples: ...@@ -77,7 +77,7 @@ examples:
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
mpr121@5a { touchkey@5a {
compatible = "fsl,mpr121-touchkey"; compatible = "fsl,mpr121-touchkey";
reg = <0x5a>; reg = <0x5a>;
poll-interval = <20>; poll-interval = <20>;
......
...@@ -15,107 +15,106 @@ properties: ...@@ -15,107 +15,106 @@ properties:
- gpio-keys - gpio-keys
- gpio-keys-polled - gpio-keys-polled
autorepeat: true
label:
description: Name of entire device
poll-interval: true
patternProperties: patternProperties:
".*": "^(button|event|key|switch|(button|event|key|switch)-[a-z0-9-]+|[a-z0-9-]+-(button|event|key|switch))$":
if: $ref: input.yaml#
type: object
then:
$ref: input.yaml#
properties: properties:
gpios: gpios:
maxItems: 1 maxItems: 1
interrupts:
maxItems: 1
interrupts: label:
maxItems: 1 description: Descriptive name of the key.
label: linux,code:
description: Descriptive name of the key. description: Key / Axis code to emit.
linux,code: linux,input-type:
description: Key / Axis code to emit. default: 1 # EV_KEY
$ref: /schemas/types.yaml#/definitions/uint32
linux,input-type: linux,input-value:
description: description: |
Specify event type this button/key generates. If not specified defaults to If linux,input-type is EV_ABS or EV_REL then this
<1> == EV_KEY. value is sent for events this button generates when pressed.
$ref: /schemas/types.yaml#/definitions/uint32 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:
default: 1 linux,input-value = <0xffffffff>; /* -1 */
linux,input-value: $ref: /schemas/types.yaml#/definitions/uint32
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 */ debounce-interval:
description:
Debouncing interval time in milliseconds. If not specified defaults to 5.
$ref: /schemas/types.yaml#/definitions/uint32
$ref: /schemas/types.yaml#/definitions/uint32 default: 5
debounce-interval: wakeup-source:
description: description: Button can wake-up the system.
Debouncing interval time in milliseconds. If not specified defaults to 5.
$ref: /schemas/types.yaml#/definitions/uint32
default: 5 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).
wakeup-source: Supported values are defined in linux-event-codes.h:
description: Button can wake-up the system.
wakeup-event-action: EV_ACT_ANY - both asserted and deasserted
description: | EV_ACT_ASSERTED - asserted
Specifies whether the key should wake the system when asserted, when EV_ACT_DEASSERTED - deasserted
deasserted, or both. This property is only valid for keys that wake up the $ref: /schemas/types.yaml#/definitions/uint32
system (e.g., when the "wakeup-source" property is also provided). enum: [0, 1, 2]
Supported values are defined in linux-event-codes.h: 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
EV_ACT_ANY - both asserted and deasserted required:
EV_ACT_ASSERTED - asserted - linux,code
EV_ACT_DEASSERTED - deasserted
$ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1, 2]
linux,can-disable: anyOf:
description: - required:
Indicates that button is connected to dedicated (not shared) interrupt - interrupts
which can be disabled to suppress events from the button. - required:
type: boolean - interrupts-extended
- required:
- gpios
dependencies:
wakeup-event-action: [ wakeup-source ]
linux,input-value: [ gpios ]
unevaluatedProperties: false
allOf:
- $ref: input.yaml#
- if:
properties:
compatible:
const: gpio-keys-polled
then:
required: required:
- linux,code - poll-interval
else:
anyOf: properties:
- required: poll-interval: false
- 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
additionalProperties: false additionalProperties: false
...@@ -127,13 +126,13 @@ examples: ...@@ -127,13 +126,13 @@ examples:
compatible = "gpio-keys"; compatible = "gpio-keys";
autorepeat; autorepeat;
up { key-up {
label = "GPIO Key UP"; label = "GPIO Key UP";
linux,code = <103>; linux,code = <103>;
gpios = <&gpio1 0 1>; gpios = <&gpio1 0 1>;
}; };
down { key-down {
label = "GPIO Key DOWN"; label = "GPIO Key DOWN";
linux,code = <108>; linux,code = <108>;
interrupts = <1 IRQ_TYPE_EDGE_FALLING>; interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
......
...@@ -21,7 +21,26 @@ properties: ...@@ -21,7 +21,26 @@ properties:
$ref: /schemas/types.yaml#/definitions/uint32-array $ref: /schemas/types.yaml#/definitions/uint32-array
items: items:
minimum: 0 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: poll-interval:
description: Poll interval time in milliseconds. description: Poll interval time in milliseconds.
...@@ -39,4 +58,7 @@ properties: ...@@ -39,4 +58,7 @@ properties:
reset automatically. Device with key pressed reset feature can specify reset automatically. Device with key pressed reset feature can specify
this property. this property.
dependencies:
linux,input-type: [ "linux,code" ]
additionalProperties: true additionalProperties: true
...@@ -370,6 +370,7 @@ patternProperties: ...@@ -370,6 +370,7 @@ patternProperties:
patternProperties: patternProperties:
"^event-prox(-alt)?$": "^event-prox(-alt)?$":
type: object type: object
$ref: input.yaml#
description: description:
Represents a proximity event reported by the channel in response to Represents a proximity event reported by the channel in response to
a decrease in counts. Node names suffixed with '-alt' instead corre- a decrease in counts. Node names suffixed with '-alt' instead corre-
...@@ -396,14 +397,13 @@ patternProperties: ...@@ -396,14 +397,13 @@ patternProperties:
default: 10 default: 10
description: Specifies the threshold for the event. description: Specifies the threshold for the event.
linux,code: linux,code: true
$ref: /schemas/types.yaml#/definitions/uint32
description: Numeric key or switch code associated with the event.
additionalProperties: false additionalProperties: false
"^event-touch(-alt)?$": "^event-touch(-alt)?$":
type: object type: object
$ref: input.yaml#
description: Represents a touch event reported by the channel. description: Represents a touch event reported by the channel.
properties: properties:
...@@ -421,14 +421,13 @@ patternProperties: ...@@ -421,14 +421,13 @@ patternProperties:
default: 4 default: 4
description: Specifies the hysteresis for the event. description: Specifies the hysteresis for the event.
linux,code: linux,code: true
$ref: /schemas/types.yaml#/definitions/uint32
description: Numeric key or switch code associated with the event.
additionalProperties: false additionalProperties: false
"^event-deep(-alt)?$": "^event-deep(-alt)?$":
type: object type: object
$ref: input.yaml#
description: Represents a deep-touch event reported by the channel. description: Represents a deep-touch event reported by the channel.
properties: properties:
...@@ -446,9 +445,7 @@ patternProperties: ...@@ -446,9 +445,7 @@ patternProperties:
default: 0 default: 0
description: Specifies the hysteresis for the event. description: Specifies the hysteresis for the event.
linux,code: linux,code: true
$ref: /schemas/types.yaml#/definitions/uint32
description: Numeric key or switch code associated with the event.
additionalProperties: false additionalProperties: false
...@@ -475,7 +472,7 @@ examples: ...@@ -475,7 +472,7 @@ examples:
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
iqs269a@44 { touch@44 {
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
......
...@@ -449,6 +449,7 @@ patternProperties: ...@@ -449,6 +449,7 @@ patternProperties:
patternProperties: patternProperties:
"^event-(prox|touch|deep)(-alt)?$": "^event-(prox|touch|deep)(-alt)?$":
type: object type: object
$ref: input.yaml#
description: description:
Represents a proximity, touch or deep-touch event reported by the Represents a proximity, touch or deep-touch event reported by the
channel in response to a decrease in counts. Node names suffixed with channel in response to a decrease in counts. Node names suffixed with
...@@ -487,21 +488,15 @@ patternProperties: ...@@ -487,21 +488,15 @@ patternProperties:
Specifies the hysteresis for the event (touch and deep-touch Specifies the hysteresis for the event (touch and deep-touch
events only). events only).
linux,code: linux,code: true
$ref: /schemas/types.yaml#/definitions/uint32
description: Numeric key or switch code associated with the event.
linux,input-type: linux,input-type:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [1, 5] enum: [1, 5]
description: description:
Specifies whether the event is to be interpreted as a key (1) or Specifies whether the event is to be interpreted as a key (1) or
a switch (5). By default, Hall-channel events are interpreted as a switch (5). By default, Hall-channel events are interpreted as
switches and all others are interpreted as keys. switches and all others are interpreted as keys.
dependencies:
linux,input-type: ["linux,code"]
additionalProperties: false additionalProperties: false
dependencies: dependencies:
...@@ -511,6 +506,7 @@ patternProperties: ...@@ -511,6 +506,7 @@ patternProperties:
"^trackpad-3x[2-3]$": "^trackpad-3x[2-3]$":
type: object type: object
$ref: input.yaml#
description: description:
Represents all channels associated with the trackpad. The channels are Represents all channels associated with the trackpad. The channels are
collectively active if the trackpad is defined and inactive otherwise. collectively active if the trackpad is defined and inactive otherwise.
...@@ -679,7 +675,6 @@ patternProperties: ...@@ -679,7 +675,6 @@ patternProperties:
Specifies the raw count filter strength during low-power mode. Specifies the raw count filter strength during low-power mode.
linux,keycodes: linux,keycodes:
$ref: /schemas/types.yaml#/definitions/uint32-array
minItems: 1 minItems: 1
maxItems: 6 maxItems: 6
description: | description: |
...@@ -751,7 +746,7 @@ examples: ...@@ -751,7 +746,7 @@ examples:
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
iqs626a@44 { touch@44 {
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
......
...@@ -9,6 +9,9 @@ title: Azoteq IQS620A/621/622/624/625 Keys and Switches ...@@ -9,6 +9,9 @@ title: Azoteq IQS620A/621/622/624/625 Keys and Switches
maintainers: maintainers:
- Jeff LaBundy <jeff@labundy.com> - Jeff LaBundy <jeff@labundy.com>
allOf:
- $ref: input.yaml#
description: | description: |
The Azoteq IQS620A, IQS621, IQS622, IQS624 and IQS625 multi-function sensors The Azoteq IQS620A, IQS621, IQS622, IQS624 and IQS625 multi-function sensors
feature a variety of self-capacitive, mutual-inductive and Hall-effect sens- feature a variety of self-capacitive, mutual-inductive and Hall-effect sens-
...@@ -30,7 +33,6 @@ properties: ...@@ -30,7 +33,6 @@ properties:
- azoteq,iqs625-keys - azoteq,iqs625-keys
linux,keycodes: linux,keycodes:
$ref: /schemas/types.yaml#/definitions/uint32-array
minItems: 1 minItems: 1
maxItems: 16 maxItems: 16
description: | description: |
...@@ -89,15 +91,14 @@ properties: ...@@ -89,15 +91,14 @@ properties:
patternProperties: patternProperties:
"^hall-switch-(north|south)$": "^hall-switch-(north|south)$":
type: object type: object
$ref: input.yaml#
description: description:
Represents north/south-field Hall-effect sensor touch or proximity Represents north/south-field Hall-effect sensor touch or proximity
events. Note that north/south-field orientation is reversed on the events. Note that north/south-field orientation is reversed on the
IQS620AXzCSR device due to its flip-chip package. IQS620AXzCSR device due to its flip-chip package.
properties: properties:
linux,code: linux,code: true
$ref: /schemas/types.yaml#/definitions/uint32
description: Numeric switch code associated with the event.
azoteq,use-prox: azoteq,use-prox:
$ref: /schemas/types.yaml#/definitions/flag $ref: /schemas/types.yaml#/definitions/flag
......
...@@ -16,15 +16,15 @@ description: | ...@@ -16,15 +16,15 @@ description: |
The onkey controller is represented as a sub-node of the PMIC node on The onkey controller is represented as a sub-node of the PMIC node on
the device tree. the device tree.
allOf:
- $ref: input.yaml#
properties: properties:
compatible: compatible:
const: maxim,max77650-onkey const: maxim,max77650-onkey
linux,code: linux,code:
$ref: /schemas/types.yaml#/definitions/uint32 default: 116 # KEY_POWER
description:
The key-code to be reported when the key is pressed. Defaults
to KEY_POWER.
maxim,onkey-slide: maxim,onkey-slide:
$ref: /schemas/types.yaml#/definitions/flag $ref: /schemas/types.yaml#/definitions/flag
......
...@@ -112,7 +112,7 @@ examples: ...@@ -112,7 +112,7 @@ examples:
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
cap1188@28 { touch@28 {
compatible = "microchip,cap1188"; compatible = "microchip,cap1188";
interrupt-parent = <&gpio1>; interrupt-parent = <&gpio1>;
interrupts = <0 0>; interrupts = <0 0>;
......
...@@ -85,6 +85,14 @@ properties: ...@@ -85,6 +85,14 @@ properties:
minimum: 0 minimum: 0
maximum: 80 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-x: true
touchscreen-size-y: true touchscreen-size-y: true
touchscreen-fuzz-x: true touchscreen-fuzz-x: true
......
/* 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 @@ ...@@ -8,6 +8,7 @@
#include <linux/input/mt.h> #include <linux/input/mt.h>
#include <linux/export.h> #include <linux/export.h>
#include <linux/slab.h> #include <linux/slab.h>
#include "input-core-private.h"
#define TRKID_SGN ((TRKID_MAX + 1) >> 1) #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) ...@@ -259,10 +260,13 @@ static void __input_mt_drop_unused(struct input_dev *dev, struct input_mt *mt)
{ {
int i; int i;
lockdep_assert_held(&dev->event_lock);
for (i = 0; i < mt->num_slots; i++) { for (i = 0; i < mt->num_slots; i++) {
if (!input_mt_is_used(mt, &mt->slots[i])) { if (input_mt_is_active(&mt->slots[i]) &&
input_mt_slot(dev, i); !input_mt_is_used(mt, &mt->slots[i])) {
input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1); 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) ...@@ -278,12 +282,43 @@ void input_mt_drop_unused(struct input_dev *dev)
struct input_mt *mt = dev->mt; struct input_mt *mt = dev->mt;
if (mt) { if (mt) {
unsigned long flags;
spin_lock_irqsave(&dev->event_lock, flags);
__input_mt_drop_unused(dev, mt); __input_mt_drop_unused(dev, mt);
mt->frame++; mt->frame++;
spin_unlock_irqrestore(&dev->event_lock, flags);
} }
} }
EXPORT_SYMBOL(input_mt_drop_unused); 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 * input_mt_sync_frame() - synchronize mt frame
* @dev: input device with allocated MT slots * @dev: input device with allocated MT slots
...@@ -300,8 +335,13 @@ void input_mt_sync_frame(struct input_dev *dev) ...@@ -300,8 +335,13 @@ void input_mt_sync_frame(struct input_dev *dev)
if (!mt) if (!mt)
return; 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); __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)) if ((mt->flags & INPUT_MT_POINTER) && !(mt->flags & INPUT_MT_SEMI_MT))
use_count = true; use_count = true;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/rcupdate.h> #include <linux/rcupdate.h>
#include "input-compat.h" #include "input-compat.h"
#include "input-core-private.h"
#include "input-poller.h" #include "input-poller.h"
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
...@@ -142,6 +143,8 @@ static void input_pass_values(struct input_dev *dev, ...@@ -142,6 +143,8 @@ static void input_pass_values(struct input_dev *dev,
struct input_handle *handle; struct input_handle *handle;
struct input_value *v; struct input_value *v;
lockdep_assert_held(&dev->event_lock);
if (!count) if (!count)
return; return;
...@@ -174,44 +177,6 @@ static void input_pass_values(struct input_dev *dev, ...@@ -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_IGNORE_EVENT 0
#define INPUT_PASS_TO_HANDLERS 1 #define INPUT_PASS_TO_HANDLERS 1
#define INPUT_PASS_TO_DEVICE 2 #define INPUT_PASS_TO_DEVICE 2
...@@ -275,6 +240,10 @@ static int input_get_disposition(struct input_dev *dev, ...@@ -275,6 +240,10 @@ static int input_get_disposition(struct input_dev *dev,
int disposition = INPUT_IGNORE_EVENT; int disposition = INPUT_IGNORE_EVENT;
int value = *pval; int value = *pval;
/* filter-out events from inhibited devices */
if (dev->inhibited)
return INPUT_IGNORE_EVENT;
switch (type) { switch (type) {
case EV_SYN: case EV_SYN:
...@@ -375,19 +344,9 @@ static int input_get_disposition(struct input_dev *dev, ...@@ -375,19 +344,9 @@ static int input_get_disposition(struct input_dev *dev,
return disposition; return disposition;
} }
static void input_handle_event(struct input_dev *dev, static void input_event_dispose(struct input_dev *dev, int disposition,
unsigned int type, unsigned int code, int value) 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) if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)
dev->event(dev, type, code, value); dev->event(dev, type, code, value);
...@@ -426,7 +385,22 @@ static void input_handle_event(struct input_dev *dev, ...@@ -426,7 +385,22 @@ static void input_handle_event(struct input_dev *dev,
input_pass_values(dev, dev->vals, dev->num_vals); input_pass_values(dev, dev->vals, dev->num_vals);
dev->num_vals = 0; 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) ...@@ -613,7 +587,7 @@ static void __input_release_device(struct input_handle *handle)
lockdep_is_held(&dev->mutex)); lockdep_is_held(&dev->mutex));
if (grabber == handle) { if (grabber == handle) {
rcu_assign_pointer(dev->grab, NULL); 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(); synchronize_rcu();
list_for_each_entry(handle, &dev->h_list, d_node) list_for_each_entry(handle, &dev->h_list, d_node)
...@@ -736,7 +710,7 @@ void input_close_device(struct input_handle *handle) ...@@ -736,7 +710,7 @@ void input_close_device(struct input_handle *handle)
if (!--handle->open) { 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 * completed and that no more input events are delivered
* through this handle * through this handle
*/ */
...@@ -751,22 +725,21 @@ EXPORT_SYMBOL(input_close_device); ...@@ -751,22 +725,21 @@ EXPORT_SYMBOL(input_close_device);
* Simulate keyup events for all keys that are marked as pressed. * Simulate keyup events for all keys that are marked as pressed.
* The function must be called with dev->event_lock held. * 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; bool need_sync = false;
int code; int code;
lockdep_assert_held(&dev->event_lock);
if (is_event_supported(EV_KEY, dev->evbit, EV_MAX)) { if (is_event_supported(EV_KEY, dev->evbit, EV_MAX)) {
for_each_set_bit(code, dev->key, KEY_CNT) { 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; 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) ...@@ -793,7 +766,8 @@ static void input_disconnect_device(struct input_dev *dev)
* generate events even after we done here but they will not * generate events even after we done here but they will not
* reach any handlers. * 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) list_for_each_entry(handle, &dev->h_list, d_node)
handle->open = 0; handle->open = 0;
...@@ -1004,12 +978,16 @@ int input_set_keycode(struct input_dev *dev, ...@@ -1004,12 +978,16 @@ int input_set_keycode(struct input_dev *dev,
} else if (test_bit(EV_KEY, dev->evbit) && } else if (test_bit(EV_KEY, dev->evbit) &&
!is_event_supported(old_keycode, dev->keybit, KEY_MAX) && !is_event_supported(old_keycode, dev->keybit, KEY_MAX) &&
__test_and_clear_bit(old_keycode, dev->key)) { __test_and_clear_bit(old_keycode, dev->key)) {
struct input_value vals[] = { /*
{ EV_KEY, old_keycode, 0 }, * We have to use input_event_dispose() here directly instead
input_value_sync * 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_pass_values(dev, vals, ARRAY_SIZE(vals)); */
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: out:
...@@ -1784,7 +1762,8 @@ void input_reset_device(struct input_dev *dev) ...@@ -1784,7 +1762,8 @@ void input_reset_device(struct input_dev *dev)
spin_lock_irqsave(&dev->event_lock, flags); spin_lock_irqsave(&dev->event_lock, flags);
input_dev_toggle(dev, true); 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); spin_unlock_irqrestore(&dev->event_lock, flags);
mutex_unlock(&dev->mutex); mutex_unlock(&dev->mutex);
...@@ -1806,7 +1785,9 @@ static int input_inhibit_device(struct input_dev *dev) ...@@ -1806,7 +1785,9 @@ static int input_inhibit_device(struct input_dev *dev)
} }
spin_lock_irq(&dev->event_lock); spin_lock_irq(&dev->event_lock);
input_mt_release_slots(dev);
input_dev_release_keys(dev); input_dev_release_keys(dev);
input_handle_event(dev, EV_SYN, SYN_REPORT, 1);
input_dev_toggle(dev, false); input_dev_toggle(dev, false);
spin_unlock_irq(&dev->event_lock); spin_unlock_irq(&dev->event_lock);
...@@ -1857,7 +1838,8 @@ static int input_dev_suspend(struct device *dev) ...@@ -1857,7 +1838,8 @@ static int input_dev_suspend(struct device *dev)
* Keys that are pressed now are unlikely to be * Keys that are pressed now are unlikely to be
* still pressed when we resume. * 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. */ /* Turn off LEDs and sounds, if any are active. */
input_dev_toggle(input_dev, false); input_dev_toggle(input_dev, false);
...@@ -1891,7 +1873,8 @@ static int input_dev_freeze(struct device *dev) ...@@ -1891,7 +1873,8 @@ static int input_dev_freeze(struct device *dev)
* Keys that are pressed now are unlikely to be * Keys that are pressed now are unlikely to be
* still pressed when we resume. * 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); spin_unlock_irq(&input_dev->event_lock);
...@@ -2259,6 +2242,34 @@ static void devm_input_device_unregister(struct device *dev, void *res) ...@@ -2259,6 +2242,34 @@ static void devm_input_device_unregister(struct device *dev, void *res)
__input_unregister_device(input); __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 * input_enable_softrepeat - enable software autorepeat
* @dev: input device * @dev: input device
......
...@@ -222,13 +222,6 @@ static int adc_joystick_probe(struct platform_device *pdev) ...@@ -222,13 +222,6 @@ static int adc_joystick_probe(struct platform_device *pdev)
if (error) if (error)
return 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); joy->buffer = iio_channel_get_all_cb(dev, adc_joystick_handle, joy);
if (IS_ERR(joy->buffer)) { if (IS_ERR(joy->buffer)) {
dev_err(dev, "Unable to allocate callback buffer\n"); dev_err(dev, "Unable to allocate callback buffer\n");
...@@ -241,6 +234,14 @@ static int adc_joystick_probe(struct platform_device *pdev) ...@@ -241,6 +234,14 @@ static int adc_joystick_probe(struct platform_device *pdev)
return 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;
}
return 0; return 0;
} }
......
...@@ -98,10 +98,8 @@ static int sensehat_joystick_probe(struct platform_device *pdev) ...@@ -98,10 +98,8 @@ static int sensehat_joystick_probe(struct platform_device *pdev)
} }
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0) { if (irq < 0)
dev_err(&pdev->dev, "Could not retrieve interrupt request");
return irq; return irq;
}
error = devm_request_threaded_irq(&pdev->dev, irq, error = devm_request_threaded_irq(&pdev->dev, irq,
NULL, sensehat_joystick_report, NULL, sensehat_joystick_report,
......
...@@ -795,7 +795,7 @@ config KEYBOARD_MT6779 ...@@ -795,7 +795,7 @@ config KEYBOARD_MT6779
config KEYBOARD_MTK_PMIC config KEYBOARD_MTK_PMIC
tristate "MediaTek PMIC keys support" tristate "MediaTek PMIC keys support"
depends on MFD_MT6397 depends on MFD_MT6397 || COMPILE_TEST
help help
Say Y here if you want to use the pmic keys (powerkey/homekey). Say Y here if you want to use the pmic keys (powerkey/homekey).
......
...@@ -8,17 +8,19 @@ ...@@ -8,17 +8,19 @@
* Copyright (C) 2008-2010 Analog Devices Inc. * 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/interrupt.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/workqueue.h> #include <linux/ktime.h>
#include <linux/errno.h> #include <linux/module.h>
#include <linux/pm.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/input.h> #include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/gpio/driver.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/timekeeping.h>
#include <linux/platform_data/adp5588.h> #include <linux/platform_data/adp5588.h>
...@@ -36,18 +38,18 @@ ...@@ -36,18 +38,18 @@
* asserted. * asserted.
*/ */
#define WA_DELAYED_READOUT_REVID(rev) ((rev) < 4) #define WA_DELAYED_READOUT_REVID(rev) ((rev) < 4)
#define WA_DELAYED_READOUT_TIME 25
struct adp5588_kpad { struct adp5588_kpad {
struct i2c_client *client; struct i2c_client *client;
struct input_dev *input; struct input_dev *input;
struct delayed_work work; ktime_t irq_time;
unsigned long delay; unsigned long delay;
unsigned short keycode[ADP5588_KEYMAPSIZE]; unsigned short keycode[ADP5588_KEYMAPSIZE];
const struct adp5588_gpi_map *gpimap; const struct adp5588_gpi_map *gpimap;
unsigned short gpimapsize; unsigned short gpimapsize;
#ifdef CONFIG_GPIOLIB #ifdef CONFIG_GPIOLIB
unsigned char gpiomap[ADP5588_MAXGPIO]; unsigned char gpiomap[ADP5588_MAXGPIO];
bool export_gpio;
struct gpio_chip gc; struct gpio_chip gc;
struct mutex gpio_lock; /* Protect cached dir, dat_out */ struct mutex gpio_lock; /* Protect cached dir, dat_out */
u8 dat_out[3]; u8 dat_out[3];
...@@ -179,6 +181,21 @@ static int adp5588_build_gpiomap(struct adp5588_kpad *kpad, ...@@ -179,6 +181,21 @@ static int adp5588_build_gpiomap(struct adp5588_kpad *kpad,
return n_unused; 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) static int adp5588_gpio_add(struct adp5588_kpad *kpad)
{ {
struct device *dev = &kpad->client->dev; struct device *dev = &kpad->client->dev;
...@@ -195,8 +212,6 @@ static int adp5588_gpio_add(struct adp5588_kpad *kpad) ...@@ -195,8 +212,6 @@ static int adp5588_gpio_add(struct adp5588_kpad *kpad)
return 0; return 0;
} }
kpad->export_gpio = true;
kpad->gc.direction_input = adp5588_gpio_direction_input; kpad->gc.direction_input = adp5588_gpio_direction_input;
kpad->gc.direction_output = adp5588_gpio_direction_output; kpad->gc.direction_output = adp5588_gpio_direction_output;
kpad->gc.get = adp5588_gpio_get_value; kpad->gc.get = adp5588_gpio_get_value;
...@@ -210,9 +225,9 @@ static int adp5588_gpio_add(struct adp5588_kpad *kpad) ...@@ -210,9 +225,9 @@ static int adp5588_gpio_add(struct adp5588_kpad *kpad)
mutex_init(&kpad->gpio_lock); mutex_init(&kpad->gpio_lock);
error = gpiochip_add_data(&kpad->gc, kpad); error = devm_gpiochip_add_data(dev, &kpad->gc, kpad);
if (error) { if (error) {
dev_err(dev, "gpiochip_add failed, err: %d\n", error); dev_err(dev, "gpiochip_add failed: %d\n", error);
return error; return error;
} }
...@@ -227,41 +242,24 @@ static int adp5588_gpio_add(struct adp5588_kpad *kpad) ...@@ -227,41 +242,24 @@ static int adp5588_gpio_add(struct adp5588_kpad *kpad)
kpad->gc.base, kpad->gc.ngpio, kpad->gc.base, kpad->gc.ngpio,
gpio_data->context); gpio_data->context);
if (error) if (error)
dev_warn(dev, "setup failed, %d\n", error); dev_warn(dev, "setup failed: %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) { if (gpio_data->teardown) {
error = gpio_data->teardown(kpad->client, error = devm_add_action(dev, adp5588_gpio_do_teardown, kpad);
kpad->gc.base, kpad->gc.ngpio,
gpio_data->context);
if (error) if (error)
dev_warn(dev, "teardown failed %d\n", error); dev_warn(dev, "failed to schedule teardown: %d\n",
error);
} }
gpiochip_remove(&kpad->gc); return 0;
} }
#else #else
static inline int adp5588_gpio_add(struct adp5588_kpad *kpad) static inline int adp5588_gpio_add(struct adp5588_kpad *kpad)
{ {
return 0; return 0;
} }
static inline void adp5588_gpio_remove(struct adp5588_kpad *kpad)
{
}
#endif #endif
static void adp5588_report_events(struct adp5588_kpad *kpad, int ev_cnt) 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) ...@@ -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 *kpad = handle;
struct adp5588_kpad, work.work);
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; struct i2c_client *client = kpad->client;
ktime_t target_time, now;
unsigned long delay;
int status, ev_cnt; 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); status = adp5588_read(client, INT_STAT);
if (status & ADP5588_OVR_FLOW_INT) /* Unlikely and should never happen */ if (status & ADP5588_OVR_FLOW_INT) /* Unlikely and should never happen */
...@@ -308,20 +329,8 @@ static void adp5588_work(struct work_struct *work) ...@@ -308,20 +329,8 @@ static void adp5588_work(struct work_struct *work)
input_sync(kpad->input); 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;
/* adp5588_write(client, INT_STAT, status); /* Status is W1C */
* 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; return IRQ_HANDLED;
} }
...@@ -496,30 +505,27 @@ static int adp5588_probe(struct i2c_client *client, ...@@ -496,30 +505,27 @@ static int adp5588_probe(struct i2c_client *client,
return -EINVAL; return -EINVAL;
} }
kpad = kzalloc(sizeof(*kpad), GFP_KERNEL); kpad = devm_kzalloc(&client->dev, sizeof(*kpad), GFP_KERNEL);
input = input_allocate_device(); if (!kpad)
if (!kpad || !input) { return -ENOMEM;
error = -ENOMEM;
goto err_free_mem; input = devm_input_allocate_device(&client->dev);
} if (!input)
return -ENOMEM;
kpad->client = client; kpad->client = client;
kpad->input = input; kpad->input = input;
INIT_DELAYED_WORK(&kpad->work, adp5588_work);
ret = adp5588_read(client, DEV_ID); ret = adp5588_read(client, DEV_ID);
if (ret < 0) { if (ret < 0)
error = ret; return ret;
goto err_free_mem;
}
revid = (u8) ret & ADP5588_DEVICE_ID_MASK; revid = (u8) ret & ADP5588_DEVICE_ID_MASK;
if (WA_DELAYED_READOUT_REVID(revid)) 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->name = client->name;
input->phys = "adp5588-keys/input0"; input->phys = "adp5588-keys/input0";
input->dev.parent = &client->dev;
input_set_drvdata(input, kpad); input_set_drvdata(input, kpad);
...@@ -556,95 +562,63 @@ static int adp5588_probe(struct i2c_client *client, ...@@ -556,95 +562,63 @@ static int adp5588_probe(struct i2c_client *client,
error = input_register_device(input); error = input_register_device(input);
if (error) { if (error) {
dev_err(&client->dev, "unable to register input device\n"); dev_err(&client->dev, "unable to register input device: %d\n",
goto err_free_mem; error);
return error;
} }
error = request_irq(client->irq, adp5588_irq, error = devm_request_threaded_irq(&client->dev, client->irq,
IRQF_TRIGGER_FALLING, adp5588_hard_irq, adp5588_thread_irq,
client->dev.driver->name, kpad); IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
client->dev.driver->name, kpad);
if (error) { if (error) {
dev_err(&client->dev, "irq %d busy?\n", client->irq); dev_err(&client->dev, "failed to request irq %d: %d\n",
goto err_unreg_dev; client->irq, error);
return error;
} }
error = adp5588_setup(client); error = adp5588_setup(client);
if (error) if (error)
goto err_free_irq; return error;
if (kpad->gpimapsize) if (kpad->gpimapsize)
adp5588_report_switch_state(kpad); adp5588_report_switch_state(kpad);
error = adp5588_gpio_add(kpad); error = adp5588_gpio_add(kpad);
if (error) if (error)
goto err_free_irq; return error;
device_init_wakeup(&client->dev, 1);
i2c_set_clientdata(client, kpad);
dev_info(&client->dev, "Rev.%d keypad, irq %d\n", revid, client->irq); dev_info(&client->dev, "Rev.%d keypad, irq %d\n", revid, client->irq);
return 0; 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) static int adp5588_remove(struct i2c_client *client)
{ {
struct adp5588_kpad *kpad = i2c_get_clientdata(client);
adp5588_write(client, CFG, 0); 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; return 0;
} }
#ifdef CONFIG_PM static int __maybe_unused adp5588_suspend(struct device *dev)
static int adp5588_suspend(struct device *dev)
{ {
struct adp5588_kpad *kpad = dev_get_drvdata(dev); struct i2c_client *client = to_i2c_client(dev);
struct i2c_client *client = kpad->client;
disable_irq(client->irq); disable_irq(client->irq);
cancel_delayed_work_sync(&kpad->work);
if (device_may_wakeup(&client->dev))
enable_irq_wake(client->irq);
return 0; 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 = to_i2c_client(dev);
struct i2c_client *client = kpad->client;
if (device_may_wakeup(&client->dev))
disable_irq_wake(client->irq);
enable_irq(client->irq); enable_irq(client->irq);
return 0; return 0;
} }
static const struct dev_pm_ops adp5588_dev_pm_ops = { static SIMPLE_DEV_PM_OPS(adp5588_dev_pm_ops, adp5588_suspend, adp5588_resume);
.suspend = adp5588_suspend,
.resume = adp5588_resume,
};
#endif
static const struct i2c_device_id adp5588_id[] = { static const struct i2c_device_id adp5588_id[] = {
{ "adp5588-keys", 0 }, { "adp5588-keys", 0 },
...@@ -656,9 +630,7 @@ MODULE_DEVICE_TABLE(i2c, adp5588_id); ...@@ -656,9 +630,7 @@ MODULE_DEVICE_TABLE(i2c, adp5588_id);
static struct i2c_driver adp5588_driver = { static struct i2c_driver adp5588_driver = {
.driver = { .driver = {
.name = KBUILD_MODNAME, .name = KBUILD_MODNAME,
#ifdef CONFIG_PM
.pm = &adp5588_dev_pm_ops, .pm = &adp5588_dev_pm_ops,
#endif
}, },
.probe = adp5588_probe, .probe = adp5588_probe,
.remove = adp5588_remove, .remove = adp5588_remove,
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
// expensive. // expensive.
#include <linux/module.h> #include <linux/module.h>
#include <linux/acpi.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/input.h> #include <linux/input.h>
...@@ -518,6 +519,50 @@ static int cros_ec_keyb_register_bs(struct cros_ec_keyb *ckdev, ...@@ -518,6 +519,50 @@ static int cros_ec_keyb_register_bs(struct cros_ec_keyb *ckdev,
return 0; 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 * cros_ec_keyb_register_matrix - Register matrix keys
* *
...@@ -534,11 +579,6 @@ static int cros_ec_keyb_register_matrix(struct cros_ec_keyb *ckdev) ...@@ -534,11 +579,6 @@ static int cros_ec_keyb_register_matrix(struct cros_ec_keyb *ckdev)
struct input_dev *idev; struct input_dev *idev;
const char *phys; const char *phys;
int err; 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); err = matrix_keypad_parse_properties(dev, &ckdev->rows, &ckdev->cols);
if (err) if (err)
...@@ -573,7 +613,7 @@ static int cros_ec_keyb_register_matrix(struct cros_ec_keyb *ckdev) ...@@ -573,7 +613,7 @@ static int cros_ec_keyb_register_matrix(struct cros_ec_keyb *ckdev)
idev->id.product = 0; idev->id.product = 0;
idev->dev.parent = dev; 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"); "google,needs-ghost-filter");
err = matrix_keypad_build_keymap(NULL, NULL, ckdev->rows, ckdev->cols, 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) ...@@ -589,22 +629,7 @@ static int cros_ec_keyb_register_matrix(struct cros_ec_keyb *ckdev)
input_set_drvdata(idev, ckdev); input_set_drvdata(idev, ckdev);
ckdev->idev = idev; ckdev->idev = idev;
cros_ec_keyb_compute_valid_keys(ckdev); cros_ec_keyb_compute_valid_keys(ckdev);
cros_ec_keyb_parse_vivaldi_physmap(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;
err = input_register_device(ckdev->idev); err = input_register_device(ckdev->idev);
if (err) { if (err) {
...@@ -653,14 +678,19 @@ static const struct attribute_group cros_ec_keyb_attr_group = { ...@@ -653,14 +678,19 @@ static const struct attribute_group cros_ec_keyb_attr_group = {
static int cros_ec_keyb_probe(struct platform_device *pdev) 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 device *dev = &pdev->dev;
struct cros_ec_keyb *ckdev; struct cros_ec_keyb *ckdev;
bool buttons_switches_only = device_get_match_data(dev); bool buttons_switches_only = device_get_match_data(dev);
int err; 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); ckdev = devm_kzalloc(dev, sizeof(*ckdev), GFP_KERNEL);
if (!ckdev) if (!ckdev)
...@@ -713,6 +743,14 @@ static int cros_ec_keyb_remove(struct platform_device *pdev) ...@@ -713,6 +743,14 @@ static int cros_ec_keyb_remove(struct platform_device *pdev)
return 0; 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 #ifdef CONFIG_OF
static const struct of_device_id cros_ec_keyb_of_match[] = { static const struct of_device_id cros_ec_keyb_of_match[] = {
{ .compatible = "google,cros-ec-keyb" }, { .compatible = "google,cros-ec-keyb" },
...@@ -730,6 +768,7 @@ static struct platform_driver cros_ec_keyb_driver = { ...@@ -730,6 +768,7 @@ static struct platform_driver cros_ec_keyb_driver = {
.driver = { .driver = {
.name = "cros-ec-keyb", .name = "cros-ec-keyb",
.of_match_table = of_match_ptr(cros_ec_keyb_of_match), .of_match_table = of_match_ptr(cros_ec_keyb_of_match),
.acpi_match_table = ACPI_PTR(cros_ec_keyb_acpi_match),
.pm = &cros_ec_keyb_pm_ops, .pm = &cros_ec_keyb_pm_ops,
}, },
}; };
......
...@@ -17,6 +17,11 @@ ...@@ -17,6 +17,11 @@
#define MTK_KPD_DEBOUNCE 0x0018 #define MTK_KPD_DEBOUNCE 0x0018
#define MTK_KPD_DEBOUNCE_MASK GENMASK(13, 0) #define MTK_KPD_DEBOUNCE_MASK GENMASK(13, 0)
#define MTK_KPD_DEBOUNCE_MAX_MS 256 #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_MEMS 5
#define MTK_KPD_NUM_BITS 136 /* 4*32+8 MEM5 only use 8 BITS */ #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) ...@@ -42,7 +47,7 @@ static irqreturn_t mt6779_keypad_irq_handler(int irq, void *dev_id)
const unsigned short *keycode = keypad->input_dev->keycode; const unsigned short *keycode = keypad->input_dev->keycode;
DECLARE_BITMAP(new_state, MTK_KPD_NUM_BITS); DECLARE_BITMAP(new_state, MTK_KPD_NUM_BITS);
DECLARE_BITMAP(change, 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 row, col;
unsigned int scancode; unsigned int scancode;
unsigned int row_shift = get_count_order(keypad->n_cols); 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) ...@@ -61,8 +66,10 @@ static irqreturn_t mt6779_keypad_irq_handler(int irq, void *dev_id)
if (bit_nr % 32 >= 16) if (bit_nr % 32 >= 16)
continue; continue;
row = bit_nr / 32; key = bit_nr / 32 * 16 + bit_nr % 32;
col = bit_nr % 32; row = key / 9;
col = key % 9;
scancode = MATRIX_SCAN_CODE(row, col, row_shift); scancode = MATRIX_SCAN_CODE(row, col, row_shift);
/* 1: not pressed, 0: pressed */ /* 1: not pressed, 0: pressed */
pressed = !test_bit(bit_nr, new_state); pressed = !test_bit(bit_nr, new_state);
...@@ -159,6 +166,11 @@ static int mt6779_keypad_pdrv_probe(struct platform_device *pdev) ...@@ -159,6 +166,11 @@ static int mt6779_keypad_pdrv_probe(struct platform_device *pdev)
regmap_write(keypad->regmap, MTK_KPD_DEBOUNCE, regmap_write(keypad->regmap, MTK_KPD_DEBOUNCE,
(debounce * (1 << 5)) & MTK_KPD_DEBOUNCE_MASK); (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"); keypad->clk = devm_clk_get(&pdev->dev, "kpd");
if (IS_ERR(keypad->clk)) if (IS_ERR(keypad->clk))
return PTR_ERR(keypad->clk); return PTR_ERR(keypad->clk);
......
...@@ -18,17 +18,9 @@ ...@@ -18,17 +18,9 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#define MTK_PMIC_PWRKEY_RST_EN_MASK 0x1 #define MTK_PMIC_RST_DU_MASK GENMASK(9, 8)
#define MTK_PMIC_PWRKEY_RST_EN_SHIFT 6 #define MTK_PMIC_PWRKEY_RST BIT(6)
#define MTK_PMIC_HOMEKEY_RST_EN_MASK 0x1 #define MTK_PMIC_HOMEKEY_RST BIT(5)
#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_PWRKEY_INDEX 0 #define MTK_PMIC_PWRKEY_INDEX 0
#define MTK_PMIC_HOMEKEY_INDEX 1 #define MTK_PMIC_HOMEKEY_INDEX 1
...@@ -39,50 +31,58 @@ struct mtk_pmic_keys_regs { ...@@ -39,50 +31,58 @@ struct mtk_pmic_keys_regs {
u32 deb_mask; u32 deb_mask;
u32 intsel_reg; u32 intsel_reg;
u32 intsel_mask; u32 intsel_mask;
u32 rst_en_mask;
}; };
#define MTK_PMIC_KEYS_REGS(_deb_reg, _deb_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_reg = _deb_reg, \
.deb_mask = _deb_mask, \ .deb_mask = _deb_mask, \
.intsel_reg = _intsel_reg, \ .intsel_reg = _intsel_reg, \
.intsel_mask = _intsel_mask, \ .intsel_mask = _intsel_mask, \
.rst_en_mask = _rst_mask, \
} }
struct mtk_pmic_regs { struct mtk_pmic_regs {
const struct mtk_pmic_keys_regs keys_regs[MTK_PMIC_MAX_KEY_COUNT]; const struct mtk_pmic_keys_regs keys_regs[MTK_PMIC_MAX_KEY_COUNT];
u32 pmic_rst_reg; u32 pmic_rst_reg;
u32 rst_lprst_mask; /* Long-press reset timeout bitmask */
}; };
static const struct mtk_pmic_regs mt6397_regs = { static const struct mtk_pmic_regs mt6397_regs = {
.keys_regs[MTK_PMIC_PWRKEY_INDEX] = .keys_regs[MTK_PMIC_PWRKEY_INDEX] =
MTK_PMIC_KEYS_REGS(MT6397_CHRSTATUS, 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] = .keys_regs[MTK_PMIC_HOMEKEY_INDEX] =
MTK_PMIC_KEYS_REGS(MT6397_OCSTATUS2, 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, .pmic_rst_reg = MT6397_TOP_RST_MISC,
.rst_lprst_mask = MTK_PMIC_RST_DU_MASK,
}; };
static const struct mtk_pmic_regs mt6323_regs = { static const struct mtk_pmic_regs mt6323_regs = {
.keys_regs[MTK_PMIC_PWRKEY_INDEX] = .keys_regs[MTK_PMIC_PWRKEY_INDEX] =
MTK_PMIC_KEYS_REGS(MT6323_CHRSTATUS, 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] = .keys_regs[MTK_PMIC_HOMEKEY_INDEX] =
MTK_PMIC_KEYS_REGS(MT6323_CHRSTATUS, 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, .pmic_rst_reg = MT6323_TOP_RST_MISC,
.rst_lprst_mask = MTK_PMIC_RST_DU_MASK,
}; };
static const struct mtk_pmic_regs mt6358_regs = { static const struct mtk_pmic_regs mt6358_regs = {
.keys_regs[MTK_PMIC_PWRKEY_INDEX] = .keys_regs[MTK_PMIC_PWRKEY_INDEX] =
MTK_PMIC_KEYS_REGS(MT6358_TOPSTATUS, 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] = .keys_regs[MTK_PMIC_HOMEKEY_INDEX] =
MTK_PMIC_KEYS_REGS(MT6358_TOPSTATUS, 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, .pmic_rst_reg = MT6358_TOP_RST_MISC,
.rst_lprst_mask = MTK_PMIC_RST_DU_MASK,
}; };
struct mtk_pmic_keys_info { struct mtk_pmic_keys_info {
...@@ -108,53 +108,49 @@ enum mtk_pmic_keys_lp_mode { ...@@ -108,53 +108,49 @@ enum mtk_pmic_keys_lp_mode {
}; };
static void mtk_pmic_keys_lp_reset_setup(struct mtk_pmic_keys *keys, 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 long_press_mode, long_press_debounce;
u32 value, mask;
int error;
kregs_home = keys->keys[MTK_PMIC_HOMEKEY_INDEX].regs;
kregs_pwr = keys->keys[MTK_PMIC_PWRKEY_INDEX].regs;
ret = of_property_read_u32(keys->dev->of_node, error = of_property_read_u32(keys->dev->of_node, "power-off-time-sec",
"power-off-time-sec", &long_press_debounce); &long_press_debounce);
if (ret) if (error)
long_press_debounce = 0; long_press_debounce = 0;
regmap_update_bits(keys->regmap, pmic_rst_reg, mask = regs->rst_lprst_mask;
MTK_PMIC_RST_DU_MASK << MTK_PMIC_RST_DU_SHIFT, value = long_press_debounce << (ffs(regs->rst_lprst_mask) - 1);
long_press_debounce << MTK_PMIC_RST_DU_SHIFT);
ret = of_property_read_u32(keys->dev->of_node, error = of_property_read_u32(keys->dev->of_node,
"mediatek,long-press-mode", &long_press_mode); "mediatek,long-press-mode",
if (ret) &long_press_mode);
if (error)
long_press_mode = LP_DISABLE; long_press_mode = LP_DISABLE;
switch (long_press_mode) { 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: case LP_TWOKEY:
regmap_update_bits(keys->regmap, pmic_rst_reg, value |= kregs_home->rst_en_mask;
MTK_PMIC_PWRKEY_RST, fallthrough;
MTK_PMIC_PWRKEY_RST);
regmap_update_bits(keys->regmap, pmic_rst_reg, case LP_ONEKEY:
MTK_PMIC_HOMEKEY_RST, value |= kregs_pwr->rst_en_mask;
MTK_PMIC_HOMEKEY_RST); fallthrough;
break;
case LP_DISABLE: case LP_DISABLE:
regmap_update_bits(keys->regmap, pmic_rst_reg, mask |= kregs_home->rst_en_mask;
MTK_PMIC_PWRKEY_RST, mask |= kregs_pwr->rst_en_mask;
0);
regmap_update_bits(keys->regmap, pmic_rst_reg,
MTK_PMIC_HOMEKEY_RST,
0);
break; break;
default: default:
break; 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) 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) ...@@ -358,7 +354,7 @@ static int mtk_pmic_keys_probe(struct platform_device *pdev)
return error; 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); platform_set_drvdata(pdev, keys);
......
...@@ -179,11 +179,9 @@ static irqreturn_t omap4_keypad_irq_thread_fn(int irq, void *dev_id) ...@@ -179,11 +179,9 @@ static irqreturn_t omap4_keypad_irq_thread_fn(int irq, void *dev_id)
int error; int error;
u64 keys; u64 keys;
error = pm_runtime_get_sync(dev); error = pm_runtime_resume_and_get(dev);
if (error < 0) { if (error)
pm_runtime_put_noidle(dev);
return IRQ_NONE; return IRQ_NONE;
}
low = kbd_readl(keypad_data, OMAP4_KBD_FULLCODE31_0); low = kbd_readl(keypad_data, OMAP4_KBD_FULLCODE31_0);
high = kbd_readl(keypad_data, OMAP4_KBD_FULLCODE63_32); high = kbd_readl(keypad_data, OMAP4_KBD_FULLCODE63_32);
...@@ -207,11 +205,9 @@ static int omap4_keypad_open(struct input_dev *input) ...@@ -207,11 +205,9 @@ static int omap4_keypad_open(struct input_dev *input)
struct device *dev = input->dev.parent; struct device *dev = input->dev.parent;
int error; int error;
error = pm_runtime_get_sync(dev); error = pm_runtime_resume_and_get(dev);
if (error < 0) { if (error)
pm_runtime_put_noidle(dev);
return error; return error;
}
disable_irq(keypad_data->irq); disable_irq(keypad_data->irq);
...@@ -254,9 +250,10 @@ static void omap4_keypad_close(struct input_dev *input) ...@@ -254,9 +250,10 @@ static void omap4_keypad_close(struct input_dev *input)
struct device *dev = input->dev.parent; struct device *dev = input->dev.parent;
int error; int error;
error = pm_runtime_get_sync(dev); error = pm_runtime_resume_and_get(dev);
if (error < 0) if (error)
pm_runtime_put_noidle(dev); dev_err(dev, "%s: pm_runtime_resume_and_get() failed: %d\n",
__func__, error);
disable_irq(keypad_data->irq); disable_irq(keypad_data->irq);
omap4_keypad_stop(keypad_data); omap4_keypad_stop(keypad_data);
...@@ -392,10 +389,9 @@ static int omap4_keypad_probe(struct platform_device *pdev) ...@@ -392,10 +389,9 @@ static int omap4_keypad_probe(struct platform_device *pdev)
* Enable clocks for the keypad module so that we can read * Enable clocks for the keypad module so that we can read
* revision register. * revision register.
*/ */
error = pm_runtime_get_sync(dev); error = pm_runtime_resume_and_get(dev);
if (error < 0) { if (error) {
dev_err(dev, "pm_runtime_get_sync() failed\n"); dev_err(dev, "pm_runtime_resume_and_get() failed\n");
pm_runtime_put_noidle(dev);
return error; return error;
} }
......
This diff is collapsed.
...@@ -57,7 +57,7 @@ struct pip_app_resp_head { ...@@ -57,7 +57,7 @@ struct pip_app_resp_head {
* The value of data_status can be the first byte of data or * The value of data_status can be the first byte of data or
* the command status or the unsupported command code depending on the * the command status or the unsupported command code depending on the
* requested command code. * requested command code.
*/ */
u8 data_status; u8 data_status;
} __packed; } __packed;
......
...@@ -41,7 +41,7 @@ struct gpio_mouse { ...@@ -41,7 +41,7 @@ struct gpio_mouse {
/* /*
* Timer function which is run every scan_ms ms when the device is opened. * 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) static void gpio_mouse_scan(struct input_dev *input)
{ {
......
This diff is collapsed.
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/property.h>
#include <linux/ratelimit.h> #include <linux/ratelimit.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -47,6 +48,8 @@ ...@@ -47,6 +48,8 @@
#define M09_REGISTER_NUM_X 0x94 #define M09_REGISTER_NUM_X 0x94
#define M09_REGISTER_NUM_Y 0x95 #define M09_REGISTER_NUM_Y 0x95
#define M12_REGISTER_REPORT_RATE 0x88
#define EV_REGISTER_THRESHOLD 0x40 #define EV_REGISTER_THRESHOLD 0x40
#define EV_REGISTER_GAIN 0x41 #define EV_REGISTER_GAIN 0x41
#define EV_REGISTER_OFFSET_Y 0x45 #define EV_REGISTER_OFFSET_Y 0x45
...@@ -127,9 +130,12 @@ struct edt_ft5x06_ts_data { ...@@ -127,9 +130,12 @@ struct edt_ft5x06_ts_data {
int max_support_points; int max_support_points;
char name[EDT_NAME_LEN]; char name[EDT_NAME_LEN];
char fw_version[EDT_NAME_LEN];
struct edt_reg_addr reg_addr; struct edt_reg_addr reg_addr;
enum edt_ver version; enum edt_ver version;
unsigned int crc_errors;
unsigned int header_errors;
}; };
struct edt_i2c_chip_data { struct edt_i2c_chip_data {
...@@ -178,6 +184,7 @@ static bool edt_ft5x06_ts_check_crc(struct edt_ft5x06_ts_data *tsdata, ...@@ -178,6 +184,7 @@ static bool edt_ft5x06_ts_check_crc(struct edt_ft5x06_ts_data *tsdata,
crc ^= buf[i]; crc ^= buf[i];
if (crc != buf[buflen-1]) { if (crc != buf[buflen-1]) {
tsdata->crc_errors++;
dev_err_ratelimited(&tsdata->client->dev, dev_err_ratelimited(&tsdata->client->dev,
"crc error: 0x%02x expected, got 0x%02x\n", "crc error: 0x%02x expected, got 0x%02x\n",
crc, buf[buflen-1]); crc, buf[buflen-1]);
...@@ -235,6 +242,7 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id) ...@@ -235,6 +242,7 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
if (tsdata->version == EDT_M06) { if (tsdata->version == EDT_M06) {
if (rdbuf[0] != 0xaa || rdbuf[1] != 0xaa || if (rdbuf[0] != 0xaa || rdbuf[1] != 0xaa ||
rdbuf[2] != datalen) { rdbuf[2] != datalen) {
tsdata->header_errors++;
dev_err_ratelimited(dev, dev_err_ratelimited(dev,
"Unexpected header: %02x%02x%02x!\n", "Unexpected header: %02x%02x%02x!\n",
rdbuf[0], rdbuf[1], rdbuf[2]); rdbuf[0], rdbuf[1], rdbuf[2]);
...@@ -523,9 +531,55 @@ static EDT_ATTR(offset_y, S_IWUSR | S_IRUGO, NO_REGISTER, NO_REGISTER, ...@@ -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... */ /* 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, static EDT_ATTR(threshold, S_IWUSR | S_IRUGO, WORK_REGISTER_THRESHOLD,
M09_REGISTER_THRESHOLD, EV_REGISTER_THRESHOLD, 0, 255); 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, 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[] = { static struct attribute *edt_ft5x06_attrs[] = {
&edt_ft5x06_attr_gain.dattr.attr, &edt_ft5x06_attr_gain.dattr.attr,
...@@ -534,6 +588,10 @@ static struct attribute *edt_ft5x06_attrs[] = { ...@@ -534,6 +588,10 @@ static struct attribute *edt_ft5x06_attrs[] = {
&edt_ft5x06_attr_offset_y.dattr.attr, &edt_ft5x06_attr_offset_y.dattr.attr,
&edt_ft5x06_attr_threshold.dattr.attr, &edt_ft5x06_attr_threshold.dattr.attr,
&edt_ft5x06_attr_report_rate.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 NULL
}; };
...@@ -820,13 +878,13 @@ static void edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata) ...@@ -820,13 +878,13 @@ static void edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)
#endif /* CONFIG_DEBUGFS */ #endif /* CONFIG_DEBUGFS */
static int edt_ft5x06_ts_identify(struct i2c_client *client, static int edt_ft5x06_ts_identify(struct i2c_client *client,
struct edt_ft5x06_ts_data *tsdata, struct edt_ft5x06_ts_data *tsdata)
char *fw_version)
{ {
u8 rdbuf[EDT_NAME_LEN]; u8 rdbuf[EDT_NAME_LEN];
char *p; char *p;
int error; int error;
char *model_name = tsdata->name; char *model_name = tsdata->name;
char *fw_version = tsdata->fw_version;
/* see what we find if we assume it is a M06 * /* see what we find if we assume it is a M06 *
* if we get less than EDT_NAME_LEN, we don't want * 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) ...@@ -1030,7 +1088,8 @@ static void edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata)
case EDT_M09: case EDT_M09:
case EDT_M12: case EDT_M12:
reg_addr->reg_threshold = M09_REGISTER_THRESHOLD; 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_gain = M09_REGISTER_GAIN;
reg_addr->reg_offset = M09_REGISTER_OFFSET; reg_addr->reg_offset = M09_REGISTER_OFFSET;
reg_addr->reg_offset_x = NO_REGISTER; reg_addr->reg_offset_x = NO_REGISTER;
...@@ -1081,7 +1140,7 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client, ...@@ -1081,7 +1140,7 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
struct input_dev *input; struct input_dev *input;
unsigned long irq_flags; unsigned long irq_flags;
int error; int error;
char fw_version[EDT_NAME_LEN]; u32 report_rate;
dev_dbg(&client->dev, "probing for EDT FT5x06 I2C\n"); dev_dbg(&client->dev, "probing for EDT FT5x06 I2C\n");
...@@ -1194,7 +1253,7 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client, ...@@ -1194,7 +1253,7 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
tsdata->input = input; tsdata->input = input;
tsdata->factory_mode = false; tsdata->factory_mode = false;
error = edt_ft5x06_ts_identify(client, tsdata, fw_version); error = edt_ft5x06_ts_identify(client, tsdata);
if (error) { if (error) {
dev_err(&client->dev, "touchscreen probe failed\n"); dev_err(&client->dev, "touchscreen probe failed\n");
return error; return error;
...@@ -1210,9 +1269,30 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client, ...@@ -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_defaults(&client->dev, tsdata);
edt_ft5x06_ts_get_parameters(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, dev_dbg(&client->dev,
"Model \"%s\", Rev. \"%s\", %dx%d sensors\n", "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->name = tsdata->name;
input->id.bustype = BUS_I2C; input->id.bustype = BUS_I2C;
......
...@@ -220,6 +220,7 @@ static int exc3000_vendor_data_request(struct exc3000_data *data, u8 *request, ...@@ -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 }; u8 buf[EXC3000_LEN_VENDOR_REQUEST] = { 0x67, 0x00, 0x42, 0x00, 0x03 };
int ret; int ret;
unsigned long time_left;
mutex_lock(&data->query_lock); mutex_lock(&data->query_lock);
...@@ -233,9 +234,9 @@ static int exc3000_vendor_data_request(struct exc3000_data *data, u8 *request, ...@@ -233,9 +234,9 @@ static int exc3000_vendor_data_request(struct exc3000_data *data, u8 *request,
goto out_unlock; goto out_unlock;
if (response) { if (response) {
ret = wait_for_completion_timeout(&data->wait_event, time_left = wait_for_completion_timeout(&data->wait_event,
timeout * HZ); timeout * HZ);
if (ret <= 0) { if (time_left == 0) {
ret = -ETIMEDOUT; ret = -ETIMEDOUT;
goto out_unlock; goto out_unlock;
} }
......
...@@ -822,22 +822,16 @@ static int goodix_resource(struct acpi_resource *ares, void *data) ...@@ -822,22 +822,16 @@ static int goodix_resource(struct acpi_resource *ares, void *data)
struct device *dev = &ts->client->dev; struct device *dev = &ts->client->dev;
struct acpi_resource_gpio *gpio; struct acpi_resource_gpio *gpio;
switch (ares->type) { if (acpi_gpio_get_irq_resource(ares, &gpio)) {
case ACPI_RESOURCE_TYPE_GPIO: if (ts->gpio_int_idx == -1) {
gpio = &ares->data.gpio; ts->gpio_int_idx = ts->gpio_count;
if (gpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT) { } else {
if (ts->gpio_int_idx == -1) { dev_err(dev, "More then one GpioInt resource, ignoring ACPI GPIO resources\n");
ts->gpio_int_idx = ts->gpio_count; ts->gpio_int_idx = -2;
} else {
dev_err(dev, "More then one GpioInt resource, ignoring ACPI GPIO resources\n");
ts->gpio_int_idx = -2;
}
} }
ts->gpio_count++; ts->gpio_count++;
break; } else if (acpi_gpio_get_io_resource(ares, &gpio))
default: ts->gpio_count++;
break;
}
return 0; return 0;
} }
......
...@@ -15,75 +15,75 @@ ...@@ -15,75 +15,75 @@
/* Register Map */ /* Register Map */
#define BT541_SWRESET_CMD 0x0000 #define ZINITIX_SWRESET_CMD 0x0000
#define BT541_WAKEUP_CMD 0x0001 #define ZINITIX_WAKEUP_CMD 0x0001
#define BT541_IDLE_CMD 0x0004 #define ZINITIX_IDLE_CMD 0x0004
#define BT541_SLEEP_CMD 0x0005 #define ZINITIX_SLEEP_CMD 0x0005
#define BT541_CLEAR_INT_STATUS_CMD 0x0003 #define ZINITIX_CLEAR_INT_STATUS_CMD 0x0003
#define BT541_CALIBRATE_CMD 0x0006 #define ZINITIX_CALIBRATE_CMD 0x0006
#define BT541_SAVE_STATUS_CMD 0x0007 #define ZINITIX_SAVE_STATUS_CMD 0x0007
#define BT541_SAVE_CALIBRATION_CMD 0x0008 #define ZINITIX_SAVE_CALIBRATION_CMD 0x0008
#define BT541_RECALL_FACTORY_CMD 0x000f #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 ZINITIX_TOUCH_MODE 0x0010
#define BT541_CHIP_REVISION 0x0011 #define ZINITIX_CHIP_REVISION 0x0011
#define BT541_FIRMWARE_VERSION 0x0012 #define ZINITIX_FIRMWARE_VERSION 0x0012
#define ZINITIX_USB_DETECT 0x116 #define ZINITIX_USB_DETECT 0x116
#define BT541_MINOR_FW_VERSION 0x0121 #define ZINITIX_MINOR_FW_VERSION 0x0121
#define BT541_VENDOR_ID 0x001C #define ZINITIX_VENDOR_ID 0x001C
#define BT541_HW_ID 0x0014 #define ZINITIX_HW_ID 0x0014
#define BT541_DATA_VERSION_REG 0x0013 #define ZINITIX_DATA_VERSION_REG 0x0013
#define BT541_SUPPORTED_FINGER_NUM 0x0015 #define ZINITIX_SUPPORTED_FINGER_NUM 0x0015
#define BT541_EEPROM_INFO 0x0018 #define ZINITIX_EEPROM_INFO 0x0018
#define BT541_INITIAL_TOUCH_MODE 0x0019 #define ZINITIX_INITIAL_TOUCH_MODE 0x0019
#define BT541_TOTAL_NUMBER_OF_X 0x0060 #define ZINITIX_TOTAL_NUMBER_OF_X 0x0060
#define BT541_TOTAL_NUMBER_OF_Y 0x0061 #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 ZINITIX_BUTTON_SUPPORTED_NUM 0x00B0
#define BT541_BUTTON_SENSITIVITY 0x00B2 #define ZINITIX_BUTTON_SENSITIVITY 0x00B2
#define BT541_DUMMY_BUTTON_SENSITIVITY 0X00C8 #define ZINITIX_DUMMY_BUTTON_SENSITIVITY 0X00C8
#define BT541_X_RESOLUTION 0x00C0 #define ZINITIX_X_RESOLUTION 0x00C0
#define BT541_Y_RESOLUTION 0x00C1 #define ZINITIX_Y_RESOLUTION 0x00C1
#define BT541_POINT_STATUS_REG 0x0080 #define ZINITIX_POINT_STATUS_REG 0x0080
#define BT541_ICON_STATUS_REG 0x00AA #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 ZINITIX_AFE_FREQUENCY 0x0100
#define BT541_DND_N_COUNT 0x0122 #define ZINITIX_DND_N_COUNT 0x0122
#define BT541_DND_U_COUNT 0x0135 #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 ZINITIX_INT_ENABLE_FLAG 0x00f0
#define BT541_PERIODICAL_INTERRUPT_INTERVAL 0x00f1 #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 ZINITIX_INIT_FLASH 0x01d0
#define BT541_WRITE_FLASH 0x01d1 #define ZINITIX_WRITE_FLASH 0x01d1
#define BT541_READ_FLASH 0x01d2 #define ZINITIX_READ_FLASH 0x01d2
#define ZINITIX_INTERNAL_FLAG_02 0x011e #define ZINITIX_INTERNAL_FLAG_02 0x011e
#define ZINITIX_INTERNAL_FLAG_03 0x011f #define ZINITIX_INTERNAL_FLAG_03 0x011f
...@@ -196,13 +196,13 @@ static int zinitix_init_touch(struct bt541_ts_data *bt541) ...@@ -196,13 +196,13 @@ static int zinitix_init_touch(struct bt541_ts_data *bt541)
int i; int i;
int error; int error;
error = zinitix_write_cmd(client, BT541_SWRESET_CMD); error = zinitix_write_cmd(client, ZINITIX_SWRESET_CMD);
if (error) { if (error) {
dev_err(&client->dev, "Failed to write reset command\n"); dev_err(&client->dev, "Failed to write reset command\n");
return error; return error;
} }
error = zinitix_write_u16(client, BT541_INT_ENABLE_FLAG, 0x0); error = zinitix_write_u16(client, ZINITIX_INT_ENABLE_FLAG, 0x0);
if (error) { if (error) {
dev_err(&client->dev, dev_err(&client->dev,
"Failed to reset interrupt enable flag\n"); "Failed to reset interrupt enable flag\n");
...@@ -210,32 +210,32 @@ static int zinitix_init_touch(struct bt541_ts_data *bt541) ...@@ -210,32 +210,32 @@ static int zinitix_init_touch(struct bt541_ts_data *bt541)
} }
/* initialize */ /* initialize */
error = zinitix_write_u16(client, BT541_X_RESOLUTION, error = zinitix_write_u16(client, ZINITIX_X_RESOLUTION,
bt541->prop.max_x); bt541->prop.max_x);
if (error) if (error)
return error; return error;
error = zinitix_write_u16(client, BT541_Y_RESOLUTION, error = zinitix_write_u16(client, ZINITIX_Y_RESOLUTION,
bt541->prop.max_y); bt541->prop.max_y);
if (error) if (error)
return 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); MAX_SUPPORTED_FINGER_NUM);
if (error) if (error)
return error; return error;
error = zinitix_write_u16(client, BT541_INITIAL_TOUCH_MODE, error = zinitix_write_u16(client, ZINITIX_INITIAL_TOUCH_MODE,
bt541->zinitix_mode); bt541->zinitix_mode);
if (error) if (error)
return error; return error;
error = zinitix_write_u16(client, BT541_TOUCH_MODE, error = zinitix_write_u16(client, ZINITIX_TOUCH_MODE,
bt541->zinitix_mode); bt541->zinitix_mode);
if (error) if (error)
return 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_PT_CNT_CHANGE | BIT_DOWN | BIT_MOVE |
BIT_UP); BIT_UP);
if (error) if (error)
...@@ -243,7 +243,7 @@ static int zinitix_init_touch(struct bt541_ts_data *bt541) ...@@ -243,7 +243,7 @@ static int zinitix_init_touch(struct bt541_ts_data *bt541)
/* clear queue */ /* clear queue */
for (i = 0; i < 10; i++) { 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); udelay(10);
} }
...@@ -361,7 +361,7 @@ static irqreturn_t zinitix_ts_irq_handler(int irq, void *bt541_handler) ...@@ -361,7 +361,7 @@ static irqreturn_t zinitix_ts_irq_handler(int irq, void *bt541_handler)
memset(&touch_event, 0, sizeof(struct touch_event)); 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)); &touch_event, sizeof(struct touch_event));
if (error) { if (error) {
dev_err(&client->dev, "Failed to read in touchpoint struct\n"); 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) ...@@ -381,7 +381,7 @@ static irqreturn_t zinitix_ts_irq_handler(int irq, void *bt541_handler)
input_sync(bt541->input_dev); input_sync(bt541->input_dev);
out: out:
zinitix_write_cmd(bt541->client, BT541_CLEAR_INT_STATUS_CMD); zinitix_write_cmd(bt541->client, ZINITIX_CLEAR_INT_STATUS_CMD);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment