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
nexedi
linux
Commits
65e91e28
Commit
65e91e28
authored
Mar 03, 2019
by
Dmitry Torokhov
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'next' into for-linus
Prepare input updates for 5.1 merge window.
parents
7ad222b3
44466306
Changes
31
Hide whitespace changes
Inline
Side-by-side
Showing
31 changed files
with
1203 additions
and
367 deletions
+1203
-367
Documentation/devicetree/bindings/input/cypress,tm2-touchkey.txt
...tation/devicetree/bindings/input/cypress,tm2-touchkey.txt
+8
-1
Documentation/devicetree/bindings/input/ilitek,ili2xxx.txt
Documentation/devicetree/bindings/input/ilitek,ili2xxx.txt
+25
-0
Documentation/devicetree/bindings/input/msm-vibrator.txt
Documentation/devicetree/bindings/input/msm-vibrator.txt
+36
-0
Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
...tion/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
+12
-1
Documentation/devicetree/bindings/input/touchscreen/goodix.txt
...entation/devicetree/bindings/input/touchscreen/goodix.txt
+9
-5
Documentation/devicetree/bindings/input/touchscreen/sitronix-st1232.txt
...devicetree/bindings/input/touchscreen/sitronix-st1232.txt
+6
-2
Documentation/devicetree/bindings/input/touchscreen/sx8654.txt
...entation/devicetree/bindings/input/touchscreen/sx8654.txt
+9
-1
drivers/input/joystick/db9.c
drivers/input/joystick/db9.c
+1
-1
drivers/input/keyboard/gpio_keys.c
drivers/input/keyboard/gpio_keys.c
+10
-0
drivers/input/keyboard/mcs_touchkey.c
drivers/input/keyboard/mcs_touchkey.c
+2
-3
drivers/input/keyboard/mtk-pmic-keys.c
drivers/input/keyboard/mtk-pmic-keys.c
+6
-7
drivers/input/keyboard/qt2160.c
drivers/input/keyboard/qt2160.c
+0
-9
drivers/input/keyboard/tca6416-keypad.c
drivers/input/keyboard/tca6416-keypad.c
+1
-3
drivers/input/keyboard/tm2-touchkey.c
drivers/input/keyboard/tm2-touchkey.c
+102
-34
drivers/input/misc/Kconfig
drivers/input/misc/Kconfig
+10
-0
drivers/input/misc/Makefile
drivers/input/misc/Makefile
+1
-0
drivers/input/misc/ims-pcu.c
drivers/input/misc/ims-pcu.c
+8
-19
drivers/input/misc/msm-vibrator.c
drivers/input/misc/msm-vibrator.c
+281
-0
drivers/input/misc/soc_button_array.c
drivers/input/misc/soc_button_array.c
+5
-1
drivers/input/mouse/synaptics_i2c.c
drivers/input/mouse/synaptics_i2c.c
+4
-18
drivers/input/serio/i8042-sparcio.h
drivers/input/serio/i8042-sparcio.h
+10
-11
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/Kconfig
+3
-3
drivers/input/touchscreen/ad7879.c
drivers/input/touchscreen/ad7879.c
+7
-4
drivers/input/touchscreen/edt-ft5x06.c
drivers/input/touchscreen/edt-ft5x06.c
+102
-8
drivers/input/touchscreen/goodix.c
drivers/input/touchscreen/goodix.c
+5
-1
drivers/input/touchscreen/ili210x.c
drivers/input/touchscreen/ili210x.c
+194
-127
drivers/input/touchscreen/st1232.c
drivers/input/touchscreen/st1232.c
+104
-50
drivers/input/touchscreen/stmfts.c
drivers/input/touchscreen/stmfts.c
+16
-14
drivers/input/touchscreen/sx8654.c
drivers/input/touchscreen/sx8654.c
+226
-29
drivers/input/touchscreen/ti_am335x_tsc.c
drivers/input/touchscreen/ti_am335x_tsc.c
+0
-4
include/linux/input/ili210x.h
include/linux/input/ili210x.h
+0
-11
No files found.
Documentation/devicetree/bindings/input/cypress,tm2-touchkey.txt
View file @
65e91e28
Samsung tm2-touchkey
Required properties:
- compatible: must be "cypress,tm2-touchkey"
- compatible:
* "cypress,tm2-touchkey" - for the touchkey found on the tm2 board
* "cypress,midas-touchkey" - for the touchkey found on midas boards
* "cypress,aries-touchkey" - for the touchkey found on aries boards
- reg: I2C address of the chip.
- interrupts: interrupt to which the chip is connected (see interrupt
binding[0]).
- vcc-supply : internal regulator output. 1.8V
- vdd-supply : power supply for IC 3.3V
Optional properties:
- linux,keycodes: array of keycodes (max 4), default KEY_PHONE and KEY_BACK
[0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
Example:
...
...
@@ -21,5 +27,6 @@ Example:
interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
vcc-supply=<&ldo32_reg>;
vdd-supply=<&ldo33_reg>;
linux,keycodes = <KEY_PHONE KEY_BACK>;
};
};
Documentation/devicetree/bindings/input/ilitek,ili2xxx.txt
0 → 100644
View file @
65e91e28
Ilitek ILI210x/ILI251x touchscreen controller
Required properties:
- compatible:
ilitek,ili210x for ILI210x
ilitek,ili251x for ILI251x
- reg: The I2C address of the device
- interrupts: The sink for the touchscreen's IRQ output
See ../interrupt-controller/interrupts.txt
Optional properties for main touchpad device:
- reset-gpios: GPIO specifier for the touchscreen's reset pin (active low)
Example:
touchscreen@41 {
compatible = "ilitek,ili251x";
reg = <0x41>;
interrupt-parent = <&gpio4>;
interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
reset-gpios = <&gpio5 21 GPIO_ACTIVE_LOW>;
};
Documentation/devicetree/bindings/input/msm-vibrator.txt
0 → 100644
View file @
65e91e28
* Device tree bindings for the Qualcomm MSM vibrator
Required properties:
- compatible: Should be one of
"qcom,msm8226-vibrator"
"qcom,msm8974-vibrator"
- reg: the base address and length of the IO memory for the registers.
- pinctrl-names: set to default.
- pinctrl-0: phandles pointing to pin configuration nodes. See
Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
- clock-names: set to pwm
- clocks: phandle of the clock. See
Documentation/devicetree/bindings/clock/clock-bindings.txt
- enable-gpios: GPIO that enables the vibrator.
Optional properties:
- vcc-supply: phandle to the regulator that provides power to the sensor.
Example from a LG Nexus 5 (hammerhead) phone:
vibrator@fd8c3450 {
reg = <0xfd8c3450 0x400>;
compatible = "qcom,msm8974-vibrator";
vcc-supply = <&pm8941_l19>;
clocks = <&mmcc CAMSS_GP1_CLK>;
clock-names = "pwm";
enable-gpios = <&msmgpio 60 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&vibrator_pin>;
};
Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
View file @
65e91e28
FocalTech EDT-FT5x06 Polytouch driver
=====================================
There are
3
variants of the chip for various touch panel sizes
There are
5
variants of the chip for various touch panel sizes
FT5206GE1 2.8" .. 3.8"
FT5306DE4 4.3" .. 7"
FT5406EE8 7" .. 8.9"
FT5506EEG 7" .. 8.9"
FT5726NEI 5.7” .. 11.6"
The software interface is identical for all those chips, so that
currently there is no need for the driver to distinguish between the
...
...
@@ -19,6 +20,7 @@ Required properties:
or: "edt,edt-ft5306"
or: "edt,edt-ft5406"
or: "edt,edt-ft5506"
or: "evervision,ev-ft5726"
or: "focaltech,ft6236"
- reg: I2C slave address of the chip (0x38)
...
...
@@ -42,6 +44,15 @@ Optional properties:
- offset: allows setting the edge compensation in the range from
0 to 31.
- offset-x: Same as offset, but applies only to the horizontal position.
Range from 0 to 80, only supported by evervision,ev-ft5726
devices.
- offset-y: Same as offset, but applies only to the vertical position.
Range from 0 to 80, only supported by evervision,ev-ft5726
devices.
- touchscreen-size-x : See touchscreen.txt
- touchscreen-size-y : See touchscreen.txt
- touchscreen-fuzz-x : See touchscreen.txt
...
...
Documentation/devicetree/bindings/input/touchscreen/goodix.txt
View file @
65e91e28
...
...
@@ -3,6 +3,7 @@ Device tree bindings for Goodix GT9xx series touchscreen controller
Required properties:
- compatible : Should be "goodix,gt1151"
or "goodix,gt5688"
or "goodix,gt911"
or "goodix,gt9110"
or "goodix,gt912"
...
...
@@ -18,11 +19,14 @@ Optional properties:
- irq-gpios : GPIO pin used for IRQ. The driver uses the
interrupt gpio pin as output to reset the device.
- reset-gpios : GPIO pin used for reset
- touchscreen-inverted-x : X axis is inverted (boolean)
- touchscreen-inverted-y : Y axis is inverted (boolean)
- touchscreen-swapped-x-y : X and Y axis are swapped (boolean)
(swapping is done after inverting the axis)
- touchscreen-inverted-x
- touchscreen-inverted-y
- touchscreen-size-x
- touchscreen-size-y
- touchscreen-swapped-x-y
The touchscreen-* properties are documented in touchscreen.txt in this
directory.
Example:
...
...
Documentation/devicetree/bindings/input/touchscreen/sitronix-st1232.txt
View file @
65e91e28
* Sitronix st1232 touchscreen controller
* Sitronix st1232
or st1633
touchscreen controller
Required properties:
- compatible: must be "sitronix,st1232"
- compatible: must contain one of
* "sitronix,st1232"
* "sitronix,st1633"
- reg: I2C address of the chip
- interrupts: interrupt to which the chip is connected
Optional properties:
- gpios: a phandle to the reset GPIO
For additional optional properties see: touchscreen.txt
Example:
i2c@00000000 {
...
...
Documentation/devicetree/bindings/input/touchscreen/sx8654.txt
View file @
65e91e28
* Semtech SX8654 I2C Touchscreen Controller
Required properties:
- compatible: must be "semtech,sx8654"
- compatible: must be one of the following, depending on the model:
"semtech,sx8650"
"semtech,sx8654"
"semtech,sx8655"
"semtech,sx8656"
- reg: i2c slave address
- interrupts: touch controller interrupt
Optional properties:
- reset-gpios: GPIO specification for the NRST input
Example:
sx8654@48 {
...
...
@@ -12,4 +19,5 @@ Example:
reg = <0x48>;
interrupt-parent = <&gpio6>;
interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
reset-gpios = <&gpio4 2 GPIO_ACTIVE_LOW>;
};
drivers/input/joystick/db9.c
View file @
65e91e28
...
...
@@ -259,7 +259,7 @@ static unsigned char db9_saturn_read_packet(struct parport *port, unsigned char
db9_saturn_write_sub
(
port
,
type
,
3
,
powered
,
0
);
return
data
[
0
]
=
0xe3
;
}
/*
else:
fall through */
/* fall through */
default:
return
data
[
0
];
}
...
...
drivers/input/keyboard/gpio_keys.c
View file @
65e91e28
...
...
@@ -1015,8 +1015,18 @@ static int __maybe_unused gpio_keys_resume(struct device *dev)
static
SIMPLE_DEV_PM_OPS
(
gpio_keys_pm_ops
,
gpio_keys_suspend
,
gpio_keys_resume
);
static
void
gpio_keys_shutdown
(
struct
platform_device
*
pdev
)
{
int
ret
;
ret
=
gpio_keys_suspend
(
&
pdev
->
dev
);
if
(
ret
)
dev_err
(
&
pdev
->
dev
,
"failed to shutdown
\n
"
);
}
static
struct
platform_driver
gpio_keys_device_driver
=
{
.
probe
=
gpio_keys_probe
,
.
shutdown
=
gpio_keys_shutdown
,
.
driver
=
{
.
name
=
"gpio-keys"
,
.
pm
=
&
gpio_keys_pm_ops
,
...
...
drivers/input/keyboard/mcs_touchkey.c
View file @
65e91e28
...
...
@@ -113,9 +113,8 @@ static int mcs_touchkey_probe(struct i2c_client *client,
return
-
EINVAL
;
}
data
=
kzalloc
(
sizeof
(
struct
mcs_touchkey_data
)
+
sizeof
(
data
->
keycodes
[
0
])
*
(
pdata
->
key_maxval
+
1
),
GFP_KERNEL
);
data
=
kzalloc
(
struct_size
(
data
,
keycodes
,
pdata
->
key_maxval
+
1
),
GFP_KERNEL
);
input_dev
=
input_allocate_device
();
if
(
!
data
||
!
input_dev
)
{
dev_err
(
&
client
->
dev
,
"Failed to allocate memory
\n
"
);
...
...
drivers/input/keyboard/mtk-pmic-keys.c
View file @
65e91e28
...
...
@@ -14,18 +14,17 @@
*
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/mfd/mt6323/registers.h>
#include <linux/mfd/mt6397/registers.h>
#include <linux/mfd/mt6397/core.h>
#include <linux/mfd/mt6397/registers.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#define MTK_PMIC_PWRKEY_RST_EN_MASK 0x1
#define MTK_PMIC_PWRKEY_RST_EN_SHIFT 6
...
...
drivers/input/keyboard/qt2160.c
View file @
65e91e28
...
...
@@ -68,7 +68,6 @@ struct qt2160_data {
struct
i2c_client
*
client
;
struct
input_dev
*
input
;
struct
delayed_work
dwork
;
spinlock_t
lock
;
/* Protects canceling/rescheduling of dwork */
unsigned
short
keycodes
[
ARRAY_SIZE
(
qt2160_key2code
)];
u16
key_matrix
;
#ifdef CONFIG_LEDS_CLASS
...
...
@@ -212,22 +211,15 @@ static int qt2160_get_key_matrix(struct qt2160_data *qt2160)
static
irqreturn_t
qt2160_irq
(
int
irq
,
void
*
_qt2160
)
{
struct
qt2160_data
*
qt2160
=
_qt2160
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
qt2160
->
lock
,
flags
);
mod_delayed_work
(
system_wq
,
&
qt2160
->
dwork
,
0
);
spin_unlock_irqrestore
(
&
qt2160
->
lock
,
flags
);
return
IRQ_HANDLED
;
}
static
void
qt2160_schedule_read
(
struct
qt2160_data
*
qt2160
)
{
spin_lock_irq
(
&
qt2160
->
lock
);
schedule_delayed_work
(
&
qt2160
->
dwork
,
QT2160_CYCLE_INTERVAL
);
spin_unlock_irq
(
&
qt2160
->
lock
);
}
static
void
qt2160_worker
(
struct
work_struct
*
work
)
...
...
@@ -391,7 +383,6 @@ static int qt2160_probe(struct i2c_client *client,
qt2160
->
client
=
client
;
qt2160
->
input
=
input
;
INIT_DELAYED_WORK
(
&
qt2160
->
dwork
,
qt2160_worker
);
spin_lock_init
(
&
qt2160
->
lock
);
input
->
name
=
"AT42QT2160 Touch Sense Keyboard"
;
input
->
id
.
bustype
=
BUS_I2C
;
...
...
drivers/input/keyboard/tca6416-keypad.c
View file @
65e91e28
...
...
@@ -219,9 +219,7 @@ static int tca6416_keypad_probe(struct i2c_client *client,
return
-
EINVAL
;
}
chip
=
kzalloc
(
sizeof
(
struct
tca6416_keypad_chip
)
+
pdata
->
nbuttons
*
sizeof
(
struct
tca6416_button
),
GFP_KERNEL
);
chip
=
kzalloc
(
struct_size
(
chip
,
buttons
,
pdata
->
nbuttons
),
GFP_KERNEL
);
input
=
input_allocate_device
();
if
(
!
chip
||
!
input
)
{
error
=
-
ENOMEM
;
...
...
drivers/input/keyboard/tm2-touchkey.c
View file @
65e91e28
...
...
@@ -22,12 +22,14 @@
#include <linux/leds.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pm.h>
#include <linux/regulator/consumer.h>
#define TM2_TOUCHKEY_DEV_NAME "tm2-touchkey"
#define TM2_TOUCHKEY_KEYCODE_REG 0x03
#define TM2_TOUCHKEY_BASE_REG 0x00
#define ARIES_TOUCHKEY_CMD_LED_ON 0x1
#define ARIES_TOUCHKEY_CMD_LED_OFF 0x2
#define TM2_TOUCHKEY_CMD_LED_ON 0x10
#define TM2_TOUCHKEY_CMD_LED_OFF 0x20
#define TM2_TOUCHKEY_BIT_PRESS_EV BIT(3)
...
...
@@ -35,9 +37,13 @@
#define TM2_TOUCHKEY_LED_VOLTAGE_MIN 2500000
#define TM2_TOUCHKEY_LED_VOLTAGE_MAX 3300000
enum
{
TM2_TOUCHKEY_KEY_MENU
=
0x1
,
TM2_TOUCHKEY_KEY_BACK
,
struct
touchkey_variant
{
u8
keycode_reg
;
u8
base_reg
;
u8
cmd_led_on
;
u8
cmd_led_off
;
bool
no_reg
;
bool
fixed_regulator
;
};
struct
tm2_touchkey_data
{
...
...
@@ -46,9 +52,33 @@ struct tm2_touchkey_data {
struct
led_classdev
led_dev
;
struct
regulator
*
vdd
;
struct
regulator_bulk_data
regulators
[
2
];
const
struct
touchkey_variant
*
variant
;
u32
keycodes
[
4
];
int
num_keycodes
;
};
static
const
struct
touchkey_variant
tm2_touchkey_variant
=
{
.
keycode_reg
=
0x03
,
.
base_reg
=
0x00
,
.
cmd_led_on
=
TM2_TOUCHKEY_CMD_LED_ON
,
.
cmd_led_off
=
TM2_TOUCHKEY_CMD_LED_OFF
,
};
static
const
struct
touchkey_variant
midas_touchkey_variant
=
{
.
keycode_reg
=
0x00
,
.
base_reg
=
0x00
,
.
cmd_led_on
=
TM2_TOUCHKEY_CMD_LED_ON
,
.
cmd_led_off
=
TM2_TOUCHKEY_CMD_LED_OFF
,
};
static
void
tm2_touchkey_led_brightness_set
(
struct
led_classdev
*
led_dev
,
static
struct
touchkey_variant
aries_touchkey_variant
=
{
.
no_reg
=
true
,
.
fixed_regulator
=
true
,
.
cmd_led_on
=
ARIES_TOUCHKEY_CMD_LED_ON
,
.
cmd_led_off
=
ARIES_TOUCHKEY_CMD_LED_OFF
,
};
static
int
tm2_touchkey_led_brightness_set
(
struct
led_classdev
*
led_dev
,
enum
led_brightness
brightness
)
{
struct
tm2_touchkey_data
*
touchkey
=
...
...
@@ -58,15 +88,19 @@ static void tm2_touchkey_led_brightness_set(struct led_classdev *led_dev,
if
(
brightness
==
LED_OFF
)
{
volt
=
TM2_TOUCHKEY_LED_VOLTAGE_MIN
;
data
=
TM2_TOUCHKEY_CMD_LED_OFF
;
data
=
touchkey
->
variant
->
cmd_led_off
;
}
else
{
volt
=
TM2_TOUCHKEY_LED_VOLTAGE_MAX
;
data
=
TM2_TOUCHKEY_CMD_LED_ON
;
data
=
touchkey
->
variant
->
cmd_led_on
;
}
regulator_set_voltage
(
touchkey
->
vdd
,
volt
,
volt
);
i2c_smbus_write_byte_data
(
touchkey
->
client
,
TM2_TOUCHKEY_BASE_REG
,
data
);
if
(
!
touchkey
->
variant
->
fixed_regulator
)
regulator_set_voltage
(
touchkey
->
vdd
,
volt
,
volt
);
return
touchkey
->
variant
->
no_reg
?
i2c_smbus_write_byte
(
touchkey
->
client
,
data
)
:
i2c_smbus_write_byte_data
(
touchkey
->
client
,
touchkey
->
variant
->
base_reg
,
data
);
}
static
int
tm2_touchkey_power_enable
(
struct
tm2_touchkey_data
*
touchkey
)
...
...
@@ -96,49 +130,57 @@ static irqreturn_t tm2_touchkey_irq_handler(int irq, void *devid)
{
struct
tm2_touchkey_data
*
touchkey
=
devid
;
int
data
;
int
key
;
data
=
i2c_smbus_read_byte_data
(
touchkey
->
client
,
TM2_TOUCHKEY_KEYCODE_REG
);
int
index
;
int
i
;
if
(
touchkey
->
variant
->
no_reg
)
data
=
i2c_smbus_read_byte
(
touchkey
->
client
);
else
data
=
i2c_smbus_read_byte_data
(
touchkey
->
client
,
touchkey
->
variant
->
keycode_reg
);
if
(
data
<
0
)
{
dev_err
(
&
touchkey
->
client
->
dev
,
"failed to read i2c data: %d
\n
"
,
data
);
goto
out
;
}
switch
(
data
&
TM2_TOUCHKEY_BIT_KEYCODE
)
{
case
TM2_TOUCHKEY_KEY_MENU
:
key
=
KEY_PHONE
;
break
;
case
TM2_TOUCHKEY_KEY_BACK
:
key
=
KEY_BACK
;
break
;
default:
index
=
(
data
&
TM2_TOUCHKEY_BIT_KEYCODE
)
-
1
;
if
(
index
<
0
||
index
>=
touchkey
->
num_keycodes
)
{
dev_warn
(
&
touchkey
->
client
->
dev
,
"
unhandled keycode, data %#02x
\n
"
,
data
);
"
invalid keycode index %d
\n
"
,
index
);
goto
out
;
}
if
(
data
&
TM2_TOUCHKEY_BIT_PRESS_EV
)
{
input_report_key
(
touchkey
->
input_dev
,
KEY_PHONE
,
0
);
input_report_key
(
touchkey
->
input_dev
,
KEY_BACK
,
0
);
for
(
i
=
0
;
i
<
touchkey
->
num_keycodes
;
i
++
)
input_report_key
(
touchkey
->
input_dev
,
touchkey
->
keycodes
[
i
],
0
);
}
else
{
input_report_key
(
touchkey
->
input_dev
,
key
,
1
);
input_report_key
(
touchkey
->
input_dev
,
touchkey
->
keycodes
[
index
],
1
);
}
input_sync
(
touchkey
->
input_dev
);
out:
if
(
touchkey
->
variant
->
fixed_regulator
&&
data
&
TM2_TOUCHKEY_BIT_PRESS_EV
)
{
/* touch turns backlight on, so make sure we're in sync */
if
(
touchkey
->
led_dev
.
brightness
==
LED_OFF
)
tm2_touchkey_led_brightness_set
(
&
touchkey
->
led_dev
,
LED_OFF
);
}
return
IRQ_HANDLED
;
}
static
int
tm2_touchkey_probe
(
struct
i2c_client
*
client
,
const
struct
i2c_device_id
*
id
)
{
struct
device_node
*
np
=
client
->
dev
.
of_node
;
struct
tm2_touchkey_data
*
touchkey
;
int
error
;
int
i
;
if
(
!
i2c_check_functionality
(
client
->
adapter
,
I2C_FUNC_SMBUS_BYTE
|
I2C_FUNC_SMBUS_BYTE_DATA
))
{
...
...
@@ -153,6 +195,8 @@ static int tm2_touchkey_probe(struct i2c_client *client,
touchkey
->
client
=
client
;
i2c_set_clientdata
(
client
,
touchkey
);
touchkey
->
variant
=
of_device_get_match_data
(
&
client
->
dev
);
touchkey
->
regulators
[
0
].
supply
=
"vcc"
;
touchkey
->
regulators
[
1
].
supply
=
"vdd"
;
error
=
devm_regulator_bulk_get
(
&
client
->
dev
,
...
...
@@ -166,6 +210,16 @@ static int tm2_touchkey_probe(struct i2c_client *client,
/* Save VDD for easy access */
touchkey
->
vdd
=
touchkey
->
regulators
[
1
].
consumer
;
touchkey
->
num_keycodes
=
of_property_read_variable_u32_array
(
np
,
"linux,keycodes"
,
touchkey
->
keycodes
,
0
,
ARRAY_SIZE
(
touchkey
->
keycodes
));
if
(
touchkey
->
num_keycodes
<=
0
)
{
/* default keycodes */
touchkey
->
keycodes
[
0
]
=
KEY_PHONE
;
touchkey
->
keycodes
[
1
]
=
KEY_BACK
;
touchkey
->
num_keycodes
=
2
;
}
error
=
tm2_touchkey_power_enable
(
touchkey
);
if
(
error
)
{
dev_err
(
&
client
->
dev
,
"failed to power up device: %d
\n
"
,
error
);
...
...
@@ -190,8 +244,9 @@ static int tm2_touchkey_probe(struct i2c_client *client,
touchkey
->
input_dev
->
name
=
TM2_TOUCHKEY_DEV_NAME
;
touchkey
->
input_dev
->
id
.
bustype
=
BUS_I2C
;
input_set_capability
(
touchkey
->
input_dev
,
EV_KEY
,
KEY_PHONE
);
input_set_capability
(
touchkey
->
input_dev
,
EV_KEY
,
KEY_BACK
);
for
(
i
=
0
;
i
<
touchkey
->
num_keycodes
;
i
++
)
input_set_capability
(
touchkey
->
input_dev
,
EV_KEY
,
touchkey
->
keycodes
[
i
]);
error
=
input_register_device
(
touchkey
->
input_dev
);
if
(
error
)
{
...
...
@@ -212,9 +267,10 @@ static int tm2_touchkey_probe(struct i2c_client *client,
/* led device */
touchkey
->
led_dev
.
name
=
TM2_TOUCHKEY_DEV_NAME
;
touchkey
->
led_dev
.
brightness
=
LED_
FULL
;
touchkey
->
led_dev
.
brightness
=
LED_
ON
;
touchkey
->
led_dev
.
max_brightness
=
LED_ON
;
touchkey
->
led_dev
.
brightness_set
=
tm2_touchkey_led_brightness_set
;
touchkey
->
led_dev
.
brightness_set_blocking
=
tm2_touchkey_led_brightness_set
;
error
=
devm_led_classdev_register
(
&
client
->
dev
,
&
touchkey
->
led_dev
);
if
(
error
)
{
...
...
@@ -223,6 +279,9 @@ static int tm2_touchkey_probe(struct i2c_client *client,
return
error
;
}
if
(
touchkey
->
variant
->
fixed_regulator
)
tm2_touchkey_led_brightness_set
(
&
touchkey
->
led_dev
,
LED_ON
);
return
0
;
}
...
...
@@ -262,7 +321,16 @@ static const struct i2c_device_id tm2_touchkey_id_table[] = {
MODULE_DEVICE_TABLE
(
i2c
,
tm2_touchkey_id_table
);
static
const
struct
of_device_id
tm2_touchkey_of_match
[]
=
{
{
.
compatible
=
"cypress,tm2-touchkey"
,
},
{
.
compatible
=
"cypress,tm2-touchkey"
,
.
data
=
&
tm2_touchkey_variant
,
},
{
.
compatible
=
"cypress,midas-touchkey"
,
.
data
=
&
midas_touchkey_variant
,
},
{
.
compatible
=
"cypress,aries-touchkey"
,
.
data
=
&
aries_touchkey_variant
,
},
{
},
};
MODULE_DEVICE_TABLE
(
of
,
tm2_touchkey_of_match
);
...
...
drivers/input/misc/Kconfig
View file @
65e91e28
...
...
@@ -117,6 +117,16 @@ config INPUT_E3X0_BUTTON
To compile this driver as a module, choose M here: the
module will be called e3x0_button.
config INPUT_MSM_VIBRATOR
tristate "Qualcomm MSM vibrator driver"
select INPUT_FF_MEMLESS
help
Support for the vibrator that is found on various Qualcomm MSM
SOCs.
To compile this driver as a module, choose M here: the module
will be called msm_vibrator.
config INPUT_PCSPKR
tristate "PC Speaker support"
depends on PCSPKR_PLATFORM
...
...
drivers/input/misc/Makefile
View file @
65e91e28
...
...
@@ -48,6 +48,7 @@ obj-$(CONFIG_INPUT_MAX8925_ONKEY) += max8925_onkey.o
obj-$(CONFIG_INPUT_MAX8997_HAPTIC)
+=
max8997_haptic.o
obj-$(CONFIG_INPUT_MC13783_PWRBUTTON)
+=
mc13783-pwrbutton.o
obj-$(CONFIG_INPUT_MMA8450)
+=
mma8450.o
obj-$(CONFIG_INPUT_MSM_VIBRATOR)
+=
msm-vibrator.o
obj-$(CONFIG_INPUT_PALMAS_PWRBUTTON)
+=
palmas-pwrbutton.o
obj-$(CONFIG_INPUT_PCAP)
+=
pcap_keys.o
obj-$(CONFIG_INPUT_PCF50633_PMU)
+=
pcf50633-input.o
...
...
drivers/input/misc/ims-pcu.c
View file @
65e91e28
...
...
@@ -39,8 +39,6 @@ struct ims_pcu_gamepad {
struct
ims_pcu_backlight
{
struct
led_classdev
cdev
;
struct
work_struct
work
;
enum
led_brightness
desired_brightness
;
char
name
[
32
];
};
...
...
@@ -949,14 +947,14 @@ static void ims_pcu_process_async_firmware(const struct firmware *fw,
#define IMS_PCU_MAX_BRIGHTNESS 31998
static
void
ims_pcu_backlight_work
(
struct
work_struct
*
work
)
static
int
ims_pcu_backlight_set_brightness
(
struct
led_classdev
*
cdev
,
enum
led_brightness
value
)
{
struct
ims_pcu_backlight
*
backlight
=
container_of
(
work
,
struct
ims_pcu_backlight
,
work
);
container_of
(
cdev
,
struct
ims_pcu_backlight
,
cdev
);
struct
ims_pcu
*
pcu
=
container_of
(
backlight
,
struct
ims_pcu
,
backlight
);
int
desired_brightness
=
backlight
->
desired_brightness
;
__le16
br_val
=
cpu_to_le16
(
desired_brightness
);
__le16
br_val
=
cpu_to_le16
(
value
);
int
error
;
mutex_lock
(
&
pcu
->
cmd_mutex
);
...
...
@@ -966,19 +964,11 @@ static void ims_pcu_backlight_work(struct work_struct *work)
if
(
error
&&
error
!=
-
ENODEV
)
dev_warn
(
pcu
->
dev
,
"Failed to set desired brightness %u, error: %d
\n
"
,
desired_brightness
,
error
);
value
,
error
);
mutex_unlock
(
&
pcu
->
cmd_mutex
);
}
static
void
ims_pcu_backlight_set_brightness
(
struct
led_classdev
*
cdev
,
enum
led_brightness
value
)
{
struct
ims_pcu_backlight
*
backlight
=
container_of
(
cdev
,
struct
ims_pcu_backlight
,
cdev
);
backlight
->
desired_brightness
=
value
;
schedule_work
(
&
backlight
->
work
);
return
error
;
}
static
enum
led_brightness
...
...
@@ -1015,14 +1005,14 @@ static int ims_pcu_setup_backlight(struct ims_pcu *pcu)
struct
ims_pcu_backlight
*
backlight
=
&
pcu
->
backlight
;
int
error
;
INIT_WORK
(
&
backlight
->
work
,
ims_pcu_backlight_work
);
snprintf
(
backlight
->
name
,
sizeof
(
backlight
->
name
),
"pcu%d::kbd_backlight"
,
pcu
->
device_no
);
backlight
->
cdev
.
name
=
backlight
->
name
;
backlight
->
cdev
.
max_brightness
=
IMS_PCU_MAX_BRIGHTNESS
;
backlight
->
cdev
.
brightness_get
=
ims_pcu_backlight_get_brightness
;
backlight
->
cdev
.
brightness_set
=
ims_pcu_backlight_set_brightness
;
backlight
->
cdev
.
brightness_set_blocking
=
ims_pcu_backlight_set_brightness
;
error
=
led_classdev_register
(
pcu
->
dev
,
&
backlight
->
cdev
);
if
(
error
)
{
...
...
@@ -1040,7 +1030,6 @@ static void ims_pcu_destroy_backlight(struct ims_pcu *pcu)
struct
ims_pcu_backlight
*
backlight
=
&
pcu
->
backlight
;
led_classdev_unregister
(
&
backlight
->
cdev
);
cancel_work_sync
(
&
backlight
->
work
);
}
...
...
drivers/input/misc/msm-vibrator.c
0 → 100644
View file @
65e91e28
// SPDX-License-Identifier: GPL-2.0+
/*
* Qualcomm MSM vibrator driver
*
* Copyright (c) 2018 Brian Masney <masneyb@onstation.org>
*
* Based on qcom,pwm-vibrator.c from:
* Copyright (c) 2018 Jonathan Marek <jonathan@marek.ca>
*
* Based on msm_pwm_vibrator.c from downstream Android sources:
* Copyright (C) 2009-2014 LGE, Inc.
*/
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/input.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#define REG_CMD_RCGR 0x00
#define REG_CFG_RCGR 0x04
#define REG_M 0x08
#define REG_N 0x0C
#define REG_D 0x10
#define REG_CBCR 0x24
#define MMSS_CC_M_DEFAULT 1
struct
msm_vibrator
{
struct
input_dev
*
input
;
struct
mutex
mutex
;
struct
work_struct
worker
;
void
__iomem
*
base
;
struct
regulator
*
vcc
;
struct
clk
*
clk
;
struct
gpio_desc
*
enable_gpio
;
u16
magnitude
;
bool
enabled
;
};
static
void
msm_vibrator_write
(
struct
msm_vibrator
*
vibrator
,
int
offset
,
u32
value
)
{
writel
(
value
,
vibrator
->
base
+
offset
);
}
static
int
msm_vibrator_start
(
struct
msm_vibrator
*
vibrator
)
{
int
d_reg_val
,
ret
=
0
;
mutex_lock
(
&
vibrator
->
mutex
);
if
(
!
vibrator
->
enabled
)
{
ret
=
clk_set_rate
(
vibrator
->
clk
,
24000
);
if
(
ret
)
{
dev_err
(
&
vibrator
->
input
->
dev
,
"Failed to set clock rate: %d
\n
"
,
ret
);
goto
unlock
;
}
ret
=
clk_prepare_enable
(
vibrator
->
clk
);
if
(
ret
)
{
dev_err
(
&
vibrator
->
input
->
dev
,
"Failed to enable clock: %d
\n
"
,
ret
);
goto
unlock
;
}
ret
=
regulator_enable
(
vibrator
->
vcc
);
if
(
ret
)
{
dev_err
(
&
vibrator
->
input
->
dev
,
"Failed to enable regulator: %d
\n
"
,
ret
);
clk_disable
(
vibrator
->
clk
);
goto
unlock
;
}
gpiod_set_value_cansleep
(
vibrator
->
enable_gpio
,
1
);
vibrator
->
enabled
=
true
;
}
d_reg_val
=
127
-
((
126
*
vibrator
->
magnitude
)
/
0xffff
);
msm_vibrator_write
(
vibrator
,
REG_CFG_RCGR
,
(
2
<<
12
)
|
/* dual edge mode */
(
0
<<
8
)
|
/* cxo */
(
7
<<
0
));
msm_vibrator_write
(
vibrator
,
REG_M
,
1
);
msm_vibrator_write
(
vibrator
,
REG_N
,
128
);
msm_vibrator_write
(
vibrator
,
REG_D
,
d_reg_val
);
msm_vibrator_write
(
vibrator
,
REG_CMD_RCGR
,
1
);
msm_vibrator_write
(
vibrator
,
REG_CBCR
,
1
);
unlock:
mutex_unlock
(
&
vibrator
->
mutex
);
return
ret
;
}
static
void
msm_vibrator_stop
(
struct
msm_vibrator
*
vibrator
)
{
mutex_lock
(
&
vibrator
->
mutex
);
if
(
vibrator
->
enabled
)
{
gpiod_set_value_cansleep
(
vibrator
->
enable_gpio
,
0
);
regulator_disable
(
vibrator
->
vcc
);
clk_disable
(
vibrator
->
clk
);
vibrator
->
enabled
=
false
;
}
mutex_unlock
(
&
vibrator
->
mutex
);
}
static
void
msm_vibrator_worker
(
struct
work_struct
*
work
)
{
struct
msm_vibrator
*
vibrator
=
container_of
(
work
,
struct
msm_vibrator
,
worker
);
if
(
vibrator
->
magnitude
)
msm_vibrator_start
(
vibrator
);
else
msm_vibrator_stop
(
vibrator
);
}
static
int
msm_vibrator_play_effect
(
struct
input_dev
*
dev
,
void
*
data
,
struct
ff_effect
*
effect
)
{
struct
msm_vibrator
*
vibrator
=
input_get_drvdata
(
dev
);
mutex_lock
(
&
vibrator
->
mutex
);
if
(
effect
->
u
.
rumble
.
strong_magnitude
>
0
)
vibrator
->
magnitude
=
effect
->
u
.
rumble
.
strong_magnitude
;
else
vibrator
->
magnitude
=
effect
->
u
.
rumble
.
weak_magnitude
;
mutex_unlock
(
&
vibrator
->
mutex
);
schedule_work
(
&
vibrator
->
worker
);
return
0
;
}
static
void
msm_vibrator_close
(
struct
input_dev
*
input
)
{
struct
msm_vibrator
*
vibrator
=
input_get_drvdata
(
input
);
cancel_work_sync
(
&
vibrator
->
worker
);
msm_vibrator_stop
(
vibrator
);
}
static
int
msm_vibrator_probe
(
struct
platform_device
*
pdev
)
{
struct
msm_vibrator
*
vibrator
;
struct
resource
*
res
;
int
ret
;
vibrator
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
vibrator
),
GFP_KERNEL
);
if
(
!
vibrator
)
return
-
ENOMEM
;
vibrator
->
input
=
devm_input_allocate_device
(
&
pdev
->
dev
);
if
(
!
vibrator
->
input
)
return
-
ENOMEM
;
vibrator
->
vcc
=
devm_regulator_get
(
&
pdev
->
dev
,
"vcc"
);
if
(
IS_ERR
(
vibrator
->
vcc
))
{
if
(
PTR_ERR
(
vibrator
->
vcc
)
!=
-
EPROBE_DEFER
)
dev_err
(
&
pdev
->
dev
,
"Failed to get regulator: %ld
\n
"
,
PTR_ERR
(
vibrator
->
vcc
));
return
PTR_ERR
(
vibrator
->
vcc
);
}
vibrator
->
enable_gpio
=
devm_gpiod_get
(
&
pdev
->
dev
,
"enable"
,
GPIOD_OUT_LOW
);
if
(
IS_ERR
(
vibrator
->
enable_gpio
))
{
if
(
PTR_ERR
(
vibrator
->
enable_gpio
)
!=
-
EPROBE_DEFER
)
dev_err
(
&
pdev
->
dev
,
"Failed to get enable gpio: %ld
\n
"
,
PTR_ERR
(
vibrator
->
enable_gpio
));
return
PTR_ERR
(
vibrator
->
enable_gpio
);
}
vibrator
->
clk
=
devm_clk_get
(
&
pdev
->
dev
,
"pwm"
);
if
(
IS_ERR
(
vibrator
->
clk
))
{
if
(
PTR_ERR
(
vibrator
->
clk
)
!=
-
EPROBE_DEFER
)
dev_err
(
&
pdev
->
dev
,
"Failed to lookup pwm clock: %ld
\n
"
,
PTR_ERR
(
vibrator
->
clk
));
return
PTR_ERR
(
vibrator
->
clk
);
}
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
if
(
!
res
)
{
dev_err
(
&
pdev
->
dev
,
"Failed to get platform resource
\n
"
);
return
-
ENODEV
;
}
vibrator
->
base
=
devm_ioremap
(
&
pdev
->
dev
,
res
->
start
,
resource_size
(
res
));
if
(
!
vibrator
->
base
)
{
dev_err
(
&
pdev
->
dev
,
"Failed to iomap resource.
\n
"
);
return
-
ENOMEM
;
}
vibrator
->
enabled
=
false
;
mutex_init
(
&
vibrator
->
mutex
);
INIT_WORK
(
&
vibrator
->
worker
,
msm_vibrator_worker
);
vibrator
->
input
->
name
=
"msm-vibrator"
;
vibrator
->
input
->
id
.
bustype
=
BUS_HOST
;
vibrator
->
input
->
close
=
msm_vibrator_close
;
input_set_drvdata
(
vibrator
->
input
,
vibrator
);
input_set_capability
(
vibrator
->
input
,
EV_FF
,
FF_RUMBLE
);
ret
=
input_ff_create_memless
(
vibrator
->
input
,
NULL
,
msm_vibrator_play_effect
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"Failed to create ff memless: %d"
,
ret
);
return
ret
;
}
ret
=
input_register_device
(
vibrator
->
input
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"Failed to register input device: %d"
,
ret
);
return
ret
;
}
platform_set_drvdata
(
pdev
,
vibrator
);
return
0
;
}
static
int
__maybe_unused
msm_vibrator_suspend
(
struct
device
*
dev
)
{
struct
platform_device
*
pdev
=
to_platform_device
(
dev
);
struct
msm_vibrator
*
vibrator
=
platform_get_drvdata
(
pdev
);
cancel_work_sync
(
&
vibrator
->
worker
);
if
(
vibrator
->
enabled
)
msm_vibrator_stop
(
vibrator
);
return
0
;
}
static
int
__maybe_unused
msm_vibrator_resume
(
struct
device
*
dev
)
{
struct
platform_device
*
pdev
=
to_platform_device
(
dev
);
struct
msm_vibrator
*
vibrator
=
platform_get_drvdata
(
pdev
);
if
(
vibrator
->
enabled
)
msm_vibrator_start
(
vibrator
);
return
0
;
}
static
SIMPLE_DEV_PM_OPS
(
msm_vibrator_pm_ops
,
msm_vibrator_suspend
,
msm_vibrator_resume
);
static
const
struct
of_device_id
msm_vibrator_of_match
[]
=
{
{
.
compatible
=
"qcom,msm8226-vibrator"
},
{
.
compatible
=
"qcom,msm8974-vibrator"
},
{},
};
MODULE_DEVICE_TABLE
(
of
,
msm_vibrator_of_match
);
static
struct
platform_driver
msm_vibrator_driver
=
{
.
probe
=
msm_vibrator_probe
,
.
driver
=
{
.
name
=
"msm-vibrator"
,
.
pm
=
&
msm_vibrator_pm_ops
,
.
of_match_table
=
of_match_ptr
(
msm_vibrator_of_match
),
},
};
module_platform_driver
(
msm_vibrator_driver
);
MODULE_AUTHOR
(
"Brian Masney <masneyb@onstation.org>"
);
MODULE_DESCRIPTION
(
"Qualcomm MSM vibrator driver"
);
MODULE_LICENSE
(
"GPL"
);
drivers/input/misc/soc_button_array.c
View file @
65e91e28
...
...
@@ -185,6 +185,10 @@ static int soc_button_parse_btn_desc(struct device *dev,
info
->
name
=
"power"
;
info
->
event_code
=
KEY_POWER
;
info
->
wakeup
=
true
;
}
else
if
(
upage
==
0x01
&&
usage
==
0xca
)
{
info
->
name
=
"rotation lock switch"
;
info
->
event_type
=
EV_SW
;
info
->
event_code
=
SW_ROTATE_LOCK
;
}
else
if
(
upage
==
0x07
&&
usage
==
0xe3
)
{
info
->
name
=
"home"
;
info
->
event_code
=
KEY_LEFTMETA
;
...
...
@@ -373,7 +377,7 @@ static struct soc_button_info soc_button_PNP0C40[] = {
{
"home"
,
1
,
EV_KEY
,
KEY_LEFTMETA
,
false
,
true
},
{
"volume_up"
,
2
,
EV_KEY
,
KEY_VOLUMEUP
,
true
,
false
},
{
"volume_down"
,
3
,
EV_KEY
,
KEY_VOLUMEDOWN
,
true
,
false
},
{
"rotation_lock"
,
4
,
EV_
SW
,
SW_ROTATE_LOCK
,
false
,
false
},
{
"rotation_lock"
,
4
,
EV_
KEY
,
KEY_ROTATE_LOCK_TOGGLE
,
false
,
false
},
{
}
};
...
...
drivers/input/mouse/synaptics_i2c.c
View file @
65e91e28
...
...
@@ -219,7 +219,6 @@ struct synaptics_i2c {
struct
i2c_client
*
client
;
struct
input_dev
*
input
;
struct
delayed_work
dwork
;
spinlock_t
lock
;
int
no_data_count
;
int
no_decel_param
;
int
reduce_report_param
;
...
...
@@ -369,23 +368,11 @@ static bool synaptics_i2c_get_input(struct synaptics_i2c *touch)
return
xy_delta
||
gesture
;
}
static
void
synaptics_i2c_reschedule_work
(
struct
synaptics_i2c
*
touch
,
unsigned
long
delay
)
{
unsigned
long
flags
;
spin_lock_irqsave
(
&
touch
->
lock
,
flags
);
mod_delayed_work
(
system_wq
,
&
touch
->
dwork
,
delay
);
spin_unlock_irqrestore
(
&
touch
->
lock
,
flags
);
}
static
irqreturn_t
synaptics_i2c_irq
(
int
irq
,
void
*
dev_id
)
{
struct
synaptics_i2c
*
touch
=
dev_id
;
synaptics_i2c_reschedule_work
(
touch
,
0
);
mod_delayed_work
(
system_wq
,
&
touch
->
dwork
,
0
);
return
IRQ_HANDLED
;
}
...
...
@@ -461,7 +448,7 @@ static void synaptics_i2c_work_handler(struct work_struct *work)
* We poll the device once in THREAD_IRQ_SLEEP_SECS and
* if error is detected, we try to reset and reconfigure the touchpad.
*/
synaptics_i2c_reschedule_work
(
touch
,
delay
);
mod_delayed_work
(
system_wq
,
&
touch
->
dwork
,
delay
);
}
static
int
synaptics_i2c_open
(
struct
input_dev
*
input
)
...
...
@@ -474,7 +461,7 @@ static int synaptics_i2c_open(struct input_dev *input)
return
ret
;
if
(
polling_req
)
synaptics_i2c_reschedule_work
(
touch
,
mod_delayed_work
(
system_wq
,
&
touch
->
dwork
,
msecs_to_jiffies
(
NO_DATA_SLEEP_MSECS
));
return
0
;
...
...
@@ -530,7 +517,6 @@ static struct synaptics_i2c *synaptics_i2c_touch_create(struct i2c_client *clien
touch
->
scan_rate_param
=
scan_rate
;
set_scan_rate
(
touch
,
scan_rate
);
INIT_DELAYED_WORK
(
&
touch
->
dwork
,
synaptics_i2c_work_handler
);
spin_lock_init
(
&
touch
->
lock
);
return
touch
;
}
...
...
@@ -637,7 +623,7 @@ static int __maybe_unused synaptics_i2c_resume(struct device *dev)
if
(
ret
)
return
ret
;
synaptics_i2c_reschedule_work
(
touch
,
mod_delayed_work
(
system_wq
,
&
touch
->
dwork
,
msecs_to_jiffies
(
NO_DATA_SLEEP_MSECS
));
return
0
;
...
...
drivers/input/serio/i8042-sparcio.h
View file @
65e91e28
...
...
@@ -53,12 +53,11 @@ static struct resource *kbd_res;
static
int
sparc_i8042_probe
(
struct
platform_device
*
op
)
{
struct
device_node
*
dp
=
op
->
dev
.
of_node
;
struct
device_node
*
dp
;
dp
=
dp
->
child
;
while
(
dp
)
{
if
(
!
strcmp
(
dp
->
name
,
OBP_PS2KBD_NAME1
)
||
!
strcmp
(
dp
->
name
,
OBP_PS2KBD_NAME2
))
{
for_each_child_of_node
(
op
->
dev
.
of_node
,
dp
)
{
if
(
of_node_name_eq
(
dp
,
OBP_PS2KBD_NAME1
)
||
of_node_name_eq
(
dp
,
OBP_PS2KBD_NAME2
))
{
struct
platform_device
*
kbd
=
of_find_device_by_node
(
dp
);
unsigned
int
irq
=
kbd
->
archdata
.
irqs
[
0
];
if
(
irq
==
0xffffffff
)
...
...
@@ -67,16 +66,14 @@ static int sparc_i8042_probe(struct platform_device *op)
kbd_iobase
=
of_ioremap
(
&
kbd
->
resource
[
0
],
0
,
8
,
"kbd"
);
kbd_res
=
&
kbd
->
resource
[
0
];
}
else
if
(
!
strcmp
(
dp
->
name
,
OBP_PS2MS_NAME1
)
||
!
strcmp
(
dp
->
name
,
OBP_PS2MS_NAME2
))
{
}
else
if
(
of_node_name_eq
(
dp
,
OBP_PS2MS_NAME1
)
||
of_node_name_eq
(
dp
,
OBP_PS2MS_NAME2
))
{
struct
platform_device
*
ms
=
of_find_device_by_node
(
dp
);
unsigned
int
irq
=
ms
->
archdata
.
irqs
[
0
];
if
(
irq
==
0xffffffff
)
irq
=
op
->
archdata
.
irqs
[
0
];
i8042_aux_irq
=
irq
;
}
dp
=
dp
->
sibling
;
}
return
0
;
...
...
@@ -109,8 +106,9 @@ static struct platform_driver sparc_i8042_driver = {
static
int
__init
i8042_platform_init
(
void
)
{
struct
device_node
*
root
=
of_find_node_by_path
(
"/"
);
const
char
*
name
=
of_get_property
(
root
,
"name"
,
NULL
);
if
(
!
strcmp
(
root
->
name
,
"SUNW,JavaStation-1"
))
{
if
(
name
&&
!
strcmp
(
name
,
"SUNW,JavaStation-1"
))
{
/* Hardcoded values for MrCoffee. */
i8042_kbd_irq
=
i8042_aux_irq
=
13
|
0x20
;
kbd_iobase
=
ioremap
(
0x71300060
,
8
);
...
...
@@ -139,8 +137,9 @@ static int __init i8042_platform_init(void)
static
inline
void
i8042_platform_exit
(
void
)
{
struct
device_node
*
root
=
of_find_node_by_path
(
"/"
);
const
char
*
name
=
of_get_property
(
root
,
"name"
,
NULL
);
if
(
strcmp
(
root
->
name
,
"SUNW,JavaStation-1"
))
if
(
!
name
||
strcmp
(
name
,
"SUNW,JavaStation-1"
))
platform_driver_unregister
(
&
sparc_i8042_driver
);
}
...
...
drivers/input/touchscreen/Kconfig
View file @
65e91e28
...
...
@@ -1168,11 +1168,11 @@ config TOUCHSCREEN_SIS_I2C
module will be called sis_i2c.
config TOUCHSCREEN_ST1232
tristate "Sitronix ST1232 touchscreen controllers"
tristate "Sitronix ST1232
or ST1633
touchscreen controllers"
depends on I2C
help
Say Y here if you want to support Sitronix ST1232
touchscreen controller.
Say Y here if you want to support
the
Sitronix ST1232
or ST1633
touchscreen controller.
If unsure, say N.
...
...
drivers/input/touchscreen/ad7879.c
View file @
65e91e28
...
...
@@ -246,11 +246,14 @@ static void ad7879_timer(struct timer_list *t)
static
irqreturn_t
ad7879_irq
(
int
irq
,
void
*
handle
)
{
struct
ad7879
*
ts
=
handle
;
int
error
;
regmap_bulk_read
(
ts
->
regmap
,
AD7879_REG_XPLUS
,
ts
->
conversion_data
,
AD7879_NR_SENSE
);
if
(
!
ad7879_report
(
ts
))
error
=
regmap_bulk_read
(
ts
->
regmap
,
AD7879_REG_XPLUS
,
ts
->
conversion_data
,
AD7879_NR_SENSE
);
if
(
error
)
dev_err_ratelimited
(
ts
->
dev
,
"failed to read %#02x: %d
\n
"
,
AD7879_REG_XPLUS
,
error
);
else
if
(
!
ad7879_report
(
ts
))
mod_timer
(
&
ts
->
timer
,
jiffies
+
TS_PEN_UP_TIMEOUT
);
return
IRQ_HANDLED
;
...
...
drivers/input/touchscreen/edt-ft5x06.c
View file @
65e91e28
...
...
@@ -31,6 +31,7 @@
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/uaccess.h>
#include <linux/delay.h>
#include <linux/debugfs.h>
...
...
@@ -53,6 +54,11 @@
#define M09_REGISTER_NUM_X 0x94
#define M09_REGISTER_NUM_Y 0x95
#define EV_REGISTER_THRESHOLD 0x40
#define EV_REGISTER_GAIN 0x41
#define EV_REGISTER_OFFSET_Y 0x45
#define EV_REGISTER_OFFSET_X 0x46
#define NO_REGISTER 0xff
#define WORK_REGISTER_OPMODE 0x3c
...
...
@@ -73,6 +79,7 @@ enum edt_ver {
EDT_M06
,
EDT_M09
,
EDT_M12
,
EV_FT
,
GENERIC_FT
,
};
...
...
@@ -81,6 +88,8 @@ struct edt_reg_addr {
int
reg_report_rate
;
int
reg_gain
;
int
reg_offset
;
int
reg_offset_x
;
int
reg_offset_y
;
int
reg_num_x
;
int
reg_num_y
;
};
...
...
@@ -106,6 +115,8 @@ struct edt_ft5x06_ts_data {
int
threshold
;
int
gain
;
int
offset
;
int
offset_x
;
int
offset_y
;
int
report_rate
;
int
max_support_points
;
...
...
@@ -190,6 +201,7 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
case
EDT_M09
:
case
EDT_M12
:
case
EV_FT
:
case
GENERIC_FT
:
cmd
=
0x0
;
offset
=
3
;
...
...
@@ -242,6 +254,10 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
x
=
((
buf
[
0
]
<<
8
)
|
buf
[
1
])
&
0x0fff
;
y
=
((
buf
[
2
]
<<
8
)
|
buf
[
3
])
&
0x0fff
;
/* The FT5x26 send the y coordinate first */
if
(
tsdata
->
version
==
EV_FT
)
swap
(
x
,
y
);
id
=
(
buf
[
2
]
>>
4
)
&
0x0f
;
down
=
type
!=
TOUCH_EVENT_UP
;
...
...
@@ -275,8 +291,10 @@ static int edt_ft5x06_register_write(struct edt_ft5x06_ts_data *tsdata,
wrbuf
[
3
]
=
wrbuf
[
0
]
^
wrbuf
[
1
]
^
wrbuf
[
2
];
return
edt_ft5x06_ts_readwrite
(
tsdata
->
client
,
4
,
wrbuf
,
0
,
NULL
);
/* fallthrough */
case
EDT_M09
:
case
EDT_M12
:
case
EV_FT
:
case
GENERIC_FT
:
wrbuf
[
0
]
=
addr
;
wrbuf
[
1
]
=
value
;
...
...
@@ -315,8 +333,10 @@ static int edt_ft5x06_register_read(struct edt_ft5x06_ts_data *tsdata,
}
break
;
/* fallthrough */
case
EDT_M09
:
case
EDT_M12
:
case
EV_FT
:
case
GENERIC_FT
:
wrbuf
[
0
]
=
addr
;
error
=
edt_ft5x06_ts_readwrite
(
tsdata
->
client
,
1
,
...
...
@@ -339,9 +359,10 @@ struct edt_ft5x06_attribute {
u8
limit_high
;
u8
addr_m06
;
u8
addr_m09
;
u8
addr_ev
;
};
#define EDT_ATTR(_field, _mode, _addr_m06, _addr_m09,
\
#define EDT_ATTR(_field, _mode, _addr_m06, _addr_m09,
_addr_ev,
\
_limit_low, _limit_high) \
struct edt_ft5x06_attribute edt_ft5x06_attr_##_field = { \
.dattr = __ATTR(_field, _mode, \
...
...
@@ -350,6 +371,7 @@ struct edt_ft5x06_attribute {
.field_offset = offsetof(struct edt_ft5x06_ts_data, _field), \
.addr_m06 = _addr_m06, \
.addr_m09 = _addr_m09, \
.addr_ev = _addr_ev, \
.limit_low = _limit_low, \
.limit_high = _limit_high, \
}
...
...
@@ -386,6 +408,10 @@ static ssize_t edt_ft5x06_setting_show(struct device *dev,
addr
=
attr
->
addr_m09
;
break
;
case
EV_FT
:
addr
=
attr
->
addr_ev
;
break
;
default:
error
=
-
ENODEV
;
goto
out
;
...
...
@@ -457,6 +483,10 @@ static ssize_t edt_ft5x06_setting_store(struct device *dev,
addr
=
attr
->
addr_m09
;
break
;
case
EV_FT
:
addr
=
attr
->
addr_ev
;
break
;
default:
error
=
-
ENODEV
;
goto
out
;
...
...
@@ -480,20 +510,28 @@ static ssize_t edt_ft5x06_setting_store(struct device *dev,
/* m06, m09: range 0-31, m12: range 0-5 */
static
EDT_ATTR
(
gain
,
S_IWUSR
|
S_IRUGO
,
WORK_REGISTER_GAIN
,
M09_REGISTER_GAIN
,
0
,
31
);
M09_REGISTER_GAIN
,
EV_REGISTER_GAIN
,
0
,
31
);
/* m06, m09: range 0-31, m12: range 0-16 */
static
EDT_ATTR
(
offset
,
S_IWUSR
|
S_IRUGO
,
WORK_REGISTER_OFFSET
,
M09_REGISTER_OFFSET
,
0
,
31
);
M09_REGISTER_OFFSET
,
NO_REGISTER
,
0
,
31
);
/* m06, m09, m12: no supported, ev_ft: range 0-80 */
static
EDT_ATTR
(
offset_x
,
S_IWUSR
|
S_IRUGO
,
NO_REGISTER
,
NO_REGISTER
,
EV_REGISTER_OFFSET_X
,
0
,
80
);
/* m06, m09, m12: no supported, ev_ft: range 0-80 */
static
EDT_ATTR
(
offset_y
,
S_IWUSR
|
S_IRUGO
,
NO_REGISTER
,
NO_REGISTER
,
EV_REGISTER_OFFSET_Y
,
0
,
80
);
/* m06: range 20 to 80, m09: range 0 to 30, m12: range 1 to 255... */
static
EDT_ATTR
(
threshold
,
S_IWUSR
|
S_IRUGO
,
WORK_REGISTER_THRESHOLD
,
M09_REGISTER_THRESHOLD
,
0
,
255
);
M09_REGISTER_THRESHOLD
,
EV_REGISTER_THRESHOLD
,
0
,
255
);
/* m06: range 3 to 14, m12: (0x64: 100Hz) */
static
EDT_ATTR
(
report_rate
,
S_IWUSR
|
S_IRUGO
,
WORK_REGISTER_REPORT_RATE
,
NO_REGISTER
,
0
,
255
);
NO_REGISTER
,
NO_REGISTER
,
0
,
255
);
static
struct
attribute
*
edt_ft5x06_attrs
[]
=
{
&
edt_ft5x06_attr_gain
.
dattr
.
attr
,
&
edt_ft5x06_attr_offset
.
dattr
.
attr
,
&
edt_ft5x06_attr_offset_x
.
dattr
.
attr
,
&
edt_ft5x06_attr_offset_y
.
dattr
.
attr
,
&
edt_ft5x06_attr_threshold
.
dattr
.
attr
,
&
edt_ft5x06_attr_report_rate
.
dattr
.
attr
,
NULL
...
...
@@ -605,8 +643,15 @@ static int edt_ft5x06_work_mode(struct edt_ft5x06_ts_data *tsdata)
tsdata
->
threshold
);
edt_ft5x06_register_write
(
tsdata
,
reg_addr
->
reg_gain
,
tsdata
->
gain
);
edt_ft5x06_register_write
(
tsdata
,
reg_addr
->
reg_offset
,
tsdata
->
offset
);
if
(
reg_addr
->
reg_offset
!=
NO_REGISTER
)
edt_ft5x06_register_write
(
tsdata
,
reg_addr
->
reg_offset
,
tsdata
->
offset
);
if
(
reg_addr
->
reg_offset_x
!=
NO_REGISTER
)
edt_ft5x06_register_write
(
tsdata
,
reg_addr
->
reg_offset_x
,
tsdata
->
offset_x
);
if
(
reg_addr
->
reg_offset_y
!=
NO_REGISTER
)
edt_ft5x06_register_write
(
tsdata
,
reg_addr
->
reg_offset_y
,
tsdata
->
offset_y
);
if
(
reg_addr
->
reg_report_rate
!=
NO_REGISTER
)
edt_ft5x06_register_write
(
tsdata
,
reg_addr
->
reg_report_rate
,
tsdata
->
report_rate
);
...
...
@@ -867,6 +912,16 @@ static int edt_ft5x06_ts_identify(struct i2c_client *client,
case
0x5a
:
/* Solomon Goldentek Display */
snprintf
(
model_name
,
EDT_NAME_LEN
,
"GKTW50SCED1R0"
);
break
;
case
0x59
:
/* Evervision Display with FT5xx6 TS */
tsdata
->
version
=
EV_FT
;
error
=
edt_ft5x06_ts_readwrite
(
client
,
1
,
"
\x53
"
,
1
,
rdbuf
);
if
(
error
)
return
error
;
strlcpy
(
fw_version
,
rdbuf
,
1
);
snprintf
(
model_name
,
EDT_NAME_LEN
,
"EVERVISION-FT5726NEi"
);
break
;
default:
snprintf
(
model_name
,
EDT_NAME_LEN
,
"generic ft5x06 (%02x)"
,
...
...
@@ -902,6 +957,18 @@ static void edt_ft5x06_ts_get_defaults(struct device *dev,
edt_ft5x06_register_write
(
tsdata
,
reg_addr
->
reg_offset
,
val
);
tsdata
->
offset
=
val
;
}
error
=
device_property_read_u32
(
dev
,
"offset-x"
,
&
val
);
if
(
!
error
)
{
edt_ft5x06_register_write
(
tsdata
,
reg_addr
->
reg_offset_x
,
val
);
tsdata
->
offset_x
=
val
;
}
error
=
device_property_read_u32
(
dev
,
"offset-y"
,
&
val
);
if
(
!
error
)
{
edt_ft5x06_register_write
(
tsdata
,
reg_addr
->
reg_offset_y
,
val
);
tsdata
->
offset_y
=
val
;
}
}
static
void
...
...
@@ -912,7 +979,15 @@ edt_ft5x06_ts_get_parameters(struct edt_ft5x06_ts_data *tsdata)
tsdata
->
threshold
=
edt_ft5x06_register_read
(
tsdata
,
reg_addr
->
reg_threshold
);
tsdata
->
gain
=
edt_ft5x06_register_read
(
tsdata
,
reg_addr
->
reg_gain
);
tsdata
->
offset
=
edt_ft5x06_register_read
(
tsdata
,
reg_addr
->
reg_offset
);
if
(
reg_addr
->
reg_offset
!=
NO_REGISTER
)
tsdata
->
offset
=
edt_ft5x06_register_read
(
tsdata
,
reg_addr
->
reg_offset
);
if
(
reg_addr
->
reg_offset_x
!=
NO_REGISTER
)
tsdata
->
offset_x
=
edt_ft5x06_register_read
(
tsdata
,
reg_addr
->
reg_offset_x
);
if
(
reg_addr
->
reg_offset_y
!=
NO_REGISTER
)
tsdata
->
offset_y
=
edt_ft5x06_register_read
(
tsdata
,
reg_addr
->
reg_offset_y
);
if
(
reg_addr
->
reg_report_rate
!=
NO_REGISTER
)
tsdata
->
report_rate
=
edt_ft5x06_register_read
(
tsdata
,
reg_addr
->
reg_report_rate
);
...
...
@@ -940,6 +1015,8 @@ edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata)
reg_addr
->
reg_report_rate
=
WORK_REGISTER_REPORT_RATE
;
reg_addr
->
reg_gain
=
WORK_REGISTER_GAIN
;
reg_addr
->
reg_offset
=
WORK_REGISTER_OFFSET
;
reg_addr
->
reg_offset_x
=
NO_REGISTER
;
reg_addr
->
reg_offset_y
=
NO_REGISTER
;
reg_addr
->
reg_num_x
=
WORK_REGISTER_NUM_X
;
reg_addr
->
reg_num_y
=
WORK_REGISTER_NUM_Y
;
break
;
...
...
@@ -950,15 +1027,30 @@ edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata)
reg_addr
->
reg_report_rate
=
NO_REGISTER
;
reg_addr
->
reg_gain
=
M09_REGISTER_GAIN
;
reg_addr
->
reg_offset
=
M09_REGISTER_OFFSET
;
reg_addr
->
reg_offset_x
=
NO_REGISTER
;
reg_addr
->
reg_offset_y
=
NO_REGISTER
;
reg_addr
->
reg_num_x
=
M09_REGISTER_NUM_X
;
reg_addr
->
reg_num_y
=
M09_REGISTER_NUM_Y
;
break
;
case
EV_FT
:
reg_addr
->
reg_threshold
=
EV_REGISTER_THRESHOLD
;
reg_addr
->
reg_gain
=
EV_REGISTER_GAIN
;
reg_addr
->
reg_offset
=
NO_REGISTER
;
reg_addr
->
reg_offset_x
=
EV_REGISTER_OFFSET_X
;
reg_addr
->
reg_offset_y
=
EV_REGISTER_OFFSET_Y
;
reg_addr
->
reg_num_x
=
NO_REGISTER
;
reg_addr
->
reg_num_y
=
NO_REGISTER
;
reg_addr
->
reg_report_rate
=
NO_REGISTER
;
break
;
case
GENERIC_FT
:
/* this is a guesswork */
reg_addr
->
reg_threshold
=
M09_REGISTER_THRESHOLD
;
reg_addr
->
reg_gain
=
M09_REGISTER_GAIN
;
reg_addr
->
reg_offset
=
M09_REGISTER_OFFSET
;
reg_addr
->
reg_offset_x
=
NO_REGISTER
;
reg_addr
->
reg_offset_y
=
NO_REGISTER
;
break
;
}
}
...
...
@@ -1155,6 +1247,7 @@ static const struct edt_i2c_chip_data edt_ft6236_data = {
static
const
struct
i2c_device_id
edt_ft5x06_ts_id
[]
=
{
{
.
name
=
"edt-ft5x06"
,
.
driver_data
=
(
long
)
&
edt_ft5x06_data
},
{
.
name
=
"edt-ft5506"
,
.
driver_data
=
(
long
)
&
edt_ft5506_data
},
{
.
name
=
"ev-ft5726"
,
.
driver_data
=
(
long
)
&
edt_ft5506_data
},
/* Note no edt- prefix for compatibility with the ft6236.c driver */
{
.
name
=
"ft6236"
,
.
driver_data
=
(
long
)
&
edt_ft6236_data
},
{
/* sentinel */
}
...
...
@@ -1167,6 +1260,7 @@ static const struct of_device_id edt_ft5x06_of_match[] = {
{
.
compatible
=
"edt,edt-ft5306"
,
.
data
=
&
edt_ft5x06_data
},
{
.
compatible
=
"edt,edt-ft5406"
,
.
data
=
&
edt_ft5x06_data
},
{
.
compatible
=
"edt,edt-ft5506"
,
.
data
=
&
edt_ft5506_data
},
{
.
compatible
=
"evervision,ev-ft5726"
,
.
data
=
&
edt_ft5506_data
},
/* Note focaltech vendor prefix for compatibility with ft6236.c */
{
.
compatible
=
"focaltech,ft6236"
,
.
data
=
&
edt_ft6236_data
},
{
/* sentinel */
}
...
...
drivers/input/touchscreen/goodix.c
View file @
65e91e28
...
...
@@ -216,6 +216,7 @@ static const struct goodix_chip_data *goodix_get_chip_data(u16 id)
{
switch
(
id
)
{
case
1151
:
case
5688
:
return
&
gt1x_chip_data
;
case
911
:
...
...
@@ -692,7 +693,9 @@ static int goodix_configure_dev(struct goodix_ts_data *ts)
touchscreen_parse_properties
(
ts
->
input_dev
,
true
,
&
ts
->
prop
);
if
(
!
ts
->
prop
.
max_x
||
!
ts
->
prop
.
max_y
||
!
ts
->
max_touch_num
)
{
dev_err
(
&
ts
->
client
->
dev
,
"Invalid config, using defaults
\n
"
);
dev_err
(
&
ts
->
client
->
dev
,
"Invalid config (%d, %d, %d), using defaults
\n
"
,
ts
->
prop
.
max_x
,
ts
->
prop
.
max_y
,
ts
->
max_touch_num
);
ts
->
prop
.
max_x
=
GOODIX_MAX_WIDTH
-
1
;
ts
->
prop
.
max_y
=
GOODIX_MAX_HEIGHT
-
1
;
ts
->
max_touch_num
=
GOODIX_MAX_CONTACTS
;
...
...
@@ -942,6 +945,7 @@ MODULE_DEVICE_TABLE(acpi, goodix_acpi_match);
#ifdef CONFIG_OF
static
const
struct
of_device_id
goodix_of_match
[]
=
{
{
.
compatible
=
"goodix,gt1151"
},
{
.
compatible
=
"goodix,gt5688"
},
{
.
compatible
=
"goodix,gt911"
},
{
.
compatible
=
"goodix,gt9110"
},
{
.
compatible
=
"goodix,gt912"
},
...
...
drivers/input/touchscreen/ili210x.c
View file @
65e91e28
...
...
@@ -4,11 +4,15 @@
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/input/touchscreen.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
#include <linux/input/ili210x.h>
#include <linux/gpio/consumer.h>
#include <linux/of_device.h>
#include <asm/unaligned.h>
#define MAX_TOUCHES 2
#define ILI210X_TOUCHES 2
#define ILI251X_TOUCHES 10
#define DEFAULT_POLL_PERIOD 20
/* Touchscreen commands */
...
...
@@ -17,41 +21,32 @@
#define REG_FIRMWARE_VERSION 0x40
#define REG_CALIBRATE 0xcc
struct
finger
{
u8
x_low
;
u8
x_high
;
u8
y_low
;
u8
y_high
;
}
__packed
;
struct
touchdata
{
u8
status
;
struct
finger
finger
[
MAX_TOUCHES
];
}
__packed
;
struct
panel_info
{
struct
finger
finger_max
;
u8
xchannel_num
;
u8
ychannel_num
;
}
__packed
;
struct
firmware_version
{
u8
id
;
u8
major
;
u8
minor
;
}
__packed
;
enum
ili2xxx_model
{
MODEL_ILI210X
,
MODEL_ILI251X
,
};
struct
ili210x
{
struct
i2c_client
*
client
;
struct
input_dev
*
input
;
bool
(
*
get_pendown_state
)(
void
);
unsigned
int
poll_period
;
struct
delayed_work
dwork
;
struct
gpio_desc
*
reset_gpio
;
struct
touchscreen_properties
prop
;
enum
ili2xxx_model
model
;
unsigned
int
max_touches
;
};
static
int
ili210x_read_reg
(
struct
i2c_client
*
client
,
u8
reg
,
void
*
buf
,
size_t
len
)
{
struct
ili210x
*
priv
=
i2c_get_clientdata
(
client
);
struct
i2c_msg
msg
[
2
]
=
{
{
.
addr
=
client
->
addr
,
...
...
@@ -67,7 +62,38 @@ static int ili210x_read_reg(struct i2c_client *client, u8 reg, void *buf,
}
};
if
(
i2c_transfer
(
client
->
adapter
,
msg
,
2
)
!=
2
)
{
if
(
priv
->
model
==
MODEL_ILI251X
)
{
if
(
i2c_transfer
(
client
->
adapter
,
msg
,
1
)
!=
1
)
{
dev_err
(
&
client
->
dev
,
"i2c transfer failed
\n
"
);
return
-
EIO
;
}
usleep_range
(
5000
,
5500
);
if
(
i2c_transfer
(
client
->
adapter
,
msg
+
1
,
1
)
!=
1
)
{
dev_err
(
&
client
->
dev
,
"i2c transfer failed
\n
"
);
return
-
EIO
;
}
}
else
{
if
(
i2c_transfer
(
client
->
adapter
,
msg
,
2
)
!=
2
)
{
dev_err
(
&
client
->
dev
,
"i2c transfer failed
\n
"
);
return
-
EIO
;
}
}
return
0
;
}
static
int
ili210x_read
(
struct
i2c_client
*
client
,
void
*
buf
,
size_t
len
)
{
struct
i2c_msg
msg
=
{
.
addr
=
client
->
addr
,
.
flags
=
I2C_M_RD
,
.
len
=
len
,
.
buf
=
buf
,
};
if
(
i2c_transfer
(
client
->
adapter
,
&
msg
,
1
)
!=
1
)
{
dev_err
(
&
client
->
dev
,
"i2c transfer failed
\n
"
);
return
-
EIO
;
}
...
...
@@ -75,42 +101,72 @@ static int ili210x_read_reg(struct i2c_client *client, u8 reg, void *buf,
return
0
;
}
static
void
ili210x_report_events
(
struct
input_dev
*
input
,
const
struct
touchdata
*
touchdata
)
static
bool
ili210x_touchdata_to_coords
(
struct
ili210x
*
priv
,
u8
*
touchdata
,
unsigned
int
finger
,
unsigned
int
*
x
,
unsigned
int
*
y
)
{
int
i
;
bool
touch
;
unsigned
int
x
,
y
;
const
struct
finger
*
finger
;
if
(
finger
>=
ILI210X_TOUCHES
)
return
false
;
for
(
i
=
0
;
i
<
MAX_TOUCHES
;
i
++
)
{
input_mt_slot
(
input
,
i
)
;
if
(
touchdata
[
0
]
&
BIT
(
finger
))
return
false
;
finger
=
&
touchdata
->
finger
[
i
];
*
x
=
get_unaligned_be16
(
touchdata
+
1
+
(
finger
*
4
)
+
0
);
*
y
=
get_unaligned_be16
(
touchdata
+
1
+
(
finger
*
4
)
+
2
);
touch
=
touchdata
->
status
&
(
1
<<
i
);
input_mt_report_slot_state
(
input
,
MT_TOOL_FINGER
,
touch
);
if
(
touch
)
{
x
=
finger
->
x_low
|
(
finger
->
x_high
<<
8
);
y
=
finger
->
y_low
|
(
finger
->
y_high
<<
8
);
return
true
;
}
static
bool
ili251x_touchdata_to_coords
(
struct
ili210x
*
priv
,
u8
*
touchdata
,
unsigned
int
finger
,
unsigned
int
*
x
,
unsigned
int
*
y
)
{
if
(
finger
>=
ILI251X_TOUCHES
)
return
false
;
*
x
=
get_unaligned_be16
(
touchdata
+
1
+
(
finger
*
5
)
+
0
);
if
(
!
(
*
x
&
BIT
(
15
)))
/* Touch indication */
return
false
;
input_report_abs
(
input
,
ABS_MT_POSITION_X
,
x
);
input_report_abs
(
input
,
ABS_MT_POSITION_Y
,
y
);
*
x
&=
0x3fff
;
*
y
=
get_unaligned_be16
(
touchdata
+
1
+
(
finger
*
5
)
+
2
);
return
true
;
}
static
bool
ili210x_report_events
(
struct
ili210x
*
priv
,
u8
*
touchdata
)
{
struct
input_dev
*
input
=
priv
->
input
;
int
i
;
bool
contact
=
false
,
touch
=
false
;
unsigned
int
x
=
0
,
y
=
0
;
for
(
i
=
0
;
i
<
priv
->
max_touches
;
i
++
)
{
if
(
priv
->
model
==
MODEL_ILI210X
)
{
touch
=
ili210x_touchdata_to_coords
(
priv
,
touchdata
,
i
,
&
x
,
&
y
);
}
else
if
(
priv
->
model
==
MODEL_ILI251X
)
{
touch
=
ili251x_touchdata_to_coords
(
priv
,
touchdata
,
i
,
&
x
,
&
y
);
if
(
touch
)
contact
=
true
;
}
input_mt_slot
(
input
,
i
);
input_mt_report_slot_state
(
input
,
MT_TOOL_FINGER
,
touch
);
if
(
!
touch
)
continue
;
touchscreen_report_pos
(
input
,
&
priv
->
prop
,
x
,
y
,
true
);
}
input_mt_report_pointer_emulation
(
input
,
false
);
input_sync
(
input
);
}
static
bool
get_pendown_state
(
const
struct
ili210x
*
priv
)
{
bool
state
=
false
;
if
(
priv
->
get_pendown_state
)
state
=
priv
->
get_pendown_state
();
if
(
priv
->
model
==
MODEL_ILI210X
)
contact
=
touchdata
[
0
]
&
0xf3
;
return
state
;
return
contact
;
}
static
void
ili210x_work
(
struct
work_struct
*
work
)
...
...
@@ -118,20 +174,29 @@ static void ili210x_work(struct work_struct *work)
struct
ili210x
*
priv
=
container_of
(
work
,
struct
ili210x
,
dwork
.
work
);
struct
i2c_client
*
client
=
priv
->
client
;
struct
touchdata
touchdata
;
int
error
;
u8
touchdata
[
64
]
=
{
0
};
bool
touch
;
int
error
=
-
EINVAL
;
if
(
priv
->
model
==
MODEL_ILI210X
)
{
error
=
ili210x_read_reg
(
client
,
REG_TOUCHDATA
,
touchdata
,
sizeof
(
touchdata
));
}
else
if
(
priv
->
model
==
MODEL_ILI251X
)
{
error
=
ili210x_read_reg
(
client
,
REG_TOUCHDATA
,
touchdata
,
31
);
if
(
!
error
&&
touchdata
[
0
]
==
2
)
error
=
ili210x_read
(
client
,
&
touchdata
[
31
],
20
);
}
error
=
ili210x_read_reg
(
client
,
REG_TOUCHDATA
,
&
touchdata
,
sizeof
(
touchdata
));
if
(
error
)
{
dev_err
(
&
client
->
dev
,
"Unable to get touchdata, err = %d
\n
"
,
error
);
return
;
}
ili210x_report_events
(
priv
->
input
,
&
touchdata
);
touch
=
ili210x_report_events
(
priv
,
touchdata
);
if
(
(
touchdata
.
status
&
0xf3
)
||
get_pendown_state
(
priv
)
)
if
(
touch
)
schedule_delayed_work
(
&
priv
->
dwork
,
msecs_to_jiffies
(
priv
->
poll_period
));
}
...
...
@@ -180,103 +245,119 @@ static const struct attribute_group ili210x_attr_group = {
.
attrs
=
ili210x_attributes
,
};
static
void
ili210x_power_down
(
void
*
data
)
{
struct
gpio_desc
*
reset_gpio
=
data
;
gpiod_set_value_cansleep
(
reset_gpio
,
1
);
}
static
void
ili210x_cancel_work
(
void
*
data
)
{
struct
ili210x
*
priv
=
data
;
cancel_delayed_work_sync
(
&
priv
->
dwork
);
}
static
int
ili210x_i2c_probe
(
struct
i2c_client
*
client
,
const
struct
i2c_device_id
*
id
)
{
struct
device
*
dev
=
&
client
->
dev
;
const
struct
ili210x_platform_data
*
pdata
=
dev_get_platdata
(
dev
);
struct
ili210x
*
priv
;
struct
gpio_desc
*
reset_gpio
;
struct
input_dev
*
input
;
struct
panel_info
panel
;
struct
firmware_version
firmware
;
int
xmax
,
ymax
;
enum
ili2xxx_model
model
;
int
error
;
dev_dbg
(
dev
,
"Probing for ILI210X I2C Touschreen driver"
)
;
model
=
(
enum
ili2xxx_model
)
id
->
driver_data
;
if
(
!
pdata
)
{
dev_err
(
dev
,
"No platform data!
\n
"
);
return
-
EINVAL
;
}
dev_dbg
(
dev
,
"Probing for ILI210X I2C Touschreen driver"
);
if
(
client
->
irq
<=
0
)
{
dev_err
(
dev
,
"No IRQ!
\n
"
);
return
-
EINVAL
;
}
/* Get firmware version */
error
=
ili210x_read_reg
(
client
,
REG_FIRMWARE_VERSION
,
&
firmware
,
sizeof
(
firmware
));
if
(
error
)
{
dev_err
(
dev
,
"Failed to get firmware version, err: %d
\n
"
,
error
);
return
error
;
}
reset_gpio
=
devm_gpiod_get_optional
(
dev
,
"reset"
,
GPIOD_OUT_HIGH
);
if
(
IS_ERR
(
reset_gpio
))
return
PTR_ERR
(
reset_gpio
);
/* get panel info */
error
=
ili210x_read_reg
(
client
,
REG_PANEL_INFO
,
&
panel
,
sizeof
(
panel
));
if
(
error
)
{
dev_err
(
dev
,
"Failed to get panel information, err: %d
\n
"
,
error
);
return
error
;
if
(
reset_gpio
)
{
error
=
devm_add_action_or_reset
(
dev
,
ili210x_power_down
,
reset_gpio
);
if
(
error
)
return
error
;
usleep_range
(
50
,
100
);
gpiod_set_value_cansleep
(
reset_gpio
,
0
);
msleep
(
100
);
}
xmax
=
panel
.
finger_max
.
x_low
|
(
panel
.
finger_max
.
x_high
<<
8
);
ymax
=
panel
.
finger_max
.
y_low
|
(
panel
.
finger_max
.
y_high
<<
8
);
priv
=
devm_kzalloc
(
dev
,
sizeof
(
*
priv
),
GFP_KERNEL
);
if
(
!
priv
)
return
-
ENOMEM
;
priv
=
kzalloc
(
sizeof
(
*
priv
),
GFP_KERNEL
);
input
=
input_allocate_device
();
if
(
!
priv
||
!
input
)
{
error
=
-
ENOMEM
;
goto
err_free_mem
;
}
input
=
devm_input_allocate_device
(
dev
);
if
(
!
input
)
return
-
ENOMEM
;
priv
->
client
=
client
;
priv
->
input
=
input
;
priv
->
get_pendown_state
=
pdata
->
get_pendown_state
;
priv
->
poll_period
=
pdata
->
poll_period
?
:
DEFAULT_POLL_PERIOD
;
priv
->
poll_period
=
DEFAULT_POLL_PERIOD
;
INIT_DELAYED_WORK
(
&
priv
->
dwork
,
ili210x_work
);
priv
->
reset_gpio
=
reset_gpio
;
priv
->
model
=
model
;
if
(
model
==
MODEL_ILI210X
)
priv
->
max_touches
=
ILI210X_TOUCHES
;
if
(
model
==
MODEL_ILI251X
)
priv
->
max_touches
=
ILI251X_TOUCHES
;
i2c_set_clientdata
(
client
,
priv
);
/* Get firmware version */
error
=
ili210x_read_reg
(
client
,
REG_FIRMWARE_VERSION
,
&
firmware
,
sizeof
(
firmware
));
if
(
error
)
{
dev_err
(
dev
,
"Failed to get firmware version, err: %d
\n
"
,
error
);
return
error
;
}
/* Setup input device */
input
->
name
=
"ILI210x Touchscreen"
;
input
->
id
.
bustype
=
BUS_I2C
;
input
->
dev
.
parent
=
dev
;
__set_bit
(
EV_SYN
,
input
->
evbit
);
__set_bit
(
EV_KEY
,
input
->
evbit
);
__set_bit
(
EV_ABS
,
input
->
evbit
);
__set_bit
(
BTN_TOUCH
,
input
->
keybit
);
/* Single touch */
input_set_abs_params
(
input
,
ABS_X
,
0
,
xmax
,
0
,
0
);
input_set_abs_params
(
input
,
ABS_Y
,
0
,
ymax
,
0
,
0
);
/* Multi touch */
input_mt_init_slots
(
input
,
MAX_TOUCHES
,
0
);
input_set_abs_params
(
input
,
ABS_MT_POSITION_X
,
0
,
xmax
,
0
,
0
);
input_set_abs_params
(
input
,
ABS_MT_POSITION_Y
,
0
,
ymax
,
0
,
0
);
input_set_abs_params
(
input
,
ABS_MT_POSITION_X
,
0
,
0xffff
,
0
,
0
);
input_set_abs_params
(
input
,
ABS_MT_POSITION_Y
,
0
,
0xffff
,
0
,
0
);
touchscreen_parse_properties
(
input
,
true
,
&
priv
->
prop
);
input_mt_init_slots
(
input
,
priv
->
max_touches
,
INPUT_MT_DIRECT
);
i2c_set_clientdata
(
client
,
priv
);
error
=
devm_add_action
(
dev
,
ili210x_cancel_work
,
priv
);
if
(
error
)
return
error
;
error
=
request_irq
(
client
->
irq
,
ili210x_irq
,
pdata
->
irq_flags
,
client
->
name
,
priv
);
error
=
devm_request_irq
(
dev
,
client
->
irq
,
ili210x_irq
,
0
,
client
->
name
,
priv
);
if
(
error
)
{
dev_err
(
dev
,
"Unable to request touchscreen IRQ, err: %d
\n
"
,
error
);
goto
err_free_mem
;
return
error
;
}
error
=
sysfs_create_group
(
&
dev
->
kobj
,
&
ili210x_attr_group
);
error
=
devm_device_add_group
(
dev
,
&
ili210x_attr_group
);
if
(
error
)
{
dev_err
(
dev
,
"Unable to create sysfs attributes, err: %d
\n
"
,
error
);
goto
err_free_irq
;
return
error
;
}
error
=
input_register_device
(
priv
->
input
);
if
(
error
)
{
dev_err
(
dev
,
"Cannot register input device, err: %d
\n
"
,
error
);
goto
err_remove_sysfs
;
return
error
;
}
device_init_wakeup
(
dev
,
1
);
...
...
@@ -286,28 +367,6 @@ static int ili210x_i2c_probe(struct i2c_client *client,
client
->
irq
,
firmware
.
id
,
firmware
.
major
,
firmware
.
minor
);
return
0
;
err_remove_sysfs:
sysfs_remove_group
(
&
dev
->
kobj
,
&
ili210x_attr_group
);
err_free_irq:
free_irq
(
client
->
irq
,
priv
);
err_free_mem:
input_free_device
(
input
);
kfree
(
priv
);
return
error
;
}
static
int
ili210x_i2c_remove
(
struct
i2c_client
*
client
)
{
struct
ili210x
*
priv
=
i2c_get_clientdata
(
client
);
sysfs_remove_group
(
&
client
->
dev
.
kobj
,
&
ili210x_attr_group
);
free_irq
(
priv
->
client
->
irq
,
priv
);
cancel_delayed_work_sync
(
&
priv
->
dwork
);
input_unregister_device
(
priv
->
input
);
kfree
(
priv
);
return
0
;
}
static
int
__maybe_unused
ili210x_i2c_suspend
(
struct
device
*
dev
)
...
...
@@ -334,19 +393,27 @@ static SIMPLE_DEV_PM_OPS(ili210x_i2c_pm,
ili210x_i2c_suspend
,
ili210x_i2c_resume
);
static
const
struct
i2c_device_id
ili210x_i2c_id
[]
=
{
{
"ili210x"
,
0
},
{
"ili210x"
,
MODEL_ILI210X
},
{
"ili251x"
,
MODEL_ILI251X
},
{
}
};
MODULE_DEVICE_TABLE
(
i2c
,
ili210x_i2c_id
);
static
const
struct
of_device_id
ili210x_dt_ids
[]
=
{
{
.
compatible
=
"ilitek,ili210x"
,
.
data
=
(
void
*
)
MODEL_ILI210X
},
{
.
compatible
=
"ilitek,ili251x"
,
.
data
=
(
void
*
)
MODEL_ILI251X
},
{
},
};
MODULE_DEVICE_TABLE
(
of
,
ili210x_dt_ids
);
static
struct
i2c_driver
ili210x_ts_driver
=
{
.
driver
=
{
.
name
=
"ili210x_i2c"
,
.
pm
=
&
ili210x_i2c_pm
,
.
of_match_table
=
ili210x_dt_ids
,
},
.
id_table
=
ili210x_i2c_id
,
.
probe
=
ili210x_i2c_probe
,
.
remove
=
ili210x_i2c_remove
,
};
module_i2c_driver
(
ili210x_ts_driver
);
...
...
drivers/input/touchscreen/st1232.c
View file @
65e91e28
...
...
@@ -11,25 +11,19 @@
*/
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/gpio
/consumer
.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/pm_qos.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/input/touchscreen.h>
#define ST1232_TS_NAME "st1232-ts"
#define MIN_X 0x00
#define MIN_Y 0x00
#define MAX_X 0x31f
/* (800 - 1) */
#define MAX_Y 0x1df
/* (480 - 1) */
#define MAX_AREA 0xff
#define MAX_FINGERS 2
#define ST1633_TS_NAME "st1633-ts"
struct
st1232_ts_finger
{
u16
x
;
...
...
@@ -38,12 +32,25 @@ struct st1232_ts_finger {
bool
is_valid
;
};
struct
st_chip_info
{
bool
have_z
;
u16
max_x
;
u16
max_y
;
u16
max_area
;
u16
max_fingers
;
u8
start_reg
;
};
struct
st1232_ts_data
{
struct
i2c_client
*
client
;
struct
input_dev
*
input_dev
;
struct
st1232_ts_finger
finger
[
MAX_FINGERS
]
;
struct
touchscreen_properties
prop
;
struct
dev_pm_qos_request
low_latency_req
;
int
reset_gpio
;
struct
gpio_desc
*
reset_gpio
;
const
struct
st_chip_info
*
chip_info
;
int
read_buf_len
;
u8
*
read_buf
;
struct
st1232_ts_finger
*
finger
;
};
static
int
st1232_ts_read_data
(
struct
st1232_ts_data
*
ts
)
...
...
@@ -52,40 +59,35 @@ static int st1232_ts_read_data(struct st1232_ts_data *ts)
struct
i2c_client
*
client
=
ts
->
client
;
struct
i2c_msg
msg
[
2
];
int
error
;
u8
start_reg
;
u8
buf
[
10
];
int
i
,
y
;
u8
start_reg
=
ts
->
chip_info
->
start_reg
;
u8
*
buf
=
ts
->
read_buf
;
/* read touchscreen data
from ST1232
*/
/* read touchscreen data */
msg
[
0
].
addr
=
client
->
addr
;
msg
[
0
].
flags
=
0
;
msg
[
0
].
len
=
1
;
msg
[
0
].
buf
=
&
start_reg
;
start_reg
=
0x10
;
msg
[
1
].
addr
=
ts
->
client
->
addr
;
msg
[
1
].
flags
=
I2C_M_RD
;
msg
[
1
].
len
=
sizeof
(
buf
)
;
msg
[
1
].
len
=
ts
->
read_buf_len
;
msg
[
1
].
buf
=
buf
;
error
=
i2c_transfer
(
client
->
adapter
,
msg
,
2
);
if
(
error
<
0
)
return
error
;
/* get "valid" bits */
finger
[
0
].
is_valid
=
buf
[
2
]
>>
7
;
finger
[
1
].
is_valid
=
buf
[
5
]
>>
7
;
for
(
i
=
0
,
y
=
0
;
i
<
ts
->
chip_info
->
max_fingers
;
i
++
,
y
+=
3
)
{
finger
[
i
].
is_valid
=
buf
[
i
+
y
]
>>
7
;
if
(
finger
[
i
].
is_valid
)
{
finger
[
i
].
x
=
((
buf
[
i
+
y
]
&
0x0070
)
<<
4
)
|
buf
[
i
+
1
];
finger
[
i
].
y
=
((
buf
[
i
+
y
]
&
0x0007
)
<<
8
)
|
buf
[
i
+
2
];
/* get xy coordinate */
if
(
finger
[
0
].
is_valid
)
{
finger
[
0
].
x
=
((
buf
[
2
]
&
0x0070
)
<<
4
)
|
buf
[
3
];
finger
[
0
].
y
=
((
buf
[
2
]
&
0x0007
)
<<
8
)
|
buf
[
4
];
finger
[
0
].
t
=
buf
[
8
];
}
if
(
finger
[
1
].
is_valid
)
{
finger
[
1
].
x
=
((
buf
[
5
]
&
0x0070
)
<<
4
)
|
buf
[
6
];
finger
[
1
].
y
=
((
buf
[
5
]
&
0x0007
)
<<
8
)
|
buf
[
7
];
finger
[
1
].
t
=
buf
[
9
];
/* st1232 includes a z-axis / touch strength */
if
(
ts
->
chip_info
->
have_z
)
finger
[
i
].
t
=
buf
[
i
+
6
];
}
}
return
0
;
...
...
@@ -104,13 +106,16 @@ static irqreturn_t st1232_ts_irq_handler(int irq, void *dev_id)
goto
end
;
/* multi touch protocol */
for
(
i
=
0
;
i
<
MAX_FINGERS
;
i
++
)
{
for
(
i
=
0
;
i
<
ts
->
chip_info
->
max_fingers
;
i
++
)
{
if
(
!
finger
[
i
].
is_valid
)
continue
;
input_report_abs
(
input_dev
,
ABS_MT_TOUCH_MAJOR
,
finger
[
i
].
t
);
input_report_abs
(
input_dev
,
ABS_MT_POSITION_X
,
finger
[
i
].
x
);
input_report_abs
(
input_dev
,
ABS_MT_POSITION_Y
,
finger
[
i
].
y
);
if
(
ts
->
chip_info
->
have_z
)
input_report_abs
(
input_dev
,
ABS_MT_TOUCH_MAJOR
,
finger
[
i
].
t
);
touchscreen_report_pos
(
input_dev
,
&
ts
->
prop
,
finger
[
i
].
x
,
finger
[
i
].
y
,
true
);
input_mt_sync
(
input_dev
);
count
++
;
}
...
...
@@ -138,17 +143,45 @@ static irqreturn_t st1232_ts_irq_handler(int irq, void *dev_id)
static
void
st1232_ts_power
(
struct
st1232_ts_data
*
ts
,
bool
poweron
)
{
if
(
gpio_is_valid
(
ts
->
reset_gpio
)
)
gpio
_direction_output
(
ts
->
reset_gpio
,
poweron
);
if
(
ts
->
reset_gpio
)
gpio
d_set_value_cansleep
(
ts
->
reset_gpio
,
!
poweron
);
}
static
const
struct
st_chip_info
st1232_chip_info
=
{
.
have_z
=
true
,
.
max_x
=
0x31f
,
/* 800 - 1 */
.
max_y
=
0x1df
,
/* 480 -1 */
.
max_area
=
0xff
,
.
max_fingers
=
2
,
.
start_reg
=
0x12
,
};
static
const
struct
st_chip_info
st1633_chip_info
=
{
.
have_z
=
false
,
.
max_x
=
0x13f
,
/* 320 - 1 */
.
max_y
=
0x1df
,
/* 480 -1 */
.
max_area
=
0x00
,
.
max_fingers
=
5
,
.
start_reg
=
0x12
,
};
static
int
st1232_ts_probe
(
struct
i2c_client
*
client
,
const
struct
i2c_device_id
*
id
)
{
const
struct
st_chip_info
*
match
;
struct
st1232_ts_data
*
ts
;
struct
st1232_ts_finger
*
finger
;
struct
input_dev
*
input_dev
;
int
error
;
match
=
device_get_match_data
(
&
client
->
dev
);
if
(
!
match
&&
id
)
match
=
(
const
void
*
)
id
->
driver_data
;
if
(
!
match
)
{
dev_err
(
&
client
->
dev
,
"unknown device model
\n
"
);
return
-
ENODEV
;
}
if
(
!
i2c_check_functionality
(
client
->
adapter
,
I2C_FUNC_I2C
))
{
dev_err
(
&
client
->
dev
,
"need I2C_FUNC_I2C
\n
"
);
return
-
EIO
;
...
...
@@ -163,6 +196,19 @@ static int st1232_ts_probe(struct i2c_client *client,
if
(
!
ts
)
return
-
ENOMEM
;
ts
->
chip_info
=
match
;
ts
->
finger
=
devm_kcalloc
(
&
client
->
dev
,
ts
->
chip_info
->
max_fingers
,
sizeof
(
*
finger
),
GFP_KERNEL
);
if
(
!
ts
->
finger
)
return
-
ENOMEM
;
/* allocate a buffer according to the number of registers to read */
ts
->
read_buf_len
=
ts
->
chip_info
->
max_fingers
*
4
;
ts
->
read_buf
=
devm_kzalloc
(
&
client
->
dev
,
ts
->
read_buf_len
,
GFP_KERNEL
);
if
(
!
ts
->
read_buf
)
return
-
ENOMEM
;
input_dev
=
devm_input_allocate_device
(
&
client
->
dev
);
if
(
!
input_dev
)
return
-
ENOMEM
;
...
...
@@ -170,15 +216,13 @@ static int st1232_ts_probe(struct i2c_client *client,
ts
->
client
=
client
;
ts
->
input_dev
=
input_dev
;
ts
->
reset_gpio
=
of_get_gpio
(
client
->
dev
.
of_node
,
0
);
if
(
gpio_is_valid
(
ts
->
reset_gpio
))
{
error
=
devm_gpio_request
(
&
client
->
dev
,
ts
->
reset_gpio
,
NULL
);
if
(
error
)
{
dev_err
(
&
client
->
dev
,
"Unable to request GPIO pin %d.
\n
"
,
ts
->
reset_gpio
);
return
error
;
}
ts
->
reset_gpio
=
devm_gpiod_get_optional
(
&
client
->
dev
,
NULL
,
GPIOD_OUT_HIGH
);
if
(
IS_ERR
(
ts
->
reset_gpio
))
{
error
=
PTR_ERR
(
ts
->
reset_gpio
);
dev_err
(
&
client
->
dev
,
"Unable to request GPIO pin: %d.
\n
"
,
error
);
return
error
;
}
st1232_ts_power
(
ts
,
true
);
...
...
@@ -192,9 +236,16 @@ static int st1232_ts_probe(struct i2c_client *client,
__set_bit
(
EV_KEY
,
input_dev
->
evbit
);
__set_bit
(
EV_ABS
,
input_dev
->
evbit
);
input_set_abs_params
(
input_dev
,
ABS_MT_TOUCH_MAJOR
,
0
,
MAX_AREA
,
0
,
0
);
input_set_abs_params
(
input_dev
,
ABS_MT_POSITION_X
,
MIN_X
,
MAX_X
,
0
,
0
);
input_set_abs_params
(
input_dev
,
ABS_MT_POSITION_Y
,
MIN_Y
,
MAX_Y
,
0
,
0
);
if
(
ts
->
chip_info
->
have_z
)
input_set_abs_params
(
input_dev
,
ABS_MT_TOUCH_MAJOR
,
0
,
ts
->
chip_info
->
max_area
,
0
,
0
);
input_set_abs_params
(
input_dev
,
ABS_MT_POSITION_X
,
0
,
ts
->
chip_info
->
max_x
,
0
,
0
);
input_set_abs_params
(
input_dev
,
ABS_MT_POSITION_Y
,
0
,
ts
->
chip_info
->
max_y
,
0
,
0
);
touchscreen_parse_properties
(
input_dev
,
true
,
&
ts
->
prop
);
error
=
devm_request_threaded_irq
(
&
client
->
dev
,
client
->
irq
,
NULL
,
st1232_ts_irq_handler
,
...
...
@@ -261,13 +312,15 @@ static SIMPLE_DEV_PM_OPS(st1232_ts_pm_ops,
st1232_ts_suspend
,
st1232_ts_resume
);
static
const
struct
i2c_device_id
st1232_ts_id
[]
=
{
{
ST1232_TS_NAME
,
0
},
{
ST1232_TS_NAME
,
(
unsigned
long
)
&
st1232_chip_info
},
{
ST1633_TS_NAME
,
(
unsigned
long
)
&
st1633_chip_info
},
{
}
};
MODULE_DEVICE_TABLE
(
i2c
,
st1232_ts_id
);
static
const
struct
of_device_id
st1232_ts_dt_ids
[]
=
{
{
.
compatible
=
"sitronix,st1232"
,
},
{
.
compatible
=
"sitronix,st1232"
,
.
data
=
&
st1232_chip_info
},
{
.
compatible
=
"sitronix,st1633"
,
.
data
=
&
st1633_chip_info
},
{
}
};
MODULE_DEVICE_TABLE
(
of
,
st1232_ts_dt_ids
);
...
...
@@ -286,5 +339,6 @@ static struct i2c_driver st1232_ts_driver = {
module_i2c_driver
(
st1232_ts_driver
);
MODULE_AUTHOR
(
"Tony SIM <chinyeow.sim.xt@renesas.com>"
);
MODULE_AUTHOR
(
"Martin Kepplinger <martin.kepplinger@ginzinger.com>"
);
MODULE_DESCRIPTION
(
"SITRONIX ST1232 Touchscreen Controller Driver"
);
MODULE_LICENSE
(
"GPL v2"
);
drivers/input/touchscreen/stmfts.c
View file @
65e91e28
...
...
@@ -106,27 +106,29 @@ struct stmfts_data {
bool
running
;
};
static
void
stmfts_brightness_set
(
struct
led_classdev
*
led_cdev
,
static
int
stmfts_brightness_set
(
struct
led_classdev
*
led_cdev
,
enum
led_brightness
value
)
{
struct
stmfts_data
*
sdata
=
container_of
(
led_cdev
,
struct
stmfts_data
,
led_cdev
);
int
err
;
if
(
value
==
sdata
->
led_status
||
!
sdata
->
ledvdd
)
return
;
if
(
!
value
)
{
regulator_disable
(
sdata
->
ledvdd
);
}
else
{
err
=
regulator_enable
(
sdata
->
ledvdd
);
if
(
err
)
dev_warn
(
&
sdata
->
client
->
dev
,
"failed to disable ledvdd regulator: %d
\n
"
,
err
);
if
(
value
!=
sdata
->
led_status
&&
sdata
->
ledvdd
)
{
if
(
!
value
)
{
regulator_disable
(
sdata
->
ledvdd
);
}
else
{
err
=
regulator_enable
(
sdata
->
ledvdd
);
if
(
err
)
{
dev_warn
(
&
sdata
->
client
->
dev
,
"failed to disable ledvdd regulator: %d
\n
"
,
err
);
return
err
;
}
}
sdata
->
led_status
=
value
;
}
sdata
->
led_status
=
value
;
return
0
;
}
static
enum
led_brightness
stmfts_brightness_get
(
struct
led_classdev
*
led_cdev
)
...
...
@@ -608,7 +610,7 @@ static int stmfts_enable_led(struct stmfts_data *sdata)
sdata
->
led_cdev
.
name
=
STMFTS_DEV_NAME
;
sdata
->
led_cdev
.
max_brightness
=
LED_ON
;
sdata
->
led_cdev
.
brightness
=
LED_OFF
;
sdata
->
led_cdev
.
brightness_set
=
stmfts_brightness_set
;
sdata
->
led_cdev
.
brightness_set
_blocking
=
stmfts_brightness_set
;
sdata
->
led_cdev
.
brightness_get
=
stmfts_brightness_get
;
err
=
devm_led_classdev_register
(
&
sdata
->
client
->
dev
,
&
sdata
->
led_cdev
);
...
...
drivers/input/touchscreen/sx8654.c
View file @
65e91e28
...
...
@@ -27,12 +27,16 @@
* published by the Free Software Foundation.
*/
#include <linux/
input
.h>
#include <linux/
module
.h>
#include <linux/
of
.h>
#include <linux/
bitops
.h>
#include <linux/
delay
.h>
#include <linux/
gpio/consumer
.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/input/touchscreen.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/of.h>
/* register addresses */
#define I2C_REG_TOUCH0 0x00
...
...
@@ -42,25 +46,28 @@
#define I2C_REG_IRQSRC 0x23
#define I2C_REG_SOFTRESET 0x3f
#define I2C_REG_SX8650_STAT 0x05
#define SX8650_STAT_CONVIRQ BIT(7)
/* commands */
#define CMD_READ_REGISTER 0x40
#define CMD_MANUAL 0xc0
#define CMD_PENTRG 0xe0
/* value for I2C_REG_SOFTRESET */
#define SOFTRESET_VALUE 0xde
/* bits for I2C_REG_IRQSRC */
#define IRQ_PENTOUCH_TOUCHCONVDONE
0x08
#define IRQ_PENRELEASE
0x04
#define IRQ_PENTOUCH_TOUCHCONVDONE
BIT(3)
#define IRQ_PENRELEASE
BIT(2)
/* bits for RegTouch1 */
#define CONDIRQ 0x20
#define RPDNT_100K 0x00
#define FILT_7SA 0x03
/* bits for I2C_REG_CHANMASK */
#define CONV_X
0x80
#define CONV_Y
0x40
#define CONV_X
BIT(7)
#define CONV_Y
BIT(6)
/* coordinates rate: higher nibble of CTRL0 register */
#define RATE_MANUAL 0x00
...
...
@@ -69,13 +76,122 @@
/* power delay: lower nibble of CTRL0 register */
#define POWDLY_1_1MS 0x0b
/* for sx8650, as we have no pen release IRQ there: timeout in ns following the
* last PENIRQ after which we assume the pen is lifted.
*/
#define SX8650_PENIRQ_TIMEOUT msecs_to_jiffies(10)
#define MAX_12BIT ((1 << 12) - 1)
#define MAX_I2C_READ_LEN 10
/* see datasheet section 5.1.5 */
/* channel definition */
#define CH_X 0x00
#define CH_Y 0x01
struct
sx865x_data
{
u8
cmd_manual
;
u8
chan_mask
;
bool
has_irq_penrelease
;
bool
has_reg_irqmask
;
irq_handler_t
irqh
;
};
struct
sx8654
{
struct
input_dev
*
input
;
struct
i2c_client
*
client
;
struct
gpio_desc
*
gpio_reset
;
spinlock_t
lock
;
/* for input reporting from irq/timer */
struct
timer_list
timer
;
struct
touchscreen_properties
props
;
const
struct
sx865x_data
*
data
;
};
static
inline
void
sx865x_penrelease
(
struct
sx8654
*
ts
)
{
struct
input_dev
*
input_dev
=
ts
->
input
;
input_report_key
(
input_dev
,
BTN_TOUCH
,
0
);
input_sync
(
input_dev
);
}
static
void
sx865x_penrelease_timer_handler
(
struct
timer_list
*
t
)
{
struct
sx8654
*
ts
=
from_timer
(
ts
,
t
,
timer
);
unsigned
long
flags
;
spin_lock_irqsave
(
&
ts
->
lock
,
flags
);
sx865x_penrelease
(
ts
);
spin_unlock_irqrestore
(
&
ts
->
lock
,
flags
);
dev_dbg
(
&
ts
->
client
->
dev
,
"penrelease by timer
\n
"
);
}
static
irqreturn_t
sx8650_irq
(
int
irq
,
void
*
handle
)
{
struct
sx8654
*
ts
=
handle
;
struct
device
*
dev
=
&
ts
->
client
->
dev
;
int
len
,
i
;
unsigned
long
flags
;
u8
stat
;
u16
x
,
y
;
u16
ch
;
u16
chdata
;
__be16
data
[
MAX_I2C_READ_LEN
/
sizeof
(
__be16
)];
u8
nchan
=
hweight32
(
ts
->
data
->
chan_mask
);
u8
readlen
=
nchan
*
sizeof
(
*
data
);
stat
=
i2c_smbus_read_byte_data
(
ts
->
client
,
CMD_READ_REGISTER
|
I2C_REG_SX8650_STAT
);
if
(
!
(
stat
&
SX8650_STAT_CONVIRQ
))
{
dev_dbg
(
dev
,
"%s ignore stat [0x%02x]"
,
__func__
,
stat
);
return
IRQ_HANDLED
;
}
len
=
i2c_master_recv
(
ts
->
client
,
(
u8
*
)
data
,
readlen
);
if
(
len
!=
readlen
)
{
dev_dbg
(
dev
,
"ignore short recv (%d)
\n
"
,
len
);
return
IRQ_HANDLED
;
}
spin_lock_irqsave
(
&
ts
->
lock
,
flags
);
x
=
0
;
y
=
0
;
for
(
i
=
0
;
i
<
nchan
;
i
++
)
{
chdata
=
be16_to_cpu
(
data
[
i
]);
if
(
unlikely
(
chdata
==
0xFFFF
))
{
dev_dbg
(
dev
,
"invalid qualified data @ %d
\n
"
,
i
);
continue
;
}
else
if
(
unlikely
(
chdata
&
0x8000
))
{
dev_warn
(
dev
,
"hibit @ %d [0x%04x]
\n
"
,
i
,
chdata
);
continue
;
}
ch
=
chdata
>>
12
;
if
(
ch
==
CH_X
)
x
=
chdata
&
MAX_12BIT
;
else
if
(
ch
==
CH_Y
)
y
=
chdata
&
MAX_12BIT
;
else
dev_warn
(
dev
,
"unknown channel %d [0x%04x]
\n
"
,
ch
,
chdata
);
}
touchscreen_report_pos
(
ts
->
input
,
&
ts
->
props
,
x
,
y
,
false
);
input_report_key
(
ts
->
input
,
BTN_TOUCH
,
1
);
input_sync
(
ts
->
input
);
dev_dbg
(
dev
,
"point(%4d,%4d)
\n
"
,
x
,
y
);
mod_timer
(
&
ts
->
timer
,
jiffies
+
SX8650_PENIRQ_TIMEOUT
);
spin_unlock_irqrestore
(
&
ts
->
lock
,
flags
);
return
IRQ_HANDLED
;
}
static
irqreturn_t
sx8654_irq
(
int
irq
,
void
*
handle
)
{
struct
sx8654
*
sx8654
=
handle
;
...
...
@@ -112,8 +228,8 @@ static irqreturn_t sx8654_irq(int irq, void *handle)
x
=
((
data
[
0
]
&
0xf
)
<<
8
)
|
(
data
[
1
]);
y
=
((
data
[
2
]
&
0xf
)
<<
8
)
|
(
data
[
3
]);
input_report_abs
(
sx8654
->
input
,
ABS_X
,
x
);
input_report_abs
(
sx8654
->
input
,
ABS_Y
,
y
);
touchscreen_report_pos
(
sx8654
->
input
,
&
sx8654
->
props
,
x
,
y
,
false
);
input_report_key
(
sx8654
->
input
,
BTN_TOUCH
,
1
);
input_sync
(
sx8654
->
input
);
...
...
@@ -124,6 +240,25 @@ static irqreturn_t sx8654_irq(int irq, void *handle)
return
IRQ_HANDLED
;
}
static
int
sx8654_reset
(
struct
sx8654
*
ts
)
{
int
err
;
if
(
ts
->
gpio_reset
)
{
gpiod_set_value_cansleep
(
ts
->
gpio_reset
,
1
);
udelay
(
2
);
/* Tpulse > 1µs */
gpiod_set_value_cansleep
(
ts
->
gpio_reset
,
0
);
}
else
{
dev_dbg
(
&
ts
->
client
->
dev
,
"NRST unavailable, try softreset
\n
"
);
err
=
i2c_smbus_write_byte_data
(
ts
->
client
,
I2C_REG_SOFTRESET
,
SOFTRESET_VALUE
);
if
(
err
)
return
err
;
}
return
0
;
}
static
int
sx8654_open
(
struct
input_dev
*
dev
)
{
struct
sx8654
*
sx8654
=
input_get_drvdata
(
dev
);
...
...
@@ -157,14 +292,17 @@ static void sx8654_close(struct input_dev *dev)
disable_irq
(
client
->
irq
);
if
(
!
sx8654
->
data
->
has_irq_penrelease
)
del_timer_sync
(
&
sx8654
->
timer
);
/* enable manual mode mode */
error
=
i2c_smbus_write_byte
(
client
,
CMD_MANUAL
);
error
=
i2c_smbus_write_byte
(
client
,
sx8654
->
data
->
cmd_manual
);
if
(
error
)
{
dev_err
(
&
client
->
dev
,
"writing command CMD_MANUAL failed"
);
return
;
}
error
=
i2c_smbus_write_byte_data
(
client
,
I2C_REG_TOUCH0
,
0
);
error
=
i2c_smbus_write_byte_data
(
client
,
I2C_REG_TOUCH0
,
RATE_MANUAL
);
if
(
error
)
{
dev_err
(
&
client
->
dev
,
"writing to I2C_REG_TOUCH0 failed"
);
return
;
...
...
@@ -186,6 +324,31 @@ static int sx8654_probe(struct i2c_client *client,
if
(
!
sx8654
)
return
-
ENOMEM
;
sx8654
->
gpio_reset
=
devm_gpiod_get_optional
(
&
client
->
dev
,
"reset"
,
GPIOD_OUT_HIGH
);
if
(
IS_ERR
(
sx8654
->
gpio_reset
))
{
error
=
PTR_ERR
(
sx8654
->
gpio_reset
);
if
(
error
!=
-
EPROBE_DEFER
)
dev_err
(
&
client
->
dev
,
"unable to get reset-gpio: %d
\n
"
,
error
);
return
error
;
}
dev_dbg
(
&
client
->
dev
,
"got GPIO reset pin
\n
"
);
sx8654
->
data
=
device_get_match_data
(
&
client
->
dev
);
if
(
!
sx8654
->
data
)
sx8654
->
data
=
(
const
struct
sx865x_data
*
)
id
->
driver_data
;
if
(
!
sx8654
->
data
)
{
dev_err
(
&
client
->
dev
,
"invalid or missing device data
\n
"
);
return
-
EINVAL
;
}
if
(
!
sx8654
->
data
->
has_irq_penrelease
)
{
dev_dbg
(
&
client
->
dev
,
"use timer for penrelease
\n
"
);
timer_setup
(
&
sx8654
->
timer
,
sx865x_penrelease_timer_handler
,
0
);
spin_lock_init
(
&
sx8654
->
lock
);
}
input
=
devm_input_allocate_device
(
&
client
->
dev
);
if
(
!
input
)
return
-
ENOMEM
;
...
...
@@ -201,43 +364,46 @@ static int sx8654_probe(struct i2c_client *client,
input_set_abs_params
(
input
,
ABS_X
,
0
,
MAX_12BIT
,
0
,
0
);
input_set_abs_params
(
input
,
ABS_Y
,
0
,
MAX_12BIT
,
0
,
0
);
touchscreen_parse_properties
(
input
,
false
,
&
sx8654
->
props
);
sx8654
->
client
=
client
;
sx8654
->
input
=
input
;
input_set_drvdata
(
sx8654
->
input
,
sx8654
);
error
=
i2c_smbus_write_byte_data
(
client
,
I2C_REG_SOFTRESET
,
SOFTRESET_VALUE
);
error
=
sx8654_reset
(
sx8654
);
if
(
error
)
{
dev_err
(
&
client
->
dev
,
"
writing softreset value
failed"
);
dev_err
(
&
client
->
dev
,
"
reset
failed"
);
return
error
;
}
error
=
i2c_smbus_write_byte_data
(
client
,
I2C_REG_CHANMASK
,
CONV_X
|
CONV_Y
);
sx8654
->
data
->
chan_mask
);
if
(
error
)
{
dev_err
(
&
client
->
dev
,
"writing to I2C_REG_CHANMASK failed"
);
return
error
;
}
error
=
i2c_smbus_write_byte_data
(
client
,
I2C_REG_IRQMASK
,
IRQ_PENTOUCH_TOUCHCONVDONE
|
IRQ_PENRELEASE
);
if
(
error
)
{
dev_err
(
&
client
->
dev
,
"writing to I2C_REG_IRQMASK failed"
);
return
error
;
if
(
sx8654
->
data
->
has_reg_irqmask
)
{
error
=
i2c_smbus_write_byte_data
(
client
,
I2C_REG_IRQMASK
,
IRQ_PENTOUCH_TOUCHCONVDONE
|
IRQ_PENRELEASE
);
if
(
error
)
{
dev_err
(
&
client
->
dev
,
"writing I2C_REG_IRQMASK failed"
);
return
error
;
}
}
error
=
i2c_smbus_write_byte_data
(
client
,
I2C_REG_TOUCH1
,
CONDIRQ
|
FILT_7SA
);
CONDIRQ
|
RPDNT_100K
|
FILT_7SA
);
if
(
error
)
{
dev_err
(
&
client
->
dev
,
"writing to I2C_REG_TOUCH1 failed"
);
return
error
;
}
error
=
devm_request_threaded_irq
(
&
client
->
dev
,
client
->
irq
,
NULL
,
sx8654
_irq
,
IRQF_
TRIGGER_FALLING
|
IRQF_
ONESHOT
,
NULL
,
sx8654
->
data
->
irqh
,
IRQF_ONESHOT
,
client
->
name
,
sx8654
);
if
(
error
)
{
dev_err
(
&
client
->
dev
,
...
...
@@ -256,17 +422,48 @@ static int sx8654_probe(struct i2c_client *client,
return
0
;
}
static
const
struct
sx865x_data
sx8650_data
=
{
.
cmd_manual
=
0xb0
,
.
has_irq_penrelease
=
false
,
.
has_reg_irqmask
=
false
,
.
chan_mask
=
(
CONV_X
|
CONV_Y
),
.
irqh
=
sx8650_irq
,
};
static
const
struct
sx865x_data
sx8654_data
=
{
.
cmd_manual
=
0xc0
,
.
has_irq_penrelease
=
true
,
.
has_reg_irqmask
=
true
,
.
chan_mask
=
(
CONV_X
|
CONV_Y
),
.
irqh
=
sx8654_irq
,
};
#ifdef CONFIG_OF
static
const
struct
of_device_id
sx8654_of_match
[]
=
{
{
.
compatible
=
"semtech,sx8654"
,
},
{
},
{
.
compatible
=
"semtech,sx8650"
,
.
data
=
&
sx8650_data
,
},
{
.
compatible
=
"semtech,sx8654"
,
.
data
=
&
sx8654_data
,
},
{
.
compatible
=
"semtech,sx8655"
,
.
data
=
&
sx8654_data
,
},
{
.
compatible
=
"semtech,sx8656"
,
.
data
=
&
sx8654_data
,
},
{
}
};
MODULE_DEVICE_TABLE
(
of
,
sx8654_of_match
);
#endif
static
const
struct
i2c_device_id
sx8654_id_table
[]
=
{
{
"semtech_sx8654"
,
0
},
{
},
{
.
name
=
"semtech_sx8650"
,
.
driver_data
=
(
long
)
&
sx8650_data
},
{
.
name
=
"semtech_sx8654"
,
.
driver_data
=
(
long
)
&
sx8654_data
},
{
.
name
=
"semtech_sx8655"
,
.
driver_data
=
(
long
)
&
sx8654_data
},
{
.
name
=
"semtech_sx8656"
,
.
driver_data
=
(
long
)
&
sx8654_data
},
{
}
};
MODULE_DEVICE_TABLE
(
i2c
,
sx8654_id_table
);
...
...
drivers/input/touchscreen/ti_am335x_tsc.c
View file @
65e91e28
...
...
@@ -507,10 +507,8 @@ static int titsc_remove(struct platform_device *pdev)
static
int
__maybe_unused
titsc_suspend
(
struct
device
*
dev
)
{
struct
titsc
*
ts_dev
=
dev_get_drvdata
(
dev
);
struct
ti_tscadc_dev
*
tscadc_dev
;
unsigned
int
idle
;
tscadc_dev
=
ti_tscadc_dev_get
(
to_platform_device
(
dev
));
if
(
device_may_wakeup
(
dev
))
{
titsc_writel
(
ts_dev
,
REG_IRQSTATUS
,
TSC_IRQENB_MASK
);
idle
=
titsc_readl
(
ts_dev
,
REG_IRQENABLE
);
...
...
@@ -524,9 +522,7 @@ static int __maybe_unused titsc_suspend(struct device *dev)
static
int
__maybe_unused
titsc_resume
(
struct
device
*
dev
)
{
struct
titsc
*
ts_dev
=
dev_get_drvdata
(
dev
);
struct
ti_tscadc_dev
*
tscadc_dev
;
tscadc_dev
=
ti_tscadc_dev_get
(
to_platform_device
(
dev
));
if
(
device_may_wakeup
(
dev
))
{
titsc_writel
(
ts_dev
,
REG_IRQWAKEUP
,
0x00
);
...
...
include/linux/input/ili210x.h
deleted
100644 → 0
View file @
7ad222b3
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ILI210X_H
#define _ILI210X_H
struct
ili210x_platform_data
{
unsigned
long
irq_flags
;
unsigned
int
poll_period
;
bool
(
*
get_pendown_state
)(
void
);
};
#endif
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