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
c758f96a
Commit
c758f96a
authored
Oct 03, 2016
by
Dmitry Torokhov
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'next' into for-linus
Prepare first round of input updates for 4.9 merge window.
parents
9fb6de1b
265d426d
Changes
34
Hide whitespace changes
Inline
Side-by-side
Showing
34 changed files
with
1033 additions
and
519 deletions
+1033
-519
Documentation/devicetree/bindings/input/adc-keys.txt
Documentation/devicetree/bindings/input/adc-keys.txt
+49
-0
Documentation/devicetree/bindings/input/gpio-decoder.txt
Documentation/devicetree/bindings/input/gpio-decoder.txt
+23
-0
Documentation/devicetree/bindings/input/gpio-keys-polled.txt
Documentation/devicetree/bindings/input/gpio-keys-polled.txt
+2
-3
Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
...tion/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
+8
-0
Documentation/devicetree/bindings/input/touchscreen/ektf2127.txt
...tation/devicetree/bindings/input/touchscreen/ektf2127.txt
+27
-0
Documentation/devicetree/bindings/input/touchscreen/focaltech-ft6236.txt
...evicetree/bindings/input/touchscreen/focaltech-ft6236.txt
+0
-35
Documentation/devicetree/bindings/input/tps65218-pwrbutton.txt
...entation/devicetree/bindings/input/tps65218-pwrbutton.txt
+14
-3
arch/arm/mach-sa1100/jornada720.c
arch/arm/mach-sa1100/jornada720.c
+16
-0
drivers/input/keyboard/Kconfig
drivers/input/keyboard/Kconfig
+15
-0
drivers/input/keyboard/Makefile
drivers/input/keyboard/Makefile
+1
-0
drivers/input/keyboard/adc-keys.c
drivers/input/keyboard/adc-keys.c
+210
-0
drivers/input/keyboard/jornada720_kbd.c
drivers/input/keyboard/jornada720_kbd.c
+16
-43
drivers/input/keyboard/snvs_pwrkey.c
drivers/input/keyboard/snvs_pwrkey.c
+0
-1
drivers/input/misc/Kconfig
drivers/input/misc/Kconfig
+14
-2
drivers/input/misc/Makefile
drivers/input/misc/Makefile
+1
-0
drivers/input/misc/gpio_decoder.c
drivers/input/misc/gpio_decoder.c
+137
-0
drivers/input/misc/max77693-haptic.c
drivers/input/misc/max77693-haptic.c
+2
-2
drivers/input/misc/tps65218-pwrbutton.c
drivers/input/misc/tps65218-pwrbutton.c
+65
-27
drivers/input/mouse/elan_i2c_smbus.c
drivers/input/mouse/elan_i2c_smbus.c
+12
-8
drivers/input/mouse/focaltech.c
drivers/input/mouse/focaltech.c
+2
-1
drivers/input/mouse/psmouse-base.c
drivers/input/mouse/psmouse-base.c
+1
-1
drivers/input/serio/serport.c
drivers/input/serio/serport.c
+14
-3
drivers/input/tablet/pegasus_notetaker.c
drivers/input/tablet/pegasus_notetaker.c
+1
-0
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/Kconfig
+12
-13
drivers/input/touchscreen/Makefile
drivers/input/touchscreen/Makefile
+1
-1
drivers/input/touchscreen/edt-ft5x06.c
drivers/input/touchscreen/edt-ft5x06.c
+8
-0
drivers/input/touchscreen/ektf2127.c
drivers/input/touchscreen/ektf2127.c
+336
-0
drivers/input/touchscreen/elants_i2c.c
drivers/input/touchscreen/elants_i2c.c
+20
-11
drivers/input/touchscreen/ft6236.c
drivers/input/touchscreen/ft6236.c
+0
-326
drivers/input/touchscreen/jornada720_ts.c
drivers/input/touchscreen/jornada720_ts.c
+14
-7
drivers/input/touchscreen/mc13783_ts.c
drivers/input/touchscreen/mc13783_ts.c
+7
-17
drivers/input/touchscreen/pixcir_i2c_ts.c
drivers/input/touchscreen/pixcir_i2c_ts.c
+1
-12
drivers/input/touchscreen/wdt87xx_i2c.c
drivers/input/touchscreen/wdt87xx_i2c.c
+3
-2
drivers/input/touchscreen/wm97xx-core.c
drivers/input/touchscreen/wm97xx-core.c
+1
-1
No files found.
Documentation/devicetree/bindings/input/adc-keys.txt
0 → 100644
View file @
c758f96a
ADC attached resistor ladder buttons
------------------------------------
Required properties:
- compatible: "adc-keys"
- io-channels: Phandle to an ADC channel
- io-channel-names = "buttons";
- keyup-threshold-microvolt: Voltage at which all the keys are considered up.
Optional properties:
- poll-interval: Poll interval time in milliseconds
- autorepeat: Boolean, Enable auto repeat feature of Linux input
subsystem.
Each button (key) is represented as a sub-node of "adc-keys":
Required subnode-properties:
- label: Descriptive name of the key.
- linux,code: Keycode to emit.
- press-threshold-microvolt: Voltage ADC input when this key is pressed.
Example:
#include <dt-bindings/input/input.h>
adc-keys {
compatible = "adc-keys";
io-channels = <&lradc 0>;
io-channel-names = "buttons";
keyup-threshold-microvolt = <2000000>;
button-up {
label = "Volume Up";
linux,code = <KEY_VOLUMEUP>;
press-threshold-microvolt = <1500000>;
};
button-down {
label = "Volume Down";
linux,code = <KEY_VOLUMEDOWN>;
press-threshold-microvolt = <1000000>;
};
button-enter {
label = "Enter";
linux,code = <KEY_ENTER>;
press-threshold-microvolt = <500000>;
};
};
Documentation/devicetree/bindings/input/gpio-decoder.txt
0 → 100644
View file @
c758f96a
* GPIO Decoder DT bindings
Required Properties:
- compatible: should be "gpio-decoder"
- gpios: a spec of gpios (at least two) to be decoded to a number with
first entry representing the MSB.
Optional Properties:
- decoder-max-value: Maximum possible value that can be reported by
the gpios.
- linux,axis: the input subsystem axis to map to (ABS_X/ABS_Y).
Defaults to 0 (ABS_X).
Example:
gpio-decoder0 {
compatible = "gpio-decoder";
gpios = <&pca9536 3 GPIO_ACTIVE_HIGH>,
<&pca9536 2 GPIO_ACTIVE_HIGH>,
<&pca9536 1 GPIO_ACTIVE_HIGH>,
<&pca9536 0 GPIO_ACTIVE_HIGH>;
linux,axis = <0>; /* ABS_X */
decoder-max-value = <9>;
};
Documentation/devicetree/bindings/input/gpio-keys-polled.txt
View file @
c758f96a
...
...
@@ -34,11 +34,10 @@ Example nodes:
gpio_keys_polled {
compatible = "gpio-keys-polled";
#address-cells = <1>;
#size-cells = <0>;
poll-interval = <100>;
autorepeat;
button@21 {
button21 {
label = "GPIO Key UP";
linux,code = <103>;
gpios = <&gpio1 0 1>;
...
...
Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
View file @
c758f96a
...
...
@@ -19,6 +19,7 @@ Required properties:
or: "edt,edt-ft5306"
or: "edt,edt-ft5406"
or: "edt,edt-ft5506"
or: "focaltech,ft6236"
- reg: I2C slave address of the chip (0x38)
- interrupt-parent: a phandle pointing to the interrupt controller
...
...
@@ -43,6 +44,13 @@ Optional properties:
- offset: allows setting the edge compensation in the range from
0 to 31.
- touchscreen-size-x : See touchscreen.txt
- touchscreen-size-y : See touchscreen.txt
- touchscreen-fuzz-x : See touchscreen.txt
- touchscreen-fuzz-y : See touchscreen.txt
- touchscreen-inverted-x : See touchscreen.txt
- touchscreen-inverted-y : See touchscreen.txt
- touchscreen-swapped-x-y : See touchscreen.txt
Example:
polytouch: edt-ft5x06@38 {
...
...
Documentation/devicetree/bindings/input/touchscreen/ektf2127.txt
0 → 100644
View file @
c758f96a
* Elan eKTF2127 I2C touchscreen controller
Required properties:
- compatible : "elan,ektf2127"
- reg : I2C slave address of the chip (0x40)
- interrupt-parent : a phandle pointing to the interrupt controller
serving the interrupt for this chip
- interrupts : interrupt specification for the ektf2127 interrupt
- power-gpios : GPIO specification for the pin connected to the
ektf2127's wake input. This needs to be driven high
to take ektf2127 out of it's low power state
For additional optional properties see: touchscreen.txt
Example:
i2c@00000000 {
ektf2127: touchscreen@15 {
compatible = "elan,ektf2127";
reg = <0x15>;
interrupt-parent = <&pio>;
interrupts = <6 11 IRQ_TYPE_EDGE_FALLING>
power-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>;
touchscreen-inverted-x;
touchscreen-swapped-x-y;
};
};
Documentation/devicetree/bindings/input/touchscreen/focaltech-ft6236.txt
deleted
100644 → 0
View file @
9fb6de1b
* FocalTech FT6236 I2C touchscreen controller
Required properties:
- compatible : "focaltech,ft6236"
- reg : I2C slave address of the chip (0x38)
- interrupt-parent : a phandle pointing to the interrupt controller
serving the interrupt for this chip
- interrupts : interrupt specification for the touch controller
interrupt
- reset-gpios : GPIO specification for the RSTN input
- touchscreen-size-x : horizontal resolution of touchscreen (in pixels)
- touchscreen-size-y : vertical resolution of touchscreen (in pixels)
Optional properties:
- touchscreen-fuzz-x : horizontal noise value of the absolute input
device (in pixels)
- touchscreen-fuzz-y : vertical noise value of the absolute input
device (in pixels)
- 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
Example:
ft6x06@38 {
compatible = "focaltech,ft6236";
reg = <0x38>;
interrupt-parent = <&gpio>;
interrupts = <23 2>;
touchscreen-size-x = <320>;
touchscreen-size-y = <480>;
touchscreen-inverted-x;
touchscreen-swapped-x-y;
};
Documentation/devicetree/bindings/input/tps65218-pwrbutton.txt
View file @
c758f96a
Texas Instruments TPS65218 power button
Texas Instruments TPS65217 and TPS65218 power button
This module is part of the TPS65217/TPS65218. For more details about the whole
TPS65217 chip see Documentation/devicetree/bindings/regulator/tps65217.txt.
This driver provides a simple power button event via an Interrupt.
Required properties:
- compatible: should be "ti,tps65218-pwrbutton"
- compatible: should be "ti,tps65217-pwrbutton" or "ti,tps65218-pwrbutton"
Required properties for TPS65218:
- interrupts: should be one of the following
- <3 IRQ_TYPE_EDGE_BOTH>: For controllers compatible with tps65218
Example:
Examples:
&tps {
tps65217-pwrbutton {
compatible = "ti,tps65217-pwrbutton";
};
};
&tps {
power-button {
...
...
arch/arm/mach-sa1100/jornada720.c
View file @
c758f96a
...
...
@@ -17,6 +17,7 @@
#include <linux/kernel.h>
#include <linux/tty.h>
#include <linux/delay.h>
#include <linux/gpio/machine.h>
#include <linux/platform_data/sa11x0-serial.h>
#include <linux/platform_device.h>
#include <linux/ioport.h>
...
...
@@ -217,9 +218,22 @@ static struct platform_device jornada_ssp_device = {
.
id
=
-
1
,
};
static
struct
resource
jornada_kbd_resources
[]
=
{
DEFINE_RES_IRQ
(
IRQ_GPIO0
),
};
static
struct
platform_device
jornada_kbd_device
=
{
.
name
=
"jornada720_kbd"
,
.
id
=
-
1
,
.
num_resources
=
ARRAY_SIZE
(
jornada_kbd_resources
),
.
resource
=
jornada_kbd_resources
,
};
static
struct
gpiod_lookup_table
jornada_ts_gpiod_table
=
{
.
dev_id
=
"jornada_ts"
,
.
table
=
{
GPIO_LOOKUP
(
"gpio"
,
9
,
"penup"
,
GPIO_ACTIVE_HIGH
),
},
};
static
struct
platform_device
jornada_ts_device
=
{
...
...
@@ -250,6 +264,8 @@ static int __init jornada720_init(void)
GPSR
=
GPIO_GPIO20
;
/* restart gpio20 */
udelay
(
20
);
/* give it some time to restart */
gpiod_add_lookup_table
(
&
jornada_ts_gpiod_table
);
ret
=
platform_add_devices
(
devices
,
ARRAY_SIZE
(
devices
));
}
...
...
drivers/input/keyboard/Kconfig
View file @
c758f96a
...
...
@@ -12,6 +12,21 @@ menuconfig INPUT_KEYBOARD
if INPUT_KEYBOARD
config KEYBOARD_ADC
tristate "ADC Ladder Buttons"
depends on IIO
select INPUT_POLLDEV
help
This driver implements support for buttons connected
to an ADC using a resistor ladder.
Say Y here if your device has such buttons connected to an ADC. Your
board-specific setup logic must also provide a configuration data
for mapping voltages to buttons.
To compile this driver as a module, choose M here: the
module will be called adc_keys.
config KEYBOARD_ADP5520
tristate "Keypad Support for ADP5520 PMIC"
depends on PMIC_ADP5520
...
...
drivers/input/keyboard/Makefile
View file @
c758f96a
...
...
@@ -4,6 +4,7 @@
# Each configuration option enables a list of files.
obj-$(CONFIG_KEYBOARD_ADC)
+=
adc-keys.o
obj-$(CONFIG_KEYBOARD_ADP5520)
+=
adp5520-keys.o
obj-$(CONFIG_KEYBOARD_ADP5588)
+=
adp5588-keys.o
obj-$(CONFIG_KEYBOARD_ADP5589)
+=
adp5589-keys.o
...
...
drivers/input/keyboard/adc-keys.c
0 → 100644
View file @
c758f96a
/*
* Input driver for resistor ladder connected on ADC
*
* Copyright (c) 2016 Alexandre Belloni
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*/
#include <linux/err.h>
#include <linux/iio/consumer.h>
#include <linux/iio/types.h>
#include <linux/input.h>
#include <linux/input-polldev.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/slab.h>
struct
adc_keys_button
{
u32
voltage
;
u32
keycode
;
};
struct
adc_keys_state
{
struct
iio_channel
*
channel
;
u32
num_keys
;
u32
last_key
;
u32
keyup_voltage
;
const
struct
adc_keys_button
*
map
;
};
static
void
adc_keys_poll
(
struct
input_polled_dev
*
dev
)
{
struct
adc_keys_state
*
st
=
dev
->
private
;
int
i
,
value
,
ret
;
u32
diff
,
closest
=
0xffffffff
;
int
keycode
=
0
;
ret
=
iio_read_channel_processed
(
st
->
channel
,
&
value
);
if
(
unlikely
(
ret
<
0
))
{
/* Forcibly release key if any was pressed */
value
=
st
->
keyup_voltage
;
}
else
{
for
(
i
=
0
;
i
<
st
->
num_keys
;
i
++
)
{
diff
=
abs
(
st
->
map
[
i
].
voltage
-
value
);
if
(
diff
<
closest
)
{
closest
=
diff
;
keycode
=
st
->
map
[
i
].
keycode
;
}
}
}
if
(
abs
(
st
->
keyup_voltage
-
value
)
<
closest
)
keycode
=
0
;
if
(
st
->
last_key
&&
st
->
last_key
!=
keycode
)
input_report_key
(
dev
->
input
,
st
->
last_key
,
0
);
if
(
keycode
)
input_report_key
(
dev
->
input
,
keycode
,
1
);
input_sync
(
dev
->
input
);
st
->
last_key
=
keycode
;
}
static
int
adc_keys_load_keymap
(
struct
device
*
dev
,
struct
adc_keys_state
*
st
)
{
struct
adc_keys_button
*
map
;
struct
fwnode_handle
*
child
;
int
i
;
st
->
num_keys
=
device_get_child_node_count
(
dev
);
if
(
st
->
num_keys
==
0
)
{
dev_err
(
dev
,
"keymap is missing
\n
"
);
return
-
EINVAL
;
}
map
=
devm_kmalloc_array
(
dev
,
st
->
num_keys
,
sizeof
(
*
map
),
GFP_KERNEL
);
if
(
!
map
)
return
-
ENOMEM
;
i
=
0
;
device_for_each_child_node
(
dev
,
child
)
{
if
(
fwnode_property_read_u32
(
child
,
"press-threshold-microvolt"
,
&
map
[
i
].
voltage
))
{
dev_err
(
dev
,
"Key with invalid or missing voltage
\n
"
);
fwnode_handle_put
(
child
);
return
-
EINVAL
;
}
map
[
i
].
voltage
/=
1000
;
if
(
fwnode_property_read_u32
(
child
,
"linux,code"
,
&
map
[
i
].
keycode
))
{
dev_err
(
dev
,
"Key with invalid or missing linux,code
\n
"
);
fwnode_handle_put
(
child
);
return
-
EINVAL
;
}
i
++
;
}
st
->
map
=
map
;
return
0
;
}
static
int
adc_keys_probe
(
struct
platform_device
*
pdev
)
{
struct
device
*
dev
=
&
pdev
->
dev
;
struct
adc_keys_state
*
st
;
struct
input_polled_dev
*
poll_dev
;
struct
input_dev
*
input
;
enum
iio_chan_type
type
;
int
i
,
value
;
int
error
;
st
=
devm_kzalloc
(
dev
,
sizeof
(
*
st
),
GFP_KERNEL
);
if
(
!
st
)
return
-
ENOMEM
;
st
->
channel
=
devm_iio_channel_get
(
dev
,
"buttons"
);
if
(
IS_ERR
(
st
->
channel
))
return
PTR_ERR
(
st
->
channel
);
if
(
!
st
->
channel
->
indio_dev
)
return
-
ENXIO
;
error
=
iio_get_channel_type
(
st
->
channel
,
&
type
);
if
(
error
<
0
)
return
error
;
if
(
type
!=
IIO_VOLTAGE
)
{
dev_err
(
dev
,
"Incompatible channel type %d
\n
"
,
type
);
return
-
EINVAL
;
}
if
(
device_property_read_u32
(
dev
,
"keyup-threshold-microvolt"
,
&
st
->
keyup_voltage
))
{
dev_err
(
dev
,
"Invalid or missing keyup voltage
\n
"
);
return
-
EINVAL
;
}
st
->
keyup_voltage
/=
1000
;
error
=
adc_keys_load_keymap
(
dev
,
st
);
if
(
error
)
return
error
;
platform_set_drvdata
(
pdev
,
st
);
poll_dev
=
devm_input_allocate_polled_device
(
dev
);
if
(
!
poll_dev
)
{
dev_err
(
dev
,
"failed to allocate input device
\n
"
);
return
-
ENOMEM
;
}
if
(
!
device_property_read_u32
(
dev
,
"poll-interval"
,
&
value
))
poll_dev
->
poll_interval
=
value
;
poll_dev
->
poll
=
adc_keys_poll
;
poll_dev
->
private
=
st
;
input
=
poll_dev
->
input
;
input
->
name
=
pdev
->
name
;
input
->
phys
=
"adc-keys/input0"
;
input
->
id
.
bustype
=
BUS_HOST
;
input
->
id
.
vendor
=
0x0001
;
input
->
id
.
product
=
0x0001
;
input
->
id
.
version
=
0x0100
;
__set_bit
(
EV_KEY
,
input
->
evbit
);
for
(
i
=
0
;
i
<
st
->
num_keys
;
i
++
)
__set_bit
(
st
->
map
[
i
].
keycode
,
input
->
keybit
);
if
(
device_property_read_bool
(
dev
,
"autorepeat"
))
__set_bit
(
EV_REP
,
input
->
evbit
);
error
=
input_register_polled_device
(
poll_dev
);
if
(
error
)
{
dev_err
(
dev
,
"Unable to register input device: %d
\n
"
,
error
);
return
error
;
}
return
0
;
}
#ifdef CONFIG_OF
static
const
struct
of_device_id
adc_keys_of_match
[]
=
{
{
.
compatible
=
"adc-keys"
,
},
{
}
};
MODULE_DEVICE_TABLE
(
of
,
adc_keys_of_match
);
#endif
static
struct
platform_driver
__refdata
adc_keys_driver
=
{
.
driver
=
{
.
name
=
"adc_keys"
,
.
of_match_table
=
of_match_ptr
(
adc_keys_of_match
),
},
.
probe
=
adc_keys_probe
,
};
module_platform_driver
(
adc_keys_driver
);
MODULE_AUTHOR
(
"Alexandre Belloni <alexandre.belloni@free-electrons.com>"
);
MODULE_DESCRIPTION
(
"Input driver for resistor ladder connected on ADC"
);
MODULE_LICENSE
(
"GPL v2"
);
drivers/input/keyboard/jornada720_kbd.c
View file @
c758f96a
...
...
@@ -25,8 +25,6 @@
#include <linux/slab.h>
#include <mach/jornada720.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
MODULE_AUTHOR
(
"Kristoffer Ericson <Kristoffer.Ericson@gmail.com>"
);
MODULE_DESCRIPTION
(
"HP Jornada 710/720/728 keyboard driver"
);
...
...
@@ -66,10 +64,8 @@ static irqreturn_t jornada720_kbd_interrupt(int irq, void *dev_id)
jornada_ssp_start
();
if
(
jornada_ssp_inout
(
GETSCANKEYCODE
)
!=
TXDUMMY
)
{
printk
(
KERN_DEBUG
"jornada720_kbd: "
"GetKeycode command failed with ETIMEDOUT, "
"flushed bus
\n
"
);
dev_dbg
(
&
pdev
->
dev
,
"GetKeycode command failed with ETIMEDOUT, flushed bus
\n
"
);
}
else
{
/* How many keycodes are waiting for us? */
count
=
jornada_ssp_byte
(
TXDUMMY
);
...
...
@@ -97,14 +93,16 @@ static int jornada720_kbd_probe(struct platform_device *pdev)
{
struct
jornadakbd
*
jornadakbd
;
struct
input_dev
*
input_dev
;
int
i
,
err
;
int
i
,
err
,
irq
;
jornadakbd
=
kzalloc
(
sizeof
(
struct
jornadakbd
),
GFP_KERNEL
);
input_dev
=
input_allocate_device
();
if
(
!
jornadakbd
||
!
input_dev
)
{
err
=
-
ENOMEM
;
goto
fail1
;
}
irq
=
platform_get_irq
(
pdev
,
0
);
if
(
irq
<=
0
)
return
irq
<
0
?
irq
:
-
EINVAL
;
jornadakbd
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
jornadakbd
),
GFP_KERNEL
);
input_dev
=
devm_input_allocate_device
(
&
pdev
->
dev
);
if
(
!
jornadakbd
||
!
input_dev
)
return
-
ENOMEM
;
platform_set_drvdata
(
pdev
,
jornadakbd
);
...
...
@@ -127,40 +125,16 @@ static int jornada720_kbd_probe(struct platform_device *pdev)
input_set_capability
(
input_dev
,
EV_MSC
,
MSC_SCAN
);
err
=
request_irq
(
IRQ_GPIO0
,
jornada720_kbd_interrupt
,
IRQF_TRIGGER_FALLING
,
"jornadakbd"
,
pdev
);
err
=
devm_request_irq
(
&
pdev
->
dev
,
irq
,
jornada720_kbd_interrupt
,
IRQF_TRIGGER_FALLING
,
"jornadakbd"
,
pdev
);
if
(
err
)
{
printk
(
KERN_INFO
"jornadakbd720_kbd: Unable to grab IRQ
\n
"
);
goto
fail1
;
dev_err
(
&
pdev
->
dev
,
"unable to grab IRQ%d: %d
\n
"
,
irq
,
err
);
return
err
;
}
err
=
input_register_device
(
jornadakbd
->
input
);
if
(
err
)
goto
fail2
;
return
0
;
fail2:
/* IRQ, DEVICE, MEMORY */
free_irq
(
IRQ_GPIO0
,
pdev
);
fail1:
/* DEVICE, MEMORY */
input_free_device
(
input_dev
);
kfree
(
jornadakbd
);
return
err
;
return
input_register_device
(
jornadakbd
->
input
);
};
static
int
jornada720_kbd_remove
(
struct
platform_device
*
pdev
)
{
struct
jornadakbd
*
jornadakbd
=
platform_get_drvdata
(
pdev
);
free_irq
(
IRQ_GPIO0
,
pdev
);
input_unregister_device
(
jornadakbd
->
input
);
kfree
(
jornadakbd
);
return
0
;
}
/* work with hotplug and coldplug */
MODULE_ALIAS
(
"platform:jornada720_kbd"
);
...
...
@@ -169,6 +143,5 @@ static struct platform_driver jornada720_kbd_driver = {
.
name
=
"jornada720_kbd"
,
},
.
probe
=
jornada720_kbd_probe
,
.
remove
=
jornada720_kbd_remove
,
};
module_platform_driver
(
jornada720_kbd_driver
);
drivers/input/keyboard/snvs_pwrkey.c
View file @
c758f96a
...
...
@@ -168,7 +168,6 @@ static int imx_snvs_pwrkey_probe(struct platform_device *pdev)
error
=
input_register_device
(
input
);
if
(
error
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"failed to register input device
\n
"
);
input_free_device
(
input
);
return
error
;
}
...
...
drivers/input/misc/Kconfig
View file @
c758f96a
...
...
@@ -292,6 +292,18 @@ config INPUT_GPIO_TILT_POLLED
To compile this driver as a module, choose M here: the
module will be called gpio_tilt_polled.
config INPUT_GPIO_DECODER
tristate "Polled GPIO Decoder Input driver"
depends on GPIOLIB || COMPILE_TEST
select INPUT_POLLDEV
help
Say Y here if you want driver to read status of multiple GPIO
lines and report the encoded value as an absolute integer to
input subsystem.
To compile this driver as a module, choose M here: the module
will be called gpio_decoder.
config INPUT_IXP4XX_BEEPER
tristate "IXP4XX Beeper support"
depends on ARCH_IXP4XX
...
...
@@ -454,10 +466,10 @@ config INPUT_RETU_PWRBUTTON
config INPUT_TPS65218_PWRBUTTON
tristate "TPS65218 Power button driver"
depends on
MFD_TPS65218
depends on
(MFD_TPS65217 || MFD_TPS65218)
help
Say Y here if you want to enable power buttong reporting for
the TPS65218 Power Management IC device
.
TPS65217 and TPS65218 Power Management IC devices
.
To compile this driver as a module, choose M here. The module will
be called tps65218-pwrbutton.
...
...
drivers/input/misc/Makefile
View file @
c758f96a
...
...
@@ -35,6 +35,7 @@ obj-$(CONFIG_INPUT_DRV2667_HAPTICS) += drv2667.o
obj-$(CONFIG_INPUT_GP2A)
+=
gp2ap002a00f.o
obj-$(CONFIG_INPUT_GPIO_BEEPER)
+=
gpio-beeper.o
obj-$(CONFIG_INPUT_GPIO_TILT_POLLED)
+=
gpio_tilt_polled.o
obj-$(CONFIG_INPUT_GPIO_DECODER)
+=
gpio_decoder.o
obj-$(CONFIG_INPUT_HISI_POWERKEY)
+=
hisi_powerkey.o
obj-$(CONFIG_HP_SDC_RTC)
+=
hp_sdc_rtc.o
obj-$(CONFIG_INPUT_IMS_PCU)
+=
ims-pcu.o
...
...
drivers/input/misc/gpio_decoder.c
0 → 100644
View file @
c758f96a
/*
* Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* A generic driver to read multiple gpio lines and translate the
* encoded numeric value into an input event.
*/
#include <linux/device.h>
#include <linux/gpio/consumer.h>
#include <linux/input.h>
#include <linux/input-polldev.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
struct
gpio_decoder
{
struct
input_polled_dev
*
poll_dev
;
struct
gpio_descs
*
input_gpios
;
struct
device
*
dev
;
u32
axis
;
u32
last_stable
;
};
static
int
gpio_decoder_get_gpios_state
(
struct
gpio_decoder
*
decoder
)
{
struct
gpio_descs
*
gpios
=
decoder
->
input_gpios
;
unsigned
int
ret
=
0
;
int
i
,
val
;
for
(
i
=
0
;
i
<
gpios
->
ndescs
;
i
++
)
{
val
=
gpiod_get_value_cansleep
(
gpios
->
desc
[
i
]);
if
(
val
<
0
)
{
dev_err
(
decoder
->
dev
,
"Error reading gpio %d: %d
\n
"
,
desc_to_gpio
(
gpios
->
desc
[
i
]),
val
);
return
val
;
}
val
=
!!
val
;
ret
=
(
ret
<<
1
)
|
val
;
}
return
ret
;
}
static
void
gpio_decoder_poll_gpios
(
struct
input_polled_dev
*
poll_dev
)
{
struct
gpio_decoder
*
decoder
=
poll_dev
->
private
;
int
state
;
state
=
gpio_decoder_get_gpios_state
(
decoder
);
if
(
state
>=
0
&&
state
!=
decoder
->
last_stable
)
{
input_report_abs
(
poll_dev
->
input
,
decoder
->
axis
,
state
);
input_sync
(
poll_dev
->
input
);
decoder
->
last_stable
=
state
;
}
}
static
int
gpio_decoder_probe
(
struct
platform_device
*
pdev
)
{
struct
device
*
dev
=
&
pdev
->
dev
;
struct
gpio_decoder
*
decoder
;
struct
input_polled_dev
*
poll_dev
;
u32
max
;
int
err
;
decoder
=
devm_kzalloc
(
dev
,
sizeof
(
struct
gpio_decoder
),
GFP_KERNEL
);
if
(
!
decoder
)
return
-
ENOMEM
;
device_property_read_u32
(
dev
,
"linux,axis"
,
&
decoder
->
axis
);
decoder
->
input_gpios
=
devm_gpiod_get_array
(
dev
,
NULL
,
GPIOD_IN
);
if
(
IS_ERR
(
decoder
->
input_gpios
))
{
dev_err
(
dev
,
"unable to acquire input gpios
\n
"
);
return
PTR_ERR
(
decoder
->
input_gpios
);
}
if
(
decoder
->
input_gpios
->
ndescs
<
2
)
{
dev_err
(
dev
,
"not enough gpios found
\n
"
);
return
-
EINVAL
;
}
if
(
device_property_read_u32
(
dev
,
"decoder-max-value"
,
&
max
))
max
=
(
1U
<<
decoder
->
input_gpios
->
ndescs
)
-
1
;
decoder
->
dev
=
dev
;
poll_dev
=
devm_input_allocate_polled_device
(
decoder
->
dev
);
if
(
!
poll_dev
)
return
-
ENOMEM
;
poll_dev
->
private
=
decoder
;
poll_dev
->
poll
=
gpio_decoder_poll_gpios
;
decoder
->
poll_dev
=
poll_dev
;
poll_dev
->
input
->
name
=
pdev
->
name
;
poll_dev
->
input
->
id
.
bustype
=
BUS_HOST
;
input_set_abs_params
(
poll_dev
->
input
,
decoder
->
axis
,
0
,
max
,
0
,
0
);
err
=
input_register_polled_device
(
poll_dev
);
if
(
err
)
{
dev_err
(
dev
,
"failed to register polled device
\n
"
);
return
err
;
}
platform_set_drvdata
(
pdev
,
decoder
);
return
0
;
}
#ifdef CONFIG_OF
static
const
struct
of_device_id
gpio_decoder_of_match
[]
=
{
{
.
compatible
=
"gpio-decoder"
,
},
{
},
};
MODULE_DEVICE_TABLE
(
of
,
gpio_decoder_of_match
);
#endif
static
struct
platform_driver
gpio_decoder_driver
=
{
.
probe
=
gpio_decoder_probe
,
.
driver
=
{
.
name
=
"gpio-decoder"
,
.
of_match_table
=
of_match_ptr
(
gpio_decoder_of_match
),
}
};
module_platform_driver
(
gpio_decoder_driver
);
MODULE_DESCRIPTION
(
"GPIO decoder input driver"
);
MODULE_AUTHOR
(
"Vignesh R <vigneshr@ti.com>"
);
MODULE_LICENSE
(
"GPL v2"
);
drivers/input/misc/max77693-haptic.c
View file @
c758f96a
...
...
@@ -3,7 +3,7 @@
*
* Copyright (C) 2014,2015 Samsung Electronics
* Jaewon Kim <jaewon02.kim@samsung.com>
* Krzysztof Kozlowski <k
.kozlowski@samsung.com
>
* Krzysztof Kozlowski <k
rzk@kernel.org
>
*
* This program is not provided / owned by Maxim Integrated Products.
*
...
...
@@ -415,7 +415,7 @@ static struct platform_driver max77693_haptic_driver = {
module_platform_driver
(
max77693_haptic_driver
);
MODULE_AUTHOR
(
"Jaewon Kim <jaewon02.kim@samsung.com>"
);
MODULE_AUTHOR
(
"Krzysztof Kozlowski <k
.kozlowski@samsung.com
>"
);
MODULE_AUTHOR
(
"Krzysztof Kozlowski <k
rzk@kernel.org
>"
);
MODULE_DESCRIPTION
(
"MAXIM 77693/77843 Haptic driver"
);
MODULE_ALIAS
(
"platform:max77693-haptic"
);
MODULE_LICENSE
(
"GPL"
);
drivers/input/misc/tps65218-pwrbutton.c
View file @
c758f96a
/*
* Texas Instruments' TPS65218 Power Button Input Driver
* Texas Instruments' TPS6521
7 and TPS6521
8 Power Button Input Driver
*
* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
* Author: Felipe Balbi <balbi@ti.com>
* Author: Marcin Niestroj <m.niestroj@grinn-global.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
...
...
@@ -18,31 +19,61 @@
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mfd/tps65217.h>
#include <linux/mfd/tps65218.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>
struct
tps65218_pwrbutton
{
struct
tps6521x_data
{
unsigned
int
reg_status
;
unsigned
int
pb_mask
;
const
char
*
name
;
};
static
const
struct
tps6521x_data
tps65217_data
=
{
.
reg_status
=
TPS65217_REG_STATUS
,
.
pb_mask
=
TPS65217_STATUS_PB
,
.
name
=
"tps65217_pwrbutton"
,
};
static
const
struct
tps6521x_data
tps65218_data
=
{
.
reg_status
=
TPS65218_REG_STATUS
,
.
pb_mask
=
TPS65218_STATUS_PB_STATE
,
.
name
=
"tps65218_pwrbutton"
,
};
struct
tps6521x_pwrbutton
{
struct
device
*
dev
;
struct
tps65218
*
tps
;
struct
regmap
*
regmap
;
struct
input_dev
*
idev
;
const
struct
tps6521x_data
*
data
;
char
phys
[
32
];
};
static
const
struct
of_device_id
of_tps6521x_pb_match
[]
=
{
{
.
compatible
=
"ti,tps65217-pwrbutton"
,
.
data
=
&
tps65217_data
},
{
.
compatible
=
"ti,tps65218-pwrbutton"
,
.
data
=
&
tps65218_data
},
{
},
};
MODULE_DEVICE_TABLE
(
of
,
of_tps6521x_pb_match
);
static
irqreturn_t
tps6521
8_pwr
_irq
(
int
irq
,
void
*
_pwr
)
static
irqreturn_t
tps6521
x_pb
_irq
(
int
irq
,
void
*
_pwr
)
{
struct
tps65218_pwrbutton
*
pwr
=
_pwr
;
struct
tps6521x_pwrbutton
*
pwr
=
_pwr
;
const
struct
tps6521x_data
*
tps_data
=
pwr
->
data
;
unsigned
int
reg
;
int
error
;
error
=
tps65218_reg_read
(
pwr
->
tps
,
TPS65218_REG_STATUS
,
&
reg
);
error
=
regmap_read
(
pwr
->
regmap
,
tps_data
->
reg_status
,
&
reg
);
if
(
error
)
{
dev_err
(
pwr
->
dev
,
"can't read register: %d
\n
"
,
error
);
goto
out
;
}
if
(
reg
&
TPS65218_STATUS_PB_STATE
)
{
if
(
reg
&
tps_data
->
pb_mask
)
{
input_report_key
(
pwr
->
idev
,
KEY_POWER
,
1
);
pm_wakeup_event
(
pwr
->
dev
,
0
);
}
else
{
...
...
@@ -55,42 +86,55 @@ static irqreturn_t tps65218_pwr_irq(int irq, void *_pwr)
return
IRQ_HANDLED
;
}
static
int
tps6521
8_pwron
_probe
(
struct
platform_device
*
pdev
)
static
int
tps6521
x_pb
_probe
(
struct
platform_device
*
pdev
)
{
struct
tps65218
*
tps
=
dev_get_drvdata
(
pdev
->
dev
.
parent
);
struct
device
*
dev
=
&
pdev
->
dev
;
struct
tps6521
8
_pwrbutton
*
pwr
;
struct
tps6521
x
_pwrbutton
*
pwr
;
struct
input_dev
*
idev
;
const
struct
of_device_id
*
match
;
int
error
;
int
irq
;
match
=
of_match_node
(
of_tps6521x_pb_match
,
pdev
->
dev
.
of_node
);
if
(
!
match
)
return
-
ENXIO
;
pwr
=
devm_kzalloc
(
dev
,
sizeof
(
*
pwr
),
GFP_KERNEL
);
if
(
!
pwr
)
return
-
ENOMEM
;
pwr
->
data
=
match
->
data
;
idev
=
devm_input_allocate_device
(
dev
);
if
(
!
idev
)
return
-
ENOMEM
;
idev
->
name
=
"tps65218_pwrbutton"
;
idev
->
phys
=
"tps65218_pwrbutton/input0"
;
idev
->
name
=
pwr
->
data
->
name
;
snprintf
(
pwr
->
phys
,
sizeof
(
pwr
->
phys
),
"%s/input0"
,
pwr
->
data
->
name
);
idev
->
phys
=
pwr
->
phys
;
idev
->
dev
.
parent
=
dev
;
idev
->
id
.
bustype
=
BUS_I2C
;
input_set_capability
(
idev
,
EV_KEY
,
KEY_POWER
);
pwr
->
tps
=
tps
;
pwr
->
regmap
=
dev_get_regmap
(
pdev
->
dev
.
parent
,
NULL
)
;
pwr
->
dev
=
dev
;
pwr
->
idev
=
idev
;
platform_set_drvdata
(
pdev
,
pwr
);
device_init_wakeup
(
dev
,
true
);
irq
=
platform_get_irq
(
pdev
,
0
);
error
=
devm_request_threaded_irq
(
dev
,
irq
,
NULL
,
tps65218_pwr_irq
,
if
(
irq
<
0
)
{
dev_err
(
dev
,
"No IRQ resource!
\n
"
);
return
-
EINVAL
;
}
error
=
devm_request_threaded_irq
(
dev
,
irq
,
NULL
,
tps6521x_pb_irq
,
IRQF_TRIGGER_RISING
|
IRQF_TRIGGER_FALLING
|
IRQF_ONESHOT
,
"tps65218-pwrbutton"
,
pwr
);
pwr
->
data
->
name
,
pwr
);
if
(
error
)
{
dev_err
(
dev
,
"failed to request IRQ #%d: %d
\n
"
,
irq
,
error
);
...
...
@@ -106,21 +150,15 @@ static int tps65218_pwron_probe(struct platform_device *pdev)
return
0
;
}
static
const
struct
of_device_id
of_tps65218_pwr_match
[]
=
{
{
.
compatible
=
"ti,tps65218-pwrbutton"
},
{
},
};
MODULE_DEVICE_TABLE
(
of
,
of_tps65218_pwr_match
);
static
struct
platform_driver
tps65218_pwron_driver
=
{
.
probe
=
tps65218_pwron_probe
,
static
struct
platform_driver
tps6521x_pb_driver
=
{
.
probe
=
tps6521x_pb_probe
,
.
driver
=
{
.
name
=
"tps6521
8
_pwrbutton"
,
.
of_match_table
=
of_tps6521
8_pwr
_match
,
.
name
=
"tps6521
x
_pwrbutton"
,
.
of_match_table
=
of_tps6521
x_pb
_match
,
},
};
module_platform_driver
(
tps6521
8_pwron
_driver
);
module_platform_driver
(
tps6521
x_pb
_driver
);
MODULE_DESCRIPTION
(
"TPS6521
8
Power Button"
);
MODULE_DESCRIPTION
(
"TPS6521
X
Power Button"
);
MODULE_LICENSE
(
"GPL v2"
);
MODULE_AUTHOR
(
"Felipe Balbi <balbi@ti.com>"
);
drivers/input/mouse/elan_i2c_smbus.c
View file @
c758f96a
...
...
@@ -222,11 +222,13 @@ static int elan_smbus_get_checksum(struct i2c_client *client,
static
int
elan_smbus_get_max
(
struct
i2c_client
*
client
,
unsigned
int
*
max_x
,
unsigned
int
*
max_y
)
{
int
ret
;
int
error
;
u8
val
[
3
];
error
=
i2c_smbus_read_block_data
(
client
,
ETP_SMBUS_RANGE_CMD
,
val
);
if
(
error
)
{
ret
=
i2c_smbus_read_block_data
(
client
,
ETP_SMBUS_RANGE_CMD
,
val
);
if
(
ret
!=
3
)
{
error
=
ret
<
0
?
ret
:
-
EIO
;
dev_err
(
&
client
->
dev
,
"failed to get dimensions: %d
\n
"
,
error
);
return
error
;
}
...
...
@@ -240,12 +242,13 @@ static int elan_smbus_get_max(struct i2c_client *client,
static
int
elan_smbus_get_resolution
(
struct
i2c_client
*
client
,
u8
*
hw_res_x
,
u8
*
hw_res_y
)
{
int
ret
;
int
error
;
u8
val
[
3
];
error
=
i2c_smbus_read_block_data
(
client
,
ETP_SMBUS_RESOLUTION_CMD
,
val
);
if
(
error
)
{
ret
=
i2c_smbus_read_block_data
(
client
,
ETP_SMBUS_RESOLUTION_CMD
,
val
);
if
(
ret
!=
3
)
{
error
=
ret
<
0
?
ret
:
-
EIO
;
dev_err
(
&
client
->
dev
,
"failed to get resolution: %d
\n
"
,
error
);
return
error
;
}
...
...
@@ -260,12 +263,13 @@ static int elan_smbus_get_num_traces(struct i2c_client *client,
unsigned
int
*
x_traces
,
unsigned
int
*
y_traces
)
{
int
ret
;
int
error
;
u8
val
[
3
];
error
=
i2c_smbus_read_block_data
(
client
,
ETP_SMBUS_XY_TRACENUM_CMD
,
val
);
if
(
error
)
{
ret
=
i2c_smbus_read_block_data
(
client
,
ETP_SMBUS_XY_TRACENUM_CMD
,
val
);
if
(
ret
!=
3
)
{
error
=
ret
<
0
?
ret
:
-
EIO
;
dev_err
(
&
client
->
dev
,
"failed to get trace info: %d
\n
"
,
error
);
return
error
;
}
...
...
drivers/input/mouse/focaltech.c
View file @
c758f96a
...
...
@@ -390,7 +390,8 @@ static int focaltech_read_size(struct psmouse *psmouse)
return
0
;
}
void
focaltech_set_resolution
(
struct
psmouse
*
psmouse
,
unsigned
int
resolution
)
static
void
focaltech_set_resolution
(
struct
psmouse
*
psmouse
,
unsigned
int
resolution
)
{
/* not supported yet */
}
...
...
drivers/input/mouse/psmouse-base.c
View file @
c758f96a
...
...
@@ -1916,7 +1916,7 @@ static int __init psmouse_init(void)
synaptics_module_init
();
hgpk_module_init
();
kpsmoused_wq
=
create_singlethread_workqueue
(
"kpsmoused"
);
kpsmoused_wq
=
alloc_ordered_workqueue
(
"kpsmoused"
,
0
);
if
(
!
kpsmoused_wq
)
{
pr_err
(
"failed to create kpsmoused workqueue
\n
"
);
return
-
ENOMEM
;
...
...
drivers/input/serio/serport.c
View file @
c758f96a
...
...
@@ -71,10 +71,7 @@ static void serport_serio_close(struct serio *serio)
spin_lock_irqsave
(
&
serport
->
lock
,
flags
);
clear_bit
(
SERPORT_ACTIVE
,
&
serport
->
flags
);
set_bit
(
SERPORT_DEAD
,
&
serport
->
flags
);
spin_unlock_irqrestore
(
&
serport
->
lock
,
flags
);
wake_up_interruptible
(
&
serport
->
wait
);
}
/*
...
...
@@ -248,6 +245,19 @@ static long serport_ldisc_compat_ioctl(struct tty_struct *tty,
}
#endif
static
int
serport_ldisc_hangup
(
struct
tty_struct
*
tty
)
{
struct
serport
*
serport
=
(
struct
serport
*
)
tty
->
disc_data
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
serport
->
lock
,
flags
);
set_bit
(
SERPORT_DEAD
,
&
serport
->
flags
);
spin_unlock_irqrestore
(
&
serport
->
lock
,
flags
);
wake_up_interruptible
(
&
serport
->
wait
);
return
0
;
}
static
void
serport_ldisc_write_wakeup
(
struct
tty_struct
*
tty
)
{
struct
serport
*
serport
=
(
struct
serport
*
)
tty
->
disc_data
;
...
...
@@ -274,6 +284,7 @@ static struct tty_ldisc_ops serport_ldisc = {
.
compat_ioctl
=
serport_ldisc_compat_ioctl
,
#endif
.
receive_buf
=
serport_ldisc_receive
,
.
hangup
=
serport_ldisc_hangup
,
.
write_wakeup
=
serport_ldisc_write_wakeup
};
...
...
drivers/input/tablet/pegasus_notetaker.c
View file @
c758f96a
...
...
@@ -40,6 +40,7 @@
#include <linux/input.h>
#include <linux/usb/input.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
/* USB HID defines */
#define USB_REQ_GET_REPORT 0x01
...
...
drivers/input/touchscreen/Kconfig
View file @
c758f96a
...
...
@@ -305,19 +305,6 @@ config TOUCHSCREEN_EGALAX_SERIAL
To compile this driver as a module, choose M here: the
module will be called egalax_ts_serial.
config TOUCHSCREEN_FT6236
tristate "FT6236 I2C touchscreen"
depends on I2C
depends on GPIOLIB || COMPILE_TEST
help
Say Y here to enable support for the I2C connected FT6x06 and
FT6x36 family of capacitive touchscreen drivers.
If unsure, say N.
To compile this driver as a module, choose M here: the
module will be called ft6236.
config TOUCHSCREEN_FUJITSU
tristate "Fujitsu serial touchscreen"
select SERIO
...
...
@@ -397,6 +384,18 @@ config TOUCHSCREEN_GUNZE
To compile this driver as a module, choose M here: the
module will be called gunze.
config TOUCHSCREEN_EKTF2127
tristate "Elan eKTF2127 I2C touchscreen"
depends on I2C
help
Say Y here if you have an Elan eKTF2127 touchscreen
connected to your system.
If unsure, say N.
To compile this driver as a module, choose M here: the
module will be called ektf2127.
config TOUCHSCREEN_ELAN
tristate "Elan eKTH I2C touchscreen"
depends on I2C
...
...
drivers/input/touchscreen/Makefile
View file @
c758f96a
...
...
@@ -32,11 +32,11 @@ obj-$(CONFIG_TOUCHSCREEN_EDT_FT5X06) += edt-ft5x06.o
obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE)
+=
hampshire.o
obj-$(CONFIG_TOUCHSCREEN_GUNZE)
+=
gunze.o
obj-$(CONFIG_TOUCHSCREEN_EETI)
+=
eeti_ts.o
obj-$(CONFIG_TOUCHSCREEN_EKTF2127)
+=
ektf2127.o
obj-$(CONFIG_TOUCHSCREEN_ELAN)
+=
elants_i2c.o
obj-$(CONFIG_TOUCHSCREEN_ELO)
+=
elo.o
obj-$(CONFIG_TOUCHSCREEN_EGALAX)
+=
egalax_ts.o
obj-$(CONFIG_TOUCHSCREEN_EGALAX_SERIAL)
+=
egalax_ts_serial.o
obj-$(CONFIG_TOUCHSCREEN_FT6236)
+=
ft6236.o
obj-$(CONFIG_TOUCHSCREEN_FUJITSU)
+=
fujitsu_ts.o
obj-$(CONFIG_TOUCHSCREEN_GOODIX)
+=
goodix.o
obj-$(CONFIG_TOUCHSCREEN_ILI210X)
+=
ili210x.o
...
...
drivers/input/touchscreen/edt-ft5x06.c
View file @
c758f96a
...
...
@@ -1063,9 +1063,15 @@ static const struct edt_i2c_chip_data edt_ft5506_data = {
.
max_support_points
=
10
,
};
static
const
struct
edt_i2c_chip_data
edt_ft6236_data
=
{
.
max_support_points
=
2
,
};
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
},
/* Note no edt- prefix for compatibility with the ft6236.c driver */
{
.
name
=
"ft6236"
,
.
driver_data
=
(
long
)
&
edt_ft6236_data
},
{
/* sentinel */
}
};
MODULE_DEVICE_TABLE
(
i2c
,
edt_ft5x06_ts_id
);
...
...
@@ -1076,6 +1082,8 @@ 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
},
/* Note focaltech vendor prefix for compatibility with ft6236.c */
{
.
compatible
=
"focaltech,ft6236"
,
.
data
=
&
edt_ft6236_data
},
{
/* sentinel */
}
};
MODULE_DEVICE_TABLE
(
of
,
edt_ft5x06_of_match
);
...
...
drivers/input/touchscreen/ektf2127.c
0 → 100644
View file @
c758f96a
/*
* Driver for ELAN eKTF2127 i2c touchscreen controller
*
* For this driver the layout of the Chipone icn8318 i2c
* touchscreencontroller is used.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Author:
* Michel Verlaan <michel.verl@gmail.com>
* Siebren Vroegindeweij <siebren.vroegindeweij@hotmail.com>
*
* Original chipone_icn8318 driver:
* Hans de Goede <hdegoede@redhat.com>
*/
#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/input/touchscreen.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/delay.h>
/* Packet header defines (first byte of data send / received) */
#define EKTF2127_NOISE 0x40
#define EKTF2127_RESPONSE 0x52
#define EKTF2127_REQUEST 0x53
#define EKTF2127_HELLO 0x55
#define EKTF2127_REPORT 0x5d
#define EKTF2127_CALIB_DONE 0x66
/* Register defines (second byte of data send / received) */
#define EKTF2127_ENV_NOISY 0x41
#define EKTF2127_HEIGHT 0x60
#define EKTF2127_WIDTH 0x63
/* 2 bytes header + 5 * 3 bytes coordinates + 3 bytes pressure info + footer */
#define EKTF2127_TOUCH_REPORT_SIZE 21
#define EKTF2127_MAX_TOUCHES 5
struct
ektf2127_ts
{
struct
i2c_client
*
client
;
struct
input_dev
*
input
;
struct
gpio_desc
*
power_gpios
;
struct
touchscreen_properties
prop
;
};
static
void
ektf2127_parse_coordinates
(
const
u8
*
buf
,
unsigned
int
touch_count
,
struct
input_mt_pos
*
touches
)
{
int
index
=
0
;
int
i
;
for
(
i
=
0
;
i
<
touch_count
;
i
++
)
{
index
=
2
+
i
*
3
;
touches
[
i
].
x
=
(
buf
[
index
]
&
0x0f
);
touches
[
i
].
x
<<=
8
;
touches
[
i
].
x
|=
buf
[
index
+
2
];
touches
[
i
].
y
=
(
buf
[
index
]
&
0xf0
);
touches
[
i
].
y
<<=
4
;
touches
[
i
].
y
|=
buf
[
index
+
1
];
}
}
static
void
ektf2127_report_event
(
struct
ektf2127_ts
*
ts
,
const
u8
*
buf
)
{
struct
input_mt_pos
touches
[
EKTF2127_MAX_TOUCHES
];
int
slots
[
EKTF2127_MAX_TOUCHES
];
unsigned
int
touch_count
,
i
;
touch_count
=
buf
[
1
]
&
0x07
;
if
(
touch_count
>
EKTF2127_MAX_TOUCHES
)
{
dev_err
(
&
ts
->
client
->
dev
,
"Too many touches %d > %d
\n
"
,
touch_count
,
EKTF2127_MAX_TOUCHES
);
touch_count
=
EKTF2127_MAX_TOUCHES
;
}
ektf2127_parse_coordinates
(
buf
,
touch_count
,
touches
);
input_mt_assign_slots
(
ts
->
input
,
slots
,
touches
,
touch_count
,
0
);
for
(
i
=
0
;
i
<
touch_count
;
i
++
)
{
input_mt_slot
(
ts
->
input
,
slots
[
i
]);
input_mt_report_slot_state
(
ts
->
input
,
MT_TOOL_FINGER
,
true
);
touchscreen_report_pos
(
ts
->
input
,
&
ts
->
prop
,
touches
[
i
].
x
,
touches
[
i
].
y
,
true
);
}
input_mt_sync_frame
(
ts
->
input
);
input_sync
(
ts
->
input
);
}
static
irqreturn_t
ektf2127_irq
(
int
irq
,
void
*
dev_id
)
{
struct
ektf2127_ts
*
ts
=
dev_id
;
struct
device
*
dev
=
&
ts
->
client
->
dev
;
char
buf
[
EKTF2127_TOUCH_REPORT_SIZE
];
int
ret
;
ret
=
i2c_master_recv
(
ts
->
client
,
buf
,
EKTF2127_TOUCH_REPORT_SIZE
);
if
(
ret
!=
EKTF2127_TOUCH_REPORT_SIZE
)
{
dev_err
(
dev
,
"Error reading touch data: %d
\n
"
,
ret
);
goto
out
;
}
switch
(
buf
[
0
])
{
case
EKTF2127_REPORT
:
ektf2127_report_event
(
ts
,
buf
);
break
;
case
EKTF2127_NOISE
:
if
(
buf
[
1
]
==
EKTF2127_ENV_NOISY
)
dev_dbg
(
dev
,
"Environment is electrically noisy
\n
"
);
break
;
case
EKTF2127_HELLO
:
case
EKTF2127_CALIB_DONE
:
break
;
default:
dev_err
(
dev
,
"Unexpected packet header byte %#02x
\n
"
,
buf
[
0
]);
break
;
}
out:
return
IRQ_HANDLED
;
}
static
int
ektf2127_start
(
struct
input_dev
*
dev
)
{
struct
ektf2127_ts
*
ts
=
input_get_drvdata
(
dev
);
enable_irq
(
ts
->
client
->
irq
);
gpiod_set_value_cansleep
(
ts
->
power_gpios
,
1
);
return
0
;
}
static
void
ektf2127_stop
(
struct
input_dev
*
dev
)
{
struct
ektf2127_ts
*
ts
=
input_get_drvdata
(
dev
);
disable_irq
(
ts
->
client
->
irq
);
gpiod_set_value_cansleep
(
ts
->
power_gpios
,
0
);
}
static
int
__maybe_unused
ektf2127_suspend
(
struct
device
*
dev
)
{
struct
ektf2127_ts
*
ts
=
i2c_get_clientdata
(
to_i2c_client
(
dev
));
mutex_lock
(
&
ts
->
input
->
mutex
);
if
(
ts
->
input
->
users
)
ektf2127_stop
(
ts
->
input
);
mutex_unlock
(
&
ts
->
input
->
mutex
);
return
0
;
}
static
int
__maybe_unused
ektf2127_resume
(
struct
device
*
dev
)
{
struct
ektf2127_ts
*
ts
=
i2c_get_clientdata
(
to_i2c_client
(
dev
));
mutex_lock
(
&
ts
->
input
->
mutex
);
if
(
ts
->
input
->
users
)
ektf2127_start
(
ts
->
input
);
mutex_unlock
(
&
ts
->
input
->
mutex
);
return
0
;
}
static
SIMPLE_DEV_PM_OPS
(
ektf2127_pm_ops
,
ektf2127_suspend
,
ektf2127_resume
);
static
int
ektf2127_query_dimension
(
struct
i2c_client
*
client
,
bool
width
)
{
struct
device
*
dev
=
&
client
->
dev
;
const
char
*
what
=
width
?
"width"
:
"height"
;
u8
what_code
=
width
?
EKTF2127_WIDTH
:
EKTF2127_HEIGHT
;
u8
buf
[
4
];
int
ret
;
int
error
;
/* Request dimension */
buf
[
0
]
=
EKTF2127_REQUEST
;
buf
[
1
]
=
width
?
EKTF2127_WIDTH
:
EKTF2127_HEIGHT
;
buf
[
2
]
=
0x00
;
buf
[
3
]
=
0x00
;
ret
=
i2c_master_send
(
client
,
buf
,
sizeof
(
buf
));
if
(
ret
!=
sizeof
(
buf
))
{
error
=
ret
<
0
?
ret
:
-
EIO
;
dev_err
(
dev
,
"Failed to request %s: %d
\n
"
,
what
,
error
);
return
error
;
}
msleep
(
20
);
/* Read response */
ret
=
i2c_master_recv
(
client
,
buf
,
sizeof
(
buf
));
if
(
ret
!=
sizeof
(
buf
))
{
error
=
ret
<
0
?
ret
:
-
EIO
;
dev_err
(
dev
,
"Failed to receive %s data: %d
\n
"
,
what
,
error
);
return
error
;
}
if
(
buf
[
0
]
!=
EKTF2127_RESPONSE
||
buf
[
1
]
!=
what_code
)
{
dev_err
(
dev
,
"Unexpected %s data: %#02x %#02x
\n
"
,
what
,
buf
[
0
],
buf
[
1
]);
return
-
EIO
;
}
return
(((
buf
[
3
]
&
0xf0
)
<<
4
)
|
buf
[
2
])
-
1
;
}
static
int
ektf2127_probe
(
struct
i2c_client
*
client
,
const
struct
i2c_device_id
*
id
)
{
struct
device
*
dev
=
&
client
->
dev
;
struct
ektf2127_ts
*
ts
;
struct
input_dev
*
input
;
u8
buf
[
4
];
int
max_x
,
max_y
;
int
error
;
if
(
!
client
->
irq
)
{
dev_err
(
dev
,
"Error no irq specified
\n
"
);
return
-
EINVAL
;
}
ts
=
devm_kzalloc
(
dev
,
sizeof
(
*
ts
),
GFP_KERNEL
);
if
(
!
ts
)
return
-
ENOMEM
;
/* This requests the gpio *and* turns on the touchscreen controller */
ts
->
power_gpios
=
devm_gpiod_get
(
dev
,
"power"
,
GPIOD_OUT_HIGH
);
if
(
IS_ERR
(
ts
->
power_gpios
))
{
error
=
PTR_ERR
(
ts
->
power_gpios
);
if
(
error
!=
-
EPROBE_DEFER
)
dev_err
(
dev
,
"Error getting power gpio: %d
\n
"
,
error
);
return
error
;
}
input
=
devm_input_allocate_device
(
dev
);
if
(
!
input
)
return
-
ENOMEM
;
input
->
name
=
client
->
name
;
input
->
id
.
bustype
=
BUS_I2C
;
input
->
open
=
ektf2127_start
;
input
->
close
=
ektf2127_stop
;
ts
->
client
=
client
;
/* Read hello (ignore result, depends on initial power state) */
msleep
(
20
);
i2c_master_recv
(
ts
->
client
,
buf
,
sizeof
(
buf
));
/* Read resolution from chip */
max_x
=
ektf2127_query_dimension
(
client
,
true
);
if
(
max_x
<
0
)
return
max_x
;
max_y
=
ektf2127_query_dimension
(
client
,
false
);
if
(
max_y
<
0
)
return
max_y
;
input_set_abs_params
(
input
,
ABS_MT_POSITION_X
,
0
,
max_x
,
0
,
0
);
input_set_abs_params
(
input
,
ABS_MT_POSITION_Y
,
0
,
max_y
,
0
,
0
);
touchscreen_parse_properties
(
input
,
true
,
&
ts
->
prop
);
error
=
input_mt_init_slots
(
input
,
EKTF2127_MAX_TOUCHES
,
INPUT_MT_DIRECT
|
INPUT_MT_DROP_UNUSED
|
INPUT_MT_TRACK
);
if
(
error
)
return
error
;
ts
->
input
=
input
;
input_set_drvdata
(
input
,
ts
);
error
=
devm_request_threaded_irq
(
dev
,
client
->
irq
,
NULL
,
ektf2127_irq
,
IRQF_ONESHOT
,
client
->
name
,
ts
);
if
(
error
)
{
dev_err
(
dev
,
"Error requesting irq: %d
\n
"
,
error
);
return
error
;
}
/* Stop device till opened */
ektf2127_stop
(
ts
->
input
);
error
=
input_register_device
(
input
);
if
(
error
)
return
error
;
i2c_set_clientdata
(
client
,
ts
);
return
0
;
}
#ifdef CONFIG_OF
static
const
struct
of_device_id
ektf2127_of_match
[]
=
{
{
.
compatible
=
"elan,ektf2127"
},
{}
};
MODULE_DEVICE_TABLE
(
of
,
ektf2127_of_match
);
#endif
static
const
struct
i2c_device_id
ektf2127_i2c_id
[]
=
{
{
"ektf2127"
,
0
},
{}
};
MODULE_DEVICE_TABLE
(
i2c
,
ektf2127_i2c_id
);
static
struct
i2c_driver
ektf2127_driver
=
{
.
driver
=
{
.
name
=
"elan_ektf2127"
,
.
pm
=
&
ektf2127_pm_ops
,
.
of_match_table
=
of_match_ptr
(
ektf2127_of_match
),
},
.
probe
=
ektf2127_probe
,
.
id_table
=
ektf2127_i2c_id
,
};
module_i2c_driver
(
ektf2127_driver
);
MODULE_DESCRIPTION
(
"ELAN eKTF2127 I2C Touchscreen Driver"
);
MODULE_AUTHOR
(
"Michel Verlaan, Siebren Vroegindeweij"
);
MODULE_LICENSE
(
"GPL"
);
drivers/input/touchscreen/elants_i2c.c
View file @
c758f96a
...
...
@@ -298,7 +298,7 @@ static u16 elants_i2c_parse_version(u8 *buf)
return
get_unaligned_be32
(
buf
)
>>
4
;
}
static
int
elants_i2c_query_
fw_id
(
struct
elants_data
*
ts
)
static
int
elants_i2c_query_
hw_version
(
struct
elants_data
*
ts
)
{
struct
i2c_client
*
client
=
ts
->
client
;
int
error
,
retry_cnt
;
...
...
@@ -318,8 +318,13 @@ static int elants_i2c_query_fw_id(struct elants_data *ts)
error
,
(
int
)
sizeof
(
resp
),
resp
);
}
dev_err
(
&
client
->
dev
,
"Failed to read fw id or fw id is invalid
\n
"
);
if
(
error
)
{
dev_err
(
&
client
->
dev
,
"Failed to read fw id: %d
\n
"
,
error
);
return
error
;
}
dev_err
(
&
client
->
dev
,
"Invalid fw id: %#04x
\n
"
,
ts
->
hw_version
);
return
-
EINVAL
;
}
...
...
@@ -508,7 +513,7 @@ static int elants_i2c_fastboot(struct i2c_client *client)
static
int
elants_i2c_initialize
(
struct
elants_data
*
ts
)
{
struct
i2c_client
*
client
=
ts
->
client
;
int
error
,
retry_cnt
;
int
error
,
error2
,
retry_cnt
;
const
u8
hello_packet
[]
=
{
0x55
,
0x55
,
0x55
,
0x55
};
const
u8
recov_packet
[]
=
{
0x55
,
0x55
,
0x80
,
0x80
};
u8
buf
[
HEADER_SIZE
];
...
...
@@ -553,18 +558,22 @@ static int elants_i2c_initialize(struct elants_data *ts)
}
}
/* hw version is available even if device in recovery state */
error2
=
elants_i2c_query_hw_version
(
ts
);
if
(
!
error
)
error
=
elants_i2c_query_fw_id
(
ts
);
error
=
error2
;
if
(
!
error
)
error
=
elants_i2c_query_fw_version
(
ts
);
if
(
!
error
)
error
=
elants_i2c_query_test_version
(
ts
);
if
(
!
error
)
error
=
elants_i2c_query_bc_version
(
ts
);
if
(
!
error
)
error
=
elants_i2c_query_ts_info
(
ts
);
if
(
error
)
{
if
(
error
)
ts
->
iap_mode
=
ELAN_IAP_RECOVERY
;
}
else
{
elants_i2c_query_test_version
(
ts
);
elants_i2c_query_bc_version
(
ts
);
elants_i2c_query_ts_info
(
ts
);
}
return
0
;
}
...
...
drivers/input/touchscreen/ft6236.c
deleted
100644 → 0
View file @
9fb6de1b
/*
* FocalTech FT6236 TouchScreen driver.
*
* Copyright (c) 2010 Focal tech Ltd.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/property.h>
#define FT6236_MAX_TOUCH_POINTS 2
#define FT6236_REG_TH_GROUP 0x80
#define FT6236_REG_PERIODACTIVE 0x88
#define FT6236_REG_LIB_VER_H 0xa1
#define FT6236_REG_LIB_VER_L 0xa2
#define FT6236_REG_CIPHER 0xa3
#define FT6236_REG_FIRMID 0xa6
#define FT6236_REG_FOCALTECH_ID 0xa8
#define FT6236_REG_RELEASE_CODE_ID 0xaf
#define FT6236_EVENT_PRESS_DOWN 0
#define FT6236_EVENT_LIFT_UP 1
#define FT6236_EVENT_CONTACT 2
#define FT6236_EVENT_NO_EVENT 3
struct
ft6236_data
{
struct
i2c_client
*
client
;
struct
input_dev
*
input
;
struct
gpio_desc
*
reset_gpio
;
u32
max_x
;
u32
max_y
;
bool
invert_x
;
bool
invert_y
;
bool
swap_xy
;
};
/*
* This struct is a touchpoint as stored in hardware. Note that the id,
* as well as the event, are stored in the upper nybble of the hi byte.
*/
struct
ft6236_touchpoint
{
union
{
u8
xhi
;
u8
event
;
};
u8
xlo
;
union
{
u8
yhi
;
u8
id
;
};
u8
ylo
;
u8
weight
;
u8
misc
;
}
__packed
;
/* This packet represents the register map as read from offset 0 */
struct
ft6236_packet
{
u8
dev_mode
;
u8
gest_id
;
u8
touches
;
struct
ft6236_touchpoint
points
[
FT6236_MAX_TOUCH_POINTS
];
}
__packed
;
static
int
ft6236_read
(
struct
i2c_client
*
client
,
u8
reg
,
u8
len
,
void
*
data
)
{
int
error
;
error
=
i2c_smbus_read_i2c_block_data
(
client
,
reg
,
len
,
data
);
if
(
error
<
0
)
return
error
;
if
(
error
!=
len
)
return
-
EIO
;
return
0
;
}
static
irqreturn_t
ft6236_interrupt
(
int
irq
,
void
*
dev_id
)
{
struct
ft6236_data
*
ft6236
=
dev_id
;
struct
device
*
dev
=
&
ft6236
->
client
->
dev
;
struct
input_dev
*
input
=
ft6236
->
input
;
struct
ft6236_packet
buf
;
u8
touches
;
int
i
,
error
;
error
=
ft6236_read
(
ft6236
->
client
,
0
,
sizeof
(
buf
),
&
buf
);
if
(
error
)
{
dev_err
(
dev
,
"read touchdata failed %d
\n
"
,
error
);
return
IRQ_HANDLED
;
}
touches
=
buf
.
touches
&
0xf
;
if
(
touches
>
FT6236_MAX_TOUCH_POINTS
)
{
dev_dbg
(
dev
,
"%d touch points reported, only %d are supported
\n
"
,
touches
,
FT6236_MAX_TOUCH_POINTS
);
touches
=
FT6236_MAX_TOUCH_POINTS
;
}
for
(
i
=
0
;
i
<
touches
;
i
++
)
{
struct
ft6236_touchpoint
*
point
=
&
buf
.
points
[
i
];
u16
x
=
((
point
->
xhi
&
0xf
)
<<
8
)
|
buf
.
points
[
i
].
xlo
;
u16
y
=
((
point
->
yhi
&
0xf
)
<<
8
)
|
buf
.
points
[
i
].
ylo
;
u8
event
=
point
->
event
>>
6
;
u8
id
=
point
->
id
>>
4
;
bool
act
=
(
event
==
FT6236_EVENT_PRESS_DOWN
||
event
==
FT6236_EVENT_CONTACT
);
input_mt_slot
(
input
,
id
);
input_mt_report_slot_state
(
input
,
MT_TOOL_FINGER
,
act
);
if
(
!
act
)
continue
;
if
(
ft6236
->
invert_x
)
x
=
ft6236
->
max_x
-
x
;
if
(
ft6236
->
invert_y
)
y
=
ft6236
->
max_y
-
y
;
if
(
ft6236
->
swap_xy
)
{
input_report_abs
(
input
,
ABS_MT_POSITION_X
,
y
);
input_report_abs
(
input
,
ABS_MT_POSITION_Y
,
x
);
}
else
{
input_report_abs
(
input
,
ABS_MT_POSITION_X
,
x
);
input_report_abs
(
input
,
ABS_MT_POSITION_Y
,
y
);
}
}
input_mt_sync_frame
(
input
);
input_sync
(
input
);
return
IRQ_HANDLED
;
}
static
u8
ft6236_debug_read_byte
(
struct
ft6236_data
*
ft6236
,
u8
reg
)
{
struct
i2c_client
*
client
=
ft6236
->
client
;
u8
val
=
0
;
int
error
;
error
=
ft6236_read
(
client
,
reg
,
1
,
&
val
);
if
(
error
)
dev_dbg
(
&
client
->
dev
,
"error reading register 0x%02x: %d
\n
"
,
reg
,
error
);
return
val
;
}
static
void
ft6236_debug_info
(
struct
ft6236_data
*
ft6236
)
{
struct
device
*
dev
=
&
ft6236
->
client
->
dev
;
dev_dbg
(
dev
,
"Touch threshold is %d
\n
"
,
ft6236_debug_read_byte
(
ft6236
,
FT6236_REG_TH_GROUP
)
*
4
);
dev_dbg
(
dev
,
"Report rate is %dHz
\n
"
,
ft6236_debug_read_byte
(
ft6236
,
FT6236_REG_PERIODACTIVE
)
*
10
);
dev_dbg
(
dev
,
"Firmware library version 0x%02x%02x
\n
"
,
ft6236_debug_read_byte
(
ft6236
,
FT6236_REG_LIB_VER_H
),
ft6236_debug_read_byte
(
ft6236
,
FT6236_REG_LIB_VER_L
));
dev_dbg
(
dev
,
"Firmware version 0x%02x
\n
"
,
ft6236_debug_read_byte
(
ft6236
,
FT6236_REG_FIRMID
));
dev_dbg
(
dev
,
"Chip vendor ID 0x%02x
\n
"
,
ft6236_debug_read_byte
(
ft6236
,
FT6236_REG_CIPHER
));
dev_dbg
(
dev
,
"CTPM vendor ID 0x%02x
\n
"
,
ft6236_debug_read_byte
(
ft6236
,
FT6236_REG_FOCALTECH_ID
));
dev_dbg
(
dev
,
"Release code version 0x%02x
\n
"
,
ft6236_debug_read_byte
(
ft6236
,
FT6236_REG_RELEASE_CODE_ID
));
}
static
void
ft6236_reset
(
struct
ft6236_data
*
ft6236
)
{
if
(
!
ft6236
->
reset_gpio
)
return
;
gpiod_set_value_cansleep
(
ft6236
->
reset_gpio
,
1
);
usleep_range
(
5000
,
20000
);
gpiod_set_value_cansleep
(
ft6236
->
reset_gpio
,
0
);
msleep
(
300
);
}
static
int
ft6236_probe
(
struct
i2c_client
*
client
,
const
struct
i2c_device_id
*
id
)
{
struct
device
*
dev
=
&
client
->
dev
;
struct
ft6236_data
*
ft6236
;
struct
input_dev
*
input
;
u32
fuzz_x
=
0
,
fuzz_y
=
0
;
u8
val
;
int
error
;
if
(
!
i2c_check_functionality
(
client
->
adapter
,
I2C_FUNC_I2C
))
return
-
ENXIO
;
if
(
!
client
->
irq
)
{
dev_err
(
dev
,
"irq is missing
\n
"
);
return
-
EINVAL
;
}
ft6236
=
devm_kzalloc
(
dev
,
sizeof
(
*
ft6236
),
GFP_KERNEL
);
if
(
!
ft6236
)
return
-
ENOMEM
;
ft6236
->
client
=
client
;
ft6236
->
reset_gpio
=
devm_gpiod_get_optional
(
dev
,
"reset"
,
GPIOD_OUT_LOW
);
if
(
IS_ERR
(
ft6236
->
reset_gpio
))
{
error
=
PTR_ERR
(
ft6236
->
reset_gpio
);
if
(
error
!=
-
EPROBE_DEFER
)
dev_err
(
dev
,
"error getting reset gpio: %d
\n
"
,
error
);
return
error
;
}
ft6236_reset
(
ft6236
);
/* verify that the controller is present */
error
=
ft6236_read
(
client
,
0x00
,
1
,
&
val
);
if
(
error
)
{
dev_err
(
dev
,
"failed to read from controller: %d
\n
"
,
error
);
return
error
;
}
ft6236_debug_info
(
ft6236
);
input
=
devm_input_allocate_device
(
dev
);
if
(
!
input
)
return
-
ENOMEM
;
ft6236
->
input
=
input
;
input
->
name
=
client
->
name
;
input
->
id
.
bustype
=
BUS_I2C
;
if
(
device_property_read_u32
(
dev
,
"touchscreen-size-x"
,
&
ft6236
->
max_x
)
||
device_property_read_u32
(
dev
,
"touchscreen-size-y"
,
&
ft6236
->
max_y
))
{
dev_err
(
dev
,
"touchscreen-size-x and/or -y missing
\n
"
);
return
-
EINVAL
;
}
device_property_read_u32
(
dev
,
"touchscreen-fuzz-x"
,
&
fuzz_x
);
device_property_read_u32
(
dev
,
"touchscreen-fuzz-y"
,
&
fuzz_y
);
ft6236
->
invert_x
=
device_property_read_bool
(
dev
,
"touchscreen-inverted-x"
);
ft6236
->
invert_y
=
device_property_read_bool
(
dev
,
"touchscreen-inverted-y"
);
ft6236
->
swap_xy
=
device_property_read_bool
(
dev
,
"touchscreen-swapped-x-y"
);
if
(
ft6236
->
swap_xy
)
{
input_set_abs_params
(
input
,
ABS_MT_POSITION_X
,
0
,
ft6236
->
max_y
,
fuzz_y
,
0
);
input_set_abs_params
(
input
,
ABS_MT_POSITION_Y
,
0
,
ft6236
->
max_x
,
fuzz_x
,
0
);
}
else
{
input_set_abs_params
(
input
,
ABS_MT_POSITION_X
,
0
,
ft6236
->
max_x
,
fuzz_x
,
0
);
input_set_abs_params
(
input
,
ABS_MT_POSITION_Y
,
0
,
ft6236
->
max_y
,
fuzz_y
,
0
);
}
error
=
input_mt_init_slots
(
input
,
FT6236_MAX_TOUCH_POINTS
,
INPUT_MT_DIRECT
|
INPUT_MT_DROP_UNUSED
);
if
(
error
)
return
error
;
error
=
devm_request_threaded_irq
(
dev
,
client
->
irq
,
NULL
,
ft6236_interrupt
,
IRQF_ONESHOT
,
client
->
name
,
ft6236
);
if
(
error
)
{
dev_err
(
dev
,
"request irq %d failed: %d
\n
"
,
client
->
irq
,
error
);
return
error
;
}
error
=
input_register_device
(
input
);
if
(
error
)
{
dev_err
(
dev
,
"failed to register input device: %d
\n
"
,
error
);
return
error
;
}
return
0
;
}
#ifdef CONFIG_OF
static
const
struct
of_device_id
ft6236_of_match
[]
=
{
{
.
compatible
=
"focaltech,ft6236"
,
},
{
}
};
MODULE_DEVICE_TABLE
(
of
,
ft6236_of_match
);
#endif
static
const
struct
i2c_device_id
ft6236_id
[]
=
{
{
"ft6236"
,
},
{
}
};
MODULE_DEVICE_TABLE
(
i2c
,
ft6236_id
);
static
struct
i2c_driver
ft6236_driver
=
{
.
driver
=
{
.
name
=
"ft6236"
,
.
of_match_table
=
of_match_ptr
(
ft6236_of_match
),
},
.
probe
=
ft6236_probe
,
.
id_table
=
ft6236_id
,
};
module_i2c_driver
(
ft6236_driver
);
MODULE_AUTHOR
(
"Sean Cross <xobs@kosagi.com>"
);
MODULE_AUTHOR
(
"Noralf Trønnes <noralf@tronnes.org>"
);
MODULE_DESCRIPTION
(
"FocalTech FT6236 TouchScreen driver"
);
MODULE_LICENSE
(
"GPL v2"
);
drivers/input/touchscreen/jornada720_ts.c
View file @
c758f96a
...
...
@@ -13,6 +13,7 @@
* HP Jornada 710/720/729 Touchscreen Driver
*/
#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/interrupt.h>
...
...
@@ -20,9 +21,7 @@
#include <linux/slab.h>
#include <linux/io.h>
#include <mach/hardware.h>
#include <mach/jornada720.h>
#include <mach/irqs.h>
MODULE_AUTHOR
(
"Kristoffer Ericson <kristoffer.ericson@gmail.com>"
);
MODULE_DESCRIPTION
(
"HP Jornada 710/720/728 touchscreen driver"
);
...
...
@@ -30,6 +29,7 @@ MODULE_LICENSE("GPL v2");
struct
jornada_ts
{
struct
input_dev
*
dev
;
struct
gpio_desc
*
gpio
;
int
x_data
[
4
];
/* X sample values */
int
y_data
[
4
];
/* Y sample values */
};
...
...
@@ -71,8 +71,8 @@ static irqreturn_t jornada720_ts_interrupt(int irq, void *dev_id)
struct
input_dev
*
input
=
jornada_ts
->
dev
;
int
x
,
y
;
/* If
GPIO_GPIO9 is set to
high then report pen up */
if
(
GPLR
&
GPIO_GPIO
(
9
))
{
/* If
gpio is
high then report pen up */
if
(
gpiod_get_value
(
jornada_ts
->
gpio
))
{
input_report_key
(
input
,
BTN_TOUCH
,
0
);
input_sync
(
input
);
}
else
{
...
...
@@ -101,7 +101,7 @@ static int jornada720_ts_probe(struct platform_device *pdev)
{
struct
jornada_ts
*
jornada_ts
;
struct
input_dev
*
input_dev
;
int
error
;
int
error
,
irq
;
jornada_ts
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
jornada_ts
),
GFP_KERNEL
);
if
(
!
jornada_ts
)
...
...
@@ -113,6 +113,14 @@ static int jornada720_ts_probe(struct platform_device *pdev)
platform_set_drvdata
(
pdev
,
jornada_ts
);
jornada_ts
->
gpio
=
devm_gpiod_get
(
&
pdev
->
dev
,
"penup"
,
GPIOD_IN
);
if
(
IS_ERR
(
jornada_ts
->
gpio
))
return
PTR_ERR
(
jornada_ts
->
gpio
);
irq
=
gpiod_to_irq
(
jornada_ts
->
gpio
);
if
(
irq
<=
0
)
return
irq
<
0
?
irq
:
-
EINVAL
;
jornada_ts
->
dev
=
input_dev
;
input_dev
->
name
=
"HP Jornada 7xx Touchscreen"
;
...
...
@@ -125,8 +133,7 @@ static int jornada720_ts_probe(struct platform_device *pdev)
input_set_abs_params
(
input_dev
,
ABS_X
,
270
,
3900
,
0
,
0
);
input_set_abs_params
(
input_dev
,
ABS_Y
,
180
,
3700
,
0
,
0
);
error
=
devm_request_irq
(
&
pdev
->
dev
,
IRQ_GPIO9
,
jornada720_ts_interrupt
,
error
=
devm_request_irq
(
&
pdev
->
dev
,
irq
,
jornada720_ts_interrupt
,
IRQF_TRIGGER_RISING
,
"HP7XX Touchscreen driver"
,
pdev
);
if
(
error
)
{
...
...
drivers/input/touchscreen/mc13783_ts.c
View file @
c758f96a
...
...
@@ -37,7 +37,6 @@ struct mc13783_ts_priv {
struct
input_dev
*
idev
;
struct
mc13xxx
*
mc13xxx
;
struct
delayed_work
work
;
struct
workqueue_struct
*
workq
;
unsigned
int
sample
[
4
];
struct
mc13xxx_ts_platform_data
*
touch
;
};
...
...
@@ -54,7 +53,7 @@ static irqreturn_t mc13783_ts_handler(int irq, void *data)
* be rescheduled for immediate execution here. However the rearm
* delay is HZ / 50 which is acceptable.
*/
queue_delayed_work
(
priv
->
workq
,
&
priv
->
work
,
0
);
schedule_delayed_work
(
&
priv
->
work
,
0
);
return
IRQ_HANDLED
;
}
...
...
@@ -106,16 +105,18 @@ static void mc13783_ts_report_sample(struct mc13783_ts_priv *priv)
dev_dbg
(
&
idev
->
dev
,
"report (%d, %d, %d)
\n
"
,
x1
,
y1
,
0x1000
-
cr0
);
queue_delayed_work
(
priv
->
workq
,
&
priv
->
work
,
HZ
/
50
);
}
else
schedule_delayed_work
(
&
priv
->
work
,
HZ
/
50
);
}
else
{
dev_dbg
(
&
idev
->
dev
,
"report release
\n
"
);
}
input_report_abs
(
idev
,
ABS_PRESSURE
,
cr0
?
0x1000
-
cr0
:
cr0
);
input_report_key
(
idev
,
BTN_TOUCH
,
cr0
);
input_sync
(
idev
);
}
else
}
else
{
dev_dbg
(
&
idev
->
dev
,
"discard event
\n
"
);
}
}
static
void
mc13783_ts_work
(
struct
work_struct
*
work
)
...
...
@@ -189,14 +190,6 @@ static int __init mc13783_ts_probe(struct platform_device *pdev)
goto
err_free_mem
;
}
/*
* We need separate workqueue because mc13783_adc_do_conversion
* uses keventd and thus would deadlock.
*/
priv
->
workq
=
create_singlethread_workqueue
(
"mc13783_ts"
);
if
(
!
priv
->
workq
)
goto
err_free_mem
;
idev
->
name
=
MC13783_TS_NAME
;
idev
->
dev
.
parent
=
&
pdev
->
dev
;
...
...
@@ -215,14 +208,12 @@ static int __init mc13783_ts_probe(struct platform_device *pdev)
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"register input device failed with %d
\n
"
,
ret
);
goto
err_
destroy_wq
;
goto
err_
free_mem
;
}
platform_set_drvdata
(
pdev
,
priv
);
return
0
;
err_destroy_wq:
destroy_workqueue
(
priv
->
workq
);
err_free_mem:
input_free_device
(
idev
);
kfree
(
priv
);
...
...
@@ -233,7 +224,6 @@ static int mc13783_ts_remove(struct platform_device *pdev)
{
struct
mc13783_ts_priv
*
priv
=
platform_get_drvdata
(
pdev
);
destroy_workqueue
(
priv
->
workq
);
input_unregister_device
(
priv
->
idev
);
kfree
(
priv
);
...
...
drivers/input/touchscreen/pixcir_i2c_ts.c
View file @
c758f96a
...
...
@@ -11,10 +11,6 @@
* 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 library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/delay.h>
...
...
@@ -404,7 +400,6 @@ static int __maybe_unused pixcir_i2c_ts_resume(struct device *dev)
mutex_lock
(
&
input
->
mutex
);
if
(
device_may_wakeup
(
&
client
->
dev
))
{
if
(
!
input
->
users
)
{
ret
=
pixcir_stop
(
ts
);
if
(
ret
)
{
...
...
@@ -431,13 +426,7 @@ static const struct of_device_id pixcir_of_match[];
static
int
pixcir_parse_dt
(
struct
device
*
dev
,
struct
pixcir_i2c_ts_data
*
tsdata
)
{
const
struct
of_device_id
*
match
;
match
=
of_match_device
(
of_match_ptr
(
pixcir_of_match
),
dev
);
if
(
!
match
)
return
-
EINVAL
;
tsdata
->
chip
=
(
const
struct
pixcir_i2c_chip_data
*
)
match
->
data
;
tsdata
->
chip
=
of_device_get_match_data
(
dev
);
if
(
!
tsdata
->
chip
)
return
-
EINVAL
;
...
...
drivers/input/touchscreen/wdt87xx_i2c.c
View file @
c758f96a
...
...
@@ -23,7 +23,7 @@
#include <asm/unaligned.h>
#define WDT87XX_NAME "wdt87xx_i2c"
#define WDT87XX_DRV_VER "0.9.
7
"
#define WDT87XX_DRV_VER "0.9.
8
"
#define WDT87XX_FW_NAME "wdt87xx_fw.bin"
#define WDT87XX_CFG_NAME "wdt87xx_cfg.bin"
...
...
@@ -157,6 +157,7 @@
/* Controller requires minimum 300us between commands */
#define WDT_COMMAND_DELAY_MS 2
#define WDT_FLASH_WRITE_DELAY_MS 4
#define WDT_FLASH_ERASE_DELAY_MS 200
#define WDT_FW_RESET_TIME 2500
struct
wdt87xx_sys_param
{
...
...
@@ -726,7 +727,7 @@ static int wdt87xx_write_firmware(struct i2c_client *client, const void *chunk)
break
;
}
msleep
(
50
);
msleep
(
WDT_FLASH_ERASE_DELAY_MS
);
error
=
wdt87xx_write_data
(
client
,
data
,
start_addr
,
page_size
);
...
...
drivers/input/touchscreen/wm97xx-core.c
View file @
c758f96a
...
...
@@ -500,7 +500,7 @@ static int wm97xx_ts_input_open(struct input_dev *idev)
{
struct
wm97xx
*
wm
=
input_get_drvdata
(
idev
);
wm
->
ts_workq
=
create_singlethread_workqueue
(
"kwm97xx"
);
wm
->
ts_workq
=
alloc_ordered_workqueue
(
"kwm97xx"
,
0
);
if
(
wm
->
ts_workq
==
NULL
)
{
dev_err
(
wm
->
dev
,
"Failed to create workqueue
\n
"
);
...
...
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