Commit 0f289bdd authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'input-for-v6.8-rc0' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input

Pull input updates from Dmitry Torokhov:

 - a new driver for Adafruit Seesaw gamepad device

 - Zforce touchscreen will handle standard device properties for axis
   swap/inversion

 - handling of advanced sensitivity settings in Microchip CAP11xx
   capacitive sensor driver

 - more drivers have been converted to use newer gpiod API

 - support for dedicated wakeup IRQs in gpio-keys dirver

 - support for slider gestures and OTP variants in iqs269a driver

 - atkbd will report keyboard version as 0xab83 in cases when GET ID
   command was skipped (to deal with problematic firmware on newer
   laptops), restoring the previous behavior

 - other assorted cleanups and changes

* tag 'input-for-v6.8-rc0' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (44 commits)
  Input: atkbd - use ab83 as id when skipping the getid command
  Input: driver for Adafruit Seesaw Gamepad
  dt-bindings: input: bindings for Adafruit Seesaw Gamepad
  Input: da9063_onkey - avoid explicitly setting input's parent
  Input: da9063_onkey - avoid using OF-specific APIs
  Input: iqs269a - add support for OTP variants
  dt-bindings: input: iqs269a: Add bindings for OTP variants
  Input: iqs269a - add support for slider gestures
  dt-bindings: input: iqs269a: Add bindings for slider gestures
  Input: gpio-keys - filter gpio_keys -EPROBE_DEFER error messages
  Input: zforce_ts - accept standard touchscreen properties
  dt-bindings: touchscreen: neonode,zforce: Use standard properties
  dt-bindings: touchscreen: convert neonode,zforce to json-schema
  dt-bindings: input: convert drv266x to json-schema
  Input: da9063 - use dev_err_probe()
  Input: da9063 - drop redundant prints in probe()
  Input: da9063 - simplify obtaining OF match data
  Input: as5011 - convert to GPIO descriptor
  Input: omap-keypad - drop optional GPIO support
  Input: tca6416-keypad - drop unused include
  ...
