aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-driver-input-axp-pek11
-rw-r--r--Documentation/devicetree/bindings/input/e3x0-button.txt25
-rw-r--r--Documentation/devicetree/bindings/input/regulator-haptic.txt21
-rw-r--r--Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt62
-rw-r--r--Documentation/devicetree/bindings/input/touchscreen/sun4i.txt4
-rw-r--r--Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt15
-rw-r--r--Documentation/devicetree/bindings/input/tps65218-pwrbutton.txt17
-rw-r--r--Documentation/devicetree/bindings/serio/allwinner,sun4i-ps2.txt23
-rw-r--r--Documentation/devicetree/bindings/vendor-prefixes.txt1
-rw-r--r--MAINTAINERS15
-rw-r--r--arch/arm/boot/dts/am335x-evm.dts1
-rw-r--r--drivers/iio/adc/ti_am335x_adc.c5
-rw-r--r--drivers/input/evdev.c71
-rw-r--r--drivers/input/input-mt.c31
-rw-r--r--drivers/input/input.c38
-rw-r--r--drivers/input/keyboard/Kconfig10
-rw-r--r--drivers/input/keyboard/Makefile1
-rw-r--r--drivers/input/keyboard/atakbd.c2
-rw-r--r--drivers/input/keyboard/cap11xx.c1
-rw-r--r--drivers/input/keyboard/imx_keypad.c3
-rw-r--r--drivers/input/keyboard/pxa27x_keypad.c5
-rw-r--r--drivers/input/keyboard/sun4i-lradc-keys.c286
-rw-r--r--drivers/input/misc/Kconfig43
-rw-r--r--drivers/input/misc/Makefile4
-rw-r--r--drivers/input/misc/axp20x-pek.c290
-rw-r--r--drivers/input/misc/drv260x.c1
-rw-r--r--drivers/input/misc/drv2667.c1
-rw-r--r--drivers/input/misc/e3x0-button.c157
-rw-r--r--drivers/input/misc/regulator-haptic.c266
-rw-r--r--drivers/input/misc/tps65218-pwrbutton.c126
-rw-r--r--drivers/input/mouse/Kconfig22
-rw-r--r--drivers/input/mouse/Makefile3
-rw-r--r--drivers/input/mouse/alps.c42
-rw-r--r--drivers/input/mouse/bcm5974.c2
-rw-r--r--drivers/input/mouse/cyapa.c1710
-rw-r--r--drivers/input/mouse/cyapa.h301
-rw-r--r--drivers/input/mouse/cyapa_gen3.c1247
-rw-r--r--drivers/input/mouse/cyapa_gen5.c2777
-rw-r--r--drivers/input/mouse/cypress_ps2.c2
-rw-r--r--drivers/input/mouse/elan_i2c.h6
-rw-r--r--drivers/input/mouse/elan_i2c_core.c21
-rw-r--r--drivers/input/mouse/elan_i2c_i2c.c1
-rw-r--r--drivers/input/mouse/elan_i2c_smbus.c3
-rw-r--r--drivers/input/mouse/focaltech.c408
-rw-r--r--drivers/input/mouse/focaltech.h2
-rw-r--r--drivers/input/mouse/psmouse-base.c32
-rw-r--r--drivers/input/mouse/psmouse.h1
-rw-r--r--drivers/input/mouse/synaptics.c438
-rw-r--r--drivers/input/mouse/synaptics.h18
-rw-r--r--drivers/input/serio/Kconfig10
-rw-r--r--drivers/input/serio/Makefile1
-rw-r--r--drivers/input/serio/gscps2.c2
-rw-r--r--drivers/input/serio/sun4i-ps2.c340
-rw-r--r--drivers/input/tablet/gtco.c20
-rw-r--r--drivers/input/touchscreen/elants_i2c.c2
-rw-r--r--drivers/input/touchscreen/pixcir_i2c_ts.c2
-rw-r--r--drivers/input/touchscreen/sun4i-ts.c78
-rw-r--r--drivers/input/touchscreen/ti_am335x_tsc.c197
-rw-r--r--include/linux/input/mt.h3
-rw-r--r--include/linux/mfd/ti_am335x_tscadc.h3
-rw-r--r--include/linux/platform_data/regulator-haptic.h29
61 files changed, 7957 insertions, 1302 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-input-axp-pek b/Documentation/ABI/testing/sysfs-driver-input-axp-pek
new file mode 100644
index 000000000000..a5e671b9fa79
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-input-axp-pek
@@ -0,0 +1,11 @@
1What: /sys/class/input/input(x)/device/startup
2Date: March 2014
3Contact: Carlo Caione <carlo@caione.org>
4Description: Startup time in us. Board is powered on if the button is pressed
5 for more than <startup_time>
6
7What: /sys/class/input/input(x)/device/shutdown
8Date: March 2014
9Contact: Carlo Caione <carlo@caione.org>
10Description: Shutdown time in us. Board is powered off if the button is pressed
11 for more than <shutdown_time>
diff --git a/Documentation/devicetree/bindings/input/e3x0-button.txt b/Documentation/devicetree/bindings/input/e3x0-button.txt
new file mode 100644
index 000000000000..751665e8e47a
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/e3x0-button.txt
@@ -0,0 +1,25 @@
1National Instruments Ettus Research USRP E3x0 button driver
2
3This module is part of the NI Ettus Research USRP E3x0 SDR.
4
5This module provides a simple power button event via two interrupts.
6
7Required properties:
8- compatible: should be one of the following
9 - "ettus,e3x0-button": For devices such as the NI Ettus Research USRP E3x0
10- interrupt-parent:
11 - a phandle to the interrupt controller that it is attached to.
12- interrupts: should be one of the following
13 - <0 30 1>, <0 31 1>: For devices such as the NI Ettus Research USRP E3x0
14- interrupt-names: should be one of the following
15 - "press", "release": For devices such as the NI Ettus Research USRP E3x0
16
17Note: Interrupt numbers might vary depending on the FPGA configuration.
18
19Example:
20 button {
21 compatible = "ettus,e3x0-button";
22 interrupt-parent = <&intc>;
23 interrupts = <0 30 1>, <0 31 1>;
24 interrupt-names = "press", "release";
25 }
diff --git a/Documentation/devicetree/bindings/input/regulator-haptic.txt b/Documentation/devicetree/bindings/input/regulator-haptic.txt
new file mode 100644
index 000000000000..3ed1c7eb2f97
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/regulator-haptic.txt
@@ -0,0 +1,21 @@
1* Regulator Haptic Device Tree Bindings
2
3Required Properties:
4 - compatible : Should be "regulator-haptic"
5 - haptic-supply : Power supply to the haptic motor.
6 [*] refer Documentation/devicetree/bindings/regulator/regulator.txt
7
8 - max-microvolt : The maximum voltage value supplied to the haptic motor.
9 [The unit of the voltage is a micro]
10
11 - min-microvolt : The minimum voltage value supplied to the haptic motor.
12 [The unit of the voltage is a micro]
13
14Example:
15
16 haptics {
17 compatible = "regulator-haptic";
18 haptic-supply = <&motor_regulator>;
19 max-microvolt = <2700000>;
20 min-microvolt = <1100000>;
21 };
diff --git a/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt b/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
new file mode 100644
index 000000000000..b9c32f6fd687
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
@@ -0,0 +1,62 @@
1Allwinner sun4i low res adc attached tablet keys
2------------------------------------------------
3
4Required properties:
5 - compatible: "allwinner,sun4i-a10-lradc-keys"
6 - reg: mmio address range of the chip
7 - interrupts: interrupt to which the chip is connected
8 - vref-supply: powersupply for the lradc reference voltage
9
10Each key is represented as a sub-node of "allwinner,sun4i-a10-lradc-keys":
11
12Required subnode-properties:
13 - label: Descriptive name of the key.
14 - linux,code: Keycode to emit.
15 - channel: Channel this key is attached to, mut be 0 or 1.
16 - voltage: Voltage in µV at lradc input when this key is pressed.
17
18Example:
19
20#include <dt-bindings/input/input.h>
21
22 lradc: lradc@01c22800 {
23 compatible = "allwinner,sun4i-a10-lradc-keys";
24 reg = <0x01c22800 0x100>;
25 interrupts = <31>;
26 vref-supply = <&reg_vcc3v0>;
27
28 button@191 {
29 label = "Volume Up";
30 linux,code = <KEY_VOLUMEUP>;
31 channel = <0>;
32 voltage = <191274>;
33 };
34
35 button@392 {
36 label = "Volume Down";
37 linux,code = <KEY_VOLUMEDOWN>;
38 channel = <0>;
39 voltage = <392644>;
40 };
41
42 button@601 {
43 label = "Menu";
44 linux,code = <KEY_MENU>;
45 channel = <0>;
46 voltage = <601151>;
47 };
48
49 button@795 {
50 label = "Enter";
51 linux,code = <KEY_ENTER>;
52 channel = <0>;
53 voltage = <795090>;
54 };
55
56 button@987 {
57 label = "Home";
58 linux,code = <KEY_HOMEPAGE>;
59 channel = <0>;
60 voltage = <987387>;
61 };
62 };
diff --git a/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt b/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt
index aef57791f40b..433332d3b2ba 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt
@@ -2,9 +2,10 @@ sun4i resistive touchscreen controller
2-------------------------------------- 2--------------------------------------
3 3
4Required properties: 4Required properties:
5 - compatible: "allwinner,sun4i-a10-ts" 5 - compatible: "allwinner,sun4i-a10-ts" or "allwinner,sun6i-a31-ts"
6 - reg: mmio address range of the chip 6 - reg: mmio address range of the chip
7 - interrupts: interrupt to which the chip is connected 7 - interrupts: interrupt to which the chip is connected
8 - #thermal-sensor-cells: shall be 0
8 9
9Optional properties: 10Optional properties:
10 - allwinner,ts-attached: boolean indicating that an actual touchscreen is 11 - allwinner,ts-attached: boolean indicating that an actual touchscreen is
@@ -17,4 +18,5 @@ Example:
17 reg = <0x01c25000 0x100>; 18 reg = <0x01c25000 0x100>;
18 interrupts = <29>; 19 interrupts = <29>;
19 allwinner,ts-attached; 20 allwinner,ts-attached;
21 #thermal-sensor-cells = <0>;
20 }; 22 };
diff --git a/Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt b/Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt
index 878549ba814d..6c4fb34823d3 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt
@@ -28,6 +28,20 @@ Required properties:
28 ti,adc-channels: List of analog inputs available for ADC. 28 ti,adc-channels: List of analog inputs available for ADC.
29 AIN0 = 0, AIN1 = 1 and so on till AIN7 = 7. 29 AIN0 = 0, AIN1 = 1 and so on till AIN7 = 7.
30 30
31Optional properties:
32- child "tsc"
33 ti,charge-delay: Length of touch screen charge delay step in terms of
34 ADC clock cycles. Charge delay value should be large
35 in order to avoid false pen-up events. This value
36 effects the overall sampling speed, hence need to be
37 kept as low as possible, while avoiding false pen-up
38 event. Start from a lower value, say 0x400, and
39 increase value until false pen-up events are avoided.
40 The pen-up detection happens immediately after the
41 charge step, so this does in fact function as a
42 hardware knob for adjusting the amount of "settling
43 time".
44
31Example: 45Example:
32 tscadc: tscadc@44e0d000 { 46 tscadc: tscadc@44e0d000 {
33 compatible = "ti,am3359-tscadc"; 47 compatible = "ti,am3359-tscadc";
@@ -36,6 +50,7 @@ Example:
36 ti,x-plate-resistance = <200>; 50 ti,x-plate-resistance = <200>;
37 ti,coordiante-readouts = <5>; 51 ti,coordiante-readouts = <5>;
38 ti,wire-config = <0x00 0x11 0x22 0x33>; 52 ti,wire-config = <0x00 0x11 0x22 0x33>;
53 ti,charge-delay = <0x400>;
39 }; 54 };
40 55
41 adc { 56 adc {
diff --git a/Documentation/devicetree/bindings/input/tps65218-pwrbutton.txt b/Documentation/devicetree/bindings/input/tps65218-pwrbutton.txt
new file mode 100644
index 000000000000..e30e0b93f2b3
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/tps65218-pwrbutton.txt
@@ -0,0 +1,17 @@
1Texas Instruments TPS65218 power button
2
3This driver provides a simple power button event via an Interrupt.
4
5Required properties:
6- compatible: should be "ti,tps65218-pwrbutton"
7- interrupts: should be one of the following
8 - <3 IRQ_TYPE_EDGE_BOTH>: For controllers compatible with tps65218
9
10Example:
11
12&tps {
13 power-button {
14 compatible = "ti,tps65218-pwrbutton";
15 interrupts = <3 IRQ_TYPE_EDGE_BOTH>;
16 };
17};
diff --git a/Documentation/devicetree/bindings/serio/allwinner,sun4i-ps2.txt b/Documentation/devicetree/bindings/serio/allwinner,sun4i-ps2.txt
new file mode 100644
index 000000000000..362a76925bcd
--- /dev/null
+++ b/Documentation/devicetree/bindings/serio/allwinner,sun4i-ps2.txt
@@ -0,0 +1,23 @@
1* Device tree bindings for Allwinner A10, A20 PS2 host controller
2
3A20 PS2 is dual role controller (PS2 host and PS2 device). These bindings are
4for PS2 A10/A20 host controller. IBM compliant IBM PS2 and AT-compatible keyboard
5and mouse can be connected.
6
7Required properties:
8
9 - reg : Offset and length of the register set for the device.
10 - compatible : Should be as of the following:
11 - "allwinner,sun4i-a10-ps2"
12 - interrupts : The interrupt line connected to the PS2.
13 - clocks : The gate clk connected to the PS2.
14
15
16Example:
17 ps20: ps2@0x01c2a000 {
18 compatible = "allwinner,sun4i-a10-ps2";
19 reg = <0x01c2a000 0x400>;
20 interrupts = <0 62 4>;
21 clocks = <&apb1_gates 6>;
22 status = "disabled";
23 };
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index d443279c95dc..96a17541391e 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -54,6 +54,7 @@ epcos EPCOS AG
54epfl Ecole Polytechnique Fédérale de Lausanne 54epfl Ecole Polytechnique Fédérale de Lausanne
55epson Seiko Epson Corp. 55epson Seiko Epson Corp.
56est ESTeem Wireless Modems 56est ESTeem Wireless Modems
57ettus NI Ettus Research
57eukrea Eukréa Electromatique 58eukrea Eukréa Electromatique
58everest Everest Semiconductor Co. Ltd. 59everest Everest Semiconductor Co. Ltd.
59excito Excito 60excito Excito
diff --git a/MAINTAINERS b/MAINTAINERS
index 249498844a43..9c632548d3bd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3479,6 +3479,14 @@ M: "Maciej W. Rozycki" <macro@linux-mips.org>
3479S: Maintained 3479S: Maintained
3480F: drivers/tty/serial/dz.* 3480F: drivers/tty/serial/dz.*
3481 3481
3482E3X0 POWER BUTTON DRIVER
3483M: Moritz Fischer <moritz.fischer@ettus.com>
3484L: usrp-users@lists.ettus.com
3485W: http://www.ettus.com
3486S: Supported
3487F: drivers/input/misc/e3x0-button.c
3488F: Documentation/devicetree/bindings/input/e3x0-button.txt
3489
3482E4000 MEDIA DRIVER 3490E4000 MEDIA DRIVER
3483M: Antti Palosaari <crope@iki.fi> 3491M: Antti Palosaari <crope@iki.fi>
3484L: linux-media@vger.kernel.org 3492L: linux-media@vger.kernel.org
@@ -9281,6 +9289,13 @@ F: arch/m68k/sun3*/
9281F: arch/m68k/include/asm/sun3* 9289F: arch/m68k/include/asm/sun3*
9282F: drivers/net/ethernet/i825xx/sun3* 9290F: drivers/net/ethernet/i825xx/sun3*
9283 9291
9292SUN4I LOW RES ADC ATTACHED TABLET KEYS DRIVER
9293M: Hans de Goede <hdegoede@redhat.com>
9294L: linux-input@vger.kernel.org
9295S: Maintained
9296F: Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
9297F: drivers/input/keyboard/sun4i-lradc-keys.c
9298
9284SUNDANCE NETWORK DRIVER 9299SUNDANCE NETWORK DRIVER
9285M: Denis Kirjanov <kda@linux-powerpc.org> 9300M: Denis Kirjanov <kda@linux-powerpc.org>
9286L: netdev@vger.kernel.org 9301L: netdev@vger.kernel.org
diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
index 54f118c08db8..66342515df20 100644
--- a/arch/arm/boot/dts/am335x-evm.dts
+++ b/arch/arm/boot/dts/am335x-evm.dts
@@ -648,6 +648,7 @@
648 ti,x-plate-resistance = <200>; 648 ti,x-plate-resistance = <200>;
649 ti,coordinate-readouts = <5>; 649 ti,coordinate-readouts = <5>;
650 ti,wire-config = <0x00 0x11 0x22 0x33>; 650 ti,wire-config = <0x00 0x11 0x22 0x33>;
651 ti,charge-delay = <0x400>;
651 }; 652 };
652 653
653 adc { 654 adc {
diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
index b730864731e8..adba23246474 100644
--- a/drivers/iio/adc/ti_am335x_adc.c
+++ b/drivers/iio/adc/ti_am335x_adc.c
@@ -86,19 +86,18 @@ static void tiadc_step_config(struct iio_dev *indio_dev)
86{ 86{
87 struct tiadc_device *adc_dev = iio_priv(indio_dev); 87 struct tiadc_device *adc_dev = iio_priv(indio_dev);
88 unsigned int stepconfig; 88 unsigned int stepconfig;
89 int i, steps; 89 int i, steps = 0;
90 90
91 /* 91 /*
92 * There are 16 configurable steps and 8 analog input 92 * There are 16 configurable steps and 8 analog input
93 * lines available which are shared between Touchscreen and ADC. 93 * lines available which are shared between Touchscreen and ADC.
94 * 94 *
95 * Steps backwards i.e. from 16 towards 0 are used by ADC 95 * Steps forwards i.e. from 0 towards 16 are used by ADC
96 * depending on number of input lines needed. 96 * depending on number of input lines needed.
97 * Channel would represent which analog input 97 * Channel would represent which analog input
98 * needs to be given to ADC to digitalize data. 98 * needs to be given to ADC to digitalize data.
99 */ 99 */
100 100
101 steps = TOTAL_STEPS - adc_dev->channels;
102 if (iio_buffer_enabled(indio_dev)) 101 if (iio_buffer_enabled(indio_dev))
103 stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1 102 stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1
104 | STEPCONFIG_MODE_SWCNT; 103 | STEPCONFIG_MODE_SWCNT;
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 18d4b2c8fe55..a18f41b89b6a 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -62,26 +62,6 @@ struct evdev_client {
62 struct input_event buffer[]; 62 struct input_event buffer[];
63}; 63};
64 64
65static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid)
66{
67 switch (clkid) {
68
69 case CLOCK_REALTIME:
70 client->clk_type = EV_CLK_REAL;
71 break;
72 case CLOCK_MONOTONIC:
73 client->clk_type = EV_CLK_MONO;
74 break;
75 case CLOCK_BOOTTIME:
76 client->clk_type = EV_CLK_BOOT;
77 break;
78 default:
79 return -EINVAL;
80 }
81
82 return 0;
83}
84
85/* flush queued events of type @type, caller must hold client->buffer_lock */ 65/* flush queued events of type @type, caller must hold client->buffer_lock */
86static void __evdev_flush_queue(struct evdev_client *client, unsigned int type) 66static void __evdev_flush_queue(struct evdev_client *client, unsigned int type)
87{ 67{
@@ -128,10 +108,8 @@ static void __evdev_flush_queue(struct evdev_client *client, unsigned int type)
128 client->head = head; 108 client->head = head;
129} 109}
130 110
131/* queue SYN_DROPPED event */ 111static void __evdev_queue_syn_dropped(struct evdev_client *client)
132static void evdev_queue_syn_dropped(struct evdev_client *client)
133{ 112{
134 unsigned long flags;
135 struct input_event ev; 113 struct input_event ev;
136 ktime_t time; 114 ktime_t time;
137 115
@@ -146,8 +124,6 @@ static void evdev_queue_syn_dropped(struct evdev_client *client)
146 ev.code = SYN_DROPPED; 124 ev.code = SYN_DROPPED;
147 ev.value = 0; 125 ev.value = 0;
148 126
149 spin_lock_irqsave(&client->buffer_lock, flags);
150
151 client->buffer[client->head++] = ev; 127 client->buffer[client->head++] = ev;
152 client->head &= client->bufsize - 1; 128 client->head &= client->bufsize - 1;
153 129
@@ -156,8 +132,53 @@ static void evdev_queue_syn_dropped(struct evdev_client *client)
156 client->tail = (client->head - 1) & (client->bufsize - 1); 132 client->tail = (client->head - 1) & (client->bufsize - 1);
157 client->packet_head = client->tail; 133 client->packet_head = client->tail;
158 } 134 }
135}
136
137static void evdev_queue_syn_dropped(struct evdev_client *client)
138{
139 unsigned long flags;
140
141 spin_lock_irqsave(&client->buffer_lock, flags);
142 __evdev_queue_syn_dropped(client);
143 spin_unlock_irqrestore(&client->buffer_lock, flags);
144}
145
146static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid)
147{
148 unsigned long flags;
149
150 if (client->clk_type == clkid)
151 return 0;
152
153 switch (clkid) {
154
155 case CLOCK_REALTIME:
156 client->clk_type = EV_CLK_REAL;
157 break;
158 case CLOCK_MONOTONIC:
159 client->clk_type = EV_CLK_MONO;
160 break;
161 case CLOCK_BOOTTIME:
162 client->clk_type = EV_CLK_BOOT;
163 break;
164 default:
165 return -EINVAL;
166 }
167
168 /*
169 * Flush pending events and queue SYN_DROPPED event,
170 * but only if the queue is not empty.
171 */
172 spin_lock_irqsave(&client->buffer_lock, flags);
173
174 if (client->head != client->tail) {
175 client->packet_head = client->head = client->tail;
176 __evdev_queue_syn_dropped(client);
177 }
159 178
160 spin_unlock_irqrestore(&client->buffer_lock, flags); 179 spin_unlock_irqrestore(&client->buffer_lock, flags);
180
181 return 0;
161} 182}
162 183
163static void __pass_event(struct evdev_client *client, 184static void __pass_event(struct evdev_client *client,
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c
index fbe29fcb15c5..cb150a1dbaff 100644
--- a/drivers/input/input-mt.c
+++ b/drivers/input/input-mt.c
@@ -293,7 +293,7 @@ void input_mt_sync_frame(struct input_dev *dev)
293} 293}
294EXPORT_SYMBOL(input_mt_sync_frame); 294EXPORT_SYMBOL(input_mt_sync_frame);
295 295
296static int adjust_dual(int *begin, int step, int *end, int eq) 296static int adjust_dual(int *begin, int step, int *end, int eq, int mu)
297{ 297{
298 int f, *p, s, c; 298 int f, *p, s, c;
299 299
@@ -311,9 +311,10 @@ static int adjust_dual(int *begin, int step, int *end, int eq)
311 s = *p; 311 s = *p;
312 312
313 c = (f + s + 1) / 2; 313 c = (f + s + 1) / 2;
314 if (c == 0 || (c > 0 && !eq)) 314 if (c == 0 || (c > mu && (!eq || mu > 0)))
315 return 0; 315 return 0;
316 if (s < 0) 316 /* Improve convergence for positive matrices by penalizing overcovers */
317 if (s < 0 && mu <= 0)
317 c *= 2; 318 c *= 2;
318 319
319 for (p = begin; p != end; p += step) 320 for (p = begin; p != end; p += step)
@@ -322,23 +323,24 @@ static int adjust_dual(int *begin, int step, int *end, int eq)
322 return (c < s && s <= 0) || (f >= 0 && f < c); 323 return (c < s && s <= 0) || (f >= 0 && f < c);
323} 324}
324 325
325static void find_reduced_matrix(int *w, int nr, int nc, int nrc) 326static void find_reduced_matrix(int *w, int nr, int nc, int nrc, int mu)
326{ 327{
327 int i, k, sum; 328 int i, k, sum;
328 329
329 for (k = 0; k < nrc; k++) { 330 for (k = 0; k < nrc; k++) {
330 for (i = 0; i < nr; i++) 331 for (i = 0; i < nr; i++)
331 adjust_dual(w + i, nr, w + i + nrc, nr <= nc); 332 adjust_dual(w + i, nr, w + i + nrc, nr <= nc, mu);
332 sum = 0; 333 sum = 0;
333 for (i = 0; i < nrc; i += nr) 334 for (i = 0; i < nrc; i += nr)
334 sum += adjust_dual(w + i, 1, w + i + nr, nc <= nr); 335 sum += adjust_dual(w + i, 1, w + i + nr, nc <= nr, mu);
335 if (!sum) 336 if (!sum)
336 break; 337 break;
337 } 338 }
338} 339}
339 340
340static int input_mt_set_matrix(struct input_mt *mt, 341static int input_mt_set_matrix(struct input_mt *mt,
341 const struct input_mt_pos *pos, int num_pos) 342 const struct input_mt_pos *pos, int num_pos,
343 int mu)
342{ 344{
343 const struct input_mt_pos *p; 345 const struct input_mt_pos *p;
344 struct input_mt_slot *s; 346 struct input_mt_slot *s;
@@ -352,7 +354,7 @@ static int input_mt_set_matrix(struct input_mt *mt,
352 y = input_mt_get_value(s, ABS_MT_POSITION_Y); 354 y = input_mt_get_value(s, ABS_MT_POSITION_Y);
353 for (p = pos; p != pos + num_pos; p++) { 355 for (p = pos; p != pos + num_pos; p++) {
354 int dx = x - p->x, dy = y - p->y; 356 int dx = x - p->x, dy = y - p->y;
355 *w++ = dx * dx + dy * dy; 357 *w++ = dx * dx + dy * dy - mu;
356 } 358 }
357 } 359 }
358 360
@@ -393,17 +395,24 @@ static void input_mt_set_slots(struct input_mt *mt,
393 * @slots: the slot assignment to be filled 395 * @slots: the slot assignment to be filled
394 * @pos: the position array to match 396 * @pos: the position array to match
395 * @num_pos: number of positions 397 * @num_pos: number of positions
398 * @dmax: maximum ABS_MT_POSITION displacement (zero for infinite)
396 * 399 *
397 * Performs a best match against the current contacts and returns 400 * Performs a best match against the current contacts and returns
398 * the slot assignment list. New contacts are assigned to unused 401 * the slot assignment list. New contacts are assigned to unused
399 * slots. 402 * slots.
400 * 403 *
404 * The assignments are balanced so that all coordinate displacements are
405 * below the euclidian distance dmax. If no such assignment can be found,
406 * some contacts are assigned to unused slots.
407 *
401 * Returns zero on success, or negative error in case of failure. 408 * Returns zero on success, or negative error in case of failure.
402 */ 409 */
403int input_mt_assign_slots(struct input_dev *dev, int *slots, 410int input_mt_assign_slots(struct input_dev *dev, int *slots,
404 const struct input_mt_pos *pos, int num_pos) 411 const struct input_mt_pos *pos, int num_pos,
412 int dmax)
405{ 413{
406 struct input_mt *mt = dev->mt; 414 struct input_mt *mt = dev->mt;
415 int mu = 2 * dmax * dmax;
407 int nrc; 416 int nrc;
408 417
409 if (!mt || !mt->red) 418 if (!mt || !mt->red)
@@ -413,8 +422,8 @@ int input_mt_assign_slots(struct input_dev *dev, int *slots,
413 if (num_pos < 1) 422 if (num_pos < 1)
414 return 0; 423 return 0;
415 424
416 nrc = input_mt_set_matrix(mt, pos, num_pos); 425 nrc = input_mt_set_matrix(mt, pos, num_pos, mu);
417 find_reduced_matrix(mt->red, num_pos, nrc / num_pos, nrc); 426 find_reduced_matrix(mt->red, num_pos, nrc / num_pos, nrc, mu);
418 input_mt_set_slots(mt, slots, num_pos); 427 input_mt_set_slots(mt, slots, num_pos);
419 428
420 return 0; 429 return 0;
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 213e3a1903ee..cc357f1516a7 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -100,23 +100,24 @@ static unsigned int input_to_handler(struct input_handle *handle,
100 struct input_value *end = vals; 100 struct input_value *end = vals;
101 struct input_value *v; 101 struct input_value *v;
102 102
103 for (v = vals; v != vals + count; v++) { 103 if (handler->filter) {
104 if (handler->filter && 104 for (v = vals; v != vals + count; v++) {
105 handler->filter(handle, v->type, v->code, v->value)) 105 if (handler->filter(handle, v->type, v->code, v->value))
106 continue; 106 continue;
107 if (end != v) 107 if (end != v)
108 *end = *v; 108 *end = *v;
109 end++; 109 end++;
110 }
111 count = end - vals;
110 } 112 }
111 113
112 count = end - vals;
113 if (!count) 114 if (!count)
114 return 0; 115 return 0;
115 116
116 if (handler->events) 117 if (handler->events)
117 handler->events(handle, vals, count); 118 handler->events(handle, vals, count);
118 else if (handler->event) 119 else if (handler->event)
119 for (v = vals; v != end; v++) 120 for (v = vals; v != vals + count; v++)
120 handler->event(handle, v->type, v->code, v->value); 121 handler->event(handle, v->type, v->code, v->value);
121 122
122 return count; 123 return count;
@@ -143,8 +144,11 @@ static void input_pass_values(struct input_dev *dev,
143 count = input_to_handler(handle, vals, count); 144 count = input_to_handler(handle, vals, count);
144 } else { 145 } else {
145 list_for_each_entry_rcu(handle, &dev->h_list, d_node) 146 list_for_each_entry_rcu(handle, &dev->h_list, d_node)
146 if (handle->open) 147 if (handle->open) {
147 count = input_to_handler(handle, vals, count); 148 count = input_to_handler(handle, vals, count);
149 if (!count)
150 break;
151 }
148 } 152 }
149 153
150 rcu_read_unlock(); 154 rcu_read_unlock();
@@ -152,12 +156,14 @@ static void input_pass_values(struct input_dev *dev,
152 add_input_randomness(vals->type, vals->code, vals->value); 156 add_input_randomness(vals->type, vals->code, vals->value);
153 157
154 /* trigger auto repeat for key events */ 158 /* trigger auto repeat for key events */
155 for (v = vals; v != vals + count; v++) { 159 if (test_bit(EV_REP, dev->evbit) && test_bit(EV_KEY, dev->evbit)) {
156 if (v->type == EV_KEY && v->value != 2) { 160 for (v = vals; v != vals + count; v++) {
157 if (v->value) 161 if (v->type == EV_KEY && v->value != 2) {
158 input_start_autorepeat(dev, v->code); 162 if (v->value)
159 else 163 input_start_autorepeat(dev, v->code);
160 input_stop_autorepeat(dev); 164 else
165 input_stop_autorepeat(dev);
166 }
161 } 167 }
162 } 168 }
163} 169}
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index a5d9b3f3c871..a89ba7cb96f1 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -568,6 +568,16 @@ config KEYBOARD_STMPE
568 To compile this driver as a module, choose M here: the module will be 568 To compile this driver as a module, choose M here: the module will be
569 called stmpe-keypad. 569 called stmpe-keypad.
570 570
571config KEYBOARD_SUN4I_LRADC
572 tristate "Allwinner sun4i low res adc attached tablet keys support"
573 depends on ARCH_SUNXI
574 help
575 This selects support for the Allwinner low res adc attached tablet
576 keys found on Allwinner sunxi SoCs.
577
578 To compile this driver as a module, choose M here: the
579 module will be called sun4i-lradc-keys.
580
571config KEYBOARD_DAVINCI 581config KEYBOARD_DAVINCI
572 tristate "TI DaVinci Key Scan" 582 tristate "TI DaVinci Key Scan"
573 depends on ARCH_DAVINCI_DM365 583 depends on ARCH_DAVINCI_DM365
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index febafa527eb6..470767884bd8 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -53,6 +53,7 @@ obj-$(CONFIG_KEYBOARD_SPEAR) += spear-keyboard.o
53obj-$(CONFIG_KEYBOARD_STMPE) += stmpe-keypad.o 53obj-$(CONFIG_KEYBOARD_STMPE) += stmpe-keypad.o
54obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o 54obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o
55obj-$(CONFIG_KEYBOARD_ST_KEYSCAN) += st-keyscan.o 55obj-$(CONFIG_KEYBOARD_ST_KEYSCAN) += st-keyscan.o
56obj-$(CONFIG_KEYBOARD_SUN4I_LRADC) += sun4i-lradc-keys.o
56obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o 57obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o
57obj-$(CONFIG_KEYBOARD_TC3589X) += tc3589x-keypad.o 58obj-$(CONFIG_KEYBOARD_TC3589X) += tc3589x-keypad.o
58obj-$(CONFIG_KEYBOARD_TEGRA) += tegra-kbc.o 59obj-$(CONFIG_KEYBOARD_TEGRA) += tegra-kbc.o
diff --git a/drivers/input/keyboard/atakbd.c b/drivers/input/keyboard/atakbd.c
index 10bcd4ae5402..f1235831283d 100644
--- a/drivers/input/keyboard/atakbd.c
+++ b/drivers/input/keyboard/atakbd.c
@@ -170,7 +170,7 @@ static unsigned char atakbd_keycode[0x72] = { /* American layout */
170 [93] = KEY_KPASTERISK, 170 [93] = KEY_KPASTERISK,
171 [94] = KEY_KPPLUS, 171 [94] = KEY_KPPLUS,
172 [95] = KEY_HELP, 172 [95] = KEY_HELP,
173 [96] = KEY_BACKSLASH, /* FIXME: '<' */ 173 [96] = KEY_102ND,
174 [97] = KEY_KPASTERISK, /* FIXME */ 174 [97] = KEY_KPASTERISK, /* FIXME */
175 [98] = KEY_KPSLASH, 175 [98] = KEY_KPSLASH,
176 [99] = KEY_KPLEFTPAREN, 176 [99] = KEY_KPLEFTPAREN,
diff --git a/drivers/input/keyboard/cap11xx.c b/drivers/input/keyboard/cap11xx.c
index 4f59f0bab28f..f07461a64d85 100644
--- a/drivers/input/keyboard/cap11xx.c
+++ b/drivers/input/keyboard/cap11xx.c
@@ -370,7 +370,6 @@ static struct i2c_driver cap11xx_i2c_driver = {
370 370
371module_i2c_driver(cap11xx_i2c_driver); 371module_i2c_driver(cap11xx_i2c_driver);
372 372
373MODULE_ALIAS("platform:cap11xx");
374MODULE_DESCRIPTION("Microchip CAP11XX driver"); 373MODULE_DESCRIPTION("Microchip CAP11XX driver");
375MODULE_AUTHOR("Daniel Mack <linux@zonque.org>"); 374MODULE_AUTHOR("Daniel Mack <linux@zonque.org>");
376MODULE_LICENSE("GPL v2"); 375MODULE_LICENSE("GPL v2");
diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c
index e53f232eda0e..2e855e6f3565 100644
--- a/drivers/input/keyboard/imx_keypad.c
+++ b/drivers/input/keyboard/imx_keypad.c
@@ -448,8 +448,7 @@ static int imx_keypad_probe(struct platform_device *pdev)
448 return -ENOMEM; 448 return -ENOMEM;
449 } 449 }
450 450
451 keypad = devm_kzalloc(&pdev->dev, sizeof(struct imx_keypad), 451 keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), GFP_KERNEL);
452 GFP_KERNEL);
453 if (!keypad) { 452 if (!keypad) {
454 dev_err(&pdev->dev, "not enough memory for driver data\n"); 453 dev_err(&pdev->dev, "not enough memory for driver data\n");
455 return -ENOMEM; 454 return -ENOMEM;
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c
index a90d6bdc499e..a89488aa1aa4 100644
--- a/drivers/input/keyboard/pxa27x_keypad.c
+++ b/drivers/input/keyboard/pxa27x_keypad.c
@@ -20,6 +20,7 @@
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/interrupt.h> 21#include <linux/interrupt.h>
22#include <linux/input.h> 22#include <linux/input.h>
23#include <linux/io.h>
23#include <linux/device.h> 24#include <linux/device.h>
24#include <linux/platform_device.h> 25#include <linux/platform_device.h>
25#include <linux/clk.h> 26#include <linux/clk.h>
@@ -28,10 +29,6 @@
28#include <linux/slab.h> 29#include <linux/slab.h>
29#include <linux/of.h> 30#include <linux/of.h>
30 31
31#include <asm/mach/arch.h>
32#include <asm/mach/map.h>
33
34#include <mach/hardware.h>
35#include <linux/platform_data/keypad-pxa27x.h> 32#include <linux/platform_data/keypad-pxa27x.h>
36/* 33/*
37 * Keypad Controller registers 34 * Keypad Controller registers
diff --git a/drivers/input/keyboard/sun4i-lradc-keys.c b/drivers/input/keyboard/sun4i-lradc-keys.c
new file mode 100644
index 000000000000..cc8f7ddcee53
--- /dev/null
+++ b/drivers/input/keyboard/sun4i-lradc-keys.c
@@ -0,0 +1,286 @@
1/*
2 * Allwinner sun4i low res adc attached tablet keys driver
3 *
4 * Copyright (C) 2014 Hans de Goede <hdegoede@redhat.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17/*
18 * Allwinnner sunxi SoCs have a lradc which is specifically designed to have
19 * various (tablet) keys (ie home, back, search, etc). attached to it using
20 * a resistor network. This driver is for the keys on such boards.
21 *
22 * There are 2 channels, currently this driver only supports channel 0 since
23 * there are no boards known to use channel 1.
24 */
25
26#include <linux/err.h>
27#include <linux/init.h>
28#include <linux/input.h>
29#include <linux/interrupt.h>
30#include <linux/io.h>
31#include <linux/module.h>
32#include <linux/of_platform.h>
33#include <linux/platform_device.h>
34#include <linux/regulator/consumer.h>
35#include <linux/slab.h>
36
37#define LRADC_CTRL 0x00
38#define LRADC_INTC 0x04
39#define LRADC_INTS 0x08
40#define LRADC_DATA0 0x0c
41#define LRADC_DATA1 0x10
42
43/* LRADC_CTRL bits */
44#define FIRST_CONVERT_DLY(x) ((x) << 24) /* 8 bits */
45#define CHAN_SELECT(x) ((x) << 22) /* 2 bits */
46#define CONTINUE_TIME_SEL(x) ((x) << 16) /* 4 bits */
47#define KEY_MODE_SEL(x) ((x) << 12) /* 2 bits */
48#define LEVELA_B_CNT(x) ((x) << 8) /* 4 bits */
49#define HOLD_EN(x) ((x) << 6)
50#define LEVELB_VOL(x) ((x) << 4) /* 2 bits */
51#define SAMPLE_RATE(x) ((x) << 2) /* 2 bits */
52#define ENABLE(x) ((x) << 0)
53
54/* LRADC_INTC and LRADC_INTS bits */
55#define CHAN1_KEYUP_IRQ BIT(12)
56#define CHAN1_ALRDY_HOLD_IRQ BIT(11)
57#define CHAN1_HOLD_IRQ BIT(10)
58#define CHAN1_KEYDOWN_IRQ BIT(9)
59#define CHAN1_DATA_IRQ BIT(8)
60#define CHAN0_KEYUP_IRQ BIT(4)
61#define CHAN0_ALRDY_HOLD_IRQ BIT(3)
62#define CHAN0_HOLD_IRQ BIT(2)
63#define CHAN0_KEYDOWN_IRQ BIT(1)
64#define CHAN0_DATA_IRQ BIT(0)
65
66struct sun4i_lradc_keymap {
67 u32 voltage;
68 u32 keycode;
69};
70
71struct sun4i_lradc_data {
72 struct device *dev;
73 struct input_dev *input;
74 void __iomem *base;
75 struct regulator *vref_supply;
76 struct sun4i_lradc_keymap *chan0_map;
77 u32 chan0_map_count;
78 u32 chan0_keycode;
79 u32 vref;
80};
81
82static irqreturn_t sun4i_lradc_irq(int irq, void *dev_id)
83{
84 struct sun4i_lradc_data *lradc = dev_id;
85 u32 i, ints, val, voltage, diff, keycode = 0, closest = 0xffffffff;
86
87 ints = readl(lradc->base + LRADC_INTS);
88
89 /*
90 * lradc supports only one keypress at a time, release does not give
91 * any info as to which key was released, so we cache the keycode.
92 */
93
94 if (ints & CHAN0_KEYUP_IRQ) {
95 input_report_key(lradc->input, lradc->chan0_keycode, 0);
96 lradc->chan0_keycode = 0;
97 }
98
99 if ((ints & CHAN0_KEYDOWN_IRQ) && lradc->chan0_keycode == 0) {
100 val = readl(lradc->base + LRADC_DATA0) & 0x3f;
101 voltage = val * lradc->vref / 63;
102
103 for (i = 0; i < lradc->chan0_map_count; i++) {
104 diff = abs(lradc->chan0_map[i].voltage - voltage);
105 if (diff < closest) {
106 closest = diff;
107 keycode = lradc->chan0_map[i].keycode;
108 }
109 }
110
111 lradc->chan0_keycode = keycode;
112 input_report_key(lradc->input, lradc->chan0_keycode, 1);
113 }
114
115 input_sync(lradc->input);
116
117 writel(ints, lradc->base + LRADC_INTS);
118
119 return IRQ_HANDLED;
120}
121
122static int sun4i_lradc_open(struct input_dev *dev)
123{
124 struct sun4i_lradc_data *lradc = input_get_drvdata(dev);
125 int error;
126
127 error = regulator_enable(lradc->vref_supply);
128 if (error)
129 return error;
130
131 /* lradc Vref internally is divided by 2/3 */
132 lradc->vref = regulator_get_voltage(lradc->vref_supply) * 2 / 3;
133
134 /*
135 * Set sample time to 4 ms / 250 Hz. Wait 2 * 4 ms for key to
136 * stabilize on press, wait (1 + 1) * 4 ms for key release
137 */
138 writel(FIRST_CONVERT_DLY(2) | LEVELA_B_CNT(1) | HOLD_EN(1) |
139 SAMPLE_RATE(0) | ENABLE(1), lradc->base + LRADC_CTRL);
140
141 writel(CHAN0_KEYUP_IRQ | CHAN0_KEYDOWN_IRQ, lradc->base + LRADC_INTC);
142
143 return 0;
144}
145
146static void sun4i_lradc_close(struct input_dev *dev)
147{
148 struct sun4i_lradc_data *lradc = input_get_drvdata(dev);
149
150 /* Disable lradc, leave other settings unchanged */
151 writel(FIRST_CONVERT_DLY(2) | LEVELA_B_CNT(1) | HOLD_EN(1) |
152 SAMPLE_RATE(2), lradc->base + LRADC_CTRL);
153 writel(0, lradc->base + LRADC_INTC);
154
155 regulator_disable(lradc->vref_supply);
156}
157
158static int sun4i_lradc_load_dt_keymap(struct device *dev,
159 struct sun4i_lradc_data *lradc)
160{
161 struct device_node *np, *pp;
162 int i;
163 int error;
164
165 np = dev->of_node;
166 if (!np)
167 return -EINVAL;
168
169 lradc->chan0_map_count = of_get_child_count(np);
170 if (lradc->chan0_map_count == 0) {
171 dev_err(dev, "keymap is missing in device tree\n");
172 return -EINVAL;
173 }
174
175 lradc->chan0_map = devm_kmalloc_array(dev, lradc->chan0_map_count,
176 sizeof(struct sun4i_lradc_keymap),
177 GFP_KERNEL);
178 if (!lradc->chan0_map)
179 return -ENOMEM;
180
181 i = 0;
182 for_each_child_of_node(np, pp) {
183 struct sun4i_lradc_keymap *map = &lradc->chan0_map[i];
184 u32 channel;
185
186 error = of_property_read_u32(pp, "channel", &channel);
187 if (error || channel != 0) {
188 dev_err(dev, "%s: Inval channel prop\n", pp->name);
189 return -EINVAL;
190 }
191
192 error = of_property_read_u32(pp, "voltage", &map->voltage);
193 if (error) {
194 dev_err(dev, "%s: Inval voltage prop\n", pp->name);
195 return -EINVAL;
196 }
197
198 error = of_property_read_u32(pp, "linux,code", &map->keycode);
199 if (error) {
200 dev_err(dev, "%s: Inval linux,code prop\n", pp->name);
201 return -EINVAL;
202 }
203
204 i++;
205 }
206
207 return 0;
208}
209
210static int sun4i_lradc_probe(struct platform_device *pdev)
211{
212 struct sun4i_lradc_data *lradc;
213 struct device *dev = &pdev->dev;
214 int i;
215 int error;
216
217 lradc = devm_kzalloc(dev, sizeof(struct sun4i_lradc_data), GFP_KERNEL);
218 if (!lradc)
219 return -ENOMEM;
220
221 error = sun4i_lradc_load_dt_keymap(dev, lradc);
222 if (error)
223 return error;
224
225 lradc->vref_supply = devm_regulator_get(dev, "vref");
226 if (IS_ERR(lradc->vref_supply))
227 return PTR_ERR(lradc->vref_supply);
228
229 lradc->dev = dev;
230 lradc->input = devm_input_allocate_device(dev);
231 if (!lradc->input)
232 return -ENOMEM;
233
234 lradc->input->name = pdev->name;
235 lradc->input->phys = "sun4i_lradc/input0";
236 lradc->input->open = sun4i_lradc_open;
237 lradc->input->close = sun4i_lradc_close;
238 lradc->input->id.bustype = BUS_HOST;
239 lradc->input->id.vendor = 0x0001;
240 lradc->input->id.product = 0x0001;
241 lradc->input->id.version = 0x0100;
242
243 __set_bit(EV_KEY, lradc->input->evbit);
244 for (i = 0; i < lradc->chan0_map_count; i++)
245 __set_bit(lradc->chan0_map[i].keycode, lradc->input->keybit);
246
247 input_set_drvdata(lradc->input, lradc);
248
249 lradc->base = devm_ioremap_resource(dev,
250 platform_get_resource(pdev, IORESOURCE_MEM, 0));
251 if (IS_ERR(lradc->base))
252 return PTR_ERR(lradc->base);
253
254 error = devm_request_irq(dev, platform_get_irq(pdev, 0),
255 sun4i_lradc_irq, 0,
256 "sun4i-a10-lradc-keys", lradc);
257 if (error)
258 return error;
259
260 error = input_register_device(lradc->input);
261 if (error)
262 return error;
263
264 platform_set_drvdata(pdev, lradc);
265 return 0;
266}
267
268static const struct of_device_id sun4i_lradc_of_match[] = {
269 { .compatible = "allwinner,sun4i-a10-lradc-keys", },
270 { /* sentinel */ }
271};
272MODULE_DEVICE_TABLE(of, sun4i_lradc_of_match);
273
274static struct platform_driver sun4i_lradc_driver = {
275 .driver = {
276 .name = "sun4i-a10-lradc-keys",
277 .of_match_table = of_match_ptr(sun4i_lradc_of_match),
278 },
279 .probe = sun4i_lradc_probe,
280};
281
282module_platform_driver(sun4i_lradc_driver);
283
284MODULE_DESCRIPTION("Allwinner sun4i low res adc attached tablet keys driver");
285MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
286MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 23297ab6163f..6deb8dae3205 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -93,6 +93,16 @@ config INPUT_BMA150
93 To compile this driver as a module, choose M here: the 93 To compile this driver as a module, choose M here: the
94 module will be called bma150. 94 module will be called bma150.
95 95
96config INPUT_E3X0_BUTTON
97 tristate "NI Ettus Research USRP E3x0 Button support."
98 default n
99 help
100 Say Y here to enable support for the NI Ettus Research
101 USRP E3x0 Button.
102
103 To compile this driver as a module, choose M here: the
104 module will be called e3x0_button.
105
96config INPUT_PCSPKR 106config INPUT_PCSPKR
97 tristate "PC Speaker support" 107 tristate "PC Speaker support"
98 depends on PCSPKR_PLATFORM 108 depends on PCSPKR_PLATFORM
@@ -394,6 +404,18 @@ config INPUT_CM109
394 To compile this driver as a module, choose M here: the module will be 404 To compile this driver as a module, choose M here: the module will be
395 called cm109. 405 called cm109.
396 406
407config INPUT_REGULATOR_HAPTIC
408 tristate "Regulator haptics support"
409 depends on REGULATOR
410 select INPUT_FF_MEMLESS
411 help
412 This option enables device driver support for the haptic controlled
413 by a regulator. This driver supports ff-memless interface
414 from input framework.
415
416 To compile this driver as a module, choose M here: the
417 module will be called regulator-haptic.
418
397config INPUT_RETU_PWRBUTTON 419config INPUT_RETU_PWRBUTTON
398 tristate "Retu Power button Driver" 420 tristate "Retu Power button Driver"
399 depends on MFD_RETU 421 depends on MFD_RETU
@@ -404,6 +426,27 @@ config INPUT_RETU_PWRBUTTON
404 To compile this driver as a module, choose M here. The module will 426 To compile this driver as a module, choose M here. The module will
405 be called retu-pwrbutton. 427 be called retu-pwrbutton.
406 428
429config INPUT_TPS65218_PWRBUTTON
430 tristate "TPS65218 Power button driver"
431 depends on MFD_TPS65218
432 help
433 Say Y here if you want to enable power buttong reporting for
434 the TPS65218 Power Management IC device.
435
436 To compile this driver as a module, choose M here. The module will
437 be called tps65218-pwrbutton.
438
439config INPUT_AXP20X_PEK
440 tristate "X-Powers AXP20X power button driver"
441 depends on MFD_AXP20X
442 help
443 Say Y here if you want to enable power key reporting via the
444 AXP20X PMIC.
445
446 To compile this driver as a module, choose M here. The module will
447 be called axp20x-pek.
448
449
407config INPUT_TWL4030_PWRBUTTON 450config INPUT_TWL4030_PWRBUTTON
408 tristate "TWL4030 Power button Driver" 451 tristate "TWL4030 Power button Driver"
409 depends on TWL4030_CORE 452 depends on TWL4030_CORE
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 19c760361f80..403a1a54a76c 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o
26obj-$(CONFIG_INPUT_DA9052_ONKEY) += da9052_onkey.o 26obj-$(CONFIG_INPUT_DA9052_ONKEY) += da9052_onkey.o
27obj-$(CONFIG_INPUT_DA9055_ONKEY) += da9055_onkey.o 27obj-$(CONFIG_INPUT_DA9055_ONKEY) += da9055_onkey.o
28obj-$(CONFIG_INPUT_DM355EVM) += dm355evm_keys.o 28obj-$(CONFIG_INPUT_DM355EVM) += dm355evm_keys.o
29obj-$(CONFIG_INPUT_E3X0_BUTTON) += e3x0-button.o
29obj-$(CONFIG_INPUT_DRV260X_HAPTICS) += drv260x.o 30obj-$(CONFIG_INPUT_DRV260X_HAPTICS) += drv260x.o
30obj-$(CONFIG_INPUT_DRV2667_HAPTICS) += drv2667.o 31obj-$(CONFIG_INPUT_DRV2667_HAPTICS) += drv2667.o
31obj-$(CONFIG_INPUT_GP2A) += gp2ap002a00f.o 32obj-$(CONFIG_INPUT_GP2A) += gp2ap002a00f.o
@@ -53,12 +54,15 @@ obj-$(CONFIG_INPUT_PMIC8XXX_PWRKEY) += pmic8xxx-pwrkey.o
53obj-$(CONFIG_INPUT_POWERMATE) += powermate.o 54obj-$(CONFIG_INPUT_POWERMATE) += powermate.o
54obj-$(CONFIG_INPUT_PWM_BEEPER) += pwm-beeper.o 55obj-$(CONFIG_INPUT_PWM_BEEPER) += pwm-beeper.o
55obj-$(CONFIG_INPUT_RB532_BUTTON) += rb532_button.o 56obj-$(CONFIG_INPUT_RB532_BUTTON) += rb532_button.o
57obj-$(CONFIG_INPUT_REGULATOR_HAPTIC) += regulator-haptic.o
56obj-$(CONFIG_INPUT_RETU_PWRBUTTON) += retu-pwrbutton.o 58obj-$(CONFIG_INPUT_RETU_PWRBUTTON) += retu-pwrbutton.o
59obj-$(CONFIG_INPUT_AXP20X_PEK) += axp20x-pek.o
57obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o 60obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o
58obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o 61obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o
59obj-$(CONFIG_INPUT_SIRFSOC_ONKEY) += sirfsoc-onkey.o 62obj-$(CONFIG_INPUT_SIRFSOC_ONKEY) += sirfsoc-onkey.o
60obj-$(CONFIG_INPUT_SOC_BUTTON_ARRAY) += soc_button_array.o 63obj-$(CONFIG_INPUT_SOC_BUTTON_ARRAY) += soc_button_array.o
61obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o 64obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o
65obj-$(CONFIG_INPUT_TPS65218_PWRBUTTON) += tps65218-pwrbutton.o
62obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o 66obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o
63obj-$(CONFIG_INPUT_TWL4030_VIBRA) += twl4030-vibra.o 67obj-$(CONFIG_INPUT_TWL4030_VIBRA) += twl4030-vibra.o
64obj-$(CONFIG_INPUT_TWL6040_VIBRA) += twl6040-vibra.o 68obj-$(CONFIG_INPUT_TWL6040_VIBRA) += twl6040-vibra.o
diff --git a/drivers/input/misc/axp20x-pek.c b/drivers/input/misc/axp20x-pek.c
new file mode 100644
index 000000000000..f1c844739cd7
--- /dev/null
+++ b/drivers/input/misc/axp20x-pek.c
@@ -0,0 +1,290 @@
1/*
2 * axp20x power button driver.
3 *
4 * Copyright (C) 2013 Carlo Caione <carlo@caione.org>
5 *
6 * This file is subject to the terms and conditions of the GNU General
7 * Public License. See the file "COPYING" in the main directory of this
8 * archive for more details.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/errno.h>
17#include <linux/irq.h>
18#include <linux/init.h>
19#include <linux/input.h>
20#include <linux/interrupt.h>
21#include <linux/kernel.h>
22#include <linux/mfd/axp20x.h>
23#include <linux/module.h>
24#include <linux/platform_device.h>
25#include <linux/regmap.h>
26#include <linux/slab.h>
27
28#define AXP20X_PEK_STARTUP_MASK (0xc0)
29#define AXP20X_PEK_SHUTDOWN_MASK (0x03)
30
31struct axp20x_pek {
32 struct axp20x_dev *axp20x;
33 struct input_dev *input;
34 int irq_dbr;
35 int irq_dbf;
36};
37
38struct axp20x_time {
39 unsigned int time;
40 unsigned int idx;
41};
42
43static const struct axp20x_time startup_time[] = {
44 { .time = 128, .idx = 0 },
45 { .time = 1000, .idx = 2 },
46 { .time = 3000, .idx = 1 },
47 { .time = 2000, .idx = 3 },
48};
49
50static const struct axp20x_time shutdown_time[] = {
51 { .time = 4000, .idx = 0 },
52 { .time = 6000, .idx = 1 },
53 { .time = 8000, .idx = 2 },
54 { .time = 10000, .idx = 3 },
55};
56
57struct axp20x_pek_ext_attr {
58 const struct axp20x_time *p_time;
59 unsigned int mask;
60};
61
62static struct axp20x_pek_ext_attr axp20x_pek_startup_ext_attr = {
63 .p_time = startup_time,
64 .mask = AXP20X_PEK_STARTUP_MASK,
65};
66
67static struct axp20x_pek_ext_attr axp20x_pek_shutdown_ext_attr = {
68 .p_time = shutdown_time,
69 .mask = AXP20X_PEK_SHUTDOWN_MASK,
70};
71
72static struct axp20x_pek_ext_attr *get_axp_ext_attr(struct device_attribute *attr)
73{
74 return container_of(attr, struct dev_ext_attribute, attr)->var;
75}
76
77static ssize_t axp20x_show_ext_attr(struct device *dev,
78 struct device_attribute *attr, char *buf)
79{
80 struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
81 struct axp20x_pek_ext_attr *axp20x_ea = get_axp_ext_attr(attr);
82 unsigned int val;
83 int ret, i;
84
85 ret = regmap_read(axp20x_pek->axp20x->regmap, AXP20X_PEK_KEY, &val);
86 if (ret != 0)
87 return ret;
88
89 val &= axp20x_ea->mask;
90 val >>= ffs(axp20x_ea->mask) - 1;
91
92 for (i = 0; i < 4; i++)
93 if (val == axp20x_ea->p_time[i].idx)
94 val = axp20x_ea->p_time[i].time;
95
96 return sprintf(buf, "%u\n", val);
97}
98
99static ssize_t axp20x_store_ext_attr(struct device *dev,
100 struct device_attribute *attr,
101 const char *buf, size_t count)
102{
103 struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
104 struct axp20x_pek_ext_attr *axp20x_ea = get_axp_ext_attr(attr);
105 char val_str[20];
106 size_t len;
107 int ret, i;
108 unsigned int val, idx = 0;
109 unsigned int best_err = UINT_MAX;
110
111 val_str[sizeof(val_str) - 1] = '\0';
112 strncpy(val_str, buf, sizeof(val_str) - 1);
113 len = strlen(val_str);
114
115 if (len && val_str[len - 1] == '\n')
116 val_str[len - 1] = '\0';
117
118 ret = kstrtouint(val_str, 10, &val);
119 if (ret)
120 return ret;
121
122 for (i = 3; i >= 0; i--) {
123 unsigned int err;
124
125 err = abs(axp20x_ea->p_time[i].time - val);
126 if (err < best_err) {
127 best_err = err;
128 idx = axp20x_ea->p_time[i].idx;
129 }
130
131 if (!err)
132 break;
133 }
134
135 idx <<= ffs(axp20x_ea->mask) - 1;
136 ret = regmap_update_bits(axp20x_pek->axp20x->regmap,
137 AXP20X_PEK_KEY,
138 axp20x_ea->mask, idx);
139 if (ret != 0)
140 return -EINVAL;
141
142 return count;
143}
144
145static struct dev_ext_attribute axp20x_dev_attr_startup = {
146 .attr = __ATTR(startup, 0644, axp20x_show_ext_attr, axp20x_store_ext_attr),
147 .var = &axp20x_pek_startup_ext_attr,
148};
149
150static struct dev_ext_attribute axp20x_dev_attr_shutdown = {
151 .attr = __ATTR(shutdown, 0644, axp20x_show_ext_attr, axp20x_store_ext_attr),
152 .var = &axp20x_pek_shutdown_ext_attr,
153};
154
155static struct attribute *axp20x_attributes[] = {
156 &axp20x_dev_attr_startup.attr.attr,
157 &axp20x_dev_attr_shutdown.attr.attr,
158 NULL,
159};
160
161static const struct attribute_group axp20x_attribute_group = {
162 .attrs = axp20x_attributes,
163};
164
165static irqreturn_t axp20x_pek_irq(int irq, void *pwr)
166{
167 struct input_dev *idev = pwr;
168 struct axp20x_pek *axp20x_pek = input_get_drvdata(idev);
169
170 if (irq == axp20x_pek->irq_dbr)
171 input_report_key(idev, KEY_POWER, true);
172 else if (irq == axp20x_pek->irq_dbf)
173 input_report_key(idev, KEY_POWER, false);
174
175 input_sync(idev);
176
177 return IRQ_HANDLED;
178}
179
180static void axp20x_remove_sysfs_group(void *_data)
181{
182 struct device *dev = _data;
183
184 sysfs_remove_group(&dev->kobj, &axp20x_attribute_group);
185}
186
187static int axp20x_pek_probe(struct platform_device *pdev)
188{
189 struct axp20x_pek *axp20x_pek;
190 struct axp20x_dev *axp20x;
191 struct input_dev *idev;
192 int error;
193
194 axp20x_pek = devm_kzalloc(&pdev->dev, sizeof(struct axp20x_pek),
195 GFP_KERNEL);
196 if (!axp20x_pek)
197 return -ENOMEM;
198
199 axp20x_pek->axp20x = dev_get_drvdata(pdev->dev.parent);
200 axp20x = axp20x_pek->axp20x;
201
202 axp20x_pek->irq_dbr = platform_get_irq_byname(pdev, "PEK_DBR");
203 if (axp20x_pek->irq_dbr < 0) {
204 dev_err(&pdev->dev, "No IRQ for PEK_DBR, error=%d\n",
205 axp20x_pek->irq_dbr);
206 return axp20x_pek->irq_dbr;
207 }
208 axp20x_pek->irq_dbr = regmap_irq_get_virq(axp20x->regmap_irqc,
209 axp20x_pek->irq_dbr);
210
211 axp20x_pek->irq_dbf = platform_get_irq_byname(pdev, "PEK_DBF");
212 if (axp20x_pek->irq_dbf < 0) {
213 dev_err(&pdev->dev, "No IRQ for PEK_DBF, error=%d\n",
214 axp20x_pek->irq_dbf);
215 return axp20x_pek->irq_dbf;
216 }
217 axp20x_pek->irq_dbf = regmap_irq_get_virq(axp20x->regmap_irqc,
218 axp20x_pek->irq_dbf);
219
220 axp20x_pek->input = devm_input_allocate_device(&pdev->dev);
221 if (!axp20x_pek->input)
222 return -ENOMEM;
223
224 idev = axp20x_pek->input;
225
226 idev->name = "axp20x-pek";
227 idev->phys = "m1kbd/input2";
228 idev->dev.parent = &pdev->dev;
229
230 input_set_capability(idev, EV_KEY, KEY_POWER);
231
232 input_set_drvdata(idev, axp20x_pek);
233
234 error = devm_request_any_context_irq(&pdev->dev, axp20x_pek->irq_dbr,
235 axp20x_pek_irq, 0,
236 "axp20x-pek-dbr", idev);
237 if (error < 0) {
238 dev_err(axp20x->dev, "Failed to request dbr IRQ#%d: %d\n",
239 axp20x_pek->irq_dbr, error);
240 return error;
241 }
242
243 error = devm_request_any_context_irq(&pdev->dev, axp20x_pek->irq_dbf,
244 axp20x_pek_irq, 0,
245 "axp20x-pek-dbf", idev);
246 if (error < 0) {
247 dev_err(axp20x->dev, "Failed to request dbf IRQ#%d: %d\n",
248 axp20x_pek->irq_dbf, error);
249 return error;
250 }
251
252 error = sysfs_create_group(&pdev->dev.kobj, &axp20x_attribute_group);
253 if (error) {
254 dev_err(axp20x->dev, "Failed to create sysfs attributes: %d\n",
255 error);
256 return error;
257 }
258
259 error = devm_add_action(&pdev->dev,
260 axp20x_remove_sysfs_group, &pdev->dev);
261 if (error) {
262 axp20x_remove_sysfs_group(&pdev->dev);
263 dev_err(&pdev->dev, "Failed to add sysfs cleanup action: %d\n",
264 error);
265 return error;
266 }
267
268 error = input_register_device(idev);
269 if (error) {
270 dev_err(axp20x->dev, "Can't register input device: %d\n",
271 error);
272 return error;
273 }
274
275 platform_set_drvdata(pdev, axp20x_pek);
276
277 return 0;
278}
279
280static struct platform_driver axp20x_pek_driver = {
281 .probe = axp20x_pek_probe,
282 .driver = {
283 .name = "axp20x-pek",
284 },
285};
286module_platform_driver(axp20x_pek_driver);
287
288MODULE_DESCRIPTION("axp20x Power Button");
289MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
290MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/drv260x.c b/drivers/input/misc/drv260x.c
index a364e109ca7c..599578042ea0 100644
--- a/drivers/input/misc/drv260x.c
+++ b/drivers/input/misc/drv260x.c
@@ -733,7 +733,6 @@ static struct i2c_driver drv260x_driver = {
733}; 733};
734module_i2c_driver(drv260x_driver); 734module_i2c_driver(drv260x_driver);
735 735
736MODULE_ALIAS("platform:drv260x-haptics");
737MODULE_DESCRIPTION("TI DRV260x haptics driver"); 736MODULE_DESCRIPTION("TI DRV260x haptics driver");
738MODULE_LICENSE("GPL"); 737MODULE_LICENSE("GPL");
739MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>"); 738MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
diff --git a/drivers/input/misc/drv2667.c b/drivers/input/misc/drv2667.c
index a021744e608c..fc0fddf0896a 100644
--- a/drivers/input/misc/drv2667.c
+++ b/drivers/input/misc/drv2667.c
@@ -492,7 +492,6 @@ static struct i2c_driver drv2667_driver = {
492}; 492};
493module_i2c_driver(drv2667_driver); 493module_i2c_driver(drv2667_driver);
494 494
495MODULE_ALIAS("platform:drv2667-haptics");
496MODULE_DESCRIPTION("TI DRV2667 haptics driver"); 495MODULE_DESCRIPTION("TI DRV2667 haptics driver");
497MODULE_LICENSE("GPL"); 496MODULE_LICENSE("GPL");
498MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>"); 497MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
diff --git a/drivers/input/misc/e3x0-button.c b/drivers/input/misc/e3x0-button.c
new file mode 100644
index 000000000000..13bfca8a7b16
--- /dev/null
+++ b/drivers/input/misc/e3x0-button.c
@@ -0,0 +1,157 @@
1/*
2 * Copyright (c) 2014, National Instruments Corp. All rights reserved.
3 *
4 * Driver for NI Ettus Research USRP E3x0 Button Driver
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/device.h>
17#include <linux/kernel.h>
18#include <linux/module.h>
19#include <linux/platform_device.h>
20#include <linux/input.h>
21#include <linux/interrupt.h>
22#include <linux/of.h>
23#include <linux/slab.h>
24
25static irqreturn_t e3x0_button_release_handler(int irq, void *data)
26{
27 struct input_dev *idev = data;
28
29 input_report_key(idev, KEY_POWER, 0);
30 input_sync(idev);
31
32 return IRQ_HANDLED;
33}
34
35static irqreturn_t e3x0_button_press_handler(int irq, void *data)
36{
37 struct input_dev *idev = data;
38
39 input_report_key(idev, KEY_POWER, 1);
40 pm_wakeup_event(idev->dev.parent, 0);
41 input_sync(idev);
42
43 return IRQ_HANDLED;
44}
45
46static int __maybe_unused e3x0_button_suspend(struct device *dev)
47{
48 struct platform_device *pdev = to_platform_device(dev);
49
50 if (device_may_wakeup(dev))
51 enable_irq_wake(platform_get_irq_byname(pdev, "press"));
52
53 return 0;
54}
55
56static int __maybe_unused e3x0_button_resume(struct device *dev)
57{
58 struct platform_device *pdev = to_platform_device(dev);
59
60 if (device_may_wakeup(dev))
61 disable_irq_wake(platform_get_irq_byname(pdev, "press"));
62
63 return 0;
64}
65
66static SIMPLE_DEV_PM_OPS(e3x0_button_pm_ops,
67 e3x0_button_suspend, e3x0_button_resume);
68
69static int e3x0_button_probe(struct platform_device *pdev)
70{
71 struct input_dev *input;
72 int irq_press, irq_release;
73 int error;
74
75 irq_press = platform_get_irq_byname(pdev, "press");
76 if (irq_press < 0) {
77 dev_err(&pdev->dev, "No IRQ for 'press', error=%d\n",
78 irq_press);
79 return irq_press;
80 }
81
82 irq_release = platform_get_irq_byname(pdev, "release");
83 if (irq_release < 0) {
84 dev_err(&pdev->dev, "No IRQ for 'release', error=%d\n",
85 irq_release);
86 return irq_release;
87 }
88
89 input = devm_input_allocate_device(&pdev->dev);
90 if (!input)
91 return -ENOMEM;
92
93 input->name = "NI Ettus Research USRP E3x0 Button Driver";
94 input->phys = "e3x0_button/input0";
95 input->dev.parent = &pdev->dev;
96
97 input_set_capability(input, EV_KEY, KEY_POWER);
98
99 error = devm_request_irq(&pdev->dev, irq_press,
100 e3x0_button_press_handler, 0,
101 "e3x0-button", input);
102 if (error) {
103 dev_err(&pdev->dev, "Failed to request 'press' IRQ#%d: %d\n",
104 irq_press, error);
105 return error;
106 }
107
108 error = devm_request_irq(&pdev->dev, irq_release,
109 e3x0_button_release_handler, 0,
110 "e3x0-button", input);
111 if (error) {
112 dev_err(&pdev->dev, "Failed to request 'release' IRQ#%d: %d\n",
113 irq_release, error);
114 return error;
115 }
116
117 error = input_register_device(input);
118 if (error) {
119 dev_err(&pdev->dev, "Can't register input device: %d\n", error);
120 return error;
121 }
122
123 platform_set_drvdata(pdev, input);
124 device_init_wakeup(&pdev->dev, 1);
125 return 0;
126}
127
128static int e3x0_button_remove(struct platform_device *pdev)
129{
130 device_init_wakeup(&pdev->dev, 0);
131 return 0;
132}
133
134#ifdef CONFIG_OF
135static const struct of_device_id e3x0_button_match[] = {
136 { .compatible = "ettus,e3x0-button", },
137 { }
138};
139MODULE_DEVICE_TABLE(of, e3x0_button_match);
140#endif
141
142static struct platform_driver e3x0_button_driver = {
143 .driver = {
144 .name = "e3x0-button",
145 .of_match_table = of_match_ptr(e3x0_button_match),
146 .pm = &e3x0_button_pm_ops,
147 },
148 .probe = e3x0_button_probe,
149 .remove = e3x0_button_remove,
150};
151
152module_platform_driver(e3x0_button_driver);
153
154MODULE_LICENSE("GPL v2");
155MODULE_AUTHOR("Moritz Fischer <moritz.fischer@ettus.com>");
156MODULE_DESCRIPTION("NI Ettus Research USRP E3x0 Button driver");
157MODULE_ALIAS("platform:e3x0-button");
diff --git a/drivers/input/misc/regulator-haptic.c b/drivers/input/misc/regulator-haptic.c
new file mode 100644
index 000000000000..132eb914ea3e
--- /dev/null
+++ b/drivers/input/misc/regulator-haptic.c
@@ -0,0 +1,266 @@
1/*
2 * Regulator haptic driver
3 *
4 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
5 * Author: Jaewon Kim <jaewon02.kim@samsung.com>
6 * Author: Hyunhee Kim <hyunhee.kim@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/input.h>
14#include <linux/module.h>
15#include <linux/of.h>
16#include <linux/platform_data/regulator-haptic.h>
17#include <linux/platform_device.h>
18#include <linux/regulator/consumer.h>
19#include <linux/slab.h>
20
21#define MAX_MAGNITUDE_SHIFT 16
22
23struct regulator_haptic {
24 struct device *dev;
25 struct input_dev *input_dev;
26 struct regulator *regulator;
27
28 struct work_struct work;
29 struct mutex mutex;
30
31 bool active;
32 bool suspended;
33
34 unsigned int max_volt;
35 unsigned int min_volt;
36 unsigned int magnitude;
37};
38
39static int regulator_haptic_toggle(struct regulator_haptic *haptic, bool on)
40{
41 int error;
42
43 if (haptic->active != on) {
44
45 error = on ? regulator_enable(haptic->regulator) :
46 regulator_disable(haptic->regulator);
47 if (error) {
48 dev_err(haptic->dev,
49 "failed to switch regulator %s: %d\n",
50 on ? "on" : "off", error);
51 return error;
52 }
53
54 haptic->active = on;
55 }
56
57 return 0;
58}
59
60static int regulator_haptic_set_voltage(struct regulator_haptic *haptic,
61 unsigned int magnitude)
62{
63 u64 volt_mag_multi;
64 unsigned int intensity;
65 int error;
66
67 volt_mag_multi = (u64)(haptic->max_volt - haptic->min_volt) * magnitude;
68 intensity = (unsigned int)(volt_mag_multi >> MAX_MAGNITUDE_SHIFT);
69
70 error = regulator_set_voltage(haptic->regulator,
71 intensity + haptic->min_volt,
72 haptic->max_volt);
73 if (error) {
74 dev_err(haptic->dev, "cannot set regulator voltage to %d: %d\n",
75 intensity + haptic->min_volt, error);
76 return error;
77 }
78
79 regulator_haptic_toggle(haptic, !!magnitude);
80
81 return 0;
82}
83
84static void regulator_haptic_work(struct work_struct *work)
85{
86 struct regulator_haptic *haptic = container_of(work,
87 struct regulator_haptic, work);
88
89 mutex_lock(&haptic->mutex);
90
91 if (!haptic->suspended)
92 regulator_haptic_set_voltage(haptic, haptic->magnitude);
93
94 mutex_unlock(&haptic->mutex);
95}
96
97static int regulator_haptic_play_effect(struct input_dev *input, void *data,
98 struct ff_effect *effect)
99{
100 struct regulator_haptic *haptic = input_get_drvdata(input);
101
102 haptic->magnitude = effect->u.rumble.strong_magnitude;
103 if (!haptic->magnitude)
104 haptic->magnitude = effect->u.rumble.weak_magnitude;
105
106 schedule_work(&haptic->work);
107
108 return 0;
109}
110
111static void regulator_haptic_close(struct input_dev *input)
112{
113 struct regulator_haptic *haptic = input_get_drvdata(input);
114
115 cancel_work_sync(&haptic->work);
116 regulator_haptic_set_voltage(haptic, 0);
117}
118
119static int __maybe_unused
120regulator_haptic_parse_dt(struct device *dev, struct regulator_haptic *haptic)
121{
122 struct device_node *node;
123 int error;
124
125 node = dev->of_node;
126 if(!node) {
127 dev_err(dev, "Missing dveice tree data\n");
128 return -EINVAL;
129 }
130
131 error = of_property_read_u32(node, "max-microvolt", &haptic->max_volt);
132 if (error) {
133 dev_err(dev, "cannot parse max-microvolt\n");
134 return error;
135 }
136
137 error = of_property_read_u32(node, "min-microvolt", &haptic->min_volt);
138 if (error) {
139 dev_err(dev, "cannot parse min-microvolt\n");
140 return error;
141 }
142
143 return 0;
144}
145
146static int regulator_haptic_probe(struct platform_device *pdev)
147{
148 const struct regulator_haptic_data *pdata = dev_get_platdata(&pdev->dev);
149 struct regulator_haptic *haptic;
150 struct input_dev *input_dev;
151 int error;
152
153 haptic = devm_kzalloc(&pdev->dev, sizeof(*haptic), GFP_KERNEL);
154 if (!haptic)
155 return -ENOMEM;
156
157 platform_set_drvdata(pdev, haptic);
158 haptic->dev = &pdev->dev;
159 mutex_init(&haptic->mutex);
160 INIT_WORK(&haptic->work, regulator_haptic_work);
161
162 if (pdata) {
163 haptic->max_volt = pdata->max_volt;
164 haptic->min_volt = pdata->min_volt;
165 } else if (IS_ENABLED(CONFIG_OF)) {
166 error = regulator_haptic_parse_dt(&pdev->dev, haptic);
167 if (error)
168 return error;
169 } else {
170 dev_err(&pdev->dev, "Missing platform data\n");
171 return -EINVAL;
172 }
173
174 haptic->regulator = devm_regulator_get_exclusive(&pdev->dev, "haptic");
175 if (IS_ERR(haptic->regulator)) {
176 dev_err(&pdev->dev, "failed to get regulator\n");
177 return PTR_ERR(haptic->regulator);
178 }
179
180 input_dev = devm_input_allocate_device(&pdev->dev);
181 if (!input_dev)
182 return -ENOMEM;
183
184 haptic->input_dev = input_dev;
185 haptic->input_dev->name = "regulator-haptic";
186 haptic->input_dev->dev.parent = &pdev->dev;
187 haptic->input_dev->close = regulator_haptic_close;
188 input_set_drvdata(haptic->input_dev, haptic);
189 input_set_capability(haptic->input_dev, EV_FF, FF_RUMBLE);
190
191 error = input_ff_create_memless(input_dev, NULL,
192 regulator_haptic_play_effect);
193 if (error) {
194 dev_err(&pdev->dev, "failed to create force-feedback\n");
195 return error;
196 }
197
198 error = input_register_device(haptic->input_dev);
199 if (error) {
200 dev_err(&pdev->dev, "failed to register input device\n");
201 return error;
202 }
203
204 return 0;
205}
206
207static int __maybe_unused regulator_haptic_suspend(struct device *dev)
208{
209 struct platform_device *pdev = to_platform_device(dev);
210 struct regulator_haptic *haptic = platform_get_drvdata(pdev);
211 int error;
212
213 error = mutex_lock_interruptible(&haptic->mutex);
214 if (error)
215 return error;
216
217 regulator_haptic_set_voltage(haptic, 0);
218
219 haptic->suspended = true;
220
221 mutex_unlock(&haptic->mutex);
222
223 return 0;
224}
225
226static int __maybe_unused regulator_haptic_resume(struct device *dev)
227{
228 struct platform_device *pdev = to_platform_device(dev);
229 struct regulator_haptic *haptic = platform_get_drvdata(pdev);
230 unsigned int magnitude;
231
232 mutex_lock(&haptic->mutex);
233
234 haptic->suspended = false;
235
236 magnitude = ACCESS_ONCE(haptic->magnitude);
237 if (magnitude)
238 regulator_haptic_set_voltage(haptic, magnitude);
239
240 mutex_unlock(&haptic->mutex);
241
242 return 0;
243}
244
245static SIMPLE_DEV_PM_OPS(regulator_haptic_pm_ops,
246 regulator_haptic_suspend, regulator_haptic_resume);
247
248static struct of_device_id regulator_haptic_dt_match[] = {
249 { .compatible = "regulator-haptic" },
250 { /* sentinel */ },
251};
252
253static struct platform_driver regulator_haptic_driver = {
254 .probe = regulator_haptic_probe,
255 .driver = {
256 .name = "regulator-haptic",
257 .of_match_table = regulator_haptic_dt_match,
258 .pm = &regulator_haptic_pm_ops,
259 },
260};
261module_platform_driver(regulator_haptic_driver);
262
263MODULE_AUTHOR("Jaewon Kim <jaewon02.kim@samsung.com>");
264MODULE_AUTHOR("Hyunhee Kim <hyunhee.kim@samsung.com>");
265MODULE_DESCRIPTION("Regulator haptic driver");
266MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/tps65218-pwrbutton.c b/drivers/input/misc/tps65218-pwrbutton.c
new file mode 100644
index 000000000000..54508dec4eb3
--- /dev/null
+++ b/drivers/input/misc/tps65218-pwrbutton.c
@@ -0,0 +1,126 @@
1/*
2 * Texas Instruments' TPS65218 Power Button Input Driver
3 *
4 * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
5 * Author: Felipe Balbi <balbi@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
12 * kind, whether express or implied; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/init.h>
18#include <linux/input.h>
19#include <linux/interrupt.h>
20#include <linux/kernel.h>
21#include <linux/mfd/tps65218.h>
22#include <linux/module.h>
23#include <linux/of.h>
24#include <linux/platform_device.h>
25#include <linux/slab.h>
26
27struct tps65218_pwrbutton {
28 struct device *dev;
29 struct tps65218 *tps;
30 struct input_dev *idev;
31};
32
33static irqreturn_t tps65218_pwr_irq(int irq, void *_pwr)
34{
35 struct tps65218_pwrbutton *pwr = _pwr;
36 unsigned int reg;
37 int error;
38
39 error = tps65218_reg_read(pwr->tps, TPS65218_REG_STATUS, &reg);
40 if (error) {
41 dev_err(pwr->dev, "can't read register: %d\n", error);
42 goto out;
43 }
44
45 if (reg & TPS65218_STATUS_PB_STATE) {
46 input_report_key(pwr->idev, KEY_POWER, 1);
47 pm_wakeup_event(pwr->dev, 0);
48 } else {
49 input_report_key(pwr->idev, KEY_POWER, 0);
50 }
51
52 input_sync(pwr->idev);
53
54out:
55 return IRQ_HANDLED;
56}
57
58static int tps65218_pwron_probe(struct platform_device *pdev)
59{
60 struct tps65218 *tps = dev_get_drvdata(pdev->dev.parent);
61 struct device *dev = &pdev->dev;
62 struct tps65218_pwrbutton *pwr;
63 struct input_dev *idev;
64 int error;
65 int irq;
66
67 pwr = devm_kzalloc(dev, sizeof(*pwr), GFP_KERNEL);
68 if (!pwr)
69 return -ENOMEM;
70
71 idev = devm_input_allocate_device(dev);
72 if (!idev)
73 return -ENOMEM;
74
75 idev->name = "tps65218_pwrbutton";
76 idev->phys = "tps65218_pwrbutton/input0";
77 idev->dev.parent = dev;
78 idev->id.bustype = BUS_I2C;
79
80 input_set_capability(idev, EV_KEY, KEY_POWER);
81
82 pwr->tps = tps;
83 pwr->dev = dev;
84 pwr->idev = idev;
85 platform_set_drvdata(pdev, pwr);
86 device_init_wakeup(dev, true);
87
88 irq = platform_get_irq(pdev, 0);
89 error = devm_request_threaded_irq(dev, irq, NULL, tps65218_pwr_irq,
90 IRQF_TRIGGER_RISING |
91 IRQF_TRIGGER_FALLING |
92 IRQF_ONESHOT,
93 "tps65218-pwrbutton", pwr);
94 if (error) {
95 dev_err(dev, "failed to request IRQ #%d: %d\n",
96 irq, error);
97 return error;
98 }
99
100 error= input_register_device(idev);
101 if (error) {
102 dev_err(dev, "Can't register power button: %d\n", error);
103 return error;
104 }
105
106 return 0;
107}
108
109static struct of_device_id of_tps65218_pwr_match[] = {
110 { .compatible = "ti,tps65218-pwrbutton" },
111 { },
112};
113MODULE_DEVICE_TABLE(of, of_tps65218_pwr_match);
114
115static struct platform_driver tps65218_pwron_driver = {
116 .probe = tps65218_pwron_probe,
117 .driver = {
118 .name = "tps65218_pwrbutton",
119 .of_match_table = of_tps65218_pwr_match,
120 },
121};
122module_platform_driver(tps65218_pwron_driver);
123
124MODULE_DESCRIPTION("TPS65218 Power Button");
125MODULE_LICENSE("GPL v2");
126MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
index d8b46b0f2dbe..4658b5d41dd7 100644
--- a/drivers/input/mouse/Kconfig
+++ b/drivers/input/mouse/Kconfig
@@ -105,19 +105,12 @@ config MOUSE_PS2_ELANTECH
105 Say Y here if you have an Elantech PS/2 touchpad connected 105 Say Y here if you have an Elantech PS/2 touchpad connected
106 to your system. 106 to your system.
107 107
108 Note that if you enable this driver you will need an updated
109 X.org Synaptics driver that does not require ABS_PRESSURE
110 reports from the touchpad (i.e. post 1.5.0 version). You can
111 grab a patch for the driver here:
112
113 http://userweb.kernel.org/~dtor/synaptics-no-abspressure.patch
114
115 If unsure, say N.
116
117 This driver exposes some configuration registers via sysfs 108 This driver exposes some configuration registers via sysfs
118 entries. For further information, 109 entries. For further information,
119 see <file:Documentation/input/elantech.txt>. 110 see <file:Documentation/input/elantech.txt>.
120 111
112 If unsure, say N.
113
121config MOUSE_PS2_SENTELIC 114config MOUSE_PS2_SENTELIC
122 bool "Sentelic Finger Sensing Pad PS/2 protocol extension" 115 bool "Sentelic Finger Sensing Pad PS/2 protocol extension"
123 depends on MOUSE_PS2 116 depends on MOUSE_PS2
@@ -146,6 +139,16 @@ config MOUSE_PS2_OLPC
146 139
147 If unsure, say N. 140 If unsure, say N.
148 141
142config MOUSE_PS2_FOCALTECH
143 bool "FocalTech PS/2 mouse protocol extension" if EXPERT
144 default y
145 depends on MOUSE_PS2
146 help
147 Say Y here if you have a FocalTech PS/2 TouchPad connected to
148 your system.
149
150 If unsure, say Y.
151
149config MOUSE_SERIAL 152config MOUSE_SERIAL
150 tristate "Serial mouse" 153 tristate "Serial mouse"
151 select SERIO 154 select SERIO
@@ -206,6 +209,7 @@ config MOUSE_BCM5974
206config MOUSE_CYAPA 209config MOUSE_CYAPA
207 tristate "Cypress APA I2C Trackpad support" 210 tristate "Cypress APA I2C Trackpad support"
208 depends on I2C 211 depends on I2C
212 select CRC_ITU_T
209 help 213 help
210 This driver adds support for Cypress All Points Addressable (APA) 214 This driver adds support for Cypress All Points Addressable (APA)
211 I2C Trackpads, including the ones used in 2012 Samsung Chromebooks. 215 I2C Trackpads, including the ones used in 2012 Samsung Chromebooks.
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
index 560003dcac37..8a9c98e76d9c 100644
--- a/drivers/input/mouse/Makefile
+++ b/drivers/input/mouse/Makefile
@@ -8,7 +8,7 @@ obj-$(CONFIG_MOUSE_AMIGA) += amimouse.o
8obj-$(CONFIG_MOUSE_APPLETOUCH) += appletouch.o 8obj-$(CONFIG_MOUSE_APPLETOUCH) += appletouch.o
9obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o 9obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o
10obj-$(CONFIG_MOUSE_BCM5974) += bcm5974.o 10obj-$(CONFIG_MOUSE_BCM5974) += bcm5974.o
11obj-$(CONFIG_MOUSE_CYAPA) += cyapa.o 11obj-$(CONFIG_MOUSE_CYAPA) += cyapatp.o
12obj-$(CONFIG_MOUSE_ELAN_I2C) += elan_i2c.o 12obj-$(CONFIG_MOUSE_ELAN_I2C) += elan_i2c.o
13obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o 13obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o
14obj-$(CONFIG_MOUSE_INPORT) += inport.o 14obj-$(CONFIG_MOUSE_INPORT) += inport.o
@@ -24,6 +24,7 @@ obj-$(CONFIG_MOUSE_SYNAPTICS_I2C) += synaptics_i2c.o
24obj-$(CONFIG_MOUSE_SYNAPTICS_USB) += synaptics_usb.o 24obj-$(CONFIG_MOUSE_SYNAPTICS_USB) += synaptics_usb.o
25obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o 25obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o
26 26
27cyapatp-objs := cyapa.o cyapa_gen3.o cyapa_gen5.o
27psmouse-objs := psmouse-base.o synaptics.o focaltech.o 28psmouse-objs := psmouse-base.o synaptics.o focaltech.o
28 29
29psmouse-$(CONFIG_MOUSE_PS2_ALPS) += alps.o 30psmouse-$(CONFIG_MOUSE_PS2_ALPS) += alps.o
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index d88d73d83552..f205b8be2ce4 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -435,7 +435,7 @@ static void alps_report_mt_data(struct psmouse *psmouse, int n)
435 struct alps_fields *f = &priv->f; 435 struct alps_fields *f = &priv->f;
436 int i, slot[MAX_TOUCHES]; 436 int i, slot[MAX_TOUCHES];
437 437
438 input_mt_assign_slots(dev, slot, f->mt, n); 438 input_mt_assign_slots(dev, slot, f->mt, n, 0);
439 for (i = 0; i < n; i++) 439 for (i = 0; i < n; i++)
440 alps_set_slot(dev, slot[i], f->mt[i].x, f->mt[i].y); 440 alps_set_slot(dev, slot[i], f->mt[i].x, f->mt[i].y);
441 441
@@ -475,6 +475,13 @@ static void alps_process_trackstick_packet_v3(struct psmouse *psmouse)
475 struct input_dev *dev = priv->dev2; 475 struct input_dev *dev = priv->dev2;
476 int x, y, z, left, right, middle; 476 int x, y, z, left, right, middle;
477 477
478 /* It should be a DualPoint when received trackstick packet */
479 if (!(priv->flags & ALPS_DUALPOINT)) {
480 psmouse_warn(psmouse,
481 "Rejected trackstick packet from non DualPoint device");
482 return;
483 }
484
478 /* Sanity check packet */ 485 /* Sanity check packet */
479 if (!(packet[0] & 0x40)) { 486 if (!(packet[0] & 0x40)) {
480 psmouse_dbg(psmouse, "Bad trackstick packet, discarding\n"); 487 psmouse_dbg(psmouse, "Bad trackstick packet, discarding\n");
@@ -699,7 +706,8 @@ static void alps_process_touchpad_packet_v3_v5(struct psmouse *psmouse)
699 706
700 alps_report_semi_mt_data(psmouse, fingers); 707 alps_report_semi_mt_data(psmouse, fingers);
701 708
702 if (!(priv->quirks & ALPS_QUIRK_TRACKSTICK_BUTTONS)) { 709 if ((priv->flags & ALPS_DUALPOINT) &&
710 !(priv->quirks & ALPS_QUIRK_TRACKSTICK_BUTTONS)) {
703 input_report_key(dev2, BTN_LEFT, f->ts_left); 711 input_report_key(dev2, BTN_LEFT, f->ts_left);
704 input_report_key(dev2, BTN_RIGHT, f->ts_right); 712 input_report_key(dev2, BTN_RIGHT, f->ts_right);
705 input_report_key(dev2, BTN_MIDDLE, f->ts_middle); 713 input_report_key(dev2, BTN_MIDDLE, f->ts_middle);
@@ -743,8 +751,11 @@ static void alps_process_packet_v6(struct psmouse *psmouse)
743 */ 751 */
744 if (packet[5] == 0x7F) { 752 if (packet[5] == 0x7F) {
745 /* It should be a DualPoint when received Trackpoint packet */ 753 /* It should be a DualPoint when received Trackpoint packet */
746 if (!(priv->flags & ALPS_DUALPOINT)) 754 if (!(priv->flags & ALPS_DUALPOINT)) {
755 psmouse_warn(psmouse,
756 "Rejected trackstick packet from non DualPoint device");
747 return; 757 return;
758 }
748 759
749 /* Trackpoint packet */ 760 /* Trackpoint packet */
750 x = packet[1] | ((packet[3] & 0x20) << 2); 761 x = packet[1] | ((packet[3] & 0x20) << 2);
@@ -1026,6 +1037,13 @@ static void alps_process_trackstick_packet_v7(struct psmouse *psmouse)
1026 struct input_dev *dev2 = priv->dev2; 1037 struct input_dev *dev2 = priv->dev2;
1027 int x, y, z, left, right, middle; 1038 int x, y, z, left, right, middle;
1028 1039
1040 /* It should be a DualPoint when received trackstick packet */
1041 if (!(priv->flags & ALPS_DUALPOINT)) {
1042 psmouse_warn(psmouse,
1043 "Rejected trackstick packet from non DualPoint device");
1044 return;
1045 }
1046
1029 /* 1047 /*
1030 * b7 b6 b5 b4 b3 b2 b1 b0 1048 * b7 b6 b5 b4 b3 b2 b1 b0
1031 * Byte0 0 1 0 0 1 0 0 0 1049 * Byte0 0 1 0 0 1 0 0 0
@@ -2443,14 +2461,24 @@ int alps_init(struct psmouse *psmouse)
2443 dev1->keybit[BIT_WORD(BTN_MIDDLE)] |= BIT_MASK(BTN_MIDDLE); 2461 dev1->keybit[BIT_WORD(BTN_MIDDLE)] |= BIT_MASK(BTN_MIDDLE);
2444 } 2462 }
2445 2463
2464 if (priv->flags & ALPS_DUALPOINT) {
2465 /*
2466 * format of input device name is: "protocol vendor name"
2467 * see function psmouse_switch_protocol() in psmouse-base.c
2468 */
2469 dev2->name = "AlpsPS/2 ALPS DualPoint Stick";
2470 dev2->id.product = PSMOUSE_ALPS;
2471 dev2->id.version = priv->proto_version;
2472 } else {
2473 dev2->name = "PS/2 ALPS Mouse";
2474 dev2->id.product = PSMOUSE_PS2;
2475 dev2->id.version = 0x0000;
2476 }
2477
2446 snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys); 2478 snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys);
2447 dev2->phys = priv->phys; 2479 dev2->phys = priv->phys;
2448 dev2->name = (priv->flags & ALPS_DUALPOINT) ?
2449 "DualPoint Stick" : "ALPS PS/2 Device";
2450 dev2->id.bustype = BUS_I8042; 2480 dev2->id.bustype = BUS_I8042;
2451 dev2->id.vendor = 0x0002; 2481 dev2->id.vendor = 0x0002;
2452 dev2->id.product = PSMOUSE_ALPS;
2453 dev2->id.version = 0x0000;
2454 dev2->dev.parent = &psmouse->ps2dev.serio->dev; 2482 dev2->dev.parent = &psmouse->ps2dev.serio->dev;
2455 2483
2456 dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); 2484 dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c
index c329cdb0b91a..b10709f04615 100644
--- a/drivers/input/mouse/bcm5974.c
+++ b/drivers/input/mouse/bcm5974.c
@@ -564,7 +564,7 @@ static int report_tp_state(struct bcm5974 *dev, int size)
564 dev->index[n++] = &f[i]; 564 dev->index[n++] = &f[i];
565 } 565 }
566 566
567 input_mt_assign_slots(input, dev->slots, dev->pos, n); 567 input_mt_assign_slots(input, dev->slots, dev->pos, n, 0);
568 568
569 for (i = 0; i < n; i++) 569 for (i = 0; i < n; i++)
570 report_finger_data(input, dev->slots[i], 570 report_finger_data(input, dev->slots[i],
diff --git a/drivers/input/mouse/cyapa.c b/drivers/input/mouse/cyapa.c
index 1bece8cad46f..58f4f6fa4857 100644
--- a/drivers/input/mouse/cyapa.c
+++ b/drivers/input/mouse/cyapa.c
@@ -20,408 +20,131 @@
20#include <linux/input/mt.h> 20#include <linux/input/mt.h>
21#include <linux/interrupt.h> 21#include <linux/interrupt.h>
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/mutex.h>
23#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/uaccess.h>
26#include <linux/pm_runtime.h>
27#include <linux/acpi.h>
28#include "cyapa.h"
24 29
25/* APA trackpad firmware generation */
26#define CYAPA_GEN3 0x03 /* support MT-protocol B with tracking ID. */
27
28#define CYAPA_NAME "Cypress APA Trackpad (cyapa)"
29
30/* commands for read/write registers of Cypress trackpad */
31#define CYAPA_CMD_SOFT_RESET 0x00
32#define CYAPA_CMD_POWER_MODE 0x01
33#define CYAPA_CMD_DEV_STATUS 0x02
34#define CYAPA_CMD_GROUP_DATA 0x03
35#define CYAPA_CMD_GROUP_CMD 0x04
36#define CYAPA_CMD_GROUP_QUERY 0x05
37#define CYAPA_CMD_BL_STATUS 0x06
38#define CYAPA_CMD_BL_HEAD 0x07
39#define CYAPA_CMD_BL_CMD 0x08
40#define CYAPA_CMD_BL_DATA 0x09
41#define CYAPA_CMD_BL_ALL 0x0a
42#define CYAPA_CMD_BLK_PRODUCT_ID 0x0b
43#define CYAPA_CMD_BLK_HEAD 0x0c
44
45/* report data start reg offset address. */
46#define DATA_REG_START_OFFSET 0x0000
47
48#define BL_HEAD_OFFSET 0x00
49#define BL_DATA_OFFSET 0x10
50
51/*
52 * Operational Device Status Register
53 *
54 * bit 7: Valid interrupt source
55 * bit 6 - 4: Reserved
56 * bit 3 - 2: Power status
57 * bit 1 - 0: Device status
58 */
59#define REG_OP_STATUS 0x00
60#define OP_STATUS_SRC 0x80
61#define OP_STATUS_POWER 0x0c
62#define OP_STATUS_DEV 0x03
63#define OP_STATUS_MASK (OP_STATUS_SRC | OP_STATUS_POWER | OP_STATUS_DEV)
64
65/*
66 * Operational Finger Count/Button Flags Register
67 *
68 * bit 7 - 4: Number of touched finger
69 * bit 3: Valid data
70 * bit 2: Middle Physical Button
71 * bit 1: Right Physical Button
72 * bit 0: Left physical Button
73 */
74#define REG_OP_DATA1 0x01
75#define OP_DATA_VALID 0x08
76#define OP_DATA_MIDDLE_BTN 0x04
77#define OP_DATA_RIGHT_BTN 0x02
78#define OP_DATA_LEFT_BTN 0x01
79#define OP_DATA_BTN_MASK (OP_DATA_MIDDLE_BTN | OP_DATA_RIGHT_BTN | \
80 OP_DATA_LEFT_BTN)
81
82/*
83 * Bootloader Status Register
84 *
85 * bit 7: Busy
86 * bit 6 - 5: Reserved
87 * bit 4: Bootloader running
88 * bit 3 - 1: Reserved
89 * bit 0: Checksum valid
90 */
91#define REG_BL_STATUS 0x01
92#define BL_STATUS_BUSY 0x80
93#define BL_STATUS_RUNNING 0x10
94#define BL_STATUS_DATA_VALID 0x08
95#define BL_STATUS_CSUM_VALID 0x01
96
97/*
98 * Bootloader Error Register
99 *
100 * bit 7: Invalid
101 * bit 6: Invalid security key
102 * bit 5: Bootloading
103 * bit 4: Command checksum
104 * bit 3: Flash protection error
105 * bit 2: Flash checksum error
106 * bit 1 - 0: Reserved
107 */
108#define REG_BL_ERROR 0x02
109#define BL_ERROR_INVALID 0x80
110#define BL_ERROR_INVALID_KEY 0x40
111#define BL_ERROR_BOOTLOADING 0x20
112#define BL_ERROR_CMD_CSUM 0x10
113#define BL_ERROR_FLASH_PROT 0x08
114#define BL_ERROR_FLASH_CSUM 0x04
115
116#define BL_STATUS_SIZE 3 /* length of bootloader status registers */
117#define BLK_HEAD_BYTES 32
118
119#define PRODUCT_ID_SIZE 16
120#define QUERY_DATA_SIZE 27
121#define REG_PROTOCOL_GEN_QUERY_OFFSET 20
122
123#define REG_OFFSET_DATA_BASE 0x0000
124#define REG_OFFSET_COMMAND_BASE 0x0028
125#define REG_OFFSET_QUERY_BASE 0x002a
126
127#define CAPABILITY_LEFT_BTN_MASK (0x01 << 3)
128#define CAPABILITY_RIGHT_BTN_MASK (0x01 << 4)
129#define CAPABILITY_MIDDLE_BTN_MASK (0x01 << 5)
130#define CAPABILITY_BTN_MASK (CAPABILITY_LEFT_BTN_MASK | \
131 CAPABILITY_RIGHT_BTN_MASK | \
132 CAPABILITY_MIDDLE_BTN_MASK)
133
134#define CYAPA_OFFSET_SOFT_RESET REG_OFFSET_COMMAND_BASE
135
136#define REG_OFFSET_POWER_MODE (REG_OFFSET_COMMAND_BASE + 1)
137
138#define PWR_MODE_MASK 0xfc
139#define PWR_MODE_FULL_ACTIVE (0x3f << 2)
140#define PWR_MODE_IDLE (0x05 << 2) /* default sleep time is 50 ms. */
141#define PWR_MODE_OFF (0x00 << 2)
142
143#define PWR_STATUS_MASK 0x0c
144#define PWR_STATUS_ACTIVE (0x03 << 2)
145#define PWR_STATUS_IDLE (0x02 << 2)
146#define PWR_STATUS_OFF (0x00 << 2)
147
148/*
149 * CYAPA trackpad device states.
150 * Used in register 0x00, bit1-0, DeviceStatus field.
151 * Other values indicate device is in an abnormal state and must be reset.
152 */
153#define CYAPA_DEV_NORMAL 0x03
154#define CYAPA_DEV_BUSY 0x01
155
156enum cyapa_state {
157 CYAPA_STATE_OP,
158 CYAPA_STATE_BL_IDLE,
159 CYAPA_STATE_BL_ACTIVE,
160 CYAPA_STATE_BL_BUSY,
161 CYAPA_STATE_NO_DEVICE,
162};
163
164
165struct cyapa_touch {
166 /*
167 * high bits or x/y position value
168 * bit 7 - 4: high 4 bits of x position value
169 * bit 3 - 0: high 4 bits of y position value
170 */
171 u8 xy_hi;
172 u8 x_lo; /* low 8 bits of x position value. */
173 u8 y_lo; /* low 8 bits of y position value. */
174 u8 pressure;
175 /* id range is 1 - 15. It is incremented with every new touch. */
176 u8 id;
177} __packed;
178
179/* The touch.id is used as the MT slot id, thus max MT slot is 15 */
180#define CYAPA_MAX_MT_SLOTS 15
181
182struct cyapa_reg_data {
183 /*
184 * bit 0 - 1: device status
185 * bit 3 - 2: power mode
186 * bit 6 - 4: reserved
187 * bit 7: interrupt valid bit
188 */
189 u8 device_status;
190 /*
191 * bit 7 - 4: number of fingers currently touching pad
192 * bit 3: valid data check bit
193 * bit 2: middle mechanism button state if exists
194 * bit 1: right mechanism button state if exists
195 * bit 0: left mechanism button state if exists
196 */
197 u8 finger_btn;
198 /* CYAPA reports up to 5 touches per packet. */
199 struct cyapa_touch touches[5];
200} __packed;
201
202/* The main device structure */
203struct cyapa {
204 enum cyapa_state state;
205
206 struct i2c_client *client;
207 struct input_dev *input;
208 char phys[32]; /* device physical location */
209 bool irq_wake; /* irq wake is enabled */
210 bool smbus;
211
212 /* read from query data region. */
213 char product_id[16];
214 u8 btn_capability;
215 u8 gen;
216 int max_abs_x;
217 int max_abs_y;
218 int physical_size_x;
219 int physical_size_y;
220};
221
222static const u8 bl_deactivate[] = { 0x00, 0xff, 0x3b, 0x00, 0x01, 0x02, 0x03,
223 0x04, 0x05, 0x06, 0x07 };
224static const u8 bl_exit[] = { 0x00, 0xff, 0xa5, 0x00, 0x01, 0x02, 0x03, 0x04,
225 0x05, 0x06, 0x07 };
226
227struct cyapa_cmd_len {
228 u8 cmd;
229 u8 len;
230};
231 30
232#define CYAPA_ADAPTER_FUNC_NONE 0 31#define CYAPA_ADAPTER_FUNC_NONE 0
233#define CYAPA_ADAPTER_FUNC_I2C 1 32#define CYAPA_ADAPTER_FUNC_I2C 1
234#define CYAPA_ADAPTER_FUNC_SMBUS 2 33#define CYAPA_ADAPTER_FUNC_SMBUS 2
235#define CYAPA_ADAPTER_FUNC_BOTH 3 34#define CYAPA_ADAPTER_FUNC_BOTH 3
236 35
237/* 36#define CYAPA_FW_NAME "cyapa.bin"
238 * macros for SMBus communication
239 */
240#define SMBUS_READ 0x01
241#define SMBUS_WRITE 0x00
242#define SMBUS_ENCODE_IDX(cmd, idx) ((cmd) | (((idx) & 0x03) << 1))
243#define SMBUS_ENCODE_RW(cmd, rw) ((cmd) | ((rw) & 0x01))
244#define SMBUS_BYTE_BLOCK_CMD_MASK 0x80
245#define SMBUS_GROUP_BLOCK_CMD_MASK 0x40
246
247 /* for byte read/write command */
248#define CMD_RESET 0
249#define CMD_POWER_MODE 1
250#define CMD_DEV_STATUS 2
251#define SMBUS_BYTE_CMD(cmd) (((cmd) & 0x3f) << 1)
252#define CYAPA_SMBUS_RESET SMBUS_BYTE_CMD(CMD_RESET)
253#define CYAPA_SMBUS_POWER_MODE SMBUS_BYTE_CMD(CMD_POWER_MODE)
254#define CYAPA_SMBUS_DEV_STATUS SMBUS_BYTE_CMD(CMD_DEV_STATUS)
255
256 /* for group registers read/write command */
257#define REG_GROUP_DATA 0
258#define REG_GROUP_CMD 2
259#define REG_GROUP_QUERY 3
260#define SMBUS_GROUP_CMD(grp) (0x80 | (((grp) & 0x07) << 3))
261#define CYAPA_SMBUS_GROUP_DATA SMBUS_GROUP_CMD(REG_GROUP_DATA)
262#define CYAPA_SMBUS_GROUP_CMD SMBUS_GROUP_CMD(REG_GROUP_CMD)
263#define CYAPA_SMBUS_GROUP_QUERY SMBUS_GROUP_CMD(REG_GROUP_QUERY)
264
265 /* for register block read/write command */
266#define CMD_BL_STATUS 0
267#define CMD_BL_HEAD 1
268#define CMD_BL_CMD 2
269#define CMD_BL_DATA 3
270#define CMD_BL_ALL 4
271#define CMD_BLK_PRODUCT_ID 5
272#define CMD_BLK_HEAD 6
273#define SMBUS_BLOCK_CMD(cmd) (0xc0 | (((cmd) & 0x1f) << 1))
274
275/* register block read/write command in bootloader mode */
276#define CYAPA_SMBUS_BL_STATUS SMBUS_BLOCK_CMD(CMD_BL_STATUS)
277#define CYAPA_SMBUS_BL_HEAD SMBUS_BLOCK_CMD(CMD_BL_HEAD)
278#define CYAPA_SMBUS_BL_CMD SMBUS_BLOCK_CMD(CMD_BL_CMD)
279#define CYAPA_SMBUS_BL_DATA SMBUS_BLOCK_CMD(CMD_BL_DATA)
280#define CYAPA_SMBUS_BL_ALL SMBUS_BLOCK_CMD(CMD_BL_ALL)
281
282/* register block read/write command in operational mode */
283#define CYAPA_SMBUS_BLK_PRODUCT_ID SMBUS_BLOCK_CMD(CMD_BLK_PRODUCT_ID)
284#define CYAPA_SMBUS_BLK_HEAD SMBUS_BLOCK_CMD(CMD_BLK_HEAD)
285
286static const struct cyapa_cmd_len cyapa_i2c_cmds[] = {
287 { CYAPA_OFFSET_SOFT_RESET, 1 },
288 { REG_OFFSET_COMMAND_BASE + 1, 1 },
289 { REG_OFFSET_DATA_BASE, 1 },
290 { REG_OFFSET_DATA_BASE, sizeof(struct cyapa_reg_data) },
291 { REG_OFFSET_COMMAND_BASE, 0 },
292 { REG_OFFSET_QUERY_BASE, QUERY_DATA_SIZE },
293 { BL_HEAD_OFFSET, 3 },
294 { BL_HEAD_OFFSET, 16 },
295 { BL_HEAD_OFFSET, 16 },
296 { BL_DATA_OFFSET, 16 },
297 { BL_HEAD_OFFSET, 32 },
298 { REG_OFFSET_QUERY_BASE, PRODUCT_ID_SIZE },
299 { REG_OFFSET_DATA_BASE, 32 }
300};
301 37
302static const struct cyapa_cmd_len cyapa_smbus_cmds[] = { 38const char product_id[] = "CYTRA";
303 { CYAPA_SMBUS_RESET, 1 },
304 { CYAPA_SMBUS_POWER_MODE, 1 },
305 { CYAPA_SMBUS_DEV_STATUS, 1 },
306 { CYAPA_SMBUS_GROUP_DATA, sizeof(struct cyapa_reg_data) },
307 { CYAPA_SMBUS_GROUP_CMD, 2 },
308 { CYAPA_SMBUS_GROUP_QUERY, QUERY_DATA_SIZE },
309 { CYAPA_SMBUS_BL_STATUS, 3 },
310 { CYAPA_SMBUS_BL_HEAD, 16 },
311 { CYAPA_SMBUS_BL_CMD, 16 },
312 { CYAPA_SMBUS_BL_DATA, 16 },
313 { CYAPA_SMBUS_BL_ALL, 32 },
314 { CYAPA_SMBUS_BLK_PRODUCT_ID, PRODUCT_ID_SIZE },
315 { CYAPA_SMBUS_BLK_HEAD, 16 },
316};
317 39
318static ssize_t cyapa_i2c_reg_read_block(struct cyapa *cyapa, u8 reg, size_t len, 40static int cyapa_reinitialize(struct cyapa *cyapa);
319 u8 *values) 41
42static inline bool cyapa_is_bootloader_mode(struct cyapa *cyapa)
320{ 43{
321 return i2c_smbus_read_i2c_block_data(cyapa->client, reg, len, values); 44 if (cyapa->gen == CYAPA_GEN5 && cyapa->state == CYAPA_STATE_GEN5_BL)
45 return true;
46
47 if (cyapa->gen == CYAPA_GEN3 &&
48 cyapa->state >= CYAPA_STATE_BL_BUSY &&
49 cyapa->state <= CYAPA_STATE_BL_ACTIVE)
50 return true;
51
52 return false;
322} 53}
323 54
324static ssize_t cyapa_i2c_reg_write_block(struct cyapa *cyapa, u8 reg, 55static inline bool cyapa_is_operational_mode(struct cyapa *cyapa)
325 size_t len, const u8 *values)
326{ 56{
327 return i2c_smbus_write_i2c_block_data(cyapa->client, reg, len, values); 57 if (cyapa->gen == CYAPA_GEN5 && cyapa->state == CYAPA_STATE_GEN5_APP)
58 return true;
59
60 if (cyapa->gen == CYAPA_GEN3 && cyapa->state == CYAPA_STATE_OP)
61 return true;
62
63 return false;
328} 64}
329 65
330/* 66/* Returns 0 on success, else negative errno on failure. */
331 * cyapa_smbus_read_block - perform smbus block read command 67static ssize_t cyapa_i2c_read(struct cyapa *cyapa, u8 reg, size_t len,
332 * @cyapa - private data structure of the driver 68 u8 *values)
333 * @cmd - the properly encoded smbus command
334 * @len - expected length of smbus command result
335 * @values - buffer to store smbus command result
336 *
337 * Returns negative errno, else the number of bytes written.
338 *
339 * Note:
340 * In trackpad device, the memory block allocated for I2C register map
341 * is 256 bytes, so the max read block for I2C bus is 256 bytes.
342 */
343static ssize_t cyapa_smbus_read_block(struct cyapa *cyapa, u8 cmd, size_t len,
344 u8 *values)
345{ 69{
346 ssize_t ret;
347 u8 index;
348 u8 smbus_cmd;
349 u8 *buf;
350 struct i2c_client *client = cyapa->client; 70 struct i2c_client *client = cyapa->client;
71 struct i2c_msg msgs[] = {
72 {
73 .addr = client->addr,
74 .flags = 0,
75 .len = 1,
76 .buf = &reg,
77 },
78 {
79 .addr = client->addr,
80 .flags = I2C_M_RD,
81 .len = len,
82 .buf = values,
83 },
84 };
85 int ret;
351 86
352 if (!(SMBUS_BYTE_BLOCK_CMD_MASK & cmd)) 87 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
353 return -EINVAL;
354
355 if (SMBUS_GROUP_BLOCK_CMD_MASK & cmd) {
356 /* read specific block registers command. */
357 smbus_cmd = SMBUS_ENCODE_RW(cmd, SMBUS_READ);
358 ret = i2c_smbus_read_block_data(client, smbus_cmd, values);
359 goto out;
360 }
361 88
362 ret = 0; 89 if (ret != ARRAY_SIZE(msgs))
363 for (index = 0; index * I2C_SMBUS_BLOCK_MAX < len; index++) { 90 return ret < 0 ? ret : -EIO;
364 smbus_cmd = SMBUS_ENCODE_IDX(cmd, index);
365 smbus_cmd = SMBUS_ENCODE_RW(smbus_cmd, SMBUS_READ);
366 buf = values + I2C_SMBUS_BLOCK_MAX * index;
367 ret = i2c_smbus_read_block_data(client, smbus_cmd, buf);
368 if (ret < 0)
369 goto out;
370 }
371 91
372out: 92 return 0;
373 return ret > 0 ? len : ret;
374} 93}
375 94
376static s32 cyapa_read_byte(struct cyapa *cyapa, u8 cmd_idx) 95/**
96 * cyapa_i2c_write - Execute i2c block data write operation
97 * @cyapa: Handle to this driver
98 * @ret: Offset of the data to written in the register map
99 * @len: number of bytes to write
100 * @values: Data to be written
101 *
102 * Return negative errno code on error; return zero when success.
103 */
104static int cyapa_i2c_write(struct cyapa *cyapa, u8 reg,
105 size_t len, const void *values)
377{ 106{
378 u8 cmd; 107 struct i2c_client *client = cyapa->client;
108 char buf[32];
109 int ret;
379 110
380 if (cyapa->smbus) { 111 if (len > sizeof(buf) - 1)
381 cmd = cyapa_smbus_cmds[cmd_idx].cmd; 112 return -ENOMEM;
382 cmd = SMBUS_ENCODE_RW(cmd, SMBUS_READ);
383 } else {
384 cmd = cyapa_i2c_cmds[cmd_idx].cmd;
385 }
386 return i2c_smbus_read_byte_data(cyapa->client, cmd);
387}
388 113
389static s32 cyapa_write_byte(struct cyapa *cyapa, u8 cmd_idx, u8 value) 114 buf[0] = reg;
390{ 115 memcpy(&buf[1], values, len);
391 u8 cmd;
392 116
393 if (cyapa->smbus) { 117 ret = i2c_master_send(client, buf, len + 1);
394 cmd = cyapa_smbus_cmds[cmd_idx].cmd; 118 if (ret != len + 1)
395 cmd = SMBUS_ENCODE_RW(cmd, SMBUS_WRITE); 119 return ret < 0 ? ret : -EIO;
396 } else { 120
397 cmd = cyapa_i2c_cmds[cmd_idx].cmd; 121 return 0;
398 }
399 return i2c_smbus_write_byte_data(cyapa->client, cmd, value);
400} 122}
401 123
402static ssize_t cyapa_read_block(struct cyapa *cyapa, u8 cmd_idx, u8 *values) 124static u8 cyapa_check_adapter_functionality(struct i2c_client *client)
403{ 125{
404 u8 cmd; 126 u8 ret = CYAPA_ADAPTER_FUNC_NONE;
405 size_t len;
406 127
407 if (cyapa->smbus) { 128 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
408 cmd = cyapa_smbus_cmds[cmd_idx].cmd; 129 ret |= CYAPA_ADAPTER_FUNC_I2C;
409 len = cyapa_smbus_cmds[cmd_idx].len; 130 if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
410 return cyapa_smbus_read_block(cyapa, cmd, len, values); 131 I2C_FUNC_SMBUS_BLOCK_DATA |
411 } else { 132 I2C_FUNC_SMBUS_I2C_BLOCK))
412 cmd = cyapa_i2c_cmds[cmd_idx].cmd; 133 ret |= CYAPA_ADAPTER_FUNC_SMBUS;
413 len = cyapa_i2c_cmds[cmd_idx].len; 134 return ret;
414 return cyapa_i2c_reg_read_block(cyapa, cmd, len, values);
415 }
416} 135}
417 136
418/* 137/*
419 * Query device for its current operating state. 138 * Query device for its current operating state.
420 *
421 */ 139 */
422static int cyapa_get_state(struct cyapa *cyapa) 140static int cyapa_get_state(struct cyapa *cyapa)
423{ 141{
424 u8 status[BL_STATUS_SIZE]; 142 u8 status[BL_STATUS_SIZE];
143 u8 cmd[32];
144 /* The i2c address of gen4 and gen5 trackpad device must be even. */
145 bool even_addr = ((cyapa->client->addr & 0x0001) == 0);
146 bool smbus = false;
147 int retries = 2;
425 int error; 148 int error;
426 149
427 cyapa->state = CYAPA_STATE_NO_DEVICE; 150 cyapa->state = CYAPA_STATE_NO_DEVICE;
@@ -433,39 +156,74 @@ static int cyapa_get_state(struct cyapa *cyapa)
433 * 156 *
434 */ 157 */
435 error = cyapa_i2c_reg_read_block(cyapa, BL_HEAD_OFFSET, BL_STATUS_SIZE, 158 error = cyapa_i2c_reg_read_block(cyapa, BL_HEAD_OFFSET, BL_STATUS_SIZE,
436 status); 159 status);
437 160
438 /* 161 /*
439 * On smbus systems in OP mode, the i2c_reg_read will fail with 162 * On smbus systems in OP mode, the i2c_reg_read will fail with
440 * -ETIMEDOUT. In this case, try again using the smbus equivalent 163 * -ETIMEDOUT. In this case, try again using the smbus equivalent
441 * command. This should return a BL_HEAD indicating CYAPA_STATE_OP. 164 * command. This should return a BL_HEAD indicating CYAPA_STATE_OP.
442 */ 165 */
443 if (cyapa->smbus && (error == -ETIMEDOUT || error == -ENXIO)) 166 if (cyapa->smbus && (error == -ETIMEDOUT || error == -ENXIO)) {
444 error = cyapa_read_block(cyapa, CYAPA_CMD_BL_STATUS, status); 167 if (!even_addr)
168 error = cyapa_read_block(cyapa,
169 CYAPA_CMD_BL_STATUS, status);
170 smbus = true;
171 }
445 172
446 if (error != BL_STATUS_SIZE) 173 if (error != BL_STATUS_SIZE)
447 goto error; 174 goto error;
448 175
449 if ((status[REG_OP_STATUS] & OP_STATUS_SRC) == OP_STATUS_SRC) { 176 /*
450 switch (status[REG_OP_STATUS] & OP_STATUS_DEV) { 177 * Detect trackpad protocol based on characteristic registers and bits.
451 case CYAPA_DEV_NORMAL: 178 */
452 case CYAPA_DEV_BUSY: 179 do {
453 cyapa->state = CYAPA_STATE_OP; 180 cyapa->status[REG_OP_STATUS] = status[REG_OP_STATUS];
454 break; 181 cyapa->status[REG_BL_STATUS] = status[REG_BL_STATUS];
455 default: 182 cyapa->status[REG_BL_ERROR] = status[REG_BL_ERROR];
456 error = -EAGAIN; 183
457 goto error; 184 if (cyapa->gen == CYAPA_GEN_UNKNOWN ||
185 cyapa->gen == CYAPA_GEN3) {
186 error = cyapa_gen3_ops.state_parse(cyapa,
187 status, BL_STATUS_SIZE);
188 if (!error)
189 goto out_detected;
458 } 190 }
459 } else { 191 if ((cyapa->gen == CYAPA_GEN_UNKNOWN ||
460 if (status[REG_BL_STATUS] & BL_STATUS_BUSY) 192 cyapa->gen == CYAPA_GEN5) &&
461 cyapa->state = CYAPA_STATE_BL_BUSY; 193 !smbus && even_addr) {
462 else if (status[REG_BL_ERROR] & BL_ERROR_BOOTLOADING) 194 error = cyapa_gen5_ops.state_parse(cyapa,
463 cyapa->state = CYAPA_STATE_BL_ACTIVE; 195 status, BL_STATUS_SIZE);
464 else 196 if (!error)
465 cyapa->state = CYAPA_STATE_BL_IDLE; 197 goto out_detected;
466 } 198 }
199
200 /*
201 * Write 0x00 0x00 to trackpad device to force update its
202 * status, then redo the detection again.
203 */
204 if (!smbus) {
205 cmd[0] = 0x00;
206 cmd[1] = 0x00;
207 error = cyapa_i2c_write(cyapa, 0, 2, cmd);
208 if (error)
209 goto error;
210
211 msleep(50);
212
213 error = cyapa_i2c_read(cyapa, BL_HEAD_OFFSET,
214 BL_STATUS_SIZE, status);
215 if (error)
216 goto error;
217 }
218 } while (--retries > 0 && !smbus);
219
220 goto error;
467 221
222out_detected:
223 if (cyapa->state <= CYAPA_STATE_BL_BUSY)
224 return -EAGAIN;
468 return 0; 225 return 0;
226
469error: 227error:
470 return (error < 0) ? error : -EAGAIN; 228 return (error < 0) ? error : -EAGAIN;
471} 229}
@@ -482,364 +240,939 @@ error:
482 * Returns: 240 * Returns:
483 * 0 when the device eventually responds with a valid non-busy state. 241 * 0 when the device eventually responds with a valid non-busy state.
484 * -ETIMEDOUT if device never responds (too many -EAGAIN) 242 * -ETIMEDOUT if device never responds (too many -EAGAIN)
485 * < 0 other errors 243 * -EAGAIN if bootload is busy, or unknown state.
244 * < 0 other errors
486 */ 245 */
487static int cyapa_poll_state(struct cyapa *cyapa, unsigned int timeout) 246int cyapa_poll_state(struct cyapa *cyapa, unsigned int timeout)
488{ 247{
489 int error; 248 int error;
490 int tries = timeout / 100; 249 int tries = timeout / 100;
491 250
492 error = cyapa_get_state(cyapa); 251 do {
493 while ((error || cyapa->state >= CYAPA_STATE_BL_BUSY) && tries--) {
494 msleep(100);
495 error = cyapa_get_state(cyapa); 252 error = cyapa_get_state(cyapa);
496 } 253 if (!error && cyapa->state > CYAPA_STATE_BL_BUSY)
497 return (error == -EAGAIN || error == -ETIMEDOUT) ? -ETIMEDOUT : error; 254 return 0;
498}
499 255
500static int cyapa_bl_deactivate(struct cyapa *cyapa) 256 msleep(100);
501{ 257 } while (tries--);
502 int error;
503
504 error = cyapa_i2c_reg_write_block(cyapa, 0, sizeof(bl_deactivate),
505 bl_deactivate);
506 if (error)
507 return error;
508 258
509 /* wait for bootloader to switch to idle state; should take < 100ms */ 259 return (error == -EAGAIN || error == -ETIMEDOUT) ? -ETIMEDOUT : error;
510 msleep(100);
511 error = cyapa_poll_state(cyapa, 500);
512 if (error)
513 return error;
514 if (cyapa->state != CYAPA_STATE_BL_IDLE)
515 return -EAGAIN;
516 return 0;
517} 260}
518 261
519/* 262/*
520 * Exit bootloader 263 * Check if device is operational.
521 * 264 *
522 * Send bl_exit command, then wait 50 - 100 ms to let device transition to 265 * An operational device is responding, has exited bootloader, and has
523 * operational mode. If this is the first time the device's firmware is 266 * firmware supported by this driver.
524 * running, it can take up to 2 seconds to calibrate its sensors. So, poll
525 * the device's new state for up to 2 seconds.
526 * 267 *
527 * Returns: 268 * Returns:
269 * -ENODEV no device
270 * -EBUSY no device or in bootloader
528 * -EIO failure while reading from device 271 * -EIO failure while reading from device
529 * -EAGAIN device is stuck in bootloader, b/c it has invalid firmware 272 * -ETIMEDOUT timeout failure for bus idle or bus no response
530 * 0 device is supported and in operational mode 273 * -EAGAIN device is still in bootloader
274 * if ->state = CYAPA_STATE_BL_IDLE, device has invalid firmware
275 * -EINVAL device is in operational mode, but not supported by this driver
276 * 0 device is supported
531 */ 277 */
532static int cyapa_bl_exit(struct cyapa *cyapa) 278static int cyapa_check_is_operational(struct cyapa *cyapa)
533{ 279{
534 int error; 280 int error;
535 281
536 error = cyapa_i2c_reg_write_block(cyapa, 0, sizeof(bl_exit), bl_exit); 282 error = cyapa_poll_state(cyapa, 4000);
537 if (error) 283 if (error)
538 return error; 284 return error;
539 285
540 /* 286 switch (cyapa->gen) {
541 * Wait for bootloader to exit, and operation mode to start. 287 case CYAPA_GEN5:
542 * Normally, this takes at least 50 ms. 288 cyapa->ops = &cyapa_gen5_ops;
543 */ 289 break;
544 usleep_range(50000, 100000); 290 case CYAPA_GEN3:
545 /* 291 cyapa->ops = &cyapa_gen3_ops;
546 * In addition, when a device boots for the first time after being 292 break;
547 * updated to new firmware, it must first calibrate its sensors, which 293 default:
548 * can take up to an additional 2 seconds. 294 return -ENODEV;
549 */ 295 }
550 error = cyapa_poll_state(cyapa, 2000);
551 if (error < 0)
552 return error;
553 if (cyapa->state != CYAPA_STATE_OP)
554 return -EAGAIN;
555 296
556 return 0; 297 error = cyapa->ops->operational_check(cyapa);
298 if (!error && cyapa_is_operational_mode(cyapa))
299 cyapa->operational = true;
300 else
301 cyapa->operational = false;
302
303 return error;
557} 304}
558 305
306
559/* 307/*
560 * Set device power mode 308 * Returns 0 on device detected, negative errno on no device detected.
561 * 309 * And when the device is detected and opertaional, it will be reset to
310 * full power active mode automatically.
562 */ 311 */
563static int cyapa_set_power_mode(struct cyapa *cyapa, u8 power_mode) 312static int cyapa_detect(struct cyapa *cyapa)
564{ 313{
565 struct device *dev = &cyapa->client->dev; 314 struct device *dev = &cyapa->client->dev;
566 int ret; 315 int error;
567 u8 power;
568
569 if (cyapa->state != CYAPA_STATE_OP)
570 return 0;
571 316
572 ret = cyapa_read_byte(cyapa, CYAPA_CMD_POWER_MODE); 317 error = cyapa_check_is_operational(cyapa);
573 if (ret < 0) 318 if (error) {
574 return ret; 319 if (error != -ETIMEDOUT && error != -ENODEV &&
320 cyapa_is_bootloader_mode(cyapa)) {
321 dev_warn(dev, "device detected but not operational\n");
322 return 0;
323 }
575 324
576 power = ret & ~PWR_MODE_MASK; 325 dev_err(dev, "no device detected: %d\n", error);
577 power |= power_mode & PWR_MODE_MASK; 326 return error;
578 ret = cyapa_write_byte(cyapa, CYAPA_CMD_POWER_MODE, power);
579 if (ret < 0) {
580 dev_err(dev, "failed to set power_mode 0x%02x err = %d\n",
581 power_mode, ret);
582 return ret;
583 } 327 }
584 328
585 return 0; 329 return 0;
586} 330}
587 331
588static int cyapa_get_query_data(struct cyapa *cyapa) 332static int cyapa_open(struct input_dev *input)
589{ 333{
590 u8 query_data[QUERY_DATA_SIZE]; 334 struct cyapa *cyapa = input_get_drvdata(input);
591 int ret; 335 struct i2c_client *client = cyapa->client;
336 int error;
592 337
593 if (cyapa->state != CYAPA_STATE_OP) 338 error = mutex_lock_interruptible(&cyapa->state_sync_lock);
594 return -EBUSY; 339 if (error)
340 return error;
595 341
596 ret = cyapa_read_block(cyapa, CYAPA_CMD_GROUP_QUERY, query_data); 342 if (cyapa->operational) {
597 if (ret < 0) 343 /*
598 return ret; 344 * though failed to set active power mode,
599 if (ret != QUERY_DATA_SIZE) 345 * but still may be able to work in lower scan rate
600 return -EIO; 346 * when in operational mode.
347 */
348 error = cyapa->ops->set_power_mode(cyapa,
349 PWR_MODE_FULL_ACTIVE, 0);
350 if (error) {
351 dev_warn(&client->dev,
352 "set active power failed: %d\n", error);
353 goto out;
354 }
355 } else {
356 error = cyapa_reinitialize(cyapa);
357 if (error || !cyapa->operational) {
358 error = error ? error : -EAGAIN;
359 goto out;
360 }
361 }
362
363 enable_irq(client->irq);
364 if (!pm_runtime_enabled(&client->dev)) {
365 pm_runtime_set_active(&client->dev);
366 pm_runtime_enable(&client->dev);
367 }
368out:
369 mutex_unlock(&cyapa->state_sync_lock);
370 return error;
371}
372
373static void cyapa_close(struct input_dev *input)
374{
375 struct cyapa *cyapa = input_get_drvdata(input);
376 struct i2c_client *client = cyapa->client;
377
378 mutex_lock(&cyapa->state_sync_lock);
379
380 disable_irq(client->irq);
381 if (pm_runtime_enabled(&client->dev))
382 pm_runtime_disable(&client->dev);
383 pm_runtime_set_suspended(&client->dev);
384
385 if (cyapa->operational)
386 cyapa->ops->set_power_mode(cyapa, PWR_MODE_OFF, 0);
601 387
602 memcpy(&cyapa->product_id[0], &query_data[0], 5); 388 mutex_unlock(&cyapa->state_sync_lock);
603 cyapa->product_id[5] = '-'; 389}
604 memcpy(&cyapa->product_id[6], &query_data[5], 6);
605 cyapa->product_id[12] = '-';
606 memcpy(&cyapa->product_id[13], &query_data[11], 2);
607 cyapa->product_id[15] = '\0';
608 390
609 cyapa->btn_capability = query_data[19] & CAPABILITY_BTN_MASK; 391static int cyapa_create_input_dev(struct cyapa *cyapa)
392{
393 struct device *dev = &cyapa->client->dev;
394 struct input_dev *input;
395 int error;
610 396
611 cyapa->gen = query_data[20] & 0x0f; 397 if (!cyapa->physical_size_x || !cyapa->physical_size_y)
398 return -EINVAL;
612 399
613 cyapa->max_abs_x = ((query_data[21] & 0xf0) << 4) | query_data[22]; 400 input = devm_input_allocate_device(dev);
614 cyapa->max_abs_y = ((query_data[21] & 0x0f) << 8) | query_data[23]; 401 if (!input) {
402 dev_err(dev, "failed to allocate memory for input device.\n");
403 return -ENOMEM;
404 }
405
406 input->name = CYAPA_NAME;
407 input->phys = cyapa->phys;
408 input->id.bustype = BUS_I2C;
409 input->id.version = 1;
410 input->id.product = 0; /* Means any product in eventcomm. */
411 input->dev.parent = &cyapa->client->dev;
412
413 input->open = cyapa_open;
414 input->close = cyapa_close;
415
416 input_set_drvdata(input, cyapa);
417
418 __set_bit(EV_ABS, input->evbit);
419
420 /* Finger position */
421 input_set_abs_params(input, ABS_MT_POSITION_X, 0, cyapa->max_abs_x, 0,
422 0);
423 input_set_abs_params(input, ABS_MT_POSITION_Y, 0, cyapa->max_abs_y, 0,
424 0);
425 input_set_abs_params(input, ABS_MT_PRESSURE, 0, cyapa->max_z, 0, 0);
426 if (cyapa->gen > CYAPA_GEN3) {
427 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
428 input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0);
429 /*
430 * Orientation is the angle between the vertical axis and
431 * the major axis of the contact ellipse.
432 * The range is -127 to 127.
433 * the positive direction is clockwise form the vertical axis.
434 * If the ellipse of contact degenerates into a circle,
435 * orientation is reported as 0.
436 *
437 * Also, for Gen5 trackpad the accurate of this orientation
438 * value is value + (-30 ~ 30).
439 */
440 input_set_abs_params(input, ABS_MT_ORIENTATION,
441 -127, 127, 0, 0);
442 }
443 if (cyapa->gen >= CYAPA_GEN5) {
444 input_set_abs_params(input, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
445 input_set_abs_params(input, ABS_MT_WIDTH_MINOR, 0, 255, 0, 0);
446 }
447
448 input_abs_set_res(input, ABS_MT_POSITION_X,
449 cyapa->max_abs_x / cyapa->physical_size_x);
450 input_abs_set_res(input, ABS_MT_POSITION_Y,
451 cyapa->max_abs_y / cyapa->physical_size_y);
452
453 if (cyapa->btn_capability & CAPABILITY_LEFT_BTN_MASK)
454 __set_bit(BTN_LEFT, input->keybit);
455 if (cyapa->btn_capability & CAPABILITY_MIDDLE_BTN_MASK)
456 __set_bit(BTN_MIDDLE, input->keybit);
457 if (cyapa->btn_capability & CAPABILITY_RIGHT_BTN_MASK)
458 __set_bit(BTN_RIGHT, input->keybit);
459
460 if (cyapa->btn_capability == CAPABILITY_LEFT_BTN_MASK)
461 __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
462
463 /* Handle pointer emulation and unused slots in core */
464 error = input_mt_init_slots(input, CYAPA_MAX_MT_SLOTS,
465 INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED);
466 if (error) {
467 dev_err(dev, "failed to initialize MT slots: %d\n", error);
468 return error;
469 }
615 470
616 cyapa->physical_size_x = 471 /* Register the device in input subsystem */
617 ((query_data[24] & 0xf0) << 4) | query_data[25]; 472 error = input_register_device(input);
618 cyapa->physical_size_y = 473 if (error) {
619 ((query_data[24] & 0x0f) << 8) | query_data[26]; 474 dev_err(dev, "failed to register input device: %d\n", error);
475 return error;
476 }
620 477
478 cyapa->input = input;
621 return 0; 479 return 0;
622} 480}
623 481
482static void cyapa_enable_irq_for_cmd(struct cyapa *cyapa)
483{
484 struct input_dev *input = cyapa->input;
485
486 if (!input || !input->users) {
487 /*
488 * When input is NULL, TP must be in deep sleep mode.
489 * In this mode, later non-power I2C command will always failed
490 * if not bring it out of deep sleep mode firstly,
491 * so must command TP to active mode here.
492 */
493 if (!input || cyapa->operational)
494 cyapa->ops->set_power_mode(cyapa,
495 PWR_MODE_FULL_ACTIVE, 0);
496 /* Gen3 always using polling mode for command. */
497 if (cyapa->gen >= CYAPA_GEN5)
498 enable_irq(cyapa->client->irq);
499 }
500}
501
502static void cyapa_disable_irq_for_cmd(struct cyapa *cyapa)
503{
504 struct input_dev *input = cyapa->input;
505
506 if (!input || !input->users) {
507 if (cyapa->gen >= CYAPA_GEN5)
508 disable_irq(cyapa->client->irq);
509 if (!input || cyapa->operational)
510 cyapa->ops->set_power_mode(cyapa, PWR_MODE_OFF, 0);
511 }
512}
513
624/* 514/*
625 * Check if device is operational. 515 * cyapa_sleep_time_to_pwr_cmd and cyapa_pwr_cmd_to_sleep_time
626 * 516 *
627 * An operational device is responding, has exited bootloader, and has 517 * These are helper functions that convert to and from integer idle
628 * firmware supported by this driver. 518 * times and register settings to write to the PowerMode register.
519 * The trackpad supports between 20ms to 1000ms scan intervals.
520 * The time will be increased in increments of 10ms from 20ms to 100ms.
521 * From 100ms to 1000ms, time will be increased in increments of 20ms.
629 * 522 *
630 * Returns: 523 * When Idle_Time < 100, the format to convert Idle_Time to Idle_Command is:
631 * -EBUSY no device or in bootloader 524 * Idle_Command = Idle Time / 10;
632 * -EIO failure while reading from device 525 * When Idle_Time >= 100, the format to convert Idle_Time to Idle_Command is:
633 * -EAGAIN device is still in bootloader 526 * Idle_Command = Idle Time / 20 + 5;
634 * if ->state = CYAPA_STATE_BL_IDLE, device has invalid firmware
635 * -EINVAL device is in operational mode, but not supported by this driver
636 * 0 device is supported
637 */ 527 */
638static int cyapa_check_is_operational(struct cyapa *cyapa) 528u8 cyapa_sleep_time_to_pwr_cmd(u16 sleep_time)
639{ 529{
640 struct device *dev = &cyapa->client->dev; 530 u16 encoded_time;
641 static const char unique_str[] = "CYTRA";
642 int error;
643 531
644 error = cyapa_poll_state(cyapa, 2000); 532 sleep_time = clamp_val(sleep_time, 20, 1000);
533 encoded_time = sleep_time < 100 ? sleep_time / 10 : sleep_time / 20 + 5;
534 return (encoded_time << 2) & PWR_MODE_MASK;
535}
536
537u16 cyapa_pwr_cmd_to_sleep_time(u8 pwr_mode)
538{
539 u8 encoded_time = pwr_mode >> 2;
540
541 return (encoded_time < 10) ? encoded_time * 10
542 : (encoded_time - 5) * 20;
543}
544
545/* 0 on driver initialize and detected successfully, negative on failure. */
546static int cyapa_initialize(struct cyapa *cyapa)
547{
548 int error = 0;
549
550 cyapa->state = CYAPA_STATE_NO_DEVICE;
551 cyapa->gen = CYAPA_GEN_UNKNOWN;
552 mutex_init(&cyapa->state_sync_lock);
553
554 /*
555 * Set to hard code default, they will be updated with trackpad set
556 * default values after probe and initialized.
557 */
558 cyapa->suspend_power_mode = PWR_MODE_SLEEP;
559 cyapa->suspend_sleep_time =
560 cyapa_pwr_cmd_to_sleep_time(cyapa->suspend_power_mode);
561
562 /* ops.initialize() is aimed to prepare for module communications. */
563 error = cyapa_gen3_ops.initialize(cyapa);
564 if (!error)
565 error = cyapa_gen5_ops.initialize(cyapa);
645 if (error) 566 if (error)
646 return error; 567 return error;
647 switch (cyapa->state) {
648 case CYAPA_STATE_BL_ACTIVE:
649 error = cyapa_bl_deactivate(cyapa);
650 if (error)
651 return error;
652 568
653 /* Fallthrough state */ 569 error = cyapa_detect(cyapa);
654 case CYAPA_STATE_BL_IDLE: 570 if (error)
655 error = cyapa_bl_exit(cyapa); 571 return error;
656 if (error)
657 return error;
658 572
659 /* Fallthrough state */ 573 /* Power down the device until we need it. */
660 case CYAPA_STATE_OP: 574 if (cyapa->operational)
661 error = cyapa_get_query_data(cyapa); 575 cyapa->ops->set_power_mode(cyapa, PWR_MODE_OFF, 0);
662 if (error)
663 return error;
664 576
665 /* only support firmware protocol gen3 */ 577 return 0;
666 if (cyapa->gen != CYAPA_GEN3) { 578}
667 dev_err(dev, "unsupported protocol version (%d)", 579
668 cyapa->gen); 580static int cyapa_reinitialize(struct cyapa *cyapa)
669 return -EINVAL; 581{
670 } 582 struct device *dev = &cyapa->client->dev;
583 struct input_dev *input = cyapa->input;
584 int error;
585
586 if (pm_runtime_enabled(dev))
587 pm_runtime_disable(dev);
671 588
672 /* only support product ID starting with CYTRA */ 589 /* Avoid command failures when TP was in OFF state. */
673 if (memcmp(cyapa->product_id, unique_str, 590 if (cyapa->operational)
674 sizeof(unique_str) - 1) != 0) { 591 cyapa->ops->set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE, 0);
675 dev_err(dev, "unsupported product ID (%s)\n", 592
676 cyapa->product_id); 593 error = cyapa_detect(cyapa);
677 return -EINVAL; 594 if (error)
595 goto out;
596
597 if (!input && cyapa->operational) {
598 error = cyapa_create_input_dev(cyapa);
599 if (error) {
600 dev_err(dev, "create input_dev instance failed: %d\n",
601 error);
602 goto out;
678 } 603 }
679 return 0; 604 }
680 605
681 default: 606out:
682 return -EIO; 607 if (!input || !input->users) {
608 /* Reset to power OFF state to save power when no user open. */
609 if (cyapa->operational)
610 cyapa->ops->set_power_mode(cyapa, PWR_MODE_OFF, 0);
611 } else if (!error && cyapa->operational) {
612 /*
613 * Make sure only enable runtime PM when device is
614 * in operational mode and input->users > 0.
615 */
616 pm_runtime_set_active(dev);
617 pm_runtime_enable(dev);
683 } 618 }
684 return 0; 619
620 return error;
685} 621}
686 622
687static irqreturn_t cyapa_irq(int irq, void *dev_id) 623static irqreturn_t cyapa_irq(int irq, void *dev_id)
688{ 624{
689 struct cyapa *cyapa = dev_id; 625 struct cyapa *cyapa = dev_id;
690 struct device *dev = &cyapa->client->dev; 626 struct device *dev = &cyapa->client->dev;
691 struct input_dev *input = cyapa->input;
692 struct cyapa_reg_data data;
693 int i;
694 int ret;
695 int num_fingers;
696 627
628 pm_runtime_get_sync(dev);
697 if (device_may_wakeup(dev)) 629 if (device_may_wakeup(dev))
698 pm_wakeup_event(dev, 0); 630 pm_wakeup_event(dev, 0);
699 631
700 ret = cyapa_read_block(cyapa, CYAPA_CMD_GROUP_DATA, (u8 *)&data); 632 /* Interrupt event maybe cuased by host command to trackpad device. */
701 if (ret != sizeof(data)) 633 if (cyapa->ops->irq_cmd_handler(cyapa)) {
702 goto out; 634 /*
635 * Interrupt event maybe from trackpad device input reporting.
636 */
637 if (!cyapa->input) {
638 /*
639 * Still in probling or in firware image
640 * udpating or reading.
641 */
642 cyapa->ops->sort_empty_output_data(cyapa,
643 NULL, NULL, NULL);
644 goto out;
645 }
703 646
704 if ((data.device_status & OP_STATUS_SRC) != OP_STATUS_SRC || 647 if (!cyapa->operational || cyapa->ops->irq_handler(cyapa)) {
705 (data.device_status & OP_STATUS_DEV) != CYAPA_DEV_NORMAL || 648 if (!mutex_trylock(&cyapa->state_sync_lock)) {
706 (data.finger_btn & OP_DATA_VALID) != OP_DATA_VALID) { 649 cyapa->ops->sort_empty_output_data(cyapa,
707 goto out; 650 NULL, NULL, NULL);
651 goto out;
652 }
653 cyapa_reinitialize(cyapa);
654 mutex_unlock(&cyapa->state_sync_lock);
655 }
708 } 656 }
709 657
710 num_fingers = (data.finger_btn >> 4) & 0x0f; 658out:
711 for (i = 0; i < num_fingers; i++) { 659 pm_runtime_mark_last_busy(dev);
712 const struct cyapa_touch *touch = &data.touches[i]; 660 pm_runtime_put_sync_autosuspend(dev);
713 /* Note: touch->id range is 1 to 15; slots are 0 to 14. */ 661 return IRQ_HANDLED;
714 int slot = touch->id - 1; 662}
663
664/*
665 **************************************************************
666 * sysfs interface
667 **************************************************************
668*/
669#ifdef CONFIG_PM_SLEEP
670static ssize_t cyapa_show_suspend_scanrate(struct device *dev,
671 struct device_attribute *attr,
672 char *buf)
673{
674 struct cyapa *cyapa = dev_get_drvdata(dev);
675 u8 pwr_cmd = cyapa->suspend_power_mode;
676 u16 sleep_time;
677 int len;
678 int error;
679
680 error = mutex_lock_interruptible(&cyapa->state_sync_lock);
681 if (error)
682 return error;
683
684 pwr_cmd = cyapa->suspend_power_mode;
685 sleep_time = cyapa->suspend_sleep_time;
686
687 mutex_unlock(&cyapa->state_sync_lock);
688
689 switch (pwr_cmd) {
690 case PWR_MODE_BTN_ONLY:
691 len = scnprintf(buf, PAGE_SIZE, "%s\n", BTN_ONLY_MODE_NAME);
692 break;
715 693
716 input_mt_slot(input, slot); 694 case PWR_MODE_OFF:
717 input_mt_report_slot_state(input, MT_TOOL_FINGER, true); 695 len = scnprintf(buf, PAGE_SIZE, "%s\n", OFF_MODE_NAME);
718 input_report_abs(input, ABS_MT_POSITION_X, 696 break;
719 ((touch->xy_hi & 0xf0) << 4) | touch->x_lo); 697
720 input_report_abs(input, ABS_MT_POSITION_Y, 698 default:
721 ((touch->xy_hi & 0x0f) << 8) | touch->y_lo); 699 len = scnprintf(buf, PAGE_SIZE, "%u\n",
722 input_report_abs(input, ABS_MT_PRESSURE, touch->pressure); 700 cyapa->gen == CYAPA_GEN3 ?
701 cyapa_pwr_cmd_to_sleep_time(pwr_cmd) :
702 sleep_time);
703 break;
723 } 704 }
724 705
725 input_mt_sync_frame(input); 706 return len;
707}
726 708
727 if (cyapa->btn_capability & CAPABILITY_LEFT_BTN_MASK) 709static ssize_t cyapa_update_suspend_scanrate(struct device *dev,
728 input_report_key(input, BTN_LEFT, 710 struct device_attribute *attr,
729 data.finger_btn & OP_DATA_LEFT_BTN); 711 const char *buf, size_t count)
712{
713 struct cyapa *cyapa = dev_get_drvdata(dev);
714 u16 sleep_time;
715 int error;
730 716
731 if (cyapa->btn_capability & CAPABILITY_MIDDLE_BTN_MASK) 717 error = mutex_lock_interruptible(&cyapa->state_sync_lock);
732 input_report_key(input, BTN_MIDDLE, 718 if (error)
733 data.finger_btn & OP_DATA_MIDDLE_BTN); 719 return error;
734 720
735 if (cyapa->btn_capability & CAPABILITY_RIGHT_BTN_MASK) 721 if (sysfs_streq(buf, BTN_ONLY_MODE_NAME)) {
736 input_report_key(input, BTN_RIGHT, 722 cyapa->suspend_power_mode = PWR_MODE_BTN_ONLY;
737 data.finger_btn & OP_DATA_RIGHT_BTN); 723 } else if (sysfs_streq(buf, OFF_MODE_NAME)) {
724 cyapa->suspend_power_mode = PWR_MODE_OFF;
725 } else if (!kstrtou16(buf, 10, &sleep_time)) {
726 cyapa->suspend_sleep_time = max_t(u16, sleep_time, 1000);
727 cyapa->suspend_power_mode =
728 cyapa_sleep_time_to_pwr_cmd(cyapa->suspend_sleep_time);
729 } else {
730 count = -EINVAL;
731 }
738 732
739 input_sync(input); 733 mutex_unlock(&cyapa->state_sync_lock);
740 734
741out: 735 return count;
742 return IRQ_HANDLED;
743} 736}
744 737
745static u8 cyapa_check_adapter_functionality(struct i2c_client *client) 738static DEVICE_ATTR(suspend_scanrate_ms, S_IRUGO|S_IWUSR,
739 cyapa_show_suspend_scanrate,
740 cyapa_update_suspend_scanrate);
741
742static struct attribute *cyapa_power_wakeup_entries[] = {
743 &dev_attr_suspend_scanrate_ms.attr,
744 NULL,
745};
746
747static const struct attribute_group cyapa_power_wakeup_group = {
748 .name = power_group_name,
749 .attrs = cyapa_power_wakeup_entries,
750};
751
752static void cyapa_remove_power_wakeup_group(void *data)
746{ 753{
747 u8 ret = CYAPA_ADAPTER_FUNC_NONE; 754 struct cyapa *cyapa = data;
748 755
749 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) 756 sysfs_unmerge_group(&cyapa->client->dev.kobj,
750 ret |= CYAPA_ADAPTER_FUNC_I2C; 757 &cyapa_power_wakeup_group);
751 if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
752 I2C_FUNC_SMBUS_BLOCK_DATA |
753 I2C_FUNC_SMBUS_I2C_BLOCK))
754 ret |= CYAPA_ADAPTER_FUNC_SMBUS;
755 return ret;
756} 758}
757 759
758static int cyapa_open(struct input_dev *input) 760static int cyapa_prepare_wakeup_controls(struct cyapa *cyapa)
759{ 761{
760 struct cyapa *cyapa = input_get_drvdata(input);
761 struct i2c_client *client = cyapa->client; 762 struct i2c_client *client = cyapa->client;
763 struct device *dev = &client->dev;
764 int error;
765
766 if (device_can_wakeup(dev)) {
767 error = sysfs_merge_group(&client->dev.kobj,
768 &cyapa_power_wakeup_group);
769 if (error) {
770 dev_err(dev, "failed to add power wakeup group: %d\n",
771 error);
772 return error;
773 }
774
775 error = devm_add_action(dev,
776 cyapa_remove_power_wakeup_group, cyapa);
777 if (error) {
778 cyapa_remove_power_wakeup_group(cyapa);
779 dev_err(dev, "failed to add power cleanup action: %d\n",
780 error);
781 return error;
782 }
783 }
784
785 return 0;
786}
787#else
788static inline int cyapa_prepare_wakeup_controls(struct cyapa *cyapa)
789{
790 return 0;
791}
792#endif /* CONFIG_PM_SLEEP */
793
794#ifdef CONFIG_PM
795static ssize_t cyapa_show_rt_suspend_scanrate(struct device *dev,
796 struct device_attribute *attr,
797 char *buf)
798{
799 struct cyapa *cyapa = dev_get_drvdata(dev);
800 u8 pwr_cmd;
801 u16 sleep_time;
802 int error;
803
804 error = mutex_lock_interruptible(&cyapa->state_sync_lock);
805 if (error)
806 return error;
807
808 pwr_cmd = cyapa->runtime_suspend_power_mode;
809 sleep_time = cyapa->runtime_suspend_sleep_time;
810
811 mutex_unlock(&cyapa->state_sync_lock);
812
813 return scnprintf(buf, PAGE_SIZE, "%u\n",
814 cyapa->gen == CYAPA_GEN3 ?
815 cyapa_pwr_cmd_to_sleep_time(pwr_cmd) :
816 sleep_time);
817}
818
819static ssize_t cyapa_update_rt_suspend_scanrate(struct device *dev,
820 struct device_attribute *attr,
821 const char *buf, size_t count)
822{
823 struct cyapa *cyapa = dev_get_drvdata(dev);
824 u16 time;
825 int error;
826
827 if (buf == NULL || count == 0 || kstrtou16(buf, 10, &time)) {
828 dev_err(dev, "invalid runtime suspend scanrate ms parameter\n");
829 return -EINVAL;
830 }
831
832 /*
833 * When the suspend scanrate is changed, pm_runtime_get to resume
834 * a potentially suspended device, update to the new pwr_cmd
835 * and then pm_runtime_put to suspend into the new power mode.
836 */
837 pm_runtime_get_sync(dev);
838
839 error = mutex_lock_interruptible(&cyapa->state_sync_lock);
840 if (error)
841 return error;
842
843 cyapa->runtime_suspend_sleep_time = max_t(u16, time, 1000);
844 cyapa->runtime_suspend_power_mode =
845 cyapa_sleep_time_to_pwr_cmd(cyapa->runtime_suspend_sleep_time);
846
847 mutex_unlock(&cyapa->state_sync_lock);
848
849 pm_runtime_put_sync_autosuspend(dev);
850
851 return count;
852}
853
854static DEVICE_ATTR(runtime_suspend_scanrate_ms, S_IRUGO|S_IWUSR,
855 cyapa_show_rt_suspend_scanrate,
856 cyapa_update_rt_suspend_scanrate);
857
858static struct attribute *cyapa_power_runtime_entries[] = {
859 &dev_attr_runtime_suspend_scanrate_ms.attr,
860 NULL,
861};
862
863static const struct attribute_group cyapa_power_runtime_group = {
864 .name = power_group_name,
865 .attrs = cyapa_power_runtime_entries,
866};
867
868static void cyapa_remove_power_runtime_group(void *data)
869{
870 struct cyapa *cyapa = data;
871
872 sysfs_unmerge_group(&cyapa->client->dev.kobj,
873 &cyapa_power_runtime_group);
874}
875
876static int cyapa_start_runtime(struct cyapa *cyapa)
877{
878 struct device *dev = &cyapa->client->dev;
762 int error; 879 int error;
763 880
764 error = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE); 881 cyapa->runtime_suspend_power_mode = PWR_MODE_IDLE;
882 cyapa->runtime_suspend_sleep_time =
883 cyapa_pwr_cmd_to_sleep_time(cyapa->runtime_suspend_power_mode);
884
885 error = sysfs_merge_group(&dev->kobj, &cyapa_power_runtime_group);
765 if (error) { 886 if (error) {
766 dev_err(&client->dev, "set active power failed: %d\n", error); 887 dev_err(dev,
888 "failed to create power runtime group: %d\n", error);
767 return error; 889 return error;
768 } 890 }
769 891
770 enable_irq(client->irq); 892 error = devm_add_action(dev, cyapa_remove_power_runtime_group, cyapa);
893 if (error) {
894 cyapa_remove_power_runtime_group(cyapa);
895 dev_err(dev,
896 "failed to add power runtime cleanup action: %d\n",
897 error);
898 return error;
899 }
900
901 /* runtime is enabled until device is operational and opened. */
902 pm_runtime_set_suspended(dev);
903 pm_runtime_use_autosuspend(dev);
904 pm_runtime_set_autosuspend_delay(dev, AUTOSUSPEND_DELAY);
905
771 return 0; 906 return 0;
772} 907}
908#else
909static inline int cyapa_start_runtime(struct cyapa *cyapa)
910{
911 return 0;
912}
913#endif /* CONFIG_PM */
773 914
774static void cyapa_close(struct input_dev *input) 915static ssize_t cyapa_show_fm_ver(struct device *dev,
916 struct device_attribute *attr, char *buf)
775{ 917{
776 struct cyapa *cyapa = input_get_drvdata(input); 918 int error;
919 struct cyapa *cyapa = dev_get_drvdata(dev);
777 920
778 disable_irq(cyapa->client->irq); 921 error = mutex_lock_interruptible(&cyapa->state_sync_lock);
779 cyapa_set_power_mode(cyapa, PWR_MODE_OFF); 922 if (error)
923 return error;
924 error = scnprintf(buf, PAGE_SIZE, "%d.%d\n", cyapa->fw_maj_ver,
925 cyapa->fw_min_ver);
926 mutex_unlock(&cyapa->state_sync_lock);
927 return error;
780} 928}
781 929
782static int cyapa_create_input_dev(struct cyapa *cyapa) 930static ssize_t cyapa_show_product_id(struct device *dev,
931 struct device_attribute *attr, char *buf)
932{
933 struct cyapa *cyapa = dev_get_drvdata(dev);
934 int size;
935 int error;
936
937 error = mutex_lock_interruptible(&cyapa->state_sync_lock);
938 if (error)
939 return error;
940 size = scnprintf(buf, PAGE_SIZE, "%s\n", cyapa->product_id);
941 mutex_unlock(&cyapa->state_sync_lock);
942 return size;
943}
944
945static int cyapa_firmware(struct cyapa *cyapa, const char *fw_name)
783{ 946{
784 struct device *dev = &cyapa->client->dev; 947 struct device *dev = &cyapa->client->dev;
785 struct input_dev *input; 948 const struct firmware *fw;
786 int error; 949 int error;
787 950
788 if (!cyapa->physical_size_x || !cyapa->physical_size_y) 951 error = request_firmware(&fw, fw_name, dev);
789 return -EINVAL; 952 if (error) {
953 dev_err(dev, "Could not load firmware from %s: %d\n",
954 fw_name, error);
955 return error;
956 }
790 957
791 input = devm_input_allocate_device(dev); 958 error = cyapa->ops->check_fw(cyapa, fw);
792 if (!input) { 959 if (error) {
793 dev_err(dev, "failed to allocate memory for input device.\n"); 960 dev_err(dev, "Invalid CYAPA firmware image: %s\n",
794 return -ENOMEM; 961 fw_name);
962 goto done;
795 } 963 }
796 964
797 input->name = CYAPA_NAME; 965 /*
798 input->phys = cyapa->phys; 966 * Resume the potentially suspended device because doing FW
799 input->id.bustype = BUS_I2C; 967 * update on a device not in the FULL mode has a chance to
800 input->id.version = 1; 968 * fail.
801 input->id.product = 0; /* Means any product in eventcomm. */ 969 */
802 input->dev.parent = &cyapa->client->dev; 970 pm_runtime_get_sync(dev);
803 971
804 input->open = cyapa_open; 972 /* Require IRQ support for firmware update commands. */
805 input->close = cyapa_close; 973 cyapa_enable_irq_for_cmd(cyapa);
806 974
807 input_set_drvdata(input, cyapa); 975 error = cyapa->ops->bl_enter(cyapa);
976 if (error) {
977 dev_err(dev, "bl_enter failed, %d\n", error);
978 goto err_detect;
979 }
808 980
809 __set_bit(EV_ABS, input->evbit); 981 error = cyapa->ops->bl_activate(cyapa);
982 if (error) {
983 dev_err(dev, "bl_activate failed, %d\n", error);
984 goto err_detect;
985 }
810 986
811 /* Finger position */ 987 error = cyapa->ops->bl_initiate(cyapa, fw);
812 input_set_abs_params(input, ABS_MT_POSITION_X, 0, cyapa->max_abs_x, 0, 988 if (error) {
813 0); 989 dev_err(dev, "bl_initiate failed, %d\n", error);
814 input_set_abs_params(input, ABS_MT_POSITION_Y, 0, cyapa->max_abs_y, 0, 990 goto err_detect;
815 0); 991 }
816 input_set_abs_params(input, ABS_MT_PRESSURE, 0, 255, 0, 0);
817 992
818 input_abs_set_res(input, ABS_MT_POSITION_X, 993 error = cyapa->ops->update_fw(cyapa, fw);
819 cyapa->max_abs_x / cyapa->physical_size_x); 994 if (error) {
820 input_abs_set_res(input, ABS_MT_POSITION_Y, 995 dev_err(dev, "update_fw failed, %d\n", error);
821 cyapa->max_abs_y / cyapa->physical_size_y); 996 goto err_detect;
997 }
822 998
823 if (cyapa->btn_capability & CAPABILITY_LEFT_BTN_MASK) 999err_detect:
824 __set_bit(BTN_LEFT, input->keybit); 1000 cyapa_disable_irq_for_cmd(cyapa);
825 if (cyapa->btn_capability & CAPABILITY_MIDDLE_BTN_MASK) 1001 pm_runtime_put_noidle(dev);
826 __set_bit(BTN_MIDDLE, input->keybit);
827 if (cyapa->btn_capability & CAPABILITY_RIGHT_BTN_MASK)
828 __set_bit(BTN_RIGHT, input->keybit);
829 1002
830 if (cyapa->btn_capability == CAPABILITY_LEFT_BTN_MASK) 1003done:
831 __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); 1004 release_firmware(fw);
1005 return error;
1006}
832 1007
833 /* Handle pointer emulation and unused slots in core */ 1008static ssize_t cyapa_update_fw_store(struct device *dev,
834 error = input_mt_init_slots(input, CYAPA_MAX_MT_SLOTS, 1009 struct device_attribute *attr,
835 INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED); 1010 const char *buf, size_t count)
1011{
1012 struct cyapa *cyapa = dev_get_drvdata(dev);
1013 char fw_name[NAME_MAX];
1014 int ret, error;
1015
1016 if (count >= NAME_MAX) {
1017 dev_err(dev, "File name too long\n");
1018 return -EINVAL;
1019 }
1020
1021 memcpy(fw_name, buf, count);
1022 if (fw_name[count - 1] == '\n')
1023 fw_name[count - 1] = '\0';
1024 else
1025 fw_name[count] = '\0';
1026
1027 if (cyapa->input) {
1028 /*
1029 * Force the input device to be registered after the firmware
1030 * image is updated, so if the corresponding parameters updated
1031 * in the new firmware image can taken effect immediately.
1032 */
1033 input_unregister_device(cyapa->input);
1034 cyapa->input = NULL;
1035 }
1036
1037 error = mutex_lock_interruptible(&cyapa->state_sync_lock);
836 if (error) { 1038 if (error) {
837 dev_err(dev, "failed to initialize MT slots: %d\n", error); 1039 /*
1040 * Whatever, do reinitialize to try to recover TP state to
1041 * previous state just as it entered fw update entrance.
1042 */
1043 cyapa_reinitialize(cyapa);
838 return error; 1044 return error;
839 } 1045 }
840 1046
841 cyapa->input = input; 1047 error = cyapa_firmware(cyapa, fw_name);
842 return 0; 1048 if (error)
1049 dev_err(dev, "firmware update failed: %d\n", error);
1050 else
1051 dev_dbg(dev, "firmware update successfully done.\n");
1052
1053 /*
1054 * Redetect trackpad device states because firmware update process
1055 * will reset trackpad device into bootloader mode.
1056 */
1057 ret = cyapa_reinitialize(cyapa);
1058 if (ret) {
1059 dev_err(dev, "failed to redetect after updated: %d\n", ret);
1060 error = error ? error : ret;
1061 }
1062
1063 mutex_unlock(&cyapa->state_sync_lock);
1064
1065 return error ? error : count;
1066}
1067
1068static ssize_t cyapa_calibrate_store(struct device *dev,
1069 struct device_attribute *attr,
1070 const char *buf, size_t count)
1071{
1072 struct cyapa *cyapa = dev_get_drvdata(dev);
1073 int error;
1074
1075 error = mutex_lock_interruptible(&cyapa->state_sync_lock);
1076 if (error)
1077 return error;
1078
1079 if (cyapa->operational) {
1080 cyapa_enable_irq_for_cmd(cyapa);
1081 error = cyapa->ops->calibrate_store(dev, attr, buf, count);
1082 cyapa_disable_irq_for_cmd(cyapa);
1083 } else {
1084 error = -EBUSY; /* Still running in bootloader mode. */
1085 }
1086
1087 mutex_unlock(&cyapa->state_sync_lock);
1088 return error < 0 ? error : count;
1089}
1090
1091static ssize_t cyapa_show_baseline(struct device *dev,
1092 struct device_attribute *attr, char *buf)
1093{
1094 struct cyapa *cyapa = dev_get_drvdata(dev);
1095 ssize_t error;
1096
1097 error = mutex_lock_interruptible(&cyapa->state_sync_lock);
1098 if (error)
1099 return error;
1100
1101 if (cyapa->operational) {
1102 cyapa_enable_irq_for_cmd(cyapa);
1103 error = cyapa->ops->show_baseline(dev, attr, buf);
1104 cyapa_disable_irq_for_cmd(cyapa);
1105 } else {
1106 error = -EBUSY; /* Still running in bootloader mode. */
1107 }
1108
1109 mutex_unlock(&cyapa->state_sync_lock);
1110 return error;
1111}
1112
1113static char *cyapa_state_to_string(struct cyapa *cyapa)
1114{
1115 switch (cyapa->state) {
1116 case CYAPA_STATE_BL_BUSY:
1117 return "bootloader busy";
1118 case CYAPA_STATE_BL_IDLE:
1119 return "bootloader idle";
1120 case CYAPA_STATE_BL_ACTIVE:
1121 return "bootloader active";
1122 case CYAPA_STATE_GEN5_BL:
1123 return "bootloader";
1124 case CYAPA_STATE_OP:
1125 case CYAPA_STATE_GEN5_APP:
1126 return "operational"; /* Normal valid state. */
1127 default:
1128 return "invalid mode";
1129 }
1130}
1131
1132static ssize_t cyapa_show_mode(struct device *dev,
1133 struct device_attribute *attr, char *buf)
1134{
1135 struct cyapa *cyapa = dev_get_drvdata(dev);
1136 int size;
1137 int error;
1138
1139 error = mutex_lock_interruptible(&cyapa->state_sync_lock);
1140 if (error)
1141 return error;
1142
1143 size = scnprintf(buf, PAGE_SIZE, "gen%d %s\n",
1144 cyapa->gen, cyapa_state_to_string(cyapa));
1145
1146 mutex_unlock(&cyapa->state_sync_lock);
1147 return size;
1148}
1149
1150static DEVICE_ATTR(firmware_version, S_IRUGO, cyapa_show_fm_ver, NULL);
1151static DEVICE_ATTR(product_id, S_IRUGO, cyapa_show_product_id, NULL);
1152static DEVICE_ATTR(update_fw, S_IWUSR, NULL, cyapa_update_fw_store);
1153static DEVICE_ATTR(baseline, S_IRUGO, cyapa_show_baseline, NULL);
1154static DEVICE_ATTR(calibrate, S_IWUSR, NULL, cyapa_calibrate_store);
1155static DEVICE_ATTR(mode, S_IRUGO, cyapa_show_mode, NULL);
1156
1157static struct attribute *cyapa_sysfs_entries[] = {
1158 &dev_attr_firmware_version.attr,
1159 &dev_attr_product_id.attr,
1160 &dev_attr_update_fw.attr,
1161 &dev_attr_baseline.attr,
1162 &dev_attr_calibrate.attr,
1163 &dev_attr_mode.attr,
1164 NULL,
1165};
1166
1167static const struct attribute_group cyapa_sysfs_group = {
1168 .attrs = cyapa_sysfs_entries,
1169};
1170
1171static void cyapa_remove_sysfs_group(void *data)
1172{
1173 struct cyapa *cyapa = data;
1174
1175 sysfs_remove_group(&cyapa->client->dev.kobj, &cyapa_sysfs_group);
843} 1176}
844 1177
845static int cyapa_probe(struct i2c_client *client, 1178static int cyapa_probe(struct i2c_client *client,
@@ -848,6 +1181,7 @@ static int cyapa_probe(struct i2c_client *client,
848 struct device *dev = &client->dev; 1181 struct device *dev = &client->dev;
849 struct cyapa *cyapa; 1182 struct cyapa *cyapa;
850 u8 adapter_func; 1183 u8 adapter_func;
1184 union i2c_smbus_data dummy;
851 int error; 1185 int error;
852 1186
853 adapter_func = cyapa_check_adapter_functionality(client); 1187 adapter_func = cyapa_check_adapter_functionality(client);
@@ -856,38 +1190,54 @@ static int cyapa_probe(struct i2c_client *client,
856 return -EIO; 1190 return -EIO;
857 } 1191 }
858 1192
1193 /* Make sure there is something at this address */
1194 if (i2c_smbus_xfer(client->adapter, client->addr, 0,
1195 I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &dummy) < 0)
1196 return -ENODEV;
1197
859 cyapa = devm_kzalloc(dev, sizeof(struct cyapa), GFP_KERNEL); 1198 cyapa = devm_kzalloc(dev, sizeof(struct cyapa), GFP_KERNEL);
860 if (!cyapa) 1199 if (!cyapa)
861 return -ENOMEM; 1200 return -ENOMEM;
862 1201
863 cyapa->gen = CYAPA_GEN3; 1202 /* i2c isn't supported, use smbus */
1203 if (adapter_func == CYAPA_ADAPTER_FUNC_SMBUS)
1204 cyapa->smbus = true;
1205
864 cyapa->client = client; 1206 cyapa->client = client;
865 i2c_set_clientdata(client, cyapa); 1207 i2c_set_clientdata(client, cyapa);
866 sprintf(cyapa->phys, "i2c-%d-%04x/input0", client->adapter->nr, 1208 sprintf(cyapa->phys, "i2c-%d-%04x/input0", client->adapter->nr,
867 client->addr); 1209 client->addr);
868 1210
869 /* i2c isn't supported, use smbus */ 1211 error = cyapa_initialize(cyapa);
870 if (adapter_func == CYAPA_ADAPTER_FUNC_SMBUS) 1212 if (error) {
871 cyapa->smbus = true; 1213 dev_err(dev, "failed to detect and initialize tp device.\n");
1214 return error;
1215 }
872 1216
873 cyapa->state = CYAPA_STATE_NO_DEVICE; 1217 error = sysfs_create_group(&client->dev.kobj, &cyapa_sysfs_group);
1218 if (error) {
1219 dev_err(dev, "failed to create sysfs entries: %d\n", error);
1220 return error;
1221 }
874 1222
875 error = cyapa_check_is_operational(cyapa); 1223 error = devm_add_action(dev, cyapa_remove_sysfs_group, cyapa);
876 if (error) { 1224 if (error) {
877 dev_err(dev, "device not operational, %d\n", error); 1225 cyapa_remove_sysfs_group(cyapa);
1226 dev_err(dev, "failed to add sysfs cleanup action: %d\n", error);
878 return error; 1227 return error;
879 } 1228 }
880 1229
881 /* Power down the device until we need it */ 1230 error = cyapa_prepare_wakeup_controls(cyapa);
882 error = cyapa_set_power_mode(cyapa, PWR_MODE_OFF);
883 if (error) { 1231 if (error) {
884 dev_err(dev, "failed to quiesce the device: %d\n", error); 1232 dev_err(dev, "failed to prepare wakeup controls: %d\n", error);
885 return error; 1233 return error;
886 } 1234 }
887 1235
888 error = cyapa_create_input_dev(cyapa); 1236 error = cyapa_start_runtime(cyapa);
889 if (error) 1237 if (error) {
1238 dev_err(dev, "failed to start pm_runtime: %d\n", error);
890 return error; 1239 return error;
1240 }
891 1241
892 error = devm_request_threaded_irq(dev, client->irq, 1242 error = devm_request_threaded_irq(dev, client->irq,
893 NULL, cyapa_irq, 1243 NULL, cyapa_irq,
@@ -901,11 +1251,18 @@ static int cyapa_probe(struct i2c_client *client,
901 /* Disable IRQ until the device is opened */ 1251 /* Disable IRQ until the device is opened */
902 disable_irq(client->irq); 1252 disable_irq(client->irq);
903 1253
904 /* Register the device in input subsystem */ 1254 /*
905 error = input_register_device(cyapa->input); 1255 * Register the device in the input subsystem when it's operational.
906 if (error) { 1256 * Otherwise, keep in this driver, so it can be be recovered or updated
907 dev_err(dev, "failed to register input device: %d\n", error); 1257 * through the sysfs mode and update_fw interfaces by user or apps.
908 return error; 1258 */
1259 if (cyapa->operational) {
1260 error = cyapa_create_input_dev(cyapa);
1261 if (error) {
1262 dev_err(dev, "create input_dev instance failed: %d\n",
1263 error);
1264 return error;
1265 }
909 } 1266 }
910 1267
911 return 0; 1268 return 0;
@@ -915,32 +1272,40 @@ static int __maybe_unused cyapa_suspend(struct device *dev)
915{ 1272{
916 struct i2c_client *client = to_i2c_client(dev); 1273 struct i2c_client *client = to_i2c_client(dev);
917 struct cyapa *cyapa = i2c_get_clientdata(client); 1274 struct cyapa *cyapa = i2c_get_clientdata(client);
918 struct input_dev *input = cyapa->input;
919 u8 power_mode; 1275 u8 power_mode;
920 int error; 1276 int error;
921 1277
922 error = mutex_lock_interruptible(&input->mutex); 1278 error = mutex_lock_interruptible(&cyapa->state_sync_lock);
923 if (error) 1279 if (error)
924 return error; 1280 return error;
925 1281
1282 /*
1283 * Runtime PM is enable only when device is in operational mode and
1284 * users in use, so need check it before disable it to
1285 * avoid unbalance warning.
1286 */
1287 if (pm_runtime_enabled(dev))
1288 pm_runtime_disable(dev);
926 disable_irq(client->irq); 1289 disable_irq(client->irq);
927 1290
928 /* 1291 /*
929 * Set trackpad device to idle mode if wakeup is allowed, 1292 * Set trackpad device to idle mode if wakeup is allowed,
930 * otherwise turn off. 1293 * otherwise turn off.
931 */ 1294 */
932 power_mode = device_may_wakeup(dev) ? PWR_MODE_IDLE 1295 if (cyapa->operational) {
933 : PWR_MODE_OFF; 1296 power_mode = device_may_wakeup(dev) ? cyapa->suspend_power_mode
934 error = cyapa_set_power_mode(cyapa, power_mode); 1297 : PWR_MODE_OFF;
935 if (error) 1298 error = cyapa->ops->set_power_mode(cyapa, power_mode,
936 dev_err(dev, "resume: set power mode to %d failed: %d\n", 1299 cyapa->suspend_sleep_time);
937 power_mode, error); 1300 if (error)
1301 dev_err(dev, "suspend set power mode failed: %d\n",
1302 error);
1303 }
938 1304
939 if (device_may_wakeup(dev)) 1305 if (device_may_wakeup(dev))
940 cyapa->irq_wake = (enable_irq_wake(client->irq) == 0); 1306 cyapa->irq_wake = (enable_irq_wake(client->irq) == 0);
941 1307
942 mutex_unlock(&input->mutex); 1308 mutex_unlock(&cyapa->state_sync_lock);
943
944 return 0; 1309 return 0;
945} 1310}
946 1311
@@ -948,29 +1313,56 @@ static int __maybe_unused cyapa_resume(struct device *dev)
948{ 1313{
949 struct i2c_client *client = to_i2c_client(dev); 1314 struct i2c_client *client = to_i2c_client(dev);
950 struct cyapa *cyapa = i2c_get_clientdata(client); 1315 struct cyapa *cyapa = i2c_get_clientdata(client);
951 struct input_dev *input = cyapa->input;
952 u8 power_mode;
953 int error; 1316 int error;
954 1317
955 mutex_lock(&input->mutex); 1318 mutex_lock(&cyapa->state_sync_lock);
956 1319
957 if (device_may_wakeup(dev) && cyapa->irq_wake) 1320 if (device_may_wakeup(dev) && cyapa->irq_wake) {
958 disable_irq_wake(client->irq); 1321 disable_irq_wake(client->irq);
1322 cyapa->irq_wake = false;
1323 }
959 1324
960 power_mode = input->users ? PWR_MODE_FULL_ACTIVE : PWR_MODE_OFF; 1325 /* Update device states and runtime PM states. */
961 error = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE); 1326 error = cyapa_reinitialize(cyapa);
962 if (error) 1327 if (error)
963 dev_warn(dev, "resume: set power mode to %d failed: %d\n", 1328 dev_warn(dev, "failed to reinitialize TP device: %d\n", error);
964 power_mode, error);
965 1329
966 enable_irq(client->irq); 1330 enable_irq(client->irq);
967 1331
968 mutex_unlock(&input->mutex); 1332 mutex_unlock(&cyapa->state_sync_lock);
1333 return 0;
1334}
1335
1336static int __maybe_unused cyapa_runtime_suspend(struct device *dev)
1337{
1338 struct cyapa *cyapa = dev_get_drvdata(dev);
1339 int error;
1340
1341 error = cyapa->ops->set_power_mode(cyapa,
1342 cyapa->runtime_suspend_power_mode,
1343 cyapa->runtime_suspend_sleep_time);
1344 if (error)
1345 dev_warn(dev, "runtime suspend failed: %d\n", error);
1346
1347 return 0;
1348}
1349
1350static int __maybe_unused cyapa_runtime_resume(struct device *dev)
1351{
1352 struct cyapa *cyapa = dev_get_drvdata(dev);
1353 int error;
1354
1355 error = cyapa->ops->set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE, 0);
1356 if (error)
1357 dev_warn(dev, "runtime resume failed: %d\n", error);
969 1358
970 return 0; 1359 return 0;
971} 1360}
972 1361
973static SIMPLE_DEV_PM_OPS(cyapa_pm_ops, cyapa_suspend, cyapa_resume); 1362static const struct dev_pm_ops cyapa_pm_ops = {
1363 SET_SYSTEM_SLEEP_PM_OPS(cyapa_suspend, cyapa_resume)
1364 SET_RUNTIME_PM_OPS(cyapa_runtime_suspend, cyapa_runtime_resume, NULL)
1365};
974 1366
975static const struct i2c_device_id cyapa_id_table[] = { 1367static const struct i2c_device_id cyapa_id_table[] = {
976 { "cyapa", 0 }, 1368 { "cyapa", 0 },
@@ -978,11 +1370,21 @@ static const struct i2c_device_id cyapa_id_table[] = {
978}; 1370};
979MODULE_DEVICE_TABLE(i2c, cyapa_id_table); 1371MODULE_DEVICE_TABLE(i2c, cyapa_id_table);
980 1372
1373#ifdef CONFIG_ACPI
1374static const struct acpi_device_id cyapa_acpi_id[] = {
1375 { "CYAP0000", 0 }, /* Gen3 trackpad with 0x67 I2C address. */
1376 { "CYAP0001", 0 }, /* Gen5 trackpad with 0x24 I2C address. */
1377 { }
1378};
1379MODULE_DEVICE_TABLE(acpi, cyapa_acpi_id);
1380#endif
1381
981static struct i2c_driver cyapa_driver = { 1382static struct i2c_driver cyapa_driver = {
982 .driver = { 1383 .driver = {
983 .name = "cyapa", 1384 .name = "cyapa",
984 .owner = THIS_MODULE, 1385 .owner = THIS_MODULE,
985 .pm = &cyapa_pm_ops, 1386 .pm = &cyapa_pm_ops,
1387 .acpi_match_table = ACPI_PTR(cyapa_acpi_id),
986 }, 1388 },
987 1389
988 .probe = cyapa_probe, 1390 .probe = cyapa_probe,
diff --git a/drivers/input/mouse/cyapa.h b/drivers/input/mouse/cyapa.h
new file mode 100644
index 000000000000..adc9ed5dcb0e
--- /dev/null
+++ b/drivers/input/mouse/cyapa.h
@@ -0,0 +1,301 @@
1/*
2 * Cypress APA trackpad with I2C interface
3 *
4 * Author: Dudley Du <dudl@cypress.com>
5 *
6 * Copyright (C) 2014 Cypress Semiconductor, Inc.
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file COPYING in the main directory of this archive for
10 * more details.
11 */
12
13#ifndef _CYAPA_H
14#define _CYAPA_H
15
16#include <linux/firmware.h>
17
18/* APA trackpad firmware generation number. */
19#define CYAPA_GEN_UNKNOWN 0x00 /* unknown protocol. */
20#define CYAPA_GEN3 0x03 /* support MT-protocol B with tracking ID. */
21#define CYAPA_GEN5 0x05 /* support TrueTouch GEN5 trackpad device. */
22
23#define CYAPA_NAME "Cypress APA Trackpad (cyapa)"
24
25/*
26 * Macros for SMBus communication
27 */
28#define SMBUS_READ 0x01
29#define SMBUS_WRITE 0x00
30#define SMBUS_ENCODE_IDX(cmd, idx) ((cmd) | (((idx) & 0x03) << 1))
31#define SMBUS_ENCODE_RW(cmd, rw) ((cmd) | ((rw) & 0x01))
32#define SMBUS_BYTE_BLOCK_CMD_MASK 0x80
33#define SMBUS_GROUP_BLOCK_CMD_MASK 0x40
34
35/* Commands for read/write registers of Cypress trackpad */
36#define CYAPA_CMD_SOFT_RESET 0x00
37#define CYAPA_CMD_POWER_MODE 0x01
38#define CYAPA_CMD_DEV_STATUS 0x02
39#define CYAPA_CMD_GROUP_DATA 0x03
40#define CYAPA_CMD_GROUP_CMD 0x04
41#define CYAPA_CMD_GROUP_QUERY 0x05
42#define CYAPA_CMD_BL_STATUS 0x06
43#define CYAPA_CMD_BL_HEAD 0x07
44#define CYAPA_CMD_BL_CMD 0x08
45#define CYAPA_CMD_BL_DATA 0x09
46#define CYAPA_CMD_BL_ALL 0x0a
47#define CYAPA_CMD_BLK_PRODUCT_ID 0x0b
48#define CYAPA_CMD_BLK_HEAD 0x0c
49#define CYAPA_CMD_MAX_BASELINE 0x0d
50#define CYAPA_CMD_MIN_BASELINE 0x0e
51
52#define BL_HEAD_OFFSET 0x00
53#define BL_DATA_OFFSET 0x10
54
55#define BL_STATUS_SIZE 3 /* Length of gen3 bootloader status registers */
56#define CYAPA_REG_MAP_SIZE 256
57
58/*
59 * Gen3 Operational Device Status Register
60 *
61 * bit 7: Valid interrupt source
62 * bit 6 - 4: Reserved
63 * bit 3 - 2: Power status
64 * bit 1 - 0: Device status
65 */
66#define REG_OP_STATUS 0x00
67#define OP_STATUS_SRC 0x80
68#define OP_STATUS_POWER 0x0c
69#define OP_STATUS_DEV 0x03
70#define OP_STATUS_MASK (OP_STATUS_SRC | OP_STATUS_POWER | OP_STATUS_DEV)
71
72/*
73 * Operational Finger Count/Button Flags Register
74 *
75 * bit 7 - 4: Number of touched finger
76 * bit 3: Valid data
77 * bit 2: Middle Physical Button
78 * bit 1: Right Physical Button
79 * bit 0: Left physical Button
80 */
81#define REG_OP_DATA1 0x01
82#define OP_DATA_VALID 0x08
83#define OP_DATA_MIDDLE_BTN 0x04
84#define OP_DATA_RIGHT_BTN 0x02
85#define OP_DATA_LEFT_BTN 0x01
86#define OP_DATA_BTN_MASK (OP_DATA_MIDDLE_BTN | OP_DATA_RIGHT_BTN | \
87 OP_DATA_LEFT_BTN)
88
89/*
90 * Write-only command file register used to issue commands and
91 * parameters to the bootloader.
92 * The default value read from it is always 0x00.
93 */
94#define REG_BL_FILE 0x00
95#define BL_FILE 0x00
96
97/*
98 * Bootloader Status Register
99 *
100 * bit 7: Busy
101 * bit 6 - 5: Reserved
102 * bit 4: Bootloader running
103 * bit 3 - 2: Reserved
104 * bit 1: Watchdog Reset
105 * bit 0: Checksum valid
106 */
107#define REG_BL_STATUS 0x01
108#define BL_STATUS_REV_6_5 0x60
109#define BL_STATUS_BUSY 0x80
110#define BL_STATUS_RUNNING 0x10
111#define BL_STATUS_REV_3_2 0x0c
112#define BL_STATUS_WATCHDOG 0x02
113#define BL_STATUS_CSUM_VALID 0x01
114#define BL_STATUS_REV_MASK (BL_STATUS_WATCHDOG | BL_STATUS_REV_3_2 | \
115 BL_STATUS_REV_6_5)
116
117/*
118 * Bootloader Error Register
119 *
120 * bit 7: Invalid
121 * bit 6: Invalid security key
122 * bit 5: Bootloading
123 * bit 4: Command checksum
124 * bit 3: Flash protection error
125 * bit 2: Flash checksum error
126 * bit 1 - 0: Reserved
127 */
128#define REG_BL_ERROR 0x02
129#define BL_ERROR_INVALID 0x80
130#define BL_ERROR_INVALID_KEY 0x40
131#define BL_ERROR_BOOTLOADING 0x20
132#define BL_ERROR_CMD_CSUM 0x10
133#define BL_ERROR_FLASH_PROT 0x08
134#define BL_ERROR_FLASH_CSUM 0x04
135#define BL_ERROR_RESERVED 0x03
136#define BL_ERROR_NO_ERR_IDLE 0x00
137#define BL_ERROR_NO_ERR_ACTIVE (BL_ERROR_BOOTLOADING)
138
139#define CAPABILITY_BTN_SHIFT 3
140#define CAPABILITY_LEFT_BTN_MASK (0x01 << 3)
141#define CAPABILITY_RIGHT_BTN_MASK (0x01 << 4)
142#define CAPABILITY_MIDDLE_BTN_MASK (0x01 << 5)
143#define CAPABILITY_BTN_MASK (CAPABILITY_LEFT_BTN_MASK | \
144 CAPABILITY_RIGHT_BTN_MASK | \
145 CAPABILITY_MIDDLE_BTN_MASK)
146
147#define PWR_MODE_MASK 0xfc
148#define PWR_MODE_FULL_ACTIVE (0x3f << 2)
149#define PWR_MODE_IDLE (0x03 << 2) /* Default rt suspend scanrate: 30ms */
150#define PWR_MODE_SLEEP (0x05 << 2) /* Default suspend scanrate: 50ms */
151#define PWR_MODE_BTN_ONLY (0x01 << 2)
152#define PWR_MODE_OFF (0x00 << 2)
153
154#define PWR_STATUS_MASK 0x0c
155#define PWR_STATUS_ACTIVE (0x03 << 2)
156#define PWR_STATUS_IDLE (0x02 << 2)
157#define PWR_STATUS_BTN_ONLY (0x01 << 2)
158#define PWR_STATUS_OFF (0x00 << 2)
159
160#define AUTOSUSPEND_DELAY 2000 /* unit : ms */
161
162#define UNINIT_SLEEP_TIME 0xFFFF
163#define UNINIT_PWR_MODE 0xFF
164
165#define BTN_ONLY_MODE_NAME "buttononly"
166#define OFF_MODE_NAME "off"
167
168/* The touch.id is used as the MT slot id, thus max MT slot is 15 */
169#define CYAPA_MAX_MT_SLOTS 15
170
171struct cyapa;
172
173typedef bool (*cb_sort)(struct cyapa *, u8 *, int);
174
175struct cyapa_dev_ops {
176 int (*check_fw)(struct cyapa *, const struct firmware *);
177 int (*bl_enter)(struct cyapa *);
178 int (*bl_activate)(struct cyapa *);
179 int (*bl_initiate)(struct cyapa *, const struct firmware *);
180 int (*update_fw)(struct cyapa *, const struct firmware *);
181 int (*bl_deactivate)(struct cyapa *);
182
183 ssize_t (*show_baseline)(struct device *,
184 struct device_attribute *, char *);
185 ssize_t (*calibrate_store)(struct device *,
186 struct device_attribute *, const char *, size_t);
187
188 int (*initialize)(struct cyapa *cyapa);
189
190 int (*state_parse)(struct cyapa *cyapa, u8 *reg_status, int len);
191 int (*operational_check)(struct cyapa *cyapa);
192
193 int (*irq_handler)(struct cyapa *);
194 bool (*irq_cmd_handler)(struct cyapa *);
195 int (*sort_empty_output_data)(struct cyapa *,
196 u8 *, int *, cb_sort);
197
198 int (*set_power_mode)(struct cyapa *, u8, u16);
199};
200
201struct cyapa_gen5_cmd_states {
202 struct mutex cmd_lock;
203 struct completion cmd_ready;
204 atomic_t cmd_issued;
205 u8 in_progress_cmd;
206 bool is_irq_mode;
207
208 cb_sort resp_sort_func;
209 u8 *resp_data;
210 int *resp_len;
211
212 u8 irq_cmd_buf[CYAPA_REG_MAP_SIZE];
213 u8 empty_buf[CYAPA_REG_MAP_SIZE];
214};
215
216union cyapa_cmd_states {
217 struct cyapa_gen5_cmd_states gen5;
218};
219
220enum cyapa_state {
221 CYAPA_STATE_NO_DEVICE,
222 CYAPA_STATE_BL_BUSY,
223 CYAPA_STATE_BL_IDLE,
224 CYAPA_STATE_BL_ACTIVE,
225 CYAPA_STATE_OP,
226 CYAPA_STATE_GEN5_BL,
227 CYAPA_STATE_GEN5_APP,
228};
229
230/* The main device structure */
231struct cyapa {
232 enum cyapa_state state;
233 u8 status[BL_STATUS_SIZE];
234 bool operational; /* true: ready for data reporting; false: not. */
235
236 struct i2c_client *client;
237 struct input_dev *input;
238 char phys[32]; /* Device physical location */
239 bool irq_wake; /* Irq wake is enabled */
240 bool smbus;
241
242 /* power mode settings */
243 u8 suspend_power_mode;
244 u16 suspend_sleep_time;
245 u8 runtime_suspend_power_mode;
246 u16 runtime_suspend_sleep_time;
247 u8 dev_pwr_mode;
248 u16 dev_sleep_time;
249
250 /* Read from query data region. */
251 char product_id[16];
252 u8 fw_maj_ver; /* Firmware major version. */
253 u8 fw_min_ver; /* Firmware minor version. */
254 u8 btn_capability;
255 u8 gen;
256 int max_abs_x;
257 int max_abs_y;
258 int physical_size_x;
259 int physical_size_y;
260
261 /* Used in ttsp and truetouch based trackpad devices. */
262 u8 x_origin; /* X Axis Origin: 0 = left side; 1 = rigth side. */
263 u8 y_origin; /* Y Axis Origin: 0 = top; 1 = bottom. */
264 int electrodes_x; /* Number of electrodes on the X Axis*/
265 int electrodes_y; /* Number of electrodes on the Y Axis*/
266 int electrodes_rx; /* Number of Rx electrodes */
267 int aligned_electrodes_rx; /* 4 aligned */
268 int max_z;
269
270 /*
271 * Used to synchronize the access or update the device state.
272 * And since update firmware and read firmware image process will take
273 * quite long time, maybe more than 10 seconds, so use mutex_lock
274 * to sync and wait other interface and detecting are done or ready.
275 */
276 struct mutex state_sync_lock;
277
278 const struct cyapa_dev_ops *ops;
279
280 union cyapa_cmd_states cmd_states;
281};
282
283
284ssize_t cyapa_i2c_reg_read_block(struct cyapa *cyapa, u8 reg, size_t len,
285 u8 *values);
286ssize_t cyapa_smbus_read_block(struct cyapa *cyapa, u8 cmd, size_t len,
287 u8 *values);
288
289ssize_t cyapa_read_block(struct cyapa *cyapa, u8 cmd_idx, u8 *values);
290
291int cyapa_poll_state(struct cyapa *cyapa, unsigned int timeout);
292
293u8 cyapa_sleep_time_to_pwr_cmd(u16 sleep_time);
294u16 cyapa_pwr_cmd_to_sleep_time(u8 pwr_mode);
295
296
297extern const char product_id[];
298extern const struct cyapa_dev_ops cyapa_gen3_ops;
299extern const struct cyapa_dev_ops cyapa_gen5_ops;
300
301#endif
diff --git a/drivers/input/mouse/cyapa_gen3.c b/drivers/input/mouse/cyapa_gen3.c
new file mode 100644
index 000000000000..77e9d70a986b
--- /dev/null
+++ b/drivers/input/mouse/cyapa_gen3.c
@@ -0,0 +1,1247 @@
1/*
2 * Cypress APA trackpad with I2C interface
3 *
4 * Author: Dudley Du <dudl@cypress.com>
5 * Further cleanup and restructuring by:
6 * Daniel Kurtz <djkurtz@chromium.org>
7 * Benson Leung <bleung@chromium.org>
8 *
9 * Copyright (C) 2011-2014 Cypress Semiconductor, Inc.
10 * Copyright (C) 2011-2012 Google, Inc.
11 *
12 * This file is subject to the terms and conditions of the GNU General Public
13 * License. See the file COPYING in the main directory of this archive for
14 * more details.
15 */
16
17#include <linux/delay.h>
18#include <linux/i2c.h>
19#include <linux/input.h>
20#include <linux/input/mt.h>
21#include <linux/module.h>
22#include <linux/slab.h>
23#include <linux/unaligned/access_ok.h>
24#include "cyapa.h"
25
26
27#define GEN3_MAX_FINGERS 5
28#define GEN3_FINGER_NUM(x) (((x) >> 4) & 0x07)
29
30#define BLK_HEAD_BYTES 32
31
32/* Macro for register map group offset. */
33#define PRODUCT_ID_SIZE 16
34#define QUERY_DATA_SIZE 27
35#define REG_PROTOCOL_GEN_QUERY_OFFSET 20
36
37#define REG_OFFSET_DATA_BASE 0x0000
38#define REG_OFFSET_COMMAND_BASE 0x0028
39#define REG_OFFSET_QUERY_BASE 0x002a
40
41#define CYAPA_OFFSET_SOFT_RESET REG_OFFSET_COMMAND_BASE
42#define OP_RECALIBRATION_MASK 0x80
43#define OP_REPORT_BASELINE_MASK 0x40
44#define REG_OFFSET_MAX_BASELINE 0x0026
45#define REG_OFFSET_MIN_BASELINE 0x0027
46
47#define REG_OFFSET_POWER_MODE (REG_OFFSET_COMMAND_BASE + 1)
48#define SET_POWER_MODE_DELAY 10000 /* Unit: us */
49#define SET_POWER_MODE_TRIES 5
50
51#define GEN3_BL_CMD_CHECKSUM_SEED 0xff
52#define GEN3_BL_CMD_INITIATE_BL 0x38
53#define GEN3_BL_CMD_WRITE_BLOCK 0x39
54#define GEN3_BL_CMD_VERIFY_BLOCK 0x3a
55#define GEN3_BL_CMD_TERMINATE_BL 0x3b
56#define GEN3_BL_CMD_LAUNCH_APP 0xa5
57
58/*
59 * CYAPA trackpad device states.
60 * Used in register 0x00, bit1-0, DeviceStatus field.
61 * Other values indicate device is in an abnormal state and must be reset.
62 */
63#define CYAPA_DEV_NORMAL 0x03
64#define CYAPA_DEV_BUSY 0x01
65
66#define CYAPA_FW_BLOCK_SIZE 64
67#define CYAPA_FW_READ_SIZE 16
68#define CYAPA_FW_HDR_START 0x0780
69#define CYAPA_FW_HDR_BLOCK_COUNT 2
70#define CYAPA_FW_HDR_BLOCK_START (CYAPA_FW_HDR_START / CYAPA_FW_BLOCK_SIZE)
71#define CYAPA_FW_HDR_SIZE (CYAPA_FW_HDR_BLOCK_COUNT * \
72 CYAPA_FW_BLOCK_SIZE)
73#define CYAPA_FW_DATA_START 0x0800
74#define CYAPA_FW_DATA_BLOCK_COUNT 480
75#define CYAPA_FW_DATA_BLOCK_START (CYAPA_FW_DATA_START / CYAPA_FW_BLOCK_SIZE)
76#define CYAPA_FW_DATA_SIZE (CYAPA_FW_DATA_BLOCK_COUNT * \
77 CYAPA_FW_BLOCK_SIZE)
78#define CYAPA_FW_SIZE (CYAPA_FW_HDR_SIZE + CYAPA_FW_DATA_SIZE)
79#define CYAPA_CMD_LEN 16
80
81#define GEN3_BL_IDLE_FW_MAJ_VER_OFFSET 0x0b
82#define GEN3_BL_IDLE_FW_MIN_VER_OFFSET (GEN3_BL_IDLE_FW_MAJ_VER_OFFSET + 1)
83
84
85struct cyapa_touch {
86 /*
87 * high bits or x/y position value
88 * bit 7 - 4: high 4 bits of x position value
89 * bit 3 - 0: high 4 bits of y position value
90 */
91 u8 xy_hi;
92 u8 x_lo; /* low 8 bits of x position value. */
93 u8 y_lo; /* low 8 bits of y position value. */
94 u8 pressure;
95 /* id range is 1 - 15. It is incremented with every new touch. */
96 u8 id;
97} __packed;
98
99struct cyapa_reg_data {
100 /*
101 * bit 0 - 1: device status
102 * bit 3 - 2: power mode
103 * bit 6 - 4: reserved
104 * bit 7: interrupt valid bit
105 */
106 u8 device_status;
107 /*
108 * bit 7 - 4: number of fingers currently touching pad
109 * bit 3: valid data check bit
110 * bit 2: middle mechanism button state if exists
111 * bit 1: right mechanism button state if exists
112 * bit 0: left mechanism button state if exists
113 */
114 u8 finger_btn;
115 /* CYAPA reports up to 5 touches per packet. */
116 struct cyapa_touch touches[5];
117} __packed;
118
119struct gen3_write_block_cmd {
120 u8 checksum_seed; /* Always be 0xff */
121 u8 cmd_code; /* command code: 0x39 */
122 u8 key[8]; /* 8-byte security key */
123 __be16 block_num;
124 u8 block_data[CYAPA_FW_BLOCK_SIZE];
125 u8 block_checksum; /* Calculated using bytes 12 - 75 */
126 u8 cmd_checksum; /* Calculated using bytes 0-76 */
127} __packed;
128
129static const u8 security_key[] = {
130 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
131static const u8 bl_activate[] = { 0x00, 0xff, 0x38, 0x00, 0x01, 0x02, 0x03,
132 0x04, 0x05, 0x06, 0x07 };
133static const u8 bl_deactivate[] = { 0x00, 0xff, 0x3b, 0x00, 0x01, 0x02, 0x03,
134 0x04, 0x05, 0x06, 0x07 };
135static const u8 bl_exit[] = { 0x00, 0xff, 0xa5, 0x00, 0x01, 0x02, 0x03, 0x04,
136 0x05, 0x06, 0x07 };
137
138
139 /* for byte read/write command */
140#define CMD_RESET 0
141#define CMD_POWER_MODE 1
142#define CMD_DEV_STATUS 2
143#define CMD_REPORT_MAX_BASELINE 3
144#define CMD_REPORT_MIN_BASELINE 4
145#define SMBUS_BYTE_CMD(cmd) (((cmd) & 0x3f) << 1)
146#define CYAPA_SMBUS_RESET SMBUS_BYTE_CMD(CMD_RESET)
147#define CYAPA_SMBUS_POWER_MODE SMBUS_BYTE_CMD(CMD_POWER_MODE)
148#define CYAPA_SMBUS_DEV_STATUS SMBUS_BYTE_CMD(CMD_DEV_STATUS)
149#define CYAPA_SMBUS_MAX_BASELINE SMBUS_BYTE_CMD(CMD_REPORT_MAX_BASELINE)
150#define CYAPA_SMBUS_MIN_BASELINE SMBUS_BYTE_CMD(CMD_REPORT_MIN_BASELINE)
151
152 /* for group registers read/write command */
153#define REG_GROUP_DATA 0
154#define REG_GROUP_CMD 2
155#define REG_GROUP_QUERY 3
156#define SMBUS_GROUP_CMD(grp) (0x80 | (((grp) & 0x07) << 3))
157#define CYAPA_SMBUS_GROUP_DATA SMBUS_GROUP_CMD(REG_GROUP_DATA)
158#define CYAPA_SMBUS_GROUP_CMD SMBUS_GROUP_CMD(REG_GROUP_CMD)
159#define CYAPA_SMBUS_GROUP_QUERY SMBUS_GROUP_CMD(REG_GROUP_QUERY)
160
161 /* for register block read/write command */
162#define CMD_BL_STATUS 0
163#define CMD_BL_HEAD 1
164#define CMD_BL_CMD 2
165#define CMD_BL_DATA 3
166#define CMD_BL_ALL 4
167#define CMD_BLK_PRODUCT_ID 5
168#define CMD_BLK_HEAD 6
169#define SMBUS_BLOCK_CMD(cmd) (0xc0 | (((cmd) & 0x1f) << 1))
170
171/* register block read/write command in bootloader mode */
172#define CYAPA_SMBUS_BL_STATUS SMBUS_BLOCK_CMD(CMD_BL_STATUS)
173#define CYAPA_SMBUS_BL_HEAD SMBUS_BLOCK_CMD(CMD_BL_HEAD)
174#define CYAPA_SMBUS_BL_CMD SMBUS_BLOCK_CMD(CMD_BL_CMD)
175#define CYAPA_SMBUS_BL_DATA SMBUS_BLOCK_CMD(CMD_BL_DATA)
176#define CYAPA_SMBUS_BL_ALL SMBUS_BLOCK_CMD(CMD_BL_ALL)
177
178/* register block read/write command in operational mode */
179#define CYAPA_SMBUS_BLK_PRODUCT_ID SMBUS_BLOCK_CMD(CMD_BLK_PRODUCT_ID)
180#define CYAPA_SMBUS_BLK_HEAD SMBUS_BLOCK_CMD(CMD_BLK_HEAD)
181
182 /* for byte read/write command */
183#define CMD_RESET 0
184#define CMD_POWER_MODE 1
185#define CMD_DEV_STATUS 2
186#define CMD_REPORT_MAX_BASELINE 3
187#define CMD_REPORT_MIN_BASELINE 4
188#define SMBUS_BYTE_CMD(cmd) (((cmd) & 0x3f) << 1)
189#define CYAPA_SMBUS_RESET SMBUS_BYTE_CMD(CMD_RESET)
190#define CYAPA_SMBUS_POWER_MODE SMBUS_BYTE_CMD(CMD_POWER_MODE)
191#define CYAPA_SMBUS_DEV_STATUS SMBUS_BYTE_CMD(CMD_DEV_STATUS)
192#define CYAPA_SMBUS_MAX_BASELINE SMBUS_BYTE_CMD(CMD_REPORT_MAX_BASELINE)
193#define CYAPA_SMBUS_MIN_BASELINE SMBUS_BYTE_CMD(CMD_REPORT_MIN_BASELINE)
194
195 /* for group registers read/write command */
196#define REG_GROUP_DATA 0
197#define REG_GROUP_CMD 2
198#define REG_GROUP_QUERY 3
199#define SMBUS_GROUP_CMD(grp) (0x80 | (((grp) & 0x07) << 3))
200#define CYAPA_SMBUS_GROUP_DATA SMBUS_GROUP_CMD(REG_GROUP_DATA)
201#define CYAPA_SMBUS_GROUP_CMD SMBUS_GROUP_CMD(REG_GROUP_CMD)
202#define CYAPA_SMBUS_GROUP_QUERY SMBUS_GROUP_CMD(REG_GROUP_QUERY)
203
204 /* for register block read/write command */
205#define CMD_BL_STATUS 0
206#define CMD_BL_HEAD 1
207#define CMD_BL_CMD 2
208#define CMD_BL_DATA 3
209#define CMD_BL_ALL 4
210#define CMD_BLK_PRODUCT_ID 5
211#define CMD_BLK_HEAD 6
212#define SMBUS_BLOCK_CMD(cmd) (0xc0 | (((cmd) & 0x1f) << 1))
213
214/* register block read/write command in bootloader mode */
215#define CYAPA_SMBUS_BL_STATUS SMBUS_BLOCK_CMD(CMD_BL_STATUS)
216#define CYAPA_SMBUS_BL_HEAD SMBUS_BLOCK_CMD(CMD_BL_HEAD)
217#define CYAPA_SMBUS_BL_CMD SMBUS_BLOCK_CMD(CMD_BL_CMD)
218#define CYAPA_SMBUS_BL_DATA SMBUS_BLOCK_CMD(CMD_BL_DATA)
219#define CYAPA_SMBUS_BL_ALL SMBUS_BLOCK_CMD(CMD_BL_ALL)
220
221/* register block read/write command in operational mode */
222#define CYAPA_SMBUS_BLK_PRODUCT_ID SMBUS_BLOCK_CMD(CMD_BLK_PRODUCT_ID)
223#define CYAPA_SMBUS_BLK_HEAD SMBUS_BLOCK_CMD(CMD_BLK_HEAD)
224
225struct cyapa_cmd_len {
226 u8 cmd;
227 u8 len;
228};
229
230/* maps generic CYAPA_CMD_* code to the I2C equivalent */
231static const struct cyapa_cmd_len cyapa_i2c_cmds[] = {
232 { CYAPA_OFFSET_SOFT_RESET, 1 }, /* CYAPA_CMD_SOFT_RESET */
233 { REG_OFFSET_COMMAND_BASE + 1, 1 }, /* CYAPA_CMD_POWER_MODE */
234 { REG_OFFSET_DATA_BASE, 1 }, /* CYAPA_CMD_DEV_STATUS */
235 { REG_OFFSET_DATA_BASE, sizeof(struct cyapa_reg_data) },
236 /* CYAPA_CMD_GROUP_DATA */
237 { REG_OFFSET_COMMAND_BASE, 0 }, /* CYAPA_CMD_GROUP_CMD */
238 { REG_OFFSET_QUERY_BASE, QUERY_DATA_SIZE }, /* CYAPA_CMD_GROUP_QUERY */
239 { BL_HEAD_OFFSET, 3 }, /* CYAPA_CMD_BL_STATUS */
240 { BL_HEAD_OFFSET, 16 }, /* CYAPA_CMD_BL_HEAD */
241 { BL_HEAD_OFFSET, 16 }, /* CYAPA_CMD_BL_CMD */
242 { BL_DATA_OFFSET, 16 }, /* CYAPA_CMD_BL_DATA */
243 { BL_HEAD_OFFSET, 32 }, /* CYAPA_CMD_BL_ALL */
244 { REG_OFFSET_QUERY_BASE, PRODUCT_ID_SIZE },
245 /* CYAPA_CMD_BLK_PRODUCT_ID */
246 { REG_OFFSET_DATA_BASE, 32 }, /* CYAPA_CMD_BLK_HEAD */
247 { REG_OFFSET_MAX_BASELINE, 1 }, /* CYAPA_CMD_MAX_BASELINE */
248 { REG_OFFSET_MIN_BASELINE, 1 }, /* CYAPA_CMD_MIN_BASELINE */
249};
250
251static const struct cyapa_cmd_len cyapa_smbus_cmds[] = {
252 { CYAPA_SMBUS_RESET, 1 }, /* CYAPA_CMD_SOFT_RESET */
253 { CYAPA_SMBUS_POWER_MODE, 1 }, /* CYAPA_CMD_POWER_MODE */
254 { CYAPA_SMBUS_DEV_STATUS, 1 }, /* CYAPA_CMD_DEV_STATUS */
255 { CYAPA_SMBUS_GROUP_DATA, sizeof(struct cyapa_reg_data) },
256 /* CYAPA_CMD_GROUP_DATA */
257 { CYAPA_SMBUS_GROUP_CMD, 2 }, /* CYAPA_CMD_GROUP_CMD */
258 { CYAPA_SMBUS_GROUP_QUERY, QUERY_DATA_SIZE },
259 /* CYAPA_CMD_GROUP_QUERY */
260 { CYAPA_SMBUS_BL_STATUS, 3 }, /* CYAPA_CMD_BL_STATUS */
261 { CYAPA_SMBUS_BL_HEAD, 16 }, /* CYAPA_CMD_BL_HEAD */
262 { CYAPA_SMBUS_BL_CMD, 16 }, /* CYAPA_CMD_BL_CMD */
263 { CYAPA_SMBUS_BL_DATA, 16 }, /* CYAPA_CMD_BL_DATA */
264 { CYAPA_SMBUS_BL_ALL, 32 }, /* CYAPA_CMD_BL_ALL */
265 { CYAPA_SMBUS_BLK_PRODUCT_ID, PRODUCT_ID_SIZE },
266 /* CYAPA_CMD_BLK_PRODUCT_ID */
267 { CYAPA_SMBUS_BLK_HEAD, 16 }, /* CYAPA_CMD_BLK_HEAD */
268 { CYAPA_SMBUS_MAX_BASELINE, 1 }, /* CYAPA_CMD_MAX_BASELINE */
269 { CYAPA_SMBUS_MIN_BASELINE, 1 }, /* CYAPA_CMD_MIN_BASELINE */
270};
271
272
273/*
274 * cyapa_smbus_read_block - perform smbus block read command
275 * @cyapa - private data structure of the driver
276 * @cmd - the properly encoded smbus command
277 * @len - expected length of smbus command result
278 * @values - buffer to store smbus command result
279 *
280 * Returns negative errno, else the number of bytes written.
281 *
282 * Note:
283 * In trackpad device, the memory block allocated for I2C register map
284 * is 256 bytes, so the max read block for I2C bus is 256 bytes.
285 */
286ssize_t cyapa_smbus_read_block(struct cyapa *cyapa, u8 cmd, size_t len,
287 u8 *values)
288{
289 ssize_t ret;
290 u8 index;
291 u8 smbus_cmd;
292 u8 *buf;
293 struct i2c_client *client = cyapa->client;
294
295 if (!(SMBUS_BYTE_BLOCK_CMD_MASK & cmd))
296 return -EINVAL;
297
298 if (SMBUS_GROUP_BLOCK_CMD_MASK & cmd) {
299 /* read specific block registers command. */
300 smbus_cmd = SMBUS_ENCODE_RW(cmd, SMBUS_READ);
301 ret = i2c_smbus_read_block_data(client, smbus_cmd, values);
302 goto out;
303 }
304
305 ret = 0;
306 for (index = 0; index * I2C_SMBUS_BLOCK_MAX < len; index++) {
307 smbus_cmd = SMBUS_ENCODE_IDX(cmd, index);
308 smbus_cmd = SMBUS_ENCODE_RW(smbus_cmd, SMBUS_READ);
309 buf = values + I2C_SMBUS_BLOCK_MAX * index;
310 ret = i2c_smbus_read_block_data(client, smbus_cmd, buf);
311 if (ret < 0)
312 goto out;
313 }
314
315out:
316 return ret > 0 ? len : ret;
317}
318
319static s32 cyapa_read_byte(struct cyapa *cyapa, u8 cmd_idx)
320{
321 u8 cmd;
322
323 if (cyapa->smbus) {
324 cmd = cyapa_smbus_cmds[cmd_idx].cmd;
325 cmd = SMBUS_ENCODE_RW(cmd, SMBUS_READ);
326 } else {
327 cmd = cyapa_i2c_cmds[cmd_idx].cmd;
328 }
329 return i2c_smbus_read_byte_data(cyapa->client, cmd);
330}
331
332static s32 cyapa_write_byte(struct cyapa *cyapa, u8 cmd_idx, u8 value)
333{
334 u8 cmd;
335
336 if (cyapa->smbus) {
337 cmd = cyapa_smbus_cmds[cmd_idx].cmd;
338 cmd = SMBUS_ENCODE_RW(cmd, SMBUS_WRITE);
339 } else {
340 cmd = cyapa_i2c_cmds[cmd_idx].cmd;
341 }
342 return i2c_smbus_write_byte_data(cyapa->client, cmd, value);
343}
344
345ssize_t cyapa_i2c_reg_read_block(struct cyapa *cyapa, u8 reg, size_t len,
346 u8 *values)
347{
348 return i2c_smbus_read_i2c_block_data(cyapa->client, reg, len, values);
349}
350
351static ssize_t cyapa_i2c_reg_write_block(struct cyapa *cyapa, u8 reg,
352 size_t len, const u8 *values)
353{
354 return i2c_smbus_write_i2c_block_data(cyapa->client, reg, len, values);
355}
356
357ssize_t cyapa_read_block(struct cyapa *cyapa, u8 cmd_idx, u8 *values)
358{
359 u8 cmd;
360 size_t len;
361
362 if (cyapa->smbus) {
363 cmd = cyapa_smbus_cmds[cmd_idx].cmd;
364 len = cyapa_smbus_cmds[cmd_idx].len;
365 return cyapa_smbus_read_block(cyapa, cmd, len, values);
366 }
367 cmd = cyapa_i2c_cmds[cmd_idx].cmd;
368 len = cyapa_i2c_cmds[cmd_idx].len;
369 return cyapa_i2c_reg_read_block(cyapa, cmd, len, values);
370}
371
372/*
373 * Determine the Gen3 trackpad device's current operating state.
374 *
375 */
376static int cyapa_gen3_state_parse(struct cyapa *cyapa, u8 *reg_data, int len)
377{
378 cyapa->state = CYAPA_STATE_NO_DEVICE;
379
380 /* Parse based on Gen3 characteristic registers and bits */
381 if (reg_data[REG_BL_FILE] == BL_FILE &&
382 reg_data[REG_BL_ERROR] == BL_ERROR_NO_ERR_IDLE &&
383 (reg_data[REG_BL_STATUS] ==
384 (BL_STATUS_RUNNING | BL_STATUS_CSUM_VALID) ||
385 reg_data[REG_BL_STATUS] == BL_STATUS_RUNNING)) {
386 /*
387 * Normal state after power on or reset,
388 * REG_BL_STATUS == 0x11, firmware image checksum is valid.
389 * REG_BL_STATUS == 0x10, firmware image checksum is invalid.
390 */
391 cyapa->gen = CYAPA_GEN3;
392 cyapa->state = CYAPA_STATE_BL_IDLE;
393 } else if (reg_data[REG_BL_FILE] == BL_FILE &&
394 (reg_data[REG_BL_STATUS] & BL_STATUS_RUNNING) ==
395 BL_STATUS_RUNNING) {
396 cyapa->gen = CYAPA_GEN3;
397 if (reg_data[REG_BL_STATUS] & BL_STATUS_BUSY) {
398 cyapa->state = CYAPA_STATE_BL_BUSY;
399 } else {
400 if ((reg_data[REG_BL_ERROR] & BL_ERROR_BOOTLOADING) ==
401 BL_ERROR_BOOTLOADING)
402 cyapa->state = CYAPA_STATE_BL_ACTIVE;
403 else
404 cyapa->state = CYAPA_STATE_BL_IDLE;
405 }
406 } else if ((reg_data[REG_OP_STATUS] & OP_STATUS_SRC) &&
407 (reg_data[REG_OP_DATA1] & OP_DATA_VALID)) {
408 /*
409 * Normal state when running in operational mode,
410 * may also not in full power state or
411 * busying in command process.
412 */
413 if (GEN3_FINGER_NUM(reg_data[REG_OP_DATA1]) <=
414 GEN3_MAX_FINGERS) {
415 /* Finger number data is valid. */
416 cyapa->gen = CYAPA_GEN3;
417 cyapa->state = CYAPA_STATE_OP;
418 }
419 } else if (reg_data[REG_OP_STATUS] == 0x0C &&
420 reg_data[REG_OP_DATA1] == 0x08) {
421 /* Op state when first two registers overwritten with 0x00 */
422 cyapa->gen = CYAPA_GEN3;
423 cyapa->state = CYAPA_STATE_OP;
424 } else if (reg_data[REG_BL_STATUS] &
425 (BL_STATUS_RUNNING | BL_STATUS_BUSY)) {
426 cyapa->gen = CYAPA_GEN3;
427 cyapa->state = CYAPA_STATE_BL_BUSY;
428 }
429
430 if (cyapa->gen == CYAPA_GEN3 && (cyapa->state == CYAPA_STATE_OP ||
431 cyapa->state == CYAPA_STATE_BL_IDLE ||
432 cyapa->state == CYAPA_STATE_BL_ACTIVE ||
433 cyapa->state == CYAPA_STATE_BL_BUSY))
434 return 0;
435
436 return -EAGAIN;
437}
438
439/*
440 * Enter bootloader by soft resetting the device.
441 *
442 * If device is already in the bootloader, the function just returns.
443 * Otherwise, reset the device; after reset, device enters bootloader idle
444 * state immediately.
445 *
446 * Returns:
447 * 0 on success
448 * -EAGAIN device was reset, but is not now in bootloader idle state
449 * < 0 if the device never responds within the timeout
450 */
451static int cyapa_gen3_bl_enter(struct cyapa *cyapa)
452{
453 int error;
454 int waiting_time;
455
456 error = cyapa_poll_state(cyapa, 500);
457 if (error)
458 return error;
459 if (cyapa->state == CYAPA_STATE_BL_IDLE) {
460 /* Already in BL_IDLE. Skipping reset. */
461 return 0;
462 }
463
464 if (cyapa->state != CYAPA_STATE_OP)
465 return -EAGAIN;
466
467 cyapa->operational = false;
468 cyapa->state = CYAPA_STATE_NO_DEVICE;
469 error = cyapa_write_byte(cyapa, CYAPA_CMD_SOFT_RESET, 0x01);
470 if (error)
471 return -EIO;
472
473 usleep_range(25000, 50000);
474 waiting_time = 2000; /* For some shipset, max waiting time is 1~2s. */
475 do {
476 error = cyapa_poll_state(cyapa, 500);
477 if (error) {
478 if (error == -ETIMEDOUT) {
479 waiting_time -= 500;
480 continue;
481 }
482 return error;
483 }
484
485 if ((cyapa->state == CYAPA_STATE_BL_IDLE) &&
486 !(cyapa->status[REG_BL_STATUS] & BL_STATUS_WATCHDOG))
487 break;
488
489 msleep(100);
490 waiting_time -= 100;
491 } while (waiting_time > 0);
492
493 if ((cyapa->state != CYAPA_STATE_BL_IDLE) ||
494 (cyapa->status[REG_BL_STATUS] & BL_STATUS_WATCHDOG))
495 return -EAGAIN;
496
497 return 0;
498}
499
500static int cyapa_gen3_bl_activate(struct cyapa *cyapa)
501{
502 int error;
503
504 error = cyapa_i2c_reg_write_block(cyapa, 0, sizeof(bl_activate),
505 bl_activate);
506 if (error)
507 return error;
508
509 /* Wait for bootloader to activate; takes between 2 and 12 seconds */
510 msleep(2000);
511 error = cyapa_poll_state(cyapa, 11000);
512 if (error)
513 return error;
514 if (cyapa->state != CYAPA_STATE_BL_ACTIVE)
515 return -EAGAIN;
516
517 return 0;
518}
519
520static int cyapa_gen3_bl_deactivate(struct cyapa *cyapa)
521{
522 int error;
523
524 error = cyapa_i2c_reg_write_block(cyapa, 0, sizeof(bl_deactivate),
525 bl_deactivate);
526 if (error)
527 return error;
528
529 /* Wait for bootloader to switch to idle state; should take < 100ms */
530 msleep(100);
531 error = cyapa_poll_state(cyapa, 500);
532 if (error)
533 return error;
534 if (cyapa->state != CYAPA_STATE_BL_IDLE)
535 return -EAGAIN;
536 return 0;
537}
538
539/*
540 * Exit bootloader
541 *
542 * Send bl_exit command, then wait 50 - 100 ms to let device transition to
543 * operational mode. If this is the first time the device's firmware is
544 * running, it can take up to 2 seconds to calibrate its sensors. So, poll
545 * the device's new state for up to 2 seconds.
546 *
547 * Returns:
548 * -EIO failure while reading from device
549 * -EAGAIN device is stuck in bootloader, b/c it has invalid firmware
550 * 0 device is supported and in operational mode
551 */
552static int cyapa_gen3_bl_exit(struct cyapa *cyapa)
553{
554 int error;
555
556 error = cyapa_i2c_reg_write_block(cyapa, 0, sizeof(bl_exit), bl_exit);
557 if (error)
558 return error;
559
560 /*
561 * Wait for bootloader to exit, and operation mode to start.
562 * Normally, this takes at least 50 ms.
563 */
564 usleep_range(50000, 100000);
565 /*
566 * In addition, when a device boots for the first time after being
567 * updated to new firmware, it must first calibrate its sensors, which
568 * can take up to an additional 2 seconds. If the device power is
569 * running low, this may take even longer.
570 */
571 error = cyapa_poll_state(cyapa, 4000);
572 if (error < 0)
573 return error;
574 if (cyapa->state != CYAPA_STATE_OP)
575 return -EAGAIN;
576
577 return 0;
578}
579
580static u16 cyapa_gen3_csum(const u8 *buf, size_t count)
581{
582 int i;
583 u16 csum = 0;
584
585 for (i = 0; i < count; i++)
586 csum += buf[i];
587
588 return csum;
589}
590
591/*
592 * Verify the integrity of a CYAPA firmware image file.
593 *
594 * The firmware image file is 30848 bytes, composed of 482 64-byte blocks.
595 *
596 * The first 2 blocks are the firmware header.
597 * The next 480 blocks are the firmware image.
598 *
599 * The first two bytes of the header hold the header checksum, computed by
600 * summing the other 126 bytes of the header.
601 * The last two bytes of the header hold the firmware image checksum, computed
602 * by summing the 30720 bytes of the image modulo 0xffff.
603 *
604 * Both checksums are stored little-endian.
605 */
606static int cyapa_gen3_check_fw(struct cyapa *cyapa, const struct firmware *fw)
607{
608 struct device *dev = &cyapa->client->dev;
609 u16 csum;
610 u16 csum_expected;
611
612 /* Firmware must match exact 30848 bytes = 482 64-byte blocks. */
613 if (fw->size != CYAPA_FW_SIZE) {
614 dev_err(dev, "invalid firmware size = %zu, expected %u.\n",
615 fw->size, CYAPA_FW_SIZE);
616 return -EINVAL;
617 }
618
619 /* Verify header block */
620 csum_expected = (fw->data[0] << 8) | fw->data[1];
621 csum = cyapa_gen3_csum(&fw->data[2], CYAPA_FW_HDR_SIZE - 2);
622 if (csum != csum_expected) {
623 dev_err(dev, "%s %04x, expected: %04x\n",
624 "invalid firmware header checksum = ",
625 csum, csum_expected);
626 return -EINVAL;
627 }
628
629 /* Verify firmware image */
630 csum_expected = (fw->data[CYAPA_FW_HDR_SIZE - 2] << 8) |
631 fw->data[CYAPA_FW_HDR_SIZE - 1];
632 csum = cyapa_gen3_csum(&fw->data[CYAPA_FW_HDR_SIZE],
633 CYAPA_FW_DATA_SIZE);
634 if (csum != csum_expected) {
635 dev_err(dev, "%s %04x, expected: %04x\n",
636 "invalid firmware header checksum = ",
637 csum, csum_expected);
638 return -EINVAL;
639 }
640 return 0;
641}
642
643/*
644 * Write a |len| byte long buffer |buf| to the device, by chopping it up into a
645 * sequence of smaller |CYAPA_CMD_LEN|-length write commands.
646 *
647 * The data bytes for a write command are prepended with the 1-byte offset
648 * of the data relative to the start of |buf|.
649 */
650static int cyapa_gen3_write_buffer(struct cyapa *cyapa,
651 const u8 *buf, size_t len)
652{
653 int error;
654 size_t i;
655 unsigned char cmd[CYAPA_CMD_LEN + 1];
656 size_t cmd_len;
657
658 for (i = 0; i < len; i += CYAPA_CMD_LEN) {
659 const u8 *payload = &buf[i];
660
661 cmd_len = (len - i >= CYAPA_CMD_LEN) ? CYAPA_CMD_LEN : len - i;
662 cmd[0] = i;
663 memcpy(&cmd[1], payload, cmd_len);
664
665 error = cyapa_i2c_reg_write_block(cyapa, 0, cmd_len + 1, cmd);
666 if (error)
667 return error;
668 }
669 return 0;
670}
671
672/*
673 * A firmware block write command writes 64 bytes of data to a single flash
674 * page in the device. The 78-byte block write command has the format:
675 * <0xff> <CMD> <Key> <Start> <Data> <Data-Checksum> <CMD Checksum>
676 *
677 * <0xff> - every command starts with 0xff
678 * <CMD> - the write command value is 0x39
679 * <Key> - write commands include an 8-byte key: { 00 01 02 03 04 05 06 07 }
680 * <Block> - Memory Block number (address / 64) (16-bit, big-endian)
681 * <Data> - 64 bytes of firmware image data
682 * <Data Checksum> - sum of 64 <Data> bytes, modulo 0xff
683 * <CMD Checksum> - sum of 77 bytes, from 0xff to <Data Checksum>
684 *
685 * Each write command is split into 5 i2c write transactions of up to 16 bytes.
686 * Each transaction starts with an i2c register offset: (00, 10, 20, 30, 40).
687 */
688static int cyapa_gen3_write_fw_block(struct cyapa *cyapa,
689 u16 block, const u8 *data)
690{
691 int ret;
692 struct gen3_write_block_cmd write_block_cmd;
693 u8 status[BL_STATUS_SIZE];
694 int tries;
695 u8 bl_status, bl_error;
696
697 /* Set write command and security key bytes. */
698 write_block_cmd.checksum_seed = GEN3_BL_CMD_CHECKSUM_SEED;
699 write_block_cmd.cmd_code = GEN3_BL_CMD_WRITE_BLOCK;
700 memcpy(write_block_cmd.key, security_key, sizeof(security_key));
701 put_unaligned_be16(block, &write_block_cmd.block_num);
702 memcpy(write_block_cmd.block_data, data, CYAPA_FW_BLOCK_SIZE);
703 write_block_cmd.block_checksum = cyapa_gen3_csum(
704 write_block_cmd.block_data, CYAPA_FW_BLOCK_SIZE);
705 write_block_cmd.cmd_checksum = cyapa_gen3_csum((u8 *)&write_block_cmd,
706 sizeof(write_block_cmd) - 1);
707
708 ret = cyapa_gen3_write_buffer(cyapa, (u8 *)&write_block_cmd,
709 sizeof(write_block_cmd));
710 if (ret)
711 return ret;
712
713 /* Wait for write to finish */
714 tries = 11; /* Programming for one block can take about 100ms. */
715 do {
716 usleep_range(10000, 20000);
717
718 /* Check block write command result status. */
719 ret = cyapa_i2c_reg_read_block(cyapa, BL_HEAD_OFFSET,
720 BL_STATUS_SIZE, status);
721 if (ret != BL_STATUS_SIZE)
722 return (ret < 0) ? ret : -EIO;
723 } while ((status[REG_BL_STATUS] & BL_STATUS_BUSY) && --tries);
724
725 /* Ignore WATCHDOG bit and reserved bits. */
726 bl_status = status[REG_BL_STATUS] & ~BL_STATUS_REV_MASK;
727 bl_error = status[REG_BL_ERROR] & ~BL_ERROR_RESERVED;
728
729 if (bl_status & BL_STATUS_BUSY)
730 ret = -ETIMEDOUT;
731 else if (bl_status != BL_STATUS_RUNNING ||
732 bl_error != BL_ERROR_BOOTLOADING)
733 ret = -EIO;
734 else
735 ret = 0;
736
737 return ret;
738}
739
740static int cyapa_gen3_write_blocks(struct cyapa *cyapa,
741 size_t start_block, size_t block_count,
742 const u8 *image_data)
743{
744 int error;
745 int i;
746
747 for (i = 0; i < block_count; i++) {
748 size_t block = start_block + i;
749 size_t addr = i * CYAPA_FW_BLOCK_SIZE;
750 const u8 *data = &image_data[addr];
751
752 error = cyapa_gen3_write_fw_block(cyapa, block, data);
753 if (error)
754 return error;
755 }
756 return 0;
757}
758
759static int cyapa_gen3_do_fw_update(struct cyapa *cyapa,
760 const struct firmware *fw)
761{
762 struct device *dev = &cyapa->client->dev;
763 int error;
764
765 /* First write data, starting at byte 128 of fw->data */
766 error = cyapa_gen3_write_blocks(cyapa,
767 CYAPA_FW_DATA_BLOCK_START, CYAPA_FW_DATA_BLOCK_COUNT,
768 &fw->data[CYAPA_FW_HDR_BLOCK_COUNT * CYAPA_FW_BLOCK_SIZE]);
769 if (error) {
770 dev_err(dev, "FW update aborted, write image: %d\n", error);
771 return error;
772 }
773
774 /* Then write checksum */
775 error = cyapa_gen3_write_blocks(cyapa,
776 CYAPA_FW_HDR_BLOCK_START, CYAPA_FW_HDR_BLOCK_COUNT,
777 &fw->data[0]);
778 if (error) {
779 dev_err(dev, "FW update aborted, write checksum: %d\n", error);
780 return error;
781 }
782
783 return 0;
784}
785
786static ssize_t cyapa_gen3_do_calibrate(struct device *dev,
787 struct device_attribute *attr,
788 const char *buf, size_t count)
789{
790 struct cyapa *cyapa = dev_get_drvdata(dev);
791 int tries;
792 int ret;
793
794 ret = cyapa_read_byte(cyapa, CYAPA_CMD_DEV_STATUS);
795 if (ret < 0) {
796 dev_err(dev, "Error reading dev status: %d\n", ret);
797 goto out;
798 }
799 if ((ret & CYAPA_DEV_NORMAL) != CYAPA_DEV_NORMAL) {
800 dev_warn(dev, "Trackpad device is busy, device state: 0x%02x\n",
801 ret);
802 ret = -EAGAIN;
803 goto out;
804 }
805
806 ret = cyapa_write_byte(cyapa, CYAPA_CMD_SOFT_RESET,
807 OP_RECALIBRATION_MASK);
808 if (ret < 0) {
809 dev_err(dev, "Failed to send calibrate command: %d\n",
810 ret);
811 goto out;
812 }
813
814 tries = 20; /* max recalibration timeout 2s. */
815 do {
816 /*
817 * For this recalibration, the max time will not exceed 2s.
818 * The average time is approximately 500 - 700 ms, and we
819 * will check the status every 100 - 200ms.
820 */
821 usleep_range(100000, 200000);
822
823 ret = cyapa_read_byte(cyapa, CYAPA_CMD_DEV_STATUS);
824 if (ret < 0) {
825 dev_err(dev, "Error reading dev status: %d\n",
826 ret);
827 goto out;
828 }
829 if ((ret & CYAPA_DEV_NORMAL) == CYAPA_DEV_NORMAL)
830 break;
831 } while (--tries);
832
833 if (tries == 0) {
834 dev_err(dev, "Failed to calibrate. Timeout.\n");
835 ret = -ETIMEDOUT;
836 goto out;
837 }
838 dev_dbg(dev, "Calibration successful.\n");
839
840out:
841 return ret < 0 ? ret : count;
842}
843
844static ssize_t cyapa_gen3_show_baseline(struct device *dev,
845 struct device_attribute *attr, char *buf)
846{
847 struct cyapa *cyapa = dev_get_drvdata(dev);
848 int max_baseline, min_baseline;
849 int tries;
850 int ret;
851
852 ret = cyapa_read_byte(cyapa, CYAPA_CMD_DEV_STATUS);
853 if (ret < 0) {
854 dev_err(dev, "Error reading dev status. err = %d\n", ret);
855 goto out;
856 }
857 if ((ret & CYAPA_DEV_NORMAL) != CYAPA_DEV_NORMAL) {
858 dev_warn(dev, "Trackpad device is busy. device state = 0x%x\n",
859 ret);
860 ret = -EAGAIN;
861 goto out;
862 }
863
864 ret = cyapa_write_byte(cyapa, CYAPA_CMD_SOFT_RESET,
865 OP_REPORT_BASELINE_MASK);
866 if (ret < 0) {
867 dev_err(dev, "Failed to send report baseline command. %d\n",
868 ret);
869 goto out;
870 }
871
872 tries = 3; /* Try for 30 to 60 ms */
873 do {
874 usleep_range(10000, 20000);
875
876 ret = cyapa_read_byte(cyapa, CYAPA_CMD_DEV_STATUS);
877 if (ret < 0) {
878 dev_err(dev, "Error reading dev status. err = %d\n",
879 ret);
880 goto out;
881 }
882 if ((ret & CYAPA_DEV_NORMAL) == CYAPA_DEV_NORMAL)
883 break;
884 } while (--tries);
885
886 if (tries == 0) {
887 dev_err(dev, "Device timed out going to Normal state.\n");
888 ret = -ETIMEDOUT;
889 goto out;
890 }
891
892 ret = cyapa_read_byte(cyapa, CYAPA_CMD_MAX_BASELINE);
893 if (ret < 0) {
894 dev_err(dev, "Failed to read max baseline. err = %d\n", ret);
895 goto out;
896 }
897 max_baseline = ret;
898
899 ret = cyapa_read_byte(cyapa, CYAPA_CMD_MIN_BASELINE);
900 if (ret < 0) {
901 dev_err(dev, "Failed to read min baseline. err = %d\n", ret);
902 goto out;
903 }
904 min_baseline = ret;
905
906 dev_dbg(dev, "Baseline report successful. Max: %d Min: %d\n",
907 max_baseline, min_baseline);
908 ret = scnprintf(buf, PAGE_SIZE, "%d %d\n", max_baseline, min_baseline);
909
910out:
911 return ret;
912}
913
914/*
915 * cyapa_get_wait_time_for_pwr_cmd
916 *
917 * Compute the amount of time we need to wait after updating the touchpad
918 * power mode. The touchpad needs to consume the incoming power mode set
919 * command at the current clock rate.
920 */
921
922static u16 cyapa_get_wait_time_for_pwr_cmd(u8 pwr_mode)
923{
924 switch (pwr_mode) {
925 case PWR_MODE_FULL_ACTIVE: return 20;
926 case PWR_MODE_BTN_ONLY: return 20;
927 case PWR_MODE_OFF: return 20;
928 default: return cyapa_pwr_cmd_to_sleep_time(pwr_mode) + 50;
929 }
930}
931
932/*
933 * Set device power mode
934 *
935 * Write to the field to configure power state. Power states include :
936 * Full : Max scans and report rate.
937 * Idle : Report rate set by user specified time.
938 * ButtonOnly : No scans for fingers. When the button is triggered,
939 * a slave interrupt is asserted to notify host to wake up.
940 * Off : Only awake for i2c commands from host. No function for button
941 * or touch sensors.
942 *
943 * The power_mode command should conform to the following :
944 * Full : 0x3f
945 * Idle : Configurable from 20 to 1000ms. See note below for
946 * cyapa_sleep_time_to_pwr_cmd and cyapa_pwr_cmd_to_sleep_time
947 * ButtonOnly : 0x01
948 * Off : 0x00
949 *
950 * Device power mode can only be set when device is in operational mode.
951 */
952static int cyapa_gen3_set_power_mode(struct cyapa *cyapa, u8 power_mode,
953 u16 always_unused)
954{
955 int ret;
956 u8 power;
957 int tries;
958 u16 sleep_time;
959
960 always_unused = 0;
961 if (cyapa->state != CYAPA_STATE_OP)
962 return 0;
963
964 tries = SET_POWER_MODE_TRIES;
965 while (tries--) {
966 ret = cyapa_read_byte(cyapa, CYAPA_CMD_POWER_MODE);
967 if (ret >= 0)
968 break;
969 usleep_range(SET_POWER_MODE_DELAY, 2 * SET_POWER_MODE_DELAY);
970 }
971 if (ret < 0)
972 return ret;
973
974 /*
975 * Return early if the power mode to set is the same as the current
976 * one.
977 */
978 if ((ret & PWR_MODE_MASK) == power_mode)
979 return 0;
980
981 sleep_time = cyapa_get_wait_time_for_pwr_cmd(ret & PWR_MODE_MASK);
982 power = ret;
983 power &= ~PWR_MODE_MASK;
984 power |= power_mode & PWR_MODE_MASK;
985 tries = SET_POWER_MODE_TRIES;
986 while (tries--) {
987 ret = cyapa_write_byte(cyapa, CYAPA_CMD_POWER_MODE, power);
988 if (!ret)
989 break;
990 usleep_range(SET_POWER_MODE_DELAY, 2 * SET_POWER_MODE_DELAY);
991 }
992
993 /*
994 * Wait for the newly set power command to go in at the previous
995 * clock speed (scanrate) used by the touchpad firmware. Not
996 * doing so before issuing the next command may result in errors
997 * depending on the command's content.
998 */
999 msleep(sleep_time);
1000 return ret;
1001}
1002
1003static int cyapa_gen3_get_query_data(struct cyapa *cyapa)
1004{
1005 u8 query_data[QUERY_DATA_SIZE];
1006 int ret;
1007
1008 if (cyapa->state != CYAPA_STATE_OP)
1009 return -EBUSY;
1010
1011 ret = cyapa_read_block(cyapa, CYAPA_CMD_GROUP_QUERY, query_data);
1012 if (ret != QUERY_DATA_SIZE)
1013 return (ret < 0) ? ret : -EIO;
1014
1015 memcpy(&cyapa->product_id[0], &query_data[0], 5);
1016 cyapa->product_id[5] = '-';
1017 memcpy(&cyapa->product_id[6], &query_data[5], 6);
1018 cyapa->product_id[12] = '-';
1019 memcpy(&cyapa->product_id[13], &query_data[11], 2);
1020 cyapa->product_id[15] = '\0';
1021
1022 cyapa->fw_maj_ver = query_data[15];
1023 cyapa->fw_min_ver = query_data[16];
1024
1025 cyapa->btn_capability = query_data[19] & CAPABILITY_BTN_MASK;
1026
1027 cyapa->gen = query_data[20] & 0x0f;
1028
1029 cyapa->max_abs_x = ((query_data[21] & 0xf0) << 4) | query_data[22];
1030 cyapa->max_abs_y = ((query_data[21] & 0x0f) << 8) | query_data[23];
1031
1032 cyapa->physical_size_x =
1033 ((query_data[24] & 0xf0) << 4) | query_data[25];
1034 cyapa->physical_size_y =
1035 ((query_data[24] & 0x0f) << 8) | query_data[26];
1036
1037 cyapa->max_z = 255;
1038
1039 return 0;
1040}
1041
1042static int cyapa_gen3_bl_query_data(struct cyapa *cyapa)
1043{
1044 u8 bl_data[CYAPA_CMD_LEN];
1045 int ret;
1046
1047 ret = cyapa_i2c_reg_read_block(cyapa, 0, CYAPA_CMD_LEN, bl_data);
1048 if (ret != CYAPA_CMD_LEN)
1049 return (ret < 0) ? ret : -EIO;
1050
1051 /*
1052 * This value will be updated again when entered application mode.
1053 * If TP failed to enter application mode, this fw version values
1054 * can be used as a reference.
1055 * This firmware version valid when fw image checksum is valid.
1056 */
1057 if (bl_data[REG_BL_STATUS] ==
1058 (BL_STATUS_RUNNING | BL_STATUS_CSUM_VALID)) {
1059 cyapa->fw_maj_ver = bl_data[GEN3_BL_IDLE_FW_MAJ_VER_OFFSET];
1060 cyapa->fw_min_ver = bl_data[GEN3_BL_IDLE_FW_MIN_VER_OFFSET];
1061 }
1062
1063 return 0;
1064}
1065
1066/*
1067 * Check if device is operational.
1068 *
1069 * An operational device is responding, has exited bootloader, and has
1070 * firmware supported by this driver.
1071 *
1072 * Returns:
1073 * -EBUSY no device or in bootloader
1074 * -EIO failure while reading from device
1075 * -EAGAIN device is still in bootloader
1076 * if ->state = CYAPA_STATE_BL_IDLE, device has invalid firmware
1077 * -EINVAL device is in operational mode, but not supported by this driver
1078 * 0 device is supported
1079 */
1080static int cyapa_gen3_do_operational_check(struct cyapa *cyapa)
1081{
1082 struct device *dev = &cyapa->client->dev;
1083 int error;
1084
1085 switch (cyapa->state) {
1086 case CYAPA_STATE_BL_ACTIVE:
1087 error = cyapa_gen3_bl_deactivate(cyapa);
1088 if (error) {
1089 dev_err(dev, "failed to bl_deactivate: %d\n", error);
1090 return error;
1091 }
1092
1093 /* Fallthrough state */
1094 case CYAPA_STATE_BL_IDLE:
1095 /* Try to get firmware version in bootloader mode. */
1096 cyapa_gen3_bl_query_data(cyapa);
1097
1098 error = cyapa_gen3_bl_exit(cyapa);
1099 if (error) {
1100 dev_err(dev, "failed to bl_exit: %d\n", error);
1101 return error;
1102 }
1103
1104 /* Fallthrough state */
1105 case CYAPA_STATE_OP:
1106 /*
1107 * Reading query data before going back to the full mode
1108 * may cause problems, so we set the power mode first here.
1109 */
1110 error = cyapa_gen3_set_power_mode(cyapa,
1111 PWR_MODE_FULL_ACTIVE, 0);
1112 if (error)
1113 dev_err(dev, "%s: set full power mode failed: %d\n",
1114 __func__, error);
1115 error = cyapa_gen3_get_query_data(cyapa);
1116 if (error < 0)
1117 return error;
1118
1119 /* Only support firmware protocol gen3 */
1120 if (cyapa->gen != CYAPA_GEN3) {
1121 dev_err(dev, "unsupported protocol version (%d)",
1122 cyapa->gen);
1123 return -EINVAL;
1124 }
1125
1126 /* Only support product ID starting with CYTRA */
1127 if (memcmp(cyapa->product_id, product_id,
1128 strlen(product_id)) != 0) {
1129 dev_err(dev, "unsupported product ID (%s)\n",
1130 cyapa->product_id);
1131 return -EINVAL;
1132 }
1133
1134 return 0;
1135
1136 default:
1137 return -EIO;
1138 }
1139 return 0;
1140}
1141
1142/*
1143 * Return false, do not continue process
1144 * Return true, continue process.
1145 */
1146static bool cyapa_gen3_irq_cmd_handler(struct cyapa *cyapa)
1147{
1148 /* Not gen3 irq command response, skip for continue. */
1149 if (cyapa->gen != CYAPA_GEN3)
1150 return true;
1151
1152 if (cyapa->operational)
1153 return true;
1154
1155 /*
1156 * Driver in detecting or other interface function processing,
1157 * so, stop cyapa_gen3_irq_handler to continue process to
1158 * avoid unwanted to error detecting and processing.
1159 *
1160 * And also, avoid the periodicly accerted interrupts to be processed
1161 * as touch inputs when gen3 failed to launch into application mode,
1162 * which will cause gen3 stays in bootloader mode.
1163 */
1164 return false;
1165}
1166
1167static int cyapa_gen3_irq_handler(struct cyapa *cyapa)
1168{
1169 struct input_dev *input = cyapa->input;
1170 struct device *dev = &cyapa->client->dev;
1171 struct cyapa_reg_data data;
1172 int num_fingers;
1173 int ret;
1174 int i;
1175
1176 ret = cyapa_read_block(cyapa, CYAPA_CMD_GROUP_DATA, (u8 *)&data);
1177 if (ret != sizeof(data)) {
1178 dev_err(dev, "failed to read report data, (%d)\n", ret);
1179 return -EINVAL;
1180 }
1181
1182 if ((data.device_status & OP_STATUS_SRC) != OP_STATUS_SRC ||
1183 (data.device_status & OP_STATUS_DEV) != CYAPA_DEV_NORMAL ||
1184 (data.finger_btn & OP_DATA_VALID) != OP_DATA_VALID) {
1185 dev_err(dev, "invalid device state bytes, %02x %02x\n",
1186 data.device_status, data.finger_btn);
1187 return -EINVAL;
1188 }
1189
1190 num_fingers = (data.finger_btn >> 4) & 0x0f;
1191 for (i = 0; i < num_fingers; i++) {
1192 const struct cyapa_touch *touch = &data.touches[i];
1193 /* Note: touch->id range is 1 to 15; slots are 0 to 14. */
1194 int slot = touch->id - 1;
1195
1196 input_mt_slot(input, slot);
1197 input_mt_report_slot_state(input, MT_TOOL_FINGER, true);
1198 input_report_abs(input, ABS_MT_POSITION_X,
1199 ((touch->xy_hi & 0xf0) << 4) | touch->x_lo);
1200 input_report_abs(input, ABS_MT_POSITION_Y,
1201 ((touch->xy_hi & 0x0f) << 8) | touch->y_lo);
1202 input_report_abs(input, ABS_MT_PRESSURE, touch->pressure);
1203 }
1204
1205 input_mt_sync_frame(input);
1206
1207 if (cyapa->btn_capability & CAPABILITY_LEFT_BTN_MASK)
1208 input_report_key(input, BTN_LEFT,
1209 !!(data.finger_btn & OP_DATA_LEFT_BTN));
1210 if (cyapa->btn_capability & CAPABILITY_MIDDLE_BTN_MASK)
1211 input_report_key(input, BTN_MIDDLE,
1212 !!(data.finger_btn & OP_DATA_MIDDLE_BTN));
1213 if (cyapa->btn_capability & CAPABILITY_RIGHT_BTN_MASK)
1214 input_report_key(input, BTN_RIGHT,
1215 !!(data.finger_btn & OP_DATA_RIGHT_BTN));
1216 input_sync(input);
1217
1218 return 0;
1219}
1220
1221static int cyapa_gen3_initialize(struct cyapa *cyapa) { return 0; }
1222static int cyapa_gen3_bl_initiate(struct cyapa *cyapa,
1223 const struct firmware *fw) { return 0; }
1224static int cyapa_gen3_empty_output_data(struct cyapa *cyapa,
1225 u8 *buf, int *len, cb_sort func) { return 0; }
1226
1227const struct cyapa_dev_ops cyapa_gen3_ops = {
1228 .check_fw = cyapa_gen3_check_fw,
1229 .bl_enter = cyapa_gen3_bl_enter,
1230 .bl_activate = cyapa_gen3_bl_activate,
1231 .update_fw = cyapa_gen3_do_fw_update,
1232 .bl_deactivate = cyapa_gen3_bl_deactivate,
1233 .bl_initiate = cyapa_gen3_bl_initiate,
1234
1235 .show_baseline = cyapa_gen3_show_baseline,
1236 .calibrate_store = cyapa_gen3_do_calibrate,
1237
1238 .initialize = cyapa_gen3_initialize,
1239
1240 .state_parse = cyapa_gen3_state_parse,
1241 .operational_check = cyapa_gen3_do_operational_check,
1242
1243 .irq_handler = cyapa_gen3_irq_handler,
1244 .irq_cmd_handler = cyapa_gen3_irq_cmd_handler,
1245 .sort_empty_output_data = cyapa_gen3_empty_output_data,
1246 .set_power_mode = cyapa_gen3_set_power_mode,
1247};
diff --git a/drivers/input/mouse/cyapa_gen5.c b/drivers/input/mouse/cyapa_gen5.c
new file mode 100644
index 000000000000..ddf5393a1180
--- /dev/null
+++ b/drivers/input/mouse/cyapa_gen5.c
@@ -0,0 +1,2777 @@
1/*
2 * Cypress APA trackpad with I2C interface
3 *
4 * Author: Dudley Du <dudl@cypress.com>
5 *
6 * Copyright (C) 2014 Cypress Semiconductor, Inc.
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file COPYING in the main directory of this archive for
10 * more details.
11 */
12
13#include <linux/delay.h>
14#include <linux/i2c.h>
15#include <linux/input.h>
16#include <linux/input/mt.h>
17#include <linux/mutex.h>
18#include <linux/completion.h>
19#include <linux/slab.h>
20#include <linux/unaligned/access_ok.h>
21#include <linux/crc-itu-t.h>
22#include "cyapa.h"
23
24
25/* Macro of Gen5 */
26#define RECORD_EVENT_NONE 0
27#define RECORD_EVENT_TOUCHDOWN 1
28#define RECORD_EVENT_DISPLACE 2
29#define RECORD_EVENT_LIFTOFF 3
30
31#define CYAPA_TSG_FLASH_MAP_BLOCK_SIZE 0x80
32#define CYAPA_TSG_IMG_FW_HDR_SIZE 13
33#define CYAPA_TSG_FW_ROW_SIZE (CYAPA_TSG_FLASH_MAP_BLOCK_SIZE)
34#define CYAPA_TSG_IMG_START_ROW_NUM 0x002e
35#define CYAPA_TSG_IMG_END_ROW_NUM 0x01fe
36#define CYAPA_TSG_IMG_APP_INTEGRITY_ROW_NUM 0x01ff
37#define CYAPA_TSG_IMG_MAX_RECORDS (CYAPA_TSG_IMG_END_ROW_NUM - \
38 CYAPA_TSG_IMG_START_ROW_NUM + 1 + 1)
39#define CYAPA_TSG_IMG_READ_SIZE (CYAPA_TSG_FLASH_MAP_BLOCK_SIZE / 2)
40#define CYAPA_TSG_START_OF_APPLICATION 0x1700
41#define CYAPA_TSG_APP_INTEGRITY_SIZE 60
42#define CYAPA_TSG_FLASH_MAP_METADATA_SIZE 60
43#define CYAPA_TSG_BL_KEY_SIZE 8
44
45#define CYAPA_TSG_MAX_CMD_SIZE 256
46
47#define GEN5_BL_CMD_VERIFY_APP_INTEGRITY 0x31
48#define GEN5_BL_CMD_GET_BL_INFO 0x38
49#define GEN5_BL_CMD_PROGRAM_VERIFY_ROW 0x39
50#define GEN5_BL_CMD_LAUNCH_APP 0x3b
51#define GEN5_BL_CMD_INITIATE_BL 0x48
52
53#define GEN5_HID_DESCRIPTOR_ADDR 0x0001
54#define GEN5_REPORT_DESCRIPTOR_ADDR 0x0002
55#define GEN5_INPUT_REPORT_ADDR 0x0003
56#define GEN5_OUTPUT_REPORT_ADDR 0x0004
57#define GEN5_CMD_DATA_ADDR 0x0006
58
59#define GEN5_TOUCH_REPORT_HEAD_SIZE 7
60#define GEN5_TOUCH_REPORT_MAX_SIZE 127
61#define GEN5_BTN_REPORT_HEAD_SIZE 6
62#define GEN5_BTN_REPORT_MAX_SIZE 14
63#define GEN5_WAKEUP_EVENT_SIZE 4
64#define GEN5_RAW_DATA_HEAD_SIZE 24
65
66#define GEN5_BL_CMD_REPORT_ID 0x40
67#define GEN5_BL_RESP_REPORT_ID 0x30
68#define GEN5_APP_CMD_REPORT_ID 0x2f
69#define GEN5_APP_RESP_REPORT_ID 0x1f
70
71#define GEN5_APP_DEEP_SLEEP_REPORT_ID 0xf0
72#define GEN5_DEEP_SLEEP_RESP_LENGTH 5
73
74#define GEN5_CMD_GET_PARAMETER 0x05
75#define GEN5_CMD_SET_PARAMETER 0x06
76#define GEN5_PARAMETER_ACT_INTERVL_ID 0x4d
77#define GEN5_PARAMETER_ACT_INTERVL_SIZE 1
78#define GEN5_PARAMETER_ACT_LFT_INTERVL_ID 0x4f
79#define GEN5_PARAMETER_ACT_LFT_INTERVL_SIZE 2
80#define GEN5_PARAMETER_LP_INTRVL_ID 0x4c
81#define GEN5_PARAMETER_LP_INTRVL_SIZE 2
82
83#define GEN5_PARAMETER_DISABLE_PIP_REPORT 0x08
84
85#define GEN5_POWER_STATE_ACTIVE 0x01
86#define GEN5_POWER_STATE_LOOK_FOR_TOUCH 0x02
87#define GEN5_POWER_STATE_READY 0x03
88#define GEN5_POWER_STATE_IDLE 0x04
89#define GEN5_POWER_STATE_BTN_ONLY 0x05
90#define GEN5_POWER_STATE_OFF 0x06
91
92#define GEN5_DEEP_SLEEP_STATE_MASK 0x03
93#define GEN5_DEEP_SLEEP_STATE_ON 0x00
94#define GEN5_DEEP_SLEEP_STATE_OFF 0x01
95
96#define GEN5_DEEP_SLEEP_OPCODE 0x08
97#define GEN5_DEEP_SLEEP_OPCODE_MASK 0x0f
98
99#define GEN5_POWER_READY_MAX_INTRVL_TIME 50 /* Unit: ms */
100#define GEN5_POWER_IDLE_MAX_INTRVL_TIME 250 /* Unit: ms */
101
102#define GEN5_CMD_REPORT_ID_OFFSET 4
103
104#define GEN5_RESP_REPORT_ID_OFFSET 2
105#define GEN5_RESP_RSVD_OFFSET 3
106#define GEN5_RESP_RSVD_KEY 0x00
107#define GEN5_RESP_BL_SOP_OFFSET 4
108#define GEN5_SOP_KEY 0x01 /* Start of Packet */
109#define GEN5_EOP_KEY 0x17 /* End of Packet */
110#define GEN5_RESP_APP_CMD_OFFSET 4
111#define GET_GEN5_CMD_CODE(reg) ((reg) & 0x7f)
112
113#define VALID_CMD_RESP_HEADER(resp, cmd) \
114 (((resp)[GEN5_RESP_REPORT_ID_OFFSET] == GEN5_APP_RESP_REPORT_ID) && \
115 ((resp)[GEN5_RESP_RSVD_OFFSET] == GEN5_RESP_RSVD_KEY) && \
116 (GET_GEN5_CMD_CODE((resp)[GEN5_RESP_APP_CMD_OFFSET]) == (cmd)))
117
118#define GEN5_MIN_BL_CMD_LENGTH 13
119#define GEN5_MIN_BL_RESP_LENGTH 11
120#define GEN5_MIN_APP_CMD_LENGTH 7
121#define GEN5_MIN_APP_RESP_LENGTH 5
122#define GEN5_UNSUPPORTED_CMD_RESP_LENGTH 6
123
124#define GEN5_RESP_LENGTH_OFFSET 0x00
125#define GEN5_RESP_LENGTH_SIZE 2
126
127#define GEN5_HID_DESCRIPTOR_SIZE 32
128#define GEN5_BL_HID_REPORT_ID 0xff
129#define GEN5_APP_HID_REPORT_ID 0xf7
130#define GEN5_BL_MAX_OUTPUT_LENGTH 0x0100
131#define GEN5_APP_MAX_OUTPUT_LENGTH 0x00fe
132
133#define GEN5_BL_REPORT_DESCRIPTOR_SIZE 0x1d
134#define GEN5_BL_REPORT_DESCRIPTOR_ID 0xfe
135#define GEN5_APP_REPORT_DESCRIPTOR_SIZE 0xee
136#define GEN5_APP_CONTRACT_REPORT_DESCRIPTOR_SIZE 0xfa
137#define GEN5_APP_REPORT_DESCRIPTOR_ID 0xf6
138
139#define GEN5_TOUCH_REPORT_ID 0x01
140#define GEN5_BTN_REPORT_ID 0x03
141#define GEN5_WAKEUP_EVENT_REPORT_ID 0x04
142#define GEN5_OLD_PUSH_BTN_REPORT_ID 0x05
143#define GEN5_PUSH_BTN_REPORT_ID 0x06
144
145#define GEN5_CMD_COMPLETE_SUCCESS(status) ((status) == 0x00)
146
147#define GEN5_BL_INITIATE_RESP_LEN 11
148#define GEN5_BL_FAIL_EXIT_RESP_LEN 11
149#define GEN5_BL_FAIL_EXIT_STATUS_CODE 0x0c
150#define GEN5_BL_VERIFY_INTEGRITY_RESP_LEN 12
151#define GEN5_BL_INTEGRITY_CHEKC_PASS 0x00
152#define GEN5_BL_BLOCK_WRITE_RESP_LEN 11
153#define GEN5_BL_READ_APP_INFO_RESP_LEN 31
154#define GEN5_CMD_CALIBRATE 0x28
155#define CYAPA_SENSING_MODE_MUTUAL_CAP_FINE 0x00
156#define CYAPA_SENSING_MODE_SELF_CAP 0x02
157
158#define GEN5_CMD_RETRIEVE_DATA_STRUCTURE 0x24
159#define GEN5_RETRIEVE_MUTUAL_PWC_DATA 0x00
160#define GEN5_RETRIEVE_SELF_CAP_PWC_DATA 0x01
161
162#define GEN5_RETRIEVE_DATA_ELEMENT_SIZE_MASK 0x07
163
164#define GEN5_CMD_EXECUTE_PANEL_SCAN 0x2a
165#define GEN5_CMD_RETRIEVE_PANEL_SCAN 0x2b
166#define GEN5_PANEL_SCAN_MUTUAL_RAW_DATA 0x00
167#define GEN5_PANEL_SCAN_MUTUAL_BASELINE 0x01
168#define GEN5_PANEL_SCAN_MUTUAL_DIFFCOUNT 0x02
169#define GEN5_PANEL_SCAN_SELF_RAW_DATA 0x03
170#define GEN5_PANEL_SCAN_SELF_BASELINE 0x04
171#define GEN5_PANEL_SCAN_SELF_DIFFCOUNT 0x05
172
173/* The offset only valid for reterive PWC and panel scan commands */
174#define GEN5_RESP_DATA_STRUCTURE_OFFSET 10
175#define GEN5_PWC_DATA_ELEMENT_SIZE_MASK 0x07
176
177#define GEN5_NUMBER_OF_TOUCH_OFFSET 5
178#define GEN5_NUMBER_OF_TOUCH_MASK 0x1f
179#define GEN5_BUTTONS_OFFSET 5
180#define GEN5_BUTTONS_MASK 0x0f
181#define GEN5_GET_EVENT_ID(reg) (((reg) >> 5) & 0x03)
182#define GEN5_GET_TOUCH_ID(reg) ((reg) & 0x1f)
183
184#define GEN5_PRODUCT_FAMILY_MASK 0xf000
185#define GEN5_PRODUCT_FAMILY_TRACKPAD 0x1000
186
187#define TSG_INVALID_CMD 0xff
188
189struct cyapa_gen5_touch_record {
190 /*
191 * Bit 7 - 3: reserved
192 * Bit 2 - 0: touch type;
193 * 0 : standard finger;
194 * 1 - 15 : reserved.
195 */
196 u8 touch_type;
197
198 /*
199 * Bit 7: indicates touch liftoff status.
200 * 0 : touch is currently on the panel.
201 * 1 : touch record indicates a liftoff.
202 * Bit 6 - 5: indicates an event associated with this touch instance
203 * 0 : no event
204 * 1 : touchdown
205 * 2 : significant displacement (> active distance)
206 * 3 : liftoff (record reports last known coordinates)
207 * Bit 4 - 0: An arbitrary ID tag associated with a finger
208 * to allow tracking a touch as it moves around the panel.
209 */
210 u8 touch_tip_event_id;
211
212 /* Bit 7 - 0 of X-axis coordinate of the touch in pixel. */
213 u8 x_lo;
214
215 /* Bit 15 - 8 of X-axis coordinate of the touch in pixel. */
216 u8 x_hi;
217
218 /* Bit 7 - 0 of Y-axis coordinate of the touch in pixel. */
219 u8 y_lo;
220
221 /* Bit 15 - 8 of Y-axis coordinate of the touch in pixel. */
222 u8 y_hi;
223
224 /* Touch intensity in counts, pressure value. */
225 u8 z;
226
227 /*
228 * The length of the major axis of the ellipse of contact between
229 * the finger and the panel (ABS_MT_TOUCH_MAJOR).
230 */
231 u8 major_axis_len;
232
233 /*
234 * The length of the minor axis of the ellipse of contact between
235 * the finger and the panel (ABS_MT_TOUCH_MINOR).
236 */
237 u8 minor_axis_len;
238
239 /*
240 * The length of the major axis of the approaching tool.
241 * (ABS_MT_WIDTH_MAJOR)
242 */
243 u8 major_tool_len;
244
245 /*
246 * The length of the minor axis of the approaching tool.
247 * (ABS_MT_WIDTH_MINOR)
248 */
249 u8 minor_tool_len;
250
251 /*
252 * The angle between the panel vertical axis and
253 * the major axis of the contact ellipse. This value is an 8-bit
254 * signed integer. The range is -127 to +127 (corresponding to
255 * -90 degree and +90 degree respectively).
256 * The positive direction is clockwise from the vertical axis.
257 * If the ellipse of contact degenerates into a circle,
258 * orientation is reported as 0.
259 */
260 u8 orientation;
261} __packed;
262
263struct cyapa_gen5_report_data {
264 u8 report_head[GEN5_TOUCH_REPORT_HEAD_SIZE];
265 struct cyapa_gen5_touch_record touch_records[10];
266} __packed;
267
268struct cyapa_tsg_bin_image_head {
269 u8 head_size; /* Unit: bytes, including itself. */
270 u8 ttda_driver_major_version; /* Reserved as 0. */
271 u8 ttda_driver_minor_version; /* Reserved as 0. */
272 u8 fw_major_version;
273 u8 fw_minor_version;
274 u8 fw_revision_control_number[8];
275} __packed;
276
277struct cyapa_tsg_bin_image_data_record {
278 u8 flash_array_id;
279 __be16 row_number;
280 /* The number of bytes of flash data contained in this record. */
281 __be16 record_len;
282 /* The flash program data. */
283 u8 record_data[CYAPA_TSG_FW_ROW_SIZE];
284} __packed;
285
286struct cyapa_tsg_bin_image {
287 struct cyapa_tsg_bin_image_head image_head;
288 struct cyapa_tsg_bin_image_data_record records[0];
289} __packed;
290
291struct gen5_bl_packet_start {
292 u8 sop; /* Start of packet, must be 01h */
293 u8 cmd_code;
294 __le16 data_length; /* Size of data parameter start from data[0] */
295} __packed;
296
297struct gen5_bl_packet_end {
298 __le16 crc;
299 u8 eop; /* End of packet, must be 17h */
300} __packed;
301
302struct gen5_bl_cmd_head {
303 __le16 addr; /* Output report register address, must be 0004h */
304 /* Size of packet not including output report register address */
305 __le16 length;
306 u8 report_id; /* Bootloader output report id, must be 40h */
307 u8 rsvd; /* Reserved, must be 0 */
308 struct gen5_bl_packet_start packet_start;
309 u8 data[0]; /* Command data variable based on commands */
310} __packed;
311
312/* Initiate bootload command data structure. */
313struct gen5_bl_initiate_cmd_data {
314 /* Key must be "A5h 01h 02h 03h FFh FEh FDh 5Ah" */
315 u8 key[CYAPA_TSG_BL_KEY_SIZE];
316 u8 metadata_raw_parameter[CYAPA_TSG_FLASH_MAP_METADATA_SIZE];
317 __le16 metadata_crc;
318} __packed;
319
320struct gen5_bl_metadata_row_params {
321 __le16 size;
322 __le16 maximum_size;
323 __le32 app_start;
324 __le16 app_len;
325 __le16 app_crc;
326 __le32 app_entry;
327 __le32 upgrade_start;
328 __le16 upgrade_len;
329 __le16 entry_row_crc;
330 u8 padding[36]; /* Padding data must be 0 */
331 __le16 metadata_crc; /* CRC starts at offset of 60 */
332} __packed;
333
334/* Bootload program and verify row command data structure */
335struct gen5_bl_flash_row_head {
336 u8 flash_array_id;
337 __le16 flash_row_id;
338 u8 flash_data[0];
339} __packed;
340
341struct gen5_app_cmd_head {
342 __le16 addr; /* Output report register address, must be 0004h */
343 /* Size of packet not including output report register address */
344 __le16 length;
345 u8 report_id; /* Application output report id, must be 2Fh */
346 u8 rsvd; /* Reserved, must be 0 */
347 /*
348 * Bit 7: reserved, must be 0.
349 * Bit 6-0: command code.
350 */
351 u8 cmd_code;
352 u8 parameter_data[0]; /* Parameter data variable based on cmd_code */
353} __packed;
354
355/* Applicaton get/set parameter command data structure */
356struct gen5_app_set_parameter_data {
357 u8 parameter_id;
358 u8 parameter_size;
359 __le32 value;
360} __packed;
361
362struct gen5_app_get_parameter_data {
363 u8 parameter_id;
364} __packed;
365
366struct gen5_retrieve_panel_scan_data {
367 __le16 read_offset;
368 __le16 read_elements;
369 u8 data_id;
370} __packed;
371
372/* Variables to record latest gen5 trackpad power states. */
373#define GEN5_DEV_SET_PWR_STATE(cyapa, s) ((cyapa)->dev_pwr_mode = (s))
374#define GEN5_DEV_GET_PWR_STATE(cyapa) ((cyapa)->dev_pwr_mode)
375#define GEN5_DEV_SET_SLEEP_TIME(cyapa, t) ((cyapa)->dev_sleep_time = (t))
376#define GEN5_DEV_GET_SLEEP_TIME(cyapa) ((cyapa)->dev_sleep_time)
377#define GEN5_DEV_UNINIT_SLEEP_TIME(cyapa) \
378 (((cyapa)->dev_sleep_time) == UNINIT_SLEEP_TIME)
379
380
381static u8 cyapa_gen5_bl_cmd_key[] = { 0xa5, 0x01, 0x02, 0x03,
382 0xff, 0xfe, 0xfd, 0x5a };
383
384static int cyapa_gen5_initialize(struct cyapa *cyapa)
385{
386 struct cyapa_gen5_cmd_states *gen5_pip = &cyapa->cmd_states.gen5;
387
388 init_completion(&gen5_pip->cmd_ready);
389 atomic_set(&gen5_pip->cmd_issued, 0);
390 mutex_init(&gen5_pip->cmd_lock);
391
392 gen5_pip->resp_sort_func = NULL;
393 gen5_pip->in_progress_cmd = TSG_INVALID_CMD;
394 gen5_pip->resp_data = NULL;
395 gen5_pip->resp_len = NULL;
396
397 cyapa->dev_pwr_mode = UNINIT_PWR_MODE;
398 cyapa->dev_sleep_time = UNINIT_SLEEP_TIME;
399
400 return 0;
401}
402
403/* Return negative errno, or else the number of bytes read. */
404static ssize_t cyapa_i2c_pip_read(struct cyapa *cyapa, u8 *buf, size_t size)
405{
406 int ret;
407
408 if (size == 0)
409 return 0;
410
411 if (!buf || size > CYAPA_REG_MAP_SIZE)
412 return -EINVAL;
413
414 ret = i2c_master_recv(cyapa->client, buf, size);
415
416 if (ret != size)
417 return (ret < 0) ? ret : -EIO;
418
419 return size;
420}
421
422/**
423 * Return a negative errno code else zero on success.
424 */
425static ssize_t cyapa_i2c_pip_write(struct cyapa *cyapa, u8 *buf, size_t size)
426{
427 int ret;
428
429 if (!buf || !size)
430 return -EINVAL;
431
432 ret = i2c_master_send(cyapa->client, buf, size);
433
434 if (ret != size)
435 return (ret < 0) ? ret : -EIO;
436
437 return 0;
438}
439
440/**
441 * This function is aimed to dump all not read data in Gen5 trackpad
442 * before send any command, otherwise, the interrupt line will be blocked.
443 */
444static int cyapa_empty_pip_output_data(struct cyapa *cyapa,
445 u8 *buf, int *len, cb_sort func)
446{
447 struct cyapa_gen5_cmd_states *gen5_pip = &cyapa->cmd_states.gen5;
448 int length;
449 int report_count;
450 int empty_count;
451 int buf_len;
452 int error;
453
454 buf_len = 0;
455 if (len) {
456 buf_len = (*len < CYAPA_REG_MAP_SIZE) ?
457 *len : CYAPA_REG_MAP_SIZE;
458 *len = 0;
459 }
460
461 report_count = 8; /* max 7 pending data before command response data */
462 empty_count = 0;
463 do {
464 /*
465 * Depending on testing in cyapa driver, there are max 5 "02 00"
466 * packets between two valid buffered data report in firmware.
467 * So in order to dump all buffered data out and
468 * make interrupt line release for reassert again,
469 * we must set the empty_count check value bigger than 5 to
470 * make it work. Otherwise, in some situation,
471 * the interrupt line may unable to reactive again,
472 * which will cause trackpad device unable to
473 * report data any more.
474 * for example, it may happen in EFT and ESD testing.
475 */
476 if (empty_count > 5)
477 return 0;
478
479 error = cyapa_i2c_pip_read(cyapa, gen5_pip->empty_buf,
480 GEN5_RESP_LENGTH_SIZE);
481 if (error < 0)
482 return error;
483
484 length = get_unaligned_le16(gen5_pip->empty_buf);
485 if (length == GEN5_RESP_LENGTH_SIZE) {
486 empty_count++;
487 continue;
488 } else if (length > CYAPA_REG_MAP_SIZE) {
489 /* Should not happen */
490 return -EINVAL;
491 } else if (length == 0) {
492 /* Application or bootloader launch data polled out. */
493 length = GEN5_RESP_LENGTH_SIZE;
494 if (buf && buf_len && func &&
495 func(cyapa, gen5_pip->empty_buf, length)) {
496 length = min(buf_len, length);
497 memcpy(buf, gen5_pip->empty_buf, length);
498 *len = length;
499 /* Response found, success. */
500 return 0;
501 }
502 continue;
503 }
504
505 error = cyapa_i2c_pip_read(cyapa, gen5_pip->empty_buf, length);
506 if (error < 0)
507 return error;
508
509 report_count--;
510 empty_count = 0;
511 length = get_unaligned_le16(gen5_pip->empty_buf);
512 if (length <= GEN5_RESP_LENGTH_SIZE) {
513 empty_count++;
514 } else if (buf && buf_len && func &&
515 func(cyapa, gen5_pip->empty_buf, length)) {
516 length = min(buf_len, length);
517 memcpy(buf, gen5_pip->empty_buf, length);
518 *len = length;
519 /* Response found, success. */
520 return 0;
521 }
522
523 error = -EINVAL;
524 } while (report_count);
525
526 return error;
527}
528
529static int cyapa_do_i2c_pip_cmd_irq_sync(
530 struct cyapa *cyapa,
531 u8 *cmd, size_t cmd_len,
532 unsigned long timeout)
533{
534 struct cyapa_gen5_cmd_states *gen5_pip = &cyapa->cmd_states.gen5;
535 int error;
536
537 /* Wait for interrupt to set ready completion */
538 init_completion(&gen5_pip->cmd_ready);
539
540 atomic_inc(&gen5_pip->cmd_issued);
541 error = cyapa_i2c_pip_write(cyapa, cmd, cmd_len);
542 if (error) {
543 atomic_dec(&gen5_pip->cmd_issued);
544 return (error < 0) ? error : -EIO;
545 }
546
547 /* Wait for interrupt to indicate command is completed. */
548 timeout = wait_for_completion_timeout(&gen5_pip->cmd_ready,
549 msecs_to_jiffies(timeout));
550 if (timeout == 0) {
551 atomic_dec(&gen5_pip->cmd_issued);
552 return -ETIMEDOUT;
553 }
554
555 return 0;
556}
557
558static int cyapa_do_i2c_pip_cmd_polling(
559 struct cyapa *cyapa,
560 u8 *cmd, size_t cmd_len,
561 u8 *resp_data, int *resp_len,
562 unsigned long timeout,
563 cb_sort func)
564{
565 struct cyapa_gen5_cmd_states *gen5_pip = &cyapa->cmd_states.gen5;
566 int tries;
567 int length;
568 int error;
569
570 atomic_inc(&gen5_pip->cmd_issued);
571 error = cyapa_i2c_pip_write(cyapa, cmd, cmd_len);
572 if (error) {
573 atomic_dec(&gen5_pip->cmd_issued);
574 return error < 0 ? error : -EIO;
575 }
576
577 length = resp_len ? *resp_len : 0;
578 if (resp_data && resp_len && length != 0 && func) {
579 tries = timeout / 5;
580 do {
581 usleep_range(3000, 5000);
582 *resp_len = length;
583 error = cyapa_empty_pip_output_data(cyapa,
584 resp_data, resp_len, func);
585 if (error || *resp_len == 0)
586 continue;
587 else
588 break;
589 } while (--tries > 0);
590 if ((error || *resp_len == 0) || tries <= 0)
591 error = error ? error : -ETIMEDOUT;
592 }
593
594 atomic_dec(&gen5_pip->cmd_issued);
595 return error;
596}
597
598static int cyapa_i2c_pip_cmd_irq_sync(
599 struct cyapa *cyapa,
600 u8 *cmd, int cmd_len,
601 u8 *resp_data, int *resp_len,
602 unsigned long timeout,
603 cb_sort func,
604 bool irq_mode)
605{
606 struct cyapa_gen5_cmd_states *gen5_pip = &cyapa->cmd_states.gen5;
607 int error;
608
609 if (!cmd || !cmd_len)
610 return -EINVAL;
611
612 /* Commands must be serialized. */
613 error = mutex_lock_interruptible(&gen5_pip->cmd_lock);
614 if (error)
615 return error;
616
617 gen5_pip->resp_sort_func = func;
618 gen5_pip->resp_data = resp_data;
619 gen5_pip->resp_len = resp_len;
620
621 if (cmd_len >= GEN5_MIN_APP_CMD_LENGTH &&
622 cmd[4] == GEN5_APP_CMD_REPORT_ID) {
623 /* Application command */
624 gen5_pip->in_progress_cmd = cmd[6] & 0x7f;
625 } else if (cmd_len >= GEN5_MIN_BL_CMD_LENGTH &&
626 cmd[4] == GEN5_BL_CMD_REPORT_ID) {
627 /* Bootloader command */
628 gen5_pip->in_progress_cmd = cmd[7];
629 }
630
631 /* Send command data, wait and read output response data's length. */
632 if (irq_mode) {
633 gen5_pip->is_irq_mode = true;
634 error = cyapa_do_i2c_pip_cmd_irq_sync(cyapa, cmd, cmd_len,
635 timeout);
636 if (error == -ETIMEDOUT && resp_data &&
637 resp_len && *resp_len != 0 && func) {
638 /*
639 * For some old version, there was no interrupt for
640 * the command response data, so need to poll here
641 * to try to get the response data.
642 */
643 error = cyapa_empty_pip_output_data(cyapa,
644 resp_data, resp_len, func);
645 if (error || *resp_len == 0)
646 error = error ? error : -ETIMEDOUT;
647 }
648 } else {
649 gen5_pip->is_irq_mode = false;
650 error = cyapa_do_i2c_pip_cmd_polling(cyapa, cmd, cmd_len,
651 resp_data, resp_len, timeout, func);
652 }
653
654 gen5_pip->resp_sort_func = NULL;
655 gen5_pip->resp_data = NULL;
656 gen5_pip->resp_len = NULL;
657 gen5_pip->in_progress_cmd = TSG_INVALID_CMD;
658
659 mutex_unlock(&gen5_pip->cmd_lock);
660 return error;
661}
662
663static bool cyapa_gen5_sort_tsg_pip_bl_resp_data(struct cyapa *cyapa,
664 u8 *data, int len)
665{
666 if (!data || len < GEN5_MIN_BL_RESP_LENGTH)
667 return false;
668
669 /* Bootloader input report id 30h */
670 if (data[GEN5_RESP_REPORT_ID_OFFSET] == GEN5_BL_RESP_REPORT_ID &&
671 data[GEN5_RESP_RSVD_OFFSET] == GEN5_RESP_RSVD_KEY &&
672 data[GEN5_RESP_BL_SOP_OFFSET] == GEN5_SOP_KEY)
673 return true;
674
675 return false;
676}
677
678static bool cyapa_gen5_sort_tsg_pip_app_resp_data(struct cyapa *cyapa,
679 u8 *data, int len)
680{
681 struct cyapa_gen5_cmd_states *gen5_pip = &cyapa->cmd_states.gen5;
682 int resp_len;
683
684 if (!data || len < GEN5_MIN_APP_RESP_LENGTH)
685 return false;
686
687 if (data[GEN5_RESP_REPORT_ID_OFFSET] == GEN5_APP_RESP_REPORT_ID &&
688 data[GEN5_RESP_RSVD_OFFSET] == GEN5_RESP_RSVD_KEY) {
689 resp_len = get_unaligned_le16(&data[GEN5_RESP_LENGTH_OFFSET]);
690 if (GET_GEN5_CMD_CODE(data[GEN5_RESP_APP_CMD_OFFSET]) == 0x00 &&
691 resp_len == GEN5_UNSUPPORTED_CMD_RESP_LENGTH &&
692 data[5] == gen5_pip->in_progress_cmd) {
693 /* Unsupported command code */
694 return false;
695 } else if (GET_GEN5_CMD_CODE(data[GEN5_RESP_APP_CMD_OFFSET]) ==
696 gen5_pip->in_progress_cmd) {
697 /* Correct command response received */
698 return true;
699 }
700 }
701
702 return false;
703}
704
705static bool cyapa_gen5_sort_application_launch_data(struct cyapa *cyapa,
706 u8 *buf, int len)
707{
708 if (buf == NULL || len < GEN5_RESP_LENGTH_SIZE)
709 return false;
710
711 /*
712 * After reset or power on, trackpad device always sets to 0x00 0x00
713 * to indicate a reset or power on event.
714 */
715 if (buf[0] == 0 && buf[1] == 0)
716 return true;
717
718 return false;
719}
720
721static bool cyapa_gen5_sort_hid_descriptor_data(struct cyapa *cyapa,
722 u8 *buf, int len)
723{
724 int resp_len;
725 int max_output_len;
726
727 /* Check hid descriptor. */
728 if (len != GEN5_HID_DESCRIPTOR_SIZE)
729 return false;
730
731 resp_len = get_unaligned_le16(&buf[GEN5_RESP_LENGTH_OFFSET]);
732 max_output_len = get_unaligned_le16(&buf[16]);
733 if (resp_len == GEN5_HID_DESCRIPTOR_SIZE) {
734 if (buf[GEN5_RESP_REPORT_ID_OFFSET] == GEN5_BL_HID_REPORT_ID &&
735 max_output_len == GEN5_BL_MAX_OUTPUT_LENGTH) {
736 /* BL mode HID Descriptor */
737 return true;
738 } else if ((buf[GEN5_RESP_REPORT_ID_OFFSET] ==
739 GEN5_APP_HID_REPORT_ID) &&
740 max_output_len == GEN5_APP_MAX_OUTPUT_LENGTH) {
741 /* APP mode HID Descriptor */
742 return true;
743 }
744 }
745
746 return false;
747}
748
749static bool cyapa_gen5_sort_deep_sleep_data(struct cyapa *cyapa,
750 u8 *buf, int len)
751{
752 if (len == GEN5_DEEP_SLEEP_RESP_LENGTH &&
753 buf[GEN5_RESP_REPORT_ID_OFFSET] ==
754 GEN5_APP_DEEP_SLEEP_REPORT_ID &&
755 (buf[4] & GEN5_DEEP_SLEEP_OPCODE_MASK) ==
756 GEN5_DEEP_SLEEP_OPCODE)
757 return true;
758 return false;
759}
760
761static int gen5_idle_state_parse(struct cyapa *cyapa)
762{
763 u8 resp_data[GEN5_HID_DESCRIPTOR_SIZE];
764 int max_output_len;
765 int length;
766 u8 cmd[2];
767 int ret;
768 int error;
769
770 /*
771 * Dump all buffered data firstly for the situation
772 * when the trackpad is just power on the cyapa go here.
773 */
774 cyapa_empty_pip_output_data(cyapa, NULL, NULL, NULL);
775
776 memset(resp_data, 0, sizeof(resp_data));
777 ret = cyapa_i2c_pip_read(cyapa, resp_data, 3);
778 if (ret != 3)
779 return ret < 0 ? ret : -EIO;
780
781 length = get_unaligned_le16(&resp_data[GEN5_RESP_LENGTH_OFFSET]);
782 if (length == GEN5_RESP_LENGTH_SIZE) {
783 /* Normal state of Gen5 with no data to respose */
784 cyapa->gen = CYAPA_GEN5;
785
786 cyapa_empty_pip_output_data(cyapa, NULL, NULL, NULL);
787
788 /* Read description from trackpad device */
789 cmd[0] = 0x01;
790 cmd[1] = 0x00;
791 length = GEN5_HID_DESCRIPTOR_SIZE;
792 error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
793 cmd, GEN5_RESP_LENGTH_SIZE,
794 resp_data, &length,
795 300,
796 cyapa_gen5_sort_hid_descriptor_data,
797 false);
798 if (error)
799 return error;
800
801 length = get_unaligned_le16(
802 &resp_data[GEN5_RESP_LENGTH_OFFSET]);
803 max_output_len = get_unaligned_le16(&resp_data[16]);
804 if ((length == GEN5_HID_DESCRIPTOR_SIZE ||
805 length == GEN5_RESP_LENGTH_SIZE) &&
806 (resp_data[GEN5_RESP_REPORT_ID_OFFSET] ==
807 GEN5_BL_HID_REPORT_ID) &&
808 max_output_len == GEN5_BL_MAX_OUTPUT_LENGTH) {
809 /* BL mode HID Description read */
810 cyapa->state = CYAPA_STATE_GEN5_BL;
811 } else if ((length == GEN5_HID_DESCRIPTOR_SIZE ||
812 length == GEN5_RESP_LENGTH_SIZE) &&
813 (resp_data[GEN5_RESP_REPORT_ID_OFFSET] ==
814 GEN5_APP_HID_REPORT_ID) &&
815 max_output_len == GEN5_APP_MAX_OUTPUT_LENGTH) {
816 /* APP mode HID Description read */
817 cyapa->state = CYAPA_STATE_GEN5_APP;
818 } else {
819 /* Should not happen!!! */
820 cyapa->state = CYAPA_STATE_NO_DEVICE;
821 }
822 }
823
824 return 0;
825}
826
827static int gen5_hid_description_header_parse(struct cyapa *cyapa, u8 *reg_data)
828{
829 int length;
830 u8 resp_data[32];
831 int max_output_len;
832 int ret;
833
834 /* 0x20 0x00 0xF7 is Gen5 Application HID Description Header;
835 * 0x20 0x00 0xFF is Gen5 Booloader HID Description Header.
836 *
837 * Must read HID Description content through out,
838 * otherwise Gen5 trackpad cannot response next command
839 * or report any touch or button data.
840 */
841 ret = cyapa_i2c_pip_read(cyapa, resp_data,
842 GEN5_HID_DESCRIPTOR_SIZE);
843 if (ret != GEN5_HID_DESCRIPTOR_SIZE)
844 return ret < 0 ? ret : -EIO;
845 length = get_unaligned_le16(&resp_data[GEN5_RESP_LENGTH_OFFSET]);
846 max_output_len = get_unaligned_le16(&resp_data[16]);
847 if (length == GEN5_RESP_LENGTH_SIZE) {
848 if (reg_data[GEN5_RESP_REPORT_ID_OFFSET] ==
849 GEN5_BL_HID_REPORT_ID) {
850 /*
851 * BL mode HID Description has been previously
852 * read out.
853 */
854 cyapa->gen = CYAPA_GEN5;
855 cyapa->state = CYAPA_STATE_GEN5_BL;
856 } else {
857 /*
858 * APP mode HID Description has been previously
859 * read out.
860 */
861 cyapa->gen = CYAPA_GEN5;
862 cyapa->state = CYAPA_STATE_GEN5_APP;
863 }
864 } else if (length == GEN5_HID_DESCRIPTOR_SIZE &&
865 resp_data[2] == GEN5_BL_HID_REPORT_ID &&
866 max_output_len == GEN5_BL_MAX_OUTPUT_LENGTH) {
867 /* BL mode HID Description read. */
868 cyapa->gen = CYAPA_GEN5;
869 cyapa->state = CYAPA_STATE_GEN5_BL;
870 } else if (length == GEN5_HID_DESCRIPTOR_SIZE &&
871 (resp_data[GEN5_RESP_REPORT_ID_OFFSET] ==
872 GEN5_APP_HID_REPORT_ID) &&
873 max_output_len == GEN5_APP_MAX_OUTPUT_LENGTH) {
874 /* APP mode HID Description read. */
875 cyapa->gen = CYAPA_GEN5;
876 cyapa->state = CYAPA_STATE_GEN5_APP;
877 } else {
878 /* Should not happen!!! */
879 cyapa->state = CYAPA_STATE_NO_DEVICE;
880 }
881
882 return 0;
883}
884
885static int gen5_report_data_header_parse(struct cyapa *cyapa, u8 *reg_data)
886{
887 int length;
888
889 length = get_unaligned_le16(&reg_data[GEN5_RESP_LENGTH_OFFSET]);
890 switch (reg_data[GEN5_RESP_REPORT_ID_OFFSET]) {
891 case GEN5_TOUCH_REPORT_ID:
892 if (length < GEN5_TOUCH_REPORT_HEAD_SIZE ||
893 length > GEN5_TOUCH_REPORT_MAX_SIZE)
894 return -EINVAL;
895 break;
896 case GEN5_BTN_REPORT_ID:
897 case GEN5_OLD_PUSH_BTN_REPORT_ID:
898 case GEN5_PUSH_BTN_REPORT_ID:
899 if (length < GEN5_BTN_REPORT_HEAD_SIZE ||
900 length > GEN5_BTN_REPORT_MAX_SIZE)
901 return -EINVAL;
902 break;
903 case GEN5_WAKEUP_EVENT_REPORT_ID:
904 if (length != GEN5_WAKEUP_EVENT_SIZE)
905 return -EINVAL;
906 break;
907 default:
908 return -EINVAL;
909 }
910
911 cyapa->gen = CYAPA_GEN5;
912 cyapa->state = CYAPA_STATE_GEN5_APP;
913 return 0;
914}
915
916static int gen5_cmd_resp_header_parse(struct cyapa *cyapa, u8 *reg_data)
917{
918 struct cyapa_gen5_cmd_states *gen5_pip = &cyapa->cmd_states.gen5;
919 int length;
920 int ret;
921
922 /*
923 * Must read report data through out,
924 * otherwise Gen5 trackpad cannot response next command
925 * or report any touch or button data.
926 */
927 length = get_unaligned_le16(&reg_data[GEN5_RESP_LENGTH_OFFSET]);
928 ret = cyapa_i2c_pip_read(cyapa, gen5_pip->empty_buf, length);
929 if (ret != length)
930 return ret < 0 ? ret : -EIO;
931
932 if (length == GEN5_RESP_LENGTH_SIZE) {
933 /* Previous command has read the data through out. */
934 if (reg_data[GEN5_RESP_REPORT_ID_OFFSET] ==
935 GEN5_BL_RESP_REPORT_ID) {
936 /* Gen5 BL command response data detected */
937 cyapa->gen = CYAPA_GEN5;
938 cyapa->state = CYAPA_STATE_GEN5_BL;
939 } else {
940 /* Gen5 APP command response data detected */
941 cyapa->gen = CYAPA_GEN5;
942 cyapa->state = CYAPA_STATE_GEN5_APP;
943 }
944 } else if ((gen5_pip->empty_buf[GEN5_RESP_REPORT_ID_OFFSET] ==
945 GEN5_BL_RESP_REPORT_ID) &&
946 (gen5_pip->empty_buf[GEN5_RESP_RSVD_OFFSET] ==
947 GEN5_RESP_RSVD_KEY) &&
948 (gen5_pip->empty_buf[GEN5_RESP_BL_SOP_OFFSET] ==
949 GEN5_SOP_KEY) &&
950 (gen5_pip->empty_buf[length - 1] ==
951 GEN5_EOP_KEY)) {
952 /* Gen5 BL command response data detected */
953 cyapa->gen = CYAPA_GEN5;
954 cyapa->state = CYAPA_STATE_GEN5_BL;
955 } else if (gen5_pip->empty_buf[GEN5_RESP_REPORT_ID_OFFSET] ==
956 GEN5_APP_RESP_REPORT_ID &&
957 gen5_pip->empty_buf[GEN5_RESP_RSVD_OFFSET] ==
958 GEN5_RESP_RSVD_KEY) {
959 /* Gen5 APP command response data detected */
960 cyapa->gen = CYAPA_GEN5;
961 cyapa->state = CYAPA_STATE_GEN5_APP;
962 } else {
963 /* Should not happen!!! */
964 cyapa->state = CYAPA_STATE_NO_DEVICE;
965 }
966
967 return 0;
968}
969
970static int cyapa_gen5_state_parse(struct cyapa *cyapa, u8 *reg_data, int len)
971{
972 int length;
973
974 if (!reg_data || len < 3)
975 return -EINVAL;
976
977 cyapa->state = CYAPA_STATE_NO_DEVICE;
978
979 /* Parse based on Gen5 characteristic registers and bits */
980 length = get_unaligned_le16(&reg_data[GEN5_RESP_LENGTH_OFFSET]);
981 if (length == 0 || length == GEN5_RESP_LENGTH_SIZE) {
982 gen5_idle_state_parse(cyapa);
983 } else if (length == GEN5_HID_DESCRIPTOR_SIZE &&
984 (reg_data[2] == GEN5_BL_HID_REPORT_ID ||
985 reg_data[2] == GEN5_APP_HID_REPORT_ID)) {
986 gen5_hid_description_header_parse(cyapa, reg_data);
987 } else if ((length == GEN5_APP_REPORT_DESCRIPTOR_SIZE ||
988 length == GEN5_APP_CONTRACT_REPORT_DESCRIPTOR_SIZE) &&
989 reg_data[2] == GEN5_APP_REPORT_DESCRIPTOR_ID) {
990 /* 0xEE 0x00 0xF6 is Gen5 APP report description header. */
991 cyapa->gen = CYAPA_GEN5;
992 cyapa->state = CYAPA_STATE_GEN5_APP;
993 } else if (length == GEN5_BL_REPORT_DESCRIPTOR_SIZE &&
994 reg_data[2] == GEN5_BL_REPORT_DESCRIPTOR_ID) {
995 /* 0x1D 0x00 0xFE is Gen5 BL report descriptior header. */
996 cyapa->gen = CYAPA_GEN5;
997 cyapa->state = CYAPA_STATE_GEN5_BL;
998 } else if (reg_data[2] == GEN5_TOUCH_REPORT_ID ||
999 reg_data[2] == GEN5_BTN_REPORT_ID ||
1000 reg_data[2] == GEN5_OLD_PUSH_BTN_REPORT_ID ||
1001 reg_data[2] == GEN5_PUSH_BTN_REPORT_ID ||
1002 reg_data[2] == GEN5_WAKEUP_EVENT_REPORT_ID) {
1003 gen5_report_data_header_parse(cyapa, reg_data);
1004 } else if (reg_data[2] == GEN5_BL_RESP_REPORT_ID ||
1005 reg_data[2] == GEN5_APP_RESP_REPORT_ID) {
1006 gen5_cmd_resp_header_parse(cyapa, reg_data);
1007 }
1008
1009 if (cyapa->gen == CYAPA_GEN5) {
1010 /*
1011 * Must read the content (e.g.: report description and so on)
1012 * from trackpad device throughout. Otherwise,
1013 * Gen5 trackpad cannot response to next command or
1014 * report any touch or button data later.
1015 */
1016 cyapa_empty_pip_output_data(cyapa, NULL, NULL, NULL);
1017
1018 if (cyapa->state == CYAPA_STATE_GEN5_APP ||
1019 cyapa->state == CYAPA_STATE_GEN5_BL)
1020 return 0;
1021 }
1022
1023 return -EAGAIN;
1024}
1025
1026static int cyapa_gen5_bl_initiate(struct cyapa *cyapa,
1027 const struct firmware *fw)
1028{
1029 struct cyapa_tsg_bin_image *image;
1030 struct gen5_bl_cmd_head *bl_cmd_head;
1031 struct gen5_bl_packet_start *bl_packet_start;
1032 struct gen5_bl_initiate_cmd_data *cmd_data;
1033 struct gen5_bl_packet_end *bl_packet_end;
1034 u8 cmd[CYAPA_TSG_MAX_CMD_SIZE];
1035 int cmd_len;
1036 u16 cmd_data_len;
1037 u16 cmd_crc = 0;
1038 u16 meta_data_crc = 0;
1039 u8 resp_data[11];
1040 int resp_len;
1041 int records_num;
1042 u8 *data;
1043 int error;
1044
1045 /* Try to dump all buffered report data before any send command. */
1046 cyapa_empty_pip_output_data(cyapa, NULL, NULL, NULL);
1047
1048 memset(cmd, 0, CYAPA_TSG_MAX_CMD_SIZE);
1049 bl_cmd_head = (struct gen5_bl_cmd_head *)cmd;
1050 cmd_data_len = CYAPA_TSG_BL_KEY_SIZE + CYAPA_TSG_FLASH_MAP_BLOCK_SIZE;
1051 cmd_len = sizeof(struct gen5_bl_cmd_head) + cmd_data_len +
1052 sizeof(struct gen5_bl_packet_end);
1053
1054 put_unaligned_le16(GEN5_OUTPUT_REPORT_ADDR, &bl_cmd_head->addr);
1055 put_unaligned_le16(cmd_len - 2, &bl_cmd_head->length);
1056 bl_cmd_head->report_id = GEN5_BL_CMD_REPORT_ID;
1057
1058 bl_packet_start = &bl_cmd_head->packet_start;
1059 bl_packet_start->sop = GEN5_SOP_KEY;
1060 bl_packet_start->cmd_code = GEN5_BL_CMD_INITIATE_BL;
1061 /* 8 key bytes and 128 bytes block size */
1062 put_unaligned_le16(cmd_data_len, &bl_packet_start->data_length);
1063
1064 cmd_data = (struct gen5_bl_initiate_cmd_data *)bl_cmd_head->data;
1065 memcpy(cmd_data->key, cyapa_gen5_bl_cmd_key, CYAPA_TSG_BL_KEY_SIZE);
1066
1067 /* Copy 60 bytes Meta Data Row Parameters */
1068 image = (struct cyapa_tsg_bin_image *)fw->data;
1069 records_num = (fw->size - sizeof(struct cyapa_tsg_bin_image_head)) /
1070 sizeof(struct cyapa_tsg_bin_image_data_record);
1071 /* APP_INTEGRITY row is always the last row block */
1072 data = image->records[records_num - 1].record_data;
1073 memcpy(cmd_data->metadata_raw_parameter, data,
1074 CYAPA_TSG_FLASH_MAP_METADATA_SIZE);
1075
1076 meta_data_crc = crc_itu_t(0xffff, cmd_data->metadata_raw_parameter,
1077 CYAPA_TSG_FLASH_MAP_METADATA_SIZE);
1078 put_unaligned_le16(meta_data_crc, &cmd_data->metadata_crc);
1079
1080 bl_packet_end = (struct gen5_bl_packet_end *)(bl_cmd_head->data +
1081 cmd_data_len);
1082 cmd_crc = crc_itu_t(0xffff, (u8 *)bl_packet_start,
1083 sizeof(struct gen5_bl_packet_start) + cmd_data_len);
1084 put_unaligned_le16(cmd_crc, &bl_packet_end->crc);
1085 bl_packet_end->eop = GEN5_EOP_KEY;
1086
1087 resp_len = sizeof(resp_data);
1088 error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
1089 cmd, cmd_len,
1090 resp_data, &resp_len, 12000,
1091 cyapa_gen5_sort_tsg_pip_bl_resp_data, true);
1092 if (error || resp_len != GEN5_BL_INITIATE_RESP_LEN ||
1093 resp_data[2] != GEN5_BL_RESP_REPORT_ID ||
1094 !GEN5_CMD_COMPLETE_SUCCESS(resp_data[5]))
1095 return error ? error : -EAGAIN;
1096
1097 return 0;
1098}
1099
1100static bool cyapa_gen5_sort_bl_exit_data(struct cyapa *cyapa, u8 *buf, int len)
1101{
1102 if (buf == NULL || len < GEN5_RESP_LENGTH_SIZE)
1103 return false;
1104
1105 if (buf[0] == 0 && buf[1] == 0)
1106 return true;
1107
1108 /* Exit bootloader failed for some reason. */
1109 if (len == GEN5_BL_FAIL_EXIT_RESP_LEN &&
1110 buf[GEN5_RESP_REPORT_ID_OFFSET] ==
1111 GEN5_BL_RESP_REPORT_ID &&
1112 buf[GEN5_RESP_RSVD_OFFSET] == GEN5_RESP_RSVD_KEY &&
1113 buf[GEN5_RESP_BL_SOP_OFFSET] == GEN5_SOP_KEY &&
1114 buf[10] == GEN5_EOP_KEY)
1115 return true;
1116
1117 return false;
1118}
1119
1120static int cyapa_gen5_bl_exit(struct cyapa *cyapa)
1121{
1122
1123 u8 bl_gen5_bl_exit[] = { 0x04, 0x00,
1124 0x0B, 0x00, 0x40, 0x00, 0x01, 0x3b, 0x00, 0x00,
1125 0x20, 0xc7, 0x17
1126 };
1127 u8 resp_data[11];
1128 int resp_len;
1129 int error;
1130
1131 resp_len = sizeof(resp_data);
1132 error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
1133 bl_gen5_bl_exit, sizeof(bl_gen5_bl_exit),
1134 resp_data, &resp_len,
1135 5000, cyapa_gen5_sort_bl_exit_data, false);
1136 if (error)
1137 return error;
1138
1139 if (resp_len == GEN5_BL_FAIL_EXIT_RESP_LEN ||
1140 resp_data[GEN5_RESP_REPORT_ID_OFFSET] ==
1141 GEN5_BL_RESP_REPORT_ID)
1142 return -EAGAIN;
1143
1144 if (resp_data[0] == 0x00 && resp_data[1] == 0x00)
1145 return 0;
1146
1147 return -ENODEV;
1148}
1149
1150static int cyapa_gen5_bl_enter(struct cyapa *cyapa)
1151{
1152 u8 cmd[] = { 0x04, 0x00, 0x05, 0x00, 0x2F, 0x00, 0x01 };
1153 u8 resp_data[2];
1154 int resp_len;
1155 int error;
1156
1157 error = cyapa_poll_state(cyapa, 500);
1158 if (error < 0)
1159 return error;
1160 if (cyapa->gen != CYAPA_GEN5)
1161 return -EINVAL;
1162
1163 /* Already in Gen5 BL. Skipping exit. */
1164 if (cyapa->state == CYAPA_STATE_GEN5_BL)
1165 return 0;
1166
1167 if (cyapa->state != CYAPA_STATE_GEN5_APP)
1168 return -EAGAIN;
1169
1170 /* Try to dump all buffered report data before any send command. */
1171 cyapa_empty_pip_output_data(cyapa, NULL, NULL, NULL);
1172
1173 /*
1174 * Send bootloader enter command to trackpad device,
1175 * after enter bootloader, the response data is two bytes of 0x00 0x00.
1176 */
1177 resp_len = sizeof(resp_data);
1178 memset(resp_data, 0, resp_len);
1179 error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
1180 cmd, sizeof(cmd),
1181 resp_data, &resp_len,
1182 5000, cyapa_gen5_sort_application_launch_data,
1183 true);
1184 if (error || resp_data[0] != 0x00 || resp_data[1] != 0x00)
1185 return error < 0 ? error : -EAGAIN;
1186
1187 cyapa->operational = false;
1188 cyapa->state = CYAPA_STATE_GEN5_BL;
1189 return 0;
1190}
1191
1192static int cyapa_gen5_check_fw(struct cyapa *cyapa, const struct firmware *fw)
1193{
1194 struct device *dev = &cyapa->client->dev;
1195 const struct cyapa_tsg_bin_image *image = (const void *)fw->data;
1196 const struct cyapa_tsg_bin_image_data_record *app_integrity;
1197 const struct gen5_bl_metadata_row_params *metadata;
1198 size_t flash_records_count;
1199 u32 fw_app_start, fw_upgrade_start;
1200 u16 fw_app_len, fw_upgrade_len;
1201 u16 app_crc;
1202 u16 app_integrity_crc;
1203 int record_index;
1204 int i;
1205
1206 flash_records_count = (fw->size -
1207 sizeof(struct cyapa_tsg_bin_image_head)) /
1208 sizeof(struct cyapa_tsg_bin_image_data_record);
1209
1210 /*
1211 * APP_INTEGRITY row is always the last row block,
1212 * and the row id must be 0x01ff.
1213 */
1214 app_integrity = &image->records[flash_records_count - 1];
1215
1216 if (app_integrity->flash_array_id != 0x00 ||
1217 get_unaligned_be16(&app_integrity->row_number) != 0x01ff) {
1218 dev_err(dev, "%s: invalid app_integrity data.\n", __func__);
1219 return -EINVAL;
1220 }
1221
1222 metadata = (const void *)app_integrity->record_data;
1223
1224 /* Verify app_integrity crc */
1225 app_integrity_crc = crc_itu_t(0xffff, app_integrity->record_data,
1226 CYAPA_TSG_APP_INTEGRITY_SIZE);
1227 if (app_integrity_crc != get_unaligned_le16(&metadata->metadata_crc)) {
1228 dev_err(dev, "%s: invalid app_integrity crc.\n", __func__);
1229 return -EINVAL;
1230 }
1231
1232 fw_app_start = get_unaligned_le32(&metadata->app_start);
1233 fw_app_len = get_unaligned_le16(&metadata->app_len);
1234 fw_upgrade_start = get_unaligned_le32(&metadata->upgrade_start);
1235 fw_upgrade_len = get_unaligned_le16(&metadata->upgrade_len);
1236
1237 if (fw_app_start % CYAPA_TSG_FW_ROW_SIZE ||
1238 fw_app_len % CYAPA_TSG_FW_ROW_SIZE ||
1239 fw_upgrade_start % CYAPA_TSG_FW_ROW_SIZE ||
1240 fw_upgrade_len % CYAPA_TSG_FW_ROW_SIZE) {
1241 dev_err(dev, "%s: invalid image alignment.\n", __func__);
1242 return -EINVAL;
1243 }
1244
1245 /*
1246 * Verify application image CRC
1247 */
1248 record_index = fw_app_start / CYAPA_TSG_FW_ROW_SIZE -
1249 CYAPA_TSG_IMG_START_ROW_NUM;
1250 app_crc = 0xffffU;
1251 for (i = 0; i < fw_app_len / CYAPA_TSG_FW_ROW_SIZE; i++) {
1252 const u8 *data = image->records[record_index + i].record_data;
1253 app_crc = crc_itu_t(app_crc, data, CYAPA_TSG_FW_ROW_SIZE);
1254 }
1255
1256 if (app_crc != get_unaligned_le16(&metadata->app_crc)) {
1257 dev_err(dev, "%s: invalid firmware app crc check.\n", __func__);
1258 return -EINVAL;
1259 }
1260
1261 return 0;
1262}
1263
1264static int cyapa_gen5_write_fw_block(struct cyapa *cyapa,
1265 struct cyapa_tsg_bin_image_data_record *flash_record)
1266{
1267 struct gen5_bl_cmd_head *bl_cmd_head;
1268 struct gen5_bl_packet_start *bl_packet_start;
1269 struct gen5_bl_flash_row_head *flash_row_head;
1270 struct gen5_bl_packet_end *bl_packet_end;
1271 u8 cmd[CYAPA_TSG_MAX_CMD_SIZE];
1272 u16 cmd_len;
1273 u8 flash_array_id;
1274 u16 flash_row_id;
1275 u16 record_len;
1276 u8 *record_data;
1277 u16 data_len;
1278 u16 crc;
1279 u8 resp_data[11];
1280 int resp_len;
1281 int error;
1282
1283 flash_array_id = flash_record->flash_array_id;
1284 flash_row_id = get_unaligned_be16(&flash_record->row_number);
1285 record_len = get_unaligned_be16(&flash_record->record_len);
1286 record_data = flash_record->record_data;
1287
1288 memset(cmd, 0, CYAPA_TSG_MAX_CMD_SIZE);
1289 bl_cmd_head = (struct gen5_bl_cmd_head *)cmd;
1290 bl_packet_start = &bl_cmd_head->packet_start;
1291 cmd_len = sizeof(struct gen5_bl_cmd_head) +
1292 sizeof(struct gen5_bl_flash_row_head) +
1293 CYAPA_TSG_FLASH_MAP_BLOCK_SIZE +
1294 sizeof(struct gen5_bl_packet_end);
1295
1296 put_unaligned_le16(GEN5_OUTPUT_REPORT_ADDR, &bl_cmd_head->addr);
1297 /* Don't include 2 bytes register address */
1298 put_unaligned_le16(cmd_len - 2, &bl_cmd_head->length);
1299 bl_cmd_head->report_id = GEN5_BL_CMD_REPORT_ID;
1300 bl_packet_start->sop = GEN5_SOP_KEY;
1301 bl_packet_start->cmd_code = GEN5_BL_CMD_PROGRAM_VERIFY_ROW;
1302
1303 /* 1 (Flash Array ID) + 2 (Flash Row ID) + 128 (flash data) */
1304 data_len = sizeof(struct gen5_bl_flash_row_head) + record_len;
1305 put_unaligned_le16(data_len, &bl_packet_start->data_length);
1306
1307 flash_row_head = (struct gen5_bl_flash_row_head *)bl_cmd_head->data;
1308 flash_row_head->flash_array_id = flash_array_id;
1309 put_unaligned_le16(flash_row_id, &flash_row_head->flash_row_id);
1310 memcpy(flash_row_head->flash_data, record_data, record_len);
1311
1312 bl_packet_end = (struct gen5_bl_packet_end *)(bl_cmd_head->data +
1313 data_len);
1314 crc = crc_itu_t(0xffff, (u8 *)bl_packet_start,
1315 sizeof(struct gen5_bl_packet_start) + data_len);
1316 put_unaligned_le16(crc, &bl_packet_end->crc);
1317 bl_packet_end->eop = GEN5_EOP_KEY;
1318
1319 resp_len = sizeof(resp_data);
1320 error = cyapa_i2c_pip_cmd_irq_sync(cyapa, cmd, cmd_len,
1321 resp_data, &resp_len,
1322 500, cyapa_gen5_sort_tsg_pip_bl_resp_data, true);
1323 if (error || resp_len != GEN5_BL_BLOCK_WRITE_RESP_LEN ||
1324 resp_data[2] != GEN5_BL_RESP_REPORT_ID ||
1325 !GEN5_CMD_COMPLETE_SUCCESS(resp_data[5]))
1326 return error < 0 ? error : -EAGAIN;
1327
1328 return 0;
1329}
1330
1331static int cyapa_gen5_do_fw_update(struct cyapa *cyapa,
1332 const struct firmware *fw)
1333{
1334 struct device *dev = &cyapa->client->dev;
1335 struct cyapa_tsg_bin_image_data_record *flash_record;
1336 struct cyapa_tsg_bin_image *image =
1337 (struct cyapa_tsg_bin_image *)fw->data;
1338 int flash_records_count;
1339 int i;
1340 int error;
1341
1342 cyapa_empty_pip_output_data(cyapa, NULL, NULL, NULL);
1343
1344 flash_records_count =
1345 (fw->size - sizeof(struct cyapa_tsg_bin_image_head)) /
1346 sizeof(struct cyapa_tsg_bin_image_data_record);
1347 /*
1348 * The last flash row 0x01ff has been written through bl_initiate
1349 * command, so DO NOT write flash 0x01ff to trackpad device.
1350 */
1351 for (i = 0; i < (flash_records_count - 1); i++) {
1352 flash_record = &image->records[i];
1353 error = cyapa_gen5_write_fw_block(cyapa, flash_record);
1354 if (error) {
1355 dev_err(dev, "%s: Gen5 FW update aborted: %d\n",
1356 __func__, error);
1357 return error;
1358 }
1359 }
1360
1361 return 0;
1362}
1363
1364static int cyapa_gen5_change_power_state(struct cyapa *cyapa, u8 power_state)
1365{
1366 u8 cmd[8] = { 0x04, 0x00, 0x06, 0x00, 0x2f, 0x00, 0x08, 0x01 };
1367 u8 resp_data[6];
1368 int resp_len;
1369 int error;
1370
1371 cmd[7] = power_state;
1372 resp_len = sizeof(resp_data);
1373 error = cyapa_i2c_pip_cmd_irq_sync(cyapa, cmd, sizeof(cmd),
1374 resp_data, &resp_len,
1375 500, cyapa_gen5_sort_tsg_pip_app_resp_data, false);
1376 if (error || !VALID_CMD_RESP_HEADER(resp_data, 0x08) ||
1377 !GEN5_CMD_COMPLETE_SUCCESS(resp_data[5]))
1378 return error < 0 ? error : -EINVAL;
1379
1380 return 0;
1381}
1382
1383static int cyapa_gen5_set_interval_time(struct cyapa *cyapa,
1384 u8 parameter_id, u16 interval_time)
1385{
1386 struct gen5_app_cmd_head *app_cmd_head;
1387 struct gen5_app_set_parameter_data *parameter_data;
1388 u8 cmd[CYAPA_TSG_MAX_CMD_SIZE];
1389 int cmd_len;
1390 u8 resp_data[7];
1391 int resp_len;
1392 u8 parameter_size;
1393 int error;
1394
1395 memset(cmd, 0, CYAPA_TSG_MAX_CMD_SIZE);
1396 app_cmd_head = (struct gen5_app_cmd_head *)cmd;
1397 parameter_data = (struct gen5_app_set_parameter_data *)
1398 app_cmd_head->parameter_data;
1399 cmd_len = sizeof(struct gen5_app_cmd_head) +
1400 sizeof(struct gen5_app_set_parameter_data);
1401
1402 switch (parameter_id) {
1403 case GEN5_PARAMETER_ACT_INTERVL_ID:
1404 parameter_size = GEN5_PARAMETER_ACT_INTERVL_SIZE;
1405 break;
1406 case GEN5_PARAMETER_ACT_LFT_INTERVL_ID:
1407 parameter_size = GEN5_PARAMETER_ACT_LFT_INTERVL_SIZE;
1408 break;
1409 case GEN5_PARAMETER_LP_INTRVL_ID:
1410 parameter_size = GEN5_PARAMETER_LP_INTRVL_SIZE;
1411 break;
1412 default:
1413 return -EINVAL;
1414 }
1415
1416 put_unaligned_le16(GEN5_OUTPUT_REPORT_ADDR, &app_cmd_head->addr);
1417 /*
1418 * Don't include unused parameter value bytes and
1419 * 2 bytes register address.
1420 */
1421 put_unaligned_le16(cmd_len - (4 - parameter_size) - 2,
1422 &app_cmd_head->length);
1423 app_cmd_head->report_id = GEN5_APP_CMD_REPORT_ID;
1424 app_cmd_head->cmd_code = GEN5_CMD_SET_PARAMETER;
1425 parameter_data->parameter_id = parameter_id;
1426 parameter_data->parameter_size = parameter_size;
1427 put_unaligned_le32((u32)interval_time, &parameter_data->value);
1428 resp_len = sizeof(resp_data);
1429 error = cyapa_i2c_pip_cmd_irq_sync(cyapa, cmd, cmd_len,
1430 resp_data, &resp_len,
1431 500, cyapa_gen5_sort_tsg_pip_app_resp_data, false);
1432 if (error || resp_data[5] != parameter_id ||
1433 resp_data[6] != parameter_size ||
1434 !VALID_CMD_RESP_HEADER(resp_data, GEN5_CMD_SET_PARAMETER))
1435 return error < 0 ? error : -EINVAL;
1436
1437 return 0;
1438}
1439
1440static int cyapa_gen5_get_interval_time(struct cyapa *cyapa,
1441 u8 parameter_id, u16 *interval_time)
1442{
1443 struct gen5_app_cmd_head *app_cmd_head;
1444 struct gen5_app_get_parameter_data *parameter_data;
1445 u8 cmd[CYAPA_TSG_MAX_CMD_SIZE];
1446 int cmd_len;
1447 u8 resp_data[11];
1448 int resp_len;
1449 u8 parameter_size;
1450 u16 mask, i;
1451 int error;
1452
1453 memset(cmd, 0, CYAPA_TSG_MAX_CMD_SIZE);
1454 app_cmd_head = (struct gen5_app_cmd_head *)cmd;
1455 parameter_data = (struct gen5_app_get_parameter_data *)
1456 app_cmd_head->parameter_data;
1457 cmd_len = sizeof(struct gen5_app_cmd_head) +
1458 sizeof(struct gen5_app_get_parameter_data);
1459
1460 *interval_time = 0;
1461 switch (parameter_id) {
1462 case GEN5_PARAMETER_ACT_INTERVL_ID:
1463 parameter_size = GEN5_PARAMETER_ACT_INTERVL_SIZE;
1464 break;
1465 case GEN5_PARAMETER_ACT_LFT_INTERVL_ID:
1466 parameter_size = GEN5_PARAMETER_ACT_LFT_INTERVL_SIZE;
1467 break;
1468 case GEN5_PARAMETER_LP_INTRVL_ID:
1469 parameter_size = GEN5_PARAMETER_LP_INTRVL_SIZE;
1470 break;
1471 default:
1472 return -EINVAL;
1473 }
1474
1475 put_unaligned_le16(GEN5_HID_DESCRIPTOR_ADDR, &app_cmd_head->addr);
1476 /* Don't include 2 bytes register address */
1477 put_unaligned_le16(cmd_len - 2, &app_cmd_head->length);
1478 app_cmd_head->report_id = GEN5_APP_CMD_REPORT_ID;
1479 app_cmd_head->cmd_code = GEN5_CMD_GET_PARAMETER;
1480 parameter_data->parameter_id = parameter_id;
1481
1482 resp_len = sizeof(resp_data);
1483 error = cyapa_i2c_pip_cmd_irq_sync(cyapa, cmd, cmd_len,
1484 resp_data, &resp_len,
1485 500, cyapa_gen5_sort_tsg_pip_app_resp_data, false);
1486 if (error || resp_data[5] != parameter_id || resp_data[6] == 0 ||
1487 !VALID_CMD_RESP_HEADER(resp_data, GEN5_CMD_GET_PARAMETER))
1488 return error < 0 ? error : -EINVAL;
1489
1490 mask = 0;
1491 for (i = 0; i < parameter_size; i++)
1492 mask |= (0xff << (i * 8));
1493 *interval_time = get_unaligned_le16(&resp_data[7]) & mask;
1494
1495 return 0;
1496}
1497
1498static int cyapa_gen5_disable_pip_report(struct cyapa *cyapa)
1499{
1500 struct gen5_app_cmd_head *app_cmd_head;
1501 u8 cmd[10];
1502 u8 resp_data[7];
1503 int resp_len;
1504 int error;
1505
1506 memset(cmd, 0, sizeof(cmd));
1507 app_cmd_head = (struct gen5_app_cmd_head *)cmd;
1508
1509 put_unaligned_le16(GEN5_HID_DESCRIPTOR_ADDR, &app_cmd_head->addr);
1510 put_unaligned_le16(sizeof(cmd) - 2, &app_cmd_head->length);
1511 app_cmd_head->report_id = GEN5_APP_CMD_REPORT_ID;
1512 app_cmd_head->cmd_code = GEN5_CMD_SET_PARAMETER;
1513 app_cmd_head->parameter_data[0] = GEN5_PARAMETER_DISABLE_PIP_REPORT;
1514 app_cmd_head->parameter_data[1] = 0x01;
1515 app_cmd_head->parameter_data[2] = 0x01;
1516 resp_len = sizeof(resp_data);
1517 error = cyapa_i2c_pip_cmd_irq_sync(cyapa, cmd, sizeof(cmd),
1518 resp_data, &resp_len,
1519 500, cyapa_gen5_sort_tsg_pip_app_resp_data, false);
1520 if (error || resp_data[5] != GEN5_PARAMETER_DISABLE_PIP_REPORT ||
1521 !VALID_CMD_RESP_HEADER(resp_data, GEN5_CMD_SET_PARAMETER) ||
1522 resp_data[6] != 0x01)
1523 return error < 0 ? error : -EINVAL;
1524
1525 return 0;
1526}
1527
1528static int cyapa_gen5_deep_sleep(struct cyapa *cyapa, u8 state)
1529{
1530 u8 cmd[] = { 0x05, 0x00, 0x00, 0x08};
1531 u8 resp_data[5];
1532 int resp_len;
1533 int error;
1534
1535 cmd[2] = state & GEN5_DEEP_SLEEP_STATE_MASK;
1536 resp_len = sizeof(resp_data);
1537 error = cyapa_i2c_pip_cmd_irq_sync(cyapa, cmd, sizeof(cmd),
1538 resp_data, &resp_len,
1539 500, cyapa_gen5_sort_deep_sleep_data, false);
1540 if (error || ((resp_data[3] & GEN5_DEEP_SLEEP_STATE_MASK) != state))
1541 return -EINVAL;
1542
1543 return 0;
1544}
1545
1546static int cyapa_gen5_set_power_mode(struct cyapa *cyapa,
1547 u8 power_mode, u16 sleep_time)
1548{
1549 struct device *dev = &cyapa->client->dev;
1550 u8 power_state;
1551 int error;
1552
1553 if (cyapa->state != CYAPA_STATE_GEN5_APP)
1554 return 0;
1555
1556 /* Dump all the report data before do power mode commmands. */
1557 cyapa_empty_pip_output_data(cyapa, NULL, NULL, NULL);
1558
1559 if (GEN5_DEV_GET_PWR_STATE(cyapa) == UNINIT_PWR_MODE) {
1560 /*
1561 * Assume TP in deep sleep mode when driver is loaded,
1562 * avoid driver unload and reload command IO issue caused by TP
1563 * has been set into deep sleep mode when unloading.
1564 */
1565 GEN5_DEV_SET_PWR_STATE(cyapa, PWR_MODE_OFF);
1566 }
1567
1568 if (GEN5_DEV_UNINIT_SLEEP_TIME(cyapa) &&
1569 GEN5_DEV_GET_PWR_STATE(cyapa) != PWR_MODE_OFF)
1570 if (cyapa_gen5_get_interval_time(cyapa,
1571 GEN5_PARAMETER_LP_INTRVL_ID,
1572 &cyapa->dev_sleep_time) != 0)
1573 GEN5_DEV_SET_SLEEP_TIME(cyapa, UNINIT_SLEEP_TIME);
1574
1575 if (GEN5_DEV_GET_PWR_STATE(cyapa) == power_mode) {
1576 if (power_mode == PWR_MODE_OFF ||
1577 power_mode == PWR_MODE_FULL_ACTIVE ||
1578 power_mode == PWR_MODE_BTN_ONLY ||
1579 GEN5_DEV_GET_SLEEP_TIME(cyapa) == sleep_time) {
1580 /* Has in correct power mode state, early return. */
1581 return 0;
1582 }
1583 }
1584
1585 if (power_mode == PWR_MODE_OFF) {
1586 error = cyapa_gen5_deep_sleep(cyapa, GEN5_DEEP_SLEEP_STATE_OFF);
1587 if (error) {
1588 dev_err(dev, "enter deep sleep fail: %d\n", error);
1589 return error;
1590 }
1591
1592 GEN5_DEV_SET_PWR_STATE(cyapa, PWR_MODE_OFF);
1593 return 0;
1594 }
1595
1596 /*
1597 * When trackpad in power off mode, it cannot change to other power
1598 * state directly, must be wake up from sleep firstly, then
1599 * continue to do next power sate change.
1600 */
1601 if (GEN5_DEV_GET_PWR_STATE(cyapa) == PWR_MODE_OFF) {
1602 error = cyapa_gen5_deep_sleep(cyapa, GEN5_DEEP_SLEEP_STATE_ON);
1603 if (error) {
1604 dev_err(dev, "deep sleep wake fail: %d\n", error);
1605 return error;
1606 }
1607 }
1608
1609 if (power_mode == PWR_MODE_FULL_ACTIVE) {
1610 error = cyapa_gen5_change_power_state(cyapa,
1611 GEN5_POWER_STATE_ACTIVE);
1612 if (error) {
1613 dev_err(dev, "change to active fail: %d\n", error);
1614 return error;
1615 }
1616
1617 GEN5_DEV_SET_PWR_STATE(cyapa, PWR_MODE_FULL_ACTIVE);
1618 } else if (power_mode == PWR_MODE_BTN_ONLY) {
1619 error = cyapa_gen5_change_power_state(cyapa,
1620 GEN5_POWER_STATE_BTN_ONLY);
1621 if (error) {
1622 dev_err(dev, "fail to button only mode: %d\n", error);
1623 return error;
1624 }
1625
1626 GEN5_DEV_SET_PWR_STATE(cyapa, PWR_MODE_BTN_ONLY);
1627 } else {
1628 /*
1629 * Continue to change power mode even failed to set
1630 * interval time, it won't affect the power mode change.
1631 * except the sleep interval time is not correct.
1632 */
1633 if (GEN5_DEV_UNINIT_SLEEP_TIME(cyapa) ||
1634 sleep_time != GEN5_DEV_GET_SLEEP_TIME(cyapa))
1635 if (cyapa_gen5_set_interval_time(cyapa,
1636 GEN5_PARAMETER_LP_INTRVL_ID,
1637 sleep_time) == 0)
1638 GEN5_DEV_SET_SLEEP_TIME(cyapa, sleep_time);
1639
1640 if (sleep_time <= GEN5_POWER_READY_MAX_INTRVL_TIME)
1641 power_state = GEN5_POWER_STATE_READY;
1642 else
1643 power_state = GEN5_POWER_STATE_IDLE;
1644 error = cyapa_gen5_change_power_state(cyapa, power_state);
1645 if (error) {
1646 dev_err(dev, "set power state to 0x%02x failed: %d\n",
1647 power_state, error);
1648 return error;
1649 }
1650
1651 /*
1652 * Disable pip report for a little time, firmware will
1653 * re-enable it automatically. It's used to fix the issue
1654 * that trackpad unable to report signal to wake system up
1655 * in the special situation that system is in suspending, and
1656 * at the same time, user touch trackpad to wake system up.
1657 * This function can avoid the data to be buffured when system
1658 * is suspending which may cause interrput line unable to be
1659 * asserted again.
1660 */
1661 cyapa_empty_pip_output_data(cyapa, NULL, NULL, NULL);
1662 cyapa_gen5_disable_pip_report(cyapa);
1663
1664 GEN5_DEV_SET_PWR_STATE(cyapa,
1665 cyapa_sleep_time_to_pwr_cmd(sleep_time));
1666 }
1667
1668 return 0;
1669}
1670
1671static int cyapa_gen5_resume_scanning(struct cyapa *cyapa)
1672{
1673 u8 cmd[] = { 0x04, 0x00, 0x05, 0x00, 0x2f, 0x00, 0x04 };
1674 u8 resp_data[6];
1675 int resp_len;
1676 int error;
1677
1678 /* Try to dump all buffered data before doing command. */
1679 cyapa_empty_pip_output_data(cyapa, NULL, NULL, NULL);
1680
1681 resp_len = sizeof(resp_data);
1682 error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
1683 cmd, sizeof(cmd),
1684 resp_data, &resp_len,
1685 500, cyapa_gen5_sort_tsg_pip_app_resp_data, true);
1686 if (error || !VALID_CMD_RESP_HEADER(resp_data, 0x04))
1687 return -EINVAL;
1688
1689 /* Try to dump all buffered data when resuming scanning. */
1690 cyapa_empty_pip_output_data(cyapa, NULL, NULL, NULL);
1691
1692 return 0;
1693}
1694
1695static int cyapa_gen5_suspend_scanning(struct cyapa *cyapa)
1696{
1697 u8 cmd[] = { 0x04, 0x00, 0x05, 0x00, 0x2f, 0x00, 0x03 };
1698 u8 resp_data[6];
1699 int resp_len;
1700 int error;
1701
1702 /* Try to dump all buffered data before doing command. */
1703 cyapa_empty_pip_output_data(cyapa, NULL, NULL, NULL);
1704
1705 resp_len = sizeof(resp_data);
1706 error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
1707 cmd, sizeof(cmd),
1708 resp_data, &resp_len,
1709 500, cyapa_gen5_sort_tsg_pip_app_resp_data, true);
1710 if (error || !VALID_CMD_RESP_HEADER(resp_data, 0x03))
1711 return -EINVAL;
1712
1713 /* Try to dump all buffered data when suspending scanning. */
1714 cyapa_empty_pip_output_data(cyapa, NULL, NULL, NULL);
1715
1716 return 0;
1717}
1718
1719static int cyapa_gen5_calibrate_pwcs(struct cyapa *cyapa,
1720 u8 calibrate_sensing_mode_type)
1721{
1722 struct gen5_app_cmd_head *app_cmd_head;
1723 u8 cmd[8];
1724 u8 resp_data[6];
1725 int resp_len;
1726 int error;
1727
1728 /* Try to dump all buffered data before doing command. */
1729 cyapa_empty_pip_output_data(cyapa, NULL, NULL, NULL);
1730
1731 memset(cmd, 0, sizeof(cmd));
1732 app_cmd_head = (struct gen5_app_cmd_head *)cmd;
1733 put_unaligned_le16(GEN5_OUTPUT_REPORT_ADDR, &app_cmd_head->addr);
1734 put_unaligned_le16(sizeof(cmd) - 2, &app_cmd_head->length);
1735 app_cmd_head->report_id = GEN5_APP_CMD_REPORT_ID;
1736 app_cmd_head->cmd_code = GEN5_CMD_CALIBRATE;
1737 app_cmd_head->parameter_data[0] = calibrate_sensing_mode_type;
1738 resp_len = sizeof(resp_data);
1739 error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
1740 cmd, sizeof(cmd),
1741 resp_data, &resp_len,
1742 5000, cyapa_gen5_sort_tsg_pip_app_resp_data, true);
1743 if (error || !VALID_CMD_RESP_HEADER(resp_data, GEN5_CMD_CALIBRATE) ||
1744 !GEN5_CMD_COMPLETE_SUCCESS(resp_data[5]))
1745 return error < 0 ? error : -EAGAIN;
1746
1747 return 0;
1748}
1749
1750static ssize_t cyapa_gen5_do_calibrate(struct device *dev,
1751 struct device_attribute *attr,
1752 const char *buf, size_t count)
1753{
1754 struct cyapa *cyapa = dev_get_drvdata(dev);
1755 int error, calibrate_error;
1756
1757 /* 1. Suspend Scanning*/
1758 error = cyapa_gen5_suspend_scanning(cyapa);
1759 if (error)
1760 return error;
1761
1762 /* 2. Do mutual capacitance fine calibrate. */
1763 calibrate_error = cyapa_gen5_calibrate_pwcs(cyapa,
1764 CYAPA_SENSING_MODE_MUTUAL_CAP_FINE);
1765 if (calibrate_error)
1766 goto resume_scanning;
1767
1768 /* 3. Do self capacitance calibrate. */
1769 calibrate_error = cyapa_gen5_calibrate_pwcs(cyapa,
1770 CYAPA_SENSING_MODE_SELF_CAP);
1771 if (calibrate_error)
1772 goto resume_scanning;
1773
1774resume_scanning:
1775 /* 4. Resume Scanning*/
1776 error = cyapa_gen5_resume_scanning(cyapa);
1777 if (error || calibrate_error)
1778 return error ? error : calibrate_error;
1779
1780 return count;
1781}
1782
1783static s32 twos_complement_to_s32(s32 value, int num_bits)
1784{
1785 if (value >> (num_bits - 1))
1786 value |= -1 << num_bits;
1787 return value;
1788}
1789
1790static s32 cyapa_parse_structure_data(u8 data_format, u8 *buf, int buf_len)
1791{
1792 int data_size;
1793 bool big_endian;
1794 bool unsigned_type;
1795 s32 value;
1796
1797 data_size = (data_format & 0x07);
1798 big_endian = ((data_format & 0x10) == 0x00);
1799 unsigned_type = ((data_format & 0x20) == 0x00);
1800
1801 if (buf_len < data_size)
1802 return 0;
1803
1804 switch (data_size) {
1805 case 1:
1806 value = buf[0];
1807 break;
1808 case 2:
1809 if (big_endian)
1810 value = get_unaligned_be16(buf);
1811 else
1812 value = get_unaligned_le16(buf);
1813 break;
1814 case 4:
1815 if (big_endian)
1816 value = get_unaligned_be32(buf);
1817 else
1818 value = get_unaligned_le32(buf);
1819 break;
1820 default:
1821 /* Should not happen, just as default case here. */
1822 value = 0;
1823 break;
1824 }
1825
1826 if (!unsigned_type)
1827 value = twos_complement_to_s32(value, data_size * 8);
1828
1829 return value;
1830}
1831
1832static void cyapa_gen5_guess_electrodes(struct cyapa *cyapa,
1833 int *electrodes_rx, int *electrodes_tx)
1834{
1835 if (cyapa->electrodes_rx != 0) {
1836 *electrodes_rx = cyapa->electrodes_rx;
1837 *electrodes_tx = (cyapa->electrodes_x == *electrodes_rx) ?
1838 cyapa->electrodes_y : cyapa->electrodes_x;
1839 } else {
1840 *electrodes_tx = min(cyapa->electrodes_x, cyapa->electrodes_y);
1841 *electrodes_rx = max(cyapa->electrodes_x, cyapa->electrodes_y);
1842 }
1843}
1844
1845/*
1846 * Read all the global mutual or self idac data or mutual or self local PWC
1847 * data based on the @idac_data_type.
1848 * If the input value of @data_size is 0, then means read global mutual or
1849 * self idac data. For read global mutual idac data, @idac_max, @idac_min and
1850 * @idac_ave are in order used to return the max value of global mutual idac
1851 * data, the min value of global mutual idac and the average value of the
1852 * global mutual idac data. For read global self idac data, @idac_max is used
1853 * to return the global self cap idac data in Rx direction, @idac_min is used
1854 * to return the global self cap idac data in Tx direction. @idac_ave is not
1855 * used.
1856 * If the input value of @data_size is not 0, than means read the mutual or
1857 * self local PWC data. The @idac_max, @idac_min and @idac_ave are used to
1858 * return the max, min and average value of the mutual or self local PWC data.
1859 * Note, in order to raed mutual local PWC data, must read invoke this function
1860 * to read the mutual global idac data firstly to set the correct Rx number
1861 * value, otherwise, the read mutual idac and PWC data may not correct.
1862 */
1863static int cyapa_gen5_read_idac_data(struct cyapa *cyapa,
1864 u8 cmd_code, u8 idac_data_type, int *data_size,
1865 int *idac_max, int *idac_min, int *idac_ave)
1866{
1867 struct gen5_app_cmd_head *cmd_head;
1868 u8 cmd[12];
1869 u8 resp_data[256];
1870 int resp_len;
1871 int read_len;
1872 int value;
1873 u16 offset;
1874 int read_elements;
1875 bool read_global_idac;
1876 int sum, count, max_element_cnt;
1877 int tmp_max, tmp_min, tmp_ave, tmp_sum, tmp_count;
1878 int electrodes_rx, electrodes_tx;
1879 int i;
1880 int error;
1881
1882 if (cmd_code != GEN5_CMD_RETRIEVE_DATA_STRUCTURE ||
1883 (idac_data_type != GEN5_RETRIEVE_MUTUAL_PWC_DATA &&
1884 idac_data_type != GEN5_RETRIEVE_SELF_CAP_PWC_DATA) ||
1885 !data_size || !idac_max || !idac_min || !idac_ave)
1886 return -EINVAL;
1887
1888 *idac_max = INT_MIN;
1889 *idac_min = INT_MAX;
1890 sum = count = tmp_count = 0;
1891 electrodes_rx = electrodes_tx = 0;
1892 if (*data_size == 0) {
1893 /*
1894 * Read global idac values firstly.
1895 * Currently, no idac data exceed 4 bytes.
1896 */
1897 read_global_idac = true;
1898 offset = 0;
1899 *data_size = 4;
1900 tmp_max = INT_MIN;
1901 tmp_min = INT_MAX;
1902 tmp_ave = tmp_sum = tmp_count = 0;
1903
1904 if (idac_data_type == GEN5_RETRIEVE_MUTUAL_PWC_DATA) {
1905 if (cyapa->aligned_electrodes_rx == 0) {
1906 cyapa_gen5_guess_electrodes(cyapa,
1907 &electrodes_rx, &electrodes_tx);
1908 cyapa->aligned_electrodes_rx =
1909 (electrodes_rx + 3) & ~3u;
1910 }
1911 max_element_cnt =
1912 (cyapa->aligned_electrodes_rx + 7) & ~7u;
1913 } else {
1914 max_element_cnt = 2;
1915 }
1916 } else {
1917 read_global_idac = false;
1918 if (*data_size > 4)
1919 *data_size = 4;
1920 /* Calculate the start offset in bytes of local PWC data. */
1921 if (idac_data_type == GEN5_RETRIEVE_MUTUAL_PWC_DATA) {
1922 offset = cyapa->aligned_electrodes_rx * (*data_size);
1923 if (cyapa->electrodes_rx == cyapa->electrodes_x)
1924 electrodes_tx = cyapa->electrodes_y;
1925 else
1926 electrodes_tx = cyapa->electrodes_x;
1927 max_element_cnt = ((cyapa->aligned_electrodes_rx + 7) &
1928 ~7u) * electrodes_tx;
1929 } else if (idac_data_type == GEN5_RETRIEVE_SELF_CAP_PWC_DATA) {
1930 offset = 2;
1931 max_element_cnt = cyapa->electrodes_x +
1932 cyapa->electrodes_y;
1933 max_element_cnt = (max_element_cnt + 3) & ~3u;
1934 }
1935 }
1936
1937 memset(cmd, 0, sizeof(cmd));
1938 cmd_head = (struct gen5_app_cmd_head *)cmd;
1939 put_unaligned_le16(GEN5_OUTPUT_REPORT_ADDR, &cmd_head->addr);
1940 put_unaligned_le16(sizeof(cmd) - 2, &cmd_head->length);
1941 cmd_head->report_id = GEN5_APP_CMD_REPORT_ID;
1942 cmd_head->cmd_code = cmd_code;
1943 do {
1944 read_elements = (256 - GEN5_RESP_DATA_STRUCTURE_OFFSET) /
1945 (*data_size);
1946 read_elements = min(read_elements, max_element_cnt - count);
1947 read_len = read_elements * (*data_size);
1948
1949 put_unaligned_le16(offset, &cmd_head->parameter_data[0]);
1950 put_unaligned_le16(read_len, &cmd_head->parameter_data[2]);
1951 cmd_head->parameter_data[4] = idac_data_type;
1952 resp_len = GEN5_RESP_DATA_STRUCTURE_OFFSET + read_len;
1953 error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
1954 cmd, sizeof(cmd),
1955 resp_data, &resp_len,
1956 500, cyapa_gen5_sort_tsg_pip_app_resp_data,
1957 true);
1958 if (error || resp_len < GEN5_RESP_DATA_STRUCTURE_OFFSET ||
1959 !VALID_CMD_RESP_HEADER(resp_data, cmd_code) ||
1960 !GEN5_CMD_COMPLETE_SUCCESS(resp_data[5]) ||
1961 resp_data[6] != idac_data_type)
1962 return (error < 0) ? error : -EAGAIN;
1963 read_len = get_unaligned_le16(&resp_data[7]);
1964 if (read_len == 0)
1965 break;
1966
1967 *data_size = (resp_data[9] & GEN5_PWC_DATA_ELEMENT_SIZE_MASK);
1968 if (read_len < *data_size)
1969 return -EINVAL;
1970
1971 if (read_global_idac &&
1972 idac_data_type == GEN5_RETRIEVE_SELF_CAP_PWC_DATA) {
1973 /* Rx's self global idac data. */
1974 *idac_max = cyapa_parse_structure_data(
1975 resp_data[9],
1976 &resp_data[GEN5_RESP_DATA_STRUCTURE_OFFSET],
1977 *data_size);
1978 /* Tx's self global idac data. */
1979 *idac_min = cyapa_parse_structure_data(
1980 resp_data[9],
1981 &resp_data[GEN5_RESP_DATA_STRUCTURE_OFFSET +
1982 *data_size],
1983 *data_size);
1984 break;
1985 }
1986
1987 /* Read mutual global idac or local mutual/self PWC data. */
1988 offset += read_len;
1989 for (i = 10; i < (read_len + GEN5_RESP_DATA_STRUCTURE_OFFSET);
1990 i += *data_size) {
1991 value = cyapa_parse_structure_data(resp_data[9],
1992 &resp_data[i], *data_size);
1993 *idac_min = min(value, *idac_min);
1994 *idac_max = max(value, *idac_max);
1995
1996 if (idac_data_type == GEN5_RETRIEVE_MUTUAL_PWC_DATA &&
1997 tmp_count < cyapa->aligned_electrodes_rx &&
1998 read_global_idac) {
1999 /*
2000 * The value gap betwen global and local mutual
2001 * idac data must bigger than 50%.
2002 * Normally, global value bigger than 50,
2003 * local values less than 10.
2004 */
2005 if (!tmp_ave || value > tmp_ave / 2) {
2006 tmp_min = min(value, tmp_min);
2007 tmp_max = max(value, tmp_max);
2008 tmp_sum += value;
2009 tmp_count++;
2010
2011 tmp_ave = tmp_sum / tmp_count;
2012 }
2013 }
2014
2015 sum += value;
2016 count++;
2017
2018 if (count >= max_element_cnt)
2019 goto out;
2020 }
2021 } while (true);
2022
2023out:
2024 *idac_ave = count ? (sum / count) : 0;
2025
2026 if (read_global_idac &&
2027 idac_data_type == GEN5_RETRIEVE_MUTUAL_PWC_DATA) {
2028 if (tmp_count == 0)
2029 return 0;
2030
2031 if (tmp_count == cyapa->aligned_electrodes_rx) {
2032 cyapa->electrodes_rx = cyapa->electrodes_rx ?
2033 cyapa->electrodes_rx : electrodes_rx;
2034 } else if (tmp_count == electrodes_rx) {
2035 cyapa->electrodes_rx = cyapa->electrodes_rx ?
2036 cyapa->electrodes_rx : electrodes_rx;
2037 cyapa->aligned_electrodes_rx = electrodes_rx;
2038 } else {
2039 cyapa->electrodes_rx = cyapa->electrodes_rx ?
2040 cyapa->electrodes_rx : electrodes_tx;
2041 cyapa->aligned_electrodes_rx = tmp_count;
2042 }
2043
2044 *idac_min = tmp_min;
2045 *idac_max = tmp_max;
2046 *idac_ave = tmp_ave;
2047 }
2048
2049 return 0;
2050}
2051
2052static int cyapa_gen5_read_mutual_idac_data(struct cyapa *cyapa,
2053 int *gidac_mutual_max, int *gidac_mutual_min, int *gidac_mutual_ave,
2054 int *lidac_mutual_max, int *lidac_mutual_min, int *lidac_mutual_ave)
2055{
2056 int data_size;
2057 int error;
2058
2059 *gidac_mutual_max = *gidac_mutual_min = *gidac_mutual_ave = 0;
2060 *lidac_mutual_max = *lidac_mutual_min = *lidac_mutual_ave = 0;
2061
2062 data_size = 0;
2063 error = cyapa_gen5_read_idac_data(cyapa,
2064 GEN5_CMD_RETRIEVE_DATA_STRUCTURE,
2065 GEN5_RETRIEVE_MUTUAL_PWC_DATA,
2066 &data_size,
2067 gidac_mutual_max, gidac_mutual_min, gidac_mutual_ave);
2068 if (error)
2069 return error;
2070
2071 error = cyapa_gen5_read_idac_data(cyapa,
2072 GEN5_CMD_RETRIEVE_DATA_STRUCTURE,
2073 GEN5_RETRIEVE_MUTUAL_PWC_DATA,
2074 &data_size,
2075 lidac_mutual_max, lidac_mutual_min, lidac_mutual_ave);
2076 return error;
2077}
2078
2079static int cyapa_gen5_read_self_idac_data(struct cyapa *cyapa,
2080 int *gidac_self_rx, int *gidac_self_tx,
2081 int *lidac_self_max, int *lidac_self_min, int *lidac_self_ave)
2082{
2083 int data_size;
2084 int error;
2085
2086 *gidac_self_rx = *gidac_self_tx = 0;
2087 *lidac_self_max = *lidac_self_min = *lidac_self_ave = 0;
2088
2089 data_size = 0;
2090 error = cyapa_gen5_read_idac_data(cyapa,
2091 GEN5_CMD_RETRIEVE_DATA_STRUCTURE,
2092 GEN5_RETRIEVE_SELF_CAP_PWC_DATA,
2093 &data_size,
2094 lidac_self_max, lidac_self_min, lidac_self_ave);
2095 if (error)
2096 return error;
2097 *gidac_self_rx = *lidac_self_max;
2098 *gidac_self_tx = *lidac_self_min;
2099
2100 error = cyapa_gen5_read_idac_data(cyapa,
2101 GEN5_CMD_RETRIEVE_DATA_STRUCTURE,
2102 GEN5_RETRIEVE_SELF_CAP_PWC_DATA,
2103 &data_size,
2104 lidac_self_max, lidac_self_min, lidac_self_ave);
2105 return error;
2106}
2107
2108static ssize_t cyapa_gen5_execute_panel_scan(struct cyapa *cyapa)
2109{
2110 struct gen5_app_cmd_head *app_cmd_head;
2111 u8 cmd[7];
2112 u8 resp_data[6];
2113 int resp_len;
2114 int error;
2115
2116 memset(cmd, 0, sizeof(cmd));
2117 app_cmd_head = (struct gen5_app_cmd_head *)cmd;
2118 put_unaligned_le16(GEN5_OUTPUT_REPORT_ADDR, &app_cmd_head->addr);
2119 put_unaligned_le16(sizeof(cmd) - 2, &app_cmd_head->length);
2120 app_cmd_head->report_id = GEN5_APP_CMD_REPORT_ID;
2121 app_cmd_head->cmd_code = GEN5_CMD_EXECUTE_PANEL_SCAN;
2122 resp_len = sizeof(resp_data);
2123 error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
2124 cmd, sizeof(cmd),
2125 resp_data, &resp_len,
2126 500, cyapa_gen5_sort_tsg_pip_app_resp_data, true);
2127 if (error || resp_len != sizeof(resp_data) ||
2128 !VALID_CMD_RESP_HEADER(resp_data,
2129 GEN5_CMD_EXECUTE_PANEL_SCAN) ||
2130 !GEN5_CMD_COMPLETE_SUCCESS(resp_data[5]))
2131 return error ? error : -EAGAIN;
2132
2133 return 0;
2134}
2135
2136static int cyapa_gen5_read_panel_scan_raw_data(struct cyapa *cyapa,
2137 u8 cmd_code, u8 raw_data_type, int raw_data_max_num,
2138 int *raw_data_max, int *raw_data_min, int *raw_data_ave,
2139 u8 *buffer)
2140{
2141 struct gen5_app_cmd_head *app_cmd_head;
2142 struct gen5_retrieve_panel_scan_data *panel_sacn_data;
2143 u8 cmd[12];
2144 u8 resp_data[256]; /* Max bytes can transfer one time. */
2145 int resp_len;
2146 int read_elements;
2147 int read_len;
2148 u16 offset;
2149 s32 value;
2150 int sum, count;
2151 int data_size;
2152 s32 *intp;
2153 int i;
2154 int error;
2155
2156 if (cmd_code != GEN5_CMD_RETRIEVE_PANEL_SCAN ||
2157 (raw_data_type > GEN5_PANEL_SCAN_SELF_DIFFCOUNT) ||
2158 !raw_data_max || !raw_data_min || !raw_data_ave)
2159 return -EINVAL;
2160
2161 intp = (s32 *)buffer;
2162 *raw_data_max = INT_MIN;
2163 *raw_data_min = INT_MAX;
2164 sum = count = 0;
2165 offset = 0;
2166 /* Assume max element size is 4 currently. */
2167 read_elements = (256 - GEN5_RESP_DATA_STRUCTURE_OFFSET) / 4;
2168 read_len = read_elements * 4;
2169 app_cmd_head = (struct gen5_app_cmd_head *)cmd;
2170 put_unaligned_le16(GEN5_OUTPUT_REPORT_ADDR, &app_cmd_head->addr);
2171 put_unaligned_le16(sizeof(cmd) - 2, &app_cmd_head->length);
2172 app_cmd_head->report_id = GEN5_APP_CMD_REPORT_ID;
2173 app_cmd_head->cmd_code = cmd_code;
2174 panel_sacn_data = (struct gen5_retrieve_panel_scan_data *)
2175 app_cmd_head->parameter_data;
2176 do {
2177 put_unaligned_le16(offset, &panel_sacn_data->read_offset);
2178 put_unaligned_le16(read_elements,
2179 &panel_sacn_data->read_elements);
2180 panel_sacn_data->data_id = raw_data_type;
2181
2182 resp_len = GEN5_RESP_DATA_STRUCTURE_OFFSET + read_len;
2183 error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
2184 cmd, sizeof(cmd),
2185 resp_data, &resp_len,
2186 500, cyapa_gen5_sort_tsg_pip_app_resp_data, true);
2187 if (error || resp_len < GEN5_RESP_DATA_STRUCTURE_OFFSET ||
2188 !VALID_CMD_RESP_HEADER(resp_data, cmd_code) ||
2189 !GEN5_CMD_COMPLETE_SUCCESS(resp_data[5]) ||
2190 resp_data[6] != raw_data_type)
2191 return error ? error : -EAGAIN;
2192
2193 read_elements = get_unaligned_le16(&resp_data[7]);
2194 if (read_elements == 0)
2195 break;
2196
2197 data_size = (resp_data[9] & GEN5_PWC_DATA_ELEMENT_SIZE_MASK);
2198 offset += read_elements;
2199 if (read_elements) {
2200 for (i = GEN5_RESP_DATA_STRUCTURE_OFFSET;
2201 i < (read_elements * data_size +
2202 GEN5_RESP_DATA_STRUCTURE_OFFSET);
2203 i += data_size) {
2204 value = cyapa_parse_structure_data(resp_data[9],
2205 &resp_data[i], data_size);
2206 *raw_data_min = min(value, *raw_data_min);
2207 *raw_data_max = max(value, *raw_data_max);
2208
2209 if (intp)
2210 put_unaligned_le32(value, &intp[count]);
2211
2212 sum += value;
2213 count++;
2214
2215 }
2216 }
2217
2218 if (count >= raw_data_max_num)
2219 break;
2220
2221 read_elements = (sizeof(resp_data) -
2222 GEN5_RESP_DATA_STRUCTURE_OFFSET) / data_size;
2223 read_len = read_elements * data_size;
2224 } while (true);
2225
2226 *raw_data_ave = count ? (sum / count) : 0;
2227
2228 return 0;
2229}
2230
2231static ssize_t cyapa_gen5_show_baseline(struct device *dev,
2232 struct device_attribute *attr, char *buf)
2233{
2234 struct cyapa *cyapa = dev_get_drvdata(dev);
2235 int gidac_mutual_max, gidac_mutual_min, gidac_mutual_ave;
2236 int lidac_mutual_max, lidac_mutual_min, lidac_mutual_ave;
2237 int gidac_self_rx, gidac_self_tx;
2238 int lidac_self_max, lidac_self_min, lidac_self_ave;
2239 int raw_cap_mutual_max, raw_cap_mutual_min, raw_cap_mutual_ave;
2240 int raw_cap_self_max, raw_cap_self_min, raw_cap_self_ave;
2241 int mutual_diffdata_max, mutual_diffdata_min, mutual_diffdata_ave;
2242 int self_diffdata_max, self_diffdata_min, self_diffdata_ave;
2243 int mutual_baseline_max, mutual_baseline_min, mutual_baseline_ave;
2244 int self_baseline_max, self_baseline_min, self_baseline_ave;
2245 int error, resume_error;
2246 int size;
2247
2248 if (cyapa->state != CYAPA_STATE_GEN5_APP)
2249 return -EBUSY;
2250
2251 /* 1. Suspend Scanning*/
2252 error = cyapa_gen5_suspend_scanning(cyapa);
2253 if (error)
2254 return error;
2255
2256 /* 2. Read global and local mutual IDAC data. */
2257 gidac_self_rx = gidac_self_tx = 0;
2258 error = cyapa_gen5_read_mutual_idac_data(cyapa,
2259 &gidac_mutual_max, &gidac_mutual_min,
2260 &gidac_mutual_ave, &lidac_mutual_max,
2261 &lidac_mutual_min, &lidac_mutual_ave);
2262 if (error)
2263 goto resume_scanning;
2264
2265 /* 3. Read global and local self IDAC data. */
2266 error = cyapa_gen5_read_self_idac_data(cyapa,
2267 &gidac_self_rx, &gidac_self_tx,
2268 &lidac_self_max, &lidac_self_min,
2269 &lidac_self_ave);
2270 if (error)
2271 goto resume_scanning;
2272
2273 /* 4. Execuate panel scan. It must be executed before read data. */
2274 error = cyapa_gen5_execute_panel_scan(cyapa);
2275 if (error)
2276 goto resume_scanning;
2277
2278 /* 5. Retrieve panel scan, mutual cap raw data. */
2279 error = cyapa_gen5_read_panel_scan_raw_data(cyapa,
2280 GEN5_CMD_RETRIEVE_PANEL_SCAN,
2281 GEN5_PANEL_SCAN_MUTUAL_RAW_DATA,
2282 cyapa->electrodes_x * cyapa->electrodes_y,
2283 &raw_cap_mutual_max, &raw_cap_mutual_min,
2284 &raw_cap_mutual_ave,
2285 NULL);
2286 if (error)
2287 goto resume_scanning;
2288
2289 /* 6. Retrieve panel scan, self cap raw data. */
2290 error = cyapa_gen5_read_panel_scan_raw_data(cyapa,
2291 GEN5_CMD_RETRIEVE_PANEL_SCAN,
2292 GEN5_PANEL_SCAN_SELF_RAW_DATA,
2293 cyapa->electrodes_x + cyapa->electrodes_y,
2294 &raw_cap_self_max, &raw_cap_self_min,
2295 &raw_cap_self_ave,
2296 NULL);
2297 if (error)
2298 goto resume_scanning;
2299
2300 /* 7. Retrieve panel scan, mutual cap diffcount raw data. */
2301 error = cyapa_gen5_read_panel_scan_raw_data(cyapa,
2302 GEN5_CMD_RETRIEVE_PANEL_SCAN,
2303 GEN5_PANEL_SCAN_MUTUAL_DIFFCOUNT,
2304 cyapa->electrodes_x * cyapa->electrodes_y,
2305 &mutual_diffdata_max, &mutual_diffdata_min,
2306 &mutual_diffdata_ave,
2307 NULL);
2308 if (error)
2309 goto resume_scanning;
2310
2311 /* 8. Retrieve panel scan, self cap diffcount raw data. */
2312 error = cyapa_gen5_read_panel_scan_raw_data(cyapa,
2313 GEN5_CMD_RETRIEVE_PANEL_SCAN,
2314 GEN5_PANEL_SCAN_SELF_DIFFCOUNT,
2315 cyapa->electrodes_x + cyapa->electrodes_y,
2316 &self_diffdata_max, &self_diffdata_min,
2317 &self_diffdata_ave,
2318 NULL);
2319 if (error)
2320 goto resume_scanning;
2321
2322 /* 9. Retrieve panel scan, mutual cap baseline raw data. */
2323 error = cyapa_gen5_read_panel_scan_raw_data(cyapa,
2324 GEN5_CMD_RETRIEVE_PANEL_SCAN,
2325 GEN5_PANEL_SCAN_MUTUAL_BASELINE,
2326 cyapa->electrodes_x * cyapa->electrodes_y,
2327 &mutual_baseline_max, &mutual_baseline_min,
2328 &mutual_baseline_ave,
2329 NULL);
2330 if (error)
2331 goto resume_scanning;
2332
2333 /* 10. Retrieve panel scan, self cap baseline raw data. */
2334 error = cyapa_gen5_read_panel_scan_raw_data(cyapa,
2335 GEN5_CMD_RETRIEVE_PANEL_SCAN,
2336 GEN5_PANEL_SCAN_SELF_BASELINE,
2337 cyapa->electrodes_x + cyapa->electrodes_y,
2338 &self_baseline_max, &self_baseline_min,
2339 &self_baseline_ave,
2340 NULL);
2341 if (error)
2342 goto resume_scanning;
2343
2344resume_scanning:
2345 /* 11. Resume Scanning*/
2346 resume_error = cyapa_gen5_resume_scanning(cyapa);
2347 if (resume_error || error)
2348 return resume_error ? resume_error : error;
2349
2350 /* 12. Output data strings */
2351 size = scnprintf(buf, PAGE_SIZE, "%d %d %d %d %d %d %d %d %d %d %d ",
2352 gidac_mutual_min, gidac_mutual_max, gidac_mutual_ave,
2353 lidac_mutual_min, lidac_mutual_max, lidac_mutual_ave,
2354 gidac_self_rx, gidac_self_tx,
2355 lidac_self_min, lidac_self_max, lidac_self_ave);
2356 size += scnprintf(buf + size, PAGE_SIZE - size,
2357 "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
2358 raw_cap_mutual_min, raw_cap_mutual_max, raw_cap_mutual_ave,
2359 raw_cap_self_min, raw_cap_self_max, raw_cap_self_ave,
2360 mutual_diffdata_min, mutual_diffdata_max, mutual_diffdata_ave,
2361 self_diffdata_min, self_diffdata_max, self_diffdata_ave,
2362 mutual_baseline_min, mutual_baseline_max, mutual_baseline_ave,
2363 self_baseline_min, self_baseline_max, self_baseline_ave);
2364 return size;
2365}
2366
2367static bool cyapa_gen5_sort_system_info_data(struct cyapa *cyapa,
2368 u8 *buf, int len)
2369{
2370 /* Check the report id and command code */
2371 if (VALID_CMD_RESP_HEADER(buf, 0x02))
2372 return true;
2373
2374 return false;
2375}
2376
2377static int cyapa_gen5_bl_query_data(struct cyapa *cyapa)
2378{
2379 u8 bl_query_data_cmd[] = { 0x04, 0x00, 0x0b, 0x00, 0x40, 0x00,
2380 0x01, 0x3c, 0x00, 0x00, 0xb0, 0x42, 0x17
2381 };
2382 u8 resp_data[GEN5_BL_READ_APP_INFO_RESP_LEN];
2383 int resp_len;
2384 int error;
2385
2386 resp_len = GEN5_BL_READ_APP_INFO_RESP_LEN;
2387 error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
2388 bl_query_data_cmd, sizeof(bl_query_data_cmd),
2389 resp_data, &resp_len,
2390 500, cyapa_gen5_sort_tsg_pip_bl_resp_data, false);
2391 if (error || resp_len != GEN5_BL_READ_APP_INFO_RESP_LEN ||
2392 !GEN5_CMD_COMPLETE_SUCCESS(resp_data[5]))
2393 return error ? error : -EIO;
2394
2395 memcpy(&cyapa->product_id[0], &resp_data[8], 5);
2396 cyapa->product_id[5] = '-';
2397 memcpy(&cyapa->product_id[6], &resp_data[13], 6);
2398 cyapa->product_id[12] = '-';
2399 memcpy(&cyapa->product_id[13], &resp_data[19], 2);
2400 cyapa->product_id[15] = '\0';
2401
2402 cyapa->fw_maj_ver = resp_data[22];
2403 cyapa->fw_min_ver = resp_data[23];
2404
2405 return 0;
2406}
2407
2408static int cyapa_gen5_get_query_data(struct cyapa *cyapa)
2409{
2410 u8 get_system_information[] = {
2411 0x04, 0x00, 0x05, 0x00, 0x2f, 0x00, 0x02
2412 };
2413 u8 resp_data[71];
2414 int resp_len;
2415 u16 product_family;
2416 int error;
2417
2418 resp_len = sizeof(resp_data);
2419 error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
2420 get_system_information, sizeof(get_system_information),
2421 resp_data, &resp_len,
2422 2000, cyapa_gen5_sort_system_info_data, false);
2423 if (error || resp_len < sizeof(resp_data))
2424 return error ? error : -EIO;
2425
2426 product_family = get_unaligned_le16(&resp_data[7]);
2427 if ((product_family & GEN5_PRODUCT_FAMILY_MASK) !=
2428 GEN5_PRODUCT_FAMILY_TRACKPAD)
2429 return -EINVAL;
2430
2431 cyapa->fw_maj_ver = resp_data[15];
2432 cyapa->fw_min_ver = resp_data[16];
2433
2434 cyapa->electrodes_x = resp_data[52];
2435 cyapa->electrodes_y = resp_data[53];
2436
2437 cyapa->physical_size_x = get_unaligned_le16(&resp_data[54]) / 100;
2438 cyapa->physical_size_y = get_unaligned_le16(&resp_data[56]) / 100;
2439
2440 cyapa->max_abs_x = get_unaligned_le16(&resp_data[58]);
2441 cyapa->max_abs_y = get_unaligned_le16(&resp_data[60]);
2442
2443 cyapa->max_z = get_unaligned_le16(&resp_data[62]);
2444
2445 cyapa->x_origin = resp_data[64] & 0x01;
2446 cyapa->y_origin = resp_data[65] & 0x01;
2447
2448 cyapa->btn_capability = (resp_data[70] << 3) & CAPABILITY_BTN_MASK;
2449
2450 memcpy(&cyapa->product_id[0], &resp_data[33], 5);
2451 cyapa->product_id[5] = '-';
2452 memcpy(&cyapa->product_id[6], &resp_data[38], 6);
2453 cyapa->product_id[12] = '-';
2454 memcpy(&cyapa->product_id[13], &resp_data[44], 2);
2455 cyapa->product_id[15] = '\0';
2456
2457 if (!cyapa->electrodes_x || !cyapa->electrodes_y ||
2458 !cyapa->physical_size_x || !cyapa->physical_size_y ||
2459 !cyapa->max_abs_x || !cyapa->max_abs_y || !cyapa->max_z)
2460 return -EINVAL;
2461
2462 return 0;
2463}
2464
2465static int cyapa_gen5_do_operational_check(struct cyapa *cyapa)
2466{
2467 struct device *dev = &cyapa->client->dev;
2468 int error;
2469
2470 if (cyapa->gen != CYAPA_GEN5)
2471 return -ENODEV;
2472
2473 switch (cyapa->state) {
2474 case CYAPA_STATE_GEN5_BL:
2475 error = cyapa_gen5_bl_exit(cyapa);
2476 if (error) {
2477 /* Rry to update trackpad product information. */
2478 cyapa_gen5_bl_query_data(cyapa);
2479 goto out;
2480 }
2481
2482 cyapa->state = CYAPA_STATE_GEN5_APP;
2483
2484 case CYAPA_STATE_GEN5_APP:
2485 /*
2486 * If trackpad device in deep sleep mode,
2487 * the app command will fail.
2488 * So always try to reset trackpad device to full active when
2489 * the device state is requeried.
2490 */
2491 error = cyapa_gen5_set_power_mode(cyapa,
2492 PWR_MODE_FULL_ACTIVE, 0);
2493 if (error)
2494 dev_warn(dev, "%s: failed to set power active mode.\n",
2495 __func__);
2496
2497 /* Get trackpad product information. */
2498 error = cyapa_gen5_get_query_data(cyapa);
2499 if (error)
2500 goto out;
2501 /* Only support product ID starting with CYTRA */
2502 if (memcmp(cyapa->product_id, product_id,
2503 strlen(product_id)) != 0) {
2504 dev_err(dev, "%s: unknown product ID (%s)\n",
2505 __func__, cyapa->product_id);
2506 error = -EINVAL;
2507 }
2508 break;
2509 default:
2510 error = -EINVAL;
2511 }
2512
2513out:
2514 return error;
2515}
2516
2517/*
2518 * Return false, do not continue process
2519 * Return true, continue process.
2520 */
2521static bool cyapa_gen5_irq_cmd_handler(struct cyapa *cyapa)
2522{
2523 struct cyapa_gen5_cmd_states *gen5_pip = &cyapa->cmd_states.gen5;
2524 int length;
2525
2526 if (atomic_read(&gen5_pip->cmd_issued)) {
2527 /* Polling command response data. */
2528 if (gen5_pip->is_irq_mode == false)
2529 return false;
2530
2531 /*
2532 * Read out all none command response data.
2533 * these output data may caused by user put finger on
2534 * trackpad when host waiting the command response.
2535 */
2536 cyapa_i2c_pip_read(cyapa, gen5_pip->irq_cmd_buf,
2537 GEN5_RESP_LENGTH_SIZE);
2538 length = get_unaligned_le16(gen5_pip->irq_cmd_buf);
2539 length = (length <= GEN5_RESP_LENGTH_SIZE) ?
2540 GEN5_RESP_LENGTH_SIZE : length;
2541 if (length > GEN5_RESP_LENGTH_SIZE)
2542 cyapa_i2c_pip_read(cyapa,
2543 gen5_pip->irq_cmd_buf, length);
2544
2545 if (!(gen5_pip->resp_sort_func &&
2546 gen5_pip->resp_sort_func(cyapa,
2547 gen5_pip->irq_cmd_buf, length))) {
2548 /*
2549 * Cover the Gen5 V1 firmware issue.
2550 * The issue is there is no interrut will be
2551 * asserted to notityf host to read a command
2552 * data out when always has finger touch on
2553 * trackpad during the command is issued to
2554 * trackad device.
2555 * This issue has the scenario is that,
2556 * user always has his fingers touched on
2557 * trackpad device when booting/rebooting
2558 * their chrome book.
2559 */
2560 length = 0;
2561 if (gen5_pip->resp_len)
2562 length = *gen5_pip->resp_len;
2563 cyapa_empty_pip_output_data(cyapa,
2564 gen5_pip->resp_data,
2565 &length,
2566 gen5_pip->resp_sort_func);
2567 if (gen5_pip->resp_len && length != 0) {
2568 *gen5_pip->resp_len = length;
2569 atomic_dec(&gen5_pip->cmd_issued);
2570 complete(&gen5_pip->cmd_ready);
2571 }
2572 return false;
2573 }
2574
2575 if (gen5_pip->resp_data && gen5_pip->resp_len) {
2576 *gen5_pip->resp_len = (*gen5_pip->resp_len < length) ?
2577 *gen5_pip->resp_len : length;
2578 memcpy(gen5_pip->resp_data, gen5_pip->irq_cmd_buf,
2579 *gen5_pip->resp_len);
2580 }
2581 atomic_dec(&gen5_pip->cmd_issued);
2582 complete(&gen5_pip->cmd_ready);
2583 return false;
2584 }
2585
2586 return true;
2587}
2588
2589static void cyapa_gen5_report_buttons(struct cyapa *cyapa,
2590 const struct cyapa_gen5_report_data *report_data)
2591{
2592 struct input_dev *input = cyapa->input;
2593 u8 buttons = report_data->report_head[GEN5_BUTTONS_OFFSET];
2594
2595 buttons = (buttons << CAPABILITY_BTN_SHIFT) & CAPABILITY_BTN_MASK;
2596
2597 if (cyapa->btn_capability & CAPABILITY_LEFT_BTN_MASK) {
2598 input_report_key(input, BTN_LEFT,
2599 !!(buttons & CAPABILITY_LEFT_BTN_MASK));
2600 }
2601 if (cyapa->btn_capability & CAPABILITY_MIDDLE_BTN_MASK) {
2602 input_report_key(input, BTN_MIDDLE,
2603 !!(buttons & CAPABILITY_MIDDLE_BTN_MASK));
2604 }
2605 if (cyapa->btn_capability & CAPABILITY_RIGHT_BTN_MASK) {
2606 input_report_key(input, BTN_RIGHT,
2607 !!(buttons & CAPABILITY_RIGHT_BTN_MASK));
2608 }
2609
2610 input_sync(input);
2611}
2612
2613static void cyapa_gen5_report_slot_data(struct cyapa *cyapa,
2614 const struct cyapa_gen5_touch_record *touch)
2615{
2616 struct input_dev *input = cyapa->input;
2617 u8 event_id = GEN5_GET_EVENT_ID(touch->touch_tip_event_id);
2618 int slot = GEN5_GET_TOUCH_ID(touch->touch_tip_event_id);
2619 int x, y;
2620
2621 if (event_id == RECORD_EVENT_LIFTOFF)
2622 return;
2623
2624 input_mt_slot(input, slot);
2625 input_mt_report_slot_state(input, MT_TOOL_FINGER, true);
2626 x = (touch->x_hi << 8) | touch->x_lo;
2627 if (cyapa->x_origin)
2628 x = cyapa->max_abs_x - x;
2629 input_report_abs(input, ABS_MT_POSITION_X, x);
2630 y = (touch->y_hi << 8) | touch->y_lo;
2631 if (cyapa->y_origin)
2632 y = cyapa->max_abs_y - y;
2633 input_report_abs(input, ABS_MT_POSITION_Y, y);
2634 input_report_abs(input, ABS_MT_PRESSURE,
2635 touch->z);
2636 input_report_abs(input, ABS_MT_TOUCH_MAJOR,
2637 touch->major_axis_len);
2638 input_report_abs(input, ABS_MT_TOUCH_MINOR,
2639 touch->minor_axis_len);
2640
2641 input_report_abs(input, ABS_MT_WIDTH_MAJOR,
2642 touch->major_tool_len);
2643 input_report_abs(input, ABS_MT_WIDTH_MINOR,
2644 touch->minor_tool_len);
2645
2646 input_report_abs(input, ABS_MT_ORIENTATION,
2647 touch->orientation);
2648}
2649
2650static void cyapa_gen5_report_touches(struct cyapa *cyapa,
2651 const struct cyapa_gen5_report_data *report_data)
2652{
2653 struct input_dev *input = cyapa->input;
2654 unsigned int touch_num;
2655 int i;
2656
2657 touch_num = report_data->report_head[GEN5_NUMBER_OF_TOUCH_OFFSET] &
2658 GEN5_NUMBER_OF_TOUCH_MASK;
2659
2660 for (i = 0; i < touch_num; i++)
2661 cyapa_gen5_report_slot_data(cyapa,
2662 &report_data->touch_records[i]);
2663
2664 input_mt_sync_frame(input);
2665 input_sync(input);
2666}
2667
2668static int cyapa_gen5_irq_handler(struct cyapa *cyapa)
2669{
2670 struct device *dev = &cyapa->client->dev;
2671 struct cyapa_gen5_report_data report_data;
2672 int ret;
2673 u8 report_id;
2674 unsigned int report_len;
2675
2676 if (cyapa->gen != CYAPA_GEN5 ||
2677 cyapa->state != CYAPA_STATE_GEN5_APP) {
2678 dev_err(dev, "invalid device state, gen=%d, state=0x%02x\n",
2679 cyapa->gen, cyapa->state);
2680 return -EINVAL;
2681 }
2682
2683 ret = cyapa_i2c_pip_read(cyapa, (u8 *)&report_data,
2684 GEN5_RESP_LENGTH_SIZE);
2685 if (ret != GEN5_RESP_LENGTH_SIZE) {
2686 dev_err(dev, "failed to read length bytes, (%d)\n", ret);
2687 return -EINVAL;
2688 }
2689
2690 report_len = get_unaligned_le16(
2691 &report_data.report_head[GEN5_RESP_LENGTH_OFFSET]);
2692 if (report_len < GEN5_RESP_LENGTH_SIZE) {
2693 /* Invliad length or internal reset happened. */
2694 dev_err(dev, "invalid report_len=%d. bytes: %02x %02x\n",
2695 report_len, report_data.report_head[0],
2696 report_data.report_head[1]);
2697 return -EINVAL;
2698 }
2699
2700 /* Idle, no data for report. */
2701 if (report_len == GEN5_RESP_LENGTH_SIZE)
2702 return 0;
2703
2704 ret = cyapa_i2c_pip_read(cyapa, (u8 *)&report_data, report_len);
2705 if (ret != report_len) {
2706 dev_err(dev, "failed to read %d bytes report data, (%d)\n",
2707 report_len, ret);
2708 return -EINVAL;
2709 }
2710
2711 report_id = report_data.report_head[GEN5_RESP_REPORT_ID_OFFSET];
2712 if (report_id == GEN5_WAKEUP_EVENT_REPORT_ID &&
2713 report_len == GEN5_WAKEUP_EVENT_SIZE) {
2714 /*
2715 * Device wake event from deep sleep mode for touch.
2716 * This interrupt event is used to wake system up.
2717 */
2718 return 0;
2719 } else if (report_id != GEN5_TOUCH_REPORT_ID &&
2720 report_id != GEN5_BTN_REPORT_ID &&
2721 report_id != GEN5_OLD_PUSH_BTN_REPORT_ID &&
2722 report_id != GEN5_PUSH_BTN_REPORT_ID) {
2723 /* Running in BL mode or unknown response data read. */
2724 dev_err(dev, "invalid report_id=0x%02x\n", report_id);
2725 return -EINVAL;
2726 }
2727
2728 if (report_id == GEN5_TOUCH_REPORT_ID &&
2729 (report_len < GEN5_TOUCH_REPORT_HEAD_SIZE ||
2730 report_len > GEN5_TOUCH_REPORT_MAX_SIZE)) {
2731 /* Invalid report data length for finger packet. */
2732 dev_err(dev, "invalid touch packet length=%d\n", report_len);
2733 return 0;
2734 }
2735
2736 if ((report_id == GEN5_BTN_REPORT_ID ||
2737 report_id == GEN5_OLD_PUSH_BTN_REPORT_ID ||
2738 report_id == GEN5_PUSH_BTN_REPORT_ID) &&
2739 (report_len < GEN5_BTN_REPORT_HEAD_SIZE ||
2740 report_len > GEN5_BTN_REPORT_MAX_SIZE)) {
2741 /* Invalid report data length of button packet. */
2742 dev_err(dev, "invalid button packet length=%d\n", report_len);
2743 return 0;
2744 }
2745
2746 if (report_id == GEN5_TOUCH_REPORT_ID)
2747 cyapa_gen5_report_touches(cyapa, &report_data);
2748 else
2749 cyapa_gen5_report_buttons(cyapa, &report_data);
2750
2751 return 0;
2752}
2753
2754static int cyapa_gen5_bl_activate(struct cyapa *cyapa) { return 0; }
2755static int cyapa_gen5_bl_deactivate(struct cyapa *cyapa) { return 0; }
2756
2757const struct cyapa_dev_ops cyapa_gen5_ops = {
2758 .check_fw = cyapa_gen5_check_fw,
2759 .bl_enter = cyapa_gen5_bl_enter,
2760 .bl_initiate = cyapa_gen5_bl_initiate,
2761 .update_fw = cyapa_gen5_do_fw_update,
2762 .bl_activate = cyapa_gen5_bl_activate,
2763 .bl_deactivate = cyapa_gen5_bl_deactivate,
2764
2765 .show_baseline = cyapa_gen5_show_baseline,
2766 .calibrate_store = cyapa_gen5_do_calibrate,
2767
2768 .initialize = cyapa_gen5_initialize,
2769
2770 .state_parse = cyapa_gen5_state_parse,
2771 .operational_check = cyapa_gen5_do_operational_check,
2772
2773 .irq_handler = cyapa_gen5_irq_handler,
2774 .irq_cmd_handler = cyapa_gen5_irq_cmd_handler,
2775 .sort_empty_output_data = cyapa_empty_pip_output_data,
2776 .set_power_mode = cyapa_gen5_set_power_mode,
2777};
diff --git a/drivers/input/mouse/cypress_ps2.c b/drivers/input/mouse/cypress_ps2.c
index 8af34ffe208b..9118a1861a45 100644
--- a/drivers/input/mouse/cypress_ps2.c
+++ b/drivers/input/mouse/cypress_ps2.c
@@ -538,7 +538,7 @@ static void cypress_process_packet(struct psmouse *psmouse, bool zero_pkt)
538 pos[i].y = contact->y; 538 pos[i].y = contact->y;
539 } 539 }
540 540
541 input_mt_assign_slots(input, slots, pos, n); 541 input_mt_assign_slots(input, slots, pos, n, 0);
542 542
543 for (i = 0; i < n; i++) { 543 for (i = 0; i < n; i++) {
544 contact = &report_data.contacts[i]; 544 contact = &report_data.contacts[i];
diff --git a/drivers/input/mouse/elan_i2c.h b/drivers/input/mouse/elan_i2c.h
index 2e838626205f..e100c1b31597 100644
--- a/drivers/input/mouse/elan_i2c.h
+++ b/drivers/input/mouse/elan_i2c.h
@@ -4,7 +4,6 @@
4 * Copyright (c) 2013 ELAN Microelectronics Corp. 4 * Copyright (c) 2013 ELAN Microelectronics Corp.
5 * 5 *
6 * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw> 6 * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
7 * Version: 1.5.5
8 * 7 *
9 * Based on cyapa driver: 8 * Based on cyapa driver:
10 * copyright (c) 2011-2012 Cypress Semiconductor, Inc. 9 * copyright (c) 2011-2012 Cypress Semiconductor, Inc.
@@ -33,8 +32,9 @@
33#define ETP_FW_IAP_PAGE_ERR (1 << 5) 32#define ETP_FW_IAP_PAGE_ERR (1 << 5)
34#define ETP_FW_IAP_INTF_ERR (1 << 4) 33#define ETP_FW_IAP_INTF_ERR (1 << 4)
35#define ETP_FW_PAGE_SIZE 64 34#define ETP_FW_PAGE_SIZE 64
36#define ETP_FW_PAGE_COUNT 768 35#define ETP_FW_VAILDPAGE_COUNT 768
37#define ETP_FW_SIZE (ETP_FW_PAGE_SIZE * ETP_FW_PAGE_COUNT) 36#define ETP_FW_SIGNATURE_SIZE 6
37#define ETP_FW_SIGNATURE_ADDRESS 0xBFFA
38 38
39struct i2c_client; 39struct i2c_client;
40struct completion; 40struct completion;
diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c
index 0cb2be48d537..7ce8bfe22d7e 100644
--- a/drivers/input/mouse/elan_i2c_core.c
+++ b/drivers/input/mouse/elan_i2c_core.c
@@ -4,7 +4,7 @@
4 * Copyright (c) 2013 ELAN Microelectronics Corp. 4 * Copyright (c) 2013 ELAN Microelectronics Corp.
5 * 5 *
6 * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw> 6 * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
7 * Version: 1.5.5 7 * Version: 1.5.6
8 * 8 *
9 * Based on cyapa driver: 9 * Based on cyapa driver:
10 * copyright (c) 2011-2012 Cypress Semiconductor, Inc. 10 * copyright (c) 2011-2012 Cypress Semiconductor, Inc.
@@ -40,7 +40,7 @@
40#include "elan_i2c.h" 40#include "elan_i2c.h"
41 41
42#define DRIVER_NAME "elan_i2c" 42#define DRIVER_NAME "elan_i2c"
43#define ELAN_DRIVER_VERSION "1.5.5" 43#define ELAN_DRIVER_VERSION "1.5.6"
44#define ETP_PRESSURE_OFFSET 25 44#define ETP_PRESSURE_OFFSET 25
45#define ETP_MAX_PRESSURE 255 45#define ETP_MAX_PRESSURE 255
46#define ETP_FWIDTH_REDUCE 90 46#define ETP_FWIDTH_REDUCE 90
@@ -312,7 +312,7 @@ static int __elan_update_firmware(struct elan_tp_data *data,
312 iap_start_addr = get_unaligned_le16(&fw->data[ETP_IAP_START_ADDR * 2]); 312 iap_start_addr = get_unaligned_le16(&fw->data[ETP_IAP_START_ADDR * 2]);
313 313
314 boot_page_count = (iap_start_addr * 2) / ETP_FW_PAGE_SIZE; 314 boot_page_count = (iap_start_addr * 2) / ETP_FW_PAGE_SIZE;
315 for (i = boot_page_count; i < ETP_FW_PAGE_COUNT; i++) { 315 for (i = boot_page_count; i < ETP_FW_VAILDPAGE_COUNT; i++) {
316 u16 checksum = 0; 316 u16 checksum = 0;
317 const u8 *page = &fw->data[i * ETP_FW_PAGE_SIZE]; 317 const u8 *page = &fw->data[i * ETP_FW_PAGE_SIZE];
318 318
@@ -434,10 +434,11 @@ static ssize_t elan_sysfs_update_fw(struct device *dev,
434 struct device_attribute *attr, 434 struct device_attribute *attr,
435 const char *buf, size_t count) 435 const char *buf, size_t count)
436{ 436{
437 struct i2c_client *client = to_i2c_client(dev); 437 struct elan_tp_data *data = dev_get_drvdata(dev);
438 struct elan_tp_data *data = i2c_get_clientdata(client);
439 const struct firmware *fw; 438 const struct firmware *fw;
440 int error; 439 int error;
440 const u8 *fw_signature;
441 static const u8 signature[] = {0xAA, 0x55, 0xCC, 0x33, 0xFF, 0xFF};
441 442
442 error = request_firmware(&fw, ETP_FW_NAME, dev); 443 error = request_firmware(&fw, ETP_FW_NAME, dev);
443 if (error) { 444 if (error) {
@@ -446,10 +447,12 @@ static ssize_t elan_sysfs_update_fw(struct device *dev,
446 return error; 447 return error;
447 } 448 }
448 449
449 /* Firmware must be exactly PAGE_NUM * PAGE_SIZE bytes */ 450 /* Firmware file must match signature data */
450 if (fw->size != ETP_FW_SIZE) { 451 fw_signature = &fw->data[ETP_FW_SIGNATURE_ADDRESS];
451 dev_err(dev, "invalid firmware size = %zu, expected %d.\n", 452 if (memcmp(fw_signature, signature, sizeof(signature)) != 0) {
452 fw->size, ETP_FW_SIZE); 453 dev_err(dev, "signature mismatch (expected %*ph, got %*ph)\n",
454 (int)sizeof(signature), signature,
455 (int)sizeof(signature), fw_signature);
453 error = -EBADF; 456 error = -EBADF;
454 goto out_release_fw; 457 goto out_release_fw;
455 } 458 }
diff --git a/drivers/input/mouse/elan_i2c_i2c.c b/drivers/input/mouse/elan_i2c_i2c.c
index 97d4937fc244..029941f861af 100644
--- a/drivers/input/mouse/elan_i2c_i2c.c
+++ b/drivers/input/mouse/elan_i2c_i2c.c
@@ -4,7 +4,6 @@
4 * Copyright (c) 2013 ELAN Microelectronics Corp. 4 * Copyright (c) 2013 ELAN Microelectronics Corp.
5 * 5 *
6 * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw> 6 * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
7 * Version: 1.5.5
8 * 7 *
9 * Based on cyapa driver: 8 * Based on cyapa driver:
10 * copyright (c) 2011-2012 Cypress Semiconductor, Inc. 9 * copyright (c) 2011-2012 Cypress Semiconductor, Inc.
diff --git a/drivers/input/mouse/elan_i2c_smbus.c b/drivers/input/mouse/elan_i2c_smbus.c
index 359bf8583d54..06a2bcd1cda2 100644
--- a/drivers/input/mouse/elan_i2c_smbus.c
+++ b/drivers/input/mouse/elan_i2c_smbus.c
@@ -4,7 +4,6 @@
4 * Copyright (c) 2013 ELAN Microelectronics Corp. 4 * Copyright (c) 2013 ELAN Microelectronics Corp.
5 * 5 *
6 * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw> 6 * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
7 * Version: 1.5.5
8 * 7 *
9 * Based on cyapa driver: 8 * Based on cyapa driver:
10 * copyright (c) 2011-2012 Cypress Semiconductor, Inc. 9 * copyright (c) 2011-2012 Cypress Semiconductor, Inc.
@@ -71,7 +70,7 @@ static int elan_smbus_initialize(struct i2c_client *client)
71 70
72 /* compare hello packet */ 71 /* compare hello packet */
73 if (memcmp(values, check, ETP_SMBUS_HELLOPACKET_LEN)) { 72 if (memcmp(values, check, ETP_SMBUS_HELLOPACKET_LEN)) {
74 dev_err(&client->dev, "hello packet fail [%*px]\n", 73 dev_err(&client->dev, "hello packet fail [%*ph]\n",
75 ETP_SMBUS_HELLOPACKET_LEN, values); 74 ETP_SMBUS_HELLOPACKET_LEN, values);
76 return -ENXIO; 75 return -ENXIO;
77 } 76 }
diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c
index f4d657ee1cc0..fca38ba63bbe 100644
--- a/drivers/input/mouse/focaltech.c
+++ b/drivers/input/mouse/focaltech.c
@@ -2,6 +2,7 @@
2 * Focaltech TouchPad PS/2 mouse driver 2 * Focaltech TouchPad PS/2 mouse driver
3 * 3 *
4 * Copyright (c) 2014 Red Hat Inc. 4 * Copyright (c) 2014 Red Hat Inc.
5 * Copyright (c) 2014 Mathias Gottschlag <mgottschlag@gmail.com>
5 * 6 *
6 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
@@ -13,15 +14,14 @@
13 * Hans de Goede <hdegoede@redhat.com> 14 * Hans de Goede <hdegoede@redhat.com>
14 */ 15 */
15 16
16/*
17 * The Focaltech PS/2 touchpad protocol is unknown. This drivers deals with
18 * detection only, to avoid further detection attempts confusing the touchpad
19 * this way it at least works in PS/2 mouse compatibility mode.
20 */
21 17
22#include <linux/device.h> 18#include <linux/device.h>
23#include <linux/libps2.h> 19#include <linux/libps2.h>
20#include <linux/input/mt.h>
21#include <linux/serio.h>
22#include <linux/slab.h>
24#include "psmouse.h" 23#include "psmouse.h"
24#include "focaltech.h"
25 25
26static const char * const focaltech_pnp_ids[] = { 26static const char * const focaltech_pnp_ids[] = {
27 "FLT0101", 27 "FLT0101",
@@ -30,6 +30,12 @@ static const char * const focaltech_pnp_ids[] = {
30 NULL 30 NULL
31}; 31};
32 32
33/*
34 * Even if the kernel is built without support for Focaltech PS/2 touchpads (or
35 * when the real driver fails to recognize the device), we still have to detect
36 * them in order to avoid further detection attempts confusing the touchpad.
37 * This way it at least works in PS/2 mouse compatibility mode.
38 */
33int focaltech_detect(struct psmouse *psmouse, bool set_properties) 39int focaltech_detect(struct psmouse *psmouse, bool set_properties)
34{ 40{
35 if (!psmouse_matches_pnp_id(psmouse, focaltech_pnp_ids)) 41 if (!psmouse_matches_pnp_id(psmouse, focaltech_pnp_ids))
@@ -37,16 +43,404 @@ int focaltech_detect(struct psmouse *psmouse, bool set_properties)
37 43
38 if (set_properties) { 44 if (set_properties) {
39 psmouse->vendor = "FocalTech"; 45 psmouse->vendor = "FocalTech";
40 psmouse->name = "FocalTech Touchpad in mouse emulation mode"; 46 psmouse->name = "FocalTech Touchpad";
41 } 47 }
42 48
43 return 0; 49 return 0;
44} 50}
45 51
46int focaltech_init(struct psmouse *psmouse) 52static void focaltech_reset(struct psmouse *psmouse)
47{ 53{
48 ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS); 54 ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
49 psmouse_reset(psmouse); 55 psmouse_reset(psmouse);
56}
57
58#ifdef CONFIG_MOUSE_PS2_FOCALTECH
59
60/*
61 * Packet types - the numbers are not consecutive, so we might be missing
62 * something here.
63 */
64#define FOC_TOUCH 0x3 /* bitmap of active fingers */
65#define FOC_ABS 0x6 /* absolute position of one finger */
66#define FOC_REL 0x9 /* relative position of 1-2 fingers */
67
68#define FOC_MAX_FINGERS 5
69
70#define FOC_MAX_X 2431
71#define FOC_MAX_Y 1663
72
73/*
74 * Current state of a single finger on the touchpad.
75 */
76struct focaltech_finger_state {
77 /* The touchpad has generated a touch event for the finger */
78 bool active;
79
80 /*
81 * The touchpad has sent position data for the finger. The
82 * flag is 0 when the finger is not active, and there is a
83 * time between the first touch event for the finger and the
84 * following absolute position packet for the finger where the
85 * touchpad has declared the finger to be valid, but we do not
86 * have any valid position yet.
87 */
88 bool valid;
89
90 /*
91 * Absolute position (from the bottom left corner) of the
92 * finger.
93 */
94 unsigned int x;
95 unsigned int y;
96};
97
98/*
99 * Description of the current state of the touchpad hardware.
100 */
101struct focaltech_hw_state {
102 /*
103 * The touchpad tracks the positions of the fingers for us,
104 * the array indices correspond to the finger indices returned
105 * in the report packages.
106 */
107 struct focaltech_finger_state fingers[FOC_MAX_FINGERS];
108
109 /* True if the clickpad has been pressed. */
110 bool pressed;
111};
112
113struct focaltech_data {
114 unsigned int x_max, y_max;
115 struct focaltech_hw_state state;
116};
117
118static void focaltech_report_state(struct psmouse *psmouse)
119{
120 struct focaltech_data *priv = psmouse->private;
121 struct focaltech_hw_state *state = &priv->state;
122 struct input_dev *dev = psmouse->dev;
123 int i;
124
125 for (i = 0; i < FOC_MAX_FINGERS; i++) {
126 struct focaltech_finger_state *finger = &state->fingers[i];
127 bool active = finger->active && finger->valid;
128
129 input_mt_slot(dev, i);
130 input_mt_report_slot_state(dev, MT_TOOL_FINGER, active);
131 if (active) {
132 input_report_abs(dev, ABS_MT_POSITION_X, finger->x);
133 input_report_abs(dev, ABS_MT_POSITION_Y,
134 FOC_MAX_Y - finger->y);
135 }
136 }
137 input_mt_report_pointer_emulation(dev, true);
138
139 input_report_key(psmouse->dev, BTN_LEFT, state->pressed);
140 input_sync(psmouse->dev);
141}
142
143static void focaltech_process_touch_packet(struct psmouse *psmouse,
144 unsigned char *packet)
145{
146 struct focaltech_data *priv = psmouse->private;
147 struct focaltech_hw_state *state = &priv->state;
148 unsigned char fingers = packet[1];
149 int i;
150
151 state->pressed = (packet[0] >> 4) & 1;
152
153 /* the second byte contains a bitmap of all fingers touching the pad */
154 for (i = 0; i < FOC_MAX_FINGERS; i++) {
155 state->fingers[i].active = fingers & 0x1;
156 if (!state->fingers[i].active) {
157 /*
158 * Even when the finger becomes active again, we still
159 * will have to wait for the first valid position.
160 */
161 state->fingers[i].valid = false;
162 }
163 fingers >>= 1;
164 }
165}
166
167static void focaltech_process_abs_packet(struct psmouse *psmouse,
168 unsigned char *packet)
169{
170 struct focaltech_data *priv = psmouse->private;
171 struct focaltech_hw_state *state = &priv->state;
172 unsigned int finger;
173
174 finger = (packet[1] >> 4) - 1;
175 if (finger >= FOC_MAX_FINGERS) {
176 psmouse_err(psmouse, "Invalid finger in abs packet: %d\n",
177 finger);
178 return;
179 }
180
181 state->pressed = (packet[0] >> 4) & 1;
182
183 /*
184 * packet[5] contains some kind of tool size in the most
185 * significant nibble. 0xff is a special value (latching) that
186 * signals a large contact area.
187 */
188 if (packet[5] == 0xff) {
189 state->fingers[finger].valid = false;
190 return;
191 }
192
193 state->fingers[finger].x = ((packet[1] & 0xf) << 8) | packet[2];
194 state->fingers[finger].y = (packet[3] << 8) | packet[4];
195 state->fingers[finger].valid = true;
196}
197
198static void focaltech_process_rel_packet(struct psmouse *psmouse,
199 unsigned char *packet)
200{
201 struct focaltech_data *priv = psmouse->private;
202 struct focaltech_hw_state *state = &priv->state;
203 int finger1, finger2;
204
205 state->pressed = packet[0] >> 7;
206 finger1 = ((packet[0] >> 4) & 0x7) - 1;
207 if (finger1 < FOC_MAX_FINGERS) {
208 state->fingers[finger1].x += (char)packet[1];
209 state->fingers[finger1].y += (char)packet[2];
210 } else {
211 psmouse_err(psmouse, "First finger in rel packet invalid: %d\n",
212 finger1);
213 }
214
215 /*
216 * If there is an odd number of fingers, the last relative
217 * packet only contains one finger. In this case, the second
218 * finger index in the packet is 0 (we subtract 1 in the lines
219 * above to create array indices, so the finger will overflow
220 * and be above FOC_MAX_FINGERS).
221 */
222 finger2 = ((packet[3] >> 4) & 0x7) - 1;
223 if (finger2 < FOC_MAX_FINGERS) {
224 state->fingers[finger2].x += (char)packet[4];
225 state->fingers[finger2].y += (char)packet[5];
226 }
227}
228
229static void focaltech_process_packet(struct psmouse *psmouse)
230{
231 unsigned char *packet = psmouse->packet;
232
233 switch (packet[0] & 0xf) {
234 case FOC_TOUCH:
235 focaltech_process_touch_packet(psmouse, packet);
236 break;
237
238 case FOC_ABS:
239 focaltech_process_abs_packet(psmouse, packet);
240 break;
241
242 case FOC_REL:
243 focaltech_process_rel_packet(psmouse, packet);
244 break;
245
246 default:
247 psmouse_err(psmouse, "Unknown packet type: %02x\n", packet[0]);
248 break;
249 }
250
251 focaltech_report_state(psmouse);
252}
253
254static psmouse_ret_t focaltech_process_byte(struct psmouse *psmouse)
255{
256 if (psmouse->pktcnt >= 6) { /* Full packet received */
257 focaltech_process_packet(psmouse);
258 return PSMOUSE_FULL_PACKET;
259 }
260
261 /*
262 * We might want to do some validation of the data here, but
263 * we do not know the protocol well enough
264 */
265 return PSMOUSE_GOOD_DATA;
266}
267
268static int focaltech_switch_protocol(struct psmouse *psmouse)
269{
270 struct ps2dev *ps2dev = &psmouse->ps2dev;
271 unsigned char param[3];
272
273 param[0] = 0;
274 if (ps2_command(ps2dev, param, 0x10f8))
275 return -EIO;
276
277 if (ps2_command(ps2dev, param, 0x10f8))
278 return -EIO;
279
280 if (ps2_command(ps2dev, param, 0x10f8))
281 return -EIO;
282
283 param[0] = 1;
284 if (ps2_command(ps2dev, param, 0x10f8))
285 return -EIO;
286
287 if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETSCALE11))
288 return -EIO;
289
290 if (ps2_command(ps2dev, param, PSMOUSE_CMD_ENABLE))
291 return -EIO;
292
293 return 0;
294}
295
296static void focaltech_disconnect(struct psmouse *psmouse)
297{
298 focaltech_reset(psmouse);
299 kfree(psmouse->private);
300 psmouse->private = NULL;
301}
302
303static int focaltech_reconnect(struct psmouse *psmouse)
304{
305 int error;
306
307 focaltech_reset(psmouse);
308
309 error = focaltech_switch_protocol(psmouse);
310 if (error) {
311 psmouse_err(psmouse, "Unable to initialize the device\n");
312 return error;
313 }
314
315 return 0;
316}
317
318static void focaltech_set_input_params(struct psmouse *psmouse)
319{
320 struct input_dev *dev = psmouse->dev;
321 struct focaltech_data *priv = psmouse->private;
322
323 /*
324 * Undo part of setup done for us by psmouse core since touchpad
325 * is not a relative device.
326 */
327 __clear_bit(EV_REL, dev->evbit);
328 __clear_bit(REL_X, dev->relbit);
329 __clear_bit(REL_Y, dev->relbit);
330 __clear_bit(BTN_RIGHT, dev->keybit);
331 __clear_bit(BTN_MIDDLE, dev->keybit);
332
333 /*
334 * Now set up our capabilities.
335 */
336 __set_bit(EV_ABS, dev->evbit);
337 input_set_abs_params(dev, ABS_MT_POSITION_X, 0, priv->x_max, 0, 0);
338 input_set_abs_params(dev, ABS_MT_POSITION_Y, 0, priv->y_max, 0, 0);
339 input_mt_init_slots(dev, 5, INPUT_MT_POINTER);
340 __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);
341}
342
343static int focaltech_read_register(struct ps2dev *ps2dev, int reg,
344 unsigned char *param)
345{
346 if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETSCALE11))
347 return -EIO;
348
349 param[0] = 0;
350 if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES))
351 return -EIO;
352
353 if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES))
354 return -EIO;
355
356 if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES))
357 return -EIO;
358
359 param[0] = reg;
360 if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES))
361 return -EIO;
362
363 if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
364 return -EIO;
365
366 return 0;
367}
368
369static int focaltech_read_size(struct psmouse *psmouse)
370{
371 struct ps2dev *ps2dev = &psmouse->ps2dev;
372 struct focaltech_data *priv = psmouse->private;
373 char param[3];
374
375 if (focaltech_read_register(ps2dev, 2, param))
376 return -EIO;
377
378 /* not sure whether this is 100% correct */
379 priv->x_max = (unsigned char)param[1] * 128;
380 priv->y_max = (unsigned char)param[2] * 128;
381
382 return 0;
383}
384int focaltech_init(struct psmouse *psmouse)
385{
386 struct focaltech_data *priv;
387 int error;
388
389 psmouse->private = priv = kzalloc(sizeof(struct focaltech_data),
390 GFP_KERNEL);
391 if (!priv)
392 return -ENOMEM;
393
394 focaltech_reset(psmouse);
395
396 error = focaltech_read_size(psmouse);
397 if (error) {
398 psmouse_err(psmouse,
399 "Unable to read the size of the touchpad\n");
400 goto fail;
401 }
402
403 error = focaltech_switch_protocol(psmouse);
404 if (error) {
405 psmouse_err(psmouse, "Unable to initialize the device\n");
406 goto fail;
407 }
408
409 focaltech_set_input_params(psmouse);
410
411 psmouse->protocol_handler = focaltech_process_byte;
412 psmouse->pktsize = 6;
413 psmouse->disconnect = focaltech_disconnect;
414 psmouse->reconnect = focaltech_reconnect;
415 psmouse->cleanup = focaltech_reset;
416 /* resync is not supported yet */
417 psmouse->resync_time = 0;
50 418
51 return 0; 419 return 0;
420
421fail:
422 focaltech_reset(psmouse);
423 kfree(priv);
424 return error;
52} 425}
426
427bool focaltech_supported(void)
428{
429 return true;
430}
431
432#else /* CONFIG_MOUSE_PS2_FOCALTECH */
433
434int focaltech_init(struct psmouse *psmouse)
435{
436 focaltech_reset(psmouse);
437
438 return 0;
439}
440
441bool focaltech_supported(void)
442{
443 return false;
444}
445
446#endif /* CONFIG_MOUSE_PS2_FOCALTECH */
diff --git a/drivers/input/mouse/focaltech.h b/drivers/input/mouse/focaltech.h
index 498650c61e28..71870a9b548a 100644
--- a/drivers/input/mouse/focaltech.h
+++ b/drivers/input/mouse/focaltech.h
@@ -2,6 +2,7 @@
2 * Focaltech TouchPad PS/2 mouse driver 2 * Focaltech TouchPad PS/2 mouse driver
3 * 3 *
4 * Copyright (c) 2014 Red Hat Inc. 4 * Copyright (c) 2014 Red Hat Inc.
5 * Copyright (c) 2014 Mathias Gottschlag <mgottschlag@gmail.com>
5 * 6 *
6 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
@@ -18,5 +19,6 @@
18 19
19int focaltech_detect(struct psmouse *psmouse, bool set_properties); 20int focaltech_detect(struct psmouse *psmouse, bool set_properties);
20int focaltech_init(struct psmouse *psmouse); 21int focaltech_init(struct psmouse *psmouse);
22bool focaltech_supported(void);
21 23
22#endif 24#endif
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index 95a3a6e2faf6..68469feda470 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -725,16 +725,19 @@ static int psmouse_extensions(struct psmouse *psmouse,
725 725
726/* Always check for focaltech, this is safe as it uses pnp-id matching */ 726/* Always check for focaltech, this is safe as it uses pnp-id matching */
727 if (psmouse_do_detect(focaltech_detect, psmouse, set_properties) == 0) { 727 if (psmouse_do_detect(focaltech_detect, psmouse, set_properties) == 0) {
728 if (!set_properties || focaltech_init(psmouse) == 0) { 728 if (max_proto > PSMOUSE_IMEX) {
729 /* 729 if (!set_properties || focaltech_init(psmouse) == 0) {
730 * Not supported yet, use bare protocol. 730 if (focaltech_supported())
731 * Note that we need to also restrict 731 return PSMOUSE_FOCALTECH;
732 * psmouse_max_proto so that psmouse_initialize() 732 /*
733 * does not try to reset rate and resolution, 733 * Note that we need to also restrict
734 * because even that upsets the device. 734 * psmouse_max_proto so that psmouse_initialize()
735 */ 735 * does not try to reset rate and resolution,
736 psmouse_max_proto = PSMOUSE_PS2; 736 * because even that upsets the device.
737 return PSMOUSE_PS2; 737 */
738 psmouse_max_proto = PSMOUSE_PS2;
739 return PSMOUSE_PS2;
740 }
738 } 741 }
739 } 742 }
740 743
@@ -1063,6 +1066,15 @@ static const struct psmouse_protocol psmouse_protocols[] = {
1063 .alias = "cortps", 1066 .alias = "cortps",
1064 .detect = cortron_detect, 1067 .detect = cortron_detect,
1065 }, 1068 },
1069#ifdef CONFIG_MOUSE_PS2_FOCALTECH
1070 {
1071 .type = PSMOUSE_FOCALTECH,
1072 .name = "FocalTechPS/2",
1073 .alias = "focaltech",
1074 .detect = focaltech_detect,
1075 .init = focaltech_init,
1076 },
1077#endif
1066 { 1078 {
1067 .type = PSMOUSE_AUTO, 1079 .type = PSMOUSE_AUTO,
1068 .name = "auto", 1080 .name = "auto",
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
index f4cf664c7db3..c2ff137ecbdb 100644
--- a/drivers/input/mouse/psmouse.h
+++ b/drivers/input/mouse/psmouse.h
@@ -96,6 +96,7 @@ enum psmouse_type {
96 PSMOUSE_FSP, 96 PSMOUSE_FSP,
97 PSMOUSE_SYNAPTICS_RELATIVE, 97 PSMOUSE_SYNAPTICS_RELATIVE,
98 PSMOUSE_CYPRESS, 98 PSMOUSE_CYPRESS,
99 PSMOUSE_FOCALTECH,
99 PSMOUSE_AUTO /* This one should always be last */ 100 PSMOUSE_AUTO /* This one should always be last */
100}; 101};
101 102
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index 23e26e0768b5..7e705ee90b86 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -67,6 +67,9 @@
67#define X_MAX_POSITIVE 8176 67#define X_MAX_POSITIVE 8176
68#define Y_MAX_POSITIVE 8176 68#define Y_MAX_POSITIVE 8176
69 69
70/* maximum ABS_MT_POSITION displacement (in mm) */
71#define DMAX 10
72
70/***************************************************************************** 73/*****************************************************************************
71 * Stuff we need even when we do not want native Synaptics support 74 * Stuff we need even when we do not want native Synaptics support
72 ****************************************************************************/ 75 ****************************************************************************/
@@ -575,14 +578,6 @@ static void synaptics_pt_create(struct psmouse *psmouse)
575 * Functions to interpret the absolute mode packets 578 * Functions to interpret the absolute mode packets
576 ****************************************************************************/ 579 ****************************************************************************/
577 580
578static void synaptics_mt_state_set(struct synaptics_mt_state *state, int count,
579 int sgm, int agm)
580{
581 state->count = count;
582 state->sgm = sgm;
583 state->agm = agm;
584}
585
586static void synaptics_parse_agm(const unsigned char buf[], 581static void synaptics_parse_agm(const unsigned char buf[],
587 struct synaptics_data *priv, 582 struct synaptics_data *priv,
588 struct synaptics_hw_state *hw) 583 struct synaptics_hw_state *hw)
@@ -601,16 +596,13 @@ static void synaptics_parse_agm(const unsigned char buf[],
601 break; 596 break;
602 597
603 case 2: 598 case 2:
604 /* AGM-CONTACT packet: (count, sgm, agm) */ 599 /* AGM-CONTACT packet: we are only interested in the count */
605 synaptics_mt_state_set(&agm->mt_state, buf[1], buf[2], buf[4]); 600 priv->agm_count = buf[1];
606 break; 601 break;
607 602
608 default: 603 default:
609 break; 604 break;
610 } 605 }
611
612 /* Record that at least one AGM has been received since last SGM */
613 priv->agm_pending = true;
614} 606}
615 607
616static bool is_forcepad; 608static bool is_forcepad;
@@ -804,424 +796,68 @@ static void synaptics_report_buttons(struct psmouse *psmouse,
804 input_report_key(dev, BTN_0 + i, hw->ext_buttons & (1 << i)); 796 input_report_key(dev, BTN_0 + i, hw->ext_buttons & (1 << i));
805} 797}
806 798
807static void synaptics_report_slot(struct input_dev *dev, int slot,
808 const struct synaptics_hw_state *hw)
809{
810 input_mt_slot(dev, slot);
811 input_mt_report_slot_state(dev, MT_TOOL_FINGER, (hw != NULL));
812 if (!hw)
813 return;
814
815 input_report_abs(dev, ABS_MT_POSITION_X, hw->x);
816 input_report_abs(dev, ABS_MT_POSITION_Y, synaptics_invert_y(hw->y));
817 input_report_abs(dev, ABS_MT_PRESSURE, hw->z);
818}
819
820static void synaptics_report_mt_data(struct psmouse *psmouse, 799static void synaptics_report_mt_data(struct psmouse *psmouse,
821 struct synaptics_mt_state *mt_state, 800 const struct synaptics_hw_state *sgm,
822 const struct synaptics_hw_state *sgm) 801 int num_fingers)
823{ 802{
824 struct input_dev *dev = psmouse->dev; 803 struct input_dev *dev = psmouse->dev;
825 struct synaptics_data *priv = psmouse->private; 804 struct synaptics_data *priv = psmouse->private;
826 struct synaptics_hw_state *agm = &priv->agm; 805 const struct synaptics_hw_state *hw[2] = { sgm, &priv->agm };
827 struct synaptics_mt_state *old = &priv->mt_state; 806 struct input_mt_pos pos[2];
807 int slot[2], nsemi, i;
828 808
829 switch (mt_state->count) { 809 nsemi = clamp_val(num_fingers, 0, 2);
830 case 0:
831 synaptics_report_slot(dev, 0, NULL);
832 synaptics_report_slot(dev, 1, NULL);
833 break;
834 case 1:
835 if (mt_state->sgm == -1) {
836 synaptics_report_slot(dev, 0, NULL);
837 synaptics_report_slot(dev, 1, NULL);
838 } else if (mt_state->sgm == 0) {
839 synaptics_report_slot(dev, 0, sgm);
840 synaptics_report_slot(dev, 1, NULL);
841 } else {
842 synaptics_report_slot(dev, 0, NULL);
843 synaptics_report_slot(dev, 1, sgm);
844 }
845 break;
846 default:
847 /*
848 * If the finger slot contained in SGM is valid, and either
849 * hasn't changed, or is new, or the old SGM has now moved to
850 * AGM, then report SGM in MTB slot 0.
851 * Otherwise, empty MTB slot 0.
852 */
853 if (mt_state->sgm != -1 &&
854 (mt_state->sgm == old->sgm ||
855 old->sgm == -1 || mt_state->agm == old->sgm))
856 synaptics_report_slot(dev, 0, sgm);
857 else
858 synaptics_report_slot(dev, 0, NULL);
859 810
860 /* 811 for (i = 0; i < nsemi; i++) {
861 * If the finger slot contained in AGM is valid, and either 812 pos[i].x = hw[i]->x;
862 * hasn't changed, or is new, then report AGM in MTB slot 1. 813 pos[i].y = synaptics_invert_y(hw[i]->y);
863 * Otherwise, empty MTB slot 1.
864 *
865 * However, in the case where the AGM is new, make sure that
866 * that it is either the same as the old SGM, or there was no
867 * SGM.
868 *
869 * Otherwise, if the SGM was just 1, and the new AGM is 2, then
870 * the new AGM will keep the old SGM's tracking ID, which can
871 * cause apparent drumroll. This happens if in the following
872 * valid finger sequence:
873 *
874 * Action SGM AGM (MTB slot:Contact)
875 * 1. Touch contact 0 (0:0)
876 * 2. Touch contact 1 (0:0, 1:1)
877 * 3. Lift contact 0 (1:1)
878 * 4. Touch contacts 2,3 (0:2, 1:3)
879 *
880 * In step 4, contact 3, in AGM must not be given the same
881 * tracking ID as contact 1 had in step 3. To avoid this,
882 * the first agm with contact 3 is dropped and slot 1 is
883 * invalidated (tracking ID = -1).
884 */
885 if (mt_state->agm != -1 &&
886 (mt_state->agm == old->agm ||
887 (old->agm == -1 &&
888 (old->sgm == -1 || mt_state->agm == old->sgm))))
889 synaptics_report_slot(dev, 1, agm);
890 else
891 synaptics_report_slot(dev, 1, NULL);
892 break;
893 } 814 }
894 815
816 input_mt_assign_slots(dev, slot, pos, nsemi, DMAX * priv->x_res);
817
818 for (i = 0; i < nsemi; i++) {
819 input_mt_slot(dev, slot[i]);
820 input_mt_report_slot_state(dev, MT_TOOL_FINGER, true);
821 input_report_abs(dev, ABS_MT_POSITION_X, pos[i].x);
822 input_report_abs(dev, ABS_MT_POSITION_Y, pos[i].y);
823 input_report_abs(dev, ABS_MT_PRESSURE, hw[i]->z);
824 }
825
826 input_mt_drop_unused(dev);
827
895 /* Don't use active slot count to generate BTN_TOOL events. */ 828 /* Don't use active slot count to generate BTN_TOOL events. */
896 input_mt_report_pointer_emulation(dev, false); 829 input_mt_report_pointer_emulation(dev, false);
897 830
898 /* Send the number of fingers reported by touchpad itself. */ 831 /* Send the number of fingers reported by touchpad itself. */
899 input_mt_report_finger_count(dev, mt_state->count); 832 input_mt_report_finger_count(dev, num_fingers);
900 833
901 synaptics_report_buttons(psmouse, sgm); 834 synaptics_report_buttons(psmouse, sgm);
902 835
903 input_sync(dev); 836 input_sync(dev);
904} 837}
905 838
906/* Handle case where mt_state->count = 0 */
907static void synaptics_image_sensor_0f(struct synaptics_data *priv,
908 struct synaptics_mt_state *mt_state)
909{
910 synaptics_mt_state_set(mt_state, 0, -1, -1);
911 priv->mt_state_lost = false;
912}
913
914/* Handle case where mt_state->count = 1 */
915static void synaptics_image_sensor_1f(struct synaptics_data *priv,
916 struct synaptics_mt_state *mt_state)
917{
918 struct synaptics_hw_state *agm = &priv->agm;
919 struct synaptics_mt_state *old = &priv->mt_state;
920
921 /*
922 * If the last AGM was (0,0,0), and there is only one finger left,
923 * then we absolutely know that SGM contains slot 0, and all other
924 * fingers have been removed.
925 */
926 if (priv->agm_pending && agm->z == 0) {
927 synaptics_mt_state_set(mt_state, 1, 0, -1);
928 priv->mt_state_lost = false;
929 return;
930 }
931
932 switch (old->count) {
933 case 0:
934 synaptics_mt_state_set(mt_state, 1, 0, -1);
935 break;
936 case 1:
937 /*
938 * If mt_state_lost, then the previous transition was 3->1,
939 * and SGM now contains either slot 0 or 1, but we don't know
940 * which. So, we just assume that the SGM now contains slot 1.
941 *
942 * If pending AGM and either:
943 * (a) the previous SGM slot contains slot 0, or
944 * (b) there was no SGM slot
945 * then, the SGM now contains slot 1
946 *
947 * Case (a) happens with very rapid "drum roll" gestures, where
948 * slot 0 finger is lifted and a new slot 1 finger touches
949 * within one reporting interval.
950 *
951 * Case (b) happens if initially two or more fingers tap
952 * briefly, and all but one lift before the end of the first
953 * reporting interval.
954 *
955 * (In both these cases, slot 0 will becomes empty, so SGM
956 * contains slot 1 with the new finger)
957 *
958 * Else, if there was no previous SGM, it now contains slot 0.
959 *
960 * Otherwise, SGM still contains the same slot.
961 */
962 if (priv->mt_state_lost ||
963 (priv->agm_pending && old->sgm <= 0))
964 synaptics_mt_state_set(mt_state, 1, 1, -1);
965 else if (old->sgm == -1)
966 synaptics_mt_state_set(mt_state, 1, 0, -1);
967 break;
968 case 2:
969 /*
970 * If mt_state_lost, we don't know which finger SGM contains.
971 *
972 * So, report 1 finger, but with both slots empty.
973 * We will use slot 1 on subsequent 1->1
974 */
975 if (priv->mt_state_lost) {
976 synaptics_mt_state_set(mt_state, 1, -1, -1);
977 break;
978 }
979 /*
980 * Since the last AGM was NOT (0,0,0), it was the finger in
981 * slot 0 that has been removed.
982 * So, SGM now contains previous AGM's slot, and AGM is now
983 * empty.
984 */
985 synaptics_mt_state_set(mt_state, 1, old->agm, -1);
986 break;
987 case 3:
988 /*
989 * Since last AGM was not (0,0,0), we don't know which finger
990 * is left.
991 *
992 * So, report 1 finger, but with both slots empty.
993 * We will use slot 1 on subsequent 1->1
994 */
995 synaptics_mt_state_set(mt_state, 1, -1, -1);
996 priv->mt_state_lost = true;
997 break;
998 case 4:
999 case 5:
1000 /* mt_state was updated by AGM-CONTACT packet */
1001 break;
1002 }
1003}
1004
1005/* Handle case where mt_state->count = 2 */
1006static void synaptics_image_sensor_2f(struct synaptics_data *priv,
1007 struct synaptics_mt_state *mt_state)
1008{
1009 struct synaptics_mt_state *old = &priv->mt_state;
1010
1011 switch (old->count) {
1012 case 0:
1013 synaptics_mt_state_set(mt_state, 2, 0, 1);
1014 break;
1015 case 1:
1016 /*
1017 * If previous SGM contained slot 1 or higher, SGM now contains
1018 * slot 0 (the newly touching finger) and AGM contains SGM's
1019 * previous slot.
1020 *
1021 * Otherwise, SGM still contains slot 0 and AGM now contains
1022 * slot 1.
1023 */
1024 if (old->sgm >= 1)
1025 synaptics_mt_state_set(mt_state, 2, 0, old->sgm);
1026 else
1027 synaptics_mt_state_set(mt_state, 2, 0, 1);
1028 break;
1029 case 2:
1030 /*
1031 * If mt_state_lost, SGM now contains either finger 1 or 2, but
1032 * we don't know which.
1033 * So, we just assume that the SGM contains slot 0 and AGM 1.
1034 */
1035 if (priv->mt_state_lost)
1036 synaptics_mt_state_set(mt_state, 2, 0, 1);
1037 /*
1038 * Otherwise, use the same mt_state, since it either hasn't
1039 * changed, or was updated by a recently received AGM-CONTACT
1040 * packet.
1041 */
1042 break;
1043 case 3:
1044 /*
1045 * 3->2 transitions have two unsolvable problems:
1046 * 1) no indication is given which finger was removed
1047 * 2) no way to tell if agm packet was for finger 3
1048 * before 3->2, or finger 2 after 3->2.
1049 *
1050 * So, report 2 fingers, but empty all slots.
1051 * We will guess slots [0,1] on subsequent 2->2.
1052 */
1053 synaptics_mt_state_set(mt_state, 2, -1, -1);
1054 priv->mt_state_lost = true;
1055 break;
1056 case 4:
1057 case 5:
1058 /* mt_state was updated by AGM-CONTACT packet */
1059 break;
1060 }
1061}
1062
1063/* Handle case where mt_state->count = 3 */
1064static void synaptics_image_sensor_3f(struct synaptics_data *priv,
1065 struct synaptics_mt_state *mt_state)
1066{
1067 struct synaptics_mt_state *old = &priv->mt_state;
1068
1069 switch (old->count) {
1070 case 0:
1071 synaptics_mt_state_set(mt_state, 3, 0, 2);
1072 break;
1073 case 1:
1074 /*
1075 * If previous SGM contained slot 2 or higher, SGM now contains
1076 * slot 0 (one of the newly touching fingers) and AGM contains
1077 * SGM's previous slot.
1078 *
1079 * Otherwise, SGM now contains slot 0 and AGM contains slot 2.
1080 */
1081 if (old->sgm >= 2)
1082 synaptics_mt_state_set(mt_state, 3, 0, old->sgm);
1083 else
1084 synaptics_mt_state_set(mt_state, 3, 0, 2);
1085 break;
1086 case 2:
1087 /*
1088 * If the AGM previously contained slot 3 or higher, then the
1089 * newly touching finger is in the lowest available slot.
1090 *
1091 * If SGM was previously 1 or higher, then the new SGM is
1092 * now slot 0 (with a new finger), otherwise, the new finger
1093 * is now in a hidden slot between 0 and AGM's slot.
1094 *
1095 * In all such cases, the SGM now contains slot 0, and the AGM
1096 * continues to contain the same slot as before.
1097 */
1098 if (old->agm >= 3) {
1099 synaptics_mt_state_set(mt_state, 3, 0, old->agm);
1100 break;
1101 }
1102
1103 /*
1104 * After some 3->1 and all 3->2 transitions, we lose track
1105 * of which slot is reported by SGM and AGM.
1106 *
1107 * For 2->3 in this state, report 3 fingers, but empty all
1108 * slots, and we will guess (0,2) on a subsequent 0->3.
1109 *
1110 * To userspace, the resulting transition will look like:
1111 * 2:[0,1] -> 3:[-1,-1] -> 3:[0,2]
1112 */
1113 if (priv->mt_state_lost) {
1114 synaptics_mt_state_set(mt_state, 3, -1, -1);
1115 break;
1116 }
1117
1118 /*
1119 * If the (SGM,AGM) really previously contained slots (0, 1),
1120 * then we cannot know what slot was just reported by the AGM,
1121 * because the 2->3 transition can occur either before or after
1122 * the AGM packet. Thus, this most recent AGM could contain
1123 * either the same old slot 1 or the new slot 2.
1124 * Subsequent AGMs will be reporting slot 2.
1125 *
1126 * To userspace, the resulting transition will look like:
1127 * 2:[0,1] -> 3:[0,-1] -> 3:[0,2]
1128 */
1129 synaptics_mt_state_set(mt_state, 3, 0, -1);
1130 break;
1131 case 3:
1132 /*
1133 * If, for whatever reason, the previous agm was invalid,
1134 * Assume SGM now contains slot 0, AGM now contains slot 2.
1135 */
1136 if (old->agm <= 2)
1137 synaptics_mt_state_set(mt_state, 3, 0, 2);
1138 /*
1139 * mt_state either hasn't changed, or was updated by a recently
1140 * received AGM-CONTACT packet.
1141 */
1142 break;
1143
1144 case 4:
1145 case 5:
1146 /* mt_state was updated by AGM-CONTACT packet */
1147 break;
1148 }
1149}
1150
1151/* Handle case where mt_state->count = 4, or = 5 */
1152static void synaptics_image_sensor_45f(struct synaptics_data *priv,
1153 struct synaptics_mt_state *mt_state)
1154{
1155 /* mt_state was updated correctly by AGM-CONTACT packet */
1156 priv->mt_state_lost = false;
1157}
1158
1159static void synaptics_image_sensor_process(struct psmouse *psmouse, 839static void synaptics_image_sensor_process(struct psmouse *psmouse,
1160 struct synaptics_hw_state *sgm) 840 struct synaptics_hw_state *sgm)
1161{ 841{
1162 struct synaptics_data *priv = psmouse->private; 842 struct synaptics_data *priv = psmouse->private;
1163 struct synaptics_hw_state *agm = &priv->agm; 843 int num_fingers;
1164 struct synaptics_mt_state mt_state;
1165
1166 /* Initialize using current mt_state (as updated by last agm) */
1167 mt_state = agm->mt_state;
1168 844
1169 /* 845 /*
1170 * Update mt_state using the new finger count and current mt_state. 846 * Update mt_state using the new finger count and current mt_state.
1171 */ 847 */
1172 if (sgm->z == 0) 848 if (sgm->z == 0)
1173 synaptics_image_sensor_0f(priv, &mt_state); 849 num_fingers = 0;
1174 else if (sgm->w >= 4) 850 else if (sgm->w >= 4)
1175 synaptics_image_sensor_1f(priv, &mt_state); 851 num_fingers = 1;
1176 else if (sgm->w == 0) 852 else if (sgm->w == 0)
1177 synaptics_image_sensor_2f(priv, &mt_state); 853 num_fingers = 2;
1178 else if (sgm->w == 1 && mt_state.count <= 3) 854 else if (sgm->w == 1)
1179 synaptics_image_sensor_3f(priv, &mt_state); 855 num_fingers = priv->agm_count ? priv->agm_count : 3;
1180 else 856 else
1181 synaptics_image_sensor_45f(priv, &mt_state); 857 num_fingers = 4;
1182 858
1183 /* Send resulting input events to user space */ 859 /* Send resulting input events to user space */
1184 synaptics_report_mt_data(psmouse, &mt_state, sgm); 860 synaptics_report_mt_data(psmouse, sgm, num_fingers);
1185
1186 /* Store updated mt_state */
1187 priv->mt_state = agm->mt_state = mt_state;
1188 priv->agm_pending = false;
1189}
1190
1191static void synaptics_profile_sensor_process(struct psmouse *psmouse,
1192 struct synaptics_hw_state *sgm,
1193 int num_fingers)
1194{
1195 struct input_dev *dev = psmouse->dev;
1196 struct synaptics_data *priv = psmouse->private;
1197 struct synaptics_hw_state *hw[2] = { sgm, &priv->agm };
1198 struct input_mt_pos pos[2];
1199 int slot[2], nsemi, i;
1200
1201 nsemi = clamp_val(num_fingers, 0, 2);
1202
1203 for (i = 0; i < nsemi; i++) {
1204 pos[i].x = hw[i]->x;
1205 pos[i].y = synaptics_invert_y(hw[i]->y);
1206 }
1207
1208 input_mt_assign_slots(dev, slot, pos, nsemi);
1209
1210 for (i = 0; i < nsemi; i++) {
1211 input_mt_slot(dev, slot[i]);
1212 input_mt_report_slot_state(dev, MT_TOOL_FINGER, true);
1213 input_report_abs(dev, ABS_MT_POSITION_X, pos[i].x);
1214 input_report_abs(dev, ABS_MT_POSITION_Y, pos[i].y);
1215 input_report_abs(dev, ABS_MT_PRESSURE, hw[i]->z);
1216 }
1217
1218 input_mt_drop_unused(dev);
1219 input_mt_report_pointer_emulation(dev, false);
1220 input_mt_report_finger_count(dev, num_fingers);
1221
1222 synaptics_report_buttons(psmouse, sgm);
1223
1224 input_sync(dev);
1225} 861}
1226 862
1227/* 863/*
@@ -1288,7 +924,7 @@ static void synaptics_process_packet(struct psmouse *psmouse)
1288 } 924 }
1289 925
1290 if (cr48_profile_sensor) { 926 if (cr48_profile_sensor) {
1291 synaptics_profile_sensor_process(psmouse, &hw, num_fingers); 927 synaptics_report_mt_data(psmouse, &hw, num_fingers);
1292 return; 928 return;
1293 } 929 }
1294 930
@@ -1445,7 +1081,7 @@ static void set_input_params(struct psmouse *psmouse,
1445 ABS_MT_POSITION_Y); 1081 ABS_MT_POSITION_Y);
1446 /* Image sensors can report per-contact pressure */ 1082 /* Image sensors can report per-contact pressure */
1447 input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 255, 0, 0); 1083 input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 255, 0, 0);
1448 input_mt_init_slots(dev, 2, INPUT_MT_POINTER); 1084 input_mt_init_slots(dev, 2, INPUT_MT_POINTER | INPUT_MT_TRACK);
1449 1085
1450 /* Image sensors can signal 4 and 5 finger clicks */ 1086 /* Image sensors can signal 4 and 5 finger clicks */
1451 __set_bit(BTN_TOOL_QUADTAP, dev->keybit); 1087 __set_bit(BTN_TOOL_QUADTAP, dev->keybit);
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h
index 1bd01f21783b..6faf9bb7c117 100644
--- a/drivers/input/mouse/synaptics.h
+++ b/drivers/input/mouse/synaptics.h
@@ -119,16 +119,6 @@
119#define SYN_REDUCED_FILTER_FUZZ 8 119#define SYN_REDUCED_FILTER_FUZZ 8
120 120
121/* 121/*
122 * A structure to describe which internal touchpad finger slots are being
123 * reported in raw packets.
124 */
125struct synaptics_mt_state {
126 int count; /* num fingers being tracked */
127 int sgm; /* which slot is reported by sgm pkt */
128 int agm; /* which slot is reported by agm pkt*/
129};
130
131/*
132 * A structure to describe the state of the touchpad hardware (buttons and pad) 122 * A structure to describe the state of the touchpad hardware (buttons and pad)
133 */ 123 */
134struct synaptics_hw_state { 124struct synaptics_hw_state {
@@ -143,9 +133,6 @@ struct synaptics_hw_state {
143 unsigned int down:1; 133 unsigned int down:1;
144 unsigned char ext_buttons; 134 unsigned char ext_buttons;
145 signed char scroll; 135 signed char scroll;
146
147 /* As reported in last AGM-CONTACT packets */
148 struct synaptics_mt_state mt_state;
149}; 136};
150 137
151struct synaptics_data { 138struct synaptics_data {
@@ -170,15 +157,12 @@ struct synaptics_data {
170 157
171 struct serio *pt_port; /* Pass-through serio port */ 158 struct serio *pt_port; /* Pass-through serio port */
172 159
173 struct synaptics_mt_state mt_state; /* Current mt finger state */
174 bool mt_state_lost; /* mt_state may be incorrect */
175
176 /* 160 /*
177 * Last received Advanced Gesture Mode (AGM) packet. An AGM packet 161 * Last received Advanced Gesture Mode (AGM) packet. An AGM packet
178 * contains position data for a second contact, at half resolution. 162 * contains position data for a second contact, at half resolution.
179 */ 163 */
180 struct synaptics_hw_state agm; 164 struct synaptics_hw_state agm;
181 bool agm_pending; /* new AGM packet received */ 165 unsigned int agm_count; /* finger count reported by agm */
182 166
183 /* ForcePad handling */ 167 /* ForcePad handling */
184 unsigned long press_start; 168 unsigned long press_start;
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig
index bc2d47431bdc..77833d7a004b 100644
--- a/drivers/input/serio/Kconfig
+++ b/drivers/input/serio/Kconfig
@@ -281,4 +281,14 @@ config HYPERV_KEYBOARD
281 To compile this driver as a module, choose M here: the module will 281 To compile this driver as a module, choose M here: the module will
282 be called hyperv_keyboard. 282 be called hyperv_keyboard.
283 283
284config SERIO_SUN4I_PS2
285 tristate "Allwinner A10 PS/2 controller support"
286 depends on ARCH_SUNXI || COMPILE_TEST
287 help
288 This selects support for the PS/2 Host Controller on
289 Allwinner A10.
290
291 To compile this driver as a module, choose M here: the
292 module will be called sun4i-ps2.
293
284endif 294endif
diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile
index 815d874fe724..c600089b7a34 100644
--- a/drivers/input/serio/Makefile
+++ b/drivers/input/serio/Makefile
@@ -29,3 +29,4 @@ obj-$(CONFIG_SERIO_ARC_PS2) += arc_ps2.o
29obj-$(CONFIG_SERIO_APBPS2) += apbps2.o 29obj-$(CONFIG_SERIO_APBPS2) += apbps2.o
30obj-$(CONFIG_SERIO_OLPC_APSP) += olpc_apsp.o 30obj-$(CONFIG_SERIO_OLPC_APSP) += olpc_apsp.o
31obj-$(CONFIG_HYPERV_KEYBOARD) += hyperv-keyboard.o 31obj-$(CONFIG_HYPERV_KEYBOARD) += hyperv-keyboard.o
32obj-$(CONFIG_SERIO_SUN4I_PS2) += sun4i-ps2.o
diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
index 8d9ba0c3827c..94ab494a6ade 100644
--- a/drivers/input/serio/gscps2.c
+++ b/drivers/input/serio/gscps2.c
@@ -40,7 +40,6 @@
40MODULE_AUTHOR("Laurent Canet <canetl@esiee.fr>, Thibaut Varene <varenet@parisc-linux.org>, Helge Deller <deller@gmx.de>"); 40MODULE_AUTHOR("Laurent Canet <canetl@esiee.fr>, Thibaut Varene <varenet@parisc-linux.org>, Helge Deller <deller@gmx.de>");
41MODULE_DESCRIPTION("HP GSC PS2 port driver"); 41MODULE_DESCRIPTION("HP GSC PS2 port driver");
42MODULE_LICENSE("GPL"); 42MODULE_LICENSE("GPL");
43MODULE_DEVICE_TABLE(parisc, gscps2_device_tbl);
44 43
45#define PFX "gscps2.c: " 44#define PFX "gscps2.c: "
46 45
@@ -439,6 +438,7 @@ static struct parisc_device_id gscps2_device_tbl[] = {
439#endif 438#endif
440 { 0, } /* 0 terminated list */ 439 { 0, } /* 0 terminated list */
441}; 440};
441MODULE_DEVICE_TABLE(parisc, gscps2_device_tbl);
442 442
443static struct parisc_driver parisc_ps2_driver = { 443static struct parisc_driver parisc_ps2_driver = {
444 .name = "gsc_ps2", 444 .name = "gsc_ps2",
diff --git a/drivers/input/serio/sun4i-ps2.c b/drivers/input/serio/sun4i-ps2.c
new file mode 100644
index 000000000000..04b96fe39339
--- /dev/null
+++ b/drivers/input/serio/sun4i-ps2.c
@@ -0,0 +1,340 @@
1/*
2 * Driver for Allwinner A10 PS2 host controller
3 *
4 * Author: Vishnu Patekar <vishnupatekar0510@gmail.com>
5 * Aaron.maoye <leafy.myeh@newbietech.com>
6 */
7
8#include <linux/module.h>
9#include <linux/serio.h>
10#include <linux/interrupt.h>
11#include <linux/errno.h>
12#include <linux/slab.h>
13#include <linux/io.h>
14#include <linux/clk.h>
15#include <linux/mod_devicetable.h>
16#include <linux/platform_device.h>
17
18#define DRIVER_NAME "sun4i-ps2"
19
20/* register offset definitions */
21#define PS2_REG_GCTL 0x00 /* PS2 Module Global Control Reg */
22#define PS2_REG_DATA 0x04 /* PS2 Module Data Reg */
23#define PS2_REG_LCTL 0x08 /* PS2 Module Line Control Reg */
24#define PS2_REG_LSTS 0x0C /* PS2 Module Line Status Reg */
25#define PS2_REG_FCTL 0x10 /* PS2 Module FIFO Control Reg */
26#define PS2_REG_FSTS 0x14 /* PS2 Module FIFO Status Reg */
27#define PS2_REG_CLKDR 0x18 /* PS2 Module Clock Divider Reg*/
28
29/* PS2 GLOBAL CONTROL REGISTER PS2_GCTL */
30#define PS2_GCTL_INTFLAG BIT(4)
31#define PS2_GCTL_INTEN BIT(3)
32#define PS2_GCTL_RESET BIT(2)
33#define PS2_GCTL_MASTER BIT(1)
34#define PS2_GCTL_BUSEN BIT(0)
35
36/* PS2 LINE CONTROL REGISTER */
37#define PS2_LCTL_NOACK BIT(18)
38#define PS2_LCTL_TXDTOEN BIT(8)
39#define PS2_LCTL_STOPERREN BIT(3)
40#define PS2_LCTL_ACKERREN BIT(2)
41#define PS2_LCTL_PARERREN BIT(1)
42#define PS2_LCTL_RXDTOEN BIT(0)
43
44/* PS2 LINE STATUS REGISTER */
45#define PS2_LSTS_TXTDO BIT(8)
46#define PS2_LSTS_STOPERR BIT(3)
47#define PS2_LSTS_ACKERR BIT(2)
48#define PS2_LSTS_PARERR BIT(1)
49#define PS2_LSTS_RXTDO BIT(0)
50
51#define PS2_LINE_ERROR_BIT \
52 (PS2_LSTS_TXTDO | PS2_LSTS_STOPERR | PS2_LSTS_ACKERR | \
53 PS2_LSTS_PARERR | PS2_LSTS_RXTDO)
54
55/* PS2 FIFO CONTROL REGISTER */
56#define PS2_FCTL_TXRST BIT(17)
57#define PS2_FCTL_RXRST BIT(16)
58#define PS2_FCTL_TXUFIEN BIT(10)
59#define PS2_FCTL_TXOFIEN BIT(9)
60#define PS2_FCTL_TXRDYIEN BIT(8)
61#define PS2_FCTL_RXUFIEN BIT(2)
62#define PS2_FCTL_RXOFIEN BIT(1)
63#define PS2_FCTL_RXRDYIEN BIT(0)
64
65/* PS2 FIFO STATUS REGISTER */
66#define PS2_FSTS_TXUF BIT(10)
67#define PS2_FSTS_TXOF BIT(9)
68#define PS2_FSTS_TXRDY BIT(8)
69#define PS2_FSTS_RXUF BIT(2)
70#define PS2_FSTS_RXOF BIT(1)
71#define PS2_FSTS_RXRDY BIT(0)
72
73#define PS2_FIFO_ERROR_BIT \
74 (PS2_FSTS_TXUF | PS2_FSTS_TXOF | PS2_FSTS_RXUF | PS2_FSTS_RXOF)
75
76#define PS2_SAMPLE_CLK 1000000
77#define PS2_SCLK 125000
78
79struct sun4i_ps2data {
80 struct serio *serio;
81 struct device *dev;
82
83 /* IO mapping base */
84 void __iomem *reg_base;
85
86 /* clock management */
87 struct clk *clk;
88
89 /* irq */
90 spinlock_t lock;
91 int irq;
92};
93
94static irqreturn_t sun4i_ps2_interrupt(int irq, void *dev_id)
95{
96 struct sun4i_ps2data *drvdata = dev_id;
97 u32 intr_status;
98 u32 fifo_status;
99 unsigned char byte;
100 unsigned int rxflags = 0;
101 u32 rval;
102
103 spin_lock(&drvdata->lock);
104
105 /* Get the PS/2 interrupts and clear them */
106 intr_status = readl(drvdata->reg_base + PS2_REG_LSTS);
107 fifo_status = readl(drvdata->reg_base + PS2_REG_FSTS);
108
109 /* Check line status register */
110 if (intr_status & PS2_LINE_ERROR_BIT) {
111 rxflags = (intr_status & PS2_LINE_ERROR_BIT) ? SERIO_FRAME : 0;
112 rxflags |= (intr_status & PS2_LSTS_PARERR) ? SERIO_PARITY : 0;
113 rxflags |= (intr_status & PS2_LSTS_PARERR) ? SERIO_TIMEOUT : 0;
114
115 rval = PS2_LSTS_TXTDO | PS2_LSTS_STOPERR | PS2_LSTS_ACKERR |
116 PS2_LSTS_PARERR | PS2_LSTS_RXTDO;
117 writel(rval, drvdata->reg_base + PS2_REG_LSTS);
118 }
119
120 /* Check FIFO status register */
121 if (fifo_status & PS2_FIFO_ERROR_BIT) {
122 rval = PS2_FSTS_TXUF | PS2_FSTS_TXOF | PS2_FSTS_TXRDY |
123 PS2_FSTS_RXUF | PS2_FSTS_RXOF | PS2_FSTS_RXRDY;
124 writel(rval, drvdata->reg_base + PS2_REG_FSTS);
125 }
126
127 rval = (fifo_status >> 16) & 0x3;
128 while (rval--) {
129 byte = readl(drvdata->reg_base + PS2_REG_DATA) & 0xff;
130 serio_interrupt(drvdata->serio, byte, rxflags);
131 }
132
133 writel(intr_status, drvdata->reg_base + PS2_REG_LSTS);
134 writel(fifo_status, drvdata->reg_base + PS2_REG_FSTS);
135
136 spin_unlock(&drvdata->lock);
137
138 return IRQ_HANDLED;
139}
140
141static int sun4i_ps2_open(struct serio *serio)
142{
143 struct sun4i_ps2data *drvdata = serio->port_data;
144 u32 src_clk = 0;
145 u32 clk_scdf;
146 u32 clk_pcdf;
147 u32 rval;
148 unsigned long flags;
149
150 /* Set line control and enable interrupt */
151 rval = PS2_LCTL_STOPERREN | PS2_LCTL_ACKERREN
152 | PS2_LCTL_PARERREN | PS2_LCTL_RXDTOEN;
153 writel(rval, drvdata->reg_base + PS2_REG_LCTL);
154
155 /* Reset FIFO */
156 rval = PS2_FCTL_TXRST | PS2_FCTL_RXRST | PS2_FCTL_TXUFIEN
157 | PS2_FCTL_TXOFIEN | PS2_FCTL_RXUFIEN
158 | PS2_FCTL_RXOFIEN | PS2_FCTL_RXRDYIEN;
159
160 writel(rval, drvdata->reg_base + PS2_REG_FCTL);
161
162 src_clk = clk_get_rate(drvdata->clk);
163 /* Set clock divider register */
164 clk_scdf = src_clk / PS2_SAMPLE_CLK - 1;
165 clk_pcdf = PS2_SAMPLE_CLK / PS2_SCLK - 1;
166 rval = (clk_scdf << 8) | clk_pcdf;
167 writel(rval, drvdata->reg_base + PS2_REG_CLKDR);
168
169 /* Set global control register */
170 rval = PS2_GCTL_RESET | PS2_GCTL_INTEN | PS2_GCTL_MASTER
171 | PS2_GCTL_BUSEN;
172
173 spin_lock_irqsave(&drvdata->lock, flags);
174 writel(rval, drvdata->reg_base + PS2_REG_GCTL);
175 spin_unlock_irqrestore(&drvdata->lock, flags);
176
177 return 0;
178}
179
180static void sun4i_ps2_close(struct serio *serio)
181{
182 struct sun4i_ps2data *drvdata = serio->port_data;
183 u32 rval;
184
185 /* Shut off the interrupt */
186 rval = readl(drvdata->reg_base + PS2_REG_GCTL);
187 writel(rval & ~(PS2_GCTL_INTEN), drvdata->reg_base + PS2_REG_GCTL);
188
189 synchronize_irq(drvdata->irq);
190}
191
192static int sun4i_ps2_write(struct serio *serio, unsigned char val)
193{
194 unsigned long expire = jiffies + msecs_to_jiffies(10000);
195 struct sun4i_ps2data *drvdata = serio->port_data;
196
197 do {
198 if (readl(drvdata->reg_base + PS2_REG_FSTS) & PS2_FSTS_TXRDY) {
199 writel(val, drvdata->reg_base + PS2_REG_DATA);
200 return 0;
201 }
202 } while (time_before(jiffies, expire));
203
204 return SERIO_TIMEOUT;
205}
206
207static int sun4i_ps2_probe(struct platform_device *pdev)
208{
209 struct resource *res; /* IO mem resources */
210 struct sun4i_ps2data *drvdata;
211 struct serio *serio;
212 struct device *dev = &pdev->dev;
213 unsigned int irq;
214 int error;
215
216 drvdata = kzalloc(sizeof(struct sun4i_ps2data), GFP_KERNEL);
217 serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
218 if (!drvdata || !serio) {
219 error = -ENOMEM;
220 goto err_free_mem;
221 }
222
223 spin_lock_init(&drvdata->lock);
224
225 /* IO */
226 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
227 if (!res) {
228 dev_err(dev, "failed to locate registers\n");
229 error = -ENXIO;
230 goto err_free_mem;
231 }
232
233 drvdata->reg_base = ioremap(res->start, resource_size(res));
234 if (!drvdata->reg_base) {
235 dev_err(dev, "failed to map registers\n");
236 error = -ENOMEM;
237 goto err_free_mem;
238 }
239
240 drvdata->clk = clk_get(dev, NULL);
241 if (IS_ERR(drvdata->clk)) {
242 error = PTR_ERR(drvdata->clk);
243 dev_err(dev, "couldn't get clock %d\n", error);
244 goto err_ioremap;
245 }
246
247 error = clk_prepare_enable(drvdata->clk);
248 if (error) {
249 dev_err(dev, "failed to enable clock %d\n", error);
250 goto err_clk;
251 }
252
253 serio->id.type = SERIO_8042;
254 serio->write = sun4i_ps2_write;
255 serio->open = sun4i_ps2_open;
256 serio->close = sun4i_ps2_close;
257 serio->port_data = drvdata;
258 serio->dev.parent = dev;
259 strlcpy(serio->name, dev_name(dev), sizeof(serio->name));
260 strlcpy(serio->phys, dev_name(dev), sizeof(serio->phys));
261
262 /* shutoff interrupt */
263 writel(0, drvdata->reg_base + PS2_REG_GCTL);
264
265 /* Get IRQ for the device */
266 irq = platform_get_irq(pdev, 0);
267 if (!irq) {
268 dev_err(dev, "no IRQ found\n");
269 error = -ENXIO;
270 goto err_disable_clk;
271 }
272
273 drvdata->irq = irq;
274 drvdata->serio = serio;
275 drvdata->dev = dev;
276
277 error = request_irq(drvdata->irq, sun4i_ps2_interrupt, 0,
278 DRIVER_NAME, drvdata);
279 if (error) {
280 dev_err(drvdata->dev, "failed to allocate interrupt %d: %d\n",
281 drvdata->irq, error);
282 goto err_disable_clk;
283 }
284
285 serio_register_port(serio);
286 platform_set_drvdata(pdev, drvdata);
287
288 return 0; /* success */
289
290err_disable_clk:
291 clk_disable_unprepare(drvdata->clk);
292err_clk:
293 clk_put(drvdata->clk);
294err_ioremap:
295 iounmap(drvdata->reg_base);
296err_free_mem:
297 kfree(serio);
298 kfree(drvdata);
299 return error;
300}
301
302static int sun4i_ps2_remove(struct platform_device *pdev)
303{
304 struct sun4i_ps2data *drvdata = platform_get_drvdata(pdev);
305
306 serio_unregister_port(drvdata->serio);
307
308 free_irq(drvdata->irq, drvdata);
309
310 clk_disable_unprepare(drvdata->clk);
311 clk_put(drvdata->clk);
312
313 iounmap(drvdata->reg_base);
314
315 kfree(drvdata);
316
317 return 0;
318}
319
320static const struct of_device_id sun4i_ps2_match[] = {
321 { .compatible = "allwinner,sun4i-a10-ps2", },
322 { },
323};
324
325MODULE_DEVICE_TABLE(of, sun4i_ps2_match);
326
327static struct platform_driver sun4i_ps2_driver = {
328 .probe = sun4i_ps2_probe,
329 .remove = sun4i_ps2_remove,
330 .driver = {
331 .name = DRIVER_NAME,
332 .of_match_table = sun4i_ps2_match,
333 },
334};
335module_platform_driver(sun4i_ps2_driver);
336
337MODULE_AUTHOR("Vishnu Patekar <vishnupatekar0510@gmail.com>");
338MODULE_AUTHOR("Aaron.maoye <leafy.myeh@newbietech.com>");
339MODULE_DESCRIPTION("Allwinner A10/Sun4i PS/2 driver");
340MODULE_LICENSE("GPL v2");
diff --git a/drivers/input/tablet/gtco.c b/drivers/input/tablet/gtco.c
index 858045694e9d..3a7f3a4a4396 100644
--- a/drivers/input/tablet/gtco.c
+++ b/drivers/input/tablet/gtco.c
@@ -59,7 +59,7 @@ Scott Hill shill@gtcocalcomp.com
59#include <asm/uaccess.h> 59#include <asm/uaccess.h>
60#include <asm/unaligned.h> 60#include <asm/unaligned.h>
61#include <asm/byteorder.h> 61#include <asm/byteorder.h>
62 62#include <linux/bitops.h>
63 63
64#include <linux/usb/input.h> 64#include <linux/usb/input.h>
65 65
@@ -614,7 +614,6 @@ static void gtco_urb_callback(struct urb *urbinfo)
614 struct input_dev *inputdev; 614 struct input_dev *inputdev;
615 int rc; 615 int rc;
616 u32 val = 0; 616 u32 val = 0;
617 s8 valsigned = 0;
618 char le_buffer[2]; 617 char le_buffer[2];
619 618
620 inputdev = device->inputdevice; 619 inputdev = device->inputdevice;
@@ -665,20 +664,11 @@ static void gtco_urb_callback(struct urb *urbinfo)
665 /* Fall thru */ 664 /* Fall thru */
666 case 4: 665 case 4:
667 /* Tilt */ 666 /* Tilt */
667 input_report_abs(inputdev, ABS_TILT_X,
668 sign_extend32(device->buffer[6], 6));
668 669
669 /* Sign extend these 7 bit numbers. */ 670 input_report_abs(inputdev, ABS_TILT_Y,
670 if (device->buffer[6] & 0x40) 671 sign_extend32(device->buffer[7], 6));
671 device->buffer[6] |= 0x80;
672
673 if (device->buffer[7] & 0x40)
674 device->buffer[7] |= 0x80;
675
676
677 valsigned = (device->buffer[6]);
678 input_report_abs(inputdev, ABS_TILT_X, (s32)valsigned);
679
680 valsigned = (device->buffer[7]);
681 input_report_abs(inputdev, ABS_TILT_Y, (s32)valsigned);
682 672
683 /* Fall thru */ 673 /* Fall thru */
684 case 2: 674 case 2:
diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c
index a510f7ef9b66..926c58e540c0 100644
--- a/drivers/input/touchscreen/elants_i2c.c
+++ b/drivers/input/touchscreen/elants_i2c.c
@@ -33,10 +33,8 @@
33#include <linux/delay.h> 33#include <linux/delay.h>
34#include <linux/uaccess.h> 34#include <linux/uaccess.h>
35#include <linux/buffer_head.h> 35#include <linux/buffer_head.h>
36#include <linux/version.h>
37#include <linux/slab.h> 36#include <linux/slab.h>
38#include <linux/firmware.h> 37#include <linux/firmware.h>
39#include <linux/version.h>
40#include <linux/input/mt.h> 38#include <linux/input/mt.h>
41#include <linux/acpi.h> 39#include <linux/acpi.h>
42#include <linux/of.h> 40#include <linux/of.h>
diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c
index 4fb5537fdd42..2c2107147319 100644
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -126,7 +126,7 @@ static void pixcir_ts_report(struct pixcir_i2c_ts_data *ts,
126 pos[i].y = touch->y; 126 pos[i].y = touch->y;
127 } 127 }
128 128
129 input_mt_assign_slots(ts->input, slots, pos, n); 129 input_mt_assign_slots(ts->input, slots, pos, n, 0);
130 } 130 }
131 131
132 for (i = 0; i < n; i++) { 132 for (i = 0; i < n; i++) {
diff --git a/drivers/input/touchscreen/sun4i-ts.c b/drivers/input/touchscreen/sun4i-ts.c
index 28a06749ae42..b93a28b955fd 100644
--- a/drivers/input/touchscreen/sun4i-ts.c
+++ b/drivers/input/touchscreen/sun4i-ts.c
@@ -34,6 +34,7 @@
34 34
35#include <linux/err.h> 35#include <linux/err.h>
36#include <linux/hwmon.h> 36#include <linux/hwmon.h>
37#include <linux/thermal.h>
37#include <linux/init.h> 38#include <linux/init.h>
38#include <linux/input.h> 39#include <linux/input.h>
39#include <linux/interrupt.h> 40#include <linux/interrupt.h>
@@ -71,6 +72,9 @@
71#define TP_ADC_SELECT(x) ((x) << 3) 72#define TP_ADC_SELECT(x) ((x) << 3)
72#define ADC_CHAN_SELECT(x) ((x) << 0) /* 3 bits */ 73#define ADC_CHAN_SELECT(x) ((x) << 0) /* 3 bits */
73 74
75/* on sun6i, bits 3~6 are left shifted by 1 to 4~7 */
76#define SUN6I_TP_MODE_EN(x) ((x) << 5)
77
74/* TP_CTRL2 bits */ 78/* TP_CTRL2 bits */
75#define TP_SENSITIVE_ADJUST(x) ((x) << 28) /* 4 bits */ 79#define TP_SENSITIVE_ADJUST(x) ((x) << 28) /* 4 bits */
76#define TP_MODE_SELECT(x) ((x) << 26) /* 2 bits */ 80#define TP_MODE_SELECT(x) ((x) << 26) /* 2 bits */
@@ -107,10 +111,13 @@
107struct sun4i_ts_data { 111struct sun4i_ts_data {
108 struct device *dev; 112 struct device *dev;
109 struct input_dev *input; 113 struct input_dev *input;
114 struct thermal_zone_device *tz;
110 void __iomem *base; 115 void __iomem *base;
111 unsigned int irq; 116 unsigned int irq;
112 bool ignore_fifo_data; 117 bool ignore_fifo_data;
113 int temp_data; 118 int temp_data;
119 int temp_offset;
120 int temp_step;
114}; 121};
115 122
116static void sun4i_ts_irq_handle_input(struct sun4i_ts_data *ts, u32 reg_val) 123static void sun4i_ts_irq_handle_input(struct sun4i_ts_data *ts, u32 reg_val)
@@ -180,16 +187,38 @@ static void sun4i_ts_close(struct input_dev *dev)
180 writel(TEMP_IRQ_EN(1), ts->base + TP_INT_FIFOC); 187 writel(TEMP_IRQ_EN(1), ts->base + TP_INT_FIFOC);
181} 188}
182 189
190static int sun4i_get_temp(const struct sun4i_ts_data *ts, long *temp)
191{
192 /* No temp_data until the first irq */
193 if (ts->temp_data == -1)
194 return -EAGAIN;
195
196 *temp = (ts->temp_data - ts->temp_offset) * ts->temp_step;
197
198 return 0;
199}
200
201static int sun4i_get_tz_temp(void *data, long *temp)
202{
203 return sun4i_get_temp(data, temp);
204}
205
206static struct thermal_zone_of_device_ops sun4i_ts_tz_ops = {
207 .get_temp = sun4i_get_tz_temp,
208};
209
183static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, 210static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
184 char *buf) 211 char *buf)
185{ 212{
186 struct sun4i_ts_data *ts = dev_get_drvdata(dev); 213 struct sun4i_ts_data *ts = dev_get_drvdata(dev);
214 long temp;
215 int error;
187 216
188 /* No temp_data until the first irq */ 217 error = sun4i_get_temp(ts, &temp);
189 if (ts->temp_data == -1) 218 if (error)
190 return -EAGAIN; 219 return error;
191 220
192 return sprintf(buf, "%d\n", (ts->temp_data - 1447) * 100); 221 return sprintf(buf, "%ld\n", temp);
193} 222}
194 223
195static ssize_t show_temp_label(struct device *dev, 224static ssize_t show_temp_label(struct device *dev,
@@ -215,6 +244,7 @@ static int sun4i_ts_probe(struct platform_device *pdev)
215 struct device_node *np = dev->of_node; 244 struct device_node *np = dev->of_node;
216 struct device *hwmon; 245 struct device *hwmon;
217 int error; 246 int error;
247 u32 reg;
218 bool ts_attached; 248 bool ts_attached;
219 249
220 ts = devm_kzalloc(dev, sizeof(struct sun4i_ts_data), GFP_KERNEL); 250 ts = devm_kzalloc(dev, sizeof(struct sun4i_ts_data), GFP_KERNEL);
@@ -224,6 +254,25 @@ static int sun4i_ts_probe(struct platform_device *pdev)
224 ts->dev = dev; 254 ts->dev = dev;
225 ts->ignore_fifo_data = true; 255 ts->ignore_fifo_data = true;
226 ts->temp_data = -1; 256 ts->temp_data = -1;
257 if (of_device_is_compatible(np, "allwinner,sun6i-a31-ts")) {
258 /* Allwinner SDK has temperature = -271 + (value / 6) (C) */
259 ts->temp_offset = 1626;
260 ts->temp_step = 167;
261 } else {
262 /*
263 * The user manuals do not contain the formula for calculating
264 * the temperature. The formula used here is from the AXP209,
265 * which is designed by X-Powers, an affiliate of Allwinner:
266 *
267 * temperature = -144.7 + (value * 0.1)
268 *
269 * Allwinner does not have any documentation whatsoever for
270 * this hardware. Moreover, it is claimed that the sensor
271 * is inaccurate and cannot work properly.
272 */
273 ts->temp_offset = 1447;
274 ts->temp_step = 100;
275 }
227 276
228 ts_attached = of_property_read_bool(np, "allwinner,ts-attached"); 277 ts_attached = of_property_read_bool(np, "allwinner,ts-attached");
229 if (ts_attached) { 278 if (ts_attached) {
@@ -280,20 +329,34 @@ static int sun4i_ts_probe(struct platform_device *pdev)
280 * Set stylus up debounce to aprox 10 ms, enable debounce, and 329 * Set stylus up debounce to aprox 10 ms, enable debounce, and
281 * finally enable tp mode. 330 * finally enable tp mode.
282 */ 331 */
283 writel(STYLUS_UP_DEBOUN(5) | STYLUS_UP_DEBOUN_EN(1) | TP_MODE_EN(1), 332 reg = STYLUS_UP_DEBOUN(5) | STYLUS_UP_DEBOUN_EN(1);
284 ts->base + TP_CTRL1); 333 if (of_device_is_compatible(np, "allwinner,sun4i-a10-ts"))
334 reg |= TP_MODE_EN(1);
335 else
336 reg |= SUN6I_TP_MODE_EN(1);
337 writel(reg, ts->base + TP_CTRL1);
285 338
339 /*
340 * The thermal core does not register hwmon devices for DT-based
341 * thermal zone sensors, such as this one.
342 */
286 hwmon = devm_hwmon_device_register_with_groups(ts->dev, "sun4i_ts", 343 hwmon = devm_hwmon_device_register_with_groups(ts->dev, "sun4i_ts",
287 ts, sun4i_ts_groups); 344 ts, sun4i_ts_groups);
288 if (IS_ERR(hwmon)) 345 if (IS_ERR(hwmon))
289 return PTR_ERR(hwmon); 346 return PTR_ERR(hwmon);
290 347
348 ts->tz = thermal_zone_of_sensor_register(ts->dev, 0, ts,
349 &sun4i_ts_tz_ops);
350 if (IS_ERR(ts->tz))
351 ts->tz = NULL;
352
291 writel(TEMP_IRQ_EN(1), ts->base + TP_INT_FIFOC); 353 writel(TEMP_IRQ_EN(1), ts->base + TP_INT_FIFOC);
292 354
293 if (ts_attached) { 355 if (ts_attached) {
294 error = input_register_device(ts->input); 356 error = input_register_device(ts->input);
295 if (error) { 357 if (error) {
296 writel(0, ts->base + TP_INT_FIFOC); 358 writel(0, ts->base + TP_INT_FIFOC);
359 thermal_zone_of_sensor_unregister(ts->dev, ts->tz);
297 return error; 360 return error;
298 } 361 }
299 } 362 }
@@ -310,6 +373,8 @@ static int sun4i_ts_remove(struct platform_device *pdev)
310 if (ts->input) 373 if (ts->input)
311 input_unregister_device(ts->input); 374 input_unregister_device(ts->input);
312 375
376 thermal_zone_of_sensor_unregister(ts->dev, ts->tz);
377
313 /* Deactivate all IRQs */ 378 /* Deactivate all IRQs */
314 writel(0, ts->base + TP_INT_FIFOC); 379 writel(0, ts->base + TP_INT_FIFOC);
315 380
@@ -318,6 +383,7 @@ static int sun4i_ts_remove(struct platform_device *pdev)
318 383
319static const struct of_device_id sun4i_ts_of_match[] = { 384static const struct of_device_id sun4i_ts_of_match[] = {
320 { .compatible = "allwinner,sun4i-a10-ts", }, 385 { .compatible = "allwinner,sun4i-a10-ts", },
386 { .compatible = "allwinner,sun6i-a31-ts", },
321 { /* sentinel */ } 387 { /* sentinel */ }
322}; 388};
323MODULE_DEVICE_TABLE(of, sun4i_ts_of_match); 389MODULE_DEVICE_TABLE(of, sun4i_ts_of_match);
diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
index 004f1346a957..191a1b87895f 100644
--- a/drivers/input/touchscreen/ti_am335x_tsc.c
+++ b/drivers/input/touchscreen/ti_am335x_tsc.c
@@ -26,6 +26,7 @@
26#include <linux/delay.h> 26#include <linux/delay.h>
27#include <linux/of.h> 27#include <linux/of.h>
28#include <linux/of_device.h> 28#include <linux/of_device.h>
29#include <linux/sort.h>
29 30
30#include <linux/mfd/ti_am335x_tscadc.h> 31#include <linux/mfd/ti_am335x_tscadc.h>
31 32
@@ -52,6 +53,7 @@ struct titsc {
52 u32 bit_xp, bit_xn, bit_yp, bit_yn; 53 u32 bit_xp, bit_xn, bit_yp, bit_yn;
53 u32 inp_xp, inp_xn, inp_yp, inp_yn; 54 u32 inp_xp, inp_xn, inp_yp, inp_yn;
54 u32 step_mask; 55 u32 step_mask;
56 u32 charge_delay;
55}; 57};
56 58
57static unsigned int titsc_readl(struct titsc *ts, unsigned int reg) 59static unsigned int titsc_readl(struct titsc *ts, unsigned int reg)
@@ -121,7 +123,7 @@ static void titsc_step_config(struct titsc *ts_dev)
121{ 123{
122 unsigned int config; 124 unsigned int config;
123 int i; 125 int i;
124 int end_step; 126 int end_step, first_step, tsc_steps;
125 u32 stepenable; 127 u32 stepenable;
126 128
127 config = STEPCONFIG_MODE_HWSYNC | 129 config = STEPCONFIG_MODE_HWSYNC |
@@ -140,9 +142,11 @@ static void titsc_step_config(struct titsc *ts_dev)
140 break; 142 break;
141 } 143 }
142 144
143 /* 1 … coordinate_readouts is for X */ 145 tsc_steps = ts_dev->coordinate_readouts * 2 + 2;
144 end_step = ts_dev->coordinate_readouts; 146 first_step = TOTAL_STEPS - tsc_steps;
145 for (i = 0; i < end_step; i++) { 147 /* Steps 16 to 16-coordinate_readouts is for X */
148 end_step = first_step + tsc_steps;
149 for (i = end_step - ts_dev->coordinate_readouts; i < end_step; i++) {
146 titsc_writel(ts_dev, REG_STEPCONFIG(i), config); 150 titsc_writel(ts_dev, REG_STEPCONFIG(i), config);
147 titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY); 151 titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY);
148 } 152 }
@@ -164,22 +168,20 @@ static void titsc_step_config(struct titsc *ts_dev)
164 break; 168 break;
165 } 169 }
166 170
167 /* coordinate_readouts coordinate_readouts * 2 is for Y */ 171 /* 1 ... coordinate_readouts is for Y */
168 end_step = ts_dev->coordinate_readouts * 2; 172 end_step = first_step + ts_dev->coordinate_readouts;
169 for (i = ts_dev->coordinate_readouts; i < end_step; i++) { 173 for (i = first_step; i < end_step; i++) {
170 titsc_writel(ts_dev, REG_STEPCONFIG(i), config); 174 titsc_writel(ts_dev, REG_STEPCONFIG(i), config);
171 titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY); 175 titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY);
172 } 176 }
173 177
174 /* Charge step configuration */ 178 /* Make CHARGECONFIG same as IDLECONFIG */
175 config = ts_dev->bit_xp | ts_dev->bit_yn |
176 STEPCHARGE_RFP_XPUL | STEPCHARGE_RFM_XNUR |
177 STEPCHARGE_INM_AN1 | STEPCHARGE_INP(ts_dev->inp_yp);
178 179
180 config = titsc_readl(ts_dev, REG_IDLECONFIG);
179 titsc_writel(ts_dev, REG_CHARGECONFIG, config); 181 titsc_writel(ts_dev, REG_CHARGECONFIG, config);
180 titsc_writel(ts_dev, REG_CHARGEDELAY, CHARGEDLY_OPENDLY); 182 titsc_writel(ts_dev, REG_CHARGEDELAY, ts_dev->charge_delay);
181 183
182 /* coordinate_readouts * 2 coordinate_readouts * 2 + 2 is for Z */ 184 /* coordinate_readouts + 1 ... coordinate_readouts + 2 is for Z */
183 config = STEPCONFIG_MODE_HWSYNC | 185 config = STEPCONFIG_MODE_HWSYNC |
184 STEPCONFIG_AVG_16 | ts_dev->bit_yp | 186 STEPCONFIG_AVG_16 | ts_dev->bit_yp |
185 ts_dev->bit_xn | STEPCONFIG_INM_ADCREFM | 187 ts_dev->bit_xn | STEPCONFIG_INM_ADCREFM |
@@ -194,73 +196,104 @@ static void titsc_step_config(struct titsc *ts_dev)
194 titsc_writel(ts_dev, REG_STEPDELAY(end_step), 196 titsc_writel(ts_dev, REG_STEPDELAY(end_step),
195 STEPCONFIG_OPENDLY); 197 STEPCONFIG_OPENDLY);
196 198
197 /* The steps1 … end and bit 0 for TS_Charge */ 199 /* The steps end ... end - readouts * 2 + 2 and bit 0 for TS_Charge */
198 stepenable = (1 << (end_step + 2)) - 1; 200 stepenable = 1;
201 for (i = 0; i < tsc_steps; i++)
202 stepenable |= 1 << (first_step + i + 1);
203
199 ts_dev->step_mask = stepenable; 204 ts_dev->step_mask = stepenable;
200 am335x_tsc_se_set_cache(ts_dev->mfd_tscadc, ts_dev->step_mask); 205 am335x_tsc_se_set_cache(ts_dev->mfd_tscadc, ts_dev->step_mask);
201} 206}
202 207
208static int titsc_cmp_coord(const void *a, const void *b)
209{
210 return *(int *)a - *(int *)b;
211}
212
203static void titsc_read_coordinates(struct titsc *ts_dev, 213static void titsc_read_coordinates(struct titsc *ts_dev,
204 u32 *x, u32 *y, u32 *z1, u32 *z2) 214 u32 *x, u32 *y, u32 *z1, u32 *z2)
205{ 215{
206 unsigned int fifocount = titsc_readl(ts_dev, REG_FIFO0CNT); 216 unsigned int yvals[7], xvals[7];
207 unsigned int prev_val_x = ~0, prev_val_y = ~0; 217 unsigned int i, xsum = 0, ysum = 0;
208 unsigned int prev_diff_x = ~0, prev_diff_y = ~0;
209 unsigned int read, diff;
210 unsigned int i, channel;
211 unsigned int creads = ts_dev->coordinate_readouts; 218 unsigned int creads = ts_dev->coordinate_readouts;
212 219
213 *z1 = *z2 = 0; 220 for (i = 0; i < creads; i++) {
214 if (fifocount % (creads * 2 + 2)) 221 yvals[i] = titsc_readl(ts_dev, REG_FIFO0);
215 fifocount -= fifocount % (creads * 2 + 2); 222 yvals[i] &= 0xfff;
216 /* 223 }
217 * Delta filter is used to remove large variations in sampled
218 * values from ADC. The filter tries to predict where the next
219 * coordinate could be. This is done by taking a previous
220 * coordinate and subtracting it form current one. Further the
221 * algorithm compares the difference with that of a present value,
222 * if true the value is reported to the sub system.
223 */
224 for (i = 0; i < fifocount; i++) {
225 read = titsc_readl(ts_dev, REG_FIFO0);
226
227 channel = (read & 0xf0000) >> 16;
228 read &= 0xfff;
229 if (channel < creads) {
230 diff = abs(read - prev_val_x);
231 if (diff < prev_diff_x) {
232 prev_diff_x = diff;
233 *x = read;
234 }
235 prev_val_x = read;
236 224
237 } else if (channel < creads * 2) { 225 *z1 = titsc_readl(ts_dev, REG_FIFO0);
238 diff = abs(read - prev_val_y); 226 *z1 &= 0xfff;
239 if (diff < prev_diff_y) { 227 *z2 = titsc_readl(ts_dev, REG_FIFO0);
240 prev_diff_y = diff; 228 *z2 &= 0xfff;
241 *y = read;
242 }
243 prev_val_y = read;
244 229
245 } else if (channel < creads * 2 + 1) { 230 for (i = 0; i < creads; i++) {
246 *z1 = read; 231 xvals[i] = titsc_readl(ts_dev, REG_FIFO0);
232 xvals[i] &= 0xfff;
233 }
247 234
248 } else if (channel < creads * 2 + 2) { 235 /*
249 *z2 = read; 236 * If co-ordinates readouts is less than 4 then
237 * report the average. In case of 4 or more
238 * readouts, sort the co-ordinate samples, drop
239 * min and max values and report the average of
240 * remaining values.
241 */
242 if (creads <= 3) {
243 for (i = 0; i < creads; i++) {
244 ysum += yvals[i];
245 xsum += xvals[i];
250 } 246 }
247 ysum /= creads;
248 xsum /= creads;
249 } else {
250 sort(yvals, creads, sizeof(unsigned int),
251 titsc_cmp_coord, NULL);
252 sort(xvals, creads, sizeof(unsigned int),
253 titsc_cmp_coord, NULL);
254 for (i = 1; i < creads - 1; i++) {
255 ysum += yvals[i];
256 xsum += xvals[i];
257 }
258 ysum /= creads - 2;
259 xsum /= creads - 2;
251 } 260 }
261 *y = ysum;
262 *x = xsum;
252} 263}
253 264
254static irqreturn_t titsc_irq(int irq, void *dev) 265static irqreturn_t titsc_irq(int irq, void *dev)
255{ 266{
256 struct titsc *ts_dev = dev; 267 struct titsc *ts_dev = dev;
257 struct input_dev *input_dev = ts_dev->input; 268 struct input_dev *input_dev = ts_dev->input;
258 unsigned int status, irqclr = 0; 269 unsigned int fsm, status, irqclr = 0;
259 unsigned int x = 0, y = 0; 270 unsigned int x = 0, y = 0;
260 unsigned int z1, z2, z; 271 unsigned int z1, z2, z;
261 unsigned int fsm;
262 272
263 status = titsc_readl(ts_dev, REG_IRQSTATUS); 273 status = titsc_readl(ts_dev, REG_RAWIRQSTATUS);
274 if (status & IRQENB_HW_PEN) {
275 ts_dev->pen_down = true;
276 titsc_writel(ts_dev, REG_IRQWAKEUP, 0x00);
277 titsc_writel(ts_dev, REG_IRQCLR, IRQENB_HW_PEN);
278 irqclr |= IRQENB_HW_PEN;
279 }
280
281 if (status & IRQENB_PENUP) {
282 fsm = titsc_readl(ts_dev, REG_ADCFSM);
283 if (fsm == ADCFSM_STEPID) {
284 ts_dev->pen_down = false;
285 input_report_key(input_dev, BTN_TOUCH, 0);
286 input_report_abs(input_dev, ABS_PRESSURE, 0);
287 input_sync(input_dev);
288 } else {
289 ts_dev->pen_down = true;
290 }
291 irqclr |= IRQENB_PENUP;
292 }
293
294 if (status & IRQENB_EOS)
295 irqclr |= IRQENB_EOS;
296
264 /* 297 /*
265 * ADC and touchscreen share the IRQ line. 298 * ADC and touchscreen share the IRQ line.
266 * FIFO1 interrupts are used by ADC. Handle FIFO0 IRQs here only 299 * FIFO1 interrupts are used by ADC. Handle FIFO0 IRQs here only
@@ -291,37 +324,11 @@ static irqreturn_t titsc_irq(int irq, void *dev)
291 } 324 }
292 irqclr |= IRQENB_FIFO0THRES; 325 irqclr |= IRQENB_FIFO0THRES;
293 } 326 }
294
295 /*
296 * Time for sequencer to settle, to read
297 * correct state of the sequencer.
298 */
299 udelay(SEQ_SETTLE);
300
301 status = titsc_readl(ts_dev, REG_RAWIRQSTATUS);
302 if (status & IRQENB_PENUP) {
303 /* Pen up event */
304 fsm = titsc_readl(ts_dev, REG_ADCFSM);
305 if (fsm == ADCFSM_STEPID) {
306 ts_dev->pen_down = false;
307 input_report_key(input_dev, BTN_TOUCH, 0);
308 input_report_abs(input_dev, ABS_PRESSURE, 0);
309 input_sync(input_dev);
310 } else {
311 ts_dev->pen_down = true;
312 }
313 irqclr |= IRQENB_PENUP;
314 }
315
316 if (status & IRQENB_HW_PEN) {
317
318 titsc_writel(ts_dev, REG_IRQWAKEUP, 0x00);
319 titsc_writel(ts_dev, REG_IRQCLR, IRQENB_HW_PEN);
320 }
321
322 if (irqclr) { 327 if (irqclr) {
323 titsc_writel(ts_dev, REG_IRQSTATUS, irqclr); 328 titsc_writel(ts_dev, REG_IRQSTATUS, irqclr);
324 am335x_tsc_se_set_cache(ts_dev->mfd_tscadc, ts_dev->step_mask); 329 if (status & IRQENB_EOS)
330 am335x_tsc_se_set_cache(ts_dev->mfd_tscadc,
331 ts_dev->step_mask);
325 return IRQ_HANDLED; 332 return IRQ_HANDLED;
326 } 333 }
327 return IRQ_NONE; 334 return IRQ_NONE;
@@ -368,6 +375,23 @@ static int titsc_parse_dt(struct platform_device *pdev,
368 if (err < 0) 375 if (err < 0)
369 return err; 376 return err;
370 377
378 if (ts_dev->coordinate_readouts <= 0) {
379 dev_warn(&pdev->dev,
380 "invalid co-ordinate readouts, resetting it to 5\n");
381 ts_dev->coordinate_readouts = 5;
382 }
383
384 err = of_property_read_u32(node, "ti,charge-delay",
385 &ts_dev->charge_delay);
386 /*
387 * If ti,charge-delay value is not specified, then use
388 * CHARGEDLY_OPENDLY as the default value.
389 */
390 if (err < 0) {
391 ts_dev->charge_delay = CHARGEDLY_OPENDLY;
392 dev_warn(&pdev->dev, "ti,charge-delay not specified\n");
393 }
394
371 return of_property_read_u32_array(node, "ti,wire-config", 395 return of_property_read_u32_array(node, "ti,wire-config",
372 ts_dev->config_inp, ARRAY_SIZE(ts_dev->config_inp)); 396 ts_dev->config_inp, ARRAY_SIZE(ts_dev->config_inp));
373} 397}
@@ -411,6 +435,7 @@ static int titsc_probe(struct platform_device *pdev)
411 } 435 }
412 436
413 titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_FIFO0THRES); 437 titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_FIFO0THRES);
438 titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_EOS);
414 err = titsc_config_wires(ts_dev); 439 err = titsc_config_wires(ts_dev);
415 if (err) { 440 if (err) {
416 dev_err(&pdev->dev, "wrong i/p wire configuration\n"); 441 dev_err(&pdev->dev, "wrong i/p wire configuration\n");
diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h
index f583ff639776..d7188de4db96 100644
--- a/include/linux/input/mt.h
+++ b/include/linux/input/mt.h
@@ -119,7 +119,8 @@ struct input_mt_pos {
119}; 119};
120 120
121int input_mt_assign_slots(struct input_dev *dev, int *slots, 121int input_mt_assign_slots(struct input_dev *dev, int *slots,
122 const struct input_mt_pos *pos, int num_pos); 122 const struct input_mt_pos *pos, int num_pos,
123 int dmax);
123 124
124int input_mt_get_slot_by_key(struct input_dev *dev, int key); 125int input_mt_get_slot_by_key(struct input_dev *dev, int key);
125 126
diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
index e2e70053470e..3f4e994ace2b 100644
--- a/include/linux/mfd/ti_am335x_tscadc.h
+++ b/include/linux/mfd/ti_am335x_tscadc.h
@@ -52,6 +52,7 @@
52 52
53/* IRQ enable */ 53/* IRQ enable */
54#define IRQENB_HW_PEN BIT(0) 54#define IRQENB_HW_PEN BIT(0)
55#define IRQENB_EOS BIT(1)
55#define IRQENB_FIFO0THRES BIT(2) 56#define IRQENB_FIFO0THRES BIT(2)
56#define IRQENB_FIFO0OVRRUN BIT(3) 57#define IRQENB_FIFO0OVRRUN BIT(3)
57#define IRQENB_FIFO0UNDRFLW BIT(4) 58#define IRQENB_FIFO0UNDRFLW BIT(4)
@@ -107,7 +108,7 @@
107/* Charge delay */ 108/* Charge delay */
108#define CHARGEDLY_OPEN_MASK (0x3FFFF << 0) 109#define CHARGEDLY_OPEN_MASK (0x3FFFF << 0)
109#define CHARGEDLY_OPEN(val) ((val) << 0) 110#define CHARGEDLY_OPEN(val) ((val) << 0)
110#define CHARGEDLY_OPENDLY CHARGEDLY_OPEN(1) 111#define CHARGEDLY_OPENDLY CHARGEDLY_OPEN(0x400)
111 112
112/* Control register */ 113/* Control register */
113#define CNTRLREG_TSCSSENB BIT(0) 114#define CNTRLREG_TSCSSENB BIT(0)
diff --git a/include/linux/platform_data/regulator-haptic.h b/include/linux/platform_data/regulator-haptic.h
new file mode 100644
index 000000000000..5658e58e0738
--- /dev/null
+++ b/include/linux/platform_data/regulator-haptic.h
@@ -0,0 +1,29 @@
1/*
2 * Regulator Haptic Platform Data
3 *
4 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
5 * Author: Jaewon Kim <jaewon02.kim@samsung.com>
6 * Author: Hyunhee Kim <hyunhee.kim@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _REGULATOR_HAPTIC_H
14#define _REGULATOR_HAPTIC_H
15
16/*
17 * struct regulator_haptic_data - Platform device data
18 *
19 * @max_volt: maximum voltage value supplied to the haptic motor.
20 * <The unit of the voltage is a micro>
21 * @min_volt: minimum voltage value supplied to the haptic motor.
22 * <The unit of the voltage is a micro>
23 */
24struct regulator_haptic_data {
25 unsigned int max_volt;
26 unsigned int min_volt;
27};
28
29#endif /* _REGULATOR_HAPTIC_H */