Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
57ed9567
Commit
57ed9567
authored
Mar 15, 2024
by
Dmitry Torokhov
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'next' into for-linus
Prepare input updates for 6.9 merge window.
parents
fbf8d717
81c32343
Changes
38
Show whitespace changes
Inline
Side-by-side
Showing
38 changed files
with
1669 additions
and
671 deletions
+1669
-671
Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml
...cetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml
+0
-1
Documentation/devicetree/bindings/input/atmel,captouch.txt
Documentation/devicetree/bindings/input/atmel,captouch.txt
+0
-36
Documentation/devicetree/bindings/input/atmel,captouch.yaml
Documentation/devicetree/bindings/input/atmel,captouch.yaml
+59
-0
Documentation/devicetree/bindings/input/samsung,s3c6410-keypad.yaml
...ion/devicetree/bindings/input/samsung,s3c6410-keypad.yaml
+121
-0
Documentation/devicetree/bindings/input/samsung-keypad.txt
Documentation/devicetree/bindings/input/samsung-keypad.txt
+0
-77
Documentation/devicetree/bindings/input/touchscreen/goodix,gt9916.yaml
.../devicetree/bindings/input/touchscreen/goodix,gt9916.yaml
+95
-0
Documentation/devicetree/bindings/input/touchscreen/goodix.yaml
...ntation/devicetree/bindings/input/touchscreen/goodix.yaml
+3
-2
Documentation/devicetree/bindings/input/touchscreen/imagis,ist3038c.yaml
...evicetree/bindings/input/touchscreen/imagis,ist3038c.yaml
+18
-3
Documentation/devicetree/bindings/input/touchscreen/melfas,mms114.yaml
.../devicetree/bindings/input/touchscreen/melfas,mms114.yaml
+5
-1
Documentation/devicetree/bindings/input/touchscreen/silead,gsl1680.yaml
...devicetree/bindings/input/touchscreen/silead,gsl1680.yaml
+1
-1
Documentation/devicetree/bindings/power/wakeup-source.txt
Documentation/devicetree/bindings/power/wakeup-source.txt
+1
-1
drivers/input/gameport/gameport.c
drivers/input/gameport/gameport.c
+2
-2
drivers/input/input-leds.c
drivers/input/input-leds.c
+7
-1
drivers/input/input.c
drivers/input/input.c
+7
-9
drivers/input/joystick/xpad.c
drivers/input/joystick/xpad.c
+11
-3
drivers/input/keyboard/bcm-keypad.c
drivers/input/keyboard/bcm-keypad.c
+1
-1
drivers/input/keyboard/matrix_keypad.c
drivers/input/keyboard/matrix_keypad.c
+54
-116
drivers/input/misc/88pm80x_onkey.c
drivers/input/misc/88pm80x_onkey.c
+1
-13
drivers/input/misc/iqs7222.c
drivers/input/misc/iqs7222.c
+112
-0
drivers/input/mouse/Kconfig
drivers/input/mouse/Kconfig
+0
-12
drivers/input/mouse/Makefile
drivers/input/mouse/Makefile
+0
-1
drivers/input/mouse/navpoint.c
drivers/input/mouse/navpoint.c
+0
-350
drivers/input/rmi4/rmi_bus.c
drivers/input/rmi4/rmi_bus.c
+1
-1
drivers/input/rmi4/rmi_bus.h
drivers/input/rmi4/rmi_bus.h
+1
-1
drivers/input/rmi4/rmi_driver.c
drivers/input/rmi4/rmi_driver.c
+5
-1
drivers/input/serio/serio.c
drivers/input/serio/serio.c
+1
-1
drivers/input/serio/xilinx_ps2.c
drivers/input/serio/xilinx_ps2.c
+1
-2
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/Kconfig
+31
-0
drivers/input/touchscreen/Makefile
drivers/input/touchscreen/Makefile
+3
-0
drivers/input/touchscreen/goodix_berlin.h
drivers/input/touchscreen/goodix_berlin.h
+24
-0
drivers/input/touchscreen/goodix_berlin_core.c
drivers/input/touchscreen/goodix_berlin_core.c
+755
-0
drivers/input/touchscreen/goodix_berlin_i2c.c
drivers/input/touchscreen/goodix_berlin_i2c.c
+75
-0
drivers/input/touchscreen/goodix_berlin_spi.c
drivers/input/touchscreen/goodix_berlin_spi.c
+178
-0
drivers/input/touchscreen/imagis.c
drivers/input/touchscreen/imagis.c
+94
-24
drivers/input/touchscreen/ti_am335x_tsc.c
drivers/input/touchscreen/ti_am335x_tsc.c
+0
-1
include/linux/input.h
include/linux/input.h
+1
-1
include/linux/input/navpoint.h
include/linux/input/navpoint.h
+0
-8
include/linux/serio.h
include/linux/serio.h
+1
-1
No files found.
Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml
View file @
57ed9567
...
...
@@ -49,7 +49,6 @@ patternProperties:
$ref
:
input.yaml#
properties
:
label
:
$ref
:
/schemas/types.yaml#/definitions/string
description
:
Descriptive name of the key
linux,code
:
true
...
...
Documentation/devicetree/bindings/input/atmel,captouch.txt
deleted
100644 → 0
View file @
fbf8d717
Device tree bindings for Atmel capacitive touch device, typically
an Atmel touch sensor connected to AtmegaXX MCU running firmware
based on Qtouch library.
The node for this device must be a child of a I2C controller node, as the
device communicates via I2C.
Required properties:
compatible: Must be "atmel,captouch".
reg: The I2C slave address of the device.
interrupts: Property describing the interrupt line the device
is connected to. The device only has one interrupt
source.
linux,keycodes: Specifies an array of numeric keycode values to
be used for reporting button presses. The array can
contain up to 8 entries.
Optional properties:
autorepeat: Enables the Linux input system's autorepeat
feature on the input device.
Example:
atmel-captouch@51 {
compatible = "atmel,captouch";
reg = <0x51>;
interrupt-parent = <&tlmm>;
interrupts = <67 IRQ_TYPE_EDGE_FALLING>;
linux,keycodes = <BTN_0>, <BTN_1>,
<BTN_2>, <BTN_3>,
<BTN_4>, <BTN_5>,
<BTN_6>, <BTN_7>;
autorepeat;
};
Documentation/devicetree/bindings/input/atmel,captouch.yaml
0 → 100644
View file @
57ed9567
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML
1.2
---
$id
:
http://devicetree.org/schemas/input/atmel,captouch.yaml#
$schema
:
http://devicetree.org/meta-schemas/core.yaml#
title
:
Atmel capacitive touch device
maintainers
:
-
Dharma balasubiramani <dharma.b@microchip.com>
description
:
Atmel capacitive touch device, typically an Atmel touch sensor connected to
AtmegaXX MCU running firmware based on Qtouch library.
allOf
:
-
$ref
:
input.yaml#
properties
:
compatible
:
const
:
atmel,captouch
reg
:
maxItems
:
1
interrupts
:
maxItems
:
1
linux,keycodes
:
minItems
:
1
maxItems
:
8
required
:
-
compatible
-
reg
-
interrupts
-
linux,keycodes
unevaluatedProperties
:
false
examples
:
-
|
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/input/linux-event-codes.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
touch@51 {
compatible = "atmel,captouch";
reg = <0x51>;
interrupt-parent = <&tlmm>;
interrupts = <67 IRQ_TYPE_EDGE_FALLING>;
linux,keycodes = <BTN_0>, <BTN_1>,
<BTN_2>, <BTN_3>,
<BTN_4>, <BTN_5>,
<BTN_6>, <BTN_7>;
autorepeat;
};
};
Documentation/devicetree/bindings/input/samsung,s3c6410-keypad.yaml
0 → 100644
View file @
57ed9567
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML
1.2
---
$id
:
http://devicetree.org/schemas/input/samsung,s3c6410-keypad.yaml#
$schema
:
http://devicetree.org/meta-schemas/core.yaml#
title
:
Samsung SoC series Keypad Controller
description
:
Samsung SoC Keypad controller is used to interface a SoC with a matrix-type
keypad device. The keypad controller supports multiple row and column lines.
A key can be placed at each intersection of a unique row and a unique column.
The keypad controller can sense a key-press and key-release and report the
event using a interrupt to the cpu.
maintainers
:
-
Krzysztof Kozlowski <krzk@kernel.org>
properties
:
compatible
:
enum
:
-
samsung,s3c6410-keypad
-
samsung,s5pv210-keypad
reg
:
maxItems
:
1
clocks
:
maxItems
:
1
clock-names
:
items
:
-
const
:
keypad
interrupts
:
maxItems
:
1
wakeup-source
:
true
linux,input-no-autorepeat
:
type
:
boolean
description
:
Do no enable autorepeat feature.
linux,input-wakeup
:
type
:
boolean
deprecated
:
true
samsung,keypad-num-columns
:
$ref
:
/schemas/types.yaml#/definitions/uint32
description
:
Number of column lines connected to the keypad controller.
samsung,keypad-num-rows
:
$ref
:
/schemas/types.yaml#/definitions/uint32
description
:
Number of row lines connected to the keypad controller.
patternProperties
:
'
^key-[0-9a-z]+$'
:
type
:
object
$ref
:
input.yaml#
additionalProperties
:
false
description
:
Each key connected to the keypad controller is represented as a child
node to the keypad controller device node.
properties
:
keypad,column
:
$ref
:
/schemas/types.yaml#/definitions/uint32
description
:
The column number to which the key is connected.
keypad,row
:
$ref
:
/schemas/types.yaml#/definitions/uint32
description
:
The row number to which the key is connected.
linux,code
:
true
required
:
-
keypad,column
-
keypad,row
-
linux,code
required
:
-
compatible
-
reg
-
interrupts
-
samsung,keypad-num-columns
-
samsung,keypad-num-rows
additionalProperties
:
false
examples
:
-
|
#include <dt-bindings/clock/exynos4.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
keypad@100a0000 {
compatible = "samsung,s5pv210-keypad";
reg = <0x100a0000 0x100>;
interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_KEYIF>;
clock-names = "keypad";
samsung,keypad-num-rows = <2>;
samsung,keypad-num-columns = <8>;
linux,input-no-autorepeat;
wakeup-source;
key-1 {
keypad,row = <0>;
keypad,column = <3>;
linux,code = <2>;
};
key-2 {
keypad,row = <0>;
keypad,column = <4>;
linux,code = <3>;
};
};
Documentation/devicetree/bindings/input/samsung-keypad.txt
deleted
100644 → 0
View file @
fbf8d717
* Samsung's Keypad Controller device tree bindings
Samsung's Keypad controller is used to interface a SoC with a matrix-type
keypad device. The keypad controller supports multiple row and column lines.
A key can be placed at each intersection of a unique row and a unique column.
The keypad controller can sense a key-press and key-release and report the
event using a interrupt to the cpu.
Required SoC Specific Properties:
- compatible: should be one of the following
- "samsung,s3c6410-keypad": For controllers compatible with s3c6410 keypad
controller.
- "samsung,s5pv210-keypad": For controllers compatible with s5pv210 keypad
controller.
- reg: physical base address of the controller and length of memory mapped
region.
- interrupts: The interrupt number to the cpu.
Required Board Specific Properties:
- samsung,keypad-num-rows: Number of row lines connected to the keypad
controller.
- samsung,keypad-num-columns: Number of column lines connected to the
keypad controller.
- Keys represented as child nodes: Each key connected to the keypad
controller is represented as a child node to the keypad controller
device node and should include the following properties.
- keypad,row: the row number to which the key is connected.
- keypad,column: the column number to which the key is connected.
- linux,code: the key-code to be reported when the key is pressed
and released.
- pinctrl-0: Should specify pin control groups used for this controller.
- pinctrl-names: Should contain only one value - "default".
Optional Properties:
- wakeup-source: use any event on keypad as wakeup event.
(Legacy property supported: "linux,input-wakeup")
Optional Properties specific to linux:
- linux,keypad-no-autorepeat: do no enable autorepeat feature.
Example:
keypad@100a0000 {
compatible = "samsung,s5pv210-keypad";
reg = <0x100A0000 0x100>;
interrupts = <173>;
samsung,keypad-num-rows = <2>;
samsung,keypad-num-columns = <8>;
linux,input-no-autorepeat;
wakeup-source;
pinctrl-names = "default";
pinctrl-0 = <&keypad_rows &keypad_columns>;
key_1 {
keypad,row = <0>;
keypad,column = <3>;
linux,code = <2>;
};
key_2 {
keypad,row = <0>;
keypad,column = <4>;
linux,code = <3>;
};
key_3 {
keypad,row = <0>;
keypad,column = <5>;
linux,code = <4>;
};
};
Documentation/devicetree/bindings/input/touchscreen/goodix,gt9916.yaml
0 → 100644
View file @
57ed9567
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML
1.2
---
$id
:
http://devicetree.org/schemas/input/touchscreen/goodix,gt9916.yaml#
$schema
:
http://devicetree.org/meta-schemas/core.yaml#
title
:
Goodix Berlin series touchscreen controller
description
:
The Goodix Berlin series of touchscreen controllers
be connected to either I2C or SPI buses.
maintainers
:
-
Neil Armstrong <neil.armstrong@linaro.org>
allOf
:
-
$ref
:
touchscreen.yaml#
-
$ref
:
/schemas/spi/spi-peripheral-props.yaml#
properties
:
compatible
:
enum
:
-
goodix,gt9916
reg
:
maxItems
:
1
interrupts
:
maxItems
:
1
reset-gpios
:
maxItems
:
1
avdd-supply
:
description
:
Analog power supply regulator on AVDD pin
vddio-supply
:
description
:
power supply regulator on VDDIO pin
spi-max-frequency
:
true
touchscreen-inverted-x
:
true
touchscreen-inverted-y
:
true
touchscreen-size-x
:
true
touchscreen-size-y
:
true
touchscreen-swapped-x-y
:
true
additionalProperties
:
false
required
:
-
compatible
-
reg
-
interrupts
-
avdd-supply
-
touchscreen-size-x
-
touchscreen-size-y
examples
:
-
|
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/gpio/gpio.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
touchscreen@5d {
compatible = "goodix,gt9916";
reg = <0x5d>;
interrupt-parent = <&gpio>;
interrupts = <25 IRQ_TYPE_LEVEL_LOW>;
reset-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
avdd-supply = <&ts_avdd>;
touchscreen-size-x = <1024>;
touchscreen-size-y = <768>;
};
};
-
|
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/gpio/gpio.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
num-cs = <1>;
cs-gpios = <&gpio 2 GPIO_ACTIVE_HIGH>;
touchscreen@0 {
compatible = "goodix,gt9916";
reg = <0>;
interrupt-parent = <&gpio>;
interrupts = <25 IRQ_TYPE_LEVEL_LOW>;
reset-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
avdd-supply = <&ts_avdd>;
spi-max-frequency = <1000000>;
touchscreen-size-x = <1024>;
touchscreen-size-y = <768>;
};
};
...
Documentation/devicetree/bindings/input/touchscreen/goodix.yaml
View file @
57ed9567
...
...
@@ -37,8 +37,9 @@ properties:
maxItems
:
1
irq-gpios
:
description
:
GPIO pin used for IRQ. The driver uses the interrupt gpio pin
as output to reset the device.
description
:
GPIO pin used for IRQ input. Additionally, this line is
sampled by the device on reset deassertion to select the I2C client
address, thus it can be driven by the host during the reset sequence.
maxItems
:
1
reset-gpios
:
...
...
Documentation/devicetree/bindings/input/touchscreen/imagis,ist3038c.yaml
View file @
57ed9567
...
...
@@ -9,15 +9,14 @@ title: Imagis IST30XXC family touchscreen controller
maintainers
:
-
Markuss Broks <markuss.broks@gmail.com>
allOf
:
-
$ref
:
touchscreen.yaml#
properties
:
$nodename
:
pattern
:
"
^touchscreen@[0-9a-f]+$"
compatible
:
enum
:
-
imagis,ist3032c
-
imagis,ist3038b
-
imagis,ist3038c
reg
:
...
...
@@ -32,6 +31,10 @@ properties:
vddio-supply
:
description
:
Power supply regulator for the I2C bus
linux,keycodes
:
description
:
Keycodes for the touch keys
maxItems
:
5
touchscreen-size-x
:
true
touchscreen-size-y
:
true
touchscreen-fuzz-x
:
true
...
...
@@ -42,6 +45,18 @@ properties:
additionalProperties
:
false
allOf
:
-
$ref
:
touchscreen.yaml#
-
if
:
not
:
properties
:
compatible
:
contains
:
const
:
imagis,ist3032c
then
:
properties
:
linux,keycodes
:
false
required
:
-
compatible
-
reg
...
...
Documentation/devicetree/bindings/input/touchscreen/melfas,mms114.yaml
View file @
57ed9567
...
...
@@ -17,13 +17,17 @@ properties:
pattern
:
"
^touchscreen(@.*)?$"
compatible
:
items
:
oneOf
:
-
enum
:
-
melfas,mms114
-
melfas,mms134s
-
melfas,mms136
-
melfas,mms152
-
melfas,mms345l
-
items
:
-
enum
:
-
melfas,mms252
-
const
:
melfas,mms114
reg
:
description
:
I2C address
...
...
Documentation/devicetree/bindings/input/touchscreen/silead,gsl1680.yaml
View file @
57ed9567
...
...
@@ -31,7 +31,7 @@ properties:
maxItems
:
1
firmware-name
:
$ref
:
/schemas/types.yaml#/definitions/string
maxItems
:
1
description
:
>
File basename for board specific firmware
...
...
Documentation/devicetree/bindings/power/wakeup-source.txt
View file @
57ed9567
...
...
@@ -23,7 +23,7 @@ List of legacy properties and respective binding document
Documentation/devicetree/bindings/mfd/tc3589x.txt
Documentation/devicetree/bindings/input/touchscreen/ads7846.txt
4. "linux,keypad-wakeup" Documentation/devicetree/bindings/input/qcom,pm8xxx-keypad.txt
5. "linux,input-wakeup" Documentation/devicetree/bindings/input/samsung
-keypad.txt
5. "linux,input-wakeup" Documentation/devicetree/bindings/input/samsung
,s3c6410-keypad.yaml
6. "nvidia,wakeup-source" Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt
Examples
...
...
drivers/input/gameport/gameport.c
View file @
57ed9567
...
...
@@ -38,7 +38,7 @@ static DEFINE_MUTEX(gameport_mutex);
static
LIST_HEAD
(
gameport_list
);
static
struct
bus_type
gameport_bus
;
static
const
struct
bus_type
gameport_bus
;
static
void
gameport_add_port
(
struct
gameport
*
gameport
);
static
void
gameport_attach_driver
(
struct
gameport_driver
*
drv
);
...
...
@@ -813,7 +813,7 @@ static int gameport_bus_match(struct device *dev, struct device_driver *drv)
return
!
gameport_drv
->
ignore
;
}
static
struct
bus_type
gameport_bus
=
{
static
const
struct
bus_type
gameport_bus
=
{
.
name
=
"gameport"
,
.
dev_groups
=
gameport_device_groups
,
.
drv_groups
=
gameport_driver_groups
,
...
...
drivers/input/input-leds.c
View file @
57ed9567
...
...
@@ -18,6 +18,12 @@
#define VT_TRIGGER(_name) .trigger = NULL
#endif
#if IS_ENABLED(CONFIG_SND_CTL_LED)
#define AUDIO_TRIGGER(_name) .trigger = _name
#else
#define AUDIO_TRIGGER(_name) .trigger = NULL
#endif
static
const
struct
{
const
char
*
name
;
const
char
*
trigger
;
...
...
@@ -29,7 +35,7 @@ static const struct {
[
LED_KANA
]
=
{
"kana"
,
VT_TRIGGER
(
"kbd-kanalock"
)
},
[
LED_SLEEP
]
=
{
"sleep"
}
,
[
LED_SUSPEND
]
=
{
"suspend"
},
[
LED_MUTE
]
=
{
"mute"
},
[
LED_MUTE
]
=
{
"mute"
,
AUDIO_TRIGGER
(
"audio-mute"
)
},
[
LED_MISC
]
=
{
"misc"
},
[
LED_MAIL
]
=
{
"mail"
},
[
LED_CHARGING
]
=
{
"charging"
},
...
...
drivers/input/input.c
View file @
57ed9567
...
...
@@ -1918,7 +1918,7 @@ static char *input_devnode(const struct device *dev, umode_t *mode)
return
kasprintf
(
GFP_KERNEL
,
"input/%s"
,
dev_name
(
dev
));
}
struct
class
input_class
=
{
const
struct
class
input_class
=
{
.
name
=
"input"
,
.
devnode
=
input_devnode
,
};
...
...
@@ -2629,17 +2629,15 @@ int input_get_new_minor(int legacy_base, unsigned int legacy_num,
* locking is needed here.
*/
if
(
legacy_base
>=
0
)
{
int
minor
=
ida_simple_get
(
&
input_ida
,
legacy_base
,
legacy_base
+
legacy_num
,
int
minor
=
ida_alloc_range
(
&
input_ida
,
legacy_base
,
legacy_base
+
legacy_num
-
1
,
GFP_KERNEL
);
if
(
minor
>=
0
||
!
allow_dynamic
)
return
minor
;
}
return
ida_simple_get
(
&
input_ida
,
INPUT_FIRST_DYNAMIC_DEV
,
INPUT_MAX_CHAR_DEVICES
,
GFP_KERNEL
);
return
ida_alloc_range
(
&
input_ida
,
INPUT_FIRST_DYNAMIC_DEV
,
INPUT_MAX_CHAR_DEVICES
-
1
,
GFP_KERNEL
);
}
EXPORT_SYMBOL
(
input_get_new_minor
);
...
...
@@ -2652,7 +2650,7 @@ EXPORT_SYMBOL(input_get_new_minor);
*/
void
input_free_minor
(
unsigned
int
minor
)
{
ida_
simple_remov
e
(
&
input_ida
,
minor
);
ida_
fre
e
(
&
input_ida
,
minor
);
}
EXPORT_SYMBOL
(
input_free_minor
);
...
...
drivers/input/joystick/xpad.c
View file @
57ed9567
...
...
@@ -127,6 +127,7 @@ static const struct xpad_device {
u8
mapping
;
u8
xtype
;
}
xpad_device
[]
=
{
/* Please keep this list sorted by vendor and product ID. */
{
0x0079
,
0x18d4
,
"GPD Win 2 X-Box Controller"
,
0
,
XTYPE_XBOX360
},
{
0x03eb
,
0xff01
,
"Wooting One (Legacy)"
,
0
,
XTYPE_XBOX360
},
{
0x03eb
,
0xff02
,
"Wooting Two (Legacy)"
,
0
,
XTYPE_XBOX360
},
...
...
@@ -152,9 +153,9 @@ static const struct xpad_device {
{
0x045e
,
0x02d1
,
"Microsoft X-Box One pad"
,
0
,
XTYPE_XBOXONE
},
{
0x045e
,
0x02dd
,
"Microsoft X-Box One pad (Firmware 2015)"
,
0
,
XTYPE_XBOXONE
},
{
0x045e
,
0x02e3
,
"Microsoft X-Box One Elite pad"
,
MAP_PADDLES
,
XTYPE_XBOXONE
},
{
0x045e
,
0x0b00
,
"Microsoft X-Box One Elite 2 pad"
,
MAP_PADDLES
,
XTYPE_XBOXONE
},
{
0x045e
,
0x02ea
,
"Microsoft X-Box One S pad"
,
0
,
XTYPE_XBOXONE
},
{
0x045e
,
0x0719
,
"Xbox 360 Wireless Receiver"
,
MAP_DPAD_TO_BUTTONS
,
XTYPE_XBOX360W
},
{
0x045e
,
0x0b00
,
"Microsoft X-Box One Elite 2 pad"
,
MAP_PADDLES
,
XTYPE_XBOXONE
},
{
0x045e
,
0x0b0a
,
"Microsoft X-Box Adaptive Controller"
,
MAP_PROFILE_BUTTON
,
XTYPE_XBOXONE
},
{
0x045e
,
0x0b12
,
"Microsoft Xbox Series S|X Controller"
,
MAP_SELECT_BUTTON
,
XTYPE_XBOXONE
},
{
0x046d
,
0xc21d
,
"Logitech Gamepad F310"
,
0
,
XTYPE_XBOX360
},
...
...
@@ -340,7 +341,6 @@ static const struct xpad_device {
{
0x20d6
,
0x2001
,
"BDA Xbox Series X Wired Controller"
,
0
,
XTYPE_XBOXONE
},
{
0x20d6
,
0x2009
,
"PowerA Enhanced Wired Controller for Xbox Series X|S"
,
0
,
XTYPE_XBOXONE
},
{
0x20d6
,
0x281f
,
"PowerA Wired Controller For Xbox 360"
,
0
,
XTYPE_XBOX360
},
{
0x2e24
,
0x0652
,
"Hyperkin Duke X-Box One pad"
,
0
,
XTYPE_XBOXONE
},
{
0x24c6
,
0x5000
,
"Razer Atrox Arcade Stick"
,
MAP_TRIGGERS_TO_BUTTONS
,
XTYPE_XBOX360
},
{
0x24c6
,
0x5300
,
"PowerA MINI PROEX Controller"
,
0
,
XTYPE_XBOX360
},
{
0x24c6
,
0x5303
,
"Xbox Airflo wired controller"
,
0
,
XTYPE_XBOX360
},
...
...
@@ -355,9 +355,9 @@ static const struct xpad_device {
{
0x24c6
,
0x5502
,
"Hori Fighting Stick VX Alt"
,
MAP_TRIGGERS_TO_BUTTONS
,
XTYPE_XBOX360
},
{
0x24c6
,
0x5503
,
"Hori Fighting Edge"
,
MAP_TRIGGERS_TO_BUTTONS
,
XTYPE_XBOX360
},
{
0x24c6
,
0x5506
,
"Hori SOULCALIBUR V Stick"
,
0
,
XTYPE_XBOX360
},
{
0x24c6
,
0x5510
,
"Hori Fighting Commander ONE (Xbox 360/PC Mode)"
,
MAP_TRIGGERS_TO_BUTTONS
,
XTYPE_XBOX360
},
{
0x24c6
,
0x550d
,
"Hori GEM Xbox controller"
,
0
,
XTYPE_XBOX360
},
{
0x24c6
,
0x550e
,
"Hori Real Arcade Pro V Kai 360"
,
MAP_TRIGGERS_TO_BUTTONS
,
XTYPE_XBOX360
},
{
0x24c6
,
0x5510
,
"Hori Fighting Commander ONE (Xbox 360/PC Mode)"
,
MAP_TRIGGERS_TO_BUTTONS
,
XTYPE_XBOX360
},
{
0x24c6
,
0x551a
,
"PowerA FUSION Pro Controller"
,
0
,
XTYPE_XBOXONE
},
{
0x24c6
,
0x561a
,
"PowerA FUSION Controller"
,
0
,
XTYPE_XBOXONE
},
{
0x24c6
,
0x5b00
,
"ThrustMaster Ferrari 458 Racing Wheel"
,
0
,
XTYPE_XBOX360
},
...
...
@@ -366,8 +366,11 @@ static const struct xpad_device {
{
0x24c6
,
0x5d04
,
"Razer Sabertooth"
,
0
,
XTYPE_XBOX360
},
{
0x24c6
,
0xfafe
,
"Rock Candy Gamepad for Xbox 360"
,
0
,
XTYPE_XBOX360
},
{
0x2563
,
0x058d
,
"OneXPlayer Gamepad"
,
0
,
XTYPE_XBOX360
},
{
0x294b
,
0x3303
,
"Snakebyte GAMEPAD BASE X"
,
0
,
XTYPE_XBOXONE
},
{
0x294b
,
0x3404
,
"Snakebyte GAMEPAD RGB X"
,
0
,
XTYPE_XBOXONE
},
{
0x2dc8
,
0x2000
,
"8BitDo Pro 2 Wired Controller fox Xbox"
,
0
,
XTYPE_XBOXONE
},
{
0x2dc8
,
0x3106
,
"8BitDo Pro 2 Wired Controller"
,
0
,
XTYPE_XBOX360
},
{
0x2e24
,
0x0652
,
"Hyperkin Duke X-Box One pad"
,
0
,
XTYPE_XBOXONE
},
{
0x31e3
,
0x1100
,
"Wooting One"
,
0
,
XTYPE_XBOX360
},
{
0x31e3
,
0x1200
,
"Wooting Two"
,
0
,
XTYPE_XBOX360
},
{
0x31e3
,
0x1210
,
"Wooting Lekker"
,
0
,
XTYPE_XBOX360
},
...
...
@@ -465,6 +468,10 @@ static const signed short xpad_btn_paddles[] = {
{ XPAD_XBOXONE_VENDOR_PROTOCOL((vend), 208) }
static
const
struct
usb_device_id
xpad_table
[]
=
{
/*
* Please keep this list sorted by vendor ID. Note that there are 2
* macros - XPAD_XBOX360_VENDOR and XPAD_XBOXONE_VENDOR.
*/
{
USB_INTERFACE_INFO
(
'X'
,
'B'
,
0
)
},
/* Xbox USB-IF not-approved class */
XPAD_XBOX360_VENDOR
(
0x0079
),
/* GPD Win 2 controller */
XPAD_XBOX360_VENDOR
(
0x03eb
),
/* Wooting Keyboards (Legacy) */
...
...
@@ -507,6 +514,7 @@ static const struct usb_device_id xpad_table[] = {
XPAD_XBOXONE_VENDOR
(
0x24c6
),
/* PowerA controllers */
XPAD_XBOX360_VENDOR
(
0x2563
),
/* OneXPlayer Gamepad */
XPAD_XBOX360_VENDOR
(
0x260d
),
/* Dareu H101 */
XPAD_XBOXONE_VENDOR
(
0x294b
),
/* Snakebyte */
XPAD_XBOX360_VENDOR
(
0x2c22
),
/* Qanba Controllers */
XPAD_XBOX360_VENDOR
(
0x2dc8
),
/* 8BitDo Pro 2 Wired Controller */
XPAD_XBOXONE_VENDOR
(
0x2dc8
),
/* 8BitDo Pro 2 Wired Controller for Xbox */
...
...
drivers/input/keyboard/bcm-keypad.c
View file @
57ed9567
...
...
@@ -418,7 +418,7 @@ static struct platform_driver bcm_kp_device_driver = {
.
probe
=
bcm_kp_probe
,
.
driver
=
{
.
name
=
"bcm-keypad"
,
.
of_match_table
=
of_match_ptr
(
bcm_kp_of_match
)
,
.
of_match_table
=
bcm_kp_of_match
,
}
};
...
...
drivers/input/keyboard/matrix_keypad.c
View file @
57ed9567
...
...
@@ -28,7 +28,9 @@ struct matrix_keypad {
struct
input_dev
*
input_dev
;
unsigned
int
row_shift
;
DECLARE_BITMAP
(
disabled_gpios
,
MATRIX_MAX_ROWS
);
unsigned
int
row_irqs
[
MATRIX_MAX_ROWS
];
unsigned
int
num_row_irqs
;
DECLARE_BITMAP
(
wakeup_enabled_irqs
,
MATRIX_MAX_ROWS
);
uint32_t
last_key_state
[
MATRIX_MAX_COLS
];
struct
delayed_work
work
;
...
...
@@ -85,28 +87,18 @@ static bool row_asserted(const struct matrix_keypad_platform_data *pdata,
static
void
enable_row_irqs
(
struct
matrix_keypad
*
keypad
)
{
const
struct
matrix_keypad_platform_data
*
pdata
=
keypad
->
pdata
;
int
i
;
if
(
pdata
->
clustered_irq
>
0
)
enable_irq
(
pdata
->
clustered_irq
);
else
{
for
(
i
=
0
;
i
<
pdata
->
num_row_gpios
;
i
++
)
enable_irq
(
gpio_to_irq
(
pdata
->
row_gpios
[
i
]));
}
for
(
i
=
0
;
i
<
keypad
->
num_row_irqs
;
i
++
)
enable_irq
(
keypad
->
row_irqs
[
i
]);
}
static
void
disable_row_irqs
(
struct
matrix_keypad
*
keypad
)
{
const
struct
matrix_keypad_platform_data
*
pdata
=
keypad
->
pdata
;
int
i
;
if
(
pdata
->
clustered_irq
>
0
)
disable_irq_nosync
(
pdata
->
clustered_irq
);
else
{
for
(
i
=
0
;
i
<
pdata
->
num_row_gpios
;
i
++
)
disable_irq_nosync
(
gpio_to_irq
(
pdata
->
row_gpios
[
i
]));
}
for
(
i
=
0
;
i
<
keypad
->
num_row_irqs
;
i
++
)
disable_irq_nosync
(
keypad
->
row_irqs
[
i
]);
}
/*
...
...
@@ -232,44 +224,20 @@ static void matrix_keypad_stop(struct input_dev *dev)
static
void
matrix_keypad_enable_wakeup
(
struct
matrix_keypad
*
keypad
)
{
const
struct
matrix_keypad_platform_data
*
pdata
=
keypad
->
pdata
;
unsigned
int
gpio
;
int
i
;
if
(
pdata
->
clustered_irq
>
0
)
{
if
(
enable_irq_wake
(
pdata
->
clustered_irq
)
==
0
)
keypad
->
gpio_all_disabled
=
true
;
}
else
{
for
(
i
=
0
;
i
<
pdata
->
num_row_gpios
;
i
++
)
{
if
(
!
test_bit
(
i
,
keypad
->
disabled_gpios
))
{
gpio
=
pdata
->
row_gpios
[
i
];
if
(
enable_irq_wake
(
gpio_to_irq
(
gpio
))
==
0
)
__set_bit
(
i
,
keypad
->
disabled_gpios
);
}
}
}
for_each_clear_bit
(
i
,
keypad
->
wakeup_enabled_irqs
,
keypad
->
num_row_irqs
)
if
(
enable_irq_wake
(
keypad
->
row_irqs
[
i
])
==
0
)
__set_bit
(
i
,
keypad
->
wakeup_enabled_irqs
);
}
static
void
matrix_keypad_disable_wakeup
(
struct
matrix_keypad
*
keypad
)
{
const
struct
matrix_keypad_platform_data
*
pdata
=
keypad
->
pdata
;
unsigned
int
gpio
;
int
i
;
if
(
pdata
->
clustered_irq
>
0
)
{
if
(
keypad
->
gpio_all_disabled
)
{
disable_irq_wake
(
pdata
->
clustered_irq
);
keypad
->
gpio_all_disabled
=
false
;
}
}
else
{
for
(
i
=
0
;
i
<
pdata
->
num_row_gpios
;
i
++
)
{
if
(
test_and_clear_bit
(
i
,
keypad
->
disabled_gpios
))
{
gpio
=
pdata
->
row_gpios
[
i
];
disable_irq_wake
(
gpio_to_irq
(
gpio
));
}
}
for_each_set_bit
(
i
,
keypad
->
wakeup_enabled_irqs
,
keypad
->
num_row_irqs
)
{
disable_irq_wake
(
keypad
->
row_irqs
[
i
]);
__clear_bit
(
i
,
keypad
->
wakeup_enabled_irqs
);
}
}
...
...
@@ -306,47 +274,62 @@ static int matrix_keypad_init_gpio(struct platform_device *pdev,
struct
matrix_keypad
*
keypad
)
{
const
struct
matrix_keypad_platform_data
*
pdata
=
keypad
->
pdata
;
int
i
,
err
;
int
i
,
irq
,
err
;
/* initialized strobe lines as outputs, activated */
for
(
i
=
0
;
i
<
pdata
->
num_col_gpios
;
i
++
)
{
err
=
gpio_request
(
pdata
->
col_gpios
[
i
],
"matrix_kbd_col"
);
err
=
devm_gpio_request
(
&
pdev
->
dev
,
pdata
->
col_gpios
[
i
],
"matrix_kbd_col"
);
if
(
err
)
{
dev_err
(
&
pdev
->
dev
,
"failed to request GPIO%d for COL%d
\n
"
,
pdata
->
col_gpios
[
i
],
i
);
goto
err_free_cols
;
return
err
;
}
gpio_direction_output
(
pdata
->
col_gpios
[
i
],
!
pdata
->
active_low
);
}
for
(
i
=
0
;
i
<
pdata
->
num_row_gpios
;
i
++
)
{
err
=
gpio_request
(
pdata
->
row_gpios
[
i
],
"matrix_kbd_row"
);
err
=
devm_gpio_request
(
&
pdev
->
dev
,
pdata
->
row_gpios
[
i
],
"matrix_kbd_row"
);
if
(
err
)
{
dev_err
(
&
pdev
->
dev
,
"failed to request GPIO%d for ROW%d
\n
"
,
pdata
->
row_gpios
[
i
],
i
);
goto
err_free_rows
;
return
err
;
}
gpio_direction_input
(
pdata
->
row_gpios
[
i
]);
}
if
(
pdata
->
clustered_irq
>
0
)
{
err
=
request_any_context_irq
(
pdata
->
clustered_irq
,
err
=
devm_request_any_context_irq
(
&
pdev
->
dev
,
pdata
->
clustered_irq
,
matrix_keypad_interrupt
,
pdata
->
clustered_irq_flags
,
"matrix-keypad"
,
keypad
);
if
(
err
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"Unable to acquire clustered interrupt
\n
"
);
goto
err_free_rows
;
return
err
;
}
keypad
->
row_irqs
[
0
]
=
pdata
->
clustered_irq
;
keypad
->
num_row_irqs
=
1
;
}
else
{
for
(
i
=
0
;
i
<
pdata
->
num_row_gpios
;
i
++
)
{
err
=
request_any_context_irq
(
gpio_to_irq
(
pdata
->
row_gpios
[
i
]),
irq
=
gpio_to_irq
(
pdata
->
row_gpios
[
i
]);
if
(
irq
<
0
)
{
err
=
irq
;
dev_err
(
&
pdev
->
dev
,
"Unable to convert GPIO line %i to irq: %d
\n
"
,
pdata
->
row_gpios
[
i
],
err
);
return
err
;
}
err
=
devm_request_any_context_irq
(
&
pdev
->
dev
,
irq
,
matrix_keypad_interrupt
,
IRQF_TRIGGER_RISING
|
IRQF_TRIGGER_FALLING
,
...
...
@@ -355,47 +338,19 @@ static int matrix_keypad_init_gpio(struct platform_device *pdev,
dev_err
(
&
pdev
->
dev
,
"Unable to acquire interrupt for GPIO line %i
\n
"
,
pdata
->
row_gpios
[
i
]);
goto
err_free_irqs
;
return
err
;
}
keypad
->
row_irqs
[
i
]
=
irq
;
}
keypad
->
num_row_irqs
=
pdata
->
num_row_gpios
;
}
/* initialized as disabled - enabled by input->open */
disable_row_irqs
(
keypad
);
return
0
;
err_free_irqs:
while
(
--
i
>=
0
)
free_irq
(
gpio_to_irq
(
pdata
->
row_gpios
[
i
]),
keypad
);
i
=
pdata
->
num_row_gpios
;
err_free_rows:
while
(
--
i
>=
0
)
gpio_free
(
pdata
->
row_gpios
[
i
]);
i
=
pdata
->
num_col_gpios
;
err_free_cols:
while
(
--
i
>=
0
)
gpio_free
(
pdata
->
col_gpios
[
i
]);
return
err
;
}
static
void
matrix_keypad_free_gpio
(
struct
matrix_keypad
*
keypad
)
{
const
struct
matrix_keypad_platform_data
*
pdata
=
keypad
->
pdata
;
int
i
;
if
(
pdata
->
clustered_irq
>
0
)
{
free_irq
(
pdata
->
clustered_irq
,
keypad
);
}
else
{
for
(
i
=
0
;
i
<
pdata
->
num_row_gpios
;
i
++
)
free_irq
(
gpio_to_irq
(
pdata
->
row_gpios
[
i
]),
keypad
);
}
for
(
i
=
0
;
i
<
pdata
->
num_row_gpios
;
i
++
)
gpio_free
(
pdata
->
row_gpios
[
i
]);
for
(
i
=
0
;
i
<
pdata
->
num_col_gpios
;
i
++
)
gpio_free
(
pdata
->
col_gpios
[
i
]);
return
0
;
}
#ifdef CONFIG_OF
...
...
@@ -494,12 +449,13 @@ static int matrix_keypad_probe(struct platform_device *pdev)
return
-
EINVAL
;
}
keypad
=
kzalloc
(
sizeof
(
struct
matrix_keypad
),
GFP_KERNEL
);
input_dev
=
input_allocate_device
();
if
(
!
keypad
||
!
input_dev
)
{
err
=
-
ENOMEM
;
goto
err_free_mem
;
}
keypad
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
keypad
),
GFP_KERNEL
);
if
(
!
keypad
)
return
-
ENOMEM
;
input_dev
=
devm_input_allocate_device
(
&
pdev
->
dev
);
if
(
!
input_dev
)
return
-
ENOMEM
;
keypad
->
input_dev
=
input_dev
;
keypad
->
pdata
=
pdata
;
...
...
@@ -510,7 +466,6 @@ static int matrix_keypad_probe(struct platform_device *pdev)
input_dev
->
name
=
pdev
->
name
;
input_dev
->
id
.
bustype
=
BUS_HOST
;
input_dev
->
dev
.
parent
=
&
pdev
->
dev
;
input_dev
->
open
=
matrix_keypad_start
;
input_dev
->
close
=
matrix_keypad_stop
;
...
...
@@ -520,7 +475,7 @@ static int matrix_keypad_probe(struct platform_device *pdev)
NULL
,
input_dev
);
if
(
err
)
{
dev_err
(
&
pdev
->
dev
,
"failed to build keymap
\n
"
);
goto
err_free_mem
;
return
-
ENOMEM
;
}
if
(
!
pdata
->
no_autorepeat
)
...
...
@@ -530,32 +485,16 @@ static int matrix_keypad_probe(struct platform_device *pdev)
err
=
matrix_keypad_init_gpio
(
pdev
,
keypad
);
if
(
err
)
goto
err_free_mem
;
return
err
;
err
=
input_register_device
(
keypad
->
input_dev
);
if
(
err
)
goto
err_free_gpio
;
return
err
;
device_init_wakeup
(
&
pdev
->
dev
,
pdata
->
wakeup
);
platform_set_drvdata
(
pdev
,
keypad
);
return
0
;
err_free_gpio:
matrix_keypad_free_gpio
(
keypad
);
err_free_mem:
input_free_device
(
input_dev
);
kfree
(
keypad
);
return
err
;
}
static
void
matrix_keypad_remove
(
struct
platform_device
*
pdev
)
{
struct
matrix_keypad
*
keypad
=
platform_get_drvdata
(
pdev
);
matrix_keypad_free_gpio
(
keypad
);
input_unregister_device
(
keypad
->
input_dev
);
kfree
(
keypad
);
}
#ifdef CONFIG_OF
...
...
@@ -568,7 +507,6 @@ MODULE_DEVICE_TABLE(of, matrix_keypad_dt_match);
static
struct
platform_driver
matrix_keypad_driver
=
{
.
probe
=
matrix_keypad_probe
,
.
remove_new
=
matrix_keypad_remove
,
.
driver
=
{
.
name
=
"matrix-keypad"
,
.
pm
=
pm_sleep_ptr
(
&
matrix_keypad_pm_ops
),
...
...
drivers/input/misc/88pm80x_onkey.c
View file @
57ed9567
// SPDX-License-Identifier: GPL-2.0-only
/*
* Marvell 88PM80x ONKEY driver
*
* Copyright (C) 2012 Marvell International Ltd.
* Haojian Zhuang <haojian.zhuang@marvell.com>
* Qiao Zhou <zhouqiao@marvell.com>
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/kernel.h>
...
...
drivers/input/misc/iqs7222.c
View file @
57ed9567
...
...
@@ -620,6 +620,118 @@ static const struct iqs7222_dev_desc iqs7222_devs[] = {
},
},
},
{
.
prod_num
=
IQS7222_PROD_NUM_D
,
.
fw_major
=
1
,
.
fw_minor
=
2
,
.
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
,
},
},
},
{
.
prod_num
=
IQS7222_PROD_NUM_D
,
.
fw_major
=
1
,
.
fw_minor
=
1
,
.
touch_link
=
1774
,
.
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
,
},
},
},
{
.
prod_num
=
IQS7222_PROD_NUM_D
,
.
fw_major
=
0
,
...
...
drivers/input/mouse/Kconfig
View file @
57ed9567
...
...
@@ -439,16 +439,4 @@ config MOUSE_SYNAPTICS_USB
To compile this driver as a module, choose M here: the
module will be called synaptics_usb.
config MOUSE_NAVPOINT_PXA27x
tristate "Synaptics NavPoint (PXA27x SSP/SPI)"
depends on PXA27x && PXA_SSP
help
This driver adds support for the Synaptics NavPoint touchpad connected
to a PXA27x SSP port in SPI slave mode. The device emulates a mouse;
a tap or tap-and-a-half drag gesture emulates the left mouse button.
For example, use the xf86-input-evdev driver for an X pointing device.
To compile this driver as a module, choose M here: the
module will be called navpoint.
endif
drivers/input/mouse/Makefile
View file @
57ed9567
...
...
@@ -15,7 +15,6 @@ obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o
obj-$(CONFIG_MOUSE_INPORT)
+=
inport.o
obj-$(CONFIG_MOUSE_LOGIBM)
+=
logibm.o
obj-$(CONFIG_MOUSE_MAPLE)
+=
maplemouse.o
obj-$(CONFIG_MOUSE_NAVPOINT_PXA27x)
+=
navpoint.o
obj-$(CONFIG_MOUSE_PC110PAD)
+=
pc110pad.o
obj-$(CONFIG_MOUSE_PS2)
+=
psmouse.o
obj-$(CONFIG_MOUSE_RISCPC)
+=
rpcmouse.o
...
...
drivers/input/mouse/navpoint.c
deleted
100644 → 0
View file @
fbf8d717
// SPDX-License-Identifier: GPL-2.0-only
/*
* Synaptics NavPoint (PXA27x SSP/SPI) driver.
*
* Copyright (C) 2012 Paul Parsons <lost.distance@yahoo.com>
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/input.h>
#include <linux/input/navpoint.h>
#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <linux/pxa2xx_ssp.h>
#include <linux/slab.h>
/*
* Synaptics Modular Embedded Protocol: Module Packet Format.
* Module header byte 2:0 = Length (# bytes that follow)
* Module header byte 4:3 = Control
* Module header byte 7:5 = Module Address
*/
#define HEADER_LENGTH(byte) ((byte) & 0x07)
#define HEADER_CONTROL(byte) (((byte) >> 3) & 0x03)
#define HEADER_ADDRESS(byte) ((byte) >> 5)
struct
navpoint
{
struct
ssp_device
*
ssp
;
struct
input_dev
*
input
;
struct
device
*
dev
;
struct
gpio_desc
*
gpiod
;
int
index
;
u8
data
[
1
+
HEADER_LENGTH
(
0xff
)];
};
/*
* Initialization values for SSCR0_x, SSCR1_x, SSSR_x.
*/
static
const
u32
sscr0
=
0
|
SSCR0_TUM
/* TIM = 1; No TUR interrupts */
|
SSCR0_RIM
/* RIM = 1; No ROR interrupts */
|
SSCR0_SSE
/* SSE = 1; SSP enabled */
|
SSCR0_Motorola
/* FRF = 0; Motorola SPI */
|
SSCR0_DataSize
(
16
)
/* DSS = 15; Data size = 16-bit */
;
static
const
u32
sscr1
=
0
|
SSCR1_SCFR
/* SCFR = 1; SSPSCLK only during transfers */
|
SSCR1_SCLKDIR
/* SCLKDIR = 1; Slave mode */
|
SSCR1_SFRMDIR
/* SFRMDIR = 1; Slave mode */
|
SSCR1_RWOT
/* RWOT = 1; Receive without transmit mode */
|
SSCR1_RxTresh
(
1
)
/* RFT = 0; Receive FIFO threshold = 1 */
|
SSCR1_SPH
/* SPH = 1; SSPSCLK inactive 0.5 + 1 cycles */
|
SSCR1_RIE
/* RIE = 1; Receive FIFO interrupt enabled */
;
static
const
u32
sssr
=
0
|
SSSR_BCE
/* BCE = 1; Clear BCE */
|
SSSR_TUR
/* TUR = 1; Clear TUR */
|
SSSR_EOC
/* EOC = 1; Clear EOC */
|
SSSR_TINT
/* TINT = 1; Clear TINT */
|
SSSR_PINT
/* PINT = 1; Clear PINT */
|
SSSR_ROR
/* ROR = 1; Clear ROR */
;
/*
* MEP Query $22: Touchpad Coordinate Range Query is not supported by
* the NavPoint module, so sampled values provide the default limits.
*/
#define NAVPOINT_X_MIN 1278
#define NAVPOINT_X_MAX 5340
#define NAVPOINT_Y_MIN 1572
#define NAVPOINT_Y_MAX 4396
#define NAVPOINT_PRESSURE_MIN 0
#define NAVPOINT_PRESSURE_MAX 255
static
void
navpoint_packet
(
struct
navpoint
*
navpoint
)
{
int
finger
;
int
gesture
;
int
x
,
y
,
z
;
switch
(
navpoint
->
data
[
0
])
{
case
0xff
:
/* Garbage (packet?) between reset and Hello packet */
case
0x00
:
/* Module 0, NULL packet */
break
;
case
0x0e
:
/* Module 0, Absolute packet */
finger
=
(
navpoint
->
data
[
1
]
&
0x01
);
gesture
=
(
navpoint
->
data
[
1
]
&
0x02
);
x
=
((
navpoint
->
data
[
2
]
&
0x1f
)
<<
8
)
|
navpoint
->
data
[
3
];
y
=
((
navpoint
->
data
[
4
]
&
0x1f
)
<<
8
)
|
navpoint
->
data
[
5
];
z
=
navpoint
->
data
[
6
];
input_report_key
(
navpoint
->
input
,
BTN_TOUCH
,
finger
);
input_report_abs
(
navpoint
->
input
,
ABS_X
,
x
);
input_report_abs
(
navpoint
->
input
,
ABS_Y
,
y
);
input_report_abs
(
navpoint
->
input
,
ABS_PRESSURE
,
z
);
input_report_key
(
navpoint
->
input
,
BTN_TOOL_FINGER
,
finger
);
input_report_key
(
navpoint
->
input
,
BTN_LEFT
,
gesture
);
input_sync
(
navpoint
->
input
);
break
;
case
0x19
:
/* Module 0, Hello packet */
if
((
navpoint
->
data
[
1
]
&
0xf0
)
==
0x10
)
break
;
fallthrough
;
default:
dev_warn
(
navpoint
->
dev
,
"spurious packet: data=0x%02x,0x%02x,...
\n
"
,
navpoint
->
data
[
0
],
navpoint
->
data
[
1
]);
break
;
}
}
static
irqreturn_t
navpoint_irq
(
int
irq
,
void
*
dev_id
)
{
struct
navpoint
*
navpoint
=
dev_id
;
struct
ssp_device
*
ssp
=
navpoint
->
ssp
;
irqreturn_t
ret
=
IRQ_NONE
;
u32
status
;
status
=
pxa_ssp_read_reg
(
ssp
,
SSSR
);
if
(
status
&
sssr
)
{
dev_warn
(
navpoint
->
dev
,
"unexpected interrupt: status=0x%08x
\n
"
,
status
);
pxa_ssp_write_reg
(
ssp
,
SSSR
,
(
status
&
sssr
));
ret
=
IRQ_HANDLED
;
}
while
(
status
&
SSSR_RNE
)
{
u32
data
;
data
=
pxa_ssp_read_reg
(
ssp
,
SSDR
);
navpoint
->
data
[
navpoint
->
index
+
0
]
=
(
data
>>
8
);
navpoint
->
data
[
navpoint
->
index
+
1
]
=
data
;
navpoint
->
index
+=
2
;
if
(
HEADER_LENGTH
(
navpoint
->
data
[
0
])
<
navpoint
->
index
)
{
navpoint_packet
(
navpoint
);
navpoint
->
index
=
0
;
}
status
=
pxa_ssp_read_reg
(
ssp
,
SSSR
);
ret
=
IRQ_HANDLED
;
}
return
ret
;
}
static
void
navpoint_up
(
struct
navpoint
*
navpoint
)
{
struct
ssp_device
*
ssp
=
navpoint
->
ssp
;
int
timeout
;
clk_prepare_enable
(
ssp
->
clk
);
pxa_ssp_write_reg
(
ssp
,
SSCR1
,
sscr1
);
pxa_ssp_write_reg
(
ssp
,
SSSR
,
sssr
);
pxa_ssp_write_reg
(
ssp
,
SSTO
,
0
);
pxa_ssp_write_reg
(
ssp
,
SSCR0
,
sscr0
);
/* SSCR0_SSE written last */
/* Wait until SSP port is ready for slave clock operations */
for
(
timeout
=
100
;
timeout
!=
0
;
--
timeout
)
{
if
(
!
(
pxa_ssp_read_reg
(
ssp
,
SSSR
)
&
SSSR_CSS
))
break
;
msleep
(
1
);
}
if
(
timeout
==
0
)
dev_err
(
navpoint
->
dev
,
"timeout waiting for SSSR[CSS] to clear
\n
"
);
gpiod_set_value
(
navpoint
->
gpiod
,
1
);
}
static
void
navpoint_down
(
struct
navpoint
*
navpoint
)
{
struct
ssp_device
*
ssp
=
navpoint
->
ssp
;
gpiod_set_value
(
navpoint
->
gpiod
,
0
);
pxa_ssp_write_reg
(
ssp
,
SSCR0
,
0
);
clk_disable_unprepare
(
ssp
->
clk
);
}
static
int
navpoint_open
(
struct
input_dev
*
input
)
{
struct
navpoint
*
navpoint
=
input_get_drvdata
(
input
);
navpoint_up
(
navpoint
);
return
0
;
}
static
void
navpoint_close
(
struct
input_dev
*
input
)
{
struct
navpoint
*
navpoint
=
input_get_drvdata
(
input
);
navpoint_down
(
navpoint
);
}
static
int
navpoint_probe
(
struct
platform_device
*
pdev
)
{
const
struct
navpoint_platform_data
*
pdata
=
dev_get_platdata
(
&
pdev
->
dev
);
struct
ssp_device
*
ssp
;
struct
input_dev
*
input
;
struct
navpoint
*
navpoint
;
int
error
;
if
(
!
pdata
)
{
dev_err
(
&
pdev
->
dev
,
"no platform data
\n
"
);
return
-
EINVAL
;
}
ssp
=
pxa_ssp_request
(
pdata
->
port
,
pdev
->
name
);
if
(
!
ssp
)
return
-
ENODEV
;
/* HaRET does not disable devices before jumping into Linux */
if
(
pxa_ssp_read_reg
(
ssp
,
SSCR0
)
&
SSCR0_SSE
)
{
pxa_ssp_write_reg
(
ssp
,
SSCR0
,
0
);
dev_warn
(
&
pdev
->
dev
,
"ssp%d already enabled
\n
"
,
pdata
->
port
);
}
navpoint
=
kzalloc
(
sizeof
(
*
navpoint
),
GFP_KERNEL
);
input
=
input_allocate_device
();
if
(
!
navpoint
||
!
input
)
{
error
=
-
ENOMEM
;
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
;
input
->
name
=
pdev
->
name
;
input
->
dev
.
parent
=
&
pdev
->
dev
;
__set_bit
(
EV_KEY
,
input
->
evbit
);
__set_bit
(
EV_ABS
,
input
->
evbit
);
__set_bit
(
BTN_LEFT
,
input
->
keybit
);
__set_bit
(
BTN_TOUCH
,
input
->
keybit
);
__set_bit
(
BTN_TOOL_FINGER
,
input
->
keybit
);
input_set_abs_params
(
input
,
ABS_X
,
NAVPOINT_X_MIN
,
NAVPOINT_X_MAX
,
0
,
0
);
input_set_abs_params
(
input
,
ABS_Y
,
NAVPOINT_Y_MIN
,
NAVPOINT_Y_MAX
,
0
,
0
);
input_set_abs_params
(
input
,
ABS_PRESSURE
,
NAVPOINT_PRESSURE_MIN
,
NAVPOINT_PRESSURE_MAX
,
0
,
0
);
input
->
open
=
navpoint_open
;
input
->
close
=
navpoint_close
;
input_set_drvdata
(
input
,
navpoint
);
error
=
request_irq
(
ssp
->
irq
,
navpoint_irq
,
0
,
pdev
->
name
,
navpoint
);
if
(
error
)
goto
err_free_mem
;
error
=
input_register_device
(
input
);
if
(
error
)
goto
err_free_irq
;
platform_set_drvdata
(
pdev
,
navpoint
);
dev_dbg
(
&
pdev
->
dev
,
"ssp%d, irq %d
\n
"
,
pdata
->
port
,
ssp
->
irq
);
return
0
;
err_free_irq:
free_irq
(
ssp
->
irq
,
navpoint
);
err_free_mem:
input_free_device
(
input
);
kfree
(
navpoint
);
pxa_ssp_free
(
ssp
);
return
error
;
}
static
void
navpoint_remove
(
struct
platform_device
*
pdev
)
{
struct
navpoint
*
navpoint
=
platform_get_drvdata
(
pdev
);
struct
ssp_device
*
ssp
=
navpoint
->
ssp
;
free_irq
(
ssp
->
irq
,
navpoint
);
input_unregister_device
(
navpoint
->
input
);
kfree
(
navpoint
);
pxa_ssp_free
(
ssp
);
}
static
int
navpoint_suspend
(
struct
device
*
dev
)
{
struct
platform_device
*
pdev
=
to_platform_device
(
dev
);
struct
navpoint
*
navpoint
=
platform_get_drvdata
(
pdev
);
struct
input_dev
*
input
=
navpoint
->
input
;
mutex_lock
(
&
input
->
mutex
);
if
(
input_device_enabled
(
input
))
navpoint_down
(
navpoint
);
mutex_unlock
(
&
input
->
mutex
);
return
0
;
}
static
int
navpoint_resume
(
struct
device
*
dev
)
{
struct
platform_device
*
pdev
=
to_platform_device
(
dev
);
struct
navpoint
*
navpoint
=
platform_get_drvdata
(
pdev
);
struct
input_dev
*
input
=
navpoint
->
input
;
mutex_lock
(
&
input
->
mutex
);
if
(
input_device_enabled
(
input
))
navpoint_up
(
navpoint
);
mutex_unlock
(
&
input
->
mutex
);
return
0
;
}
static
DEFINE_SIMPLE_DEV_PM_OPS
(
navpoint_pm_ops
,
navpoint_suspend
,
navpoint_resume
);
static
struct
platform_driver
navpoint_driver
=
{
.
probe
=
navpoint_probe
,
.
remove_new
=
navpoint_remove
,
.
driver
=
{
.
name
=
"navpoint"
,
.
pm
=
pm_sleep_ptr
(
&
navpoint_pm_ops
),
},
};
module_platform_driver
(
navpoint_driver
);
MODULE_AUTHOR
(
"Paul Parsons <lost.distance@yahoo.com>"
);
MODULE_DESCRIPTION
(
"Synaptics NavPoint (PXA27x SSP/SPI) driver"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_ALIAS
(
"platform:navpoint"
);
drivers/input/rmi4/rmi_bus.c
View file @
57ed9567
...
...
@@ -344,7 +344,7 @@ static int rmi_bus_match(struct device *dev, struct device_driver *drv)
return
physical
||
rmi_function_match
(
dev
,
drv
);
}
struct
bus_type
rmi_bus_type
=
{
const
struct
bus_type
rmi_bus_type
=
{
.
match
=
rmi_bus_match
,
.
name
=
"rmi4"
,
};
...
...
drivers/input/rmi4/rmi_bus.h
View file @
57ed9567
...
...
@@ -185,7 +185,7 @@ static inline int rmi_write_block(struct rmi_device *d, u16 addr,
int
rmi_for_each_dev
(
void
*
data
,
int
(
*
func
)(
struct
device
*
dev
,
void
*
data
));
extern
struct
bus_type
rmi_bus_type
;
extern
const
struct
bus_type
rmi_bus_type
;
int
rmi_of_property_read_u32
(
struct
device
*
dev
,
u32
*
result
,
const
char
*
prop
,
bool
optional
);
...
...
drivers/input/rmi4/rmi_driver.c
View file @
57ed9567
...
...
@@ -1197,6 +1197,10 @@ static int rmi_driver_probe(struct device *dev)
rmi_driver_set_input_params
(
rmi_dev
,
data
->
input
);
data
->
input
->
phys
=
devm_kasprintf
(
dev
,
GFP_KERNEL
,
"%s/input0"
,
dev_name
(
dev
));
if
(
!
data
->
input
->
phys
)
{
retval
=
-
ENOMEM
;
goto
err
;
}
}
retval
=
rmi_init_functions
(
data
);
...
...
drivers/input/serio/serio.c
View file @
57ed9567
...
...
@@ -1007,7 +1007,7 @@ irqreturn_t serio_interrupt(struct serio *serio,
}
EXPORT_SYMBOL
(
serio_interrupt
);
struct
bus_type
serio_bus
=
{
const
struct
bus_type
serio_bus
=
{
.
name
=
"serio"
,
.
drv_groups
=
serio_driver_groups
,
.
match
=
serio_bus_match
,
...
...
drivers/input/serio/xilinx_ps2.c
View file @
57ed9567
...
...
@@ -219,8 +219,7 @@ static void sxps2_close(struct serio *pserio)
/**
* xps2_of_probe - probe method for the PS/2 device.
* @of_dev: pointer to OF device structure
* @match: pointer to the structure used for matching a device
* @ofdev: pointer to OF device structure
*
* This function probes the PS/2 device in the device tree.
* It initializes the driver data structure and the hardware.
...
...
drivers/input/touchscreen/Kconfig
View file @
57ed9567
...
...
@@ -416,6 +416,37 @@ config TOUCHSCREEN_GOODIX
To compile this driver as a module, choose M here: the
module will be called goodix.
config TOUCHSCREEN_GOODIX_BERLIN_CORE
tristate
config TOUCHSCREEN_GOODIX_BERLIN_I2C
tristate "Goodix Berlin I2C touchscreen"
depends on I2C
select REGMAP_I2C
select TOUCHSCREEN_GOODIX_BERLIN_CORE
help
Say Y here if you have a Goodix Berlin IC connected to
your system via I2C.
If unsure, say N.
To compile this driver as a module, choose M here: the
module will be called goodix_berlin_i2c.
config TOUCHSCREEN_GOODIX_BERLIN_SPI
tristate "Goodix Berlin SPI touchscreen"
depends on SPI_MASTER
select REGMAP
select TOUCHSCREEN_GOODIX_BERLIN_CORE
help
Say Y here if you have a Goodix Berlin IC connected to
your system via SPI.
If unsure, say N.
To compile this driver as a module, choose M here: the
module will be called goodix_berlin_spi.
config TOUCHSCREEN_HIDEEP
tristate "HiDeep Touch IC"
depends on I2C
...
...
drivers/input/touchscreen/Makefile
View file @
57ed9567
...
...
@@ -47,6 +47,9 @@ obj-$(CONFIG_TOUCHSCREEN_EGALAX_SERIAL) += egalax_ts_serial.o
obj-$(CONFIG_TOUCHSCREEN_EXC3000)
+=
exc3000.o
obj-$(CONFIG_TOUCHSCREEN_FUJITSU)
+=
fujitsu_ts.o
obj-$(CONFIG_TOUCHSCREEN_GOODIX)
+=
goodix_ts.o
obj-$(CONFIG_TOUCHSCREEN_GOODIX_BERLIN_CORE)
+=
goodix_berlin_core.o
obj-$(CONFIG_TOUCHSCREEN_GOODIX_BERLIN_I2C)
+=
goodix_berlin_i2c.o
obj-$(CONFIG_TOUCHSCREEN_GOODIX_BERLIN_SPI)
+=
goodix_berlin_spi.o
obj-$(CONFIG_TOUCHSCREEN_HIDEEP)
+=
hideep.o
obj-$(CONFIG_TOUCHSCREEN_HYNITRON_CSTXXX)
+=
hynitron_cstxxx.o
obj-$(CONFIG_TOUCHSCREEN_ILI210X)
+=
ili210x.o
...
...
drivers/input/touchscreen/goodix_berlin.h
0 → 100644
View file @
57ed9567
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Goodix Touchscreen Driver
* Copyright (C) 2020 - 2021 Goodix, Inc.
* Copyright (C) 2023 Linaro Ltd.
*
* Based on goodix_berlin_berlin driver.
*/
#ifndef __GOODIX_BERLIN_H_
#define __GOODIX_BERLIN_H_
#include <linux/pm.h>
struct
device
;
struct
input_id
;
struct
regmap
;
int
goodix_berlin_probe
(
struct
device
*
dev
,
int
irq
,
const
struct
input_id
*
id
,
struct
regmap
*
regmap
);
extern
const
struct
dev_pm_ops
goodix_berlin_pm_ops
;
#endif
drivers/input/touchscreen/goodix_berlin_core.c
0 → 100644
View file @
57ed9567
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Goodix "Berlin" Touchscreen IC driver
* Copyright (C) 2020 - 2021 Goodix, Inc.
* Copyright (C) 2023 Linaro Ltd.
*
* Based on goodix_ts_berlin driver.
*
* This driver is distinct from goodix.c since hardware interface
* is different enough to require a new driver.
* None of the register address or data structure are close enough
* to the previous generations.
*
* Currently the driver only handles Multitouch events with already
* programmed firmware and "config" for "Revision D" Berlin IC.
*
* Support is missing for:
* - ESD Management
* - Firmware update/flashing
* - "Config" update/flashing
* - Stylus Events
* - Gesture Events
* - Support for older revisions (A & B)
*/
#include <linux/bitfield.h>
#include <linux/gpio/consumer.h>
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/input/touchscreen.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/sizes.h>
#include <asm/unaligned.h>
#include "goodix_berlin.h"
#define GOODIX_BERLIN_MAX_TOUCH 10
#define GOODIX_BERLIN_NORMAL_RESET_DELAY_MS 100
#define GOODIX_BERLIN_TOUCH_EVENT BIT(7)
#define GOODIX_BERLIN_REQUEST_EVENT BIT(6)
#define GOODIX_BERLIN_TOUCH_COUNT_MASK GENMASK(3, 0)
#define GOODIX_BERLIN_REQUEST_CODE_RESET 3
#define GOODIX_BERLIN_POINT_TYPE_MASK GENMASK(3, 0)
#define GOODIX_BERLIN_POINT_TYPE_STYLUS_HOVER 1
#define GOODIX_BERLIN_POINT_TYPE_STYLUS 3
#define GOODIX_BERLIN_TOUCH_ID_MASK GENMASK(7, 4)
#define GOODIX_BERLIN_DEV_CONFIRM_VAL 0xAA
#define GOODIX_BERLIN_BOOTOPTION_ADDR 0x10000
#define GOODIX_BERLIN_FW_VERSION_INFO_ADDR 0x10014
#define GOODIX_BERLIN_IC_INFO_MAX_LEN SZ_1K
#define GOODIX_BERLIN_IC_INFO_ADDR 0x10070
#define GOODIX_BERLIN_CHECKSUM_SIZE sizeof(u16)
struct
goodix_berlin_fw_version
{
u8
rom_pid
[
6
];
u8
rom_vid
[
3
];
u8
rom_vid_reserved
;
u8
patch_pid
[
8
];
u8
patch_vid
[
4
];
u8
patch_vid_reserved
;
u8
sensor_id
;
u8
reserved
[
2
];
__le16
checksum
;
};
struct
goodix_berlin_ic_info_version
{
u8
info_customer_id
;
u8
info_version_id
;
u8
ic_die_id
;
u8
ic_version_id
;
__le32
config_id
;
u8
config_version
;
u8
frame_data_customer_id
;
u8
frame_data_version_id
;
u8
touch_data_customer_id
;
u8
touch_data_version_id
;
u8
reserved
[
3
];
}
__packed
;
struct
goodix_berlin_ic_info_feature
{
__le16
freqhop_feature
;
__le16
calibration_feature
;
__le16
gesture_feature
;
__le16
side_touch_feature
;
__le16
stylus_feature
;
}
__packed
;
struct
goodix_berlin_ic_info_misc
{
__le32
cmd_addr
;
__le16
cmd_max_len
;
__le32
cmd_reply_addr
;
__le16
cmd_reply_len
;
__le32
fw_state_addr
;
__le16
fw_state_len
;
__le32
fw_buffer_addr
;
__le16
fw_buffer_max_len
;
__le32
frame_data_addr
;
__le16
frame_data_head_len
;
__le16
fw_attr_len
;
__le16
fw_log_len
;
u8
pack_max_num
;
u8
pack_compress_version
;
__le16
stylus_struct_len
;
__le16
mutual_struct_len
;
__le16
self_struct_len
;
__le16
noise_struct_len
;
__le32
touch_data_addr
;
__le16
touch_data_head_len
;
__le16
point_struct_len
;
__le16
reserved1
;
__le16
reserved2
;
__le32
mutual_rawdata_addr
;
__le32
mutual_diffdata_addr
;
__le32
mutual_refdata_addr
;
__le32
self_rawdata_addr
;
__le32
self_diffdata_addr
;
__le32
self_refdata_addr
;
__le32
iq_rawdata_addr
;
__le32
iq_refdata_addr
;
__le32
im_rawdata_addr
;
__le16
im_readata_len
;
__le32
noise_rawdata_addr
;
__le16
noise_rawdata_len
;
__le32
stylus_rawdata_addr
;
__le16
stylus_rawdata_len
;
__le32
noise_data_addr
;
__le32
esd_addr
;
}
__packed
;
struct
goodix_berlin_touch
{
u8
status
;
u8
reserved
;
__le16
x
;
__le16
y
;
__le16
w
;
};
#define GOODIX_BERLIN_TOUCH_SIZE sizeof(struct goodix_berlin_touch)
struct
goodix_berlin_header
{
u8
status
;
u8
reserved1
;
u8
request_type
;
u8
reserved2
[
3
];
__le16
checksum
;
};
#define GOODIX_BERLIN_HEADER_SIZE sizeof(struct goodix_berlin_header)
struct
goodix_berlin_event
{
struct
goodix_berlin_header
hdr
;
/* The data below is u16/__le16 aligned */
u8
data
[
GOODIX_BERLIN_TOUCH_SIZE
*
GOODIX_BERLIN_MAX_TOUCH
+
GOODIX_BERLIN_CHECKSUM_SIZE
];
};
struct
goodix_berlin_core
{
struct
device
*
dev
;
struct
regmap
*
regmap
;
struct
regulator
*
avdd
;
struct
regulator
*
iovdd
;
struct
gpio_desc
*
reset_gpio
;
struct
touchscreen_properties
props
;
struct
goodix_berlin_fw_version
fw_version
;
struct
input_dev
*
input_dev
;
int
irq
;
/* Runtime parameters extracted from IC_INFO buffer */
u32
touch_data_addr
;
struct
goodix_berlin_event
event
;
};
static
bool
goodix_berlin_checksum_valid
(
const
u8
*
data
,
int
size
)
{
u32
cal_checksum
=
0
;
u16
r_checksum
;
int
i
;
if
(
size
<
GOODIX_BERLIN_CHECKSUM_SIZE
)
return
false
;
for
(
i
=
0
;
i
<
size
-
GOODIX_BERLIN_CHECKSUM_SIZE
;
i
++
)
cal_checksum
+=
data
[
i
];
r_checksum
=
get_unaligned_le16
(
&
data
[
i
]);
return
(
u16
)
cal_checksum
==
r_checksum
;
}
static
bool
goodix_berlin_is_dummy_data
(
struct
goodix_berlin_core
*
cd
,
const
u8
*
data
,
int
size
)
{
int
i
;
/*
* If the device is missing or doesn't respond the buffer
* could be filled with bus default line state, 0x00 or 0xff,
* so declare success the first time we encounter neither.
*/
for
(
i
=
0
;
i
<
size
;
i
++
)
if
(
data
[
i
]
>
0
&&
data
[
i
]
<
0xff
)
return
false
;
return
true
;
}
static
int
goodix_berlin_dev_confirm
(
struct
goodix_berlin_core
*
cd
)
{
u8
tx_buf
[
8
],
rx_buf
[
8
];
int
retry
=
3
;
int
error
;
memset
(
tx_buf
,
GOODIX_BERLIN_DEV_CONFIRM_VAL
,
sizeof
(
tx_buf
));
while
(
retry
--
)
{
error
=
regmap_raw_write
(
cd
->
regmap
,
GOODIX_BERLIN_BOOTOPTION_ADDR
,
tx_buf
,
sizeof
(
tx_buf
));
if
(
error
)
return
error
;
error
=
regmap_raw_read
(
cd
->
regmap
,
GOODIX_BERLIN_BOOTOPTION_ADDR
,
rx_buf
,
sizeof
(
rx_buf
));
if
(
error
)
return
error
;
if
(
!
memcmp
(
tx_buf
,
rx_buf
,
sizeof
(
tx_buf
)))
return
0
;
usleep_range
(
5000
,
5100
);
}
dev_err
(
cd
->
dev
,
"device confirm failed, rx_buf: %*ph
\n
"
,
(
int
)
sizeof
(
rx_buf
),
rx_buf
);
return
-
EINVAL
;
}
static
int
goodix_berlin_power_on
(
struct
goodix_berlin_core
*
cd
)
{
int
error
;
error
=
regulator_enable
(
cd
->
iovdd
);
if
(
error
)
{
dev_err
(
cd
->
dev
,
"Failed to enable iovdd: %d
\n
"
,
error
);
return
error
;
}
/* Vendor waits 3ms for IOVDD to settle */
usleep_range
(
3000
,
3100
);
error
=
regulator_enable
(
cd
->
avdd
);
if
(
error
)
{
dev_err
(
cd
->
dev
,
"Failed to enable avdd: %d
\n
"
,
error
);
goto
err_iovdd_disable
;
}
/* Vendor waits 15ms for IOVDD to settle */
usleep_range
(
15000
,
15100
);
gpiod_set_value_cansleep
(
cd
->
reset_gpio
,
0
);
/* Vendor waits 4ms for Firmware to initialize */
usleep_range
(
4000
,
4100
);
error
=
goodix_berlin_dev_confirm
(
cd
);
if
(
error
)
goto
err_dev_reset
;
/* Vendor waits 100ms for Firmware to fully boot */
msleep
(
GOODIX_BERLIN_NORMAL_RESET_DELAY_MS
);
return
0
;
err_dev_reset:
gpiod_set_value_cansleep
(
cd
->
reset_gpio
,
1
);
regulator_disable
(
cd
->
avdd
);
err_iovdd_disable:
regulator_disable
(
cd
->
iovdd
);
return
error
;
}
static
void
goodix_berlin_power_off
(
struct
goodix_berlin_core
*
cd
)
{
gpiod_set_value_cansleep
(
cd
->
reset_gpio
,
1
);
regulator_disable
(
cd
->
avdd
);
regulator_disable
(
cd
->
iovdd
);
}
static
int
goodix_berlin_read_version
(
struct
goodix_berlin_core
*
cd
)
{
int
error
;
error
=
regmap_raw_read
(
cd
->
regmap
,
GOODIX_BERLIN_FW_VERSION_INFO_ADDR
,
&
cd
->
fw_version
,
sizeof
(
cd
->
fw_version
));
if
(
error
)
{
dev_err
(
cd
->
dev
,
"error reading fw version, %d
\n
"
,
error
);
return
error
;
}
if
(
!
goodix_berlin_checksum_valid
((
u8
*
)
&
cd
->
fw_version
,
sizeof
(
cd
->
fw_version
)))
{
dev_err
(
cd
->
dev
,
"invalid fw version: checksum error
\n
"
);
return
-
EINVAL
;
}
return
0
;
}
/* Only extract necessary data for runtime */
static
int
goodix_berlin_parse_ic_info
(
struct
goodix_berlin_core
*
cd
,
const
u8
*
data
,
u16
length
)
{
struct
goodix_berlin_ic_info_misc
*
misc
;
unsigned
int
offset
=
0
;
offset
+=
sizeof
(
__le16
);
/* length */
offset
+=
sizeof
(
struct
goodix_berlin_ic_info_version
);
offset
+=
sizeof
(
struct
goodix_berlin_ic_info_feature
);
/* IC_INFO Parameters, variable width structure */
offset
+=
4
*
sizeof
(
u8
);
/* drv_num, sen_num, button_num, force_num */
if
(
offset
>=
length
)
goto
invalid_offset
;
#define ADVANCE_LE16_PARAMS() \
do { \
u8 param_num = data[offset++]; \
offset += param_num * sizeof(__le16); \
if (offset >= length) \
goto invalid_offset; \
} while (0)
ADVANCE_LE16_PARAMS
();
/* active_scan_rate_num */
ADVANCE_LE16_PARAMS
();
/* mutual_freq_num*/
ADVANCE_LE16_PARAMS
();
/* self_tx_freq_num */
ADVANCE_LE16_PARAMS
();
/* self_rx_freq_num */
ADVANCE_LE16_PARAMS
();
/* stylus_freq_num */
#undef ADVANCE_LE16_PARAMS
misc
=
(
struct
goodix_berlin_ic_info_misc
*
)
&
data
[
offset
];
cd
->
touch_data_addr
=
le32_to_cpu
(
misc
->
touch_data_addr
);
return
0
;
invalid_offset:
dev_err
(
cd
->
dev
,
"ic_info length is invalid (offset %d length %d)
\n
"
,
offset
,
length
);
return
-
EINVAL
;
}
static
int
goodix_berlin_get_ic_info
(
struct
goodix_berlin_core
*
cd
)
{
u8
*
afe_data
__free
(
kfree
)
=
NULL
;
__le16
length_raw
;
u16
length
;
int
error
;
afe_data
=
kzalloc
(
GOODIX_BERLIN_IC_INFO_MAX_LEN
,
GFP_KERNEL
);
if
(
!
afe_data
)
return
-
ENOMEM
;
error
=
regmap_raw_read
(
cd
->
regmap
,
GOODIX_BERLIN_IC_INFO_ADDR
,
&
length_raw
,
sizeof
(
length_raw
));
if
(
error
)
{
dev_err
(
cd
->
dev
,
"failed get ic info length, %d
\n
"
,
error
);
return
error
;
}
length
=
le16_to_cpu
(
length_raw
);
if
(
length
>=
GOODIX_BERLIN_IC_INFO_MAX_LEN
)
{
dev_err
(
cd
->
dev
,
"invalid ic info length %d
\n
"
,
length
);
return
-
EINVAL
;
}
error
=
regmap_raw_read
(
cd
->
regmap
,
GOODIX_BERLIN_IC_INFO_ADDR
,
afe_data
,
length
);
if
(
error
)
{
dev_err
(
cd
->
dev
,
"failed get ic info data, %d
\n
"
,
error
);
return
error
;
}
/* check whether the data is valid (ex. bus default values) */
if
(
goodix_berlin_is_dummy_data
(
cd
,
afe_data
,
length
))
{
dev_err
(
cd
->
dev
,
"fw info data invalid
\n
"
);
return
-
EINVAL
;
}
if
(
!
goodix_berlin_checksum_valid
(
afe_data
,
length
))
{
dev_err
(
cd
->
dev
,
"fw info checksum error
\n
"
);
return
-
EINVAL
;
}
error
=
goodix_berlin_parse_ic_info
(
cd
,
afe_data
,
length
);
if
(
error
)
return
error
;
/* check some key info */
if
(
!
cd
->
touch_data_addr
)
{
dev_err
(
cd
->
dev
,
"touch_data_addr is null
\n
"
);
return
-
EINVAL
;
}
return
0
;
}
static
int
goodix_berlin_get_remaining_contacts
(
struct
goodix_berlin_core
*
cd
,
int
n
)
{
size_t
offset
=
2
*
GOODIX_BERLIN_TOUCH_SIZE
+
GOODIX_BERLIN_CHECKSUM_SIZE
;
u32
addr
=
cd
->
touch_data_addr
+
GOODIX_BERLIN_HEADER_SIZE
+
offset
;
int
error
;
error
=
regmap_raw_read
(
cd
->
regmap
,
addr
,
&
cd
->
event
.
data
[
offset
],
(
n
-
2
)
*
GOODIX_BERLIN_TOUCH_SIZE
);
if
(
error
)
{
dev_err_ratelimited
(
cd
->
dev
,
"failed to get touch data, %d
\n
"
,
error
);
return
error
;
}
return
0
;
}
static
void
goodix_berlin_report_state
(
struct
goodix_berlin_core
*
cd
,
int
n
)
{
struct
goodix_berlin_touch
*
touch_data
=
(
struct
goodix_berlin_touch
*
)
cd
->
event
.
data
;
struct
goodix_berlin_touch
*
t
;
int
i
;
u8
type
,
id
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
t
=
&
touch_data
[
i
];
type
=
FIELD_GET
(
GOODIX_BERLIN_POINT_TYPE_MASK
,
t
->
status
);
if
(
type
==
GOODIX_BERLIN_POINT_TYPE_STYLUS
||
type
==
GOODIX_BERLIN_POINT_TYPE_STYLUS_HOVER
)
{
dev_warn_once
(
cd
->
dev
,
"Stylus event type not handled
\n
"
);
continue
;
}
id
=
FIELD_GET
(
GOODIX_BERLIN_TOUCH_ID_MASK
,
t
->
status
);
if
(
id
>=
GOODIX_BERLIN_MAX_TOUCH
)
{
dev_warn_ratelimited
(
cd
->
dev
,
"invalid finger id %d
\n
"
,
id
);
continue
;
}
input_mt_slot
(
cd
->
input_dev
,
id
);
input_mt_report_slot_state
(
cd
->
input_dev
,
MT_TOOL_FINGER
,
true
);
touchscreen_report_pos
(
cd
->
input_dev
,
&
cd
->
props
,
__le16_to_cpu
(
t
->
x
),
__le16_to_cpu
(
t
->
y
),
true
);
input_report_abs
(
cd
->
input_dev
,
ABS_MT_TOUCH_MAJOR
,
__le16_to_cpu
(
t
->
w
));
}
input_mt_sync_frame
(
cd
->
input_dev
);
input_sync
(
cd
->
input_dev
);
}
static
void
goodix_berlin_touch_handler
(
struct
goodix_berlin_core
*
cd
)
{
u8
touch_num
;
int
error
;
touch_num
=
FIELD_GET
(
GOODIX_BERLIN_TOUCH_COUNT_MASK
,
cd
->
event
.
hdr
.
request_type
);
if
(
touch_num
>
GOODIX_BERLIN_MAX_TOUCH
)
{
dev_warn
(
cd
->
dev
,
"invalid touch num %d
\n
"
,
touch_num
);
return
;
}
if
(
touch_num
>
2
)
{
/* read additional contact data if more than 2 touch events */
error
=
goodix_berlin_get_remaining_contacts
(
cd
,
touch_num
);
if
(
error
)
return
;
}
if
(
touch_num
)
{
int
len
=
touch_num
*
GOODIX_BERLIN_TOUCH_SIZE
+
GOODIX_BERLIN_CHECKSUM_SIZE
;
if
(
!
goodix_berlin_checksum_valid
(
cd
->
event
.
data
,
len
))
{
dev_err
(
cd
->
dev
,
"touch data checksum error: %*ph
\n
"
,
len
,
cd
->
event
.
data
);
return
;
}
}
goodix_berlin_report_state
(
cd
,
touch_num
);
}
static
int
goodix_berlin_request_handle_reset
(
struct
goodix_berlin_core
*
cd
)
{
gpiod_set_value_cansleep
(
cd
->
reset_gpio
,
1
);
usleep_range
(
2000
,
2100
);
gpiod_set_value_cansleep
(
cd
->
reset_gpio
,
0
);
msleep
(
GOODIX_BERLIN_NORMAL_RESET_DELAY_MS
);
return
0
;
}
static
irqreturn_t
goodix_berlin_irq
(
int
irq
,
void
*
data
)
{
struct
goodix_berlin_core
*
cd
=
data
;
int
error
;
/*
* First, read buffer with space for 2 touch events:
* - GOODIX_BERLIN_HEADER_SIZE = 8 bytes
* - GOODIX_BERLIN_TOUCH_SIZE * 2 = 16 bytes
* - GOODIX_BERLIN_CHECKLSUM_SIZE = 2 bytes
* For a total of 26 bytes.
*
* If only a single finger is reported, we will read 8 bytes more than
* needed:
* - bytes 0-7: Header (GOODIX_BERLIN_HEADER_SIZE)
* - bytes 8-15: Finger 0 Data
* - bytes 24-25: Checksum
* - bytes 18-25: Unused 8 bytes
*
* If 2 fingers are reported, we would have read the exact needed
* amount of data and checksum would be at the end of the buffer:
* - bytes 0-7: Header (GOODIX_BERLIN_HEADER_SIZE)
* - bytes 8-15: Finger 0 Bytes 0-7
* - bytes 16-23: Finger 1 Bytes 0-7
* - bytes 24-25: Checksum
*
* If more than 2 fingers were reported, the "Checksum" bytes would
* in fact contain part of the next finger data, and then
* goodix_berlin_get_remaining_contacts() would complete the buffer
* with the missing bytes, including the trailing checksum.
* For example, if 3 fingers are reported, then we would do:
* Read 1:
* - bytes 0-7: Header (GOODIX_BERLIN_HEADER_SIZE)
* - bytes 8-15: Finger 0 Bytes 0-7
* - bytes 16-23: Finger 1 Bytes 0-7
* - bytes 24-25: Finger 2 Bytes 0-1
* Read 2 (with length of (3 - 2) * 8 = 8 bytes):
* - bytes 26-31: Finger 2 Bytes 2-7
* - bytes 32-33: Checksum
*/
error
=
regmap_raw_read
(
cd
->
regmap
,
cd
->
touch_data_addr
,
&
cd
->
event
,
GOODIX_BERLIN_HEADER_SIZE
+
2
*
GOODIX_BERLIN_TOUCH_SIZE
+
GOODIX_BERLIN_CHECKSUM_SIZE
);
if
(
error
)
{
dev_warn_ratelimited
(
cd
->
dev
,
"failed get event head data: %d
\n
"
,
error
);
goto
out
;
}
if
(
cd
->
event
.
hdr
.
status
==
0
)
goto
out
;
if
(
!
goodix_berlin_checksum_valid
((
u8
*
)
&
cd
->
event
.
hdr
,
GOODIX_BERLIN_HEADER_SIZE
))
{
dev_warn_ratelimited
(
cd
->
dev
,
"touch head checksum error: %*ph
\n
"
,
(
int
)
GOODIX_BERLIN_HEADER_SIZE
,
&
cd
->
event
.
hdr
);
goto
out_clear
;
}
if
(
cd
->
event
.
hdr
.
status
&
GOODIX_BERLIN_TOUCH_EVENT
)
goodix_berlin_touch_handler
(
cd
);
if
(
cd
->
event
.
hdr
.
status
&
GOODIX_BERLIN_REQUEST_EVENT
)
{
switch
(
cd
->
event
.
hdr
.
request_type
)
{
case
GOODIX_BERLIN_REQUEST_CODE_RESET
:
if
(
cd
->
reset_gpio
)
goodix_berlin_request_handle_reset
(
cd
);
break
;
default:
dev_warn
(
cd
->
dev
,
"unsupported request code 0x%x
\n
"
,
cd
->
event
.
hdr
.
request_type
);
}
}
out_clear:
/* Clear up status field */
regmap_write
(
cd
->
regmap
,
cd
->
touch_data_addr
,
0
);
out:
return
IRQ_HANDLED
;
}
static
int
goodix_berlin_input_dev_config
(
struct
goodix_berlin_core
*
cd
,
const
struct
input_id
*
id
)
{
struct
input_dev
*
input_dev
;
int
error
;
input_dev
=
devm_input_allocate_device
(
cd
->
dev
);
if
(
!
input_dev
)
return
-
ENOMEM
;
cd
->
input_dev
=
input_dev
;
input_set_drvdata
(
input_dev
,
cd
);
input_dev
->
name
=
"Goodix Berlin Capacitive TouchScreen"
;
input_dev
->
phys
=
"input/ts"
;
input_dev
->
id
=
*
id
;
input_set_abs_params
(
cd
->
input_dev
,
ABS_MT_POSITION_X
,
0
,
SZ_64K
-
1
,
0
,
0
);
input_set_abs_params
(
cd
->
input_dev
,
ABS_MT_POSITION_Y
,
0
,
SZ_64K
-
1
,
0
,
0
);
input_set_abs_params
(
cd
->
input_dev
,
ABS_MT_TOUCH_MAJOR
,
0
,
255
,
0
,
0
);
touchscreen_parse_properties
(
cd
->
input_dev
,
true
,
&
cd
->
props
);
error
=
input_mt_init_slots
(
cd
->
input_dev
,
GOODIX_BERLIN_MAX_TOUCH
,
INPUT_MT_DIRECT
|
INPUT_MT_DROP_UNUSED
);
if
(
error
)
return
error
;
error
=
input_register_device
(
cd
->
input_dev
);
if
(
error
)
return
error
;
return
0
;
}
static
int
goodix_berlin_suspend
(
struct
device
*
dev
)
{
struct
goodix_berlin_core
*
cd
=
dev_get_drvdata
(
dev
);
disable_irq
(
cd
->
irq
);
goodix_berlin_power_off
(
cd
);
return
0
;
}
static
int
goodix_berlin_resume
(
struct
device
*
dev
)
{
struct
goodix_berlin_core
*
cd
=
dev_get_drvdata
(
dev
);
int
error
;
error
=
goodix_berlin_power_on
(
cd
);
if
(
error
)
return
error
;
enable_irq
(
cd
->
irq
);
return
0
;
}
EXPORT_GPL_SIMPLE_DEV_PM_OPS
(
goodix_berlin_pm_ops
,
goodix_berlin_suspend
,
goodix_berlin_resume
);
static
void
goodix_berlin_power_off_act
(
void
*
data
)
{
struct
goodix_berlin_core
*
cd
=
data
;
goodix_berlin_power_off
(
cd
);
}
int
goodix_berlin_probe
(
struct
device
*
dev
,
int
irq
,
const
struct
input_id
*
id
,
struct
regmap
*
regmap
)
{
struct
goodix_berlin_core
*
cd
;
int
error
;
if
(
irq
<=
0
)
{
dev_err
(
dev
,
"Missing interrupt number
\n
"
);
return
-
EINVAL
;
}
cd
=
devm_kzalloc
(
dev
,
sizeof
(
*
cd
),
GFP_KERNEL
);
if
(
!
cd
)
return
-
ENOMEM
;
cd
->
dev
=
dev
;
cd
->
regmap
=
regmap
;
cd
->
irq
=
irq
;
cd
->
reset_gpio
=
devm_gpiod_get_optional
(
dev
,
"reset"
,
GPIOD_OUT_HIGH
);
if
(
IS_ERR
(
cd
->
reset_gpio
))
return
dev_err_probe
(
dev
,
PTR_ERR
(
cd
->
reset_gpio
),
"Failed to request reset gpio
\n
"
);
cd
->
avdd
=
devm_regulator_get
(
dev
,
"avdd"
);
if
(
IS_ERR
(
cd
->
avdd
))
return
dev_err_probe
(
dev
,
PTR_ERR
(
cd
->
avdd
),
"Failed to request avdd regulator
\n
"
);
cd
->
iovdd
=
devm_regulator_get
(
dev
,
"iovdd"
);
if
(
IS_ERR
(
cd
->
iovdd
))
return
dev_err_probe
(
dev
,
PTR_ERR
(
cd
->
iovdd
),
"Failed to request iovdd regulator
\n
"
);
error
=
goodix_berlin_power_on
(
cd
);
if
(
error
)
{
dev_err
(
dev
,
"failed power on"
);
return
error
;
}
error
=
devm_add_action_or_reset
(
dev
,
goodix_berlin_power_off_act
,
cd
);
if
(
error
)
return
error
;
error
=
goodix_berlin_read_version
(
cd
);
if
(
error
)
{
dev_err
(
dev
,
"failed to get version info"
);
return
error
;
}
error
=
goodix_berlin_get_ic_info
(
cd
);
if
(
error
)
{
dev_err
(
dev
,
"invalid ic info, abort"
);
return
error
;
}
error
=
goodix_berlin_input_dev_config
(
cd
,
id
);
if
(
error
)
{
dev_err
(
dev
,
"failed set input device"
);
return
error
;
}
error
=
devm_request_threaded_irq
(
dev
,
cd
->
irq
,
NULL
,
goodix_berlin_irq
,
IRQF_ONESHOT
,
"goodix-berlin"
,
cd
);
if
(
error
)
{
dev_err
(
dev
,
"request threaded irq failed: %d
\n
"
,
error
);
return
error
;
}
dev_set_drvdata
(
dev
,
cd
);
dev_dbg
(
dev
,
"Goodix Berlin %s Touchscreen Controller"
,
cd
->
fw_version
.
patch_pid
);
return
0
;
}
EXPORT_SYMBOL_GPL
(
goodix_berlin_probe
);
MODULE_LICENSE
(
"GPL"
);
MODULE_DESCRIPTION
(
"Goodix Berlin Core Touchscreen driver"
);
MODULE_AUTHOR
(
"Neil Armstrong <neil.armstrong@linaro.org>"
);
drivers/input/touchscreen/goodix_berlin_i2c.c
0 → 100644
View file @
57ed9567
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Goodix Berlin Touchscreen Driver
*
* Copyright (C) 2020 - 2021 Goodix, Inc.
* Copyright (C) 2023 Linaro Ltd.
*
* Based on goodix_ts_berlin driver.
*/
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/input.h>
#include "goodix_berlin.h"
#define I2C_MAX_TRANSFER_SIZE 256
static
const
struct
regmap_config
goodix_berlin_i2c_regmap_conf
=
{
.
reg_bits
=
32
,
.
val_bits
=
8
,
.
max_raw_read
=
I2C_MAX_TRANSFER_SIZE
,
.
max_raw_write
=
I2C_MAX_TRANSFER_SIZE
,
};
/* vendor & product left unassigned here, should probably be updated from fw info */
static
const
struct
input_id
goodix_berlin_i2c_input_id
=
{
.
bustype
=
BUS_I2C
,
};
static
int
goodix_berlin_i2c_probe
(
struct
i2c_client
*
client
)
{
struct
regmap
*
regmap
;
int
error
;
regmap
=
devm_regmap_init_i2c
(
client
,
&
goodix_berlin_i2c_regmap_conf
);
if
(
IS_ERR
(
regmap
))
return
PTR_ERR
(
regmap
);
error
=
goodix_berlin_probe
(
&
client
->
dev
,
client
->
irq
,
&
goodix_berlin_i2c_input_id
,
regmap
);
if
(
error
)
return
error
;
return
0
;
}
static
const
struct
i2c_device_id
goodix_berlin_i2c_id
[]
=
{
{
"gt9916"
,
0
},
{
}
};
MODULE_DEVICE_TABLE
(
i2c
,
goodix_berlin_i2c_id
);
static
const
struct
of_device_id
goodix_berlin_i2c_of_match
[]
=
{
{
.
compatible
=
"goodix,gt9916"
,
},
{
}
};
MODULE_DEVICE_TABLE
(
of
,
goodix_berlin_i2c_of_match
);
static
struct
i2c_driver
goodix_berlin_i2c_driver
=
{
.
driver
=
{
.
name
=
"goodix-berlin-i2c"
,
.
of_match_table
=
goodix_berlin_i2c_of_match
,
.
pm
=
pm_sleep_ptr
(
&
goodix_berlin_pm_ops
),
},
.
probe
=
goodix_berlin_i2c_probe
,
.
id_table
=
goodix_berlin_i2c_id
,
};
module_i2c_driver
(
goodix_berlin_i2c_driver
);
MODULE_LICENSE
(
"GPL"
);
MODULE_DESCRIPTION
(
"Goodix Berlin I2C Touchscreen driver"
);
MODULE_AUTHOR
(
"Neil Armstrong <neil.armstrong@linaro.org>"
);
drivers/input/touchscreen/goodix_berlin_spi.c
0 → 100644
View file @
57ed9567
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Goodix Berlin Touchscreen Driver
*
* Copyright (C) 2020 - 2021 Goodix, Inc.
* Copyright (C) 2023 Linaro Ltd.
*
* Based on goodix_ts_berlin driver.
*/
#include <asm/unaligned.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/spi/spi.h>
#include <linux/input.h>
#include "goodix_berlin.h"
#define GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN 1
#define GOODIX_BERLIN_REGISTER_WIDTH 4
#define GOODIX_BERLIN_SPI_READ_DUMMY_LEN 3
#define GOODIX_BERLIN_SPI_READ_PREFIX_LEN (GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN + \
GOODIX_BERLIN_REGISTER_WIDTH + \
GOODIX_BERLIN_SPI_READ_DUMMY_LEN)
#define GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN (GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN + \
GOODIX_BERLIN_REGISTER_WIDTH)
#define GOODIX_BERLIN_SPI_WRITE_FLAG 0xF0
#define GOODIX_BERLIN_SPI_READ_FLAG 0xF1
static
int
goodix_berlin_spi_read
(
void
*
context
,
const
void
*
reg_buf
,
size_t
reg_size
,
void
*
val_buf
,
size_t
val_size
)
{
struct
spi_device
*
spi
=
context
;
struct
spi_transfer
xfers
;
struct
spi_message
spi_msg
;
const
u32
*
reg
=
reg_buf
;
/* reg is stored as native u32 at start of buffer */
u8
*
buf
;
int
error
;
if
(
reg_size
!=
GOODIX_BERLIN_REGISTER_WIDTH
)
return
-
EINVAL
;
buf
=
kzalloc
(
GOODIX_BERLIN_SPI_READ_PREFIX_LEN
+
val_size
,
GFP_KERNEL
);
if
(
!
buf
)
return
-
ENOMEM
;
spi_message_init
(
&
spi_msg
);
memset
(
&
xfers
,
0
,
sizeof
(
xfers
));
/* buffer format: 0xF1 + addr(4bytes) + dummy(3bytes) + data */
buf
[
0
]
=
GOODIX_BERLIN_SPI_READ_FLAG
;
put_unaligned_be32
(
*
reg
,
buf
+
GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN
);
memset
(
buf
+
GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN
+
GOODIX_BERLIN_REGISTER_WIDTH
,
0xff
,
GOODIX_BERLIN_SPI_READ_DUMMY_LEN
);
xfers
.
tx_buf
=
buf
;
xfers
.
rx_buf
=
buf
;
xfers
.
len
=
GOODIX_BERLIN_SPI_READ_PREFIX_LEN
+
val_size
;
xfers
.
cs_change
=
0
;
spi_message_add_tail
(
&
xfers
,
&
spi_msg
);
error
=
spi_sync
(
spi
,
&
spi_msg
);
if
(
error
<
0
)
dev_err
(
&
spi
->
dev
,
"spi transfer error, %d"
,
error
);
else
memcpy
(
val_buf
,
buf
+
GOODIX_BERLIN_SPI_READ_PREFIX_LEN
,
val_size
);
kfree
(
buf
);
return
error
;
}
static
int
goodix_berlin_spi_write
(
void
*
context
,
const
void
*
data
,
size_t
count
)
{
unsigned
int
len
=
count
-
GOODIX_BERLIN_REGISTER_WIDTH
;
struct
spi_device
*
spi
=
context
;
struct
spi_transfer
xfers
;
struct
spi_message
spi_msg
;
const
u32
*
reg
=
data
;
/* reg is stored as native u32 at start of buffer */
u8
*
buf
;
int
error
;
buf
=
kzalloc
(
GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN
+
len
,
GFP_KERNEL
);
if
(
!
buf
)
return
-
ENOMEM
;
spi_message_init
(
&
spi_msg
);
memset
(
&
xfers
,
0
,
sizeof
(
xfers
));
buf
[
0
]
=
GOODIX_BERLIN_SPI_WRITE_FLAG
;
put_unaligned_be32
(
*
reg
,
buf
+
GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN
);
memcpy
(
buf
+
GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN
,
data
+
GOODIX_BERLIN_REGISTER_WIDTH
,
len
);
xfers
.
tx_buf
=
buf
;
xfers
.
len
=
GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN
+
len
;
xfers
.
cs_change
=
0
;
spi_message_add_tail
(
&
xfers
,
&
spi_msg
);
error
=
spi_sync
(
spi
,
&
spi_msg
);
if
(
error
<
0
)
dev_err
(
&
spi
->
dev
,
"spi transfer error, %d"
,
error
);
kfree
(
buf
);
return
error
;
}
static
const
struct
regmap_config
goodix_berlin_spi_regmap_conf
=
{
.
reg_bits
=
32
,
.
val_bits
=
8
,
.
read
=
goodix_berlin_spi_read
,
.
write
=
goodix_berlin_spi_write
,
};
/* vendor & product left unassigned here, should probably be updated from fw info */
static
const
struct
input_id
goodix_berlin_spi_input_id
=
{
.
bustype
=
BUS_SPI
,
};
static
int
goodix_berlin_spi_probe
(
struct
spi_device
*
spi
)
{
struct
regmap_config
regmap_config
;
struct
regmap
*
regmap
;
size_t
max_size
;
int
error
=
0
;
spi
->
mode
=
SPI_MODE_0
;
spi
->
bits_per_word
=
8
;
error
=
spi_setup
(
spi
);
if
(
error
)
return
error
;
max_size
=
spi_max_transfer_size
(
spi
);
regmap_config
=
goodix_berlin_spi_regmap_conf
;
regmap_config
.
max_raw_read
=
max_size
-
GOODIX_BERLIN_SPI_READ_PREFIX_LEN
;
regmap_config
.
max_raw_write
=
max_size
-
GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN
;
regmap
=
devm_regmap_init
(
&
spi
->
dev
,
NULL
,
spi
,
&
regmap_config
);
if
(
IS_ERR
(
regmap
))
return
PTR_ERR
(
regmap
);
error
=
goodix_berlin_probe
(
&
spi
->
dev
,
spi
->
irq
,
&
goodix_berlin_spi_input_id
,
regmap
);
if
(
error
)
return
error
;
return
0
;
}
static
const
struct
spi_device_id
goodix_berlin_spi_ids
[]
=
{
{
"gt9916"
},
{
},
};
MODULE_DEVICE_TABLE
(
spi
,
goodix_berlin_spi_ids
);
static
const
struct
of_device_id
goodix_berlin_spi_of_match
[]
=
{
{
.
compatible
=
"goodix,gt9916"
,
},
{
}
};
MODULE_DEVICE_TABLE
(
of
,
goodix_berlin_spi_of_match
);
static
struct
spi_driver
goodix_berlin_spi_driver
=
{
.
driver
=
{
.
name
=
"goodix-berlin-spi"
,
.
of_match_table
=
goodix_berlin_spi_of_match
,
.
pm
=
pm_sleep_ptr
(
&
goodix_berlin_pm_ops
),
},
.
probe
=
goodix_berlin_spi_probe
,
.
id_table
=
goodix_berlin_spi_ids
,
};
module_spi_driver
(
goodix_berlin_spi_driver
);
MODULE_LICENSE
(
"GPL"
);
MODULE_DESCRIPTION
(
"Goodix Berlin SPI Touchscreen driver"
);
MODULE_AUTHOR
(
"Neil Armstrong <neil.armstrong@linaro.org>"
);
drivers/input/touchscreen/imagis.c
View file @
57ed9567
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/bitfield.h>
#include <linux/bits.h>
#include <linux/delay.h>
#include <linux/i2c.h>
...
...
@@ -11,9 +12,15 @@
#include <linux/property.h>
#include <linux/regulator/consumer.h>
#define IST3032C_WHOAMI 0x32c
#define IST3038B_REG_STATUS 0x20
#define IST3038B_REG_CHIPID 0x30
#define IST3038B_WHOAMI 0x30380b
#define IST3038C_HIB_ACCESS (0x800B << 16)
#define IST3038C_DIRECT_ACCESS BIT(31)
#define IST3038C_REG_CHIPID
0x40001000
#define IST3038C_REG_CHIPID
(0x40001000 | IST3038C_DIRECT_ACCESS)
#define IST3038C_REG_HIB_BASE 0x30000100
#define IST3038C_REG_TOUCH_STATUS (IST3038C_REG_HIB_BASE | IST3038C_HIB_ACCESS)
#define IST3038C_REG_TOUCH_COORD (IST3038C_REG_HIB_BASE | IST3038C_HIB_ACCESS | 0x8)
...
...
@@ -23,19 +30,29 @@
#define IST3038C_I2C_RETRY_COUNT 3
#define IST3038C_MAX_FINGER_NUM 10
#define IST3038C_X_MASK GENMASK(23, 12)
#define IST3038C_X_SHIFT 12
#define IST3038C_Y_MASK GENMASK(11, 0)
#define IST3038C_AREA_MASK GENMASK(27, 24)
#define IST3038C_AREA_SHIFT 24
#define IST3038C_FINGER_COUNT_MASK GENMASK(15, 12)
#define IST3038C_FINGER_COUNT_SHIFT 12
#define IST3038C_FINGER_STATUS_MASK GENMASK(9, 0)
#define IST3032C_KEY_STATUS_MASK GENMASK(20, 16)
struct
imagis_properties
{
unsigned
int
interrupt_msg_cmd
;
unsigned
int
touch_coord_cmd
;
unsigned
int
whoami_cmd
;
unsigned
int
whoami_val
;
bool
protocol_b
;
bool
touch_keys_supported
;
};
struct
imagis_ts
{
struct
i2c_client
*
client
;
const
struct
imagis_properties
*
tdata
;
struct
input_dev
*
input_dev
;
struct
touchscreen_properties
prop
;
struct
regulator_bulk_data
supplies
[
2
];
u32
keycodes
[
5
];
int
num_keycodes
;
};
static
int
imagis_i2c_read_reg
(
struct
imagis_ts
*
ts
,
...
...
@@ -80,20 +97,18 @@ static irqreturn_t imagis_interrupt(int irq, void *dev_id)
{
struct
imagis_ts
*
ts
=
dev_id
;
u32
intr_message
,
finger_status
;
unsigned
int
finger_count
,
finger_pressed
;
unsigned
int
finger_count
,
finger_pressed
,
key_pressed
;
int
i
;
int
error
;
error
=
imagis_i2c_read_reg
(
ts
,
IST3038C_REG_INTR_MESSAGE
,
&
intr_message
);
error
=
imagis_i2c_read_reg
(
ts
,
ts
->
tdata
->
interrupt_msg_cmd
,
&
intr_message
);
if
(
error
)
{
dev_err
(
&
ts
->
client
->
dev
,
"failed to read the interrupt message: %d
\n
"
,
error
);
goto
out
;
}
finger_count
=
(
intr_message
&
IST3038C_FINGER_COUNT_MASK
)
>>
IST3038C_FINGER_COUNT_SHIFT
;
finger_count
=
FIELD_GET
(
IST3038C_FINGER_COUNT_MASK
,
intr_message
);
if
(
finger_count
>
IST3038C_MAX_FINGER_NUM
)
{
dev_err
(
&
ts
->
client
->
dev
,
"finger count %d is more than maximum supported
\n
"
,
...
...
@@ -101,11 +116,15 @@ static irqreturn_t imagis_interrupt(int irq, void *dev_id)
goto
out
;
}
finger_pressed
=
intr_message
&
IST3038C_FINGER_STATUS_MASK
;
finger_pressed
=
FIELD_GET
(
IST3038C_FINGER_STATUS_MASK
,
intr_message
)
;
for
(
i
=
0
;
i
<
finger_count
;
i
++
)
{
if
(
ts
->
tdata
->
protocol_b
)
error
=
imagis_i2c_read_reg
(
ts
,
IST3038C_REG_TOUCH_COORD
+
(
i
*
4
),
ts
->
tdata
->
touch_coord_cmd
,
&
finger_status
);
else
error
=
imagis_i2c_read_reg
(
ts
,
ts
->
tdata
->
touch_coord_cmd
+
(
i
*
4
),
&
finger_status
);
if
(
error
)
{
dev_err
(
&
ts
->
client
->
dev
,
...
...
@@ -118,14 +137,19 @@ static irqreturn_t imagis_interrupt(int irq, void *dev_id)
input_mt_report_slot_state
(
ts
->
input_dev
,
MT_TOOL_FINGER
,
finger_pressed
&
BIT
(
i
));
touchscreen_report_pos
(
ts
->
input_dev
,
&
ts
->
prop
,
(
finger_status
&
IST3038C_X_MASK
)
>>
IST3038C_X_SHIFT
,
finger_status
&
IST3038C_Y_MASK
,
1
);
FIELD_GET
(
IST3038C_X_MASK
,
finger_status
),
FIELD_GET
(
IST3038C_Y_MASK
,
finger_status
)
,
true
);
input_report_abs
(
ts
->
input_dev
,
ABS_MT_TOUCH_MAJOR
,
(
finger_status
&
IST3038C_AREA_MASK
)
>>
IST3038C_AREA_SHIFT
);
FIELD_GET
(
IST3038C_AREA_MASK
,
finger_status
));
}
key_pressed
=
FIELD_GET
(
IST3032C_KEY_STATUS_MASK
,
intr_message
);
for
(
int
i
=
0
;
i
<
ts
->
num_keycodes
;
i
++
)
input_report_key
(
ts
->
input_dev
,
ts
->
keycodes
[
i
],
key_pressed
&
BIT
(
i
));
input_mt_sync_frame
(
ts
->
input_dev
);
input_sync
(
ts
->
input_dev
);
...
...
@@ -210,7 +234,24 @@ static int imagis_init_input_dev(struct imagis_ts *ts)
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_TOUCH_MAJOR
,
0
,
255
,
0
,
0
);
input_set_abs_params
(
input_dev
,
ABS_MT_TOUCH_MAJOR
,
0
,
16
,
0
,
0
);
if
(
ts
->
tdata
->
touch_keys_supported
)
{
ts
->
num_keycodes
=
of_property_read_variable_u32_array
(
ts
->
client
->
dev
.
of_node
,
"linux,keycodes"
,
ts
->
keycodes
,
0
,
ARRAY_SIZE
(
ts
->
keycodes
));
if
(
ts
->
num_keycodes
<=
0
)
{
ts
->
keycodes
[
0
]
=
KEY_APPSELECT
;
ts
->
keycodes
[
1
]
=
KEY_BACK
;
ts
->
num_keycodes
=
2
;
}
input_dev
->
keycodemax
=
ts
->
num_keycodes
;
input_dev
->
keycodesize
=
sizeof
(
ts
->
keycodes
[
0
]);
input_dev
->
keycode
=
ts
->
keycodes
;
}
for
(
int
i
=
0
;
i
<
ts
->
num_keycodes
;
i
++
)
input_set_capability
(
input_dev
,
EV_KEY
,
ts
->
keycodes
[
i
]);
touchscreen_parse_properties
(
input_dev
,
true
,
&
ts
->
prop
);
if
(
!
ts
->
prop
.
max_x
||
!
ts
->
prop
.
max_y
)
{
...
...
@@ -261,6 +302,12 @@ static int imagis_probe(struct i2c_client *i2c)
ts
->
client
=
i2c
;
ts
->
tdata
=
device_get_match_data
(
dev
);
if
(
!
ts
->
tdata
)
{
dev_err
(
dev
,
"missing chip data
\n
"
);
return
-
EINVAL
;
}
error
=
imagis_init_regulators
(
ts
);
if
(
error
)
{
dev_err
(
dev
,
"regulator init error: %d
\n
"
,
error
);
...
...
@@ -279,15 +326,13 @@ static int imagis_probe(struct i2c_client *i2c)
return
error
;
}
error
=
imagis_i2c_read_reg
(
ts
,
IST3038C_REG_CHIPID
|
IST3038C_DIRECT_ACCESS
,
&
chip_id
);
error
=
imagis_i2c_read_reg
(
ts
,
ts
->
tdata
->
whoami_cmd
,
&
chip_id
);
if
(
error
)
{
dev_err
(
dev
,
"chip ID read failure: %d
\n
"
,
error
);
return
error
;
}
if
(
chip_id
!=
IST3038C_WHOAMI
)
{
if
(
chip_id
!=
ts
->
tdata
->
whoami_val
)
{
dev_err
(
dev
,
"unknown chip ID: 0x%x
\n
"
,
chip_id
);
return
-
EINVAL
;
}
...
...
@@ -343,9 +388,34 @@ static int imagis_resume(struct device *dev)
static
DEFINE_SIMPLE_DEV_PM_OPS
(
imagis_pm_ops
,
imagis_suspend
,
imagis_resume
);
static
const
struct
imagis_properties
imagis_3032c_data
=
{
.
interrupt_msg_cmd
=
IST3038C_REG_INTR_MESSAGE
,
.
touch_coord_cmd
=
IST3038C_REG_TOUCH_COORD
,
.
whoami_cmd
=
IST3038C_REG_CHIPID
,
.
whoami_val
=
IST3032C_WHOAMI
,
.
touch_keys_supported
=
true
,
};
static
const
struct
imagis_properties
imagis_3038b_data
=
{
.
interrupt_msg_cmd
=
IST3038B_REG_STATUS
,
.
touch_coord_cmd
=
IST3038B_REG_STATUS
,
.
whoami_cmd
=
IST3038B_REG_CHIPID
,
.
whoami_val
=
IST3038B_WHOAMI
,
.
protocol_b
=
true
,
};
static
const
struct
imagis_properties
imagis_3038c_data
=
{
.
interrupt_msg_cmd
=
IST3038C_REG_INTR_MESSAGE
,
.
touch_coord_cmd
=
IST3038C_REG_TOUCH_COORD
,
.
whoami_cmd
=
IST3038C_REG_CHIPID
,
.
whoami_val
=
IST3038C_WHOAMI
,
};
#ifdef CONFIG_OF
static
const
struct
of_device_id
imagis_of_match
[]
=
{
{
.
compatible
=
"imagis,ist3038c"
,
},
{
.
compatible
=
"imagis,ist3032c"
,
.
data
=
&
imagis_3032c_data
},
{
.
compatible
=
"imagis,ist3038b"
,
.
data
=
&
imagis_3038b_data
},
{
.
compatible
=
"imagis,ist3038c"
,
.
data
=
&
imagis_3038c_data
},
{
},
};
MODULE_DEVICE_TABLE
(
of
,
imagis_of_match
);
...
...
drivers/input/touchscreen/ti_am335x_tsc.c
View file @
57ed9567
...
...
@@ -157,7 +157,6 @@ static void titsc_step_config(struct titsc *ts_dev)
n
++
==
0
?
STEPCONFIG_OPENDLY
:
0
);
}
config
=
0
;
config
=
STEPCONFIG_MODE_HWSYNC
|
STEPCONFIG_AVG_16
|
ts_dev
->
bit_yn
|
STEPCONFIG_INM_ADCREFM
;
...
...
include/linux/input.h
View file @
57ed9567
...
...
@@ -514,7 +514,7 @@ void input_enable_softrepeat(struct input_dev *dev, int delay, int period);
bool
input_device_enabled
(
struct
input_dev
*
dev
);
extern
struct
class
input_class
;
extern
const
struct
class
input_class
;
/**
* struct ff_device - force-feedback part of an input device
...
...
include/linux/input/navpoint.h
deleted
100644 → 0
View file @
fbf8d717
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2012 Paul Parsons <lost.distance@yahoo.com>
*/
struct
navpoint_platform_data
{
int
port
;
/* PXA SSP port for pxa_ssp_request() */
};
include/linux/serio.h
View file @
57ed9567
...
...
@@ -15,7 +15,7 @@
#include <linux/mod_devicetable.h>
#include <uapi/linux/serio.h>
extern
struct
bus_type
serio_bus
;
extern
const
struct
bus_type
serio_bus
;
struct
serio
{
void
*
port_data
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment