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:
Linus Torvalds 2023-09-06 09:24:25 -07:00
commit 744a759492
80 changed files with 4643 additions and 1055 deletions

View file

@ -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))$":

View file

@ -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>;
};
};
};
};
...

View file

@ -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

View file

@ -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

View file

@ -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:

View file

@ -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,

View file

@ -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);

View file

@ -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;
}

View file

@ -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;

View file

@ -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",
},

View file

@ -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;

View file

@ -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)) {
/*

View file

@ -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)) {
/*

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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,
};

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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,
};

View file

@ -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);

View file

@ -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>

View file

@ -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

View file

@ -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>

View file

@ -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,

View file

@ -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);

View file

@ -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>

View file

@ -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>

View file

@ -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");

View file

@ -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"

View file

@ -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>

View file

@ -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>

View file

@ -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)

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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>

View file

@ -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) {

View file

@ -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;

View file

@ -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>

View file

@ -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"),

View file

@ -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>

View file

@ -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);

View file

@ -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"

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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)

View file

@ -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)

View file

@ -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>

View file

@ -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)) {

View file

@ -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)

View file

@ -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)) {

View file

@ -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,

View file

@ -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 @@ static int goodix_get_gpio_config(struct goodix_ts_data *ts)
/* 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);

View file

@ -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>

View file

@ -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>

File diff suppressed because it is too large Load diff

View file

@ -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,

View file

@ -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)

View file

@ -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);

View file

@ -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");

View file

@ -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);

View file

@ -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)

View file

@ -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;

View file

@ -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)

View file

@ -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);

View file

@ -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;
}

View file

@ -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);

View file

@ -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>

View file

@ -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 */

View file

@ -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