mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 05:32:00 +00:00
Input updates for 6.6 merge window:
- a new driver for Azoteq IQS7210A/7211A/E touch controllers - support for Azoteq IQS7222D variant added to iqs7222 driver - support for touch keys functionality added to Melfas MMS114 driver - new hardware IDs added to exc3000 and Goodix drivers - xpad driver gained support for GameSir T4 Kaleid Controller - a fix for xpad driver to properly support some third-party controllers that need a magic packet to start properly - a fix for psmouse driver to more reliably switch to RMI4 mode on devices that use native RMI4/SMbus protocol - a quirk for i8042 for TUXEDO Gemini 17 Gen1/Clevo PD70PN laptops - multiple drivers have been updated to make use of devm and other newer APIs such as dev_err_probe(), devm_regulator_get_enable(), and others. -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQST2eWILY88ieB2DOtAj56VGEWXnAUCZPeTEAAKCRBAj56VGEWX nKzYAPwJ7ctpjx11opQrxAz83mW2NSuEI+v3vodpRfqO3DewvQD/QnspSzUuTSWv hWSQ1uagKZm4FqeJPDowVrU1E9Lq9Aw= =z9DZ -----END PGP SIGNATURE----- Merge tag 'input-for-v6.6-rc0' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input Pull input updates from Dmitry Torokhov: - a new driver for Azoteq IQS7210A/7211A/E touch controllers - support for Azoteq IQS7222D variant added to iqs7222 driver - support for touch keys functionality added to Melfas MMS114 driver - new hardware IDs added to exc3000 and Goodix drivers - xpad driver gained support for GameSir T4 Kaleid Controller - a fix for xpad driver to properly support some third-party controllers that need a magic packet to start properly - a fix for psmouse driver to more reliably switch to RMI4 mode on devices that use native RMI4/SMbus protocol - a quirk for i8042 for TUXEDO Gemini 17 Gen1/Clevo PD70PN laptops - multiple drivers have been updated to make use of devm and other newer APIs such as dev_err_probe(), devm_regulator_get_enable(), and others. * tag 'input-for-v6.6-rc0' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (83 commits) Input: goodix - add support for ACPI ID GDX9110 Input: rpckbd - fix the return value handle for platform_get_irq() Input: tca6416-keypad - switch to using input core's polling features Input: tca6416-keypad - convert to use devm_* api Input: tca6416-keypad - fix interrupt enable disbalance Input: tca6416-keypad - rely on I2C core to set up suspend/resume Input: tca6416-keypad - always expect proper IRQ number in i2c client Input: lm8323 - convert to use devm_* api Input: lm8323 - rely on device core to create kp_disable attribute Input: qt2160 - convert to use devm_* api Input: qt2160 - do not hard code interrupt trigger Input: qt2160 - switch to using threaded interrupt handler Input: qt2160 - tweak check for i2c adapter functionality Input: psmouse - add delay when deactivating for SMBus mode Input: mcs-touchkey - fix uninitialized use of error in mcs_touchkey_probe() Input: qt1070 - convert to use devm_* api Input: mcs-touchkey - convert to use devm_* api Input: amikbd - convert to use devm_* api Input: lm8333 - convert to use devm_* api Input: mms114 - add support for touch keys ...
This commit is contained in:
commit
744a759492
@ -4,14 +4,14 @@
|
||||
$id: http://devicetree.org/schemas/input/azoteq,iqs7222.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Azoteq IQS7222A/B/C Capacitive Touch Controller
|
||||
title: Azoteq IQS7222A/B/C/D Capacitive Touch Controller
|
||||
|
||||
maintainers:
|
||||
- Jeff LaBundy <jeff@labundy.com>
|
||||
|
||||
description: |
|
||||
The Azoteq IQS7222A, IQS7222B and IQS7222C are multichannel capacitive touch
|
||||
controllers that feature additional sensing capabilities.
|
||||
The Azoteq IQS7222A, IQS7222B, IQS7222C and IQS7222D are multichannel
|
||||
capacitive touch controllers that feature additional sensing capabilities.
|
||||
|
||||
Link to datasheets: https://www.azoteq.com/
|
||||
|
||||
@ -21,6 +21,7 @@ properties:
|
||||
- azoteq,iqs7222a
|
||||
- azoteq,iqs7222b
|
||||
- azoteq,iqs7222c
|
||||
- azoteq,iqs7222d
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@ -173,6 +174,152 @@ properties:
|
||||
maximum: 3000
|
||||
description: Specifies the report rate (in ms) during ultra-low-power mode.
|
||||
|
||||
touchscreen-size-x: true
|
||||
touchscreen-size-y: true
|
||||
touchscreen-inverted-x: true
|
||||
touchscreen-inverted-y: true
|
||||
touchscreen-swapped-x-y: true
|
||||
|
||||
trackpad:
|
||||
type: object
|
||||
description: Represents all channels associated with the trackpad.
|
||||
|
||||
properties:
|
||||
azoteq,channel-select:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 12
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 13
|
||||
description:
|
||||
Specifies the order of the channels that participate in the trackpad.
|
||||
Specify 255 to omit a given channel for the purpose of mapping a non-
|
||||
rectangular trackpad.
|
||||
|
||||
azoteq,num-rows:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 1
|
||||
maximum: 12
|
||||
description: Specifies the number of rows that comprise the trackpad.
|
||||
|
||||
azoteq,num-cols:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 1
|
||||
maximum: 12
|
||||
description: Specifies the number of columns that comprise the trackpad.
|
||||
|
||||
azoteq,top-speed:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
multipleOf: 4
|
||||
minimum: 0
|
||||
maximum: 1020
|
||||
description:
|
||||
Specifies the speed (in coordinates traveled per conversion) after
|
||||
which coordinate filtering is no longer applied.
|
||||
|
||||
azoteq,bottom-speed:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description:
|
||||
Specifies the speed (in coordinates traveled per conversion) after
|
||||
which coordinate filtering is linearly reduced.
|
||||
|
||||
azoteq,use-prox:
|
||||
type: boolean
|
||||
description:
|
||||
Directs the trackpad to respond to the proximity states of the
|
||||
selected channels instead of their corresponding touch states.
|
||||
Note the trackpad cannot report granular coordinates during a
|
||||
state of proximity.
|
||||
|
||||
patternProperties:
|
||||
"^azoteq,lower-cal-(x|y)$":
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the trackpad's lower starting points.
|
||||
|
||||
"^azoteq,upper-cal-(x|y)$":
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the trackpad's upper starting points.
|
||||
|
||||
"^event-(press|tap|(swipe|flick)-(x|y)-(pos|neg))$":
|
||||
type: object
|
||||
$ref: input.yaml#
|
||||
description:
|
||||
Represents a press or gesture event reported by the trackpad. Specify
|
||||
'linux,code' under the press event to report absolute coordinates.
|
||||
|
||||
properties:
|
||||
linux,code: true
|
||||
|
||||
azoteq,gesture-angle-tighten:
|
||||
type: boolean
|
||||
description:
|
||||
Limits the tangent of the gesture angle to 0.5 (axial gestures
|
||||
only). If specified in one direction, the effect is applied in
|
||||
either direction.
|
||||
|
||||
azoteq,gesture-max-ms:
|
||||
multipleOf: 16
|
||||
minimum: 0
|
||||
maximum: 4080
|
||||
description:
|
||||
Specifies the length of time (in ms) within which a tap, swipe
|
||||
or flick gesture must be completed in order to be acknowledged
|
||||
by the device. The number specified for any one swipe or flick
|
||||
gesture applies to all other swipe or flick gestures.
|
||||
|
||||
azoteq,gesture-min-ms:
|
||||
multipleOf: 16
|
||||
minimum: 0
|
||||
maximum: 4080
|
||||
description:
|
||||
Specifies the length of time (in ms) for which a tap gesture must
|
||||
be held in order to be acknowledged by the device.
|
||||
|
||||
azoteq,gesture-dist:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description:
|
||||
Specifies the distance (in coordinates) across which a swipe or
|
||||
flick gesture must travel in order to be acknowledged by the
|
||||
device. The number specified for any one swipe or flick gesture
|
||||
applies to all remaining swipe or flick gestures.
|
||||
|
||||
For tap gestures, this property specifies the distance from the
|
||||
original point of contact across which the contact is permitted
|
||||
to travel before the gesture is rejected by the device.
|
||||
|
||||
azoteq,gpio-select:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 2
|
||||
description: |
|
||||
Specifies one or more GPIO mapped to the event as follows:
|
||||
0: GPIO0
|
||||
1: GPIO3
|
||||
2: GPIO4
|
||||
|
||||
Note that although multiple events can be mapped to a single
|
||||
GPIO, they must all be of the same type (proximity, touch or
|
||||
trackpad gesture).
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- azoteq,channel-select
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
patternProperties:
|
||||
"^cycle-[0-9]$":
|
||||
type: object
|
||||
@ -288,6 +435,10 @@ patternProperties:
|
||||
Activates the reference channel in response to proximity events
|
||||
instead of touch events.
|
||||
|
||||
azoteq,counts-filt-enable:
|
||||
type: boolean
|
||||
description: Applies counts filtering to the channel.
|
||||
|
||||
azoteq,ati-band:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1, 2, 3]
|
||||
@ -432,12 +583,12 @@ patternProperties:
|
||||
description: |
|
||||
Specifies one or more GPIO mapped to the event as follows:
|
||||
0: GPIO0
|
||||
1: GPIO3 (IQS7222C only)
|
||||
2: GPIO4 (IQS7222C only)
|
||||
1: GPIO3
|
||||
2: GPIO4
|
||||
|
||||
Note that although multiple events can be mapped to a single
|
||||
GPIO, they must all be of the same type (proximity, touch or
|
||||
slider gesture).
|
||||
slider/trackpad gesture).
|
||||
|
||||
azoteq,thresh:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
@ -521,16 +672,16 @@ patternProperties:
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description:
|
||||
Specifies the speed of movement after which coordinate filtering is
|
||||
no longer applied.
|
||||
Specifies the speed (in coordinates traveled per conversion) after
|
||||
which coordinate filtering is no longer applied.
|
||||
|
||||
azoteq,bottom-speed:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description:
|
||||
Specifies the speed of movement after which coordinate filtering is
|
||||
linearly reduced.
|
||||
Specifies the speed (in coordinates traveled per conversion) after
|
||||
which coordinate filtering is linearly reduced.
|
||||
|
||||
azoteq,bottom-beta:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
@ -595,10 +746,10 @@ patternProperties:
|
||||
minimum: 0
|
||||
maximum: 4080
|
||||
description:
|
||||
Specifies the distance across which a swipe or flick gesture must
|
||||
travel in order to be acknowledged by the device. The number spec-
|
||||
ified for any one swipe or flick gesture applies to all remaining
|
||||
swipe or flick gestures.
|
||||
Specifies the distance (in coordinates) across which a swipe or
|
||||
flick gesture must travel in order to be acknowledged by the
|
||||
device. The number specified for any one swipe or flick gesture
|
||||
applies to all remaining swipe or flick gestures.
|
||||
|
||||
azoteq,gpio-select:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
@ -610,8 +761,8 @@ patternProperties:
|
||||
description: |
|
||||
Specifies one or more GPIO mapped to the event as follows:
|
||||
0: GPIO0
|
||||
1: GPIO3 (IQS7222C only)
|
||||
2: GPIO4 (IQS7222C only)
|
||||
1: GPIO3
|
||||
2: GPIO4
|
||||
|
||||
Note that although multiple events can be mapped to a single
|
||||
GPIO, they must all be of the same type (proximity, touch or
|
||||
@ -629,8 +780,8 @@ patternProperties:
|
||||
description: |
|
||||
Represents a GPIO mapped to one or more events as follows:
|
||||
gpio-0: GPIO0
|
||||
gpio-1: GPIO3 (IQS7222C only)
|
||||
gpio-2: GPIO4 (IQS7222C only)
|
||||
gpio-1: GPIO3
|
||||
gpio-2: GPIO4
|
||||
|
||||
allOf:
|
||||
- $ref: ../pinctrl/pincfg-node.yaml#
|
||||
@ -641,11 +792,53 @@ patternProperties:
|
||||
additionalProperties: false
|
||||
|
||||
allOf:
|
||||
- $ref: touchscreen/touchscreen.yaml#
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: azoteq,iqs7222b
|
||||
enum:
|
||||
- azoteq,iqs7222a
|
||||
- azoteq,iqs7222b
|
||||
- azoteq,iqs7222c
|
||||
|
||||
then:
|
||||
properties:
|
||||
touchscreen-size-x: false
|
||||
touchscreen-size-y: false
|
||||
touchscreen-inverted-x: false
|
||||
touchscreen-inverted-y: false
|
||||
touchscreen-swapped-x-y: false
|
||||
|
||||
trackpad: false
|
||||
|
||||
patternProperties:
|
||||
"^channel-([0-9]|1[0-9])$":
|
||||
properties:
|
||||
azoteq,counts-filt-enable: false
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- azoteq,iqs7222b
|
||||
- azoteq,iqs7222c
|
||||
|
||||
then:
|
||||
patternProperties:
|
||||
"^channel-([0-9]|1[0-9])$":
|
||||
properties:
|
||||
azoteq,ulp-allow: false
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- azoteq,iqs7222b
|
||||
- azoteq,iqs7222d
|
||||
|
||||
then:
|
||||
patternProperties:
|
||||
@ -657,13 +850,22 @@ allOf:
|
||||
properties:
|
||||
azoteq,ref-select: false
|
||||
|
||||
"^slider-[0-1]$": false
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: azoteq,iqs7222b
|
||||
|
||||
then:
|
||||
patternProperties:
|
||||
"^channel-([0-9]|1[0-9])$":
|
||||
patternProperties:
|
||||
"^event-(prox|touch)$":
|
||||
properties:
|
||||
azoteq,gpio-select: false
|
||||
|
||||
"^slider-[0-1]$": false
|
||||
|
||||
"^gpio-[0-2]$": false
|
||||
|
||||
- if:
|
||||
@ -704,10 +906,6 @@ allOf:
|
||||
|
||||
else:
|
||||
patternProperties:
|
||||
"^channel-([0-9]|1[0-9])$":
|
||||
properties:
|
||||
azoteq,ulp-allow: false
|
||||
|
||||
"^slider-[0-1]$":
|
||||
patternProperties:
|
||||
"^event-(press|tap|(swipe|flick)-(pos|neg))$":
|
||||
|
@ -0,0 +1,769 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/input/touchscreen/azoteq,iqs7211.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Azoteq IQS7210A/7211A/E Trackpad/Touchscreen Controller
|
||||
|
||||
maintainers:
|
||||
- Jeff LaBundy <jeff@labundy.com>
|
||||
|
||||
description: |
|
||||
The Azoteq IQS7210A, IQS7211A and IQS7211E trackpad and touchscreen control-
|
||||
lers employ projected-capacitance sensing and can track two contacts.
|
||||
|
||||
Link to datasheets: https://www.azoteq.com/
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- azoteq,iqs7210a
|
||||
- azoteq,iqs7211a
|
||||
- azoteq,iqs7211e
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
irq-gpios:
|
||||
maxItems: 1
|
||||
description:
|
||||
Specifies the GPIO connected to the device's active-low RDY output. The
|
||||
pin doubles as the IQS7211E's active-low MCLR input, in which case this
|
||||
GPIO must be configured as open-drain.
|
||||
|
||||
reset-gpios:
|
||||
maxItems: 1
|
||||
description:
|
||||
Specifies the GPIO connected to the device's active-low MCLR input. The
|
||||
device is temporarily held in hardware reset prior to initialization if
|
||||
this property is present.
|
||||
|
||||
azoteq,forced-comms:
|
||||
type: boolean
|
||||
description:
|
||||
Enables forced communication; to be used with host adapters that cannot
|
||||
tolerate clock stretching.
|
||||
|
||||
azoteq,forced-comms-default:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1]
|
||||
description:
|
||||
Indicates if the device's OTP memory enables (1) or disables (0) forced
|
||||
communication by default. Specifying this property can expedite startup
|
||||
time if the default value is known.
|
||||
|
||||
If this property is not specified, communication is not initiated until
|
||||
the device asserts its RDY pin shortly after exiting hardware reset. At
|
||||
that point, forced communication is either enabled or disabled based on
|
||||
the presence or absence of the 'azoteq,forced-comms' property.
|
||||
|
||||
azoteq,rate-active-ms:
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description: Specifies the report rate (in ms) during active mode.
|
||||
|
||||
azoteq,rate-touch-ms:
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description: Specifies the report rate (in ms) during idle-touch mode.
|
||||
|
||||
azoteq,rate-idle-ms:
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description: Specifies the report rate (in ms) during idle mode.
|
||||
|
||||
azoteq,rate-lp1-ms:
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description: Specifies the report rate (in ms) during low-power mode 1.
|
||||
|
||||
azoteq,rate-lp2-ms:
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description: Specifies the report rate (in ms) during low-power mode 2.
|
||||
|
||||
azoteq,timeout-active-ms:
|
||||
multipleOf: 1000
|
||||
minimum: 0
|
||||
maximum: 65535000
|
||||
description:
|
||||
Specifies the length of time (in ms) to wait for an event before moving
|
||||
from active mode to idle or idle-touch modes.
|
||||
|
||||
azoteq,timeout-touch-ms:
|
||||
multipleOf: 1000
|
||||
minimum: 0
|
||||
maximum: 65535000
|
||||
description:
|
||||
Specifies the length of time (in ms) to wait for an event before moving
|
||||
from idle-touch mode to idle mode.
|
||||
|
||||
azoteq,timeout-idle-ms:
|
||||
multipleOf: 1000
|
||||
minimum: 0
|
||||
maximum: 65535000
|
||||
description:
|
||||
Specifies the length of time (in ms) to wait for an event before moving
|
||||
from idle mode to low-power mode 1.
|
||||
|
||||
azoteq,timeout-lp1-ms:
|
||||
multipleOf: 1000
|
||||
minimum: 0
|
||||
maximum: 65535000
|
||||
description:
|
||||
Specifies the length of time (in ms) to wait for an event before moving
|
||||
from low-power mode 1 to low-power mode 2.
|
||||
|
||||
azoteq,timeout-lp2-ms:
|
||||
multipleOf: 1000
|
||||
minimum: 0
|
||||
maximum: 60000
|
||||
description:
|
||||
Specifies the rate (in ms) at which the trackpad reference values
|
||||
are updated during low-power modes 1 and 2.
|
||||
|
||||
azoteq,timeout-ati-ms:
|
||||
multipleOf: 1000
|
||||
minimum: 0
|
||||
maximum: 60000
|
||||
description:
|
||||
Specifies the delay (in ms) before the automatic tuning implementation
|
||||
(ATI) is retried in the event it fails to complete.
|
||||
|
||||
azoteq,timeout-comms-ms:
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description:
|
||||
Specifies the delay (in ms) before a communication window is closed.
|
||||
|
||||
azoteq,timeout-press-ms:
|
||||
multipleOf: 1000
|
||||
minimum: 0
|
||||
maximum: 60000
|
||||
description:
|
||||
Specifies the length of time (in ms) to wait before automatically
|
||||
releasing a press event. Specify zero to allow the press state to
|
||||
persist indefinitely.
|
||||
|
||||
azoteq,fosc-freq:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1]
|
||||
description: |
|
||||
Specifies the device's core clock frequency as follows:
|
||||
0: 14 MHz
|
||||
1: 18 MHz
|
||||
|
||||
azoteq,fosc-trim:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 15
|
||||
description: Specifies the device's core clock frequency trim.
|
||||
|
||||
azoteq,num-contacts:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 2
|
||||
default: 0
|
||||
description: Specifies the number of contacts reported by the device.
|
||||
|
||||
azoteq,contact-split:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the contact (finger) split factor.
|
||||
|
||||
azoteq,trim-x:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the horizontal trim width.
|
||||
|
||||
azoteq,trim-y:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the vertical trim height.
|
||||
|
||||
trackpad:
|
||||
type: object
|
||||
description: Represents all channels associated with the trackpad.
|
||||
|
||||
properties:
|
||||
azoteq,rx-enable:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 8
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 7
|
||||
description:
|
||||
Specifies the order of the CRx pin(s) associated with the trackpad.
|
||||
|
||||
azoteq,tx-enable:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 12
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 11
|
||||
description:
|
||||
Specifies the order of the CTx pin(s) associated with the trackpad.
|
||||
|
||||
azoteq,channel-select:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 36
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: |
|
||||
Specifies the channels mapped to each cycle in the following order:
|
||||
Cycle 0, slot 0
|
||||
Cycle 0, slot 1
|
||||
Cycle 1, slot 0
|
||||
Cycle 1, slot 1
|
||||
...and so on. Specify 255 to disable a given slot.
|
||||
|
||||
azoteq,ati-frac-div-fine:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 31
|
||||
description: Specifies the trackpad's ATI fine fractional divider.
|
||||
|
||||
azoteq,ati-frac-mult-coarse:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 15
|
||||
description: Specifies the trackpad's ATI coarse fractional multiplier.
|
||||
|
||||
azoteq,ati-frac-div-coarse:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 31
|
||||
description: Specifies the trackpad's ATI coarse fractional divider.
|
||||
|
||||
azoteq,ati-comp-div:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 31
|
||||
description: Specifies the trackpad's ATI compensation divider.
|
||||
|
||||
azoteq,ati-target:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description: Specifies the trackpad's ATI target.
|
||||
|
||||
azoteq,touch-enter:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the trackpad's touch entrance factor.
|
||||
|
||||
azoteq,touch-exit:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the trackpad's touch exit factor.
|
||||
|
||||
azoteq,thresh:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the trackpad's stationary touch threshold.
|
||||
|
||||
azoteq,conv-period:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the trackpad's conversion period.
|
||||
|
||||
azoteq,conv-frac:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the trackpad's conversion frequency fraction.
|
||||
|
||||
patternProperties:
|
||||
"^event-(tap(-double|-triple)?|hold|palm|swipe-(x|y)-(pos|neg)(-hold)?)$":
|
||||
type: object
|
||||
$ref: ../input.yaml#
|
||||
description:
|
||||
Represents a gesture event reported by the trackpad. In the case of
|
||||
axial gestures, the duration or distance specified in one direction
|
||||
applies to both directions along the same axis.
|
||||
|
||||
properties:
|
||||
linux,code: true
|
||||
|
||||
azoteq,gesture-max-ms:
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description: Specifies the maximum duration of tap/swipe gestures.
|
||||
|
||||
azoteq,gesture-mid-ms:
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description:
|
||||
Specifies the maximum duration between subsequent tap gestures
|
||||
(IQS7211E only).
|
||||
|
||||
azoteq,gesture-min-ms:
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description: Specifies the minimum duration of hold gestures.
|
||||
|
||||
azoteq,gesture-dist:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description:
|
||||
Specifies the minimum (swipe) or maximum (tap and hold) distance
|
||||
a finger may travel to be considered a gesture.
|
||||
|
||||
azoteq,gesture-dist-rep:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description:
|
||||
Specifies the minimum distance a finger must travel to elicit a
|
||||
repeated swipe gesture (IQS7211E only).
|
||||
|
||||
azoteq,gesture-angle:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 75
|
||||
description:
|
||||
Specifies the maximum angle (in degrees) a finger may travel to
|
||||
be considered a swipe gesture.
|
||||
|
||||
azoteq,thresh:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 42
|
||||
description: Specifies the palm gesture threshold (IQS7211E only).
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
dependencies:
|
||||
azoteq,rx-enable: ["azoteq,tx-enable"]
|
||||
azoteq,tx-enable: ["azoteq,rx-enable"]
|
||||
azoteq,channel-select: ["azoteq,rx-enable"]
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
alp:
|
||||
type: object
|
||||
$ref: ../input.yaml#
|
||||
description: Represents the alternate low-power channel (ALP).
|
||||
|
||||
properties:
|
||||
azoteq,rx-enable:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 8
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 7
|
||||
description:
|
||||
Specifies the CRx pin(s) associated with the ALP in no particular
|
||||
order.
|
||||
|
||||
azoteq,tx-enable:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 12
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 11
|
||||
description:
|
||||
Specifies the CTx pin(s) associated with the ALP in no particular
|
||||
order.
|
||||
|
||||
azoteq,ati-frac-div-fine:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 31
|
||||
description: Specifies the ALP's ATI fine fractional divider.
|
||||
|
||||
azoteq,ati-frac-mult-coarse:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 15
|
||||
description: Specifies the ALP's ATI coarse fractional multiplier.
|
||||
|
||||
azoteq,ati-frac-div-coarse:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 31
|
||||
description: Specifies the ALP's ATI coarse fractional divider.
|
||||
|
||||
azoteq,ati-comp-div:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 31
|
||||
description: Specifies the ALP's ATI compensation divider.
|
||||
|
||||
azoteq,ati-target:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description: Specifies the ALP's ATI target.
|
||||
|
||||
azoteq,ati-base:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
multipleOf: 8
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the ALP's ATI base.
|
||||
|
||||
azoteq,ati-mode:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1]
|
||||
description: |
|
||||
Specifies the ALP's ATI mode as follows:
|
||||
0: Partial
|
||||
1: Full
|
||||
|
||||
azoteq,sense-mode:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1]
|
||||
description: |
|
||||
Specifies the ALP's sensing mode as follows:
|
||||
0: Self capacitive
|
||||
1: Mutual capacitive
|
||||
|
||||
azoteq,debounce-enter:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the ALP's debounce entrance factor.
|
||||
|
||||
azoteq,debounce-exit:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the ALP's debounce exit factor.
|
||||
|
||||
azoteq,thresh:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description: Specifies the ALP's proximity or touch threshold.
|
||||
|
||||
azoteq,conv-period:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the ALP's conversion period.
|
||||
|
||||
azoteq,conv-frac:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the ALP's conversion frequency fraction.
|
||||
|
||||
linux,code: true
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
button:
|
||||
type: object
|
||||
description: Represents the inductive or capacitive button.
|
||||
|
||||
properties:
|
||||
azoteq,ati-frac-div-fine:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 31
|
||||
description: Specifies the button's ATI fine fractional divider.
|
||||
|
||||
azoteq,ati-frac-mult-coarse:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 15
|
||||
description: Specifies the button's ATI coarse fractional multiplier.
|
||||
|
||||
azoteq,ati-frac-div-coarse:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 31
|
||||
description: Specifies the button's ATI coarse fractional divider.
|
||||
|
||||
azoteq,ati-comp-div:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 31
|
||||
description: Specifies the button's ATI compensation divider.
|
||||
|
||||
azoteq,ati-target:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description: Specifies the button's ATI target.
|
||||
|
||||
azoteq,ati-base:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
multipleOf: 8
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the button's ATI base.
|
||||
|
||||
azoteq,ati-mode:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1]
|
||||
description: |
|
||||
Specifies the button's ATI mode as follows:
|
||||
0: Partial
|
||||
1: Full
|
||||
|
||||
azoteq,sense-mode:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1, 2]
|
||||
description: |
|
||||
Specifies the button's sensing mode as follows:
|
||||
0: Self capacitive
|
||||
1: Mutual capacitive
|
||||
2: Inductive
|
||||
|
||||
azoteq,touch-enter:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the button's touch entrance factor.
|
||||
|
||||
azoteq,touch-exit:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the button's touch exit factor.
|
||||
|
||||
azoteq,debounce-enter:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the button's debounce entrance factor.
|
||||
|
||||
azoteq,debounce-exit:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the button's debounce exit factor.
|
||||
|
||||
azoteq,thresh:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 65535
|
||||
description: Specifies the button's proximity threshold.
|
||||
|
||||
azoteq,conv-period:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the button's conversion period.
|
||||
|
||||
azoteq,conv-frac:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
description: Specifies the button's conversion frequency fraction.
|
||||
|
||||
patternProperties:
|
||||
"^event-(prox|touch)$":
|
||||
type: object
|
||||
$ref: ../input.yaml#
|
||||
description:
|
||||
Represents a proximity or touch event reported by the button.
|
||||
|
||||
properties:
|
||||
linux,code: true
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
wakeup-source: true
|
||||
|
||||
touchscreen-size-x: true
|
||||
touchscreen-size-y: true
|
||||
touchscreen-inverted-x: true
|
||||
touchscreen-inverted-y: true
|
||||
touchscreen-swapped-x-y: true
|
||||
|
||||
dependencies:
|
||||
touchscreen-size-x: ["azoteq,num-contacts"]
|
||||
touchscreen-size-y: ["azoteq,num-contacts"]
|
||||
touchscreen-inverted-x: ["azoteq,num-contacts"]
|
||||
touchscreen-inverted-y: ["azoteq,num-contacts"]
|
||||
touchscreen-swapped-x-y: ["azoteq,num-contacts"]
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- irq-gpios
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
allOf:
|
||||
- $ref: touchscreen.yaml#
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: azoteq,iqs7210a
|
||||
|
||||
then:
|
||||
properties:
|
||||
alp:
|
||||
properties:
|
||||
azoteq,rx-enable:
|
||||
maxItems: 4
|
||||
items:
|
||||
minimum: 4
|
||||
|
||||
else:
|
||||
properties:
|
||||
azoteq,timeout-press-ms: false
|
||||
|
||||
alp:
|
||||
properties:
|
||||
azoteq,ati-mode: false
|
||||
|
||||
button: false
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: azoteq,iqs7211e
|
||||
|
||||
then:
|
||||
properties:
|
||||
reset-gpios: false
|
||||
|
||||
trackpad:
|
||||
properties:
|
||||
azoteq,tx-enable:
|
||||
maxItems: 13
|
||||
items:
|
||||
maximum: 12
|
||||
|
||||
alp:
|
||||
properties:
|
||||
azoteq,tx-enable:
|
||||
maxItems: 13
|
||||
items:
|
||||
maximum: 12
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
touch@56 {
|
||||
compatible = "azoteq,iqs7210a";
|
||||
reg = <0x56>;
|
||||
irq-gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
|
||||
reset-gpios = <&gpio 17 (GPIO_ACTIVE_LOW |
|
||||
GPIO_PUSH_PULL)>;
|
||||
azoteq,num-contacts = <2>;
|
||||
|
||||
trackpad {
|
||||
azoteq,rx-enable = <6>, <5>, <4>, <3>, <2>;
|
||||
azoteq,tx-enable = <1>, <7>, <8>, <9>, <10>;
|
||||
};
|
||||
|
||||
button {
|
||||
azoteq,sense-mode = <2>;
|
||||
azoteq,touch-enter = <40>;
|
||||
azoteq,touch-exit = <36>;
|
||||
|
||||
event-touch {
|
||||
linux,code = <KEY_HOME>;
|
||||
};
|
||||
};
|
||||
|
||||
alp {
|
||||
azoteq,sense-mode = <1>;
|
||||
linux,code = <KEY_POWER>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
touch@56 {
|
||||
compatible = "azoteq,iqs7211e";
|
||||
reg = <0x56>;
|
||||
irq-gpios = <&gpio 4 (GPIO_ACTIVE_LOW |
|
||||
GPIO_OPEN_DRAIN)>;
|
||||
|
||||
trackpad {
|
||||
event-tap {
|
||||
linux,code = <KEY_PLAYPAUSE>;
|
||||
};
|
||||
|
||||
event-tap-double {
|
||||
linux,code = <KEY_SHUFFLE>;
|
||||
};
|
||||
|
||||
event-tap-triple {
|
||||
linux,code = <KEY_AGAIN>;
|
||||
};
|
||||
|
||||
event-hold {
|
||||
linux,code = <KEY_STOP>;
|
||||
};
|
||||
|
||||
event-palm {
|
||||
linux,code = <KEY_EXIT>;
|
||||
};
|
||||
|
||||
event-swipe-x-pos {
|
||||
linux,code = <KEY_REWIND>;
|
||||
};
|
||||
|
||||
event-swipe-x-pos-hold {
|
||||
linux,code = <KEY_PREVIOUS>;
|
||||
};
|
||||
|
||||
event-swipe-x-neg {
|
||||
linux,code = <KEY_FASTFORWARD>;
|
||||
};
|
||||
|
||||
event-swipe-x-neg-hold {
|
||||
linux,code = <KEY_NEXT>;
|
||||
};
|
||||
|
||||
event-swipe-y-pos {
|
||||
linux,code = <KEY_VOLUMEUP>;
|
||||
};
|
||||
|
||||
event-swipe-y-pos-hold {
|
||||
linux,code = <KEY_MUTE>;
|
||||
};
|
||||
|
||||
event-swipe-y-neg {
|
||||
linux,code = <KEY_VOLUMEDOWN>;
|
||||
};
|
||||
|
||||
event-swipe-y-neg-hold {
|
||||
linux,code = <KEY_MUTE>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
@ -93,6 +93,12 @@ properties:
|
||||
minimum: 1
|
||||
maximum: 255
|
||||
|
||||
threshold:
|
||||
description: Allows setting the "click"-threshold in the range from 0 to 255.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
|
||||
touchscreen-size-x: true
|
||||
touchscreen-size-y: true
|
||||
touchscreen-fuzz-x: true
|
||||
|
@ -24,6 +24,8 @@ properties:
|
||||
maxItems: 1
|
||||
reset-gpios:
|
||||
maxItems: 1
|
||||
vdd-supply:
|
||||
description: Power supply regulator for the chip
|
||||
touchscreen-size-x: true
|
||||
touchscreen-size-y: true
|
||||
touchscreen-inverted-x: true
|
||||
|
@ -52,6 +52,11 @@ properties:
|
||||
touchscreen-swapped-x-y: true
|
||||
touchscreen-max-pressure: true
|
||||
|
||||
linux,keycodes:
|
||||
description: Keycodes for the touch keys
|
||||
minItems: 1
|
||||
maxItems: 15
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
|
@ -25,6 +25,7 @@ if GAMEPORT
|
||||
|
||||
config GAMEPORT_NS558
|
||||
tristate "Classic ISA and PnP gameport support"
|
||||
depends on ISA
|
||||
help
|
||||
Say Y here if you have an ISA or PnP gameport.
|
||||
|
||||
@ -35,6 +36,7 @@ config GAMEPORT_NS558
|
||||
|
||||
config GAMEPORT_L4
|
||||
tristate "PDPI Lightning 4 gamecard support"
|
||||
depends on ISA
|
||||
help
|
||||
Say Y here if you have a PDPI Lightning 4 gamecard.
|
||||
|
||||
@ -53,7 +55,7 @@ config GAMEPORT_EMU10K1
|
||||
|
||||
config GAMEPORT_FM801
|
||||
tristate "ForteMedia FM801 gameport support"
|
||||
depends on PCI
|
||||
depends on PCI && HAS_IOPORT
|
||||
help
|
||||
Say Y here if you have ForteMedia FM801 PCI audio controller
|
||||
(Abit AU10, Genius Sound Maker, HP Workstation zx2000,
|
||||
|
@ -519,12 +519,32 @@ EXPORT_SYMBOL(gameport_set_phys);
|
||||
|
||||
static void gameport_default_trigger(struct gameport *gameport)
|
||||
{
|
||||
#ifdef CONFIG_HAS_IOPORT
|
||||
outb(0xff, gameport->io);
|
||||
#endif
|
||||
}
|
||||
|
||||
static unsigned char gameport_default_read(struct gameport *gameport)
|
||||
{
|
||||
#ifdef CONFIG_HAS_IOPORT
|
||||
return inb(gameport->io);
|
||||
#else
|
||||
return 0xff;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void gameport_setup_default_handlers(struct gameport *gameport)
|
||||
{
|
||||
if ((!gameport->trigger || !gameport->read) &&
|
||||
!IS_ENABLED(CONFIG_HAS_IOPORT))
|
||||
dev_err(&gameport->dev,
|
||||
"I/O port access is required for %s (%s) but is not available\n",
|
||||
gameport->phys, gameport->name);
|
||||
|
||||
if (!gameport->trigger)
|
||||
gameport->trigger = gameport_default_trigger;
|
||||
if (!gameport->read)
|
||||
gameport->read = gameport_default_read;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -545,11 +565,7 @@ static void gameport_init_port(struct gameport *gameport)
|
||||
if (gameport->parent)
|
||||
gameport->dev.parent = &gameport->parent->dev;
|
||||
|
||||
if (!gameport->trigger)
|
||||
gameport->trigger = gameport_default_trigger;
|
||||
if (!gameport->read)
|
||||
gameport->read = gameport_default_read;
|
||||
|
||||
gameport_setup_default_handlers(gameport);
|
||||
INIT_LIST_HEAD(&gameport->node);
|
||||
spin_lock_init(&gameport->timer_lock);
|
||||
timer_setup(&gameport->poll_timer, gameport_run_poll_handler, 0);
|
||||
|
@ -264,6 +264,7 @@ static const struct xpad_device {
|
||||
{ 0x0f0d, 0x0067, "HORIPAD ONE", 0, XTYPE_XBOXONE },
|
||||
{ 0x0f0d, 0x0078, "Hori Real Arcade Pro V Kai Xbox One", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
|
||||
{ 0x0f0d, 0x00c5, "Hori Fighting Commander ONE", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
|
||||
{ 0x0f0d, 0x00dc, "HORIPAD FPS for Nintendo Switch", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
|
||||
{ 0x0f30, 0x010b, "Philips Recoil", 0, XTYPE_XBOX },
|
||||
{ 0x0f30, 0x0202, "Joytech Advanced Controller", 0, XTYPE_XBOX },
|
||||
{ 0x0f30, 0x8888, "BigBen XBMiniPad Controller", 0, XTYPE_XBOX },
|
||||
@ -365,6 +366,7 @@ static const struct xpad_device {
|
||||
{ 0x31e3, 0x1300, "Wooting 60HE (AVR)", 0, XTYPE_XBOX360 },
|
||||
{ 0x31e3, 0x1310, "Wooting 60HE (ARM)", 0, XTYPE_XBOX360 },
|
||||
{ 0x3285, 0x0607, "Nacon GC-100", 0, XTYPE_XBOX360 },
|
||||
{ 0x3537, 0x1004, "GameSir T4 Kaleid", 0, XTYPE_XBOX360 },
|
||||
{ 0x3767, 0x0101, "Fanatec Speedster 3 Forceshock Wheel", 0, XTYPE_XBOX },
|
||||
{ 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX },
|
||||
{ 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN }
|
||||
@ -499,6 +501,8 @@ static const struct usb_device_id xpad_table[] = {
|
||||
XPAD_XBOX360_VENDOR(0x2f24), /* GameSir controllers */
|
||||
XPAD_XBOX360_VENDOR(0x31e3), /* Wooting Keyboards */
|
||||
XPAD_XBOX360_VENDOR(0x3285), /* Nacon GC-100 */
|
||||
XPAD_XBOX360_VENDOR(0x3537), /* GameSir Controllers */
|
||||
XPAD_XBOXONE_VENDOR(0x3537), /* GameSir Controllers */
|
||||
{ }
|
||||
};
|
||||
|
||||
@ -1720,6 +1724,27 @@ static int xpad_start_input(struct usb_xpad *xpad)
|
||||
return error;
|
||||
}
|
||||
}
|
||||
if (xpad->xtype == XTYPE_XBOX360) {
|
||||
/*
|
||||
* Some third-party controllers Xbox 360-style controllers
|
||||
* require this message to finish initialization.
|
||||
*/
|
||||
u8 dummy[20];
|
||||
|
||||
error = usb_control_msg_recv(xpad->udev, 0,
|
||||
/* bRequest */ 0x01,
|
||||
/* bmRequestType */
|
||||
USB_TYPE_VENDOR | USB_DIR_IN |
|
||||
USB_RECIP_INTERFACE,
|
||||
/* wValue */ 0x100,
|
||||
/* wIndex */ 0x00,
|
||||
dummy, sizeof(dummy),
|
||||
25, GFP_KERNEL);
|
||||
if (error)
|
||||
dev_warn(&xpad->dev->dev,
|
||||
"unable to receive magic message: %d\n",
|
||||
error);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -713,17 +713,11 @@ static int adp5588_fw_parse(struct adp5588_kpad *kpad)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void adp5588_disable_regulator(void *reg)
|
||||
{
|
||||
regulator_disable(reg);
|
||||
}
|
||||
|
||||
static int adp5588_probe(struct i2c_client *client)
|
||||
{
|
||||
struct adp5588_kpad *kpad;
|
||||
struct input_dev *input;
|
||||
struct gpio_desc *gpio;
|
||||
struct regulator *vcc;
|
||||
unsigned int revid;
|
||||
int ret;
|
||||
int error;
|
||||
@ -749,16 +743,7 @@ static int adp5588_probe(struct i2c_client *client)
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
vcc = devm_regulator_get(&client->dev, "vcc");
|
||||
if (IS_ERR(vcc))
|
||||
return PTR_ERR(vcc);
|
||||
|
||||
error = regulator_enable(vcc);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = devm_add_action_or_reset(&client->dev,
|
||||
adp5588_disable_regulator, vcc);
|
||||
error = devm_regulator_get_enable(&client->dev, "vcc");
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
@ -196,7 +196,7 @@ static int __init amikbd_probe(struct platform_device *pdev)
|
||||
struct input_dev *dev;
|
||||
int i, err;
|
||||
|
||||
dev = input_allocate_device();
|
||||
dev = devm_input_allocate_device(&pdev->dev);
|
||||
if (!dev) {
|
||||
dev_err(&pdev->dev, "Not enough memory for input device\n");
|
||||
return -ENOMEM;
|
||||
@ -208,7 +208,6 @@ static int __init amikbd_probe(struct platform_device *pdev)
|
||||
dev->id.vendor = 0x0001;
|
||||
dev->id.product = 0x0001;
|
||||
dev->id.version = 0x0100;
|
||||
dev->dev.parent = &pdev->dev;
|
||||
|
||||
dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
|
||||
|
||||
@ -218,35 +217,21 @@ static int __init amikbd_probe(struct platform_device *pdev)
|
||||
amikbd_init_console_keymaps();
|
||||
|
||||
ciaa.cra &= ~0x41; /* serial data in, turn off TA */
|
||||
err = request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd",
|
||||
dev);
|
||||
err = devm_request_irq(&pdev->dev, IRQ_AMIGA_CIAA_SP, amikbd_interrupt,
|
||||
0, "amikbd", dev);
|
||||
if (err)
|
||||
goto fail2;
|
||||
return err;
|
||||
|
||||
err = input_register_device(dev);
|
||||
if (err)
|
||||
goto fail3;
|
||||
return err;
|
||||
|
||||
platform_set_drvdata(pdev, dev);
|
||||
|
||||
return 0;
|
||||
|
||||
fail3: free_irq(IRQ_AMIGA_CIAA_SP, dev);
|
||||
fail2: input_free_device(dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __exit amikbd_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct input_dev *dev = platform_get_drvdata(pdev);
|
||||
|
||||
free_irq(IRQ_AMIGA_CIAA_SP, dev);
|
||||
input_unregister_device(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver amikbd_driver = {
|
||||
.remove = __exit_p(amikbd_remove),
|
||||
.driver = {
|
||||
.name = "amiga-keyboard",
|
||||
},
|
||||
|
@ -307,7 +307,6 @@ static int bcm_kp_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct bcm_kp *kp;
|
||||
struct input_dev *input_dev;
|
||||
struct resource *res;
|
||||
int error;
|
||||
|
||||
kp = devm_kzalloc(&pdev->dev, sizeof(*kp), GFP_KERNEL);
|
||||
@ -353,29 +352,16 @@ static int bcm_kp_probe(struct platform_device *pdev)
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Get the KEYPAD base address */
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "Missing keypad base address resource\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
kp->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
kp->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(kp->base))
|
||||
return PTR_ERR(kp->base);
|
||||
|
||||
/* Enable clock */
|
||||
kp->clk = devm_clk_get(&pdev->dev, "peri_clk");
|
||||
kp->clk = devm_clk_get_optional(&pdev->dev, "peri_clk");
|
||||
if (IS_ERR(kp->clk)) {
|
||||
error = PTR_ERR(kp->clk);
|
||||
if (error != -ENOENT) {
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(&pdev->dev, "Failed to get clock\n");
|
||||
return error;
|
||||
}
|
||||
dev_dbg(&pdev->dev,
|
||||
"No clock specified. Assuming it's enabled\n");
|
||||
kp->clk = NULL;
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(kp->clk), "Failed to get clock\n");
|
||||
} else if (!kp->clk) {
|
||||
dev_dbg(&pdev->dev, "No clock specified. Assuming it's enabled\n");
|
||||
} else {
|
||||
unsigned int desired_rate;
|
||||
long actual_rate;
|
||||
|
@ -523,18 +523,15 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
|
||||
NULL, GPIOD_IN, desc);
|
||||
if (IS_ERR(bdata->gpiod)) {
|
||||
error = PTR_ERR(bdata->gpiod);
|
||||
if (error == -ENOENT) {
|
||||
/*
|
||||
* GPIO is optional, we may be dealing with
|
||||
* purely interrupt-driven setup.
|
||||
*/
|
||||
bdata->gpiod = NULL;
|
||||
} else {
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(dev, "failed to get gpio: %d\n",
|
||||
error);
|
||||
return error;
|
||||
}
|
||||
if (error != -ENOENT)
|
||||
return dev_err_probe(dev, error,
|
||||
"failed to get gpio\n");
|
||||
|
||||
/*
|
||||
* GPIO is optional, we may be dealing with
|
||||
* purely interrupt-driven setup.
|
||||
*/
|
||||
bdata->gpiod = NULL;
|
||||
}
|
||||
} else if (gpio_is_valid(button->gpio)) {
|
||||
/*
|
||||
|
@ -299,13 +299,9 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
|
||||
NULL, GPIOD_IN,
|
||||
button->desc);
|
||||
if (IS_ERR(bdata->gpiod)) {
|
||||
error = PTR_ERR(bdata->gpiod);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(dev,
|
||||
"failed to get gpio: %d\n",
|
||||
error);
|
||||
fwnode_handle_put(child);
|
||||
return error;
|
||||
return dev_err_probe(dev, PTR_ERR(bdata->gpiod),
|
||||
"failed to get gpio\n");
|
||||
}
|
||||
} else if (gpio_is_valid(button->gpio)) {
|
||||
/*
|
||||
|
@ -556,6 +556,7 @@ static int init_pwm(struct lm8323_chip *lm, int id, struct device *dev,
|
||||
const char *name)
|
||||
{
|
||||
struct lm8323_pwm *pwm;
|
||||
int err;
|
||||
|
||||
BUG_ON(id > 3);
|
||||
|
||||
@ -575,9 +576,11 @@ static int init_pwm(struct lm8323_chip *lm, int id, struct device *dev,
|
||||
pwm->cdev.name = name;
|
||||
pwm->cdev.brightness_set = lm8323_pwm_set_brightness;
|
||||
pwm->cdev.groups = lm8323_pwm_groups;
|
||||
if (led_classdev_register(dev, &pwm->cdev) < 0) {
|
||||
dev_err(dev, "couldn't register PWM %d\n", id);
|
||||
return -1;
|
||||
|
||||
err = devm_led_classdev_register(dev, &pwm->cdev);
|
||||
if (err) {
|
||||
dev_err(dev, "couldn't register PWM %d: %d\n", id, err);
|
||||
return err;
|
||||
}
|
||||
pwm->enabled = true;
|
||||
}
|
||||
@ -585,8 +588,6 @@ static int init_pwm(struct lm8323_chip *lm, int id, struct device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct i2c_driver lm8323_i2c_driver;
|
||||
|
||||
static ssize_t lm8323_show_disable(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
@ -615,6 +616,12 @@ static ssize_t lm8323_set_disable(struct device *dev,
|
||||
}
|
||||
static DEVICE_ATTR(disable_kp, 0644, lm8323_show_disable, lm8323_set_disable);
|
||||
|
||||
static struct attribute *lm8323_attrs[] = {
|
||||
&dev_attr_disable_kp.attr,
|
||||
NULL,
|
||||
};
|
||||
ATTRIBUTE_GROUPS(lm8323);
|
||||
|
||||
static int lm8323_probe(struct i2c_client *client)
|
||||
{
|
||||
struct lm8323_platform_data *pdata = dev_get_platdata(&client->dev);
|
||||
@ -642,12 +649,13 @@ static int lm8323_probe(struct i2c_client *client)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
lm = kzalloc(sizeof *lm, GFP_KERNEL);
|
||||
idev = input_allocate_device();
|
||||
if (!lm || !idev) {
|
||||
err = -ENOMEM;
|
||||
goto fail1;
|
||||
}
|
||||
lm = devm_kzalloc(&client->dev, sizeof(*lm), GFP_KERNEL);
|
||||
if (!lm)
|
||||
return -ENOMEM;
|
||||
|
||||
idev = devm_input_allocate_device(&client->dev);
|
||||
if (!idev)
|
||||
return -ENOMEM;
|
||||
|
||||
lm->client = client;
|
||||
lm->idev = idev;
|
||||
@ -663,8 +671,10 @@ static int lm8323_probe(struct i2c_client *client)
|
||||
|
||||
lm8323_reset(lm);
|
||||
|
||||
/* Nothing's set up to service the IRQ yet, so just spin for max.
|
||||
* 100ms until we can configure. */
|
||||
/*
|
||||
* Nothing's set up to service the IRQ yet, so just spin for max.
|
||||
* 100ms until we can configure.
|
||||
*/
|
||||
tmo = jiffies + msecs_to_jiffies(100);
|
||||
while (lm8323_read(lm, LM8323_CMD_READ_INT, data, 1) == 1) {
|
||||
if (data[0] & INT_NOINIT)
|
||||
@ -684,21 +694,17 @@ static int lm8323_probe(struct i2c_client *client)
|
||||
/* If a true probe check the device */
|
||||
if (lm8323_read_id(lm, data) != 0) {
|
||||
dev_err(&client->dev, "device not found\n");
|
||||
err = -ENODEV;
|
||||
goto fail1;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
for (pwm = 0; pwm < LM8323_NUM_PWMS; pwm++) {
|
||||
err = init_pwm(lm, pwm + 1, &client->dev,
|
||||
pdata->pwm_names[pwm]);
|
||||
if (err < 0)
|
||||
goto fail2;
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
lm->kp_enabled = true;
|
||||
err = device_create_file(&client->dev, &dev_attr_disable_kp);
|
||||
if (err < 0)
|
||||
goto fail2;
|
||||
|
||||
idev->name = pdata->name ? : "LM8323 keypad";
|
||||
snprintf(lm->phys, sizeof(lm->phys),
|
||||
@ -719,14 +725,16 @@ static int lm8323_probe(struct i2c_client *client)
|
||||
err = input_register_device(idev);
|
||||
if (err) {
|
||||
dev_dbg(&client->dev, "error registering input device\n");
|
||||
goto fail3;
|
||||
return err;
|
||||
}
|
||||
|
||||
err = request_threaded_irq(client->irq, NULL, lm8323_irq,
|
||||
IRQF_TRIGGER_LOW|IRQF_ONESHOT, "lm8323", lm);
|
||||
err = devm_request_threaded_irq(&client->dev, client->irq,
|
||||
NULL, lm8323_irq,
|
||||
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
|
||||
"lm8323", lm);
|
||||
if (err) {
|
||||
dev_err(&client->dev, "could not get IRQ %d\n", client->irq);
|
||||
goto fail4;
|
||||
return err;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(client, lm);
|
||||
@ -735,39 +743,6 @@ static int lm8323_probe(struct i2c_client *client)
|
||||
enable_irq_wake(client->irq);
|
||||
|
||||
return 0;
|
||||
|
||||
fail4:
|
||||
input_unregister_device(idev);
|
||||
idev = NULL;
|
||||
fail3:
|
||||
device_remove_file(&client->dev, &dev_attr_disable_kp);
|
||||
fail2:
|
||||
while (--pwm >= 0)
|
||||
if (lm->pwm[pwm].enabled)
|
||||
led_classdev_unregister(&lm->pwm[pwm].cdev);
|
||||
fail1:
|
||||
input_free_device(idev);
|
||||
kfree(lm);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void lm8323_remove(struct i2c_client *client)
|
||||
{
|
||||
struct lm8323_chip *lm = i2c_get_clientdata(client);
|
||||
int i;
|
||||
|
||||
disable_irq_wake(client->irq);
|
||||
free_irq(client->irq, lm);
|
||||
|
||||
input_unregister_device(lm->idev);
|
||||
|
||||
device_remove_file(&lm->client->dev, &dev_attr_disable_kp);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
if (lm->pwm[i].enabled)
|
||||
led_classdev_unregister(&lm->pwm[i].cdev);
|
||||
|
||||
kfree(lm);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -823,11 +798,11 @@ static const struct i2c_device_id lm8323_id[] = {
|
||||
|
||||
static struct i2c_driver lm8323_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "lm8323",
|
||||
.pm = pm_sleep_ptr(&lm8323_pm_ops),
|
||||
.name = "lm8323",
|
||||
.pm = pm_sleep_ptr(&lm8323_pm_ops),
|
||||
.dev_groups = lm8323_groups,
|
||||
},
|
||||
.probe = lm8323_probe,
|
||||
.remove = lm8323_remove,
|
||||
.id_table = lm8323_id,
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, lm8323_id);
|
||||
|
@ -142,18 +142,18 @@ static int lm8333_probe(struct i2c_client *client)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
lm8333 = kzalloc(sizeof(*lm8333), GFP_KERNEL);
|
||||
input = input_allocate_device();
|
||||
if (!lm8333 || !input) {
|
||||
err = -ENOMEM;
|
||||
goto free_mem;
|
||||
}
|
||||
lm8333 = devm_kzalloc(&client->dev, sizeof(*lm8333), GFP_KERNEL);
|
||||
if (!lm8333)
|
||||
return -ENOMEM;
|
||||
|
||||
input = devm_input_allocate_device(&client->dev);
|
||||
if (!input)
|
||||
return -ENOMEM;
|
||||
|
||||
lm8333->client = client;
|
||||
lm8333->input = input;
|
||||
|
||||
input->name = client->name;
|
||||
input->dev.parent = &client->dev;
|
||||
input->id.bustype = BUS_I2C;
|
||||
|
||||
input_set_capability(input, EV_MSC, MSC_SCAN);
|
||||
@ -162,7 +162,7 @@ static int lm8333_probe(struct i2c_client *client)
|
||||
LM8333_NUM_ROWS, LM8333_NUM_COLS,
|
||||
lm8333->keycodes, input);
|
||||
if (err)
|
||||
goto free_mem;
|
||||
return err;
|
||||
|
||||
if (pdata->debounce_time) {
|
||||
err = lm8333_write8(lm8333, LM8333_DEBOUNCE,
|
||||
@ -178,34 +178,19 @@ static int lm8333_probe(struct i2c_client *client)
|
||||
dev_warn(&client->dev, "Unable to set active time\n");
|
||||
}
|
||||
|
||||
err = request_threaded_irq(client->irq, NULL, lm8333_irq_thread,
|
||||
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
|
||||
"lm8333", lm8333);
|
||||
err = devm_request_threaded_irq(&client->dev, client->irq,
|
||||
NULL, lm8333_irq_thread,
|
||||
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
|
||||
"lm8333", lm8333);
|
||||
if (err)
|
||||
goto free_mem;
|
||||
return err;
|
||||
|
||||
err = input_register_device(input);
|
||||
if (err)
|
||||
goto free_irq;
|
||||
return err;
|
||||
|
||||
i2c_set_clientdata(client, lm8333);
|
||||
return 0;
|
||||
|
||||
free_irq:
|
||||
free_irq(client->irq, lm8333);
|
||||
free_mem:
|
||||
input_free_device(input);
|
||||
kfree(lm8333);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void lm8333_remove(struct i2c_client *client)
|
||||
{
|
||||
struct lm8333 *lm8333 = i2c_get_clientdata(client);
|
||||
|
||||
free_irq(client->irq, lm8333);
|
||||
input_unregister_device(lm8333->input);
|
||||
kfree(lm8333);
|
||||
}
|
||||
|
||||
static const struct i2c_device_id lm8333_id[] = {
|
||||
@ -219,7 +204,6 @@ static struct i2c_driver lm8333_driver = {
|
||||
.name = "lm8333",
|
||||
},
|
||||
.probe = lm8333_probe,
|
||||
.remove = lm8333_remove,
|
||||
.id_table = lm8333_id,
|
||||
};
|
||||
module_i2c_driver(lm8333_driver);
|
||||
|
@ -160,17 +160,10 @@ static int lpc32xx_kscan_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct lpc32xx_kscan_drv *kscandat;
|
||||
struct input_dev *input;
|
||||
struct resource *res;
|
||||
size_t keymap_size;
|
||||
int error;
|
||||
int irq;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "failed to get platform I/O memory\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0)
|
||||
return -EINVAL;
|
||||
@ -221,7 +214,7 @@ static int lpc32xx_kscan_probe(struct platform_device *pdev)
|
||||
|
||||
input_set_drvdata(kscandat->input, kscandat);
|
||||
|
||||
kscandat->kscan_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
kscandat->kscan_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(kscandat->kscan_base))
|
||||
return PTR_ERR(kscandat->kscan_base);
|
||||
|
||||
|
@ -92,6 +92,13 @@ static irqreturn_t mcs_touchkey_interrupt(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void mcs_touchkey_poweroff(void *data)
|
||||
{
|
||||
struct mcs_touchkey_data *touchkey = data;
|
||||
|
||||
touchkey->poweron(false);
|
||||
}
|
||||
|
||||
static int mcs_touchkey_probe(struct i2c_client *client)
|
||||
{
|
||||
const struct i2c_device_id *id = i2c_client_get_device_id(client);
|
||||
@ -109,13 +116,16 @@ static int mcs_touchkey_probe(struct i2c_client *client)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
data = kzalloc(struct_size(data, keycodes, pdata->key_maxval + 1),
|
||||
GFP_KERNEL);
|
||||
input_dev = input_allocate_device();
|
||||
if (!data || !input_dev) {
|
||||
dev_err(&client->dev, "Failed to allocate memory\n");
|
||||
error = -ENOMEM;
|
||||
goto err_free_mem;
|
||||
data = devm_kzalloc(&client->dev,
|
||||
struct_size(data, keycodes, pdata->key_maxval + 1),
|
||||
GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
input_dev = devm_input_allocate_device(&client->dev);
|
||||
if (!input_dev) {
|
||||
dev_err(&client->dev, "Failed to allocate input device\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
data->client = client;
|
||||
@ -136,15 +146,13 @@ static int mcs_touchkey_probe(struct i2c_client *client)
|
||||
|
||||
fw_ver = i2c_smbus_read_byte_data(client, fw_reg);
|
||||
if (fw_ver < 0) {
|
||||
error = fw_ver;
|
||||
dev_err(&client->dev, "i2c read error[%d]\n", error);
|
||||
goto err_free_mem;
|
||||
dev_err(&client->dev, "i2c read error[%d]\n", fw_ver);
|
||||
return fw_ver;
|
||||
}
|
||||
dev_info(&client->dev, "Firmware version: %d\n", fw_ver);
|
||||
|
||||
input_dev->name = "MELFAS MCS Touchkey";
|
||||
input_dev->id.bustype = BUS_I2C;
|
||||
input_dev->dev.parent = &client->dev;
|
||||
input_dev->evbit[0] = BIT_MASK(EV_KEY);
|
||||
if (!pdata->no_autorepeat)
|
||||
input_dev->evbit[0] |= BIT_MASK(EV_REP);
|
||||
@ -169,40 +177,28 @@ static int mcs_touchkey_probe(struct i2c_client *client)
|
||||
if (pdata->poweron) {
|
||||
data->poweron = pdata->poweron;
|
||||
data->poweron(true);
|
||||
|
||||
error = devm_add_action_or_reset(&client->dev,
|
||||
mcs_touchkey_poweroff, data);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
error = request_threaded_irq(client->irq, NULL, mcs_touchkey_interrupt,
|
||||
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
|
||||
client->dev.driver->name, data);
|
||||
error = devm_request_threaded_irq(&client->dev, client->irq,
|
||||
NULL, mcs_touchkey_interrupt,
|
||||
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
|
||||
client->dev.driver->name, data);
|
||||
if (error) {
|
||||
dev_err(&client->dev, "Failed to register interrupt\n");
|
||||
goto err_free_mem;
|
||||
return error;
|
||||
}
|
||||
|
||||
error = input_register_device(input_dev);
|
||||
if (error)
|
||||
goto err_free_irq;
|
||||
return error;
|
||||
|
||||
i2c_set_clientdata(client, data);
|
||||
return 0;
|
||||
|
||||
err_free_irq:
|
||||
free_irq(client->irq, data);
|
||||
err_free_mem:
|
||||
input_free_device(input_dev);
|
||||
kfree(data);
|
||||
return error;
|
||||
}
|
||||
|
||||
static void mcs_touchkey_remove(struct i2c_client *client)
|
||||
{
|
||||
struct mcs_touchkey_data *data = i2c_get_clientdata(client);
|
||||
|
||||
free_irq(client->irq, data);
|
||||
if (data->poweron)
|
||||
data->poweron(false);
|
||||
input_unregister_device(data->input_dev);
|
||||
kfree(data);
|
||||
}
|
||||
|
||||
static void mcs_touchkey_shutdown(struct i2c_client *client)
|
||||
@ -259,7 +255,6 @@ static struct i2c_driver mcs_touchkey_driver = {
|
||||
.pm = pm_sleep_ptr(&mcs_touchkey_pm_ops),
|
||||
},
|
||||
.probe = mcs_touchkey_probe,
|
||||
.remove = mcs_touchkey_remove,
|
||||
.shutdown = mcs_touchkey_shutdown,
|
||||
.id_table = mcs_touchkey_id,
|
||||
};
|
||||
|
@ -221,13 +221,20 @@ static irqreturn_t ske_keypad_irq(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void ske_keypad_board_exit(void *data)
|
||||
{
|
||||
struct ske_keypad *keypad = data;
|
||||
|
||||
keypad->board->exit();
|
||||
}
|
||||
|
||||
static int __init ske_keypad_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct ske_keypad_platform_data *plat =
|
||||
dev_get_platdata(&pdev->dev);
|
||||
struct device *dev = &pdev->dev;
|
||||
struct ske_keypad *keypad;
|
||||
struct input_dev *input;
|
||||
struct resource *res;
|
||||
int irq;
|
||||
int error;
|
||||
|
||||
@ -238,20 +245,14 @@ static int __init ske_keypad_probe(struct platform_device *pdev)
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0)
|
||||
return -EINVAL;
|
||||
return irq;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "missing platform resources\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
keypad = kzalloc(sizeof(struct ske_keypad), GFP_KERNEL);
|
||||
input = input_allocate_device();
|
||||
keypad = devm_kzalloc(dev, sizeof(struct ske_keypad),
|
||||
GFP_KERNEL);
|
||||
input = devm_input_allocate_device(dev);
|
||||
if (!keypad || !input) {
|
||||
dev_err(&pdev->dev, "failed to allocate keypad memory\n");
|
||||
error = -ENOMEM;
|
||||
goto err_free_mem;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
keypad->irq = irq;
|
||||
@ -259,31 +260,20 @@ static int __init ske_keypad_probe(struct platform_device *pdev)
|
||||
keypad->input = input;
|
||||
spin_lock_init(&keypad->ske_keypad_lock);
|
||||
|
||||
if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
|
||||
dev_err(&pdev->dev, "failed to request I/O memory\n");
|
||||
error = -EBUSY;
|
||||
goto err_free_mem;
|
||||
}
|
||||
keypad->reg_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(keypad->reg_base))
|
||||
return PTR_ERR(keypad->reg_base);
|
||||
|
||||
keypad->reg_base = ioremap(res->start, resource_size(res));
|
||||
if (!keypad->reg_base) {
|
||||
dev_err(&pdev->dev, "failed to remap I/O memory\n");
|
||||
error = -ENXIO;
|
||||
goto err_free_mem_region;
|
||||
}
|
||||
|
||||
keypad->pclk = clk_get(&pdev->dev, "apb_pclk");
|
||||
keypad->pclk = devm_clk_get_enabled(dev, "apb_pclk");
|
||||
if (IS_ERR(keypad->pclk)) {
|
||||
dev_err(&pdev->dev, "failed to get pclk\n");
|
||||
error = PTR_ERR(keypad->pclk);
|
||||
goto err_iounmap;
|
||||
return PTR_ERR(keypad->pclk);
|
||||
}
|
||||
|
||||
keypad->clk = clk_get(&pdev->dev, NULL);
|
||||
keypad->clk = devm_clk_get_enabled(dev, NULL);
|
||||
if (IS_ERR(keypad->clk)) {
|
||||
dev_err(&pdev->dev, "failed to get clk\n");
|
||||
error = PTR_ERR(keypad->clk);
|
||||
goto err_pclk;
|
||||
return PTR_ERR(keypad->clk);
|
||||
}
|
||||
|
||||
input->id.bustype = BUS_HOST;
|
||||
@ -295,48 +285,43 @@ static int __init ske_keypad_probe(struct platform_device *pdev)
|
||||
keypad->keymap, input);
|
||||
if (error) {
|
||||
dev_err(&pdev->dev, "Failed to build keymap\n");
|
||||
goto err_clk;
|
||||
return error;
|
||||
}
|
||||
|
||||
input_set_capability(input, EV_MSC, MSC_SCAN);
|
||||
if (!plat->no_autorepeat)
|
||||
__set_bit(EV_REP, input->evbit);
|
||||
|
||||
error = clk_prepare_enable(keypad->pclk);
|
||||
if (error) {
|
||||
dev_err(&pdev->dev, "Failed to prepare/enable pclk\n");
|
||||
goto err_clk;
|
||||
}
|
||||
|
||||
error = clk_prepare_enable(keypad->clk);
|
||||
if (error) {
|
||||
dev_err(&pdev->dev, "Failed to prepare/enable clk\n");
|
||||
goto err_pclk_disable;
|
||||
}
|
||||
|
||||
|
||||
/* go through board initialization helpers */
|
||||
if (keypad->board->init)
|
||||
keypad->board->init();
|
||||
|
||||
if (keypad->board->exit) {
|
||||
error = devm_add_action_or_reset(dev, ske_keypad_board_exit,
|
||||
keypad);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
error = ske_keypad_chip_init(keypad);
|
||||
if (error) {
|
||||
dev_err(&pdev->dev, "unable to init keypad hardware\n");
|
||||
goto err_clk_disable;
|
||||
return error;
|
||||
}
|
||||
|
||||
error = request_threaded_irq(keypad->irq, NULL, ske_keypad_irq,
|
||||
IRQF_ONESHOT, "ske-keypad", keypad);
|
||||
error = devm_request_threaded_irq(dev, keypad->irq,
|
||||
NULL, ske_keypad_irq,
|
||||
IRQF_ONESHOT, "ske-keypad", keypad);
|
||||
if (error) {
|
||||
dev_err(&pdev->dev, "allocate irq %d failed\n", keypad->irq);
|
||||
goto err_clk_disable;
|
||||
return error;
|
||||
}
|
||||
|
||||
error = input_register_device(input);
|
||||
if (error) {
|
||||
dev_err(&pdev->dev,
|
||||
"unable to register input device: %d\n", error);
|
||||
goto err_free_irq;
|
||||
"unable to register input device: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
if (plat->wakeup_enable)
|
||||
@ -344,47 +329,6 @@ static int __init ske_keypad_probe(struct platform_device *pdev)
|
||||
|
||||
platform_set_drvdata(pdev, keypad);
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_irq:
|
||||
free_irq(keypad->irq, keypad);
|
||||
err_clk_disable:
|
||||
clk_disable_unprepare(keypad->clk);
|
||||
err_pclk_disable:
|
||||
clk_disable_unprepare(keypad->pclk);
|
||||
err_clk:
|
||||
clk_put(keypad->clk);
|
||||
err_pclk:
|
||||
clk_put(keypad->pclk);
|
||||
err_iounmap:
|
||||
iounmap(keypad->reg_base);
|
||||
err_free_mem_region:
|
||||
release_mem_region(res->start, resource_size(res));
|
||||
err_free_mem:
|
||||
input_free_device(input);
|
||||
kfree(keypad);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int ske_keypad_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct ske_keypad *keypad = platform_get_drvdata(pdev);
|
||||
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
|
||||
free_irq(keypad->irq, keypad);
|
||||
|
||||
input_unregister_device(keypad->input);
|
||||
|
||||
clk_disable_unprepare(keypad->clk);
|
||||
clk_put(keypad->clk);
|
||||
|
||||
if (keypad->board->exit)
|
||||
keypad->board->exit();
|
||||
|
||||
iounmap(keypad->reg_base);
|
||||
release_mem_region(res->start, resource_size(res));
|
||||
kfree(keypad);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -424,7 +368,6 @@ static struct platform_driver ske_keypad_driver = {
|
||||
.name = "nmk-ske-keypad",
|
||||
.pm = pm_sleep_ptr(&ske_keypad_dev_pm_ops),
|
||||
},
|
||||
.remove = ske_keypad_remove,
|
||||
};
|
||||
|
||||
module_platform_driver_probe(ske_keypad_driver, ske_keypad_probe);
|
||||
|
@ -186,8 +186,7 @@ static int nspire_keypad_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(keypad->clk);
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
keypad->reg_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
keypad->reg_base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||
if (IS_ERR(keypad->reg_base))
|
||||
return PTR_ERR(keypad->reg_base);
|
||||
|
||||
|
@ -341,17 +341,10 @@ static int omap4_keypad_probe(struct platform_device *pdev)
|
||||
struct device *dev = &pdev->dev;
|
||||
struct omap4_keypad *keypad_data;
|
||||
struct input_dev *input_dev;
|
||||
struct resource *res;
|
||||
unsigned int max_keys;
|
||||
int irq;
|
||||
int error;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "no base address specified\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
@ -370,7 +363,7 @@ static int omap4_keypad_probe(struct platform_device *pdev)
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
keypad_data->base = devm_ioremap_resource(dev, res);
|
||||
keypad_data->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(keypad_data->base))
|
||||
return PTR_ERR(keypad_data->base);
|
||||
|
||||
|
@ -39,15 +39,8 @@ static int opencores_kbd_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct input_dev *input;
|
||||
struct opencores_kbd *opencores_kbd;
|
||||
struct resource *res;
|
||||
int irq, i, error;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "missing board memory resource\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0)
|
||||
return -EINVAL;
|
||||
@ -65,7 +58,7 @@ static int opencores_kbd_probe(struct platform_device *pdev)
|
||||
|
||||
opencores_kbd->input = input;
|
||||
|
||||
opencores_kbd->addr = devm_ioremap_resource(&pdev->dev, res);
|
||||
opencores_kbd->addr = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(opencores_kbd->addr))
|
||||
return PTR_ERR(opencores_kbd->addr);
|
||||
|
||||
|
@ -318,40 +318,22 @@ static void ppkb_close(struct input_dev *input)
|
||||
ppkb_set_scan(client, false);
|
||||
}
|
||||
|
||||
static void ppkb_regulator_disable(void *regulator)
|
||||
{
|
||||
regulator_disable(regulator);
|
||||
}
|
||||
|
||||
static int ppkb_probe(struct i2c_client *client)
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
unsigned int phys_rows, phys_cols;
|
||||
struct pinephone_keyboard *ppkb;
|
||||
struct regulator *vbat_supply;
|
||||
u8 info[PPKB_MATRIX_SIZE + 1];
|
||||
struct device_node *i2c_bus;
|
||||
int ret;
|
||||
int error;
|
||||
|
||||
vbat_supply = devm_regulator_get(dev, "vbat");
|
||||
error = PTR_ERR_OR_ZERO(vbat_supply);
|
||||
error = devm_regulator_get_enable(dev, "vbat");
|
||||
if (error) {
|
||||
dev_err(dev, "Failed to get VBAT supply: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
error = regulator_enable(vbat_supply);
|
||||
if (error) {
|
||||
dev_err(dev, "Failed to enable VBAT: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
error = devm_add_action_or_reset(dev, ppkb_regulator_disable,
|
||||
vbat_supply);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
ret = i2c_smbus_read_i2c_block_data(client, 0, sizeof(info), info);
|
||||
if (ret != sizeof(info)) {
|
||||
error = ret < 0 ? ret : -EIO;
|
||||
|
@ -717,7 +717,6 @@ static int pxa27x_keypad_probe(struct platform_device *pdev)
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct pxa27x_keypad *keypad;
|
||||
struct input_dev *input_dev;
|
||||
struct resource *res;
|
||||
int irq, error;
|
||||
|
||||
/* Driver need build keycode from device tree or pdata */
|
||||
@ -728,12 +727,6 @@ static int pxa27x_keypad_probe(struct platform_device *pdev)
|
||||
if (irq < 0)
|
||||
return -ENXIO;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (res == NULL) {
|
||||
dev_err(&pdev->dev, "failed to get I/O memory\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad),
|
||||
GFP_KERNEL);
|
||||
if (!keypad)
|
||||
@ -747,7 +740,7 @@ static int pxa27x_keypad_probe(struct platform_device *pdev)
|
||||
keypad->input_dev = input_dev;
|
||||
keypad->irq = irq;
|
||||
|
||||
keypad->mmio_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
keypad->mmio_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(keypad->mmio_base))
|
||||
return PTR_ERR(keypad->mmio_base);
|
||||
|
||||
|
@ -149,20 +149,20 @@ static int qt1070_probe(struct i2c_client *client)
|
||||
if (!qt1070_identify(client))
|
||||
return -ENODEV;
|
||||
|
||||
data = kzalloc(sizeof(struct qt1070_data), GFP_KERNEL);
|
||||
input = input_allocate_device();
|
||||
if (!data || !input) {
|
||||
dev_err(&client->dev, "insufficient memory\n");
|
||||
err = -ENOMEM;
|
||||
goto err_free_mem;
|
||||
}
|
||||
data = devm_kzalloc(&client->dev, sizeof(struct qt1070_data),
|
||||
GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
input = devm_input_allocate_device(&client->dev);
|
||||
if (!input)
|
||||
return -ENOMEM;
|
||||
|
||||
data->client = client;
|
||||
data->input = input;
|
||||
data->irq = client->irq;
|
||||
|
||||
input->name = "AT42QT1070 QTouch Sensor";
|
||||
input->dev.parent = &client->dev;
|
||||
input->id.bustype = BUS_I2C;
|
||||
|
||||
/* Add the keycode */
|
||||
@ -185,19 +185,20 @@ static int qt1070_probe(struct i2c_client *client)
|
||||
qt1070_write(client, RESET, 1);
|
||||
msleep(QT1070_RESET_TIME);
|
||||
|
||||
err = request_threaded_irq(client->irq, NULL, qt1070_interrupt,
|
||||
IRQF_TRIGGER_NONE | IRQF_ONESHOT,
|
||||
client->dev.driver->name, data);
|
||||
err = devm_request_threaded_irq(&client->dev, client->irq,
|
||||
NULL, qt1070_interrupt,
|
||||
IRQF_TRIGGER_NONE | IRQF_ONESHOT,
|
||||
client->dev.driver->name, data);
|
||||
if (err) {
|
||||
dev_err(&client->dev, "fail to request irq\n");
|
||||
goto err_free_mem;
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Register the input device */
|
||||
err = input_register_device(data->input);
|
||||
if (err) {
|
||||
dev_err(&client->dev, "Failed to register input device\n");
|
||||
goto err_free_irq;
|
||||
return err;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(client, data);
|
||||
@ -206,24 +207,6 @@ static int qt1070_probe(struct i2c_client *client)
|
||||
qt1070_read(client, DET_STATUS);
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_irq:
|
||||
free_irq(client->irq, data);
|
||||
err_free_mem:
|
||||
input_free_device(input);
|
||||
kfree(data);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void qt1070_remove(struct i2c_client *client)
|
||||
{
|
||||
struct qt1070_data *data = i2c_get_clientdata(client);
|
||||
|
||||
/* Release IRQ */
|
||||
free_irq(client->irq, data);
|
||||
|
||||
input_unregister_device(data->input);
|
||||
kfree(data);
|
||||
}
|
||||
|
||||
static int qt1070_suspend(struct device *dev)
|
||||
@ -272,7 +255,6 @@ static struct i2c_driver qt1070_driver = {
|
||||
},
|
||||
.id_table = qt1070_id,
|
||||
.probe = qt1070_probe,
|
||||
.remove = qt1070_remove,
|
||||
};
|
||||
|
||||
module_i2c_driver(qt1070_driver);
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#define QT2160_NUM_LEDS_X 8
|
||||
|
||||
#define QT2160_CYCLE_INTERVAL (2*HZ)
|
||||
#define QT2160_CYCLE_INTERVAL 2000 /* msec - 2 sec */
|
||||
|
||||
static unsigned char qt2160_key2code[] = {
|
||||
KEY_0, KEY_1, KEY_2, KEY_3,
|
||||
@ -54,7 +54,6 @@ struct qt2160_led {
|
||||
struct qt2160_data {
|
||||
struct i2c_client *client;
|
||||
struct input_dev *input;
|
||||
struct delayed_work dwork;
|
||||
unsigned short keycodes[ARRAY_SIZE(qt2160_key2code)];
|
||||
u16 key_matrix;
|
||||
#ifdef CONFIG_LEDS_CLASS
|
||||
@ -155,10 +154,10 @@ static int qt2160_read_block(struct i2c_client *client,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qt2160_get_key_matrix(struct qt2160_data *qt2160)
|
||||
static void qt2160_get_key_matrix(struct input_dev *input)
|
||||
{
|
||||
struct qt2160_data *qt2160 = input_get_drvdata(input);
|
||||
struct i2c_client *client = qt2160->client;
|
||||
struct input_dev *input = qt2160->input;
|
||||
u8 regs[6];
|
||||
u16 old_matrix, new_matrix;
|
||||
int ret, i, mask;
|
||||
@ -173,7 +172,7 @@ static int qt2160_get_key_matrix(struct qt2160_data *qt2160)
|
||||
if (ret) {
|
||||
dev_err(&client->dev,
|
||||
"could not perform chip read.\n");
|
||||
return ret;
|
||||
return;
|
||||
}
|
||||
|
||||
old_matrix = qt2160->key_matrix;
|
||||
@ -191,37 +190,17 @@ static int qt2160_get_key_matrix(struct qt2160_data *qt2160)
|
||||
}
|
||||
|
||||
input_sync(input);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t qt2160_irq(int irq, void *_qt2160)
|
||||
static irqreturn_t qt2160_irq(int irq, void *data)
|
||||
{
|
||||
struct qt2160_data *qt2160 = _qt2160;
|
||||
struct input_dev *input = data;
|
||||
|
||||
mod_delayed_work(system_wq, &qt2160->dwork, 0);
|
||||
qt2160_get_key_matrix(input);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void qt2160_schedule_read(struct qt2160_data *qt2160)
|
||||
{
|
||||
schedule_delayed_work(&qt2160->dwork, QT2160_CYCLE_INTERVAL);
|
||||
}
|
||||
|
||||
static void qt2160_worker(struct work_struct *work)
|
||||
{
|
||||
struct qt2160_data *qt2160 =
|
||||
container_of(work, struct qt2160_data, dwork.work);
|
||||
|
||||
dev_dbg(&qt2160->client->dev, "worker\n");
|
||||
|
||||
qt2160_get_key_matrix(qt2160);
|
||||
|
||||
/* Avoid device lock up by checking every so often */
|
||||
qt2160_schedule_read(qt2160);
|
||||
}
|
||||
|
||||
static int qt2160_read(struct i2c_client *client, u8 reg)
|
||||
{
|
||||
int ret;
|
||||
@ -260,7 +239,7 @@ static int qt2160_write(struct i2c_client *client, u8 reg, u8 data)
|
||||
static int qt2160_register_leds(struct qt2160_data *qt2160)
|
||||
{
|
||||
struct i2c_client *client = qt2160->client;
|
||||
int ret;
|
||||
int error;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < QT2160_NUM_LEDS_X; i++) {
|
||||
@ -273,9 +252,9 @@ static int qt2160_register_leds(struct qt2160_data *qt2160)
|
||||
led->id = i;
|
||||
led->qt2160 = qt2160;
|
||||
|
||||
ret = led_classdev_register(&client->dev, &led->cdev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
error = devm_led_classdev_register(&client->dev, &led->cdev);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Tur off LEDs */
|
||||
@ -286,14 +265,6 @@ static int qt2160_register_leds(struct qt2160_data *qt2160)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void qt2160_unregister_leds(struct qt2160_data *qt2160)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < QT2160_NUM_LEDS_X; i++)
|
||||
led_classdev_unregister(&qt2160->leds[i].cdev);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline int qt2160_register_leds(struct qt2160_data *qt2160)
|
||||
@ -301,10 +272,6 @@ static inline int qt2160_register_leds(struct qt2160_data *qt2160)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void qt2160_unregister_leds(struct qt2160_data *qt2160)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static bool qt2160_identify(struct i2c_client *client)
|
||||
@ -345,12 +312,9 @@ static int qt2160_probe(struct i2c_client *client)
|
||||
int i;
|
||||
int error;
|
||||
|
||||
/* Check functionality */
|
||||
error = i2c_check_functionality(client->adapter,
|
||||
I2C_FUNC_SMBUS_BYTE);
|
||||
if (!error) {
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) {
|
||||
dev_err(&client->dev, "%s adapter not supported\n",
|
||||
dev_driver_string(&client->adapter->dev));
|
||||
dev_driver_string(&client->adapter->dev));
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@ -358,17 +322,16 @@ static int qt2160_probe(struct i2c_client *client)
|
||||
return -ENODEV;
|
||||
|
||||
/* Chip is valid and active. Allocate structure */
|
||||
qt2160 = kzalloc(sizeof(struct qt2160_data), GFP_KERNEL);
|
||||
input = input_allocate_device();
|
||||
if (!qt2160 || !input) {
|
||||
dev_err(&client->dev, "insufficient memory\n");
|
||||
error = -ENOMEM;
|
||||
goto err_free_mem;
|
||||
}
|
||||
qt2160 = devm_kzalloc(&client->dev, sizeof(*qt2160), GFP_KERNEL);
|
||||
if (!qt2160)
|
||||
return -ENOMEM;
|
||||
|
||||
input = devm_input_allocate_device(&client->dev);
|
||||
if (!input)
|
||||
return -ENOMEM;
|
||||
|
||||
qt2160->client = client;
|
||||
qt2160->input = input;
|
||||
INIT_DELAYED_WORK(&qt2160->dwork, qt2160_worker);
|
||||
|
||||
input->name = "AT42QT2160 Touch Sense Keyboard";
|
||||
input->id.bustype = BUS_I2C;
|
||||
@ -385,66 +348,48 @@ static int qt2160_probe(struct i2c_client *client)
|
||||
}
|
||||
__clear_bit(KEY_RESERVED, input->keybit);
|
||||
|
||||
input_set_drvdata(input, qt2160);
|
||||
|
||||
/* Calibrate device */
|
||||
error = qt2160_write(client, QT2160_CMD_CALIBRATE, 1);
|
||||
if (error) {
|
||||
dev_err(&client->dev, "failed to calibrate device\n");
|
||||
goto err_free_mem;
|
||||
return error;
|
||||
}
|
||||
|
||||
if (client->irq) {
|
||||
error = request_irq(client->irq, qt2160_irq,
|
||||
IRQF_TRIGGER_FALLING, "qt2160", qt2160);
|
||||
error = devm_request_threaded_irq(&client->dev, client->irq,
|
||||
NULL, qt2160_irq,
|
||||
IRQF_ONESHOT,
|
||||
"qt2160", input);
|
||||
if (error) {
|
||||
dev_err(&client->dev,
|
||||
"failed to allocate irq %d\n", client->irq);
|
||||
goto err_free_mem;
|
||||
return error;
|
||||
}
|
||||
} else {
|
||||
error = input_setup_polling(input, qt2160_get_key_matrix);
|
||||
if (error) {
|
||||
dev_err(&client->dev, "Failed to setup polling\n");
|
||||
return error;
|
||||
}
|
||||
input_set_poll_interval(input, QT2160_CYCLE_INTERVAL);
|
||||
}
|
||||
|
||||
error = qt2160_register_leds(qt2160);
|
||||
if (error) {
|
||||
dev_err(&client->dev, "Failed to register leds\n");
|
||||
goto err_free_irq;
|
||||
return error;
|
||||
}
|
||||
|
||||
error = input_register_device(qt2160->input);
|
||||
if (error) {
|
||||
dev_err(&client->dev,
|
||||
"Failed to register input device\n");
|
||||
goto err_unregister_leds;
|
||||
return error;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(client, qt2160);
|
||||
qt2160_schedule_read(qt2160);
|
||||
|
||||
return 0;
|
||||
|
||||
err_unregister_leds:
|
||||
qt2160_unregister_leds(qt2160);
|
||||
err_free_irq:
|
||||
if (client->irq)
|
||||
free_irq(client->irq, qt2160);
|
||||
err_free_mem:
|
||||
input_free_device(input);
|
||||
kfree(qt2160);
|
||||
return error;
|
||||
}
|
||||
|
||||
static void qt2160_remove(struct i2c_client *client)
|
||||
{
|
||||
struct qt2160_data *qt2160 = i2c_get_clientdata(client);
|
||||
|
||||
qt2160_unregister_leds(qt2160);
|
||||
|
||||
/* Release IRQ so no queue will be scheduled */
|
||||
if (client->irq)
|
||||
free_irq(client->irq, qt2160);
|
||||
|
||||
cancel_delayed_work_sync(&qt2160->dwork);
|
||||
|
||||
input_unregister_device(qt2160->input);
|
||||
kfree(qt2160);
|
||||
}
|
||||
|
||||
static const struct i2c_device_id qt2160_idtable[] = {
|
||||
@ -461,7 +406,6 @@ static struct i2c_driver qt2160_driver = {
|
||||
|
||||
.id_table = qt2160_idtable,
|
||||
.probe = qt2160_probe,
|
||||
.remove = qt2160_remove,
|
||||
};
|
||||
|
||||
module_i2c_driver(qt2160_driver);
|
||||
|
@ -21,10 +21,11 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_wakeirq.h>
|
||||
#include <linux/pm_wakeup.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/slab.h>
|
||||
@ -307,8 +308,7 @@ static int sun4i_lradc_probe(struct platform_device *pdev)
|
||||
|
||||
input_set_drvdata(lradc->input, lradc);
|
||||
|
||||
lradc->base = devm_ioremap_resource(dev,
|
||||
platform_get_resource(pdev, IORESOURCE_MEM, 0));
|
||||
lradc->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(lradc->base))
|
||||
return PTR_ERR(lradc->base);
|
||||
|
||||
|
@ -24,6 +24,8 @@
|
||||
#define TCA6416_INVERT 2
|
||||
#define TCA6416_DIRECTION 3
|
||||
|
||||
#define TCA6416_POLL_INTERVAL 100 /* msec */
|
||||
|
||||
static const struct i2c_device_id tca6416_id[] = {
|
||||
{ "tca6416-keys", 16, },
|
||||
{ "tca6408-keys", 8, },
|
||||
@ -43,7 +45,6 @@ struct tca6416_keypad_chip {
|
||||
|
||||
struct i2c_client *client;
|
||||
struct input_dev *input;
|
||||
struct delayed_work dwork;
|
||||
int io_size;
|
||||
int irqnum;
|
||||
u16 pinmask;
|
||||
@ -85,9 +86,9 @@ static int tca6416_read_reg(struct tca6416_keypad_chip *chip, int reg, u16 *val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tca6416_keys_scan(struct tca6416_keypad_chip *chip)
|
||||
static void tca6416_keys_scan(struct input_dev *input)
|
||||
{
|
||||
struct input_dev *input = chip->input;
|
||||
struct tca6416_keypad_chip *chip = input_get_drvdata(input);
|
||||
u16 reg_val, val;
|
||||
int error, i, pin_index;
|
||||
|
||||
@ -122,33 +123,20 @@ static void tca6416_keys_scan(struct tca6416_keypad_chip *chip)
|
||||
*/
|
||||
static irqreturn_t tca6416_keys_isr(int irq, void *dev_id)
|
||||
{
|
||||
struct tca6416_keypad_chip *chip = dev_id;
|
||||
|
||||
tca6416_keys_scan(chip);
|
||||
tca6416_keys_scan(dev_id);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void tca6416_keys_work_func(struct work_struct *work)
|
||||
{
|
||||
struct tca6416_keypad_chip *chip =
|
||||
container_of(work, struct tca6416_keypad_chip, dwork.work);
|
||||
|
||||
tca6416_keys_scan(chip);
|
||||
schedule_delayed_work(&chip->dwork, msecs_to_jiffies(100));
|
||||
}
|
||||
|
||||
static int tca6416_keys_open(struct input_dev *dev)
|
||||
{
|
||||
struct tca6416_keypad_chip *chip = input_get_drvdata(dev);
|
||||
|
||||
/* Get initial device state in case it has switches */
|
||||
tca6416_keys_scan(chip);
|
||||
|
||||
if (chip->use_polling)
|
||||
schedule_delayed_work(&chip->dwork, msecs_to_jiffies(100));
|
||||
else
|
||||
enable_irq(chip->irqnum);
|
||||
if (!chip->use_polling) {
|
||||
/* Get initial device state in case it has switches */
|
||||
tca6416_keys_scan(dev);
|
||||
enable_irq(chip->client->irq);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -157,10 +145,8 @@ static void tca6416_keys_close(struct input_dev *dev)
|
||||
{
|
||||
struct tca6416_keypad_chip *chip = input_get_drvdata(dev);
|
||||
|
||||
if (chip->use_polling)
|
||||
cancel_delayed_work_sync(&chip->dwork);
|
||||
else
|
||||
disable_irq(chip->irqnum);
|
||||
if (!chip->use_polling)
|
||||
disable_irq(chip->client->irq);
|
||||
}
|
||||
|
||||
static int tca6416_setup_registers(struct tca6416_keypad_chip *chip)
|
||||
@ -216,12 +202,15 @@ static int tca6416_keypad_probe(struct i2c_client *client)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
chip = kzalloc(struct_size(chip, buttons, pdata->nbuttons), GFP_KERNEL);
|
||||
input = input_allocate_device();
|
||||
if (!chip || !input) {
|
||||
error = -ENOMEM;
|
||||
goto fail1;
|
||||
}
|
||||
chip = devm_kzalloc(&client->dev,
|
||||
struct_size(chip, buttons, pdata->nbuttons),
|
||||
GFP_KERNEL);
|
||||
if (!chip)
|
||||
return -ENOMEM;
|
||||
|
||||
input = devm_input_allocate_device(&client->dev);
|
||||
if (!input)
|
||||
return -ENOMEM;
|
||||
|
||||
chip->client = client;
|
||||
chip->input = input;
|
||||
@ -229,11 +218,8 @@ static int tca6416_keypad_probe(struct i2c_client *client)
|
||||
chip->pinmask = pdata->pinmask;
|
||||
chip->use_polling = pdata->use_polling;
|
||||
|
||||
INIT_DELAYED_WORK(&chip->dwork, tca6416_keys_work_func);
|
||||
|
||||
input->phys = "tca6416-keys/input0";
|
||||
input->name = client->name;
|
||||
input->dev.parent = &client->dev;
|
||||
|
||||
input->open = tca6416_keys_open;
|
||||
input->close = tca6416_keys_close;
|
||||
@ -263,24 +249,28 @@ static int tca6416_keypad_probe(struct i2c_client *client)
|
||||
*/
|
||||
error = tca6416_setup_registers(chip);
|
||||
if (error)
|
||||
goto fail1;
|
||||
return error;
|
||||
|
||||
if (!chip->use_polling) {
|
||||
if (pdata->irq_is_gpio)
|
||||
chip->irqnum = gpio_to_irq(client->irq);
|
||||
else
|
||||
chip->irqnum = client->irq;
|
||||
if (chip->use_polling) {
|
||||
error = input_setup_polling(input, tca6416_keys_scan);
|
||||
if (error) {
|
||||
dev_err(&client->dev, "Failed to setup polling\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
error = request_threaded_irq(chip->irqnum, NULL,
|
||||
tca6416_keys_isr,
|
||||
IRQF_TRIGGER_FALLING |
|
||||
IRQF_ONESHOT | IRQF_NO_AUTOEN,
|
||||
"tca6416-keypad", chip);
|
||||
input_set_poll_interval(input, TCA6416_POLL_INTERVAL);
|
||||
} else {
|
||||
error = devm_request_threaded_irq(&client->dev, client->irq,
|
||||
NULL, tca6416_keys_isr,
|
||||
IRQF_TRIGGER_FALLING |
|
||||
IRQF_ONESHOT |
|
||||
IRQF_NO_AUTOEN,
|
||||
"tca6416-keypad", input);
|
||||
if (error) {
|
||||
dev_dbg(&client->dev,
|
||||
"Unable to claim irq %d; error %d\n",
|
||||
chip->irqnum, error);
|
||||
goto fail1;
|
||||
client->irq, error);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
@ -288,70 +278,19 @@ static int tca6416_keypad_probe(struct i2c_client *client)
|
||||
if (error) {
|
||||
dev_dbg(&client->dev,
|
||||
"Unable to register input device, error: %d\n", error);
|
||||
goto fail2;
|
||||
return error;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(client, chip);
|
||||
device_init_wakeup(&client->dev, 1);
|
||||
|
||||
return 0;
|
||||
|
||||
fail2:
|
||||
if (!chip->use_polling) {
|
||||
free_irq(chip->irqnum, chip);
|
||||
enable_irq(chip->irqnum);
|
||||
}
|
||||
fail1:
|
||||
input_free_device(input);
|
||||
kfree(chip);
|
||||
return error;
|
||||
}
|
||||
|
||||
static void tca6416_keypad_remove(struct i2c_client *client)
|
||||
{
|
||||
struct tca6416_keypad_chip *chip = i2c_get_clientdata(client);
|
||||
|
||||
if (!chip->use_polling) {
|
||||
free_irq(chip->irqnum, chip);
|
||||
enable_irq(chip->irqnum);
|
||||
}
|
||||
|
||||
input_unregister_device(chip->input);
|
||||
kfree(chip);
|
||||
}
|
||||
|
||||
static int tca6416_keypad_suspend(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct tca6416_keypad_chip *chip = i2c_get_clientdata(client);
|
||||
|
||||
if (device_may_wakeup(dev))
|
||||
enable_irq_wake(chip->irqnum);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tca6416_keypad_resume(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct tca6416_keypad_chip *chip = i2c_get_clientdata(client);
|
||||
|
||||
if (device_may_wakeup(dev))
|
||||
disable_irq_wake(chip->irqnum);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(tca6416_keypad_dev_pm_ops,
|
||||
tca6416_keypad_suspend, tca6416_keypad_resume);
|
||||
|
||||
static struct i2c_driver tca6416_keypad_driver = {
|
||||
.driver = {
|
||||
.name = "tca6416-keypad",
|
||||
.pm = pm_sleep_ptr(&tca6416_keypad_dev_pm_ops),
|
||||
},
|
||||
.probe = tca6416_keypad_probe,
|
||||
.remove = tca6416_keypad_remove,
|
||||
.id_table = tca6416_id,
|
||||
};
|
||||
|
||||
|
@ -640,7 +640,7 @@ static int tegra_kbc_probe(struct platform_device *pdev)
|
||||
|
||||
timer_setup(&kbc->timer, tegra_kbc_keypress_timer, 0);
|
||||
|
||||
kbc->mmio = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
|
||||
kbc->mmio = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(kbc->mmio))
|
||||
return PTR_ERR(kbc->mmio);
|
||||
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include <linux/leds.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
|
@ -791,10 +791,10 @@ config INPUT_IQS626A
|
||||
module will be called iqs626a.
|
||||
|
||||
config INPUT_IQS7222
|
||||
tristate "Azoteq IQS7222A/B/C capacitive touch controller"
|
||||
tristate "Azoteq IQS7222A/B/C/D capacitive touch controller"
|
||||
depends on I2C
|
||||
help
|
||||
Say Y to enable support for the Azoteq IQS7222A/B/C family
|
||||
Say Y to enable support for the Azoteq IQS7222A/B/C/D family
|
||||
of capacitive touch controllers.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
|
@ -1,16 +1,8 @@
|
||||
/**
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* CPCAP Power Button Input Driver
|
||||
*
|
||||
* Copyright (C) 2017 Sebastian Reichel <sre@kernel.org>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General
|
||||
* Public License. See the file "COPYING" in the main directory of this
|
||||
* archive for more details.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_wakeirq.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/of.h>
|
||||
@ -251,6 +252,14 @@ static int da9063_onkey_probe(struct platform_device *pdev)
|
||||
return error;
|
||||
}
|
||||
|
||||
error = dev_pm_set_wake_irq(&pdev->dev, irq);
|
||||
if (error)
|
||||
dev_warn(&pdev->dev,
|
||||
"Failed to set IRQ %d as a wake IRQ: %d\n",
|
||||
irq, error);
|
||||
else
|
||||
device_init_wakeup(&pdev->dev, true);
|
||||
|
||||
error = input_register_device(onkey->input);
|
||||
if (error) {
|
||||
dev_err(&pdev->dev,
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include <linux/input.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
@ -113,22 +113,14 @@ static int gpio_vibrator_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
vibrator->vcc = devm_regulator_get(&pdev->dev, "vcc");
|
||||
err = PTR_ERR_OR_ZERO(vibrator->vcc);
|
||||
if (err) {
|
||||
if (err != -EPROBE_DEFER)
|
||||
dev_err(&pdev->dev, "Failed to request regulator: %d\n",
|
||||
err);
|
||||
return err;
|
||||
}
|
||||
if (IS_ERR(vibrator->vcc))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(vibrator->vcc),
|
||||
"Failed to request regulator\n");
|
||||
|
||||
vibrator->gpio = devm_gpiod_get(&pdev->dev, "enable", GPIOD_OUT_LOW);
|
||||
err = PTR_ERR_OR_ZERO(vibrator->gpio);
|
||||
if (err) {
|
||||
if (err != -EPROBE_DEFER)
|
||||
dev_err(&pdev->dev, "Failed to request main gpio: %d\n",
|
||||
err);
|
||||
return err;
|
||||
}
|
||||
if (IS_ERR(vibrator->gpio))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(vibrator->gpio),
|
||||
"Failed to request main gpio\n");
|
||||
|
||||
INIT_WORK(&vibrator->play_work, gpio_vibrator_play_work);
|
||||
|
||||
|
@ -17,9 +17,9 @@
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -19,8 +19,8 @@
|
||||
#include <linux/input/touchscreen.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Azoteq IQS7222A/B/C Capacitive Touch Controller
|
||||
* Azoteq IQS7222A/B/C/D Capacitive Touch Controller
|
||||
*
|
||||
* Copyright (C) 2022 Jeff LaBundy <jeff@labundy.com>
|
||||
*/
|
||||
@ -12,11 +12,12 @@
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/input/touchscreen.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/ktime.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/slab.h>
|
||||
#include <asm/unaligned.h>
|
||||
@ -25,6 +26,7 @@
|
||||
#define IQS7222_PROD_NUM_A 840
|
||||
#define IQS7222_PROD_NUM_B 698
|
||||
#define IQS7222_PROD_NUM_C 863
|
||||
#define IQS7222_PROD_NUM_D 1046
|
||||
|
||||
#define IQS7222_SYS_STATUS 0x10
|
||||
#define IQS7222_SYS_STATUS_RESET BIT(3)
|
||||
@ -54,6 +56,7 @@
|
||||
|
||||
#define IQS7222_EVENT_MASK_ATI BIT(12)
|
||||
#define IQS7222_EVENT_MASK_SLDR BIT(10)
|
||||
#define IQS7222_EVENT_MASK_TPAD IQS7222_EVENT_MASK_SLDR
|
||||
#define IQS7222_EVENT_MASK_TOUCH BIT(1)
|
||||
#define IQS7222_EVENT_MASK_PROX BIT(0)
|
||||
|
||||
@ -71,6 +74,7 @@
|
||||
#define IQS7222_MAX_COLS_CHAN 6
|
||||
#define IQS7222_MAX_COLS_FILT 2
|
||||
#define IQS7222_MAX_COLS_SLDR 11
|
||||
#define IQS7222_MAX_COLS_TPAD 24
|
||||
#define IQS7222_MAX_COLS_GPIO 3
|
||||
#define IQS7222_MAX_COLS_SYS 13
|
||||
|
||||
@ -102,16 +106,18 @@ enum iqs7222_reg_grp_id {
|
||||
IQS7222_REG_GRP_BTN,
|
||||
IQS7222_REG_GRP_CHAN,
|
||||
IQS7222_REG_GRP_SLDR,
|
||||
IQS7222_REG_GRP_TPAD,
|
||||
IQS7222_REG_GRP_GPIO,
|
||||
IQS7222_REG_GRP_SYS,
|
||||
IQS7222_NUM_REG_GRPS
|
||||
};
|
||||
|
||||
static const char * const iqs7222_reg_grp_names[IQS7222_NUM_REG_GRPS] = {
|
||||
[IQS7222_REG_GRP_CYCLE] = "cycle",
|
||||
[IQS7222_REG_GRP_CHAN] = "channel",
|
||||
[IQS7222_REG_GRP_SLDR] = "slider",
|
||||
[IQS7222_REG_GRP_GPIO] = "gpio",
|
||||
[IQS7222_REG_GRP_CYCLE] = "cycle-%d",
|
||||
[IQS7222_REG_GRP_CHAN] = "channel-%d",
|
||||
[IQS7222_REG_GRP_SLDR] = "slider-%d",
|
||||
[IQS7222_REG_GRP_TPAD] = "trackpad",
|
||||
[IQS7222_REG_GRP_GPIO] = "gpio-%d",
|
||||
};
|
||||
|
||||
static const unsigned int iqs7222_max_cols[IQS7222_NUM_REG_GRPS] = {
|
||||
@ -122,6 +128,7 @@ static const unsigned int iqs7222_max_cols[IQS7222_NUM_REG_GRPS] = {
|
||||
[IQS7222_REG_GRP_CHAN] = IQS7222_MAX_COLS_CHAN,
|
||||
[IQS7222_REG_GRP_FILT] = IQS7222_MAX_COLS_FILT,
|
||||
[IQS7222_REG_GRP_SLDR] = IQS7222_MAX_COLS_SLDR,
|
||||
[IQS7222_REG_GRP_TPAD] = IQS7222_MAX_COLS_TPAD,
|
||||
[IQS7222_REG_GRP_GPIO] = IQS7222_MAX_COLS_GPIO,
|
||||
[IQS7222_REG_GRP_SYS] = IQS7222_MAX_COLS_SYS,
|
||||
};
|
||||
@ -130,8 +137,10 @@ static const unsigned int iqs7222_gpio_links[] = { 2, 5, 6, };
|
||||
|
||||
struct iqs7222_event_desc {
|
||||
const char *name;
|
||||
u16 link;
|
||||
u16 mask;
|
||||
u16 val;
|
||||
u16 strict;
|
||||
u16 enable;
|
||||
enum iqs7222_reg_key_id reg_key;
|
||||
};
|
||||
@ -188,6 +197,93 @@ static const struct iqs7222_event_desc iqs7222_sl_events[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct iqs7222_event_desc iqs7222_tp_events[] = {
|
||||
{
|
||||
.name = "event-press",
|
||||
.link = BIT(7),
|
||||
},
|
||||
{
|
||||
.name = "event-tap",
|
||||
.link = BIT(0),
|
||||
.mask = BIT(0),
|
||||
.val = BIT(0),
|
||||
.enable = BIT(0),
|
||||
.reg_key = IQS7222_REG_KEY_TAP,
|
||||
},
|
||||
{
|
||||
.name = "event-swipe-x-pos",
|
||||
.link = BIT(2),
|
||||
.mask = BIT(2) | BIT(1),
|
||||
.val = BIT(2),
|
||||
.strict = BIT(4),
|
||||
.enable = BIT(1),
|
||||
.reg_key = IQS7222_REG_KEY_AXIAL,
|
||||
},
|
||||
{
|
||||
.name = "event-swipe-y-pos",
|
||||
.link = BIT(3),
|
||||
.mask = BIT(3) | BIT(1),
|
||||
.val = BIT(3),
|
||||
.strict = BIT(3),
|
||||
.enable = BIT(1),
|
||||
.reg_key = IQS7222_REG_KEY_AXIAL,
|
||||
},
|
||||
{
|
||||
.name = "event-swipe-x-neg",
|
||||
.link = BIT(4),
|
||||
.mask = BIT(4) | BIT(1),
|
||||
.val = BIT(4),
|
||||
.strict = BIT(4),
|
||||
.enable = BIT(1),
|
||||
.reg_key = IQS7222_REG_KEY_AXIAL,
|
||||
},
|
||||
{
|
||||
.name = "event-swipe-y-neg",
|
||||
.link = BIT(5),
|
||||
.mask = BIT(5) | BIT(1),
|
||||
.val = BIT(5),
|
||||
.strict = BIT(3),
|
||||
.enable = BIT(1),
|
||||
.reg_key = IQS7222_REG_KEY_AXIAL,
|
||||
},
|
||||
{
|
||||
.name = "event-flick-x-pos",
|
||||
.link = BIT(2),
|
||||
.mask = BIT(2) | BIT(1),
|
||||
.val = BIT(2) | BIT(1),
|
||||
.strict = BIT(4),
|
||||
.enable = BIT(2),
|
||||
.reg_key = IQS7222_REG_KEY_AXIAL,
|
||||
},
|
||||
{
|
||||
.name = "event-flick-y-pos",
|
||||
.link = BIT(3),
|
||||
.mask = BIT(3) | BIT(1),
|
||||
.val = BIT(3) | BIT(1),
|
||||
.strict = BIT(3),
|
||||
.enable = BIT(2),
|
||||
.reg_key = IQS7222_REG_KEY_AXIAL,
|
||||
},
|
||||
{
|
||||
.name = "event-flick-x-neg",
|
||||
.link = BIT(4),
|
||||
.mask = BIT(4) | BIT(1),
|
||||
.val = BIT(4) | BIT(1),
|
||||
.strict = BIT(4),
|
||||
.enable = BIT(2),
|
||||
.reg_key = IQS7222_REG_KEY_AXIAL,
|
||||
},
|
||||
{
|
||||
.name = "event-flick-y-neg",
|
||||
.link = BIT(5),
|
||||
.mask = BIT(5) | BIT(1),
|
||||
.val = BIT(5) | BIT(1),
|
||||
.strict = BIT(3),
|
||||
.enable = BIT(2),
|
||||
.reg_key = IQS7222_REG_KEY_AXIAL,
|
||||
},
|
||||
};
|
||||
|
||||
struct iqs7222_reg_grp_desc {
|
||||
u16 base;
|
||||
int num_row;
|
||||
@ -524,6 +620,62 @@ static const struct iqs7222_dev_desc iqs7222_devs[] = {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
.prod_num = IQS7222_PROD_NUM_D,
|
||||
.fw_major = 0,
|
||||
.fw_minor = 37,
|
||||
.touch_link = 1770,
|
||||
.allow_offset = 9,
|
||||
.event_offset = 10,
|
||||
.comms_offset = 11,
|
||||
.reg_grps = {
|
||||
[IQS7222_REG_GRP_STAT] = {
|
||||
.base = IQS7222_SYS_STATUS,
|
||||
.num_row = 1,
|
||||
.num_col = 7,
|
||||
},
|
||||
[IQS7222_REG_GRP_CYCLE] = {
|
||||
.base = 0x8000,
|
||||
.num_row = 7,
|
||||
.num_col = 2,
|
||||
},
|
||||
[IQS7222_REG_GRP_GLBL] = {
|
||||
.base = 0x8700,
|
||||
.num_row = 1,
|
||||
.num_col = 3,
|
||||
},
|
||||
[IQS7222_REG_GRP_BTN] = {
|
||||
.base = 0x9000,
|
||||
.num_row = 14,
|
||||
.num_col = 3,
|
||||
},
|
||||
[IQS7222_REG_GRP_CHAN] = {
|
||||
.base = 0xA000,
|
||||
.num_row = 14,
|
||||
.num_col = 4,
|
||||
},
|
||||
[IQS7222_REG_GRP_FILT] = {
|
||||
.base = 0xAE00,
|
||||
.num_row = 1,
|
||||
.num_col = 2,
|
||||
},
|
||||
[IQS7222_REG_GRP_TPAD] = {
|
||||
.base = 0xB000,
|
||||
.num_row = 1,
|
||||
.num_col = 24,
|
||||
},
|
||||
[IQS7222_REG_GRP_GPIO] = {
|
||||
.base = 0xC000,
|
||||
.num_row = 3,
|
||||
.num_col = 3,
|
||||
},
|
||||
[IQS7222_REG_GRP_SYS] = {
|
||||
.base = IQS7222_SYS_SETUP,
|
||||
.num_row = 1,
|
||||
.num_col = 12,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
struct iqs7222_prop_desc {
|
||||
@ -1008,6 +1160,123 @@ static const struct iqs7222_prop_desc iqs7222_props[] = {
|
||||
.val_pitch = 4,
|
||||
.label = "maximum gesture time",
|
||||
},
|
||||
{
|
||||
.name = "azoteq,num-rows",
|
||||
.reg_grp = IQS7222_REG_GRP_TPAD,
|
||||
.reg_offset = 0,
|
||||
.reg_shift = 4,
|
||||
.reg_width = 4,
|
||||
.val_min = 1,
|
||||
.val_max = 12,
|
||||
.label = "number of rows",
|
||||
},
|
||||
{
|
||||
.name = "azoteq,num-cols",
|
||||
.reg_grp = IQS7222_REG_GRP_TPAD,
|
||||
.reg_offset = 0,
|
||||
.reg_shift = 0,
|
||||
.reg_width = 4,
|
||||
.val_min = 1,
|
||||
.val_max = 12,
|
||||
.label = "number of columns",
|
||||
},
|
||||
{
|
||||
.name = "azoteq,lower-cal-y",
|
||||
.reg_grp = IQS7222_REG_GRP_TPAD,
|
||||
.reg_offset = 1,
|
||||
.reg_shift = 8,
|
||||
.reg_width = 8,
|
||||
.label = "lower vertical calibration",
|
||||
},
|
||||
{
|
||||
.name = "azoteq,lower-cal-x",
|
||||
.reg_grp = IQS7222_REG_GRP_TPAD,
|
||||
.reg_offset = 1,
|
||||
.reg_shift = 0,
|
||||
.reg_width = 8,
|
||||
.label = "lower horizontal calibration",
|
||||
},
|
||||
{
|
||||
.name = "azoteq,upper-cal-y",
|
||||
.reg_grp = IQS7222_REG_GRP_TPAD,
|
||||
.reg_offset = 2,
|
||||
.reg_shift = 8,
|
||||
.reg_width = 8,
|
||||
.label = "upper vertical calibration",
|
||||
},
|
||||
{
|
||||
.name = "azoteq,upper-cal-x",
|
||||
.reg_grp = IQS7222_REG_GRP_TPAD,
|
||||
.reg_offset = 2,
|
||||
.reg_shift = 0,
|
||||
.reg_width = 8,
|
||||
.label = "upper horizontal calibration",
|
||||
},
|
||||
{
|
||||
.name = "azoteq,top-speed",
|
||||
.reg_grp = IQS7222_REG_GRP_TPAD,
|
||||
.reg_offset = 3,
|
||||
.reg_shift = 8,
|
||||
.reg_width = 8,
|
||||
.val_pitch = 4,
|
||||
.label = "top speed",
|
||||
},
|
||||
{
|
||||
.name = "azoteq,bottom-speed",
|
||||
.reg_grp = IQS7222_REG_GRP_TPAD,
|
||||
.reg_offset = 3,
|
||||
.reg_shift = 0,
|
||||
.reg_width = 8,
|
||||
.label = "bottom speed",
|
||||
},
|
||||
{
|
||||
.name = "azoteq,gesture-min-ms",
|
||||
.reg_grp = IQS7222_REG_GRP_TPAD,
|
||||
.reg_key = IQS7222_REG_KEY_TAP,
|
||||
.reg_offset = 20,
|
||||
.reg_shift = 8,
|
||||
.reg_width = 8,
|
||||
.val_pitch = 16,
|
||||
.label = "minimum gesture time",
|
||||
},
|
||||
{
|
||||
.name = "azoteq,gesture-max-ms",
|
||||
.reg_grp = IQS7222_REG_GRP_TPAD,
|
||||
.reg_key = IQS7222_REG_KEY_AXIAL,
|
||||
.reg_offset = 21,
|
||||
.reg_shift = 8,
|
||||
.reg_width = 8,
|
||||
.val_pitch = 16,
|
||||
.label = "maximum gesture time",
|
||||
},
|
||||
{
|
||||
.name = "azoteq,gesture-max-ms",
|
||||
.reg_grp = IQS7222_REG_GRP_TPAD,
|
||||
.reg_key = IQS7222_REG_KEY_TAP,
|
||||
.reg_offset = 21,
|
||||
.reg_shift = 0,
|
||||
.reg_width = 8,
|
||||
.val_pitch = 16,
|
||||
.label = "maximum gesture time",
|
||||
},
|
||||
{
|
||||
.name = "azoteq,gesture-dist",
|
||||
.reg_grp = IQS7222_REG_GRP_TPAD,
|
||||
.reg_key = IQS7222_REG_KEY_TAP,
|
||||
.reg_offset = 22,
|
||||
.reg_shift = 0,
|
||||
.reg_width = 16,
|
||||
.label = "gesture distance",
|
||||
},
|
||||
{
|
||||
.name = "azoteq,gesture-dist",
|
||||
.reg_grp = IQS7222_REG_GRP_TPAD,
|
||||
.reg_key = IQS7222_REG_KEY_AXIAL,
|
||||
.reg_offset = 23,
|
||||
.reg_shift = 0,
|
||||
.reg_width = 16,
|
||||
.label = "gesture distance",
|
||||
},
|
||||
{
|
||||
.name = "drive-open-drain",
|
||||
.reg_grp = IQS7222_REG_GRP_GPIO,
|
||||
@ -1091,16 +1360,19 @@ struct iqs7222_private {
|
||||
struct gpio_desc *irq_gpio;
|
||||
struct i2c_client *client;
|
||||
struct input_dev *keypad;
|
||||
struct touchscreen_properties prop;
|
||||
unsigned int kp_type[IQS7222_MAX_CHAN][ARRAY_SIZE(iqs7222_kp_events)];
|
||||
unsigned int kp_code[IQS7222_MAX_CHAN][ARRAY_SIZE(iqs7222_kp_events)];
|
||||
unsigned int sl_code[IQS7222_MAX_SLDR][ARRAY_SIZE(iqs7222_sl_events)];
|
||||
unsigned int sl_axis[IQS7222_MAX_SLDR];
|
||||
unsigned int tp_code[ARRAY_SIZE(iqs7222_tp_events)];
|
||||
u16 cycle_setup[IQS7222_MAX_CHAN / 2][IQS7222_MAX_COLS_CYCLE];
|
||||
u16 glbl_setup[IQS7222_MAX_COLS_GLBL];
|
||||
u16 btn_setup[IQS7222_MAX_CHAN][IQS7222_MAX_COLS_BTN];
|
||||
u16 chan_setup[IQS7222_MAX_CHAN][IQS7222_MAX_COLS_CHAN];
|
||||
u16 filt_setup[IQS7222_MAX_COLS_FILT];
|
||||
u16 sldr_setup[IQS7222_MAX_SLDR][IQS7222_MAX_COLS_SLDR];
|
||||
u16 tpad_setup[IQS7222_MAX_COLS_TPAD];
|
||||
u16 gpio_setup[ARRAY_SIZE(iqs7222_gpio_links)][IQS7222_MAX_COLS_GPIO];
|
||||
u16 sys_setup[IQS7222_MAX_COLS_SYS];
|
||||
};
|
||||
@ -1127,6 +1399,9 @@ static u16 *iqs7222_setup(struct iqs7222_private *iqs7222,
|
||||
case IQS7222_REG_GRP_SLDR:
|
||||
return iqs7222->sldr_setup[row];
|
||||
|
||||
case IQS7222_REG_GRP_TPAD:
|
||||
return iqs7222->tpad_setup;
|
||||
|
||||
case IQS7222_REG_GRP_GPIO:
|
||||
return iqs7222->gpio_setup[row];
|
||||
|
||||
@ -1381,9 +1656,6 @@ static int iqs7222_ati_trigger(struct iqs7222_private *iqs7222)
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
sys_setup &= ~IQS7222_SYS_SETUP_INTF_MODE_MASK;
|
||||
sys_setup &= ~IQS7222_SYS_SETUP_PWR_MODE_MASK;
|
||||
|
||||
for (i = 0; i < IQS7222_NUM_RETRIES; i++) {
|
||||
/*
|
||||
* Trigger ATI from streaming and normal-power modes so that
|
||||
@ -1561,8 +1833,11 @@ static int iqs7222_dev_init(struct iqs7222_private *iqs7222, int dir)
|
||||
return error;
|
||||
}
|
||||
|
||||
if (dir == READ)
|
||||
if (dir == READ) {
|
||||
iqs7222->sys_setup[0] &= ~IQS7222_SYS_SETUP_INTF_MODE_MASK;
|
||||
iqs7222->sys_setup[0] &= ~IQS7222_SYS_SETUP_PWR_MODE_MASK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return iqs7222_ati_trigger(iqs7222);
|
||||
}
|
||||
@ -1936,6 +2211,14 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222,
|
||||
ref_setup[4] = dev_desc->touch_link;
|
||||
if (fwnode_property_present(chan_node, "azoteq,use-prox"))
|
||||
ref_setup[4] -= 2;
|
||||
} else if (dev_desc->reg_grps[IQS7222_REG_GRP_TPAD].num_row &&
|
||||
fwnode_property_present(chan_node,
|
||||
"azoteq,counts-filt-enable")) {
|
||||
/*
|
||||
* In the case of IQS7222D, however, the reference mode field
|
||||
* is partially repurposed as a counts filter enable control.
|
||||
*/
|
||||
chan_setup[0] |= IQS7222_CHAN_SETUP_0_REF_MODE_REF;
|
||||
}
|
||||
|
||||
if (fwnode_property_present(chan_node, "azoteq,rx-enable")) {
|
||||
@ -2278,6 +2561,136 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222,
|
||||
IQS7222_REG_KEY_NO_WHEEL);
|
||||
}
|
||||
|
||||
static int iqs7222_parse_tpad(struct iqs7222_private *iqs7222,
|
||||
struct fwnode_handle *tpad_node, int tpad_index)
|
||||
{
|
||||
const struct iqs7222_dev_desc *dev_desc = iqs7222->dev_desc;
|
||||
struct touchscreen_properties *prop = &iqs7222->prop;
|
||||
struct i2c_client *client = iqs7222->client;
|
||||
int num_chan = dev_desc->reg_grps[IQS7222_REG_GRP_CHAN].num_row;
|
||||
int count, error, i;
|
||||
u16 *event_mask = &iqs7222->sys_setup[dev_desc->event_offset];
|
||||
u16 *tpad_setup = iqs7222->tpad_setup;
|
||||
unsigned int chan_sel[12];
|
||||
|
||||
error = iqs7222_parse_props(iqs7222, tpad_node, tpad_index,
|
||||
IQS7222_REG_GRP_TPAD,
|
||||
IQS7222_REG_KEY_NONE);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
count = fwnode_property_count_u32(tpad_node, "azoteq,channel-select");
|
||||
if (count < 0) {
|
||||
dev_err(&client->dev, "Failed to count %s channels: %d\n",
|
||||
fwnode_get_name(tpad_node), count);
|
||||
return count;
|
||||
} else if (!count || count > ARRAY_SIZE(chan_sel)) {
|
||||
dev_err(&client->dev, "Invalid number of %s channels\n",
|
||||
fwnode_get_name(tpad_node));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
error = fwnode_property_read_u32_array(tpad_node,
|
||||
"azoteq,channel-select",
|
||||
chan_sel, count);
|
||||
if (error) {
|
||||
dev_err(&client->dev, "Failed to read %s channels: %d\n",
|
||||
fwnode_get_name(tpad_node), error);
|
||||
return error;
|
||||
}
|
||||
|
||||
tpad_setup[6] &= ~GENMASK(num_chan - 1, 0);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(chan_sel); i++) {
|
||||
tpad_setup[8 + i] = 0;
|
||||
if (i >= count || chan_sel[i] == U8_MAX)
|
||||
continue;
|
||||
|
||||
if (chan_sel[i] >= num_chan) {
|
||||
dev_err(&client->dev, "Invalid %s channel: %u\n",
|
||||
fwnode_get_name(tpad_node), chan_sel[i]);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following fields indicate which channels participate in
|
||||
* the trackpad, as well as each channel's relative placement.
|
||||
*/
|
||||
tpad_setup[6] |= BIT(chan_sel[i]);
|
||||
tpad_setup[8 + i] = chan_sel[i] * 34 + 1072;
|
||||
}
|
||||
|
||||
tpad_setup[7] = dev_desc->touch_link;
|
||||
if (fwnode_property_present(tpad_node, "azoteq,use-prox"))
|
||||
tpad_setup[7] -= 2;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(iqs7222_tp_events); i++)
|
||||
tpad_setup[20] &= ~(iqs7222_tp_events[i].strict |
|
||||
iqs7222_tp_events[i].enable);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(iqs7222_tp_events); i++) {
|
||||
const char *event_name = iqs7222_tp_events[i].name;
|
||||
struct fwnode_handle *event_node;
|
||||
|
||||
event_node = fwnode_get_named_child_node(tpad_node, event_name);
|
||||
if (!event_node)
|
||||
continue;
|
||||
|
||||
if (fwnode_property_present(event_node,
|
||||
"azoteq,gesture-angle-tighten"))
|
||||
tpad_setup[20] |= iqs7222_tp_events[i].strict;
|
||||
|
||||
tpad_setup[20] |= iqs7222_tp_events[i].enable;
|
||||
|
||||
error = iqs7222_parse_event(iqs7222, event_node, tpad_index,
|
||||
IQS7222_REG_GRP_TPAD,
|
||||
iqs7222_tp_events[i].reg_key,
|
||||
iqs7222_tp_events[i].link, 1566,
|
||||
NULL,
|
||||
&iqs7222->tp_code[i]);
|
||||
fwnode_handle_put(event_node);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (!dev_desc->event_offset)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* The press/release event is determined based on whether the
|
||||
* coordinate fields report 0xFFFF and solely relies on touch
|
||||
* or proximity interrupts to be unmasked.
|
||||
*/
|
||||
if (i)
|
||||
*event_mask |= IQS7222_EVENT_MASK_TPAD;
|
||||
else if (tpad_setup[7] == dev_desc->touch_link)
|
||||
*event_mask |= IQS7222_EVENT_MASK_TOUCH;
|
||||
else
|
||||
*event_mask |= IQS7222_EVENT_MASK_PROX;
|
||||
}
|
||||
|
||||
if (!iqs7222->tp_code[0])
|
||||
return 0;
|
||||
|
||||
input_set_abs_params(iqs7222->keypad, ABS_X,
|
||||
0, (tpad_setup[4] ? : 1) - 1, 0, 0);
|
||||
|
||||
input_set_abs_params(iqs7222->keypad, ABS_Y,
|
||||
0, (tpad_setup[5] ? : 1) - 1, 0, 0);
|
||||
|
||||
touchscreen_parse_properties(iqs7222->keypad, false, prop);
|
||||
|
||||
if (prop->max_x >= U16_MAX || prop->max_y >= U16_MAX) {
|
||||
dev_err(&client->dev, "Invalid trackpad size: %u*%u\n",
|
||||
prop->max_x, prop->max_y);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tpad_setup[4] = prop->max_x + 1;
|
||||
tpad_setup[5] = prop->max_y + 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int (*iqs7222_parse_extra[IQS7222_NUM_REG_GRPS])
|
||||
(struct iqs7222_private *iqs7222,
|
||||
struct fwnode_handle *reg_grp_node,
|
||||
@ -2285,6 +2698,7 @@ static int (*iqs7222_parse_extra[IQS7222_NUM_REG_GRPS])
|
||||
[IQS7222_REG_GRP_CYCLE] = iqs7222_parse_cycle,
|
||||
[IQS7222_REG_GRP_CHAN] = iqs7222_parse_chan,
|
||||
[IQS7222_REG_GRP_SLDR] = iqs7222_parse_sldr,
|
||||
[IQS7222_REG_GRP_TPAD] = iqs7222_parse_tpad,
|
||||
};
|
||||
|
||||
static int iqs7222_parse_reg_grp(struct iqs7222_private *iqs7222,
|
||||
@ -2298,7 +2712,7 @@ static int iqs7222_parse_reg_grp(struct iqs7222_private *iqs7222,
|
||||
if (iqs7222_reg_grp_names[reg_grp]) {
|
||||
char reg_grp_name[16];
|
||||
|
||||
snprintf(reg_grp_name, sizeof(reg_grp_name), "%s-%d",
|
||||
snprintf(reg_grp_name, sizeof(reg_grp_name),
|
||||
iqs7222_reg_grp_names[reg_grp], reg_grp_index);
|
||||
|
||||
reg_grp_node = device_get_named_child_node(&client->dev,
|
||||
@ -2346,8 +2760,8 @@ static int iqs7222_parse_all(struct iqs7222_private *iqs7222)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* The IQS7222C exposes multiple GPIO and must be informed
|
||||
* as to which GPIO this group represents.
|
||||
* The IQS7222C and IQS7222D expose multiple GPIO and must be
|
||||
* informed as to which GPIO this group represents.
|
||||
*/
|
||||
for (j = 0; j < ARRAY_SIZE(iqs7222_gpio_links); j++)
|
||||
gpio_setup[0] &= ~BIT(iqs7222_gpio_links[j]);
|
||||
@ -2480,6 +2894,41 @@ static int iqs7222_report(struct iqs7222_private *iqs7222)
|
||||
iqs7222->sl_code[i][j], 0);
|
||||
}
|
||||
|
||||
for (i = 0; i < dev_desc->reg_grps[IQS7222_REG_GRP_TPAD].num_row; i++) {
|
||||
u16 tpad_pos_x = le16_to_cpu(status[4]);
|
||||
u16 tpad_pos_y = le16_to_cpu(status[5]);
|
||||
u16 state = le16_to_cpu(status[6]);
|
||||
|
||||
input_report_key(iqs7222->keypad, iqs7222->tp_code[0],
|
||||
tpad_pos_x < U16_MAX);
|
||||
|
||||
if (tpad_pos_x < U16_MAX)
|
||||
touchscreen_report_pos(iqs7222->keypad, &iqs7222->prop,
|
||||
tpad_pos_x, tpad_pos_y, false);
|
||||
|
||||
if (!(le16_to_cpu(status[1]) & IQS7222_EVENT_MASK_TPAD))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Skip the press/release event, as it does not have separate
|
||||
* status fields and is handled separately.
|
||||
*/
|
||||
for (j = 1; j < ARRAY_SIZE(iqs7222_tp_events); j++) {
|
||||
u16 mask = iqs7222_tp_events[j].mask;
|
||||
u16 val = iqs7222_tp_events[j].val;
|
||||
|
||||
input_report_key(iqs7222->keypad,
|
||||
iqs7222->tp_code[j],
|
||||
(state & mask) == val);
|
||||
}
|
||||
|
||||
input_sync(iqs7222->keypad);
|
||||
|
||||
for (j = 1; j < ARRAY_SIZE(iqs7222_tp_events); j++)
|
||||
input_report_key(iqs7222->keypad,
|
||||
iqs7222->tp_code[j], 0);
|
||||
}
|
||||
|
||||
input_sync(iqs7222->keypad);
|
||||
|
||||
return 0;
|
||||
@ -2584,6 +3033,7 @@ static const struct of_device_id iqs7222_of_match[] = {
|
||||
{ .compatible = "azoteq,iqs7222a" },
|
||||
{ .compatible = "azoteq,iqs7222b" },
|
||||
{ .compatible = "azoteq,iqs7222c" },
|
||||
{ .compatible = "azoteq,iqs7222d" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, iqs7222_of_match);
|
||||
@ -2598,5 +3048,5 @@ static struct i2c_driver iqs7222_i2c_driver = {
|
||||
module_i2c_driver(iqs7222_i2c_driver);
|
||||
|
||||
MODULE_AUTHOR("Jeff LaBundy <jeff@labundy.com>");
|
||||
MODULE_DESCRIPTION("Azoteq IQS7222A/B/C Capacitive Touch Controller");
|
||||
MODULE_DESCRIPTION("Azoteq IQS7222A/B/C/D Capacitive Touch Controller");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
|
||||
#define MMA8450_DRV_NAME "mma8450"
|
||||
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/regmap.h>
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/log2.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
|
||||
#define PON_CNTL_1 0x1C
|
||||
#define PON_CNTL_PULL_UP BIT(7)
|
||||
|
@ -132,13 +132,8 @@ static int pwm_beeper_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
beeper->pwm = devm_pwm_get(dev, NULL);
|
||||
if (IS_ERR(beeper->pwm)) {
|
||||
error = PTR_ERR(beeper->pwm);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(dev, "Failed to request PWM device: %d\n",
|
||||
error);
|
||||
return error;
|
||||
}
|
||||
if (IS_ERR(beeper->pwm))
|
||||
return dev_err_probe(dev, PTR_ERR(beeper->pwm), "Failed to request PWM device\n");
|
||||
|
||||
/* Sync up PWM state and ensure it is off. */
|
||||
pwm_init_state(beeper->pwm, &state);
|
||||
@ -151,13 +146,9 @@ static int pwm_beeper_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
beeper->amplifier = devm_regulator_get(dev, "amp");
|
||||
if (IS_ERR(beeper->amplifier)) {
|
||||
error = PTR_ERR(beeper->amplifier);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(dev, "Failed to get 'amp' regulator: %d\n",
|
||||
error);
|
||||
return error;
|
||||
}
|
||||
if (IS_ERR(beeper->amplifier))
|
||||
return dev_err_probe(dev, PTR_ERR(beeper->amplifier),
|
||||
"Failed to get 'amp' regulator\n");
|
||||
|
||||
INIT_WORK(&beeper->work, pwm_beeper_work);
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include <linux/input.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/pwm.h>
|
||||
@ -140,32 +140,20 @@ static int pwm_vibrator_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
vibrator->vcc = devm_regulator_get(&pdev->dev, "vcc");
|
||||
err = PTR_ERR_OR_ZERO(vibrator->vcc);
|
||||
if (err) {
|
||||
if (err != -EPROBE_DEFER)
|
||||
dev_err(&pdev->dev, "Failed to request regulator: %d\n",
|
||||
err);
|
||||
return err;
|
||||
}
|
||||
if (IS_ERR(vibrator->vcc))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(vibrator->vcc),
|
||||
"Failed to request regulator\n");
|
||||
|
||||
vibrator->enable_gpio = devm_gpiod_get_optional(&pdev->dev, "enable",
|
||||
GPIOD_OUT_LOW);
|
||||
err = PTR_ERR_OR_ZERO(vibrator->enable_gpio);
|
||||
if (err) {
|
||||
if (err != -EPROBE_DEFER)
|
||||
dev_err(&pdev->dev, "Failed to request enable gpio: %d\n",
|
||||
err);
|
||||
return err;
|
||||
}
|
||||
if (IS_ERR(vibrator->enable_gpio))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(vibrator->enable_gpio),
|
||||
"Failed to request enable gpio\n");
|
||||
|
||||
vibrator->pwm = devm_pwm_get(&pdev->dev, "enable");
|
||||
err = PTR_ERR_OR_ZERO(vibrator->pwm);
|
||||
if (err) {
|
||||
if (err != -EPROBE_DEFER)
|
||||
dev_err(&pdev->dev, "Failed to request main pwm: %d\n",
|
||||
err);
|
||||
return err;
|
||||
}
|
||||
if (IS_ERR(vibrator->pwm))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(vibrator->pwm),
|
||||
"Failed to request main pwm\n");
|
||||
|
||||
INIT_WORK(&vibrator->play_work, pwm_vibrator_play_work);
|
||||
|
||||
|
@ -236,12 +236,8 @@ static int rotary_encoder_probe(struct platform_device *pdev)
|
||||
device_property_read_bool(dev, "rotary-encoder,relative-axis");
|
||||
|
||||
encoder->gpios = devm_gpiod_get_array(dev, NULL, GPIOD_IN);
|
||||
if (IS_ERR(encoder->gpios)) {
|
||||
err = PTR_ERR(encoder->gpios);
|
||||
if (err != -EPROBE_DEFER)
|
||||
dev_err(dev, "unable to get gpios: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
if (IS_ERR(encoder->gpios))
|
||||
return dev_err_probe(dev, PTR_ERR(encoder->gpios), "unable to get gpios\n");
|
||||
if (encoder->gpios->ndescs < 2) {
|
||||
dev_err(dev, "not enough gpios found\n");
|
||||
return -EINVAL;
|
||||
@ -255,7 +251,6 @@ static int rotary_encoder_probe(struct platform_device *pdev)
|
||||
|
||||
input->name = pdev->name;
|
||||
input->id.bustype = BUS_HOST;
|
||||
input->dev.parent = dev;
|
||||
|
||||
if (encoder->relative_axis)
|
||||
input_set_capability(input, EV_REL, encoder->axis);
|
||||
|
@ -9,7 +9,8 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
|
@ -1221,13 +1221,8 @@ static int elan_probe(struct i2c_client *client)
|
||||
mutex_init(&data->sysfs_mutex);
|
||||
|
||||
data->vcc = devm_regulator_get(dev, "vcc");
|
||||
if (IS_ERR(data->vcc)) {
|
||||
error = PTR_ERR(data->vcc);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(dev, "Failed to get 'vcc' regulator: %d\n",
|
||||
error);
|
||||
return error;
|
||||
}
|
||||
if (IS_ERR(data->vcc))
|
||||
return dev_err_probe(dev, PTR_ERR(data->vcc), "Failed to get 'vcc' regulator\n");
|
||||
|
||||
error = regulator_enable(data->vcc);
|
||||
if (error) {
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/libps2.h>
|
||||
@ -118,13 +119,18 @@ static psmouse_ret_t psmouse_smbus_process_byte(struct psmouse *psmouse)
|
||||
return PSMOUSE_FULL_PACKET;
|
||||
}
|
||||
|
||||
static void psmouse_activate_smbus_mode(struct psmouse_smbus_dev *smbdev)
|
||||
{
|
||||
if (smbdev->need_deactivate) {
|
||||
psmouse_deactivate(smbdev->psmouse);
|
||||
/* Give the device time to switch into SMBus mode */
|
||||
msleep(30);
|
||||
}
|
||||
}
|
||||
|
||||
static int psmouse_smbus_reconnect(struct psmouse *psmouse)
|
||||
{
|
||||
struct psmouse_smbus_dev *smbdev = psmouse->private;
|
||||
|
||||
if (smbdev->need_deactivate)
|
||||
psmouse_deactivate(psmouse);
|
||||
|
||||
psmouse_activate_smbus_mode(psmouse->private);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -257,8 +263,7 @@ int psmouse_smbus_init(struct psmouse *psmouse,
|
||||
}
|
||||
}
|
||||
|
||||
if (need_deactivate)
|
||||
psmouse_deactivate(psmouse);
|
||||
psmouse_activate_smbus_mode(smbdev);
|
||||
|
||||
psmouse->private = smbdev;
|
||||
psmouse->protocol_handler = psmouse_smbus_process_byte;
|
||||
|
@ -14,11 +14,11 @@
|
||||
* Contributors: Daniel Hellstrom <daniel@gaisler.com>
|
||||
*/
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/serio.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/delay.h>
|
||||
|
@ -1281,6 +1281,13 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
|
||||
SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
|
||||
},
|
||||
/* See comment on TUXEDO InfinityBook S17 Gen6 / Clevo NS70MU above */
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "PD5x_7xPNP_PNR_PNN_PNT"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOAUX)
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "X170SM"),
|
||||
|
@ -2,7 +2,9 @@
|
||||
#ifndef _I8042_SPARCIO_H
|
||||
#define _I8042_SPARCIO_H
|
||||
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
|
@ -101,12 +101,12 @@ static int rpckbd_probe(struct platform_device *dev)
|
||||
int tx_irq, rx_irq;
|
||||
|
||||
rx_irq = platform_get_irq(dev, 0);
|
||||
if (rx_irq <= 0)
|
||||
return rx_irq < 0 ? rx_irq : -ENXIO;
|
||||
if (rx_irq < 0)
|
||||
return rx_irq;
|
||||
|
||||
tx_irq = platform_get_irq(dev, 1);
|
||||
if (tx_irq <= 0)
|
||||
return tx_irq < 0 ? tx_irq : -ENXIO;
|
||||
if (tx_irq < 0)
|
||||
return tx_irq;
|
||||
|
||||
serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
|
||||
rpckbd = kzalloc(sizeof(*rpckbd), GFP_KERNEL);
|
||||
|
@ -14,10 +14,10 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#define DRIVER_NAME "xilinx_ps2"
|
||||
|
||||
|
@ -655,10 +655,10 @@ config TOUCHSCREEN_MTOUCH
|
||||
module will be called mtouch.
|
||||
|
||||
config TOUCHSCREEN_NOVATEK_NVT_TS
|
||||
tristate "Novatek NVT-ts touchscreen support"
|
||||
tristate "Novatek NT11205 touchscreen support"
|
||||
depends on I2C
|
||||
help
|
||||
Say Y here if you have a Novatek NVT-ts touchscreen.
|
||||
Say Y here if you have a Novatek NT11205 touchscreen.
|
||||
If unsure, say N.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
@ -1365,6 +1365,16 @@ config TOUCHSCREEN_IQS5XX
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called iqs5xx.
|
||||
|
||||
config TOUCHSCREEN_IQS7211
|
||||
tristate "Azoteq IQS7210A/7211A/E trackpad/touchscreen controller"
|
||||
depends on I2C
|
||||
help
|
||||
Say Y to enable support for the Azoteq IQS7210A/7211A/E
|
||||
family of trackpad/touchscreen controllers.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called iqs7211.
|
||||
|
||||
config TOUCHSCREEN_ZINITIX
|
||||
tristate "Zinitix touchscreen support"
|
||||
depends on I2C
|
||||
|
@ -115,5 +115,6 @@ obj-$(CONFIG_TOUCHSCREEN_COLIBRI_VF50) += colibri-vf50-ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_ROHM_BU21023) += rohm_bu21023.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_RASPBERRYPI_FW) += raspberrypi-ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_IQS5XX) += iqs5xx.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_IQS7211) += iqs7211.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_ZINITIX) += zinitix.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_HIMAX_HX83112B) += himax_hx83112b.o
|
||||
|
@ -410,31 +410,32 @@ static int bu21013_probe(struct i2c_client *client)
|
||||
struct input_dev *in_dev;
|
||||
struct input_absinfo *info;
|
||||
u32 max_x = 0, max_y = 0;
|
||||
struct device *dev = &client->dev;
|
||||
int error;
|
||||
|
||||
if (!i2c_check_functionality(client->adapter,
|
||||
I2C_FUNC_SMBUS_BYTE_DATA)) {
|
||||
dev_err(&client->dev, "i2c smbus byte data not supported\n");
|
||||
dev_err(dev, "i2c smbus byte data not supported\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (!client->irq) {
|
||||
dev_err(&client->dev, "No IRQ set up\n");
|
||||
dev_err(dev, "No IRQ set up\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL);
|
||||
ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
|
||||
if (!ts)
|
||||
return -ENOMEM;
|
||||
|
||||
ts->client = client;
|
||||
|
||||
ts->x_flip = device_property_read_bool(&client->dev, "rohm,flip-x");
|
||||
ts->y_flip = device_property_read_bool(&client->dev, "rohm,flip-y");
|
||||
ts->x_flip = device_property_read_bool(dev, "rohm,flip-x");
|
||||
ts->y_flip = device_property_read_bool(dev, "rohm,flip-y");
|
||||
|
||||
in_dev = devm_input_allocate_device(&client->dev);
|
||||
in_dev = devm_input_allocate_device(dev);
|
||||
if (!in_dev) {
|
||||
dev_err(&client->dev, "device memory alloc failed\n");
|
||||
dev_err(dev, "device memory alloc failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
ts->in_dev = in_dev;
|
||||
@ -444,8 +445,8 @@ static int bu21013_probe(struct i2c_client *client)
|
||||
in_dev->name = DRIVER_TP;
|
||||
in_dev->id.bustype = BUS_I2C;
|
||||
|
||||
device_property_read_u32(&client->dev, "rohm,touch-max-x", &max_x);
|
||||
device_property_read_u32(&client->dev, "rohm,touch-max-y", &max_y);
|
||||
device_property_read_u32(dev, "rohm,touch-max-x", &max_x);
|
||||
device_property_read_u32(dev, "rohm,touch-max-y", &max_y);
|
||||
|
||||
input_set_abs_params(in_dev, ABS_MT_POSITION_X, 0, max_x, 0, 0);
|
||||
input_set_abs_params(in_dev, ABS_MT_POSITION_Y, 0, max_y, 0, 0);
|
||||
@ -454,14 +455,14 @@ static int bu21013_probe(struct i2c_client *client)
|
||||
|
||||
/* Adjust for the legacy "flip" properties, if present */
|
||||
if (!ts->props.invert_x &&
|
||||
device_property_read_bool(&client->dev, "rohm,flip-x")) {
|
||||
device_property_read_bool(dev, "rohm,flip-x")) {
|
||||
info = &in_dev->absinfo[ABS_MT_POSITION_X];
|
||||
info->maximum -= info->minimum;
|
||||
info->minimum = 0;
|
||||
}
|
||||
|
||||
if (!ts->props.invert_y &&
|
||||
device_property_read_bool(&client->dev, "rohm,flip-y")) {
|
||||
device_property_read_bool(dev, "rohm,flip-y")) {
|
||||
info = &in_dev->absinfo[ABS_MT_POSITION_Y];
|
||||
info->maximum -= info->minimum;
|
||||
info->minimum = 0;
|
||||
@ -471,55 +472,46 @@ static int bu21013_probe(struct i2c_client *client)
|
||||
INPUT_MT_DIRECT | INPUT_MT_TRACK |
|
||||
INPUT_MT_DROP_UNUSED);
|
||||
if (error) {
|
||||
dev_err(&client->dev, "failed to initialize MT slots");
|
||||
dev_err(dev, "failed to initialize MT slots");
|
||||
return error;
|
||||
}
|
||||
|
||||
ts->regulator = devm_regulator_get(&client->dev, "avdd");
|
||||
ts->regulator = devm_regulator_get(dev, "avdd");
|
||||
if (IS_ERR(ts->regulator)) {
|
||||
dev_err(&client->dev, "regulator_get failed\n");
|
||||
dev_err(dev, "regulator_get failed\n");
|
||||
return PTR_ERR(ts->regulator);
|
||||
}
|
||||
|
||||
error = regulator_enable(ts->regulator);
|
||||
if (error) {
|
||||
dev_err(&client->dev, "regulator enable failed\n");
|
||||
dev_err(dev, "regulator enable failed\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
error = devm_add_action_or_reset(&client->dev, bu21013_power_off, ts);
|
||||
error = devm_add_action_or_reset(dev, bu21013_power_off, ts);
|
||||
if (error) {
|
||||
dev_err(&client->dev, "failed to install power off handler\n");
|
||||
dev_err(dev, "failed to install power off handler\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Named "CS" on the chip, DT binding is "reset" */
|
||||
ts->cs_gpiod = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
|
||||
error = PTR_ERR_OR_ZERO(ts->cs_gpiod);
|
||||
if (error) {
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(&client->dev, "failed to get CS GPIO\n");
|
||||
return error;
|
||||
}
|
||||
ts->cs_gpiod = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(ts->cs_gpiod))
|
||||
return dev_err_probe(dev, PTR_ERR(ts->cs_gpiod), "failed to get CS GPIO\n");
|
||||
|
||||
gpiod_set_consumer_name(ts->cs_gpiod, "BU21013 CS");
|
||||
|
||||
error = devm_add_action_or_reset(&client->dev,
|
||||
bu21013_disable_chip, ts);
|
||||
error = devm_add_action_or_reset(dev, bu21013_disable_chip, ts);
|
||||
if (error) {
|
||||
dev_err(&client->dev,
|
||||
"failed to install chip disable handler\n");
|
||||
dev_err(dev, "failed to install chip disable handler\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Named "INT" on the chip, DT binding is "touch" */
|
||||
ts->int_gpiod = devm_gpiod_get_optional(&client->dev,
|
||||
"touch", GPIOD_IN);
|
||||
ts->int_gpiod = devm_gpiod_get_optional(dev, "touch", GPIOD_IN);
|
||||
error = PTR_ERR_OR_ZERO(ts->int_gpiod);
|
||||
if (error) {
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(&client->dev, "failed to get INT GPIO\n");
|
||||
return error;
|
||||
}
|
||||
if (error)
|
||||
return dev_err_probe(dev, error, "failed to get INT GPIO\n");
|
||||
|
||||
if (ts->int_gpiod)
|
||||
gpiod_set_consumer_name(ts->int_gpiod, "BU21013 INT");
|
||||
@ -527,22 +519,20 @@ static int bu21013_probe(struct i2c_client *client)
|
||||
/* configure the touch panel controller */
|
||||
error = bu21013_init_chip(ts);
|
||||
if (error) {
|
||||
dev_err(&client->dev, "error in bu21013 config\n");
|
||||
dev_err(dev, "error in bu21013 config\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
error = devm_request_threaded_irq(&client->dev, client->irq,
|
||||
NULL, bu21013_gpio_irq,
|
||||
error = devm_request_threaded_irq(dev, client->irq, NULL, bu21013_gpio_irq,
|
||||
IRQF_ONESHOT, DRIVER_TP, ts);
|
||||
if (error) {
|
||||
dev_err(&client->dev, "request irq %d failed\n",
|
||||
client->irq);
|
||||
dev_err(dev, "request irq %d failed\n", client->irq);
|
||||
return error;
|
||||
}
|
||||
|
||||
error = input_register_device(in_dev);
|
||||
if (error) {
|
||||
dev_err(&client->dev, "failed to register input device\n");
|
||||
dev_err(dev, "failed to register input device\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -333,6 +333,7 @@ static void bu21029_stop_chip(struct input_dev *dev)
|
||||
|
||||
static int bu21029_probe(struct i2c_client *client)
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
struct bu21029_ts_data *bu21029;
|
||||
struct input_dev *in_dev;
|
||||
int error;
|
||||
@ -341,45 +342,33 @@ static int bu21029_probe(struct i2c_client *client)
|
||||
I2C_FUNC_SMBUS_WRITE_BYTE |
|
||||
I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
|
||||
I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
|
||||
dev_err(&client->dev,
|
||||
"i2c functionality support is not sufficient\n");
|
||||
dev_err(dev, "i2c functionality support is not sufficient\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
bu21029 = devm_kzalloc(&client->dev, sizeof(*bu21029), GFP_KERNEL);
|
||||
bu21029 = devm_kzalloc(dev, sizeof(*bu21029), GFP_KERNEL);
|
||||
if (!bu21029)
|
||||
return -ENOMEM;
|
||||
|
||||
error = device_property_read_u32(&client->dev, "rohm,x-plate-ohms",
|
||||
&bu21029->x_plate_ohms);
|
||||
error = device_property_read_u32(dev, "rohm,x-plate-ohms", &bu21029->x_plate_ohms);
|
||||
if (error) {
|
||||
dev_err(&client->dev,
|
||||
"invalid 'x-plate-ohms' supplied: %d\n", error);
|
||||
dev_err(dev, "invalid 'x-plate-ohms' supplied: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
bu21029->vdd = devm_regulator_get(&client->dev, "vdd");
|
||||
if (IS_ERR(bu21029->vdd)) {
|
||||
error = PTR_ERR(bu21029->vdd);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(&client->dev,
|
||||
"failed to acquire 'vdd' supply: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
bu21029->vdd = devm_regulator_get(dev, "vdd");
|
||||
if (IS_ERR(bu21029->vdd))
|
||||
return dev_err_probe(dev, PTR_ERR(bu21029->vdd),
|
||||
"failed to acquire 'vdd' supply\n");
|
||||
|
||||
bu21029->reset_gpios = devm_gpiod_get_optional(&client->dev,
|
||||
"reset", GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(bu21029->reset_gpios)) {
|
||||
error = PTR_ERR(bu21029->reset_gpios);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(&client->dev,
|
||||
"failed to acquire 'reset' gpio: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
bu21029->reset_gpios = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(bu21029->reset_gpios))
|
||||
return dev_err_probe(dev, PTR_ERR(bu21029->reset_gpios),
|
||||
"failed to acquire 'reset' gpio\n");
|
||||
|
||||
in_dev = devm_input_allocate_device(&client->dev);
|
||||
in_dev = devm_input_allocate_device(dev);
|
||||
if (!in_dev) {
|
||||
dev_err(&client->dev, "unable to allocate input device\n");
|
||||
dev_err(dev, "unable to allocate input device\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@ -400,20 +389,18 @@ static int bu21029_probe(struct i2c_client *client)
|
||||
|
||||
input_set_drvdata(in_dev, bu21029);
|
||||
|
||||
error = devm_request_threaded_irq(&client->dev, client->irq,
|
||||
NULL, bu21029_touch_soft_irq,
|
||||
error = devm_request_threaded_irq(dev, client->irq, NULL,
|
||||
bu21029_touch_soft_irq,
|
||||
IRQF_ONESHOT | IRQF_NO_AUTOEN,
|
||||
DRIVER_NAME, bu21029);
|
||||
if (error) {
|
||||
dev_err(&client->dev,
|
||||
"unable to request touch irq: %d\n", error);
|
||||
dev_err(dev, "unable to request touch irq: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
error = input_register_device(in_dev);
|
||||
if (error) {
|
||||
dev_err(&client->dev,
|
||||
"unable to register input device: %d\n", error);
|
||||
dev_err(dev, "unable to register input device: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -191,12 +191,8 @@ static int icn8318_probe(struct i2c_client *client)
|
||||
return -ENOMEM;
|
||||
|
||||
data->wake_gpio = devm_gpiod_get(dev, "wake", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(data->wake_gpio)) {
|
||||
error = PTR_ERR(data->wake_gpio);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(dev, "Error getting wake gpio: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
if (IS_ERR(data->wake_gpio))
|
||||
return dev_err_probe(dev, PTR_ERR(data->wake_gpio), "Error getting wake gpio\n");
|
||||
|
||||
input = devm_input_allocate_device(dev);
|
||||
if (!input)
|
||||
|
@ -258,12 +258,8 @@ static int cy8ctma140_probe(struct i2c_client *client)
|
||||
ts->regulators[1].supply = "vdd";
|
||||
error = devm_regulator_bulk_get(dev, ARRAY_SIZE(ts->regulators),
|
||||
ts->regulators);
|
||||
if (error) {
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(dev, "Failed to get regulators %d\n",
|
||||
error);
|
||||
return error;
|
||||
}
|
||||
if (error)
|
||||
return dev_err_probe(dev, error, "Failed to get regulators\n");
|
||||
|
||||
error = cy8ctma140_power_up(ts);
|
||||
if (error)
|
||||
|
@ -18,8 +18,8 @@
|
||||
#include <linux/input/touchscreen.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
|
@ -1168,13 +1168,9 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client)
|
||||
tsdata->max_support_points = chip_data->max_support_points;
|
||||
|
||||
tsdata->vcc = devm_regulator_get(&client->dev, "vcc");
|
||||
if (IS_ERR(tsdata->vcc)) {
|
||||
error = PTR_ERR(tsdata->vcc);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(&client->dev,
|
||||
"failed to request regulator: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
if (IS_ERR(tsdata->vcc))
|
||||
return dev_err_probe(&client->dev, PTR_ERR(tsdata->vcc),
|
||||
"failed to request regulator\n");
|
||||
|
||||
tsdata->iovcc = devm_regulator_get(&client->dev, "iovcc");
|
||||
if (IS_ERR(tsdata->iovcc)) {
|
||||
|
@ -264,12 +264,8 @@ static int ektf2127_probe(struct i2c_client *client)
|
||||
|
||||
/* This requests the gpio *and* turns on the touchscreen controller */
|
||||
ts->power_gpios = devm_gpiod_get(dev, "power", GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(ts->power_gpios)) {
|
||||
error = PTR_ERR(ts->power_gpios);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(dev, "Error getting power gpio: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
if (IS_ERR(ts->power_gpios))
|
||||
return dev_err_probe(dev, PTR_ERR(ts->power_gpios), "Error getting power gpio\n");
|
||||
|
||||
input = devm_input_allocate_device(dev);
|
||||
if (!input)
|
||||
|
@ -1438,24 +1438,14 @@ static int elants_i2c_probe(struct i2c_client *client)
|
||||
i2c_set_clientdata(client, ts);
|
||||
|
||||
ts->vcc33 = devm_regulator_get(&client->dev, "vcc33");
|
||||
if (IS_ERR(ts->vcc33)) {
|
||||
error = PTR_ERR(ts->vcc33);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(&client->dev,
|
||||
"Failed to get 'vcc33' regulator: %d\n",
|
||||
error);
|
||||
return error;
|
||||
}
|
||||
if (IS_ERR(ts->vcc33))
|
||||
return dev_err_probe(&client->dev, PTR_ERR(ts->vcc33),
|
||||
"Failed to get 'vcc33' regulator\n");
|
||||
|
||||
ts->vccio = devm_regulator_get(&client->dev, "vccio");
|
||||
if (IS_ERR(ts->vccio)) {
|
||||
error = PTR_ERR(ts->vccio);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(&client->dev,
|
||||
"Failed to get 'vccio' regulator: %d\n",
|
||||
error);
|
||||
return error;
|
||||
}
|
||||
if (IS_ERR(ts->vccio))
|
||||
return dev_err_probe(&client->dev, PTR_ERR(ts->vccio),
|
||||
"Failed to get 'vccio' regulator\n");
|
||||
|
||||
ts->reset_gpio = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(ts->reset_gpio)) {
|
||||
|
@ -7,6 +7,7 @@
|
||||
* minimal implementation based on egalax_ts.c and egalax_i2c.c
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
@ -18,6 +19,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <linux/timer.h>
|
||||
#include <asm/unaligned.h>
|
||||
@ -360,6 +362,12 @@ static int exc3000_probe(struct i2c_client *client)
|
||||
if (IS_ERR(data->reset))
|
||||
return PTR_ERR(data->reset);
|
||||
|
||||
/* For proper reset sequence, enable power while reset asserted */
|
||||
error = devm_regulator_get_enable(&client->dev, "vdd");
|
||||
if (error && error != -ENODEV)
|
||||
return dev_err_probe(&client->dev, error,
|
||||
"failed to request vdd regulator\n");
|
||||
|
||||
if (data->reset) {
|
||||
msleep(EXC3000_RESET_MS);
|
||||
gpiod_set_value_cansleep(data->reset, 0);
|
||||
@ -454,10 +462,19 @@ static const struct of_device_id exc3000_of_match[] = {
|
||||
MODULE_DEVICE_TABLE(of, exc3000_of_match);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
static const struct acpi_device_id exc3000_acpi_match[] = {
|
||||
{ "EGA00001", .driver_data = (kernel_ulong_t)&exc3000_info[EETI_EXC80H60] },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, exc3000_acpi_match);
|
||||
#endif
|
||||
|
||||
static struct i2c_driver exc3000_driver = {
|
||||
.driver = {
|
||||
.name = "exc3000",
|
||||
.of_match_table = of_match_ptr(exc3000_of_match),
|
||||
.acpi_match_table = ACPI_PTR(exc3000_acpi_match),
|
||||
},
|
||||
.id_table = exc3000_id,
|
||||
.probe = exc3000_probe,
|
||||
|
@ -935,7 +935,6 @@ static int goodix_add_acpi_gpio_mappings(struct goodix_ts_data *ts)
|
||||
*/
|
||||
static int goodix_get_gpio_config(struct goodix_ts_data *ts)
|
||||
{
|
||||
int error;
|
||||
struct device *dev;
|
||||
struct gpio_desc *gpiod;
|
||||
bool added_acpi_mappings = false;
|
||||
@ -951,33 +950,20 @@ static int goodix_get_gpio_config(struct goodix_ts_data *ts)
|
||||
ts->gpiod_rst_flags = GPIOD_IN;
|
||||
|
||||
ts->avdd28 = devm_regulator_get(dev, "AVDD28");
|
||||
if (IS_ERR(ts->avdd28)) {
|
||||
error = PTR_ERR(ts->avdd28);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(dev,
|
||||
"Failed to get AVDD28 regulator: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
if (IS_ERR(ts->avdd28))
|
||||
return dev_err_probe(dev, PTR_ERR(ts->avdd28), "Failed to get AVDD28 regulator\n");
|
||||
|
||||
ts->vddio = devm_regulator_get(dev, "VDDIO");
|
||||
if (IS_ERR(ts->vddio)) {
|
||||
error = PTR_ERR(ts->vddio);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(dev,
|
||||
"Failed to get VDDIO regulator: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
if (IS_ERR(ts->vddio))
|
||||
return dev_err_probe(dev, PTR_ERR(ts->vddio), "Failed to get VDDIO regulator\n");
|
||||
|
||||
retry_get_irq_gpio:
|
||||
/* Get the interrupt GPIO pin number */
|
||||
gpiod = devm_gpiod_get_optional(dev, GOODIX_GPIO_INT_NAME, GPIOD_IN);
|
||||
if (IS_ERR(gpiod)) {
|
||||
error = PTR_ERR(gpiod);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(dev, "Failed to get %s GPIO: %d\n",
|
||||
GOODIX_GPIO_INT_NAME, error);
|
||||
return error;
|
||||
}
|
||||
if (IS_ERR(gpiod))
|
||||
return dev_err_probe(dev, PTR_ERR(gpiod), "Failed to get %s GPIO\n",
|
||||
GOODIX_GPIO_INT_NAME);
|
||||
|
||||
if (!gpiod && has_acpi_companion(dev) && !added_acpi_mappings) {
|
||||
added_acpi_mappings = true;
|
||||
if (goodix_add_acpi_gpio_mappings(ts) == 0)
|
||||
@ -988,13 +974,9 @@ retry_get_irq_gpio:
|
||||
|
||||
/* Get the reset line GPIO pin number */
|
||||
gpiod = devm_gpiod_get_optional(dev, GOODIX_GPIO_RST_NAME, ts->gpiod_rst_flags);
|
||||
if (IS_ERR(gpiod)) {
|
||||
error = PTR_ERR(gpiod);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(dev, "Failed to get %s GPIO: %d\n",
|
||||
GOODIX_GPIO_RST_NAME, error);
|
||||
return error;
|
||||
}
|
||||
if (IS_ERR(gpiod))
|
||||
return dev_err_probe(dev, PTR_ERR(gpiod), "Failed to get %s GPIO\n",
|
||||
GOODIX_GPIO_RST_NAME);
|
||||
|
||||
ts->gpiod_rst = gpiod;
|
||||
|
||||
@ -1517,6 +1499,7 @@ MODULE_DEVICE_TABLE(i2c, goodix_ts_id);
|
||||
static const struct acpi_device_id goodix_acpi_match[] = {
|
||||
{ "GDIX1001", 0 },
|
||||
{ "GDIX1002", 0 },
|
||||
{ "GDX9110", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, goodix_acpi_match);
|
||||
|
@ -8,8 +8,8 @@
|
||||
#include <linux/input/mt.h>
|
||||
#include <linux/input/touchscreen.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <linux/slab.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
@ -23,8 +23,8 @@
|
||||
#include <linux/input/touchscreen.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
|
2557
drivers/input/touchscreen/iqs7211.c
Normal file
2557
drivers/input/touchscreen/iqs7211.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -198,54 +198,36 @@ static void lpc32xx_ts_close(struct input_dev *dev)
|
||||
|
||||
static int lpc32xx_ts_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct lpc32xx_tsc *tsc;
|
||||
struct input_dev *input;
|
||||
struct resource *res;
|
||||
resource_size_t size;
|
||||
int irq;
|
||||
int error;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "Can't get memory resource\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
|
||||
tsc = kzalloc(sizeof(*tsc), GFP_KERNEL);
|
||||
input = input_allocate_device();
|
||||
if (!tsc || !input) {
|
||||
dev_err(&pdev->dev, "failed allocating memory\n");
|
||||
error = -ENOMEM;
|
||||
goto err_free_mem;
|
||||
}
|
||||
tsc = devm_kzalloc(dev, sizeof(*tsc), GFP_KERNEL);
|
||||
if (!tsc)
|
||||
return -ENOMEM;
|
||||
|
||||
tsc->dev = input;
|
||||
tsc->irq = irq;
|
||||
|
||||
size = resource_size(res);
|
||||
tsc->tsc_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(tsc->tsc_base))
|
||||
return PTR_ERR(tsc->tsc_base);
|
||||
|
||||
if (!request_mem_region(res->start, size, pdev->name)) {
|
||||
dev_err(&pdev->dev, "TSC registers are not free\n");
|
||||
error = -EBUSY;
|
||||
goto err_free_mem;
|
||||
}
|
||||
|
||||
tsc->tsc_base = ioremap(res->start, size);
|
||||
if (!tsc->tsc_base) {
|
||||
dev_err(&pdev->dev, "Can't map memory\n");
|
||||
error = -ENOMEM;
|
||||
goto err_release_mem;
|
||||
}
|
||||
|
||||
tsc->clk = clk_get(&pdev->dev, NULL);
|
||||
tsc->clk = devm_clk_get(dev, NULL);
|
||||
if (IS_ERR(tsc->clk)) {
|
||||
dev_err(&pdev->dev, "failed getting clock\n");
|
||||
error = PTR_ERR(tsc->clk);
|
||||
goto err_unmap;
|
||||
return PTR_ERR(tsc->clk);
|
||||
}
|
||||
|
||||
input = devm_input_allocate_device(dev);
|
||||
if (!input) {
|
||||
dev_err(&pdev->dev, "failed allocating input device\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
input->name = MOD_NAME;
|
||||
@ -254,68 +236,33 @@ static int lpc32xx_ts_probe(struct platform_device *pdev)
|
||||
input->id.vendor = 0x0001;
|
||||
input->id.product = 0x0002;
|
||||
input->id.version = 0x0100;
|
||||
input->dev.parent = &pdev->dev;
|
||||
input->open = lpc32xx_ts_open;
|
||||
input->close = lpc32xx_ts_close;
|
||||
|
||||
input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
|
||||
input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
|
||||
input_set_capability(input, EV_KEY, BTN_TOUCH);
|
||||
input_set_abs_params(input, ABS_X, LPC32XX_TSC_MIN_XY_VAL,
|
||||
LPC32XX_TSC_MAX_XY_VAL, 0, 0);
|
||||
input_set_abs_params(input, ABS_Y, LPC32XX_TSC_MIN_XY_VAL,
|
||||
LPC32XX_TSC_MAX_XY_VAL, 0, 0);
|
||||
|
||||
input_set_drvdata(input, tsc);
|
||||
tsc->dev = input;
|
||||
|
||||
error = request_irq(tsc->irq, lpc32xx_ts_interrupt,
|
||||
0, pdev->name, tsc);
|
||||
error = devm_request_irq(dev, tsc->irq, lpc32xx_ts_interrupt,
|
||||
0, pdev->name, tsc);
|
||||
if (error) {
|
||||
dev_err(&pdev->dev, "failed requesting interrupt\n");
|
||||
goto err_put_clock;
|
||||
return error;
|
||||
}
|
||||
|
||||
error = input_register_device(input);
|
||||
if (error) {
|
||||
dev_err(&pdev->dev, "failed registering input device\n");
|
||||
goto err_free_irq;
|
||||
return error;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, tsc);
|
||||
device_init_wakeup(&pdev->dev, 1);
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_irq:
|
||||
free_irq(tsc->irq, tsc);
|
||||
err_put_clock:
|
||||
clk_put(tsc->clk);
|
||||
err_unmap:
|
||||
iounmap(tsc->tsc_base);
|
||||
err_release_mem:
|
||||
release_mem_region(res->start, size);
|
||||
err_free_mem:
|
||||
input_free_device(input);
|
||||
kfree(tsc);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int lpc32xx_ts_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct lpc32xx_tsc *tsc = platform_get_drvdata(pdev);
|
||||
struct resource *res;
|
||||
|
||||
free_irq(tsc->irq, tsc);
|
||||
|
||||
input_unregister_device(tsc->dev);
|
||||
|
||||
clk_put(tsc->clk);
|
||||
|
||||
iounmap(tsc->tsc_base);
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
release_mem_region(res->start, resource_size(res));
|
||||
|
||||
kfree(tsc);
|
||||
device_init_wakeup(&pdev->dev, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -384,7 +331,6 @@ MODULE_DEVICE_TABLE(of, lpc32xx_tsc_of_match);
|
||||
|
||||
static struct platform_driver lpc32xx_ts_driver = {
|
||||
.probe = lpc32xx_ts_probe,
|
||||
.remove = lpc32xx_ts_remove,
|
||||
.driver = {
|
||||
.name = MOD_NAME,
|
||||
.pm = LPC32XX_TS_PM_OPS,
|
||||
|
@ -1451,13 +1451,8 @@ static int mip4_probe(struct i2c_client *client)
|
||||
|
||||
ts->gpio_ce = devm_gpiod_get_optional(&client->dev,
|
||||
"ce", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(ts->gpio_ce)) {
|
||||
error = PTR_ERR(ts->gpio_ce);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(&client->dev,
|
||||
"Failed to get gpio: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
if (IS_ERR(ts->gpio_ce))
|
||||
return dev_err_probe(&client->dev, PTR_ERR(ts->gpio_ce), "Failed to get gpio\n");
|
||||
|
||||
error = mip4_power_on(ts);
|
||||
if (error)
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/input/mt.h>
|
||||
#include <linux/input/touchscreen.h>
|
||||
@ -43,6 +42,7 @@
|
||||
/* Touchscreen absolute values */
|
||||
#define MMS114_MAX_AREA 0xff
|
||||
|
||||
#define MMS114_MAX_TOUCHKEYS 15
|
||||
#define MMS114_MAX_TOUCH 10
|
||||
#define MMS114_EVENT_SIZE 8
|
||||
#define MMS136_EVENT_SIZE 6
|
||||
@ -70,6 +70,9 @@ struct mms114_data {
|
||||
unsigned int contact_threshold;
|
||||
unsigned int moving_threshold;
|
||||
|
||||
u32 keycodes[MMS114_MAX_TOUCHKEYS];
|
||||
int num_keycodes;
|
||||
|
||||
/* Use cache data for mode control register(write only) */
|
||||
u8 cache_mode_control;
|
||||
};
|
||||
@ -167,11 +170,6 @@ static void mms114_process_mt(struct mms114_data *data, struct mms114_touch *tou
|
||||
return;
|
||||
}
|
||||
|
||||
if (touch->type != MMS114_TYPE_TOUCHSCREEN) {
|
||||
dev_err(&client->dev, "Wrong touch type (%d)\n", touch->type);
|
||||
return;
|
||||
}
|
||||
|
||||
id = touch->id - 1;
|
||||
x = touch->x_lo | touch->x_hi << 8;
|
||||
y = touch->y_lo | touch->y_hi << 8;
|
||||
@ -191,9 +189,33 @@ static void mms114_process_mt(struct mms114_data *data, struct mms114_touch *tou
|
||||
}
|
||||
}
|
||||
|
||||
static void mms114_process_touchkey(struct mms114_data *data,
|
||||
struct mms114_touch *touch)
|
||||
{
|
||||
struct i2c_client *client = data->client;
|
||||
struct input_dev *input_dev = data->input_dev;
|
||||
unsigned int keycode_id;
|
||||
|
||||
if (touch->id == 0)
|
||||
return;
|
||||
|
||||
if (touch->id > data->num_keycodes) {
|
||||
dev_err(&client->dev, "Wrong touch id for touchkey (%d)\n",
|
||||
touch->id);
|
||||
return;
|
||||
}
|
||||
|
||||
keycode_id = touch->id - 1;
|
||||
dev_dbg(&client->dev, "keycode id: %d, pressed: %d\n", keycode_id,
|
||||
touch->pressed);
|
||||
|
||||
input_report_key(input_dev, data->keycodes[keycode_id], touch->pressed);
|
||||
}
|
||||
|
||||
static irqreturn_t mms114_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct mms114_data *data = dev_id;
|
||||
struct i2c_client *client = data->client;
|
||||
struct input_dev *input_dev = data->input_dev;
|
||||
struct mms114_touch touch[MMS114_MAX_TOUCH];
|
||||
int packet_size;
|
||||
@ -223,8 +245,22 @@ static irqreturn_t mms114_interrupt(int irq, void *dev_id)
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
for (index = 0; index < touch_size; index++)
|
||||
mms114_process_mt(data, touch + index);
|
||||
for (index = 0; index < touch_size; index++) {
|
||||
switch (touch[index].type) {
|
||||
case MMS114_TYPE_TOUCHSCREEN:
|
||||
mms114_process_mt(data, touch + index);
|
||||
break;
|
||||
|
||||
case MMS114_TYPE_TOUCHKEY:
|
||||
mms114_process_touchkey(data, touch + index);
|
||||
break;
|
||||
|
||||
default:
|
||||
dev_err(&client->dev, "Wrong touch type (%d)\n",
|
||||
touch[index].type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
input_mt_report_pointer_emulation(data->input_dev, true);
|
||||
input_sync(data->input_dev);
|
||||
@ -446,6 +482,7 @@ static int mms114_probe(struct i2c_client *client)
|
||||
struct input_dev *input_dev;
|
||||
const void *match_data;
|
||||
int error;
|
||||
int i;
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
|
||||
dev_err(&client->dev, "Not supported I2C adapter\n");
|
||||
@ -469,6 +506,42 @@ static int mms114_probe(struct i2c_client *client)
|
||||
|
||||
data->type = (enum mms_type)match_data;
|
||||
|
||||
data->num_keycodes = device_property_count_u32(&client->dev,
|
||||
"linux,keycodes");
|
||||
if (data->num_keycodes == -EINVAL) {
|
||||
data->num_keycodes = 0;
|
||||
} else if (data->num_keycodes < 0) {
|
||||
dev_err(&client->dev,
|
||||
"Unable to parse linux,keycodes property: %d\n",
|
||||
data->num_keycodes);
|
||||
return data->num_keycodes;
|
||||
} else if (data->num_keycodes > MMS114_MAX_TOUCHKEYS) {
|
||||
dev_warn(&client->dev,
|
||||
"Found %d linux,keycodes but max is %d, ignoring the rest\n",
|
||||
data->num_keycodes, MMS114_MAX_TOUCHKEYS);
|
||||
data->num_keycodes = MMS114_MAX_TOUCHKEYS;
|
||||
}
|
||||
|
||||
if (data->num_keycodes > 0) {
|
||||
error = device_property_read_u32_array(&client->dev,
|
||||
"linux,keycodes",
|
||||
data->keycodes,
|
||||
data->num_keycodes);
|
||||
if (error) {
|
||||
dev_err(&client->dev,
|
||||
"Unable to read linux,keycodes values: %d\n",
|
||||
error);
|
||||
return error;
|
||||
}
|
||||
|
||||
input_dev->keycode = data->keycodes;
|
||||
input_dev->keycodemax = data->num_keycodes;
|
||||
input_dev->keycodesize = sizeof(data->keycodes[0]);
|
||||
for (i = 0; i < data->num_keycodes; i++)
|
||||
input_set_capability(input_dev,
|
||||
EV_KEY, data->keycodes[i]);
|
||||
}
|
||||
|
||||
input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_X);
|
||||
input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_Y);
|
||||
input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 255, 0, 0);
|
||||
|
@ -1,9 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Driver for Novatek i2c touchscreen controller as found on
|
||||
* the Acer Iconia One 7 B1-750 tablet. The Touchscreen controller
|
||||
* model-number is unknown. Android calls this a "NVT-ts" touchscreen,
|
||||
* but that may apply to other Novatek controller models too.
|
||||
* Driver for Novatek NT11205 i2c touchscreen controller as found
|
||||
* on the Acer Iconia One 7 B1-750 tablet.
|
||||
*
|
||||
* Copyright (c) 2023 Hans de Goede <hdegoede@redhat.com>
|
||||
*/
|
||||
@ -272,7 +270,7 @@ static int nvt_ts_probe(struct i2c_client *client)
|
||||
|
||||
error = input_register_device(input);
|
||||
if (error) {
|
||||
dev_err(dev, "failed to request irq: %d\n", error);
|
||||
dev_err(dev, "failed to register input device: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -296,6 +294,6 @@ static struct i2c_driver nvt_ts_driver = {
|
||||
|
||||
module_i2c_driver(nvt_ts_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Novatek NVT-ts touchscreen driver");
|
||||
MODULE_DESCRIPTION("Novatek NT11205 touchscreen driver");
|
||||
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -13,8 +13,8 @@
|
||||
#include <linux/input/mt.h>
|
||||
#include <linux/input/touchscreen.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define PIXCIR_MAX_SLOTS 5 /* Max fingers supported by driver */
|
||||
@ -515,41 +515,27 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client)
|
||||
input_set_drvdata(input, tsdata);
|
||||
|
||||
tsdata->gpio_attb = devm_gpiod_get(dev, "attb", GPIOD_IN);
|
||||
if (IS_ERR(tsdata->gpio_attb)) {
|
||||
error = PTR_ERR(tsdata->gpio_attb);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(dev, "Failed to request ATTB gpio: %d\n",
|
||||
error);
|
||||
return error;
|
||||
}
|
||||
if (IS_ERR(tsdata->gpio_attb))
|
||||
return dev_err_probe(dev, PTR_ERR(tsdata->gpio_attb),
|
||||
"Failed to request ATTB gpio\n");
|
||||
|
||||
tsdata->gpio_reset = devm_gpiod_get_optional(dev, "reset",
|
||||
GPIOD_OUT_LOW);
|
||||
if (IS_ERR(tsdata->gpio_reset)) {
|
||||
error = PTR_ERR(tsdata->gpio_reset);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(dev, "Failed to request RESET gpio: %d\n",
|
||||
error);
|
||||
return error;
|
||||
}
|
||||
if (IS_ERR(tsdata->gpio_reset))
|
||||
return dev_err_probe(dev, PTR_ERR(tsdata->gpio_reset),
|
||||
"Failed to request RESET gpio\n");
|
||||
|
||||
tsdata->gpio_wake = devm_gpiod_get_optional(dev, "wake",
|
||||
GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(tsdata->gpio_wake)) {
|
||||
error = PTR_ERR(tsdata->gpio_wake);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(dev, "Failed to get wake gpio: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
if (IS_ERR(tsdata->gpio_wake))
|
||||
return dev_err_probe(dev, PTR_ERR(tsdata->gpio_wake),
|
||||
"Failed to get wake gpio\n");
|
||||
|
||||
tsdata->gpio_enable = devm_gpiod_get_optional(dev, "enable",
|
||||
GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(tsdata->gpio_enable)) {
|
||||
error = PTR_ERR(tsdata->gpio_enable);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(dev, "Failed to get enable gpio: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
if (IS_ERR(tsdata->gpio_enable))
|
||||
return dev_err_probe(dev, PTR_ERR(tsdata->gpio_enable),
|
||||
"Failed to get enable gpio\n");
|
||||
|
||||
if (tsdata->gpio_enable)
|
||||
msleep(100);
|
||||
|
@ -1087,32 +1087,20 @@ static int raydium_i2c_probe(struct i2c_client *client)
|
||||
i2c_set_clientdata(client, ts);
|
||||
|
||||
ts->avdd = devm_regulator_get(&client->dev, "avdd");
|
||||
if (IS_ERR(ts->avdd)) {
|
||||
error = PTR_ERR(ts->avdd);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(&client->dev,
|
||||
"Failed to get 'avdd' regulator: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
if (IS_ERR(ts->avdd))
|
||||
return dev_err_probe(&client->dev, PTR_ERR(ts->avdd),
|
||||
"Failed to get 'avdd' regulator\n");
|
||||
|
||||
ts->vccio = devm_regulator_get(&client->dev, "vccio");
|
||||
if (IS_ERR(ts->vccio)) {
|
||||
error = PTR_ERR(ts->vccio);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(&client->dev,
|
||||
"Failed to get 'vccio' regulator: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
if (IS_ERR(ts->vccio))
|
||||
return dev_err_probe(&client->dev, PTR_ERR(ts->vccio),
|
||||
"Failed to get 'vccio' regulator\n");
|
||||
|
||||
ts->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset",
|
||||
GPIOD_OUT_LOW);
|
||||
if (IS_ERR(ts->reset_gpio)) {
|
||||
error = PTR_ERR(ts->reset_gpio);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(&client->dev,
|
||||
"failed to get reset gpio: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
if (IS_ERR(ts->reset_gpio))
|
||||
return dev_err_probe(&client->dev, PTR_ERR(ts->reset_gpio),
|
||||
"Failed to get reset gpio\n");
|
||||
|
||||
error = raydium_i2c_power_on(ts);
|
||||
if (error)
|
||||
|
@ -210,12 +210,8 @@ static int grts_probe(struct platform_device *pdev)
|
||||
|
||||
/* get the channels from IIO device */
|
||||
st->iio_chans = devm_iio_channel_get_all(dev);
|
||||
if (IS_ERR(st->iio_chans)) {
|
||||
error = PTR_ERR(st->iio_chans);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(dev, "can't get iio channels.\n");
|
||||
return error;
|
||||
}
|
||||
if (IS_ERR(st->iio_chans))
|
||||
return dev_err_probe(dev, PTR_ERR(st->iio_chans), "can't get iio channels\n");
|
||||
|
||||
if (!device_property_present(dev, "io-channel-names"))
|
||||
return -ENODEV;
|
||||
|
@ -706,11 +706,9 @@ static int silead_ts_probe(struct i2c_client *client)
|
||||
|
||||
/* Power GPIO pin */
|
||||
data->gpio_power = devm_gpiod_get_optional(dev, "power", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(data->gpio_power)) {
|
||||
if (PTR_ERR(data->gpio_power) != -EPROBE_DEFER)
|
||||
dev_err(dev, "Shutdown GPIO request failed\n");
|
||||
return PTR_ERR(data->gpio_power);
|
||||
}
|
||||
if (IS_ERR(data->gpio_power))
|
||||
return dev_err_probe(dev, PTR_ERR(data->gpio_power),
|
||||
"Shutdown GPIO request failed\n");
|
||||
|
||||
error = silead_ts_setup(client);
|
||||
if (error)
|
||||
|
@ -310,23 +310,15 @@ static int sis_ts_probe(struct i2c_client *client)
|
||||
|
||||
ts->attn_gpio = devm_gpiod_get_optional(&client->dev,
|
||||
"attn", GPIOD_IN);
|
||||
if (IS_ERR(ts->attn_gpio)) {
|
||||
error = PTR_ERR(ts->attn_gpio);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(&client->dev,
|
||||
"Failed to get attention GPIO: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
if (IS_ERR(ts->attn_gpio))
|
||||
return dev_err_probe(&client->dev, PTR_ERR(ts->attn_gpio),
|
||||
"Failed to get attention GPIO\n");
|
||||
|
||||
ts->reset_gpio = devm_gpiod_get_optional(&client->dev,
|
||||
"reset", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(ts->reset_gpio)) {
|
||||
error = PTR_ERR(ts->reset_gpio);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(&client->dev,
|
||||
"Failed to get reset GPIO: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
if (IS_ERR(ts->reset_gpio))
|
||||
return dev_err_probe(&client->dev, PTR_ERR(ts->reset_gpio),
|
||||
"Failed to get reset GPIO\n");
|
||||
|
||||
sis_ts_reset(ts);
|
||||
|
||||
|
@ -221,7 +221,6 @@ static void surface3_spi_power(struct surface3_ts_data *data, bool on)
|
||||
*/
|
||||
static int surface3_spi_get_gpio_config(struct surface3_ts_data *data)
|
||||
{
|
||||
int error;
|
||||
struct device *dev;
|
||||
struct gpio_desc *gpiod;
|
||||
int i;
|
||||
@ -231,15 +230,9 @@ static int surface3_spi_get_gpio_config(struct surface3_ts_data *data)
|
||||
/* Get the reset lines GPIO pin number */
|
||||
for (i = 0; i < 2; i++) {
|
||||
gpiod = devm_gpiod_get_index(dev, NULL, i, GPIOD_OUT_LOW);
|
||||
if (IS_ERR(gpiod)) {
|
||||
error = PTR_ERR(gpiod);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(dev,
|
||||
"Failed to get power GPIO %d: %d\n",
|
||||
i,
|
||||
error);
|
||||
return error;
|
||||
}
|
||||
if (IS_ERR(gpiod))
|
||||
return dev_err_probe(dev, PTR_ERR(gpiod),
|
||||
"Failed to get power GPIO %d\n", i);
|
||||
|
||||
data->gpiod_rst[i] = gpiod;
|
||||
}
|
||||
|
@ -323,13 +323,9 @@ static int sx8654_probe(struct i2c_client *client)
|
||||
|
||||
sx8654->gpio_reset = devm_gpiod_get_optional(&client->dev, "reset",
|
||||
GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(sx8654->gpio_reset)) {
|
||||
error = PTR_ERR(sx8654->gpio_reset);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(&client->dev, "unable to get reset-gpio: %d\n",
|
||||
error);
|
||||
return error;
|
||||
}
|
||||
if (IS_ERR(sx8654->gpio_reset))
|
||||
return dev_err_probe(&client->dev, PTR_ERR(sx8654->gpio_reset),
|
||||
"unable to get reset-gpio\n");
|
||||
dev_dbg(&client->dev, "got GPIO reset pin\n");
|
||||
|
||||
sx8654->data = device_get_match_data(&client->dev);
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/sort.h>
|
||||
#include <linux/pm_wakeirq.h>
|
||||
|
||||
|
@ -63,7 +63,7 @@ struct gameport_driver {
|
||||
int gameport_open(struct gameport *gameport, struct gameport_driver *drv, int mode);
|
||||
void gameport_close(struct gameport *gameport);
|
||||
|
||||
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
|
||||
#if IS_REACHABLE(CONFIG_GAMEPORT)
|
||||
|
||||
void __gameport_register_port(struct gameport *gameport, struct module *owner);
|
||||
/* use a define to avoid include chaining to get THIS_MODULE */
|
||||
|
@ -25,7 +25,6 @@ struct tca6416_keys_platform_data {
|
||||
unsigned int rep:1; /* enable input subsystem auto repeat */
|
||||
uint16_t pinmask;
|
||||
uint16_t invert;
|
||||
int irq_is_gpio;
|
||||
int use_polling; /* use polling if Interrupt is not connected*/
|
||||
};
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user