parents 33a9caa4 58f65f9d
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/input/adafruit,seesaw-gamepad.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Adafruit Mini I2C Gamepad with seesaw
maintainers:
- Anshul Dalal <anshulusr@gmail.com>
description: |
Adafruit Mini I2C Gamepad
+-----------------------------+
| ___ |
| / \ (X) |
| | S | __ __ (Y) (A) |
| \___/ |ST| |SE| (B) |
| |
+-----------------------------+
S -> 10-bit precision bidirectional analog joystick
ST -> Start
SE -> Select
X, A, B, Y -> Digital action buttons
Datasheet: https://cdn-learn.adafruit.com/downloads/pdf/gamepad-qt.pdf
Product page: https://www.adafruit.com/product/5743
Arduino Driver: https://github.com/adafruit/Adafruit_Seesaw
properties:
compatible:
const: adafruit,seesaw-gamepad
reg:
maxItems: 1
interrupts:
maxItems: 1
description:
The gamepad's IRQ pin triggers a rising edge if interrupts are enabled.
required:
- compatible
- reg
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
joystick@50 {
compatible = "adafruit,seesaw-gamepad";
interrupts = <18 IRQ_TYPE_EDGE_RISING>;
reg = <0x50>;
};
};
......@@ -31,7 +31,23 @@ patternProperties:
maxItems: 1
interrupts:
maxItems: 1
oneOf:
- items:
- description: Optional key interrupt or wakeup interrupt
- items:
- description: Key interrupt
- description: Wakeup interrupt
interrupt-names:
description:
Optional interrupt names, can be used to specify a separate dedicated
wake-up interrupt in addition to the gpio irq
oneOf:
- items:
- enum: [ irq, wakeup ]
- items:
- const: irq
- const: wakeup
label:
description: Descriptive name of the key.
......@@ -97,6 +113,20 @@ patternProperties:
- required:
- gpios
allOf:
- if:
properties:
interrupts:
minItems: 2
required:
- interrupts
then:
properties:
interrupt-names:
minItems: 2
required:
- interrupt-names
dependencies:
wakeup-event-action: [ wakeup-source ]
linux,input-value: [ gpios ]
......@@ -137,6 +167,15 @@ examples:
linux,code = <108>;
interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
};
key-wakeup {
label = "GPIO Key WAKEUP";
linux,code = <143>;
interrupts-extended = <&intc 2 IRQ_TYPE_EDGE_FALLING>,
<&intc_wakeup 0 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "irq", "wakeup";
wakeup-source;
};
};
...
Device-Tree bindings for GPIO attached mice
This simply uses standard GPIO handles to define a simple mouse connected
to 5-7 GPIO lines.
Required properties:
- compatible: must be "gpio-mouse"
- scan-interval-ms: The scanning interval in milliseconds
- up-gpios: GPIO line phandle to the line indicating "up"
- down-gpios: GPIO line phandle to the line indicating "down"
- left-gpios: GPIO line phandle to the line indicating "left"
- right-gpios: GPIO line phandle to the line indicating "right"
Optional properties:
- button-left-gpios: GPIO line handle to the left mouse button
- button-middle-gpios: GPIO line handle to the middle mouse button
- button-right-gpios: GPIO line handle to the right mouse button
Example:
#include <dt-bindings/gpio/gpio.h>
gpio-mouse {
compatible = "gpio-mouse";
scan-interval-ms = <50>;
up-gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
down-gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
left-gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
right-gpios = <&gpio0 3 GPIO_ACTIVE_LOW>;
button-left-gpios = <&gpio0 4 GPIO_ACTIVE_LOW>;
button-middle-gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
button-right-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/input/gpio-mouse.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: GPIO attached mouse
description: |
This simply uses standard GPIO handles to define a simple mouse connected
to 5-7 GPIO lines.
maintainers:
- Anshul Dalal <anshulusr@gmail.com>
properties:
compatible:
const: gpio-mouse
scan-interval-ms:
maxItems: 1
up-gpios:
maxItems: 1
down-gpios:
maxItems: 1
left-gpios:
maxItems: 1
right-gpios:
maxItems: 1
button-left-gpios:
maxItems: 1
button-middle-gpios:
maxItems: 1
button-right-gpios:
maxItems: 1
required:
- compatible
- scan-interval-ms
- up-gpios
- down-gpios
- left-gpios
- right-gpios
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
gpio-mouse {
compatible = "gpio-mouse";
scan-interval-ms = <50>;
up-gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
down-gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
left-gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
right-gpios = <&gpio0 3 GPIO_ACTIVE_LOW>;
button-left-gpios = <&gpio0 4 GPIO_ACTIVE_LOW>;
button-middle-gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
button-right-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
};
......@@ -9,6 +9,9 @@ title: Azoteq IQS269A Capacitive Touch Controller
maintainers:
- Jeff LaBundy <jeff@labundy.com>
allOf:
- $ref: input.yaml#
description: |
The Azoteq IQS269A is an 8-channel capacitive touch controller that features
additional Hall-effect and inductive sensing capabilities.
......@@ -17,7 +20,10 @@ description: |
properties:
compatible:
const: azoteq,iqs269a
enum:
- azoteq,iqs269a
- azoteq,iqs269a-00
- azoteq,iqs269a-d0
reg:
maxItems: 1
......@@ -204,6 +210,73 @@ properties:
default: 1
description: Specifies the slider coordinate filter strength.
azoteq,touch-hold-ms:
multipleOf: 256
minimum: 256
maximum: 65280
default: 5120
description:
Specifies the length of time (in ms) for which the channel selected by
'azoteq,gpio3-select' must be held in a state of touch in order for an
approximately 60-ms pulse to be asserted on the GPIO4 pin.
linux,keycodes:
minItems: 1
maxItems: 8
description: |
Specifies the numeric keycodes associated with each available gesture in
the following order (enter 0 for unused gestures):
0: Slider 0 tap
1: Slider 0 hold
2: Slider 0 positive flick or swipe
3: Slider 0 negative flick or swipe
4: Slider 1 tap
5: Slider 1 hold
6: Slider 1 positive flick or swipe
7: Slider 1 negative flick or swipe
azoteq,gesture-swipe:
type: boolean
description:
Directs the device to interpret axial gestures as a swipe (finger remains
on slider) instead of a flick (finger leaves slider).
azoteq,timeout-tap-ms:
multipleOf: 16
minimum: 0
maximum: 4080
default: 400
description:
Specifies the length of time (in ms) within which a slider touch must be
released in order to be interpreted as a tap. Default and maximum values
as well as step size are reduced by a factor of 4 with device version 2.
azoteq,timeout-swipe-ms:
multipleOf: 16
minimum: 0
maximum: 4080
default: 2000
description:
Specifies the length of time (in ms) within which an axial gesture must be
completed in order to be interpreted as a flick or swipe. Default and max-
imum values as well as step size are reduced by a factor of 4 with device
version 2.
azoteq,thresh-swipe:
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 255
default: 128
description:
Specifies the number of points across which an axial gesture must travel
in order to be interpreted as a flick or swipe.
dependencies:
azoteq,gesture-swipe: ["linux,keycodes"]
azoteq,timeout-tap-ms: ["linux,keycodes"]
azoteq,timeout-swipe-ms: ["linux,keycodes"]
azoteq,thresh-swipe: ["linux,keycodes"]
patternProperties:
"^channel@[0-7]$":
type: object
......@@ -454,6 +527,21 @@ patternProperties:
additionalProperties: false
if:
properties:
compatible:
contains:
enum:
- azoteq,iqs269a-d0
then:
patternProperties:
"^channel@[0-7]$":
properties:
azoteq,slider1-select: false
else:
properties:
azoteq,touch-hold-ms: false
required:
- compatible
- reg
......@@ -484,6 +572,14 @@ examples:
azoteq,hall-enable;
azoteq,suspend-mode = <2>;
linux,keycodes = <KEY_PLAYPAUSE>,
<KEY_STOPCD>,
<KEY_NEXTSONG>,
<KEY_PREVIOUSSONG>;
azoteq,timeout-tap-ms = <400>;
azoteq,timeout-swipe-ms = <800>;
channel@0 {
reg = <0x0>;
......
......@@ -90,26 +90,4 @@ required:
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/input/input.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
pmic {
compatible = "mediatek,mt6397";
keys {
compatible = "mediatek,mt6397-keys";
mediatek,long-press-mode = <1>;
power-off-time-sec = <0>;
key-power {
linux,keycodes = <KEY_POWER>;
wakeup-source;
};
key-home {
linux,keycodes = <KEY_VOLUMEDOWN>;
};
};
};
...
......@@ -45,13 +45,13 @@ properties:
Enables the Linux input system's autorepeat feature on the input device.
linux,keycodes:
minItems: 6
maxItems: 6
minItems: 3
maxItems: 8
description: |
Specifies an array of numeric keycode values to
be used for the channels. If this property is
omitted, KEY_A, KEY_B, etc are used as defaults.
The array must have exactly six entries.
The number of entries must correspond to the number of channels.
microchip,sensor-gain:
$ref: /schemas/types.yaml#/definitions/uint32
......@@ -70,6 +70,59 @@ properties:
open drain. This property allows using the active
high push-pull output.
microchip,sensitivity-delta-sense:
$ref: /schemas/types.yaml#/definitions/uint32
default: 32
enum: [1, 2, 4, 8, 16, 32, 64, 128]
description:
Controls the sensitivity multiplier of a touch detection.
Higher value means more sensitive settings.
At the more sensitive settings, touches are detected for a smaller delta
capacitance corresponding to a "lighter" touch.
microchip,signal-guard:
$ref: /schemas/types.yaml#/definitions/uint32-array
minItems: 3
maxItems: 8
items:
enum: [0, 1]
description: |
0 - off
1 - on
The signal guard isolates the signal from virtual grounds.
If enabled then the behavior of the channel is changed to signal guard.
The number of entries must correspond to the number of channels.
microchip,input-threshold:
$ref: /schemas/types.yaml#/definitions/uint32-array
minItems: 3
maxItems: 8
items:
minimum: 0
maximum: 127
description:
Specifies the delta threshold that is used to determine if a touch has
been detected. A higher value means a larger difference in capacitance
is required for a touch to be registered, making the touch sensor less
sensitive.
The number of entries must correspond to the number of channels.
microchip,calib-sensitivity:
$ref: /schemas/types.yaml#/definitions/uint32-array
minItems: 3
maxItems: 8
items:
enum: [1, 2, 4]
description: |
Specifies an array of numeric values that controls the gain
used by the calibration routine to enable sensor inputs
to be more sensitive for proximity detection.
Gain is based on touch pad capacitance range
1 - 5-50pF
2 - 0-25pF
4 - 0-12.5pF
The number of entries must correspond to the number of channels.
patternProperties:
"^led@[0-7]$":
type: object
......@@ -99,10 +152,29 @@ allOf:
contains:
enum:
- microchip,cap1106
- microchip,cap1203
- microchip,cap1206
- microchip,cap1293
- microchip,cap1298
then:
patternProperties:
"^led@[0-7]$": false
- if:
properties:
compatible:
contains:
enum:
- microchip,cap1106
- microchip,cap1126
- microchip,cap1188
- microchip,cap1203
- microchip,cap1206
then:
properties:
microchip,signal-guard: false
microchip,calib-sensitivity: false
required:
- compatible
- interrupts
......@@ -122,6 +194,8 @@ examples:
reg = <0x28>;
autorepeat;
microchip,sensor-gain = <2>;
microchip,sensitivity-delta-sense = <16>;
microchip,input-threshold = <21>, <18>, <46>, <46>, <46>, <21>;
linux,keycodes = <103>, /* KEY_UP */
<106>, /* KEY_RIGHT */
......
......@@ -28,21 +28,4 @@ required:
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
sc2731_pmic: pmic@0 {
compatible = "sprd,sc2731";
reg = <0 0>;
spi-max-frequency = <26000000>;
interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
#interrupt-cells = <2>;
#address-cells = <1>;
#size-cells = <0>;
vibrator@eb4 {
compatible = "sprd,sc2731-vibrator";
reg = <0xeb4>;
};
};
...
* Texas Instruments - drv2665 Haptics driver
Required properties:
- compatible - "ti,drv2665" - DRV2665
- reg - I2C slave address
- vbat-supply - Required supply regulator
Example:
haptics: haptics@59 {
compatible = "ti,drv2665";
reg = <0x59>;
vbat-supply = <&vbat>;
};
For more product information please see the link below:
http://www.ti.com/product/drv2665
* Texas Instruments - drv2667 Haptics driver
Required properties:
- compatible - "ti,drv2667" - DRV2667
- reg - I2C slave address
- vbat-supply - Required supply regulator
Example:
haptics: haptics@59 {
compatible = "ti,drv2667";
reg = <0x59>;
vbat-supply = <&vbat>;
};
For more product information please see the link below:
http://www.ti.com/product/drv2667
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/input/ti,drv266x.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Texas Instruments - drv266x Haptics driver
description: |
Product Page:
http://www.ti.com/product/drv2665
http://www.ti.com/product/drv2667
maintainers:
- Anshul Dalal <anshulusr@gmail.com>
properties:
compatible:
enum:
- ti,drv2665
- ti,drv2667
reg:
maxItems: 1
vbat-supply:
description: Required supply regulator
required:
- compatible
- reg
- vbat-supply
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
haptics@59 {
compatible = "ti,drv2667";
reg = <0x59>;
vbat-supply = <&vbat>;
};
};
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/input/touchscreen/neonode,zforce.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Neonode infrared touchscreen controller
maintainers:
- Heiko Stuebner <heiko@sntech.de>
allOf:
- $ref: touchscreen.yaml#
properties:
compatible:
const: neonode,zforce
reg:
maxItems: 1
interrupts:
maxItems: 1
reset-gpios:
maxItems: 1
irq-gpios:
maxItems: 1
x-size:
deprecated: true
$ref: /schemas/types.yaml#/definitions/uint32
y-size:
deprecated: true
$ref: /schemas/types.yaml#/definitions/uint32
vdd-supply: true
required:
- compatible
- reg
- interrupts
- reset-gpios
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
touchscreen@50 {
compatible = "neonode,zforce";
reg = <0x50>;
interrupts = <2 0>;
vdd-supply = <&reg_zforce_vdd>;
reset-gpios = <&gpio5 9 0>; /* RST */
irq-gpios = <&gpio5 6 0>; /* IRQ, optional */
touchscreen-min-x = <0>;
touchscreen-size-x = <800>;
touchscreen-min-y = <0>;
touchscreen-size-y = <600>;
};
};
...
* Samsung S6SY761 touchscreen controller
Required properties:
- compatible : must be "samsung,s6sy761"
- reg : I2C slave address, (e.g. 0x48)
- interrupts : interrupt specification
- avdd-supply : analogic power supply
- vdd-supply : power supply
Optional properties:
- touchscreen-size-x : see touchscreen.txt. This property is embedded in the
device. If defined it forces a different x resolution.
- touchscreen-size-y : see touchscreen.txt. This property is embedded in the
device. If defined it forces a different y resolution.
Example:
i2c@00000000 {
/* ... */
touchscreen@48 {
compatible = "samsung,s6sy761";
reg = <0x48>;
interrupt-parent = <&gpa1>;
interrupts = <1 IRQ_TYPE_NONE>;
avdd-supply = <&ldo30_reg>;
vdd-supply = <&ldo31_reg>;
touchscreen-size-x = <4096>;
touchscreen-size-y = <4096>;
};
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/input/touchscreen/samsung,s6sy761.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Samsung S6SY761 touchscreen controller
maintainers:
- Andi Shyti <andi.shyti@kernel.org>
allOf:
- $ref: touchscreen.yaml#
properties:
compatible:
const: samsung,s6sy761
reg:
maxItems: 1
interrupts:
maxItems: 1
avdd-supply: true
vdd-supply: true
unevaluatedProperties: false
required:
- compatible
- reg
- interrupts
- avdd-supply
- vdd-supply
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
touchscreen@48 {
compatible = "samsung,s6sy761";
reg = <0x48>;
interrupt-parent = <&gpa1>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH>;
avdd-supply = <&ldo30_reg>;
vdd-supply = <&ldo31_reg>;
touchscreen-size-x = <4096>;
touchscreen-size-y = <4096>;
};
};
* Neonode infrared touchscreen controller
Required properties:
- compatible: must be "neonode,zforce"
- reg: I2C address of the chip
- interrupts: interrupt to which the chip is connected
- reset-gpios: reset gpio the chip is connected to
- x-size: horizontal resolution of touchscreen
- y-size: vertical resolution of touchscreen
Optional properties:
- irq-gpios : interrupt gpio the chip is connected to
- vdd-supply: Regulator controlling the controller supply
Example:
i2c@00000000 {
/* ... */
zforce_ts@50 {
compatible = "neonode,zforce";
reg = <0x50>;
interrupts = <2 0>;
vdd-supply = <&reg_zforce_vdd>;
reset-gpios = <&gpio5 9 0>; /* RST */
irq-gpios = <&gpio5 6 0>; /* IRQ, optional */
x-size = <800>;
y-size = <600>;
};
/* ... */
};
......@@ -441,6 +441,13 @@ W: http://wiki.analog.com/AD7879
W: https://ez.analog.com/linux-software-drivers
F: drivers/input/touchscreen/ad7879.c
ADAFRUIT MINI I2C GAMEPAD
M: Anshul Dalal <anshulusr@gmail.com>
L: linux-input@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/input/adafruit,seesaw-gamepad.yaml
F: drivers/input/joystick/adafruit-seesaw.c
ADDRESS SPACE LAYOUT RANDOMIZATION (ASLR)
M: Jiri Kosina <jikos@kernel.org>
S: Maintained
......
......@@ -1365,8 +1365,8 @@ static ssize_t input_dev_show_##name(struct device *dev, \
{ \
struct input_dev *input_dev = to_input_dev(dev); \
\
return scnprintf(buf, PAGE_SIZE, "%s\n", \
input_dev->name ? input_dev->name : ""); \
return sysfs_emit(buf, "%s\n", \
input_dev->name ? input_dev->name : ""); \
} \
static DEVICE_ATTR(name, S_IRUGO, input_dev_show_##name, NULL)
......@@ -1458,7 +1458,7 @@ static ssize_t inhibited_show(struct device *dev,
{
struct input_dev *input_dev = to_input_dev(dev);
return scnprintf(buf, PAGE_SIZE, "%d\n", input_dev->inhibited);
return sysfs_emit(buf, "%d\n", input_dev->inhibited);
}
static ssize_t inhibited_store(struct device *dev,
......@@ -1505,7 +1505,7 @@ static ssize_t input_dev_show_id_##name(struct device *dev, \
char *buf) \
{ \
struct input_dev *input_dev = to_input_dev(dev); \
return scnprintf(buf, PAGE_SIZE, "%04x\n", input_dev->id.name); \
return sysfs_emit(buf, "%04x\n", input_dev->id.name); \
} \
static DEVICE_ATTR(name, S_IRUGO, input_dev_show_id_##name, NULL)
......
......@@ -412,4 +412,14 @@ config JOYSTICK_SENSEHAT
To compile this driver as a module, choose M here: the
module will be called sensehat_joystick.
config JOYSTICK_SEESAW
tristate "Adafruit Mini I2C Gamepad with Seesaw"
depends on I2C
select INPUT_SPARSEKMAP
help
Say Y here if you want to use the Adafruit Mini I2C Gamepad.
To compile this driver as a module, choose M here: the module will be
called adafruit-seesaw.
endif
......@@ -28,6 +28,7 @@ obj-$(CONFIG_JOYSTICK_N64) += n64joy.o
obj-$(CONFIG_JOYSTICK_PSXPAD_SPI) += psxpad-spi.o
obj-$(CONFIG_JOYSTICK_PXRC) += pxrc.o
obj-$(CONFIG_JOYSTICK_QWIIC) += qwiic-joystick.o
obj-$(CONFIG_JOYSTICK_SEESAW) += adafruit-seesaw.o
obj-$(CONFIG_JOYSTICK_SENSEHAT) += sensehat-joystick.o
obj-$(CONFIG_JOYSTICK_SIDEWINDER) += sidewinder.o
obj-$(CONFIG_JOYSTICK_SPACEBALL) += spaceball.o
......
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2023 Anshul Dalal <anshulusr@gmail.com>
*
* Driver for Adafruit Mini I2C Gamepad
*
* Based on the work of:
* Oleh Kravchenko (Sparkfun Qwiic Joystick driver)
*
* Datasheet: https://cdn-learn.adafruit.com/downloads/pdf/gamepad-qt.pdf
* Product page: https://www.adafruit.com/product/5743
* Firmware and hardware sources: https://github.com/adafruit/Adafruit_Seesaw
*
* TODO:
* - Add interrupt support
*/
#include <asm/unaligned.h>
#include <linux/bits.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/input/sparse-keymap.h>
#include <linux/kernel.h>
#include <linux/module.h>
#define SEESAW_DEVICE_NAME "seesaw-gamepad"
#define SEESAW_ADC_BASE 0x0900
#define SEESAW_GPIO_DIRCLR_BULK 0x0103
#define SEESAW_GPIO_BULK 0x0104
#define SEESAW_GPIO_BULK_SET 0x0105
#define SEESAW_GPIO_PULLENSET 0x010b
#define SEESAW_STATUS_HW_ID 0x0001
#define SEESAW_STATUS_SWRST 0x007f
#define SEESAW_ADC_OFFSET 0x07
#define SEESAW_BUTTON_A 0x05
#define SEESAW_BUTTON_B 0x01
#define SEESAW_BUTTON_X 0x06
#define SEESAW_BUTTON_Y 0x02
#define SEESAW_BUTTON_START 0x10
#define SEESAW_BUTTON_SELECT 0x00
#define SEESAW_ANALOG_X 0x0e
#define SEESAW_ANALOG_Y 0x0f
#define SEESAW_JOYSTICK_MAX_AXIS 1023
#define SEESAW_JOYSTICK_FUZZ 2
#define SEESAW_JOYSTICK_FLAT 4
#define SEESAW_GAMEPAD_POLL_INTERVAL_MS 16
#define SEESAW_GAMEPAD_POLL_MIN 8
#define SEESAW_GAMEPAD_POLL_MAX 32
static const unsigned long SEESAW_BUTTON_MASK =
BIT(SEESAW_BUTTON_A) | BIT(SEESAW_BUTTON_B) | BIT(SEESAW_BUTTON_X) |
BIT(SEESAW_BUTTON_Y) | BIT(SEESAW_BUTTON_START) |
BIT(SEESAW_BUTTON_SELECT);
struct seesaw_gamepad {
struct input_dev *input_dev;
struct i2c_client *i2c_client;
};
struct seesaw_data {
u16 x;
u16 y;
u32 button_state;
};
static const struct key_entry seesaw_buttons_new[] = {
{ KE_KEY, SEESAW_BUTTON_A, .keycode = BTN_SOUTH },
{ KE_KEY, SEESAW_BUTTON_B, .keycode = BTN_EAST },
{ KE_KEY, SEESAW_BUTTON_X, .keycode = BTN_NORTH },
{ KE_KEY, SEESAW_BUTTON_Y, .keycode = BTN_WEST },
{ KE_KEY, SEESAW_BUTTON_START, .keycode = BTN_START },
{ KE_KEY, SEESAW_BUTTON_SELECT, .keycode = BTN_SELECT },
{ KE_END, 0 }
};
static int seesaw_register_read(struct i2c_client *client, u16 reg, void *buf,
int count)
{
__be16 register_buf = cpu_to_be16(reg);
struct i2c_msg message_buf[2] = {
{
.addr = client->addr,
.flags = client->flags,
.len = sizeof(register_buf),
.buf = (u8 *)&register_buf,
},
{
.addr = client->addr,
.flags = client->flags | I2C_M_RD,
.len = count,
.buf = (u8 *)buf,
},
};
int ret;
ret = i2c_transfer(client->adapter, message_buf,
ARRAY_SIZE(message_buf));
if (ret < 0)
return ret;
return 0;
}
static int seesaw_register_write_u8(struct i2c_client *client, u16 reg,
u8 value)
{
u8 write_buf[sizeof(reg) + sizeof(value)];
int ret;
put_unaligned_be16(reg, write_buf);
write_buf[sizeof(reg)] = value;
ret = i2c_master_send(client, write_buf, sizeof(write_buf));
if (ret < 0)
return ret;
return 0;
}
static int seesaw_register_write_u32(struct i2c_client *client, u16 reg,
u32 value)
{
u8 write_buf[sizeof(reg) + sizeof(value)];
int ret;
put_unaligned_be16(reg, write_buf);
put_unaligned_be32(value, write_buf + sizeof(reg));
ret = i2c_master_send(client, write_buf, sizeof(write_buf));
if (ret < 0)
return ret;
return 0;
}
static int seesaw_read_data(struct i2c_client *client, struct seesaw_data *data)
{
__be16 adc_data;
__be32 read_buf;
int err;
err = seesaw_register_read(client, SEESAW_GPIO_BULK,
&read_buf, sizeof(read_buf));
if (err)
return err;
data->button_state = ~be32_to_cpu(read_buf);
err = seesaw_register_read(client,
SEESAW_ADC_BASE |
(SEESAW_ADC_OFFSET + SEESAW_ANALOG_X),
&adc_data, sizeof(adc_data));
if (err)
return err;
/*
* ADC reads left as max and right as 0, must be reversed since kernel
* expects reports in opposite order.
*/
data->x = SEESAW_JOYSTICK_MAX_AXIS - be16_to_cpu(adc_data);
err = seesaw_register_read(client,
SEESAW_ADC_BASE |
(SEESAW_ADC_OFFSET + SEESAW_ANALOG_Y),
&adc_data, sizeof(adc_data));
if (err)
return err;
data->y = be16_to_cpu(adc_data);
return 0;
}
static void seesaw_poll(struct input_dev *input)
{
struct seesaw_gamepad *private = input_get_drvdata(input);
struct seesaw_data data;
int err, i;
err = seesaw_read_data(private->i2c_client, &data);
if (err) {
dev_err_ratelimited(&input->dev,
"failed to read joystick state: %d\n", err);
return;
}
input_report_abs(input, ABS_X, data.x);
input_report_abs(input, ABS_Y, data.y);
for_each_set_bit(i, &SEESAW_BUTTON_MASK,
BITS_PER_TYPE(SEESAW_BUTTON_MASK)) {
if (!sparse_keymap_report_event(input, i,
data.button_state & BIT(i),
false))
dev_err_ratelimited(&input->dev,
"failed to report keymap event");
}
input_sync(input);
}
static int seesaw_probe(struct i2c_client *client)
{
struct seesaw_gamepad *seesaw;
u8 hardware_id;
int err;
err = seesaw_register_write_u8(client, SEESAW_STATUS_SWRST, 0xFF);
if (err)
return err;
/* Wait for the registers to reset before proceeding */
usleep_range(10000, 15000);
seesaw = devm_kzalloc(&client->dev, sizeof(*seesaw), GFP_KERNEL);
if (!seesaw)
return -ENOMEM;
err = seesaw_register_read(client, SEESAW_STATUS_HW_ID,
&hardware_id, sizeof(hardware_id));
if (err)
return err;
dev_dbg(&client->dev, "Adafruit Seesaw Gamepad, Hardware ID: %02x\n",
hardware_id);
/* Set Pin Mode to input and enable pull-up resistors */
err = seesaw_register_write_u32(client, SEESAW_GPIO_DIRCLR_BULK,
SEESAW_BUTTON_MASK);
if (err)
return err;
err = seesaw_register_write_u32(client, SEESAW_GPIO_PULLENSET,
SEESAW_BUTTON_MASK);
if (err)
return err;
err = seesaw_register_write_u32(client, SEESAW_GPIO_BULK_SET,
SEESAW_BUTTON_MASK);
if (err)
return err;
seesaw->i2c_client = client;
seesaw->input_dev = devm_input_allocate_device(&client->dev);
if (!seesaw->input_dev)
return -ENOMEM;
seesaw->input_dev->id.bustype = BUS_I2C;
seesaw->input_dev->name = "Adafruit Seesaw Gamepad";
seesaw->input_dev->phys = "i2c/" SEESAW_DEVICE_NAME;
input_set_drvdata(seesaw->input_dev, seesaw);
input_set_abs_params(seesaw->input_dev, ABS_X,
0, SEESAW_JOYSTICK_MAX_AXIS,
SEESAW_JOYSTICK_FUZZ, SEESAW_JOYSTICK_FLAT);
input_set_abs_params(seesaw->input_dev, ABS_Y,
0, SEESAW_JOYSTICK_MAX_AXIS,
SEESAW_JOYSTICK_FUZZ, SEESAW_JOYSTICK_FLAT);
err = sparse_keymap_setup(seesaw->input_dev, seesaw_buttons_new, NULL);
if (err) {
dev_err(&client->dev,
"failed to set up input device keymap: %d\n", err);
return err;
}
err = input_setup_polling(seesaw->input_dev, seesaw_poll);
if (err) {
dev_err(&client->dev, "failed to set up polling: %d\n", err);
return err;
}
input_set_poll_interval(seesaw->input_dev,
SEESAW_GAMEPAD_POLL_INTERVAL_MS);
input_set_max_poll_interval(seesaw->input_dev, SEESAW_GAMEPAD_POLL_MAX);
input_set_min_poll_interval(seesaw->input_dev, SEESAW_GAMEPAD_POLL_MIN);
err = input_register_device(seesaw->input_dev);
if (err) {
dev_err(&client->dev, "failed to register joystick: %d\n", err);
return err;
}
return 0;
}
static const struct i2c_device_id seesaw_id_table[] = {
{ SEESAW_DEVICE_NAME },
{ /* Sentinel */ }
};
MODULE_DEVICE_TABLE(i2c, seesaw_id_table);
static const struct of_device_id seesaw_of_table[] = {
{ .compatible = "adafruit,seesaw-gamepad"},
{ /* Sentinel */ }
};
MODULE_DEVICE_TABLE(of, seesaw_of_table);
static struct i2c_driver seesaw_driver = {
.driver = {
.name = SEESAW_DEVICE_NAME,
.of_match_table = seesaw_of_table,
},
.id_table = seesaw_id_table,
.probe = seesaw_probe,
};
module_i2c_driver(seesaw_driver);
MODULE_AUTHOR("Anshul Dalal <anshulusr@gmail.com>");
MODULE_DESCRIPTION("Adafruit Mini I2C Gamepad driver");
MODULE_LICENSE("GPL");
......@@ -13,7 +13,7 @@
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/delay.h>
#include <linux/input/as5011.h>
#include <linux/slab.h>
......@@ -61,7 +61,7 @@ MODULE_LICENSE("GPL");
struct as5011_device {
struct input_dev *input_dev;
struct i2c_client *i2c_client;
unsigned int button_gpio;
struct gpio_desc *button_gpiod;
unsigned int button_irq;
unsigned int axis_irq;
};
......@@ -114,7 +114,7 @@ static int as5011_i2c_read(struct i2c_client *client,
static irqreturn_t as5011_button_interrupt(int irq, void *dev_id)
{
struct as5011_device *as5011 = dev_id;
int val = gpio_get_value_cansleep(as5011->button_gpio);
int val = gpiod_get_value_cansleep(as5011->button_gpiod);
input_report_key(as5011->input_dev, BTN_JOYSTICK, !val);
input_sync(as5011->input_dev);
......@@ -248,7 +248,6 @@ static int as5011_probe(struct i2c_client *client)
as5011->i2c_client = client;
as5011->input_dev = input_dev;
as5011->button_gpio = plat_data->button_gpio;
as5011->axis_irq = plat_data->axis_irq;
input_dev->name = "Austria Microsystem as5011 joystick";
......@@ -262,18 +261,20 @@ static int as5011_probe(struct i2c_client *client)
input_set_abs_params(as5011->input_dev, ABS_Y,
AS5011_MIN_AXIS, AS5011_MAX_AXIS, AS5011_FUZZ, AS5011_FLAT);
error = gpio_request(as5011->button_gpio, "AS5011 button");
if (error < 0) {
dev_err(&client->dev, "Failed to request button gpio\n");
as5011->button_gpiod = devm_gpiod_get(&client->dev, NULL, GPIOD_IN);
if (IS_ERR(as5011->button_gpiod)) {
error = PTR_ERR(as5011->button_gpiod);
dev_err(&client->dev, "Failed to request button GPIO\n");
goto err_free_mem;
}
gpiod_set_consumer_name(as5011->button_gpiod, "AS5011 button");
irq = gpio_to_irq(as5011->button_gpio);
irq = gpiod_to_irq(as5011->button_gpiod);
if (irq < 0) {
dev_err(&client->dev,
"Failed to get irq number for button gpio\n");
error = irq;
goto err_free_button_gpio;
goto err_free_mem;
}
as5011->button_irq = irq;
......@@ -286,7 +287,7 @@ static int as5011_probe(struct i2c_client *client)
if (error < 0) {
dev_err(&client->dev,
"Can't allocate button irq %d\n", as5011->button_irq);
goto err_free_button_gpio;
goto err_free_mem;
}
error = as5011_configure_chip(as5011, plat_data);
......@@ -317,8 +318,6 @@ static int as5011_probe(struct i2c_client *client)
free_irq(as5011->axis_irq, as5011);
err_free_button_irq:
free_irq(as5011->button_irq, as5011);
err_free_button_gpio:
gpio_free(as5011->button_gpio);
err_free_mem:
input_free_device(input_dev);
kfree(as5011);
......@@ -332,7 +331,6 @@ static void as5011_remove(struct i2c_client *client)
free_irq(as5011->axis_irq, as5011);
free_irq(as5011->button_irq, as5011);
gpio_free(as5011->button_gpio);
input_unregister_device(as5011->input_dev);
kfree(as5011);
......
......@@ -5,15 +5,17 @@
* Copyright (C) 2018 Marcus Folkesson <marcus.folkesson@gmail.com>
*/
#include <linux/kernel.h>
#include <linux/cleanup.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/input.h>
#include <linux/mutex.h>
#include <linux/input.h>
#define PXRC_VENDOR_ID 0x1781
#define PXRC_PRODUCT_ID 0x0898
......@@ -81,33 +83,28 @@ static void pxrc_usb_irq(struct urb *urb)
static int pxrc_open(struct input_dev *input)
{
struct pxrc *pxrc = input_get_drvdata(input);
int retval;
int error;
mutex_lock(&pxrc->pm_mutex);
retval = usb_submit_urb(pxrc->urb, GFP_KERNEL);
if (retval) {
guard(mutex)(&pxrc->pm_mutex);
error = usb_submit_urb(pxrc->urb, GFP_KERNEL);
if (error) {
dev_err(&pxrc->intf->dev,
"%s - usb_submit_urb failed, error: %d\n",
__func__, retval);
retval = -EIO;
goto out;
__func__, error);
return -EIO;
}
pxrc->is_open = true;
out:
mutex_unlock(&pxrc->pm_mutex);
return retval;
return 0;
}
static void pxrc_close(struct input_dev *input)
{
struct pxrc *pxrc = input_get_drvdata(input);
mutex_lock(&pxrc->pm_mutex);
guard(mutex)(&pxrc->pm_mutex);
usb_kill_urb(pxrc->urb);
pxrc->is_open = false;
mutex_unlock(&pxrc->pm_mutex);
}
static void pxrc_free_urb(void *_pxrc)
......@@ -208,10 +205,9 @@ static int pxrc_suspend(struct usb_interface *intf, pm_message_t message)
{
struct pxrc *pxrc = usb_get_intfdata(intf);
mutex_lock(&pxrc->pm_mutex);
guard(mutex)(&pxrc->pm_mutex);
if (pxrc->is_open)
usb_kill_urb(pxrc->urb);
mutex_unlock(&pxrc->pm_mutex);
return 0;
}
......@@ -219,14 +215,12 @@ static int pxrc_suspend(struct usb_interface *intf, pm_message_t message)
static int pxrc_resume(struct usb_interface *intf)
{
struct pxrc *pxrc = usb_get_intfdata(intf);
int retval = 0;
mutex_lock(&pxrc->pm_mutex);
guard(mutex)(&pxrc->pm_mutex);
if (pxrc->is_open && usb_submit_urb(pxrc->urb, GFP_KERNEL) < 0)
retval = -EIO;
return -EIO;
mutex_unlock(&pxrc->pm_mutex);
return retval;
return 0;
}
static int pxrc_pre_reset(struct usb_interface *intf)
......
......@@ -1670,7 +1670,7 @@ static int xpad_led_probe(struct usb_xpad *xpad)
if (!led)
return -ENOMEM;
xpad->pad_nr = ida_simple_get(&xpad_pad_seq, 0, 0, GFP_KERNEL);
xpad->pad_nr = ida_alloc(&xpad_pad_seq, GFP_KERNEL);
if (xpad->pad_nr < 0) {
error = xpad->pad_nr;
goto err_free_mem;
......@@ -1693,7 +1693,7 @@ static int xpad_led_probe(struct usb_xpad *xpad)
return 0;
err_free_id:
ida_simple_remove(&xpad_pad_seq, xpad->pad_nr);
ida_free(&xpad_pad_seq, xpad->pad_nr);
err_free_mem:
kfree(led);
xpad->led = NULL;
......@@ -1706,7 +1706,7 @@ static void xpad_led_disconnect(struct usb_xpad *xpad)
if (xpad_led) {
led_classdev_unregister(&xpad_led->led_cdev);
ida_simple_remove(&xpad_pad_seq, xpad->pad_nr);
ida_free(&xpad_pad_seq, xpad->pad_nr);
kfree(xpad_led);
}
}
......
......@@ -791,9 +791,9 @@ static bool atkbd_is_portable_device(void)
* not work. So in this case simply assume a keyboard is connected to avoid
* confusing some laptop keyboards.
*
* Skipping ATKBD_CMD_GETID ends up using a fake keyboard id. Using a fake id is
* ok in translated mode, only atkbd_select_set() checks atkbd->id and in
* translated mode that is a no-op.
* Skipping ATKBD_CMD_GETID ends up using a fake keyboard id. Using the standard
* 0xab83 id is ok in translated mode, only atkbd_select_set() checks atkbd->id
* and in translated mode that is a no-op.
*/
static bool atkbd_skip_getid(struct atkbd *atkbd)
{
......@@ -811,6 +811,7 @@ static int atkbd_probe(struct atkbd *atkbd)
{
struct ps2dev *ps2dev = &atkbd->ps2dev;
unsigned char param[2];
bool skip_getid;
/*
* Some systems, where the bit-twiddling when testing the io-lines of the
......@@ -832,7 +833,8 @@ static int atkbd_probe(struct atkbd *atkbd)
*/
param[0] = param[1] = 0xa5; /* initialize with invalid values */
if (atkbd_skip_getid(atkbd) || ps2_command(ps2dev, param, ATKBD_CMD_GETID)) {
skip_getid = atkbd_skip_getid(atkbd);
if (skip_getid || ps2_command(ps2dev, param, ATKBD_CMD_GETID)) {
/*
* If the get ID command was skipped or failed, we check if we can at least set
......@@ -842,7 +844,7 @@ static int atkbd_probe(struct atkbd *atkbd)
param[0] = 0;
if (ps2_command(ps2dev, param, ATKBD_CMD_SETLEDS))
return -1;
atkbd->id = 0xabba;
atkbd->id = skip_getid ? 0xab83 : 0xabba;
return 0;
}
......
This diff is collapsed.
......@@ -45,7 +45,9 @@ struct gpio_button_data {
unsigned int software_debounce; /* in msecs, for GPIO-driven buttons */
unsigned int irq;
unsigned int wakeirq;
unsigned int wakeup_trigger_type;
spinlock_t lock;
bool disabled;
bool key_pressed;
......@@ -511,6 +513,7 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
struct gpio_button_data *bdata = &ddata->data[idx];
irq_handler_t isr;
unsigned long irqflags;
const char *wakedesc;
int irq;
int error;
......@@ -575,15 +578,23 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
!gpiod_cansleep(bdata->gpiod);
}
/*
* If an interrupt was specified, use it instead of the gpio
* interrupt and use the gpio for reading the state. A separate
* interrupt may be used as the main button interrupt for
* runtime PM to detect events also in deeper idle states. If a
* dedicated wakeirq is used for system suspend only, see below
* for bdata->wakeirq setup.
*/
if (button->irq) {
bdata->irq = button->irq;
} else {
irq = gpiod_to_irq(bdata->gpiod);
if (irq < 0) {
error = irq;
dev_err(dev,
"Unable to get irq number for GPIO %d, error %d\n",
button->gpio, error);
dev_err_probe(dev, error,
"Unable to get irq number for GPIO %d\n",
button->gpio);
return error;
}
bdata->irq = irq;
......@@ -672,6 +683,36 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
return error;
}
if (!button->wakeirq)
return 0;
/* Use :wakeup suffix like drivers/base/power/wakeirq.c does */
wakedesc = devm_kasprintf(dev, GFP_KERNEL, "%s:wakeup", desc);
if (!wakedesc)
return -ENOMEM;
bdata->wakeirq = button->wakeirq;
irqflags |= IRQF_NO_SUSPEND;
/*
* Wakeirq shares the handler with the main interrupt, it's only
* active during system suspend. See gpio_keys_button_enable_wakeup()
* and gpio_keys_button_disable_wakeup().
*/
error = devm_request_any_context_irq(dev, bdata->wakeirq, isr,
irqflags, wakedesc, bdata);
if (error < 0) {
dev_err(dev, "Unable to claim wakeirq %d; error %d\n",
bdata->irq, error);
return error;
}
/*
* Disable wakeirq until suspend. IRQF_NO_AUTOEN won't work if
* IRQF_SHARED was set based on !button->can_disable.
*/
disable_irq(bdata->wakeirq);
return 0;
}
......@@ -728,7 +769,7 @@ gpio_keys_get_devtree_pdata(struct device *dev)
struct gpio_keys_platform_data *pdata;
struct gpio_keys_button *button;
struct fwnode_handle *child;
int nbuttons;
int nbuttons, irq;
nbuttons = device_get_child_node_count(dev);
if (nbuttons == 0)
......@@ -750,9 +791,19 @@ gpio_keys_get_devtree_pdata(struct device *dev)
device_property_read_string(dev, "label", &pdata->name);
device_for_each_child_node(dev, child) {
if (is_of_node(child))
button->irq =
irq_of_parse_and_map(to_of_node(child), 0);
if (is_of_node(child)) {
irq = of_irq_get_byname(to_of_node(child), "irq");
if (irq > 0)
button->irq = irq;
irq = of_irq_get_byname(to_of_node(child), "wakeup");
if (irq > 0)
button->wakeirq = irq;
if (!button->irq && !button->wakeirq)
button->irq =
irq_of_parse_and_map(to_of_node(child), 0);
}
if (fwnode_property_read_u32(child, "linux,code",
&button->code)) {
......@@ -921,6 +972,11 @@ gpio_keys_button_enable_wakeup(struct gpio_button_data *bdata)
}
}
if (bdata->wakeirq) {
enable_irq(bdata->wakeirq);
disable_irq(bdata->irq);
}
return 0;
}
......@@ -929,6 +985,11 @@ gpio_keys_button_disable_wakeup(struct gpio_button_data *bdata)
{
int error;
if (bdata->wakeirq) {
enable_irq(bdata->irq);
disable_irq(bdata->wakeirq);
}
/*
* The trigger type is always both edges for gpio-based keys and we do
* not support changing wakeup trigger for interrupt-based keys.
......
......@@ -21,7 +21,6 @@
#include <linux/mutex.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/platform_data/gpio-omap.h>
#include <linux/platform_data/keypad-omap.h>
#include <linux/soc/ti/omap1-io.h>
......@@ -49,9 +48,6 @@ struct omap_kp {
static DECLARE_TASKLET_DISABLED_OLD(kp_tasklet, omap_kp_tasklet);
static unsigned int *row_gpios;
static unsigned int *col_gpios;
static irqreturn_t omap_kp_interrupt(int irq, void *dev_id)
{
/* disable keyboard interrupt and schedule for handling */
......@@ -180,7 +176,7 @@ static int omap_kp_probe(struct platform_device *pdev)
struct omap_kp *omap_kp;
struct input_dev *input_dev;
struct omap_kp_platform_data *pdata = dev_get_platdata(&pdev->dev);
int i, col_idx, row_idx, ret;
int ret;
unsigned int row_shift, keycodemax;
if (!pdata->rows || !pdata->cols || !pdata->keymap_data) {
......@@ -209,17 +205,9 @@ static int omap_kp_probe(struct platform_device *pdev)
if (pdata->delay)
omap_kp->delay = pdata->delay;
if (pdata->row_gpios && pdata->col_gpios) {
row_gpios = pdata->row_gpios;
col_gpios = pdata->col_gpios;
}
omap_kp->rows = pdata->rows;
omap_kp->cols = pdata->cols;
col_idx = 0;
row_idx = 0;
timer_setup(&omap_kp->timer, omap_kp_timer, 0);
/* get the irq and init timer*/
......@@ -276,11 +264,6 @@ static int omap_kp_probe(struct platform_device *pdev)
err3:
device_remove_file(&pdev->dev, &dev_attr_enable);
err2:
for (i = row_idx - 1; i >= 0; i--)
gpio_free(row_gpios[i]);
for (i = col_idx - 1; i >= 0; i--)
gpio_free(col_gpios[i]);
kfree(omap_kp);
input_free_device(input_dev);
......
......@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/errno.h>
#include <linux/io.h>
#include <linux/of.h>
......@@ -83,6 +84,7 @@ struct omap4_keypad {
bool no_autorepeat;
u64 keys;
unsigned short *keymap;
struct clk *fck;
};
static int kbd_readl(struct omap4_keypad *keypad_data, u32 offset)
......@@ -209,6 +211,10 @@ static int omap4_keypad_open(struct input_dev *input)
if (error)
return error;
error = clk_prepare_enable(keypad_data->fck);
if (error)
goto out;
disable_irq(keypad_data->irq);
kbd_writel(keypad_data, OMAP4_KBD_CTRL,
......@@ -226,10 +232,11 @@ static int omap4_keypad_open(struct input_dev *input)
enable_irq(keypad_data->irq);
out:
pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);
return 0;
return error;
}
static void omap4_keypad_stop(struct omap4_keypad *keypad_data)
......@@ -258,6 +265,7 @@ static void omap4_keypad_close(struct input_dev *input)
disable_irq(keypad_data->irq);
omap4_keypad_stop(keypad_data);
enable_irq(keypad_data->irq);
clk_disable_unprepare(keypad_data->fck);
pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);
......@@ -356,6 +364,11 @@ static int omap4_keypad_probe(struct platform_device *pdev)
}
keypad_data->irq = irq;
keypad_data->fck = devm_clk_get(&pdev->dev, "fck");
if (IS_ERR(keypad_data->fck))
return dev_err_probe(&pdev->dev, PTR_ERR(keypad_data->fck),
"unable to get fck");
mutex_init(&keypad_data->lock);
platform_set_drvdata(pdev, keypad_data);
......
......@@ -213,7 +213,7 @@ static struct regmap_config qt1050_regmap_config = {
.val_bits = 8,
.max_register = QT1050_RES_CAL,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.wr_table = &qt1050_writeable_table,
.rd_table = &qt1050_readable_table,
......
......@@ -14,7 +14,6 @@
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/tca6416_keypad.h>
......
......@@ -9,11 +9,12 @@
#include <linux/errno.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include <linux/pm_wakeirq.h>
#include <linux/property.h>
#include <linux/workqueue.h>
#include <linux/regmap.h>
#include <linux/of.h>
#include <linux/mfd/da9063/core.h>
#include <linux/mfd/da9063/registers.h>
#include <linux/mfd/da9062/core.h>
......@@ -74,13 +75,6 @@ static const struct da906x_chip_config da9062_regs = {
.name = "da9062-onkey",
};
static const struct of_device_id da9063_compatible_reg_id_table[] = {
{ .compatible = "dlg,da9063-onkey", .data = &da9063_regs },
{ .compatible = "dlg,da9062-onkey", .data = &da9062_regs },
{ },
};
MODULE_DEVICE_TABLE(of, da9063_compatible_reg_id_table);
static void da9063_poll_on(struct work_struct *work)
{
struct da9063_onkey *onkey = container_of(work,
......@@ -187,56 +181,43 @@ static irqreturn_t da9063_onkey_irq_handler(int irq, void *data)
static int da9063_onkey_probe(struct platform_device *pdev)
{
struct da9063_onkey *onkey;
const struct of_device_id *match;
int irq;
int error;
match = of_match_node(da9063_compatible_reg_id_table,
pdev->dev.of_node);
if (!match)
return -ENXIO;
int irq;
onkey = devm_kzalloc(&pdev->dev, sizeof(struct da9063_onkey),
GFP_KERNEL);
if (!onkey) {
dev_err(&pdev->dev, "Failed to allocate memory.\n");
if (!onkey)
return -ENOMEM;
}
onkey->config = match->data;
onkey->config = device_get_match_data(&pdev->dev);
if (!onkey->config)
return -ENXIO;
onkey->dev = &pdev->dev;
onkey->regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!onkey->regmap) {
dev_err(&pdev->dev, "Parent regmap unavailable.\n");
return -ENXIO;
}
if (!onkey->regmap)
return dev_err_probe(&pdev->dev, -ENXIO,
"Parent regmap unavailable.\n");
onkey->key_power = !of_property_read_bool(pdev->dev.of_node,
"dlg,disable-key-power");
onkey->key_power = !device_property_read_bool(&pdev->dev,
"dlg,disable-key-power");
onkey->input = devm_input_allocate_device(&pdev->dev);
if (!onkey->input) {
dev_err(&pdev->dev, "Failed to allocated input device.\n");
if (!onkey->input)
return -ENOMEM;
}
onkey->input->name = onkey->config->name;
snprintf(onkey->phys, sizeof(onkey->phys), "%s/input0",
onkey->config->name);
onkey->input->phys = onkey->phys;
onkey->input->dev.parent = &pdev->dev;
input_set_capability(onkey->input, EV_KEY, KEY_POWER);
error = devm_delayed_work_autocancel(&pdev->dev, &onkey->work,
da9063_poll_on);
if (error) {
dev_err(&pdev->dev,
"Failed to add cancel poll action: %d\n",
error);
if (error)
return error;
}
irq = platform_get_irq_byname(pdev, "ONKEY");
if (irq < 0)
......@@ -246,11 +227,9 @@ static int da9063_onkey_probe(struct platform_device *pdev)
NULL, da9063_onkey_irq_handler,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
"ONKEY", onkey);
if (error) {
dev_err(&pdev->dev,
"Failed to request IRQ %d: %d\n", irq, error);
return error;
}
if (error)
return dev_err_probe(&pdev->dev, error,
"Failed to allocate onkey IRQ\n");
error = dev_pm_set_wake_irq(&pdev->dev, irq);
if (error)
......@@ -261,15 +240,19 @@ static int da9063_onkey_probe(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, true);
error = input_register_device(onkey->input);
if (error) {
dev_err(&pdev->dev,
"Failed to register input device: %d\n", error);
if (error)
return error;
}
return 0;
}
static const struct of_device_id da9063_compatible_reg_id_table[] = {
{ .compatible = "dlg,da9063-onkey", .data = &da9063_regs },
{ .compatible = "dlg,da9062-onkey", .data = &da9062_regs },
{ }
};
MODULE_DEVICE_TABLE(of, da9063_compatible_reg_id_table);
static struct platform_driver da9063_onkey_driver = {
.probe = da9063_onkey_probe,
.driver = {
......
......@@ -1050,7 +1050,7 @@ static ssize_t ims_pcu_attribute_show(struct device *dev,
container_of(dattr, struct ims_pcu_attribute, dattr);
char *field = (char *)pcu + attr->field_offset;
return scnprintf(buf, PAGE_SIZE, "%.*s\n", attr->field_length, field);
return sysfs_emit(buf, "%.*s\n", attr->field_length, field);
}
static ssize_t ims_pcu_attribute_store(struct device *dev,
......@@ -1206,7 +1206,7 @@ ims_pcu_update_firmware_status_show(struct device *dev,
struct usb_interface *intf = to_usb_interface(dev);
struct ims_pcu *pcu = usb_get_intfdata(intf);
return scnprintf(buf, PAGE_SIZE, "%d\n", pcu->update_firmware_status);
return sysfs_emit(buf, "%d\n", pcu->update_firmware_status);
}
static DEVICE_ATTR(update_firmware_status, S_IRUGO,
......@@ -1309,7 +1309,7 @@ static ssize_t ims_pcu_ofn_reg_data_show(struct device *dev,
if (error)
return error;
return scnprintf(buf, PAGE_SIZE, "%x\n", data);
return sysfs_emit(buf, "%x\n", data);
}
static ssize_t ims_pcu_ofn_reg_data_store(struct device *dev,
......@@ -1344,7 +1344,7 @@ static ssize_t ims_pcu_ofn_reg_addr_show(struct device *dev,
int error;
mutex_lock(&pcu->cmd_mutex);
error = scnprintf(buf, PAGE_SIZE, "%x\n", pcu->ofn_reg_addr);
error = sysfs_emit(buf, "%x\n", pcu->ofn_reg_addr);
mutex_unlock(&pcu->cmd_mutex);
return error;
......@@ -1397,7 +1397,7 @@ static ssize_t ims_pcu_ofn_bit_show(struct device *dev,
if (error)
return error;
return scnprintf(buf, PAGE_SIZE, "%d\n", !!(data & (1 << attr->nr)));
return sysfs_emit(buf, "%d\n", !!(data & (1 << attr->nr)));
}
static ssize_t ims_pcu_ofn_bit_store(struct device *dev,
......
This diff is collapsed.
......@@ -307,7 +307,7 @@ static int max77693_haptic_probe(struct platform_device *pdev)
haptic->suspend_state = false;
/* Variant-specific init */
haptic->dev_type = platform_get_device_id(pdev)->driver_data;
haptic->dev_type = max77693->type;
switch (haptic->dev_type) {
case TYPE_MAX77693:
haptic->regmap_haptic = max77693->regmap_haptic;
......@@ -406,16 +406,24 @@ static DEFINE_SIMPLE_DEV_PM_OPS(max77693_haptic_pm_ops,
max77693_haptic_resume);
static const struct platform_device_id max77693_haptic_id[] = {
{ "max77693-haptic", TYPE_MAX77693 },
{ "max77843-haptic", TYPE_MAX77843 },
{ "max77693-haptic", },
{ "max77843-haptic", },
{},
};
MODULE_DEVICE_TABLE(platform, max77693_haptic_id);
static const struct of_device_id of_max77693_haptic_dt_match[] = {
{ .compatible = "maxim,max77693-haptic", },
{ .compatible = "maxim,max77843-haptic", },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, of_max77693_haptic_dt_match);
static struct platform_driver max77693_haptic_driver = {
.driver = {
.name = "max77693-haptic",
.pm = pm_sleep_ptr(&max77693_haptic_pm_ops),
.of_match_table = of_max77693_haptic_dt_match,
},
.probe = max77693_haptic_probe,
.id_table = max77693_haptic_id,
......
......@@ -756,16 +756,16 @@ static ssize_t cyapa_show_suspend_scanrate(struct device *dev,
switch (pwr_cmd) {
case PWR_MODE_BTN_ONLY:
len = scnprintf(buf, PAGE_SIZE, "%s\n", BTN_ONLY_MODE_NAME);
len = sysfs_emit(buf, "%s\n", BTN_ONLY_MODE_NAME);
break;
case PWR_MODE_OFF:
len = scnprintf(buf, PAGE_SIZE, "%s\n", OFF_MODE_NAME);
len = sysfs_emit(buf, "%s\n", OFF_MODE_NAME);
break;
default:
len = scnprintf(buf, PAGE_SIZE, "%u\n",
cyapa->gen == CYAPA_GEN3 ?
len = sysfs_emit(buf, "%u\n",
cyapa->gen == CYAPA_GEN3 ?
cyapa_pwr_cmd_to_sleep_time(pwr_cmd) :
sleep_time);
break;
......@@ -877,8 +877,8 @@ static ssize_t cyapa_show_rt_suspend_scanrate(struct device *dev,
mutex_unlock(&cyapa->state_sync_lock);
return scnprintf(buf, PAGE_SIZE, "%u\n",
cyapa->gen == CYAPA_GEN3 ?
return sysfs_emit(buf, "%u\n",
cyapa->gen == CYAPA_GEN3 ?
cyapa_pwr_cmd_to_sleep_time(pwr_cmd) :
sleep_time);
}
......@@ -988,8 +988,8 @@ static ssize_t cyapa_show_fm_ver(struct device *dev,
error = mutex_lock_interruptible(&cyapa->state_sync_lock);
if (error)
return error;
error = scnprintf(buf, PAGE_SIZE, "%d.%d\n", cyapa->fw_maj_ver,
cyapa->fw_min_ver);
error = sysfs_emit(buf, "%d.%d\n",
cyapa->fw_maj_ver, cyapa->fw_min_ver);
mutex_unlock(&cyapa->state_sync_lock);
return error;
}
......@@ -1004,7 +1004,7 @@ static ssize_t cyapa_show_product_id(struct device *dev,
error = mutex_lock_interruptible(&cyapa->state_sync_lock);
if (error)
return error;
size = scnprintf(buf, PAGE_SIZE, "%s\n", cyapa->product_id);
size = sysfs_emit(buf, "%s\n", cyapa->product_id);
mutex_unlock(&cyapa->state_sync_lock);
return size;
}
......@@ -1209,8 +1209,8 @@ static ssize_t cyapa_show_mode(struct device *dev,
if (error)
return error;
size = scnprintf(buf, PAGE_SIZE, "gen%d %s\n",
cyapa->gen, cyapa_state_to_string(cyapa));
size = sysfs_emit(buf, "gen%d %s\n",
cyapa->gen, cyapa_state_to_string(cyapa));
mutex_unlock(&cyapa->state_sync_lock);
return size;
......
......@@ -860,7 +860,7 @@ static ssize_t cyapa_gen3_show_baseline(struct device *dev,
dev_dbg(dev, "Baseline report successful. Max: %d Min: %d\n",
max_baseline, min_baseline);
ret = scnprintf(buf, PAGE_SIZE, "%d %d\n", max_baseline, min_baseline);
ret = sysfs_emit(buf, "%d %d\n", max_baseline, min_baseline);
out:
return ret;
......
......@@ -2418,12 +2418,12 @@ static ssize_t cyapa_gen5_show_baseline(struct device *dev,
return resume_error ? resume_error : error;
/* 12. Output data strings */
size = scnprintf(buf, PAGE_SIZE, "%d %d %d %d %d %d %d %d %d %d %d ",
size = sysfs_emit(buf, "%d %d %d %d %d %d %d %d %d %d %d ",
gidac_mutual_min, gidac_mutual_max, gidac_mutual_ave,
lidac_mutual_min, lidac_mutual_max, lidac_mutual_ave,
gidac_self_rx, gidac_self_tx,
lidac_self_min, lidac_self_max, lidac_self_ave);
size += scnprintf(buf + size, PAGE_SIZE - size,
size += sysfs_emit_at(buf, size,
"%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
raw_cap_mutual_min, raw_cap_mutual_max, raw_cap_mutual_ave,
raw_cap_self_min, raw_cap_self_max, raw_cap_self_ave,
......
......@@ -629,14 +629,14 @@ static ssize_t cyapa_gen6_show_baseline(struct device *dev,
if (error)
goto resume_scanning;
size = scnprintf(buf, PAGE_SIZE, "%d %d %d %d %d %d ",
data[0], /* RX Attenuator Mutual */
data[1], /* IDAC Mutual */
data[2], /* RX Attenuator Self RX */
data[3], /* IDAC Self RX */
data[4], /* RX Attenuator Self TX */
data[5] /* IDAC Self TX */
);
size = sysfs_emit(buf, "%d %d %d %d %d %d ",
data[0], /* RX Attenuator Mutual */
data[1], /* IDAC Mutual */
data[2], /* RX Attenuator Self RX */
data[3], /* IDAC Self RX */
data[4], /* RX Attenuator Self TX */
data[5] /* IDAC Self TX */
);
/* 3. Read Attenuator Trim. */
data_len = sizeof(data);
......@@ -648,8 +648,8 @@ static ssize_t cyapa_gen6_show_baseline(struct device *dev,
/* set attenuator trim values. */
for (i = 0; i < data_len; i++)
size += scnprintf(buf + size, PAGE_SIZE - size, "%d ", data[i]);
size += scnprintf(buf + size, PAGE_SIZE - size, "\n");
size += sysfs_emit_at(buf, size, "%d ", data[i]);
size += sysfs_emit_at(buf, size, "\n");
resume_scanning:
/* 4. Resume Scanning*/
......
......@@ -572,7 +572,7 @@ static ssize_t elan_sysfs_read_fw_checksum(struct device *dev,
struct i2c_client *client = to_i2c_client(dev);
struct elan_tp_data *data = i2c_get_clientdata(client);
return sprintf(buf, "0x%04x\n", data->fw_checksum);
return sysfs_emit(buf, "0x%04x\n", data->fw_checksum);
}
static ssize_t elan_sysfs_read_product_id(struct device *dev,
......@@ -582,8 +582,8 @@ static ssize_t elan_sysfs_read_product_id(struct device *dev,
struct i2c_client *client = to_i2c_client(dev);
struct elan_tp_data *data = i2c_get_clientdata(client);
return sprintf(buf, ETP_PRODUCT_ID_FORMAT_STRING "\n",
data->product_id);
return sysfs_emit(buf, ETP_PRODUCT_ID_FORMAT_STRING "\n",
data->product_id);
}
static ssize_t elan_sysfs_read_fw_ver(struct device *dev,
......@@ -593,7 +593,7 @@ static ssize_t elan_sysfs_read_fw_ver(struct device *dev,
struct i2c_client *client = to_i2c_client(dev);
struct elan_tp_data *data = i2c_get_clientdata(client);
return sprintf(buf, "%d.0\n", data->fw_version);
return sysfs_emit(buf, "%d.0\n", data->fw_version);
}
static ssize_t elan_sysfs_read_sm_ver(struct device *dev,
......@@ -603,7 +603,7 @@ static ssize_t elan_sysfs_read_sm_ver(struct device *dev,
struct i2c_client *client = to_i2c_client(dev);
struct elan_tp_data *data = i2c_get_clientdata(client);
return sprintf(buf, "%d.0\n", data->sm_version);
return sysfs_emit(buf, "%d.0\n", data->sm_version);
}
static ssize_t elan_sysfs_read_iap_ver(struct device *dev,
......@@ -613,7 +613,7 @@ static ssize_t elan_sysfs_read_iap_ver(struct device *dev,
struct i2c_client *client = to_i2c_client(dev);
struct elan_tp_data *data = i2c_get_clientdata(client);
return sprintf(buf, "%d.0\n", data->iap_version);
return sysfs_emit(buf, "%d.0\n", data->iap_version);
}
static ssize_t elan_sysfs_update_fw(struct device *dev,
......@@ -754,7 +754,7 @@ static ssize_t elan_sysfs_read_mode(struct device *dev,
if (error)
return error;
return sprintf(buf, "%d\n", (int)mode);
return sysfs_emit(buf, "%d\n", (int)mode);
}
static DEVICE_ATTR(product_id, S_IRUGO, elan_sysfs_read_product_id, NULL);
......@@ -858,7 +858,7 @@ static ssize_t min_show(struct device *dev,
goto out;
}
retval = snprintf(buf, PAGE_SIZE, "%d", data->min_baseline);
retval = sysfs_emit(buf, "%d", data->min_baseline);
out:
mutex_unlock(&data->sysfs_mutex);
......@@ -881,7 +881,7 @@ static ssize_t max_show(struct device *dev,
goto out;
}
retval = snprintf(buf, PAGE_SIZE, "%d", data->max_baseline);
retval = sysfs_emit(buf, "%d", data->max_baseline);
out:
mutex_unlock(&data->sysfs_mutex);
......
......@@ -10,7 +10,7 @@
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/input.h>
#include <linux/input/navpoint.h>
#include <linux/interrupt.h>
......@@ -32,7 +32,7 @@ struct navpoint {
struct ssp_device *ssp;
struct input_dev *input;
struct device *dev;
int gpio;
struct gpio_desc *gpiod;
int index;
u8 data[1 + HEADER_LENGTH(0xff)];
};
......@@ -170,16 +170,14 @@ static void navpoint_up(struct navpoint *navpoint)
dev_err(navpoint->dev,
"timeout waiting for SSSR[CSS] to clear\n");
if (gpio_is_valid(navpoint->gpio))
gpio_set_value(navpoint->gpio, 1);
gpiod_set_value(navpoint->gpiod, 1);
}
static void navpoint_down(struct navpoint *navpoint)
{
struct ssp_device *ssp = navpoint->ssp;
if (gpio_is_valid(navpoint->gpio))
gpio_set_value(navpoint->gpio, 0);
gpiod_set_value(navpoint->gpiod, 0);
pxa_ssp_write_reg(ssp, SSCR0, 0);
......@@ -216,18 +214,9 @@ static int navpoint_probe(struct platform_device *pdev)
return -EINVAL;
}
if (gpio_is_valid(pdata->gpio)) {
error = gpio_request_one(pdata->gpio, GPIOF_OUT_INIT_LOW,
"SYNAPTICS_ON");
if (error)
return error;
}
ssp = pxa_ssp_request(pdata->port, pdev->name);
if (!ssp) {
error = -ENODEV;
goto err_free_gpio;
}
if (!ssp)
return -ENODEV;
/* HaRET does not disable devices before jumping into Linux */
if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) {
......@@ -242,10 +231,18 @@ static int navpoint_probe(struct platform_device *pdev)
goto err_free_mem;
}
navpoint->gpiod = gpiod_get_optional(&pdev->dev,
NULL, GPIOD_OUT_LOW);
if (IS_ERR(navpoint->gpiod)) {
error = PTR_ERR(navpoint->gpiod);
dev_err(&pdev->dev, "error getting GPIO\n");
goto err_free_mem;
}
gpiod_set_consumer_name(navpoint->gpiod, "SYNAPTICS_ON");
navpoint->ssp = ssp;
navpoint->input = input;
navpoint->dev = &pdev->dev;
navpoint->gpio = pdata->gpio;
input->name = pdev->name;
input->dev.parent = &pdev->dev;
......@@ -288,17 +285,12 @@ static int navpoint_probe(struct platform_device *pdev)
input_free_device(input);
kfree(navpoint);
pxa_ssp_free(ssp);
err_free_gpio:
if (gpio_is_valid(pdata->gpio))
gpio_free(pdata->gpio);
return error;
}
static void navpoint_remove(struct platform_device *pdev)
{
const struct navpoint_platform_data *pdata =
dev_get_platdata(&pdev->dev);
struct navpoint *navpoint = platform_get_drvdata(pdev);
struct ssp_device *ssp = navpoint->ssp;
......@@ -308,9 +300,6 @@ static void navpoint_remove(struct platform_device *pdev)
kfree(navpoint);
pxa_ssp_free(ssp);
if (gpio_is_valid(pdata->gpio))
gpio_free(pdata->gpio);
}
static int navpoint_suspend(struct device *dev)
......
......@@ -267,8 +267,7 @@ static ssize_t rmi_driver_manufacturer_id_show(struct device *dev,
struct rmi_driver_data *data = dev_get_drvdata(dev);
struct f01_data *f01 = dev_get_drvdata(&data->f01_container->dev);
return scnprintf(buf, PAGE_SIZE, "%d\n",
f01->properties.manufacturer_id);
return sysfs_emit(buf, "%d\n", f01->properties.manufacturer_id);
}
static DEVICE_ATTR(manufacturer_id, 0444,
......@@ -280,7 +279,7 @@ static ssize_t rmi_driver_dom_show(struct device *dev,
struct rmi_driver_data *data = dev_get_drvdata(dev);
struct f01_data *f01 = dev_get_drvdata(&data->f01_container->dev);
return scnprintf(buf, PAGE_SIZE, "%s\n", f01->properties.dom);
return sysfs_emit(buf, "%s\n", f01->properties.dom);
}
static DEVICE_ATTR(date_of_manufacture, 0444, rmi_driver_dom_show, NULL);
......@@ -292,7 +291,7 @@ static ssize_t rmi_driver_product_id_show(struct device *dev,
struct rmi_driver_data *data = dev_get_drvdata(dev);
struct f01_data *f01 = dev_get_drvdata(&data->f01_container->dev);
return scnprintf(buf, PAGE_SIZE, "%s\n", f01->properties.product_id);
return sysfs_emit(buf, "%s\n", f01->properties.product_id);
}
static DEVICE_ATTR(product_id, 0444, rmi_driver_product_id_show, NULL);
......@@ -304,7 +303,7 @@ static ssize_t rmi_driver_firmware_id_show(struct device *dev,
struct rmi_driver_data *data = dev_get_drvdata(dev);
struct f01_data *f01 = dev_get_drvdata(&data->f01_container->dev);
return scnprintf(buf, PAGE_SIZE, "%d\n", f01->properties.firmware_id);
return sysfs_emit(buf, "%d\n", f01->properties.firmware_id);
}
static DEVICE_ATTR(firmware_id, 0444, rmi_driver_firmware_id_show, NULL);
......@@ -318,8 +317,8 @@ static ssize_t rmi_driver_package_id_show(struct device *dev,
u32 package_id = f01->properties.package_id;
return scnprintf(buf, PAGE_SIZE, "%04x.%04x\n",
package_id & 0xffff, (package_id >> 16) & 0xffff);
return sysfs_emit(buf, "%04x.%04x\n",
package_id & 0xffff, (package_id >> 16) & 0xffff);
}
static DEVICE_ATTR(package_id, 0444, rmi_driver_package_id_show, NULL);
......
......@@ -2818,8 +2818,8 @@ static ssize_t mxt_fw_version_show(struct device *dev,
{
struct mxt_data *data = dev_get_drvdata(dev);
struct mxt_info *info = data->info;
return scnprintf(buf, PAGE_SIZE, "%u.%u.%02X\n",
info->version >> 4, info->version & 0xf, info->build);
return sysfs_emit(buf, "%u.%u.%02X\n",
info->version >> 4, info->version & 0xf, info->build);
}
/* Hardware Version is returned as FamilyID.VariantID */
......@@ -2828,8 +2828,7 @@ static ssize_t mxt_hw_version_show(struct device *dev,
{
struct mxt_data *data = dev_get_drvdata(dev);
struct mxt_info *info = data->info;
return scnprintf(buf, PAGE_SIZE, "%u.%u\n",
info->family_id, info->variant_id);
return sysfs_emit(buf, "%u.%u\n", info->family_id, info->variant_id);
}
static ssize_t mxt_show_instance(char *buf, int count,
......@@ -2839,19 +2838,18 @@ static ssize_t mxt_show_instance(char *buf, int count,
int i;
if (mxt_obj_instances(object) > 1)
count += scnprintf(buf + count, PAGE_SIZE - count,
"Instance %u\n", instance);
count += sysfs_emit_at(buf, count, "Instance %u\n", instance);
for (i = 0; i < mxt_obj_size(object); i++)
count += scnprintf(buf + count, PAGE_SIZE - count,
"\t[%2u]: %02x (%d)\n", i, val[i], val[i]);
count += scnprintf(buf + count, PAGE_SIZE - count, "\n");
count += sysfs_emit_at(buf, count, "\t[%2u]: %02x (%d)\n",
i, val[i], val[i]);
count += sysfs_emit_at(buf, count, "\n");
return count;
}
static ssize_t mxt_object_show(struct device *dev,
struct device_attribute *attr, char *buf)
struct device_attribute *attr, char *buf)
{
struct mxt_data *data = dev_get_drvdata(dev);
struct mxt_object *object;
......@@ -2872,8 +2870,7 @@ static ssize_t mxt_object_show(struct device *dev,
if (!mxt_object_readable(object->type))
continue;
count += scnprintf(buf + count, PAGE_SIZE - count,
"T%u:\n", object->type);
count += sysfs_emit_at(buf, count, "T%u:\n", object->type);
for (j = 0; j < mxt_obj_instances(object); j++) {
u16 size = mxt_obj_size(object);
......
......@@ -431,7 +431,7 @@ static ssize_t edt_ft5x06_setting_show(struct device *dev,
*field = val;
}
count = scnprintf(buf, PAGE_SIZE, "%d\n", val);
count = sysfs_emit(buf, "%d\n", val);
out:
mutex_unlock(&tsdata->mutex);
return error ?: count;
......
......@@ -928,8 +928,7 @@ static ssize_t hideep_fw_version_show(struct device *dev,
ssize_t len;
mutex_lock(&ts->dev_mutex);
len = scnprintf(buf, PAGE_SIZE, "%04x\n",
be16_to_cpu(ts->dwz_info.release_ver));
len = sysfs_emit(buf, "%04x\n", be16_to_cpu(ts->dwz_info.release_ver));
mutex_unlock(&ts->dev_mutex);
return len;
......@@ -943,8 +942,7 @@ static ssize_t hideep_product_id_show(struct device *dev,
ssize_t len;
mutex_lock(&ts->dev_mutex);
len = scnprintf(buf, PAGE_SIZE, "%04x\n",
be16_to_cpu(ts->dwz_info.product_id));
len = sysfs_emit(buf, "%04x\n", be16_to_cpu(ts->dwz_info.product_id));
mutex_unlock(&ts->dev_mutex);
return len;
......
......@@ -202,7 +202,7 @@ static ssize_t hycon_hy46xx_setting_show(struct device *dev,
*field = val;
}
count = scnprintf(buf, PAGE_SIZE, "%d\n", val);
count = sysfs_emit(buf, "%d\n", val);
out:
mutex_unlock(&tsdata->mutex);
......
......@@ -512,12 +512,12 @@ static ssize_t firmware_version_show(struct device *dev,
struct i2c_client *client = to_i2c_client(dev);
struct ilitek_ts_data *ts = i2c_get_clientdata(client);
return scnprintf(buf, PAGE_SIZE,
"fw version: [%02X%02X.%02X%02X.%02X%02X.%02X%02X]\n",
ts->firmware_ver[0], ts->firmware_ver[1],
ts->firmware_ver[2], ts->firmware_ver[3],
ts->firmware_ver[4], ts->firmware_ver[5],
ts->firmware_ver[6], ts->firmware_ver[7]);
return sysfs_emit(buf,
"fw version: [%02X%02X.%02X%02X.%02X%02X.%02X%02X]\n",
ts->firmware_ver[0], ts->firmware_ver[1],
ts->firmware_ver[2], ts->firmware_ver[3],
ts->firmware_ver[4], ts->firmware_ver[5],
ts->firmware_ver[6], ts->firmware_ver[7]);
}
static DEVICE_ATTR_RO(firmware_version);
......@@ -527,8 +527,8 @@ static ssize_t product_id_show(struct device *dev,
struct i2c_client *client = to_i2c_client(dev);
struct ilitek_ts_data *ts = i2c_get_clientdata(client);
return scnprintf(buf, PAGE_SIZE, "product id: [%04X], module: [%s]\n",
ts->mcu_ver, ts->product_id);
return sysfs_emit(buf, "product id: [%04X], module: [%s]\n",
ts->mcu_ver, ts->product_id);
}
static DEVICE_ATTR_RO(product_id);
......
......@@ -943,12 +943,12 @@ static ssize_t fw_info_show(struct device *dev,
if (!iqs5xx->dev_id_info.bl_status)
return -ENODATA;
return scnprintf(buf, PAGE_SIZE, "%u.%u.%u.%u:%u.%u\n",
be16_to_cpu(iqs5xx->dev_id_info.prod_num),
be16_to_cpu(iqs5xx->dev_id_info.proj_num),
iqs5xx->dev_id_info.major_ver,
iqs5xx->dev_id_info.minor_ver,
iqs5xx->exp_file[0], iqs5xx->exp_file[1]);
return sysfs_emit(buf, "%u.%u.%u.%u:%u.%u\n",
be16_to_cpu(iqs5xx->dev_id_info.prod_num),
be16_to_cpu(iqs5xx->dev_id_info.proj_num),
iqs5xx->dev_id_info.major_ver,
iqs5xx->dev_id_info.minor_ver,
iqs5xx->exp_file[0], iqs5xx->exp_file[1]);
}
static DEVICE_ATTR_WO(fw_file);
......
......@@ -2401,12 +2401,12 @@ static ssize_t fw_info_show(struct device *dev,
{
struct iqs7211_private *iqs7211 = dev_get_drvdata(dev);
return scnprintf(buf, PAGE_SIZE, "%u.%u.%u.%u:%u.%u\n",
le16_to_cpu(iqs7211->ver_info.prod_num),
le32_to_cpu(iqs7211->ver_info.patch),
le16_to_cpu(iqs7211->ver_info.major),
le16_to_cpu(iqs7211->ver_info.minor),
iqs7211->exp_file[1], iqs7211->exp_file[0]);
return sysfs_emit(buf, "%u.%u.%u.%u:%u.%u\n",
le16_to_cpu(iqs7211->ver_info.prod_num),
le32_to_cpu(iqs7211->ver_info.patch),
le16_to_cpu(iqs7211->ver_info.major),
le16_to_cpu(iqs7211->ver_info.minor),
iqs7211->exp_file[1], iqs7211->exp_file[0]);
}
static DEVICE_ATTR_RO(fw_info);
......
......@@ -1336,9 +1336,9 @@ static ssize_t mip4_sysfs_read_fw_version(struct device *dev,
/* Take lock to prevent racing with firmware update */
mutex_lock(&ts->input->mutex);
count = snprintf(buf, PAGE_SIZE, "%04X %04X %04X %04X\n",
ts->fw_version.boot, ts->fw_version.core,
ts->fw_version.app, ts->fw_version.param);
count = sysfs_emit(buf, "%04X %04X %04X %04X\n",
ts->fw_version.boot, ts->fw_version.core,
ts->fw_version.app, ts->fw_version.param);
mutex_unlock(&ts->input->mutex);
......@@ -1362,8 +1362,8 @@ static ssize_t mip4_sysfs_read_hw_version(struct device *dev,
* product_name shows the name or version of the hardware
* paired with current firmware in the chip.
*/
count = snprintf(buf, PAGE_SIZE, "%.*s\n",
(int)sizeof(ts->product_name), ts->product_name);
count = sysfs_emit(buf, "%.*s\n",
(int)sizeof(ts->product_name), ts->product_name);
mutex_unlock(&ts->input->mutex);
......@@ -1382,7 +1382,7 @@ static ssize_t mip4_sysfs_read_product_id(struct device *dev,
mutex_lock(&ts->input->mutex);
count = snprintf(buf, PAGE_SIZE, "%04X\n", ts->product_id);
count = sysfs_emit(buf, "%04X\n", ts->product_id);
mutex_unlock(&ts->input->mutex);
......@@ -1401,8 +1401,8 @@ static ssize_t mip4_sysfs_read_ic_name(struct device *dev,
mutex_lock(&ts->input->mutex);
count = snprintf(buf, PAGE_SIZE, "%.*s\n",
(int)sizeof(ts->ic_name), ts->ic_name);
count = sysfs_emit(buf, "%.*s\n",
(int)sizeof(ts->ic_name), ts->ic_name);
mutex_unlock(&ts->input->mutex);
......
......@@ -456,8 +456,8 @@ static ssize_t mtouch_firmware_rev_show(struct device *dev,
struct usbtouch_usb *usbtouch = usb_get_intfdata(intf);
struct mtouch_priv *priv = usbtouch->priv;
return scnprintf(output, PAGE_SIZE, "%1x.%1x\n",
priv->fw_rev_major, priv->fw_rev_minor);
return sysfs_emit(output, "%1x.%1x\n",
priv->fw_rev_major, priv->fw_rev_minor);
}
static DEVICE_ATTR(firmware_rev, 0444, mtouch_firmware_rev_show, NULL);
......
......@@ -887,7 +887,7 @@ static ssize_t config_csum_show(struct device *dev,
cfg_csum = wdt->param.xmls_id1;
cfg_csum = (cfg_csum << 16) | wdt->param.xmls_id2;
return scnprintf(buf, PAGE_SIZE, "%x\n", cfg_csum);
return sysfs_emit(buf, "%x\n", cfg_csum);
}
static ssize_t fw_version_show(struct device *dev,
......@@ -896,7 +896,7 @@ static ssize_t fw_version_show(struct device *dev,
struct i2c_client *client = to_i2c_client(dev);
struct wdt87xx_data *wdt = i2c_get_clientdata(client);
return scnprintf(buf, PAGE_SIZE, "%x\n", wdt->param.fw_id);
return sysfs_emit(buf, "%x\n", wdt->param.fw_id);
}
static ssize_t plat_id_show(struct device *dev,
......@@ -905,7 +905,7 @@ static ssize_t plat_id_show(struct device *dev,
struct i2c_client *client = to_i2c_client(dev);
struct wdt87xx_data *wdt = i2c_get_clientdata(client);
return scnprintf(buf, PAGE_SIZE, "%x\n", wdt->param.plat_id);
return sysfs_emit(buf, "%x\n", wdt->param.plat_id);
}
static ssize_t update_config_store(struct device *dev,
......
......@@ -20,6 +20,7 @@
#include <linux/device.h>
#include <linux/sysfs.h>
#include <linux/input/mt.h>
#include <linux/input/touchscreen.h>
#include <linux/platform_data/zforce_ts.h>
#include <linux/regulator/consumer.h>
#include <linux/of.h>
......@@ -106,6 +107,7 @@ struct zforce_point {
struct zforce_ts {
struct i2c_client *client;
struct input_dev *input;
struct touchscreen_properties prop;
const struct zforce_ts_platdata *pdata;
char phys[32];
......@@ -266,7 +268,6 @@ static int zforce_setconfig(struct zforce_ts *ts, char b1)
static int zforce_start(struct zforce_ts *ts)
{
struct i2c_client *client = ts->client;
const struct zforce_ts_platdata *pdata = ts->pdata;
int ret;
dev_dbg(&client->dev, "starting device\n");
......@@ -277,7 +278,7 @@ static int zforce_start(struct zforce_ts *ts)
return ret;
}
ret = zforce_resolution(ts, pdata->x_max, pdata->y_max);
ret = zforce_resolution(ts, ts->prop.max_x, ts->prop.max_y);
if (ret) {
dev_err(&client->dev, "Unable to set resolution, %d\n", ret);
goto error;
......@@ -337,7 +338,6 @@ static int zforce_stop(struct zforce_ts *ts)
static int zforce_touch_event(struct zforce_ts *ts, u8 *payload)
{
struct i2c_client *client = ts->client;
const struct zforce_ts_platdata *pdata = ts->pdata;
struct zforce_point point;
int count, i, num = 0;
......@@ -355,8 +355,8 @@ static int zforce_touch_event(struct zforce_ts *ts, u8 *payload)
point.coord_y =
payload[9 * i + 4] << 8 | payload[9 * i + 3];
if (point.coord_x > pdata->x_max ||
point.coord_y > pdata->y_max) {
if (point.coord_x > ts->prop.max_x ||
point.coord_y > ts->prop.max_y) {
dev_warn(&client->dev, "coordinates (%d,%d) invalid\n",
point.coord_x, point.coord_y);
point.coord_x = point.coord_y = 0;
......@@ -390,10 +390,9 @@ static int zforce_touch_event(struct zforce_ts *ts, u8 *payload)
point.state != STATE_UP);
if (point.state != STATE_UP) {
input_report_abs(ts->input, ABS_MT_POSITION_X,
point.coord_x);
input_report_abs(ts->input, ABS_MT_POSITION_Y,
point.coord_y);
touchscreen_report_pos(ts->input, &ts->prop,
point.coord_x, point.coord_y,
true);
input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR,
point.area_major);
input_report_abs(ts->input, ABS_MT_TOUCH_MINOR,
......@@ -719,15 +718,8 @@ static struct zforce_ts_platdata *zforce_parse_dt(struct device *dev)
return ERR_PTR(-ENOMEM);
}
if (of_property_read_u32(np, "x-size", &pdata->x_max)) {
dev_err(dev, "failed to get x-size property\n");
return ERR_PTR(-EINVAL);
}
if (of_property_read_u32(np, "y-size", &pdata->y_max)) {
dev_err(dev, "failed to get y-size property\n");
return ERR_PTR(-EINVAL);
}
of_property_read_u32(np, "x-size", &pdata->x_max);
of_property_read_u32(np, "y-size", &pdata->y_max);
return pdata;
}
......@@ -856,6 +848,12 @@ static int zforce_probe(struct i2c_client *client)
input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0,
pdata->y_max, 0, 0);
touchscreen_parse_properties(input_dev, true, &ts->prop);
if (ts->prop.max_x == 0 || ts->prop.max_y == 0) {
dev_err(&client->dev, "no size specified\n");
return -EINVAL;
}
input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0,
ZFORCE_MAX_AREA, 0, 0);
input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR, 0,
......
......@@ -27,10 +27,10 @@ ssize_t vivaldi_function_row_physmap_show(const struct vivaldi_data *data,
return 0;
for (i = 0; i < data->num_function_row_keys; i++)
size += scnprintf(buf + size, PAGE_SIZE - size,
"%s%02X", size ? " " : "", physmap[i]);
size += sysfs_emit_at(buf, size,
"%s%02X", size ? " " : "", physmap[i]);
if (size)
size += scnprintf(buf + size, PAGE_SIZE - size, "\n");
size += sysfs_emit_at(buf, size, "\n");
return size;
}
......
......@@ -21,6 +21,7 @@ struct device;
* disable button via sysfs
* @value: axis value for %EV_ABS
* @irq: Irq number in case of interrupt keys
* @wakeirq: Optional dedicated wake-up interrupt
*/
struct gpio_keys_button {
unsigned int code;
......@@ -34,6 +35,7 @@ struct gpio_keys_button {
bool can_disable;
int value;
unsigned int irq;
unsigned int wakeirq;
};
/**
......
......@@ -7,7 +7,6 @@
*/
struct as5011_platform_data {
unsigned int button_gpio;
unsigned int axis_irq; /* irq number */
unsigned long axis_irqflags;
char xp, xn; /* threshold for x axis */
......
......@@ -5,5 +5,4 @@
struct navpoint_platform_data {
int port; /* PXA SSP port for pxa_ssp_request() */
int gpio; /* GPIO for power on/off */
};
......@@ -19,9 +19,6 @@ struct omap_kp_platform_data {
bool rep;
unsigned long delay;
bool dbounce;
/* specific to OMAP242x*/
unsigned int *row_gpios;
unsigned int *col_gpios;
};
/* Group (0..3) -- when multiple keys are pressed, only the
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment