diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-20 14:00:43 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-20 14:00:43 -0500 |
commit | c6699b58f4fe2f968f036a862c09ce44b6968376 (patch) | |
tree | d26743fa88966c2bdfd35ba723e3631f08a1f5fc | |
parent | 5a1203914a637b642442a861cf462d16401548e1 (diff) | |
parent | 2d9f0d964be94fd51c7303288c6f9c88bf2381fe (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input updates from Dmitry Torokhov:
"Two new touchpad drivers - Cypress APA I2C Trackpad and Cypress PS/2
touchpad and a big update to ALPS driver from Kevin Cernekee that adds
support for "Rushmore" touchpads and paves way for adding support for
"Dolphin" touchpads.
There is also a new input driver for Goldfish emulator and also
Android keyreset driver was folded into SysRq code.
A few more drivers were updated with device tree bindings and others
got some small cleanups and fixes."
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (55 commits)
Input: cyttsp-spi - remove duplicate MODULE_ALIAS()
Input: tsc2005 - add MODULE_ALIAS
Input: tegra-kbc - require CONFIG_OF, remove platform data
Input: synaptics - initialize pointer emulation usage
Input: MT - do not apply filtering on emulated events
Input: bma150 - make some defines public and fix some comments
Input: bma150 - fix checking pm_runtime_get_sync() return value
Input: ALPS - enable trackstick on Rushmore touchpads
Input: ALPS - add support for "Rushmore" touchpads
Input: ALPS - make the V3 packet field decoder "pluggable"
Input: ALPS - move pixel and bitmap info into alps_data struct
Input: ALPS - fix command mode check
Input: ALPS - rework detection of Pinnacle AGx touchpads
Input: ALPS - move {addr,nibble}_command settings into alps_set_defaults()
Input: ALPS - use function pointers for different protocol handlers
Input: ALPS - rework detection sequence
Input: ALPS - introduce helper function for repeated commands
Input: ALPS - move alps_get_model() down below hw_init code
Input: ALPS - copy "model" info into alps_data struct
Input: ALPS - document the alps.h data structures
...
41 files changed, 3608 insertions, 1182 deletions
diff --git a/Documentation/devicetree/bindings/input/imx-keypad.txt b/Documentation/devicetree/bindings/input/imx-keypad.txt new file mode 100644 index 000000000000..2ebaf7d26843 --- /dev/null +++ b/Documentation/devicetree/bindings/input/imx-keypad.txt | |||
@@ -0,0 +1,53 @@ | |||
1 | * Freescale i.MX Keypad Port(KPP) device tree bindings | ||
2 | |||
3 | The KPP is designed to interface with a keypad matrix with 2-point contact | ||
4 | or 3-point contact keys. The KPP is designed to simplify the software task | ||
5 | of scanning a keypad matrix. The KPP is capable of detecting, debouncing, | ||
6 | and decoding one or multiple keys pressed simultaneously on a keypad. | ||
7 | |||
8 | Required SoC Specific Properties: | ||
9 | - compatible: Should be "fsl,<soc>-kpp". | ||
10 | |||
11 | - reg: Physical base address of the KPP and length of memory mapped | ||
12 | region. | ||
13 | |||
14 | - interrupts: The KPP interrupt number to the CPU(s). | ||
15 | |||
16 | - clocks: The clock provided by the SoC to the KPP. Some SoCs use dummy | ||
17 | clock(The clock for the KPP is provided by the SoCs automatically). | ||
18 | |||
19 | Required Board Specific Properties: | ||
20 | - pinctrl-names: The definition can be found at | ||
21 | pinctrl/pinctrl-bindings.txt. | ||
22 | |||
23 | - pinctrl-0: The definition can be found at | ||
24 | pinctrl/pinctrl-bindings.txt. | ||
25 | |||
26 | - linux,keymap: The definition can be found at | ||
27 | bindings/input/matrix-keymap.txt. | ||
28 | |||
29 | Example: | ||
30 | kpp: kpp@73f94000 { | ||
31 | compatible = "fsl,imx51-kpp", "fsl,imx21-kpp"; | ||
32 | reg = <0x73f94000 0x4000>; | ||
33 | interrupts = <60>; | ||
34 | clocks = <&clks 0>; | ||
35 | pinctrl-names = "default"; | ||
36 | pinctrl-0 = <&pinctrl_kpp_1>; | ||
37 | linux,keymap = <0x00000067 /* KEY_UP */ | ||
38 | 0x0001006c /* KEY_DOWN */ | ||
39 | 0x00020072 /* KEY_VOLUMEDOWN */ | ||
40 | 0x00030066 /* KEY_HOME */ | ||
41 | 0x0100006a /* KEY_RIGHT */ | ||
42 | 0x01010069 /* KEY_LEFT */ | ||
43 | 0x0102001c /* KEY_ENTER */ | ||
44 | 0x01030073 /* KEY_VOLUMEUP */ | ||
45 | 0x02000040 /* KEY_F6 */ | ||
46 | 0x02010042 /* KEY_F8 */ | ||
47 | 0x02020043 /* KEY_F9 */ | ||
48 | 0x02030044 /* KEY_F10 */ | ||
49 | 0x0300003b /* KEY_F1 */ | ||
50 | 0x0301003c /* KEY_F2 */ | ||
51 | 0x0302003d /* KEY_F3 */ | ||
52 | 0x03030074>; /* KEY_POWER */ | ||
53 | }; | ||
diff --git a/Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt b/Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt index 72683be6de35..2995fae7ee47 100644 --- a/Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt +++ b/Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt | |||
@@ -1,7 +1,18 @@ | |||
1 | * Tegra keyboard controller | 1 | * Tegra keyboard controller |
2 | The key controller has maximum 24 pins to make matrix keypad. Any pin | ||
3 | can be configured as row or column. The maximum column pin can be 8 | ||
4 | and maximum row pins can be 16 for Tegra20/Tegra30. | ||
2 | 5 | ||
3 | Required properties: | 6 | Required properties: |
4 | - compatible: "nvidia,tegra20-kbc" | 7 | - compatible: "nvidia,tegra20-kbc" |
8 | - reg: Register base address of KBC. | ||
9 | - interrupts: Interrupt number for the KBC. | ||
10 | - nvidia,kbc-row-pins: The KBC pins which are configured as row. This is an | ||
11 | array of pin numbers which is used as rows. | ||
12 | - nvidia,kbc-col-pins: The KBC pins which are configured as column. This is an | ||
13 | array of pin numbers which is used as column. | ||
14 | - linux,keymap: The keymap for keys as described in the binding document | ||
15 | devicetree/bindings/input/matrix-keymap.txt. | ||
5 | 16 | ||
6 | Optional properties, in addition to those specified by the shared | 17 | Optional properties, in addition to those specified by the shared |
7 | matrix-keyboard bindings: | 18 | matrix-keyboard bindings: |
@@ -19,5 +30,16 @@ Example: | |||
19 | keyboard: keyboard { | 30 | keyboard: keyboard { |
20 | compatible = "nvidia,tegra20-kbc"; | 31 | compatible = "nvidia,tegra20-kbc"; |
21 | reg = <0x7000e200 0x100>; | 32 | reg = <0x7000e200 0x100>; |
33 | interrupts = <0 85 0x04>; | ||
22 | nvidia,ghost-filter; | 34 | nvidia,ghost-filter; |
35 | nvidia,debounce-delay-ms = <640>; | ||
36 | nvidia,kbc-row-pins = <0 1 2>; /* pin 0, 1, 2 as rows */ | ||
37 | nvidia,kbc-col-pins = <11 12 13>; /* pin 11, 12, 13 as columns */ | ||
38 | linux,keymap = <0x00000074 | ||
39 | 0x00010067 | ||
40 | 0x00020066 | ||
41 | 0x01010068 | ||
42 | 0x02000069 | ||
43 | 0x02010070 | ||
44 | 0x02020071>; | ||
23 | }; | 45 | }; |
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index 55f7e57d4e42..38b523a1ece0 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | menu "Input device support" | 5 | menu "Input device support" |
6 | depends on !S390 && !UML | 6 | depends on !UML |
7 | 7 | ||
8 | config INPUT | 8 | config INPUT |
9 | tristate "Generic input layer (needed for keyboard, mouse, ...)" if EXPERT | 9 | tristate "Generic input layer (needed for keyboard, mouse, ...)" if EXPERT |
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c index 47a6009dbf43..71db1930573f 100644 --- a/drivers/input/input-mt.c +++ b/drivers/input/input-mt.c | |||
@@ -18,6 +18,7 @@ static void copy_abs(struct input_dev *dev, unsigned int dst, unsigned int src) | |||
18 | { | 18 | { |
19 | if (dev->absinfo && test_bit(src, dev->absbit)) { | 19 | if (dev->absinfo && test_bit(src, dev->absbit)) { |
20 | dev->absinfo[dst] = dev->absinfo[src]; | 20 | dev->absinfo[dst] = dev->absinfo[src]; |
21 | dev->absinfo[dst].fuzz = 0; | ||
21 | dev->absbit[BIT_WORD(dst)] |= BIT_MASK(dst); | 22 | dev->absbit[BIT_WORD(dst)] |= BIT_MASK(dst); |
22 | } | 23 | } |
23 | } | 24 | } |
diff --git a/drivers/input/joystick/walkera0701.c b/drivers/input/joystick/walkera0701.c index f8f892b076e8..b76ac580703c 100644 --- a/drivers/input/joystick/walkera0701.c +++ b/drivers/input/joystick/walkera0701.c | |||
@@ -12,7 +12,7 @@ | |||
12 | * the Free Software Foundation. | 12 | * the Free Software Foundation. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | /* #define WK0701_DEBUG */ | 15 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
16 | 16 | ||
17 | #define RESERVE 20000 | 17 | #define RESERVE 20000 |
18 | #define SYNC_PULSE 1306000 | 18 | #define SYNC_PULSE 1306000 |
@@ -67,6 +67,7 @@ static inline void walkera0701_parse_frame(struct walkera_dev *w) | |||
67 | { | 67 | { |
68 | int i; | 68 | int i; |
69 | int val1, val2, val3, val4, val5, val6, val7, val8; | 69 | int val1, val2, val3, val4, val5, val6, val7, val8; |
70 | int magic, magic_bit; | ||
70 | int crc1, crc2; | 71 | int crc1, crc2; |
71 | 72 | ||
72 | for (crc1 = crc2 = i = 0; i < 10; i++) { | 73 | for (crc1 = crc2 = i = 0; i < 10; i++) { |
@@ -102,17 +103,12 @@ static inline void walkera0701_parse_frame(struct walkera_dev *w) | |||
102 | val8 = (w->buf[18] & 1) << 8 | (w->buf[19] << 4) | w->buf[20]; | 103 | val8 = (w->buf[18] & 1) << 8 | (w->buf[19] << 4) | w->buf[20]; |
103 | val8 *= (w->buf[18] & 2) - 1; /*sign */ | 104 | val8 *= (w->buf[18] & 2) - 1; /*sign */ |
104 | 105 | ||
105 | #ifdef WK0701_DEBUG | 106 | magic = (w->buf[21] << 4) | w->buf[22]; |
106 | { | 107 | magic_bit = (w->buf[24] & 8) >> 3; |
107 | int magic, magic_bit; | 108 | pr_debug("%4d %4d %4d %4d %4d %4d %4d %4d (magic %2x %d)\n", |
108 | magic = (w->buf[21] << 4) | w->buf[22]; | 109 | val1, val2, val3, val4, val5, val6, val7, val8, |
109 | magic_bit = (w->buf[24] & 8) >> 3; | 110 | magic, magic_bit); |
110 | printk(KERN_DEBUG | 111 | |
111 | "walkera0701: %4d %4d %4d %4d %4d %4d %4d %4d (magic %2x %d)\n", | ||
112 | val1, val2, val3, val4, val5, val6, val7, val8, magic, | ||
113 | magic_bit); | ||
114 | } | ||
115 | #endif | ||
116 | input_report_abs(w->input_dev, ABS_X, val2); | 112 | input_report_abs(w->input_dev, ABS_X, val2); |
117 | input_report_abs(w->input_dev, ABS_Y, val1); | 113 | input_report_abs(w->input_dev, ABS_Y, val1); |
118 | input_report_abs(w->input_dev, ABS_Z, val6); | 114 | input_report_abs(w->input_dev, ABS_Z, val6); |
@@ -187,6 +183,9 @@ static int walkera0701_open(struct input_dev *dev) | |||
187 | { | 183 | { |
188 | struct walkera_dev *w = input_get_drvdata(dev); | 184 | struct walkera_dev *w = input_get_drvdata(dev); |
189 | 185 | ||
186 | if (parport_claim(w->pardevice)) | ||
187 | return -EBUSY; | ||
188 | |||
190 | parport_enable_irq(w->parport); | 189 | parport_enable_irq(w->parport); |
191 | return 0; | 190 | return 0; |
192 | } | 191 | } |
@@ -197,40 +196,51 @@ static void walkera0701_close(struct input_dev *dev) | |||
197 | 196 | ||
198 | parport_disable_irq(w->parport); | 197 | parport_disable_irq(w->parport); |
199 | hrtimer_cancel(&w->timer); | 198 | hrtimer_cancel(&w->timer); |
199 | |||
200 | parport_release(w->pardevice); | ||
200 | } | 201 | } |
201 | 202 | ||
202 | static int walkera0701_connect(struct walkera_dev *w, int parport) | 203 | static int walkera0701_connect(struct walkera_dev *w, int parport) |
203 | { | 204 | { |
204 | int err = -ENODEV; | 205 | int error; |
205 | 206 | ||
206 | w->parport = parport_find_number(parport); | 207 | w->parport = parport_find_number(parport); |
207 | if (w->parport == NULL) | 208 | if (!w->parport) { |
209 | pr_err("parport %d does not exist\n", parport); | ||
208 | return -ENODEV; | 210 | return -ENODEV; |
211 | } | ||
209 | 212 | ||
210 | if (w->parport->irq == -1) { | 213 | if (w->parport->irq == -1) { |
211 | printk(KERN_ERR "walkera0701: parport without interrupt\n"); | 214 | pr_err("parport %d does not have interrupt assigned\n", |
212 | goto init_err; | 215 | parport); |
216 | error = -EINVAL; | ||
217 | goto err_put_parport; | ||
213 | } | 218 | } |
214 | 219 | ||
215 | err = -EBUSY; | ||
216 | w->pardevice = parport_register_device(w->parport, "walkera0701", | 220 | w->pardevice = parport_register_device(w->parport, "walkera0701", |
217 | NULL, NULL, walkera0701_irq_handler, | 221 | NULL, NULL, walkera0701_irq_handler, |
218 | PARPORT_DEV_EXCL, w); | 222 | PARPORT_DEV_EXCL, w); |
219 | if (!w->pardevice) | 223 | if (!w->pardevice) { |
220 | goto init_err; | 224 | pr_err("failed to register parport device\n"); |
221 | 225 | error = -EIO; | |
222 | if (parport_negotiate(w->pardevice->port, IEEE1284_MODE_COMPAT)) | 226 | goto err_put_parport; |
223 | goto init_err1; | 227 | } |
224 | 228 | ||
225 | if (parport_claim(w->pardevice)) | 229 | if (parport_negotiate(w->pardevice->port, IEEE1284_MODE_COMPAT)) { |
226 | goto init_err1; | 230 | pr_err("failed to negotiate parport mode\n"); |
231 | error = -EIO; | ||
232 | goto err_unregister_device; | ||
233 | } | ||
227 | 234 | ||
228 | hrtimer_init(&w->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | 235 | hrtimer_init(&w->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
229 | w->timer.function = timer_handler; | 236 | w->timer.function = timer_handler; |
230 | 237 | ||
231 | w->input_dev = input_allocate_device(); | 238 | w->input_dev = input_allocate_device(); |
232 | if (!w->input_dev) | 239 | if (!w->input_dev) { |
233 | goto init_err2; | 240 | pr_err("failed to allocate input device\n"); |
241 | error = -ENOMEM; | ||
242 | goto err_unregister_device; | ||
243 | } | ||
234 | 244 | ||
235 | input_set_drvdata(w->input_dev, w); | 245 | input_set_drvdata(w->input_dev, w); |
236 | w->input_dev->name = "Walkera WK-0701 TX"; | 246 | w->input_dev->name = "Walkera WK-0701 TX"; |
@@ -241,6 +251,7 @@ static int walkera0701_connect(struct walkera_dev *w, int parport) | |||
241 | w->input_dev->id.vendor = 0x0001; | 251 | w->input_dev->id.vendor = 0x0001; |
242 | w->input_dev->id.product = 0x0001; | 252 | w->input_dev->id.product = 0x0001; |
243 | w->input_dev->id.version = 0x0100; | 253 | w->input_dev->id.version = 0x0100; |
254 | w->input_dev->dev.parent = w->parport->dev; | ||
244 | w->input_dev->open = walkera0701_open; | 255 | w->input_dev->open = walkera0701_open; |
245 | w->input_dev->close = walkera0701_close; | 256 | w->input_dev->close = walkera0701_close; |
246 | 257 | ||
@@ -254,27 +265,26 @@ static int walkera0701_connect(struct walkera_dev *w, int parport) | |||
254 | input_set_abs_params(w->input_dev, ABS_RUDDER, -512, 512, 0, 0); | 265 | input_set_abs_params(w->input_dev, ABS_RUDDER, -512, 512, 0, 0); |
255 | input_set_abs_params(w->input_dev, ABS_MISC, -512, 512, 0, 0); | 266 | input_set_abs_params(w->input_dev, ABS_MISC, -512, 512, 0, 0); |
256 | 267 | ||
257 | err = input_register_device(w->input_dev); | 268 | error = input_register_device(w->input_dev); |
258 | if (err) | 269 | if (error) { |
259 | goto init_err3; | 270 | pr_err("failed to register input device\n"); |
271 | goto err_free_input_dev; | ||
272 | } | ||
260 | 273 | ||
261 | return 0; | 274 | return 0; |
262 | 275 | ||
263 | init_err3: | 276 | err_free_input_dev: |
264 | input_free_device(w->input_dev); | 277 | input_free_device(w->input_dev); |
265 | init_err2: | 278 | err_unregister_device: |
266 | parport_release(w->pardevice); | ||
267 | init_err1: | ||
268 | parport_unregister_device(w->pardevice); | 279 | parport_unregister_device(w->pardevice); |
269 | init_err: | 280 | err_put_parport: |
270 | parport_put_port(w->parport); | 281 | parport_put_port(w->parport); |
271 | return err; | 282 | return error; |
272 | } | 283 | } |
273 | 284 | ||
274 | static void walkera0701_disconnect(struct walkera_dev *w) | 285 | static void walkera0701_disconnect(struct walkera_dev *w) |
275 | { | 286 | { |
276 | input_unregister_device(w->input_dev); | 287 | input_unregister_device(w->input_dev); |
277 | parport_release(w->pardevice); | ||
278 | parport_unregister_device(w->pardevice); | 288 | parport_unregister_device(w->pardevice); |
279 | parport_put_port(w->parport); | 289 | parport_put_port(w->parport); |
280 | } | 290 | } |
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 5a240c60342d..ac0500667000 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -224,7 +224,7 @@ config KEYBOARD_TCA6416 | |||
224 | 224 | ||
225 | config KEYBOARD_TCA8418 | 225 | config KEYBOARD_TCA8418 |
226 | tristate "TCA8418 Keypad Support" | 226 | tristate "TCA8418 Keypad Support" |
227 | depends on I2C | 227 | depends on I2C && GENERIC_HARDIRQS |
228 | select INPUT_MATRIXKMAP | 228 | select INPUT_MATRIXKMAP |
229 | help | 229 | help |
230 | This driver implements basic keypad functionality | 230 | This driver implements basic keypad functionality |
@@ -303,7 +303,7 @@ config KEYBOARD_HP7XX | |||
303 | 303 | ||
304 | config KEYBOARD_LM8323 | 304 | config KEYBOARD_LM8323 |
305 | tristate "LM8323 keypad chip" | 305 | tristate "LM8323 keypad chip" |
306 | depends on I2C | 306 | depends on I2C && GENERIC_HARDIRQS |
307 | depends on LEDS_CLASS | 307 | depends on LEDS_CLASS |
308 | help | 308 | help |
309 | If you say yes here you get support for the National Semiconductor | 309 | If you say yes here you get support for the National Semiconductor |
@@ -420,7 +420,7 @@ config KEYBOARD_NOMADIK | |||
420 | 420 | ||
421 | config KEYBOARD_TEGRA | 421 | config KEYBOARD_TEGRA |
422 | tristate "NVIDIA Tegra internal matrix keyboard controller support" | 422 | tristate "NVIDIA Tegra internal matrix keyboard controller support" |
423 | depends on ARCH_TEGRA | 423 | depends on ARCH_TEGRA && OF |
424 | select INPUT_MATRIXKMAP | 424 | select INPUT_MATRIXKMAP |
425 | help | 425 | help |
426 | Say Y here if you want to use a matrix keyboard connected directly | 426 | Say Y here if you want to use a matrix keyboard connected directly |
@@ -479,6 +479,16 @@ config KEYBOARD_SAMSUNG | |||
479 | To compile this driver as a module, choose M here: the | 479 | To compile this driver as a module, choose M here: the |
480 | module will be called samsung-keypad. | 480 | module will be called samsung-keypad. |
481 | 481 | ||
482 | config KEYBOARD_GOLDFISH_EVENTS | ||
483 | depends on GOLDFISH | ||
484 | tristate "Generic Input Event device for Goldfish" | ||
485 | help | ||
486 | Say Y here to get an input event device for the Goldfish virtual | ||
487 | device emulator. | ||
488 | |||
489 | To compile this driver as a module, choose M here: the | ||
490 | module will be called goldfish-events. | ||
491 | |||
482 | config KEYBOARD_STOWAWAY | 492 | config KEYBOARD_STOWAWAY |
483 | tristate "Stowaway keyboard" | 493 | tristate "Stowaway keyboard" |
484 | select SERIO | 494 | select SERIO |
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 44e76002f54b..49b16453d00e 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
@@ -13,6 +13,7 @@ obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o | |||
13 | obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o | 13 | obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o |
14 | obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o | 14 | obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o |
15 | obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o | 15 | obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o |
16 | obj-$(CONFIG_KEYBOARD_GOLDFISH_EVENTS) += goldfish_events.o | ||
16 | obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o | 17 | obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o |
17 | obj-$(CONFIG_KEYBOARD_GPIO_POLLED) += gpio_keys_polled.o | 18 | obj-$(CONFIG_KEYBOARD_GPIO_POLLED) += gpio_keys_polled.o |
18 | obj-$(CONFIG_KEYBOARD_TCA6416) += tca6416-keypad.o | 19 | obj-$(CONFIG_KEYBOARD_TCA6416) += tca6416-keypad.o |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index add5ffd9fe26..2626773ff29b 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -676,6 +676,39 @@ static inline void atkbd_disable(struct atkbd *atkbd) | |||
676 | serio_continue_rx(atkbd->ps2dev.serio); | 676 | serio_continue_rx(atkbd->ps2dev.serio); |
677 | } | 677 | } |
678 | 678 | ||
679 | static int atkbd_activate(struct atkbd *atkbd) | ||
680 | { | ||
681 | struct ps2dev *ps2dev = &atkbd->ps2dev; | ||
682 | |||
683 | /* | ||
684 | * Enable the keyboard to receive keystrokes. | ||
685 | */ | ||
686 | |||
687 | if (ps2_command(ps2dev, NULL, ATKBD_CMD_ENABLE)) { | ||
688 | dev_err(&ps2dev->serio->dev, | ||
689 | "Failed to enable keyboard on %s\n", | ||
690 | ps2dev->serio->phys); | ||
691 | return -1; | ||
692 | } | ||
693 | |||
694 | return 0; | ||
695 | } | ||
696 | |||
697 | /* | ||
698 | * atkbd_deactivate() resets and disables the keyboard from sending | ||
699 | * keystrokes. | ||
700 | */ | ||
701 | |||
702 | static void atkbd_deactivate(struct atkbd *atkbd) | ||
703 | { | ||
704 | struct ps2dev *ps2dev = &atkbd->ps2dev; | ||
705 | |||
706 | if (ps2_command(ps2dev, NULL, ATKBD_CMD_RESET_DIS)) | ||
707 | dev_err(&ps2dev->serio->dev, | ||
708 | "Failed to deactivate keyboard on %s\n", | ||
709 | ps2dev->serio->phys); | ||
710 | } | ||
711 | |||
679 | /* | 712 | /* |
680 | * atkbd_probe() probes for an AT keyboard on a serio port. | 713 | * atkbd_probe() probes for an AT keyboard on a serio port. |
681 | */ | 714 | */ |
@@ -726,11 +759,17 @@ static int atkbd_probe(struct atkbd *atkbd) | |||
726 | 759 | ||
727 | if (atkbd->id == 0xaca1 && atkbd->translated) { | 760 | if (atkbd->id == 0xaca1 && atkbd->translated) { |
728 | dev_err(&ps2dev->serio->dev, | 761 | dev_err(&ps2dev->serio->dev, |
729 | "NCD terminal keyboards are only supported on non-translating controlelrs. " | 762 | "NCD terminal keyboards are only supported on non-translating controllers. " |
730 | "Use i8042.direct=1 to disable translation.\n"); | 763 | "Use i8042.direct=1 to disable translation.\n"); |
731 | return -1; | 764 | return -1; |
732 | } | 765 | } |
733 | 766 | ||
767 | /* | ||
768 | * Make sure nothing is coming from the keyboard and disturbs our | ||
769 | * internal state. | ||
770 | */ | ||
771 | atkbd_deactivate(atkbd); | ||
772 | |||
734 | return 0; | 773 | return 0; |
735 | } | 774 | } |
736 | 775 | ||
@@ -825,24 +864,6 @@ static int atkbd_reset_state(struct atkbd *atkbd) | |||
825 | return 0; | 864 | return 0; |
826 | } | 865 | } |
827 | 866 | ||
828 | static int atkbd_activate(struct atkbd *atkbd) | ||
829 | { | ||
830 | struct ps2dev *ps2dev = &atkbd->ps2dev; | ||
831 | |||
832 | /* | ||
833 | * Enable the keyboard to receive keystrokes. | ||
834 | */ | ||
835 | |||
836 | if (ps2_command(ps2dev, NULL, ATKBD_CMD_ENABLE)) { | ||
837 | dev_err(&ps2dev->serio->dev, | ||
838 | "Failed to enable keyboard on %s\n", | ||
839 | ps2dev->serio->phys); | ||
840 | return -1; | ||
841 | } | ||
842 | |||
843 | return 0; | ||
844 | } | ||
845 | |||
846 | /* | 867 | /* |
847 | * atkbd_cleanup() restores the keyboard state so that BIOS is happy after a | 868 | * atkbd_cleanup() restores the keyboard state so that BIOS is happy after a |
848 | * reboot. | 869 | * reboot. |
@@ -1150,7 +1171,6 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
1150 | 1171 | ||
1151 | atkbd->set = atkbd_select_set(atkbd, atkbd_set, atkbd_extra); | 1172 | atkbd->set = atkbd_select_set(atkbd, atkbd_set, atkbd_extra); |
1152 | atkbd_reset_state(atkbd); | 1173 | atkbd_reset_state(atkbd); |
1153 | atkbd_activate(atkbd); | ||
1154 | 1174 | ||
1155 | } else { | 1175 | } else { |
1156 | atkbd->set = 2; | 1176 | atkbd->set = 2; |
@@ -1165,6 +1185,8 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
1165 | goto fail3; | 1185 | goto fail3; |
1166 | 1186 | ||
1167 | atkbd_enable(atkbd); | 1187 | atkbd_enable(atkbd); |
1188 | if (serio->write) | ||
1189 | atkbd_activate(atkbd); | ||
1168 | 1190 | ||
1169 | err = input_register_device(atkbd->dev); | 1191 | err = input_register_device(atkbd->dev); |
1170 | if (err) | 1192 | if (err) |
@@ -1208,8 +1230,6 @@ static int atkbd_reconnect(struct serio *serio) | |||
1208 | if (atkbd->set != atkbd_select_set(atkbd, atkbd->set, atkbd->extra)) | 1230 | if (atkbd->set != atkbd_select_set(atkbd, atkbd->set, atkbd->extra)) |
1209 | goto out; | 1231 | goto out; |
1210 | 1232 | ||
1211 | atkbd_activate(atkbd); | ||
1212 | |||
1213 | /* | 1233 | /* |
1214 | * Restore LED state and repeat rate. While input core | 1234 | * Restore LED state and repeat rate. While input core |
1215 | * will do this for us at resume time reconnect may happen | 1235 | * will do this for us at resume time reconnect may happen |
@@ -1223,7 +1243,17 @@ static int atkbd_reconnect(struct serio *serio) | |||
1223 | 1243 | ||
1224 | } | 1244 | } |
1225 | 1245 | ||
1246 | /* | ||
1247 | * Reset our state machine in case reconnect happened in the middle | ||
1248 | * of multi-byte scancode. | ||
1249 | */ | ||
1250 | atkbd->xl_bit = 0; | ||
1251 | atkbd->emul = 0; | ||
1252 | |||
1226 | atkbd_enable(atkbd); | 1253 | atkbd_enable(atkbd); |
1254 | if (atkbd->write) | ||
1255 | atkbd_activate(atkbd); | ||
1256 | |||
1227 | retval = 0; | 1257 | retval = 0; |
1228 | 1258 | ||
1229 | out: | 1259 | out: |
diff --git a/drivers/input/keyboard/goldfish_events.c b/drivers/input/keyboard/goldfish_events.c new file mode 100644 index 000000000000..9f60a2ec88db --- /dev/null +++ b/drivers/input/keyboard/goldfish_events.c | |||
@@ -0,0 +1,194 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007 Google, Inc. | ||
3 | * Copyright (C) 2012 Intel, Inc. | ||
4 | * | ||
5 | * This software is licensed under the terms of the GNU General Public | ||
6 | * License version 2, as published by the Free Software Foundation, and | ||
7 | * may be copied, distributed, and modified under those terms. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/module.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/types.h> | ||
20 | #include <linux/input.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/irq.h> | ||
25 | #include <linux/io.h> | ||
26 | |||
27 | enum { | ||
28 | REG_READ = 0x00, | ||
29 | REG_SET_PAGE = 0x00, | ||
30 | REG_LEN = 0x04, | ||
31 | REG_DATA = 0x08, | ||
32 | |||
33 | PAGE_NAME = 0x00000, | ||
34 | PAGE_EVBITS = 0x10000, | ||
35 | PAGE_ABSDATA = 0x20000 | EV_ABS, | ||
36 | }; | ||
37 | |||
38 | struct event_dev { | ||
39 | struct input_dev *input; | ||
40 | int irq; | ||
41 | void __iomem *addr; | ||
42 | char name[0]; | ||
43 | }; | ||
44 | |||
45 | static irqreturn_t events_interrupt(int irq, void *dev_id) | ||
46 | { | ||
47 | struct event_dev *edev = dev_id; | ||
48 | unsigned type, code, value; | ||
49 | |||
50 | type = __raw_readl(edev->addr + REG_READ); | ||
51 | code = __raw_readl(edev->addr + REG_READ); | ||
52 | value = __raw_readl(edev->addr + REG_READ); | ||
53 | |||
54 | input_event(edev->input, type, code, value); | ||
55 | input_sync(edev->input); | ||
56 | return IRQ_HANDLED; | ||
57 | } | ||
58 | |||
59 | static void events_import_bits(struct event_dev *edev, | ||
60 | unsigned long bits[], unsigned type, size_t count) | ||
61 | { | ||
62 | void __iomem *addr = edev->addr; | ||
63 | int i, j; | ||
64 | size_t size; | ||
65 | uint8_t val; | ||
66 | |||
67 | __raw_writel(PAGE_EVBITS | type, addr + REG_SET_PAGE); | ||
68 | |||
69 | size = __raw_readl(addr + REG_LEN) * 8; | ||
70 | if (size < count) | ||
71 | count = size; | ||
72 | |||
73 | addr += REG_DATA; | ||
74 | for (i = 0; i < count; i += 8) { | ||
75 | val = __raw_readb(addr++); | ||
76 | for (j = 0; j < 8; j++) | ||
77 | if (val & 1 << j) | ||
78 | set_bit(i + j, bits); | ||
79 | } | ||
80 | } | ||
81 | |||
82 | static void events_import_abs_params(struct event_dev *edev) | ||
83 | { | ||
84 | struct input_dev *input_dev = edev->input; | ||
85 | void __iomem *addr = edev->addr; | ||
86 | u32 val[4]; | ||
87 | int count; | ||
88 | int i, j; | ||
89 | |||
90 | __raw_writel(PAGE_ABSDATA, addr + REG_SET_PAGE); | ||
91 | |||
92 | count = __raw_readl(addr + REG_LEN) / sizeof(val); | ||
93 | if (count > ABS_MAX) | ||
94 | count = ABS_MAX; | ||
95 | |||
96 | for (i = 0; i < count; i++) { | ||
97 | if (!test_bit(i, input_dev->absbit)) | ||
98 | continue; | ||
99 | |||
100 | for (j = 0; j < ARRAY_SIZE(val); j++) { | ||
101 | int offset = (i * ARRAY_SIZE(val) + j) * sizeof(u32); | ||
102 | val[j] = __raw_readl(edev->addr + REG_DATA + offset); | ||
103 | } | ||
104 | |||
105 | input_set_abs_params(input_dev, i, | ||
106 | val[0], val[1], val[2], val[3]); | ||
107 | } | ||
108 | } | ||
109 | |||
110 | static int events_probe(struct platform_device *pdev) | ||
111 | { | ||
112 | struct input_dev *input_dev; | ||
113 | struct event_dev *edev; | ||
114 | struct resource *res; | ||
115 | unsigned keymapnamelen; | ||
116 | void __iomem *addr; | ||
117 | int irq; | ||
118 | int i; | ||
119 | int error; | ||
120 | |||
121 | irq = platform_get_irq(pdev, 0); | ||
122 | if (irq < 0) | ||
123 | return -EINVAL; | ||
124 | |||
125 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
126 | if (!res) | ||
127 | return -EINVAL; | ||
128 | |||
129 | addr = devm_ioremap(&pdev->dev, res->start, 4096); | ||
130 | if (!addr) | ||
131 | return -ENOMEM; | ||
132 | |||
133 | __raw_writel(PAGE_NAME, addr + REG_SET_PAGE); | ||
134 | keymapnamelen = __raw_readl(addr + REG_LEN); | ||
135 | |||
136 | edev = devm_kzalloc(&pdev->dev, | ||
137 | sizeof(struct event_dev) + keymapnamelen + 1, | ||
138 | GFP_KERNEL); | ||
139 | if (!edev) | ||
140 | return -ENOMEM; | ||
141 | |||
142 | input_dev = devm_input_allocate_device(&pdev->dev); | ||
143 | if (!input_dev) | ||
144 | return -ENOMEM; | ||
145 | |||
146 | edev->input = input_dev; | ||
147 | edev->addr = addr; | ||
148 | edev->irq = irq; | ||
149 | |||
150 | for (i = 0; i < keymapnamelen; i++) | ||
151 | edev->name[i] = __raw_readb(edev->addr + REG_DATA + i); | ||
152 | |||
153 | pr_debug("events_probe() keymap=%s\n", edev->name); | ||
154 | |||
155 | input_dev->name = edev->name; | ||
156 | input_dev->id.bustype = BUS_HOST; | ||
157 | |||
158 | events_import_bits(edev, input_dev->evbit, EV_SYN, EV_MAX); | ||
159 | events_import_bits(edev, input_dev->keybit, EV_KEY, KEY_MAX); | ||
160 | events_import_bits(edev, input_dev->relbit, EV_REL, REL_MAX); | ||
161 | events_import_bits(edev, input_dev->absbit, EV_ABS, ABS_MAX); | ||
162 | events_import_bits(edev, input_dev->mscbit, EV_MSC, MSC_MAX); | ||
163 | events_import_bits(edev, input_dev->ledbit, EV_LED, LED_MAX); | ||
164 | events_import_bits(edev, input_dev->sndbit, EV_SND, SND_MAX); | ||
165 | events_import_bits(edev, input_dev->ffbit, EV_FF, FF_MAX); | ||
166 | events_import_bits(edev, input_dev->swbit, EV_SW, SW_MAX); | ||
167 | |||
168 | events_import_abs_params(edev); | ||
169 | |||
170 | error = devm_request_irq(&pdev->dev, edev->irq, events_interrupt, 0, | ||
171 | "goldfish-events-keypad", edev); | ||
172 | if (error) | ||
173 | return error; | ||
174 | |||
175 | error = input_register_device(input_dev); | ||
176 | if (error) | ||
177 | return error; | ||
178 | |||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static struct platform_driver events_driver = { | ||
183 | .probe = events_probe, | ||
184 | .driver = { | ||
185 | .owner = THIS_MODULE, | ||
186 | .name = "goldfish_events", | ||
187 | }, | ||
188 | }; | ||
189 | |||
190 | module_platform_driver(events_driver); | ||
191 | |||
192 | MODULE_AUTHOR("Brian Swetland"); | ||
193 | MODULE_DESCRIPTION("Goldfish Event Device"); | ||
194 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c index 6d150e3e1f55..98f9113251d2 100644 --- a/drivers/input/keyboard/imx_keypad.c +++ b/drivers/input/keyboard/imx_keypad.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/jiffies.h> | 20 | #include <linux/jiffies.h> |
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/of.h> | ||
23 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
24 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
25 | #include <linux/timer.h> | 26 | #include <linux/timer.h> |
@@ -414,15 +415,23 @@ open_err: | |||
414 | return -EIO; | 415 | return -EIO; |
415 | } | 416 | } |
416 | 417 | ||
418 | #ifdef CONFIG_OF | ||
419 | static struct of_device_id imx_keypad_of_match[] = { | ||
420 | { .compatible = "fsl,imx21-kpp", }, | ||
421 | { /* sentinel */ } | ||
422 | }; | ||
423 | MODULE_DEVICE_TABLE(of, imx_keypad_of_match); | ||
424 | #endif | ||
425 | |||
417 | static int imx_keypad_probe(struct platform_device *pdev) | 426 | static int imx_keypad_probe(struct platform_device *pdev) |
418 | { | 427 | { |
419 | const struct matrix_keymap_data *keymap_data = pdev->dev.platform_data; | 428 | const struct matrix_keymap_data *keymap_data = pdev->dev.platform_data; |
420 | struct imx_keypad *keypad; | 429 | struct imx_keypad *keypad; |
421 | struct input_dev *input_dev; | 430 | struct input_dev *input_dev; |
422 | struct resource *res; | 431 | struct resource *res; |
423 | int irq, error, i; | 432 | int irq, error, i, row, col; |
424 | 433 | ||
425 | if (keymap_data == NULL) { | 434 | if (!keymap_data && !pdev->dev.of_node) { |
426 | dev_err(&pdev->dev, "no keymap defined\n"); | 435 | dev_err(&pdev->dev, "no keymap defined\n"); |
427 | return -EINVAL; | 436 | return -EINVAL; |
428 | } | 437 | } |
@@ -480,22 +489,6 @@ static int imx_keypad_probe(struct platform_device *pdev) | |||
480 | goto failed_unmap; | 489 | goto failed_unmap; |
481 | } | 490 | } |
482 | 491 | ||
483 | /* Search for rows and cols enabled */ | ||
484 | for (i = 0; i < keymap_data->keymap_size; i++) { | ||
485 | keypad->rows_en_mask |= 1 << KEY_ROW(keymap_data->keymap[i]); | ||
486 | keypad->cols_en_mask |= 1 << KEY_COL(keymap_data->keymap[i]); | ||
487 | } | ||
488 | |||
489 | if (keypad->rows_en_mask > ((1 << MAX_MATRIX_KEY_ROWS) - 1) || | ||
490 | keypad->cols_en_mask > ((1 << MAX_MATRIX_KEY_COLS) - 1)) { | ||
491 | dev_err(&pdev->dev, | ||
492 | "invalid key data (too many rows or colums)\n"); | ||
493 | error = -EINVAL; | ||
494 | goto failed_clock_put; | ||
495 | } | ||
496 | dev_dbg(&pdev->dev, "enabled rows mask: %x\n", keypad->rows_en_mask); | ||
497 | dev_dbg(&pdev->dev, "enabled cols mask: %x\n", keypad->cols_en_mask); | ||
498 | |||
499 | /* Init the Input device */ | 492 | /* Init the Input device */ |
500 | input_dev->name = pdev->name; | 493 | input_dev->name = pdev->name; |
501 | input_dev->id.bustype = BUS_HOST; | 494 | input_dev->id.bustype = BUS_HOST; |
@@ -512,6 +505,19 @@ static int imx_keypad_probe(struct platform_device *pdev) | |||
512 | goto failed_clock_put; | 505 | goto failed_clock_put; |
513 | } | 506 | } |
514 | 507 | ||
508 | /* Search for rows and cols enabled */ | ||
509 | for (row = 0; row < MAX_MATRIX_KEY_ROWS; row++) { | ||
510 | for (col = 0; col < MAX_MATRIX_KEY_COLS; col++) { | ||
511 | i = MATRIX_SCAN_CODE(row, col, MATRIX_ROW_SHIFT); | ||
512 | if (keypad->keycodes[i] != KEY_RESERVED) { | ||
513 | keypad->rows_en_mask |= 1 << row; | ||
514 | keypad->cols_en_mask |= 1 << col; | ||
515 | } | ||
516 | } | ||
517 | } | ||
518 | dev_dbg(&pdev->dev, "enabled rows mask: %x\n", keypad->rows_en_mask); | ||
519 | dev_dbg(&pdev->dev, "enabled cols mask: %x\n", keypad->cols_en_mask); | ||
520 | |||
515 | __set_bit(EV_REP, input_dev->evbit); | 521 | __set_bit(EV_REP, input_dev->evbit); |
516 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | 522 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); |
517 | input_set_drvdata(input_dev, keypad); | 523 | input_set_drvdata(input_dev, keypad); |
@@ -631,6 +637,7 @@ static struct platform_driver imx_keypad_driver = { | |||
631 | .name = "imx-keypad", | 637 | .name = "imx-keypad", |
632 | .owner = THIS_MODULE, | 638 | .owner = THIS_MODULE, |
633 | .pm = &imx_kbd_pm_ops, | 639 | .pm = &imx_kbd_pm_ops, |
640 | .of_match_table = of_match_ptr(imx_keypad_of_match), | ||
634 | }, | 641 | }, |
635 | .probe = imx_keypad_probe, | 642 | .probe = imx_keypad_probe, |
636 | .remove = imx_keypad_remove, | 643 | .remove = imx_keypad_remove, |
diff --git a/drivers/input/keyboard/qt2160.c b/drivers/input/keyboard/qt2160.c index 3dc2b0f27b0c..1c0ddad0a1cc 100644 --- a/drivers/input/keyboard/qt2160.c +++ b/drivers/input/keyboard/qt2160.c | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/leds.h> | ||
23 | #include <linux/module.h> | 24 | #include <linux/module.h> |
24 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
25 | #include <linux/jiffies.h> | 26 | #include <linux/jiffies.h> |
@@ -39,6 +40,11 @@ | |||
39 | #define QT2160_CMD_GPIOS 6 | 40 | #define QT2160_CMD_GPIOS 6 |
40 | #define QT2160_CMD_SUBVER 7 | 41 | #define QT2160_CMD_SUBVER 7 |
41 | #define QT2160_CMD_CALIBRATE 10 | 42 | #define QT2160_CMD_CALIBRATE 10 |
43 | #define QT2160_CMD_DRIVE_X 70 | ||
44 | #define QT2160_CMD_PWMEN_X 74 | ||
45 | #define QT2160_CMD_PWM_DUTY 76 | ||
46 | |||
47 | #define QT2160_NUM_LEDS_X 8 | ||
42 | 48 | ||
43 | #define QT2160_CYCLE_INTERVAL (2*HZ) | 49 | #define QT2160_CYCLE_INTERVAL (2*HZ) |
44 | 50 | ||
@@ -49,6 +55,17 @@ static unsigned char qt2160_key2code[] = { | |||
49 | KEY_C, KEY_D, KEY_E, KEY_F, | 55 | KEY_C, KEY_D, KEY_E, KEY_F, |
50 | }; | 56 | }; |
51 | 57 | ||
58 | #ifdef CONFIG_LEDS_CLASS | ||
59 | struct qt2160_led { | ||
60 | struct qt2160_data *qt2160; | ||
61 | struct led_classdev cdev; | ||
62 | struct work_struct work; | ||
63 | char name[32]; | ||
64 | int id; | ||
65 | enum led_brightness new_brightness; | ||
66 | }; | ||
67 | #endif | ||
68 | |||
52 | struct qt2160_data { | 69 | struct qt2160_data { |
53 | struct i2c_client *client; | 70 | struct i2c_client *client; |
54 | struct input_dev *input; | 71 | struct input_dev *input; |
@@ -56,8 +73,61 @@ struct qt2160_data { | |||
56 | spinlock_t lock; /* Protects canceling/rescheduling of dwork */ | 73 | spinlock_t lock; /* Protects canceling/rescheduling of dwork */ |
57 | unsigned short keycodes[ARRAY_SIZE(qt2160_key2code)]; | 74 | unsigned short keycodes[ARRAY_SIZE(qt2160_key2code)]; |
58 | u16 key_matrix; | 75 | u16 key_matrix; |
76 | #ifdef CONFIG_LEDS_CLASS | ||
77 | struct qt2160_led leds[QT2160_NUM_LEDS_X]; | ||
78 | struct mutex led_lock; | ||
79 | #endif | ||
59 | }; | 80 | }; |
60 | 81 | ||
82 | static int qt2160_read(struct i2c_client *client, u8 reg); | ||
83 | static int qt2160_write(struct i2c_client *client, u8 reg, u8 data); | ||
84 | |||
85 | #ifdef CONFIG_LEDS_CLASS | ||
86 | |||
87 | static void qt2160_led_work(struct work_struct *work) | ||
88 | { | ||
89 | struct qt2160_led *led = container_of(work, struct qt2160_led, work); | ||
90 | struct qt2160_data *qt2160 = led->qt2160; | ||
91 | struct i2c_client *client = qt2160->client; | ||
92 | int value = led->new_brightness; | ||
93 | u32 drive, pwmen; | ||
94 | |||
95 | mutex_lock(&qt2160->led_lock); | ||
96 | |||
97 | drive = qt2160_read(client, QT2160_CMD_DRIVE_X); | ||
98 | pwmen = qt2160_read(client, QT2160_CMD_PWMEN_X); | ||
99 | if (value != LED_OFF) { | ||
100 | drive |= (1 << led->id); | ||
101 | pwmen |= (1 << led->id); | ||
102 | |||
103 | } else { | ||
104 | drive &= ~(1 << led->id); | ||
105 | pwmen &= ~(1 << led->id); | ||
106 | } | ||
107 | qt2160_write(client, QT2160_CMD_DRIVE_X, drive); | ||
108 | qt2160_write(client, QT2160_CMD_PWMEN_X, pwmen); | ||
109 | |||
110 | /* | ||
111 | * Changing this register will change the brightness | ||
112 | * of every LED in the qt2160. It's a HW limitation. | ||
113 | */ | ||
114 | if (value != LED_OFF) | ||
115 | qt2160_write(client, QT2160_CMD_PWM_DUTY, value); | ||
116 | |||
117 | mutex_unlock(&qt2160->led_lock); | ||
118 | } | ||
119 | |||
120 | static void qt2160_led_set(struct led_classdev *cdev, | ||
121 | enum led_brightness value) | ||
122 | { | ||
123 | struct qt2160_led *led = container_of(cdev, struct qt2160_led, cdev); | ||
124 | |||
125 | led->new_brightness = value; | ||
126 | schedule_work(&led->work); | ||
127 | } | ||
128 | |||
129 | #endif /* CONFIG_LEDS_CLASS */ | ||
130 | |||
61 | static int qt2160_read_block(struct i2c_client *client, | 131 | static int qt2160_read_block(struct i2c_client *client, |
62 | u8 inireg, u8 *buffer, unsigned int count) | 132 | u8 inireg, u8 *buffer, unsigned int count) |
63 | { | 133 | { |
@@ -216,6 +286,63 @@ static int qt2160_write(struct i2c_client *client, u8 reg, u8 data) | |||
216 | return ret; | 286 | return ret; |
217 | } | 287 | } |
218 | 288 | ||
289 | #ifdef CONFIG_LEDS_CLASS | ||
290 | |||
291 | static int qt2160_register_leds(struct qt2160_data *qt2160) | ||
292 | { | ||
293 | struct i2c_client *client = qt2160->client; | ||
294 | int ret; | ||
295 | int i; | ||
296 | |||
297 | mutex_init(&qt2160->led_lock); | ||
298 | |||
299 | for (i = 0; i < QT2160_NUM_LEDS_X; i++) { | ||
300 | struct qt2160_led *led = &qt2160->leds[i]; | ||
301 | |||
302 | snprintf(led->name, sizeof(led->name), "qt2160:x%d", i); | ||
303 | led->cdev.name = led->name; | ||
304 | led->cdev.brightness_set = qt2160_led_set; | ||
305 | led->cdev.brightness = LED_OFF; | ||
306 | led->id = i; | ||
307 | led->qt2160 = qt2160; | ||
308 | |||
309 | INIT_WORK(&led->work, qt2160_led_work); | ||
310 | |||
311 | ret = led_classdev_register(&client->dev, &led->cdev); | ||
312 | if (ret < 0) | ||
313 | return ret; | ||
314 | } | ||
315 | |||
316 | /* Tur off LEDs */ | ||
317 | qt2160_write(client, QT2160_CMD_DRIVE_X, 0); | ||
318 | qt2160_write(client, QT2160_CMD_PWMEN_X, 0); | ||
319 | qt2160_write(client, QT2160_CMD_PWM_DUTY, 0); | ||
320 | |||
321 | return 0; | ||
322 | } | ||
323 | |||
324 | static void qt2160_unregister_leds(struct qt2160_data *qt2160) | ||
325 | { | ||
326 | int i; | ||
327 | |||
328 | for (i = 0; i < QT2160_NUM_LEDS_X; i++) { | ||
329 | led_classdev_unregister(&qt2160->leds[i].cdev); | ||
330 | cancel_work_sync(&qt2160->leds[i].work); | ||
331 | } | ||
332 | } | ||
333 | |||
334 | #else | ||
335 | |||
336 | static inline int qt2160_register_leds(struct qt2160_data *qt2160) | ||
337 | { | ||
338 | return 0; | ||
339 | } | ||
340 | |||
341 | static inline void qt2160_unregister_leds(struct qt2160_data *qt2160) | ||
342 | { | ||
343 | } | ||
344 | |||
345 | #endif | ||
219 | 346 | ||
220 | static bool qt2160_identify(struct i2c_client *client) | 347 | static bool qt2160_identify(struct i2c_client *client) |
221 | { | 348 | { |
@@ -249,7 +376,7 @@ static bool qt2160_identify(struct i2c_client *client) | |||
249 | } | 376 | } |
250 | 377 | ||
251 | static int qt2160_probe(struct i2c_client *client, | 378 | static int qt2160_probe(struct i2c_client *client, |
252 | const struct i2c_device_id *id) | 379 | const struct i2c_device_id *id) |
253 | { | 380 | { |
254 | struct qt2160_data *qt2160; | 381 | struct qt2160_data *qt2160; |
255 | struct input_dev *input; | 382 | struct input_dev *input; |
@@ -314,11 +441,17 @@ static int qt2160_probe(struct i2c_client *client, | |||
314 | } | 441 | } |
315 | } | 442 | } |
316 | 443 | ||
444 | error = qt2160_register_leds(qt2160); | ||
445 | if (error) { | ||
446 | dev_err(&client->dev, "Failed to register leds\n"); | ||
447 | goto err_free_irq; | ||
448 | } | ||
449 | |||
317 | error = input_register_device(qt2160->input); | 450 | error = input_register_device(qt2160->input); |
318 | if (error) { | 451 | if (error) { |
319 | dev_err(&client->dev, | 452 | dev_err(&client->dev, |
320 | "Failed to register input device\n"); | 453 | "Failed to register input device\n"); |
321 | goto err_free_irq; | 454 | goto err_unregister_leds; |
322 | } | 455 | } |
323 | 456 | ||
324 | i2c_set_clientdata(client, qt2160); | 457 | i2c_set_clientdata(client, qt2160); |
@@ -326,6 +459,8 @@ static int qt2160_probe(struct i2c_client *client, | |||
326 | 459 | ||
327 | return 0; | 460 | return 0; |
328 | 461 | ||
462 | err_unregister_leds: | ||
463 | qt2160_unregister_leds(qt2160); | ||
329 | err_free_irq: | 464 | err_free_irq: |
330 | if (client->irq) | 465 | if (client->irq) |
331 | free_irq(client->irq, qt2160); | 466 | free_irq(client->irq, qt2160); |
@@ -339,6 +474,8 @@ static int qt2160_remove(struct i2c_client *client) | |||
339 | { | 474 | { |
340 | struct qt2160_data *qt2160 = i2c_get_clientdata(client); | 475 | struct qt2160_data *qt2160 = i2c_get_clientdata(client); |
341 | 476 | ||
477 | qt2160_unregister_leds(qt2160); | ||
478 | |||
342 | /* Release IRQ so no queue will be scheduled */ | 479 | /* Release IRQ so no queue will be scheduled */ |
343 | if (client->irq) | 480 | if (client->irq) |
344 | free_irq(client->irq, qt2160); | 481 | free_irq(client->irq, qt2160); |
diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index c76f96872d31..d89e7d392d1e 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c | |||
@@ -29,9 +29,16 @@ | |||
29 | #include <linux/of.h> | 29 | #include <linux/of.h> |
30 | #include <linux/clk.h> | 30 | #include <linux/clk.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include <linux/input/tegra_kbc.h> | 32 | #include <linux/input/matrix_keypad.h> |
33 | #include <mach/clk.h> | 33 | #include <mach/clk.h> |
34 | 34 | ||
35 | #define KBC_MAX_GPIO 24 | ||
36 | #define KBC_MAX_KPENT 8 | ||
37 | |||
38 | #define KBC_MAX_ROW 16 | ||
39 | #define KBC_MAX_COL 8 | ||
40 | #define KBC_MAX_KEY (KBC_MAX_ROW * KBC_MAX_COL) | ||
41 | |||
35 | #define KBC_MAX_DEBOUNCE_CNT 0x3ffu | 42 | #define KBC_MAX_DEBOUNCE_CNT 0x3ffu |
36 | 43 | ||
37 | /* KBC row scan time and delay for beginning the row scan. */ | 44 | /* KBC row scan time and delay for beginning the row scan. */ |
@@ -67,10 +74,27 @@ | |||
67 | 74 | ||
68 | #define KBC_ROW_SHIFT 3 | 75 | #define KBC_ROW_SHIFT 3 |
69 | 76 | ||
77 | enum tegra_pin_type { | ||
78 | PIN_CFG_IGNORE, | ||
79 | PIN_CFG_COL, | ||
80 | PIN_CFG_ROW, | ||
81 | }; | ||
82 | |||
83 | struct tegra_kbc_pin_cfg { | ||
84 | enum tegra_pin_type type; | ||
85 | unsigned char num; | ||
86 | }; | ||
87 | |||
70 | struct tegra_kbc { | 88 | struct tegra_kbc { |
89 | struct device *dev; | ||
90 | unsigned int debounce_cnt; | ||
91 | unsigned int repeat_cnt; | ||
92 | struct tegra_kbc_pin_cfg pin_cfg[KBC_MAX_GPIO]; | ||
93 | const struct matrix_keymap_data *keymap_data; | ||
94 | bool wakeup; | ||
71 | void __iomem *mmio; | 95 | void __iomem *mmio; |
72 | struct input_dev *idev; | 96 | struct input_dev *idev; |
73 | unsigned int irq; | 97 | int irq; |
74 | spinlock_t lock; | 98 | spinlock_t lock; |
75 | unsigned int repoll_dly; | 99 | unsigned int repoll_dly; |
76 | unsigned long cp_dly_jiffies; | 100 | unsigned long cp_dly_jiffies; |
@@ -78,7 +102,6 @@ struct tegra_kbc { | |||
78 | bool use_fn_map; | 102 | bool use_fn_map; |
79 | bool use_ghost_filter; | 103 | bool use_ghost_filter; |
80 | bool keypress_caused_wake; | 104 | bool keypress_caused_wake; |
81 | const struct tegra_kbc_platform_data *pdata; | ||
82 | unsigned short keycode[KBC_MAX_KEY * 2]; | 105 | unsigned short keycode[KBC_MAX_KEY * 2]; |
83 | unsigned short current_keys[KBC_MAX_KPENT]; | 106 | unsigned short current_keys[KBC_MAX_KPENT]; |
84 | unsigned int num_pressed_keys; | 107 | unsigned int num_pressed_keys; |
@@ -87,147 +110,6 @@ struct tegra_kbc { | |||
87 | struct clk *clk; | 110 | struct clk *clk; |
88 | }; | 111 | }; |
89 | 112 | ||
90 | static const u32 tegra_kbc_default_keymap[] = { | ||
91 | KEY(0, 2, KEY_W), | ||
92 | KEY(0, 3, KEY_S), | ||
93 | KEY(0, 4, KEY_A), | ||
94 | KEY(0, 5, KEY_Z), | ||
95 | KEY(0, 7, KEY_FN), | ||
96 | |||
97 | KEY(1, 7, KEY_LEFTMETA), | ||
98 | |||
99 | KEY(2, 6, KEY_RIGHTALT), | ||
100 | KEY(2, 7, KEY_LEFTALT), | ||
101 | |||
102 | KEY(3, 0, KEY_5), | ||
103 | KEY(3, 1, KEY_4), | ||
104 | KEY(3, 2, KEY_R), | ||
105 | KEY(3, 3, KEY_E), | ||
106 | KEY(3, 4, KEY_F), | ||
107 | KEY(3, 5, KEY_D), | ||
108 | KEY(3, 6, KEY_X), | ||
109 | |||
110 | KEY(4, 0, KEY_7), | ||
111 | KEY(4, 1, KEY_6), | ||
112 | KEY(4, 2, KEY_T), | ||
113 | KEY(4, 3, KEY_H), | ||
114 | KEY(4, 4, KEY_G), | ||
115 | KEY(4, 5, KEY_V), | ||
116 | KEY(4, 6, KEY_C), | ||
117 | KEY(4, 7, KEY_SPACE), | ||
118 | |||
119 | KEY(5, 0, KEY_9), | ||
120 | KEY(5, 1, KEY_8), | ||
121 | KEY(5, 2, KEY_U), | ||
122 | KEY(5, 3, KEY_Y), | ||
123 | KEY(5, 4, KEY_J), | ||
124 | KEY(5, 5, KEY_N), | ||
125 | KEY(5, 6, KEY_B), | ||
126 | KEY(5, 7, KEY_BACKSLASH), | ||
127 | |||
128 | KEY(6, 0, KEY_MINUS), | ||
129 | KEY(6, 1, KEY_0), | ||
130 | KEY(6, 2, KEY_O), | ||
131 | KEY(6, 3, KEY_I), | ||
132 | KEY(6, 4, KEY_L), | ||
133 | KEY(6, 5, KEY_K), | ||
134 | KEY(6, 6, KEY_COMMA), | ||
135 | KEY(6, 7, KEY_M), | ||
136 | |||
137 | KEY(7, 1, KEY_EQUAL), | ||
138 | KEY(7, 2, KEY_RIGHTBRACE), | ||
139 | KEY(7, 3, KEY_ENTER), | ||
140 | KEY(7, 7, KEY_MENU), | ||
141 | |||
142 | KEY(8, 4, KEY_RIGHTSHIFT), | ||
143 | KEY(8, 5, KEY_LEFTSHIFT), | ||
144 | |||
145 | KEY(9, 5, KEY_RIGHTCTRL), | ||
146 | KEY(9, 7, KEY_LEFTCTRL), | ||
147 | |||
148 | KEY(11, 0, KEY_LEFTBRACE), | ||
149 | KEY(11, 1, KEY_P), | ||
150 | KEY(11, 2, KEY_APOSTROPHE), | ||
151 | KEY(11, 3, KEY_SEMICOLON), | ||
152 | KEY(11, 4, KEY_SLASH), | ||
153 | KEY(11, 5, KEY_DOT), | ||
154 | |||
155 | KEY(12, 0, KEY_F10), | ||
156 | KEY(12, 1, KEY_F9), | ||
157 | KEY(12, 2, KEY_BACKSPACE), | ||
158 | KEY(12, 3, KEY_3), | ||
159 | KEY(12, 4, KEY_2), | ||
160 | KEY(12, 5, KEY_UP), | ||
161 | KEY(12, 6, KEY_PRINT), | ||
162 | KEY(12, 7, KEY_PAUSE), | ||
163 | |||
164 | KEY(13, 0, KEY_INSERT), | ||
165 | KEY(13, 1, KEY_DELETE), | ||
166 | KEY(13, 3, KEY_PAGEUP), | ||
167 | KEY(13, 4, KEY_PAGEDOWN), | ||
168 | KEY(13, 5, KEY_RIGHT), | ||
169 | KEY(13, 6, KEY_DOWN), | ||
170 | KEY(13, 7, KEY_LEFT), | ||
171 | |||
172 | KEY(14, 0, KEY_F11), | ||
173 | KEY(14, 1, KEY_F12), | ||
174 | KEY(14, 2, KEY_F8), | ||
175 | KEY(14, 3, KEY_Q), | ||
176 | KEY(14, 4, KEY_F4), | ||
177 | KEY(14, 5, KEY_F3), | ||
178 | KEY(14, 6, KEY_1), | ||
179 | KEY(14, 7, KEY_F7), | ||
180 | |||
181 | KEY(15, 0, KEY_ESC), | ||
182 | KEY(15, 1, KEY_GRAVE), | ||
183 | KEY(15, 2, KEY_F5), | ||
184 | KEY(15, 3, KEY_TAB), | ||
185 | KEY(15, 4, KEY_F1), | ||
186 | KEY(15, 5, KEY_F2), | ||
187 | KEY(15, 6, KEY_CAPSLOCK), | ||
188 | KEY(15, 7, KEY_F6), | ||
189 | |||
190 | /* Software Handled Function Keys */ | ||
191 | KEY(20, 0, KEY_KP7), | ||
192 | |||
193 | KEY(21, 0, KEY_KP9), | ||
194 | KEY(21, 1, KEY_KP8), | ||
195 | KEY(21, 2, KEY_KP4), | ||
196 | KEY(21, 4, KEY_KP1), | ||
197 | |||
198 | KEY(22, 1, KEY_KPSLASH), | ||
199 | KEY(22, 2, KEY_KP6), | ||
200 | KEY(22, 3, KEY_KP5), | ||
201 | KEY(22, 4, KEY_KP3), | ||
202 | KEY(22, 5, KEY_KP2), | ||
203 | KEY(22, 7, KEY_KP0), | ||
204 | |||
205 | KEY(27, 1, KEY_KPASTERISK), | ||
206 | KEY(27, 3, KEY_KPMINUS), | ||
207 | KEY(27, 4, KEY_KPPLUS), | ||
208 | KEY(27, 5, KEY_KPDOT), | ||
209 | |||
210 | KEY(28, 5, KEY_VOLUMEUP), | ||
211 | |||
212 | KEY(29, 3, KEY_HOME), | ||
213 | KEY(29, 4, KEY_END), | ||
214 | KEY(29, 5, KEY_BRIGHTNESSDOWN), | ||
215 | KEY(29, 6, KEY_VOLUMEDOWN), | ||
216 | KEY(29, 7, KEY_BRIGHTNESSUP), | ||
217 | |||
218 | KEY(30, 0, KEY_NUMLOCK), | ||
219 | KEY(30, 1, KEY_SCROLLLOCK), | ||
220 | KEY(30, 2, KEY_MUTE), | ||
221 | |||
222 | KEY(31, 4, KEY_HELP), | ||
223 | }; | ||
224 | |||
225 | static const | ||
226 | struct matrix_keymap_data tegra_kbc_default_keymap_data = { | ||
227 | .keymap = tegra_kbc_default_keymap, | ||
228 | .keymap_size = ARRAY_SIZE(tegra_kbc_default_keymap), | ||
229 | }; | ||
230 | |||
231 | static void tegra_kbc_report_released_keys(struct input_dev *input, | 113 | static void tegra_kbc_report_released_keys(struct input_dev *input, |
232 | unsigned short old_keycodes[], | 114 | unsigned short old_keycodes[], |
233 | unsigned int old_num_keys, | 115 | unsigned int old_num_keys, |
@@ -357,18 +239,6 @@ static void tegra_kbc_set_fifo_interrupt(struct tegra_kbc *kbc, bool enable) | |||
357 | writel(val, kbc->mmio + KBC_CONTROL_0); | 239 | writel(val, kbc->mmio + KBC_CONTROL_0); |
358 | } | 240 | } |
359 | 241 | ||
360 | static void tegra_kbc_set_keypress_interrupt(struct tegra_kbc *kbc, bool enable) | ||
361 | { | ||
362 | u32 val; | ||
363 | |||
364 | val = readl(kbc->mmio + KBC_CONTROL_0); | ||
365 | if (enable) | ||
366 | val |= KBC_CONTROL_KEYPRESS_INT_EN; | ||
367 | else | ||
368 | val &= ~KBC_CONTROL_KEYPRESS_INT_EN; | ||
369 | writel(val, kbc->mmio + KBC_CONTROL_0); | ||
370 | } | ||
371 | |||
372 | static void tegra_kbc_keypress_timer(unsigned long data) | 242 | static void tegra_kbc_keypress_timer(unsigned long data) |
373 | { | 243 | { |
374 | struct tegra_kbc *kbc = (struct tegra_kbc *)data; | 244 | struct tegra_kbc *kbc = (struct tegra_kbc *)data; |
@@ -439,12 +309,11 @@ static irqreturn_t tegra_kbc_isr(int irq, void *args) | |||
439 | 309 | ||
440 | static void tegra_kbc_setup_wakekeys(struct tegra_kbc *kbc, bool filter) | 310 | static void tegra_kbc_setup_wakekeys(struct tegra_kbc *kbc, bool filter) |
441 | { | 311 | { |
442 | const struct tegra_kbc_platform_data *pdata = kbc->pdata; | ||
443 | int i; | 312 | int i; |
444 | unsigned int rst_val; | 313 | unsigned int rst_val; |
445 | 314 | ||
446 | /* Either mask all keys or none. */ | 315 | /* Either mask all keys or none. */ |
447 | rst_val = (filter && !pdata->wakeup) ? ~0 : 0; | 316 | rst_val = (filter && !kbc->wakeup) ? ~0 : 0; |
448 | 317 | ||
449 | for (i = 0; i < KBC_MAX_ROW; i++) | 318 | for (i = 0; i < KBC_MAX_ROW; i++) |
450 | writel(rst_val, kbc->mmio + KBC_ROW0_MASK_0 + i * 4); | 319 | writel(rst_val, kbc->mmio + KBC_ROW0_MASK_0 + i * 4); |
@@ -452,7 +321,6 @@ static void tegra_kbc_setup_wakekeys(struct tegra_kbc *kbc, bool filter) | |||
452 | 321 | ||
453 | static void tegra_kbc_config_pins(struct tegra_kbc *kbc) | 322 | static void tegra_kbc_config_pins(struct tegra_kbc *kbc) |
454 | { | 323 | { |
455 | const struct tegra_kbc_platform_data *pdata = kbc->pdata; | ||
456 | int i; | 324 | int i; |
457 | 325 | ||
458 | for (i = 0; i < KBC_MAX_GPIO; i++) { | 326 | for (i = 0; i < KBC_MAX_GPIO; i++) { |
@@ -468,13 +336,13 @@ static void tegra_kbc_config_pins(struct tegra_kbc *kbc) | |||
468 | row_cfg &= ~r_mask; | 336 | row_cfg &= ~r_mask; |
469 | col_cfg &= ~c_mask; | 337 | col_cfg &= ~c_mask; |
470 | 338 | ||
471 | switch (pdata->pin_cfg[i].type) { | 339 | switch (kbc->pin_cfg[i].type) { |
472 | case PIN_CFG_ROW: | 340 | case PIN_CFG_ROW: |
473 | row_cfg |= ((pdata->pin_cfg[i].num << 1) | 1) << r_shft; | 341 | row_cfg |= ((kbc->pin_cfg[i].num << 1) | 1) << r_shft; |
474 | break; | 342 | break; |
475 | 343 | ||
476 | case PIN_CFG_COL: | 344 | case PIN_CFG_COL: |
477 | col_cfg |= ((pdata->pin_cfg[i].num << 1) | 1) << c_shft; | 345 | col_cfg |= ((kbc->pin_cfg[i].num << 1) | 1) << c_shft; |
478 | break; | 346 | break; |
479 | 347 | ||
480 | case PIN_CFG_IGNORE: | 348 | case PIN_CFG_IGNORE: |
@@ -488,7 +356,6 @@ static void tegra_kbc_config_pins(struct tegra_kbc *kbc) | |||
488 | 356 | ||
489 | static int tegra_kbc_start(struct tegra_kbc *kbc) | 357 | static int tegra_kbc_start(struct tegra_kbc *kbc) |
490 | { | 358 | { |
491 | const struct tegra_kbc_platform_data *pdata = kbc->pdata; | ||
492 | unsigned int debounce_cnt; | 359 | unsigned int debounce_cnt; |
493 | u32 val = 0; | 360 | u32 val = 0; |
494 | 361 | ||
@@ -503,10 +370,10 @@ static int tegra_kbc_start(struct tegra_kbc *kbc) | |||
503 | tegra_kbc_config_pins(kbc); | 370 | tegra_kbc_config_pins(kbc); |
504 | tegra_kbc_setup_wakekeys(kbc, false); | 371 | tegra_kbc_setup_wakekeys(kbc, false); |
505 | 372 | ||
506 | writel(pdata->repeat_cnt, kbc->mmio + KBC_RPT_DLY_0); | 373 | writel(kbc->repeat_cnt, kbc->mmio + KBC_RPT_DLY_0); |
507 | 374 | ||
508 | /* Keyboard debounce count is maximum of 12 bits. */ | 375 | /* Keyboard debounce count is maximum of 12 bits. */ |
509 | debounce_cnt = min(pdata->debounce_cnt, KBC_MAX_DEBOUNCE_CNT); | 376 | debounce_cnt = min(kbc->debounce_cnt, KBC_MAX_DEBOUNCE_CNT); |
510 | val = KBC_DEBOUNCE_CNT_SHIFT(debounce_cnt); | 377 | val = KBC_DEBOUNCE_CNT_SHIFT(debounce_cnt); |
511 | val |= KBC_FIFO_TH_CNT_SHIFT(1); /* set fifo interrupt threshold to 1 */ | 378 | val |= KBC_FIFO_TH_CNT_SHIFT(1); /* set fifo interrupt threshold to 1 */ |
512 | val |= KBC_CONTROL_FIFO_CNT_INT_EN; /* interrupt on FIFO threshold */ | 379 | val |= KBC_CONTROL_FIFO_CNT_INT_EN; /* interrupt on FIFO threshold */ |
@@ -573,21 +440,20 @@ static void tegra_kbc_close(struct input_dev *dev) | |||
573 | return tegra_kbc_stop(kbc); | 440 | return tegra_kbc_stop(kbc); |
574 | } | 441 | } |
575 | 442 | ||
576 | static bool | 443 | static bool tegra_kbc_check_pin_cfg(const struct tegra_kbc *kbc, |
577 | tegra_kbc_check_pin_cfg(const struct tegra_kbc_platform_data *pdata, | 444 | unsigned int *num_rows) |
578 | struct device *dev, unsigned int *num_rows) | ||
579 | { | 445 | { |
580 | int i; | 446 | int i; |
581 | 447 | ||
582 | *num_rows = 0; | 448 | *num_rows = 0; |
583 | 449 | ||
584 | for (i = 0; i < KBC_MAX_GPIO; i++) { | 450 | for (i = 0; i < KBC_MAX_GPIO; i++) { |
585 | const struct tegra_kbc_pin_cfg *pin_cfg = &pdata->pin_cfg[i]; | 451 | const struct tegra_kbc_pin_cfg *pin_cfg = &kbc->pin_cfg[i]; |
586 | 452 | ||
587 | switch (pin_cfg->type) { | 453 | switch (pin_cfg->type) { |
588 | case PIN_CFG_ROW: | 454 | case PIN_CFG_ROW: |
589 | if (pin_cfg->num >= KBC_MAX_ROW) { | 455 | if (pin_cfg->num >= KBC_MAX_ROW) { |
590 | dev_err(dev, | 456 | dev_err(kbc->dev, |
591 | "pin_cfg[%d]: invalid row number %d\n", | 457 | "pin_cfg[%d]: invalid row number %d\n", |
592 | i, pin_cfg->num); | 458 | i, pin_cfg->num); |
593 | return false; | 459 | return false; |
@@ -597,7 +463,7 @@ tegra_kbc_check_pin_cfg(const struct tegra_kbc_platform_data *pdata, | |||
597 | 463 | ||
598 | case PIN_CFG_COL: | 464 | case PIN_CFG_COL: |
599 | if (pin_cfg->num >= KBC_MAX_COL) { | 465 | if (pin_cfg->num >= KBC_MAX_COL) { |
600 | dev_err(dev, | 466 | dev_err(kbc->dev, |
601 | "pin_cfg[%d]: invalid column number %d\n", | 467 | "pin_cfg[%d]: invalid column number %d\n", |
602 | i, pin_cfg->num); | 468 | i, pin_cfg->num); |
603 | return false; | 469 | return false; |
@@ -608,7 +474,7 @@ tegra_kbc_check_pin_cfg(const struct tegra_kbc_platform_data *pdata, | |||
608 | break; | 474 | break; |
609 | 475 | ||
610 | default: | 476 | default: |
611 | dev_err(dev, | 477 | dev_err(kbc->dev, |
612 | "pin_cfg[%d]: invalid entry type %d\n", | 478 | "pin_cfg[%d]: invalid entry type %d\n", |
613 | pin_cfg->type, pin_cfg->num); | 479 | pin_cfg->type, pin_cfg->num); |
614 | return false; | 480 | return false; |
@@ -618,154 +484,140 @@ tegra_kbc_check_pin_cfg(const struct tegra_kbc_platform_data *pdata, | |||
618 | return true; | 484 | return true; |
619 | } | 485 | } |
620 | 486 | ||
621 | #ifdef CONFIG_OF | 487 | static int tegra_kbc_parse_dt(struct tegra_kbc *kbc) |
622 | static struct tegra_kbc_platform_data *tegra_kbc_dt_parse_pdata( | ||
623 | struct platform_device *pdev) | ||
624 | { | 488 | { |
625 | struct tegra_kbc_platform_data *pdata; | 489 | struct device_node *np = kbc->dev->of_node; |
626 | struct device_node *np = pdev->dev.of_node; | ||
627 | u32 prop; | 490 | u32 prop; |
628 | int i; | 491 | int i; |
629 | 492 | u32 num_rows = 0; | |
630 | if (!np) | 493 | u32 num_cols = 0; |
631 | return NULL; | 494 | u32 cols_cfg[KBC_MAX_GPIO]; |
632 | 495 | u32 rows_cfg[KBC_MAX_GPIO]; | |
633 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); | 496 | int proplen; |
634 | if (!pdata) | 497 | int ret; |
635 | return NULL; | ||
636 | 498 | ||
637 | if (!of_property_read_u32(np, "nvidia,debounce-delay-ms", &prop)) | 499 | if (!of_property_read_u32(np, "nvidia,debounce-delay-ms", &prop)) |
638 | pdata->debounce_cnt = prop; | 500 | kbc->debounce_cnt = prop; |
639 | 501 | ||
640 | if (!of_property_read_u32(np, "nvidia,repeat-delay-ms", &prop)) | 502 | if (!of_property_read_u32(np, "nvidia,repeat-delay-ms", &prop)) |
641 | pdata->repeat_cnt = prop; | 503 | kbc->repeat_cnt = prop; |
642 | 504 | ||
643 | if (of_find_property(np, "nvidia,needs-ghost-filter", NULL)) | 505 | if (of_find_property(np, "nvidia,needs-ghost-filter", NULL)) |
644 | pdata->use_ghost_filter = true; | 506 | kbc->use_ghost_filter = true; |
645 | 507 | ||
646 | if (of_find_property(np, "nvidia,wakeup-source", NULL)) | 508 | if (of_find_property(np, "nvidia,wakeup-source", NULL)) |
647 | pdata->wakeup = true; | 509 | kbc->wakeup = true; |
648 | 510 | ||
649 | /* | 511 | if (!of_get_property(np, "nvidia,kbc-row-pins", &proplen)) { |
650 | * All currently known keymaps with device tree support use the same | 512 | dev_err(kbc->dev, "property nvidia,kbc-row-pins not found\n"); |
651 | * pin_cfg, so set it up here. | 513 | return -ENOENT; |
652 | */ | ||
653 | for (i = 0; i < KBC_MAX_ROW; i++) { | ||
654 | pdata->pin_cfg[i].num = i; | ||
655 | pdata->pin_cfg[i].type = PIN_CFG_ROW; | ||
656 | } | 514 | } |
515 | num_rows = proplen / sizeof(u32); | ||
657 | 516 | ||
658 | for (i = 0; i < KBC_MAX_COL; i++) { | 517 | if (!of_get_property(np, "nvidia,kbc-col-pins", &proplen)) { |
659 | pdata->pin_cfg[KBC_MAX_ROW + i].num = i; | 518 | dev_err(kbc->dev, "property nvidia,kbc-col-pins not found\n"); |
660 | pdata->pin_cfg[KBC_MAX_ROW + i].type = PIN_CFG_COL; | 519 | return -ENOENT; |
661 | } | 520 | } |
521 | num_cols = proplen / sizeof(u32); | ||
662 | 522 | ||
663 | return pdata; | 523 | if (!of_get_property(np, "linux,keymap", &proplen)) { |
664 | } | 524 | dev_err(kbc->dev, "property linux,keymap not found\n"); |
665 | #else | 525 | return -ENOENT; |
666 | static inline struct tegra_kbc_platform_data *tegra_kbc_dt_parse_pdata( | 526 | } |
667 | struct platform_device *pdev) | ||
668 | { | ||
669 | return NULL; | ||
670 | } | ||
671 | #endif | ||
672 | 527 | ||
673 | static int tegra_kbd_setup_keymap(struct tegra_kbc *kbc) | 528 | if (!num_rows || !num_cols || ((num_rows + num_cols) > KBC_MAX_GPIO)) { |
674 | { | 529 | dev_err(kbc->dev, |
675 | const struct tegra_kbc_platform_data *pdata = kbc->pdata; | 530 | "keypad rows/columns not porperly specified\n"); |
676 | const struct matrix_keymap_data *keymap_data = pdata->keymap_data; | 531 | return -EINVAL; |
677 | unsigned int keymap_rows = KBC_MAX_KEY; | 532 | } |
678 | int retval; | ||
679 | 533 | ||
680 | if (keymap_data && pdata->use_fn_map) | 534 | /* Set all pins as non-configured */ |
681 | keymap_rows *= 2; | 535 | for (i = 0; i < KBC_MAX_GPIO; i++) |
536 | kbc->pin_cfg[i].type = PIN_CFG_IGNORE; | ||
682 | 537 | ||
683 | retval = matrix_keypad_build_keymap(keymap_data, NULL, | 538 | ret = of_property_read_u32_array(np, "nvidia,kbc-row-pins", |
684 | keymap_rows, KBC_MAX_COL, | 539 | rows_cfg, num_rows); |
685 | kbc->keycode, kbc->idev); | 540 | if (ret < 0) { |
686 | if (retval == -ENOSYS || retval == -ENOENT) { | 541 | dev_err(kbc->dev, "Rows configurations are not proper\n"); |
687 | /* | 542 | return -EINVAL; |
688 | * If there is no OF support in kernel or keymap | 543 | } |
689 | * property is missing, use default keymap. | 544 | |
690 | */ | 545 | ret = of_property_read_u32_array(np, "nvidia,kbc-col-pins", |
691 | retval = matrix_keypad_build_keymap( | 546 | cols_cfg, num_cols); |
692 | &tegra_kbc_default_keymap_data, NULL, | 547 | if (ret < 0) { |
693 | keymap_rows, KBC_MAX_COL, | 548 | dev_err(kbc->dev, "Cols configurations are not proper\n"); |
694 | kbc->keycode, kbc->idev); | 549 | return -EINVAL; |
550 | } | ||
551 | |||
552 | for (i = 0; i < num_rows; i++) { | ||
553 | kbc->pin_cfg[rows_cfg[i]].type = PIN_CFG_ROW; | ||
554 | kbc->pin_cfg[rows_cfg[i]].num = i; | ||
695 | } | 555 | } |
696 | 556 | ||
697 | return retval; | 557 | for (i = 0; i < num_cols; i++) { |
558 | kbc->pin_cfg[cols_cfg[i]].type = PIN_CFG_COL; | ||
559 | kbc->pin_cfg[cols_cfg[i]].num = i; | ||
560 | } | ||
561 | |||
562 | return 0; | ||
698 | } | 563 | } |
699 | 564 | ||
700 | static int tegra_kbc_probe(struct platform_device *pdev) | 565 | static int tegra_kbc_probe(struct platform_device *pdev) |
701 | { | 566 | { |
702 | const struct tegra_kbc_platform_data *pdata = pdev->dev.platform_data; | ||
703 | struct tegra_kbc *kbc; | 567 | struct tegra_kbc *kbc; |
704 | struct input_dev *input_dev; | ||
705 | struct resource *res; | 568 | struct resource *res; |
706 | int irq; | ||
707 | int err; | 569 | int err; |
708 | int num_rows = 0; | 570 | int num_rows = 0; |
709 | unsigned int debounce_cnt; | 571 | unsigned int debounce_cnt; |
710 | unsigned int scan_time_rows; | 572 | unsigned int scan_time_rows; |
573 | unsigned int keymap_rows = KBC_MAX_KEY; | ||
711 | 574 | ||
712 | if (!pdata) | 575 | kbc = devm_kzalloc(&pdev->dev, sizeof(*kbc), GFP_KERNEL); |
713 | pdata = tegra_kbc_dt_parse_pdata(pdev); | 576 | if (!kbc) { |
577 | dev_err(&pdev->dev, "failed to alloc memory for kbc\n"); | ||
578 | return -ENOMEM; | ||
579 | } | ||
714 | 580 | ||
715 | if (!pdata) | 581 | kbc->dev = &pdev->dev; |
716 | return -EINVAL; | 582 | spin_lock_init(&kbc->lock); |
717 | 583 | ||
718 | if (!tegra_kbc_check_pin_cfg(pdata, &pdev->dev, &num_rows)) { | 584 | err = tegra_kbc_parse_dt(kbc); |
719 | err = -EINVAL; | 585 | if (err) |
720 | goto err_free_pdata; | 586 | return err; |
721 | } | 587 | |
588 | if (!tegra_kbc_check_pin_cfg(kbc, &num_rows)) | ||
589 | return -EINVAL; | ||
722 | 590 | ||
723 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 591 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
724 | if (!res) { | 592 | if (!res) { |
725 | dev_err(&pdev->dev, "failed to get I/O memory\n"); | 593 | dev_err(&pdev->dev, "failed to get I/O memory\n"); |
726 | err = -ENXIO; | 594 | return -ENXIO; |
727 | goto err_free_pdata; | ||
728 | } | 595 | } |
729 | 596 | ||
730 | irq = platform_get_irq(pdev, 0); | 597 | kbc->irq = platform_get_irq(pdev, 0); |
731 | if (irq < 0) { | 598 | if (kbc->irq < 0) { |
732 | dev_err(&pdev->dev, "failed to get keyboard IRQ\n"); | 599 | dev_err(&pdev->dev, "failed to get keyboard IRQ\n"); |
733 | err = -ENXIO; | 600 | return -ENXIO; |
734 | goto err_free_pdata; | ||
735 | } | 601 | } |
736 | 602 | ||
737 | kbc = kzalloc(sizeof(*kbc), GFP_KERNEL); | 603 | kbc->idev = devm_input_allocate_device(&pdev->dev); |
738 | input_dev = input_allocate_device(); | 604 | if (!kbc->idev) { |
739 | if (!kbc || !input_dev) { | 605 | dev_err(&pdev->dev, "failed to allocate input device\n"); |
740 | err = -ENOMEM; | 606 | return -ENOMEM; |
741 | goto err_free_mem; | ||
742 | } | 607 | } |
743 | 608 | ||
744 | kbc->pdata = pdata; | ||
745 | kbc->idev = input_dev; | ||
746 | kbc->irq = irq; | ||
747 | spin_lock_init(&kbc->lock); | ||
748 | setup_timer(&kbc->timer, tegra_kbc_keypress_timer, (unsigned long)kbc); | 609 | setup_timer(&kbc->timer, tegra_kbc_keypress_timer, (unsigned long)kbc); |
749 | 610 | ||
750 | res = request_mem_region(res->start, resource_size(res), pdev->name); | 611 | kbc->mmio = devm_request_and_ioremap(&pdev->dev, res); |
751 | if (!res) { | ||
752 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | ||
753 | err = -EBUSY; | ||
754 | goto err_free_mem; | ||
755 | } | ||
756 | |||
757 | kbc->mmio = ioremap(res->start, resource_size(res)); | ||
758 | if (!kbc->mmio) { | 612 | if (!kbc->mmio) { |
759 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | 613 | dev_err(&pdev->dev, "Cannot request memregion/iomap address\n"); |
760 | err = -ENXIO; | 614 | return -EBUSY; |
761 | goto err_free_mem_region; | ||
762 | } | 615 | } |
763 | 616 | ||
764 | kbc->clk = clk_get(&pdev->dev, NULL); | 617 | kbc->clk = devm_clk_get(&pdev->dev, NULL); |
765 | if (IS_ERR(kbc->clk)) { | 618 | if (IS_ERR(kbc->clk)) { |
766 | dev_err(&pdev->dev, "failed to get keyboard clock\n"); | 619 | dev_err(&pdev->dev, "failed to get keyboard clock\n"); |
767 | err = PTR_ERR(kbc->clk); | 620 | return PTR_ERR(kbc->clk); |
768 | goto err_iounmap; | ||
769 | } | 621 | } |
770 | 622 | ||
771 | /* | 623 | /* |
@@ -774,37 +626,38 @@ static int tegra_kbc_probe(struct platform_device *pdev) | |||
774 | * the rows. There is an additional delay before the row scanning | 626 | * the rows. There is an additional delay before the row scanning |
775 | * starts. The repoll delay is computed in milliseconds. | 627 | * starts. The repoll delay is computed in milliseconds. |
776 | */ | 628 | */ |
777 | debounce_cnt = min(pdata->debounce_cnt, KBC_MAX_DEBOUNCE_CNT); | 629 | debounce_cnt = min(kbc->debounce_cnt, KBC_MAX_DEBOUNCE_CNT); |
778 | scan_time_rows = (KBC_ROW_SCAN_TIME + debounce_cnt) * num_rows; | 630 | scan_time_rows = (KBC_ROW_SCAN_TIME + debounce_cnt) * num_rows; |
779 | kbc->repoll_dly = KBC_ROW_SCAN_DLY + scan_time_rows + pdata->repeat_cnt; | 631 | kbc->repoll_dly = KBC_ROW_SCAN_DLY + scan_time_rows + kbc->repeat_cnt; |
780 | kbc->repoll_dly = DIV_ROUND_UP(kbc->repoll_dly, KBC_CYCLE_MS); | 632 | kbc->repoll_dly = DIV_ROUND_UP(kbc->repoll_dly, KBC_CYCLE_MS); |
781 | 633 | ||
782 | kbc->wakeup_key = pdata->wakeup_key; | 634 | kbc->idev->name = pdev->name; |
783 | kbc->use_fn_map = pdata->use_fn_map; | 635 | kbc->idev->id.bustype = BUS_HOST; |
784 | kbc->use_ghost_filter = pdata->use_ghost_filter; | 636 | kbc->idev->dev.parent = &pdev->dev; |
637 | kbc->idev->open = tegra_kbc_open; | ||
638 | kbc->idev->close = tegra_kbc_close; | ||
785 | 639 | ||
786 | input_dev->name = pdev->name; | 640 | if (kbc->keymap_data && kbc->use_fn_map) |
787 | input_dev->id.bustype = BUS_HOST; | 641 | keymap_rows *= 2; |
788 | input_dev->dev.parent = &pdev->dev; | ||
789 | input_dev->open = tegra_kbc_open; | ||
790 | input_dev->close = tegra_kbc_close; | ||
791 | 642 | ||
792 | err = tegra_kbd_setup_keymap(kbc); | 643 | err = matrix_keypad_build_keymap(kbc->keymap_data, NULL, |
644 | keymap_rows, KBC_MAX_COL, | ||
645 | kbc->keycode, kbc->idev); | ||
793 | if (err) { | 646 | if (err) { |
794 | dev_err(&pdev->dev, "failed to setup keymap\n"); | 647 | dev_err(&pdev->dev, "failed to setup keymap\n"); |
795 | goto err_put_clk; | 648 | return err; |
796 | } | 649 | } |
797 | 650 | ||
798 | __set_bit(EV_REP, input_dev->evbit); | 651 | __set_bit(EV_REP, kbc->idev->evbit); |
799 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | 652 | input_set_capability(kbc->idev, EV_MSC, MSC_SCAN); |
800 | 653 | ||
801 | input_set_drvdata(input_dev, kbc); | 654 | input_set_drvdata(kbc->idev, kbc); |
802 | 655 | ||
803 | err = request_irq(kbc->irq, tegra_kbc_isr, | 656 | err = devm_request_irq(&pdev->dev, kbc->irq, tegra_kbc_isr, |
804 | IRQF_NO_SUSPEND | IRQF_TRIGGER_HIGH, pdev->name, kbc); | 657 | IRQF_NO_SUSPEND | IRQF_TRIGGER_HIGH, pdev->name, kbc); |
805 | if (err) { | 658 | if (err) { |
806 | dev_err(&pdev->dev, "failed to request keyboard IRQ\n"); | 659 | dev_err(&pdev->dev, "failed to request keyboard IRQ\n"); |
807 | goto err_put_clk; | 660 | return err; |
808 | } | 661 | } |
809 | 662 | ||
810 | disable_irq(kbc->irq); | 663 | disable_irq(kbc->irq); |
@@ -812,60 +665,28 @@ static int tegra_kbc_probe(struct platform_device *pdev) | |||
812 | err = input_register_device(kbc->idev); | 665 | err = input_register_device(kbc->idev); |
813 | if (err) { | 666 | if (err) { |
814 | dev_err(&pdev->dev, "failed to register input device\n"); | 667 | dev_err(&pdev->dev, "failed to register input device\n"); |
815 | goto err_free_irq; | 668 | return err; |
816 | } | 669 | } |
817 | 670 | ||
818 | platform_set_drvdata(pdev, kbc); | 671 | platform_set_drvdata(pdev, kbc); |
819 | device_init_wakeup(&pdev->dev, pdata->wakeup); | 672 | device_init_wakeup(&pdev->dev, kbc->wakeup); |
820 | 673 | ||
821 | return 0; | 674 | return 0; |
822 | |||
823 | err_free_irq: | ||
824 | free_irq(kbc->irq, pdev); | ||
825 | err_put_clk: | ||
826 | clk_put(kbc->clk); | ||
827 | err_iounmap: | ||
828 | iounmap(kbc->mmio); | ||
829 | err_free_mem_region: | ||
830 | release_mem_region(res->start, resource_size(res)); | ||
831 | err_free_mem: | ||
832 | input_free_device(input_dev); | ||
833 | kfree(kbc); | ||
834 | err_free_pdata: | ||
835 | if (!pdev->dev.platform_data) | ||
836 | kfree(pdata); | ||
837 | |||
838 | return err; | ||
839 | } | 675 | } |
840 | 676 | ||
841 | static int tegra_kbc_remove(struct platform_device *pdev) | 677 | #ifdef CONFIG_PM_SLEEP |
678 | static void tegra_kbc_set_keypress_interrupt(struct tegra_kbc *kbc, bool enable) | ||
842 | { | 679 | { |
843 | struct tegra_kbc *kbc = platform_get_drvdata(pdev); | 680 | u32 val; |
844 | struct resource *res; | ||
845 | |||
846 | platform_set_drvdata(pdev, NULL); | ||
847 | |||
848 | free_irq(kbc->irq, pdev); | ||
849 | clk_put(kbc->clk); | ||
850 | |||
851 | input_unregister_device(kbc->idev); | ||
852 | iounmap(kbc->mmio); | ||
853 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
854 | release_mem_region(res->start, resource_size(res)); | ||
855 | |||
856 | /* | ||
857 | * If we do not have platform data attached to the device we | ||
858 | * allocated it ourselves and thus need to free it. | ||
859 | */ | ||
860 | if (!pdev->dev.platform_data) | ||
861 | kfree(kbc->pdata); | ||
862 | |||
863 | kfree(kbc); | ||
864 | 681 | ||
865 | return 0; | 682 | val = readl(kbc->mmio + KBC_CONTROL_0); |
683 | if (enable) | ||
684 | val |= KBC_CONTROL_KEYPRESS_INT_EN; | ||
685 | else | ||
686 | val &= ~KBC_CONTROL_KEYPRESS_INT_EN; | ||
687 | writel(val, kbc->mmio + KBC_CONTROL_0); | ||
866 | } | 688 | } |
867 | 689 | ||
868 | #ifdef CONFIG_PM_SLEEP | ||
869 | static int tegra_kbc_suspend(struct device *dev) | 690 | static int tegra_kbc_suspend(struct device *dev) |
870 | { | 691 | { |
871 | struct platform_device *pdev = to_platform_device(dev); | 692 | struct platform_device *pdev = to_platform_device(dev); |
@@ -954,7 +775,6 @@ MODULE_DEVICE_TABLE(of, tegra_kbc_of_match); | |||
954 | 775 | ||
955 | static struct platform_driver tegra_kbc_driver = { | 776 | static struct platform_driver tegra_kbc_driver = { |
956 | .probe = tegra_kbc_probe, | 777 | .probe = tegra_kbc_probe, |
957 | .remove = tegra_kbc_remove, | ||
958 | .driver = { | 778 | .driver = { |
959 | .name = "tegra-kbc", | 779 | .name = "tegra-kbc", |
960 | .owner = THIS_MODULE, | 780 | .owner = THIS_MODULE, |
diff --git a/drivers/input/misc/adxl34x.c b/drivers/input/misc/adxl34x.c index 1cf72fe513e6..0735de3a6468 100644 --- a/drivers/input/misc/adxl34x.c +++ b/drivers/input/misc/adxl34x.c | |||
@@ -232,7 +232,7 @@ static const struct adxl34x_platform_data adxl34x_default_init = { | |||
232 | 232 | ||
233 | .ev_code_tap = {BTN_TOUCH, BTN_TOUCH, BTN_TOUCH}, /* EV_KEY {x,y,z} */ | 233 | .ev_code_tap = {BTN_TOUCH, BTN_TOUCH, BTN_TOUCH}, /* EV_KEY {x,y,z} */ |
234 | .power_mode = ADXL_AUTO_SLEEP | ADXL_LINK, | 234 | .power_mode = ADXL_AUTO_SLEEP | ADXL_LINK, |
235 | .fifo_mode = FIFO_STREAM, | 235 | .fifo_mode = ADXL_FIFO_STREAM, |
236 | .watermark = 0, | 236 | .watermark = 0, |
237 | }; | 237 | }; |
238 | 238 | ||
@@ -732,7 +732,7 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq, | |||
732 | mutex_init(&ac->mutex); | 732 | mutex_init(&ac->mutex); |
733 | 733 | ||
734 | input_dev->name = "ADXL34x accelerometer"; | 734 | input_dev->name = "ADXL34x accelerometer"; |
735 | revid = ac->bops->read(dev, DEVID); | 735 | revid = AC_READ(ac, DEVID); |
736 | 736 | ||
737 | switch (revid) { | 737 | switch (revid) { |
738 | case ID_ADXL345: | 738 | case ID_ADXL345: |
@@ -809,7 +809,7 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq, | |||
809 | if (FIFO_MODE(pdata->fifo_mode) == FIFO_BYPASS) | 809 | if (FIFO_MODE(pdata->fifo_mode) == FIFO_BYPASS) |
810 | ac->fifo_delay = false; | 810 | ac->fifo_delay = false; |
811 | 811 | ||
812 | ac->bops->write(dev, POWER_CTL, 0); | 812 | AC_WRITE(ac, POWER_CTL, 0); |
813 | 813 | ||
814 | err = request_threaded_irq(ac->irq, NULL, adxl34x_irq, | 814 | err = request_threaded_irq(ac->irq, NULL, adxl34x_irq, |
815 | IRQF_TRIGGER_HIGH | IRQF_ONESHOT, | 815 | IRQF_TRIGGER_HIGH | IRQF_ONESHOT, |
@@ -827,7 +827,6 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq, | |||
827 | if (err) | 827 | if (err) |
828 | goto err_remove_attr; | 828 | goto err_remove_attr; |
829 | 829 | ||
830 | AC_WRITE(ac, THRESH_TAP, pdata->tap_threshold); | ||
831 | AC_WRITE(ac, OFSX, pdata->x_axis_offset); | 830 | AC_WRITE(ac, OFSX, pdata->x_axis_offset); |
832 | ac->hwcal.x = pdata->x_axis_offset; | 831 | ac->hwcal.x = pdata->x_axis_offset; |
833 | AC_WRITE(ac, OFSY, pdata->y_axis_offset); | 832 | AC_WRITE(ac, OFSY, pdata->y_axis_offset); |
diff --git a/drivers/input/misc/bma150.c b/drivers/input/misc/bma150.c index 08ffcabd7220..865c2f9d25b9 100644 --- a/drivers/input/misc/bma150.c +++ b/drivers/input/misc/bma150.c | |||
@@ -46,18 +46,6 @@ | |||
46 | #define BMA150_POLL_MAX 200 | 46 | #define BMA150_POLL_MAX 200 |
47 | #define BMA150_POLL_MIN 0 | 47 | #define BMA150_POLL_MIN 0 |
48 | 48 | ||
49 | #define BMA150_BW_25HZ 0 | ||
50 | #define BMA150_BW_50HZ 1 | ||
51 | #define BMA150_BW_100HZ 2 | ||
52 | #define BMA150_BW_190HZ 3 | ||
53 | #define BMA150_BW_375HZ 4 | ||
54 | #define BMA150_BW_750HZ 5 | ||
55 | #define BMA150_BW_1500HZ 6 | ||
56 | |||
57 | #define BMA150_RANGE_2G 0 | ||
58 | #define BMA150_RANGE_4G 1 | ||
59 | #define BMA150_RANGE_8G 2 | ||
60 | |||
61 | #define BMA150_MODE_NORMAL 0 | 49 | #define BMA150_MODE_NORMAL 0 |
62 | #define BMA150_MODE_SLEEP 2 | 50 | #define BMA150_MODE_SLEEP 2 |
63 | #define BMA150_MODE_WAKE_UP 3 | 51 | #define BMA150_MODE_WAKE_UP 3 |
@@ -372,7 +360,7 @@ static int bma150_open(struct bma150_data *bma150) | |||
372 | int error; | 360 | int error; |
373 | 361 | ||
374 | error = pm_runtime_get_sync(&bma150->client->dev); | 362 | error = pm_runtime_get_sync(&bma150->client->dev); |
375 | if (error && error != -ENOSYS) | 363 | if (error < 0 && error != -ENOSYS) |
376 | return error; | 364 | return error; |
377 | 365 | ||
378 | /* | 366 | /* |
diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c index 78eb6b30580a..68a5f33152a8 100644 --- a/drivers/input/misc/twl4030-vibra.c +++ b/drivers/input/misc/twl4030-vibra.c | |||
@@ -43,7 +43,6 @@ struct vibra_info { | |||
43 | struct device *dev; | 43 | struct device *dev; |
44 | struct input_dev *input_dev; | 44 | struct input_dev *input_dev; |
45 | 45 | ||
46 | struct workqueue_struct *workqueue; | ||
47 | struct work_struct play_work; | 46 | struct work_struct play_work; |
48 | 47 | ||
49 | bool enabled; | 48 | bool enabled; |
@@ -143,19 +142,7 @@ static int vibra_play(struct input_dev *input, void *data, | |||
143 | if (!info->speed) | 142 | if (!info->speed) |
144 | info->speed = effect->u.rumble.weak_magnitude >> 9; | 143 | info->speed = effect->u.rumble.weak_magnitude >> 9; |
145 | info->direction = effect->direction < EFFECT_DIR_180_DEG ? 0 : 1; | 144 | info->direction = effect->direction < EFFECT_DIR_180_DEG ? 0 : 1; |
146 | queue_work(info->workqueue, &info->play_work); | 145 | schedule_work(&info->play_work); |
147 | return 0; | ||
148 | } | ||
149 | |||
150 | static int twl4030_vibra_open(struct input_dev *input) | ||
151 | { | ||
152 | struct vibra_info *info = input_get_drvdata(input); | ||
153 | |||
154 | info->workqueue = create_singlethread_workqueue("vibra"); | ||
155 | if (info->workqueue == NULL) { | ||
156 | dev_err(&input->dev, "couldn't create workqueue\n"); | ||
157 | return -ENOMEM; | ||
158 | } | ||
159 | return 0; | 146 | return 0; |
160 | } | 147 | } |
161 | 148 | ||
@@ -164,9 +151,6 @@ static void twl4030_vibra_close(struct input_dev *input) | |||
164 | struct vibra_info *info = input_get_drvdata(input); | 151 | struct vibra_info *info = input_get_drvdata(input); |
165 | 152 | ||
166 | cancel_work_sync(&info->play_work); | 153 | cancel_work_sync(&info->play_work); |
167 | INIT_WORK(&info->play_work, vibra_play_work); /* cleanup */ | ||
168 | destroy_workqueue(info->workqueue); | ||
169 | info->workqueue = NULL; | ||
170 | 154 | ||
171 | if (info->enabled) | 155 | if (info->enabled) |
172 | vibra_disable(info); | 156 | vibra_disable(info); |
@@ -219,7 +203,7 @@ static int twl4030_vibra_probe(struct platform_device *pdev) | |||
219 | return -EINVAL; | 203 | return -EINVAL; |
220 | } | 204 | } |
221 | 205 | ||
222 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 206 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); |
223 | if (!info) | 207 | if (!info) |
224 | return -ENOMEM; | 208 | return -ENOMEM; |
225 | 209 | ||
@@ -227,11 +211,10 @@ static int twl4030_vibra_probe(struct platform_device *pdev) | |||
227 | info->coexist = twl4030_vibra_check_coexist(pdata, twl4030_core_node); | 211 | info->coexist = twl4030_vibra_check_coexist(pdata, twl4030_core_node); |
228 | INIT_WORK(&info->play_work, vibra_play_work); | 212 | INIT_WORK(&info->play_work, vibra_play_work); |
229 | 213 | ||
230 | info->input_dev = input_allocate_device(); | 214 | info->input_dev = devm_input_allocate_device(&pdev->dev); |
231 | if (info->input_dev == NULL) { | 215 | if (info->input_dev == NULL) { |
232 | dev_err(&pdev->dev, "couldn't allocate input device\n"); | 216 | dev_err(&pdev->dev, "couldn't allocate input device\n"); |
233 | ret = -ENOMEM; | 217 | return -ENOMEM; |
234 | goto err_kzalloc; | ||
235 | } | 218 | } |
236 | 219 | ||
237 | input_set_drvdata(info->input_dev, info); | 220 | input_set_drvdata(info->input_dev, info); |
@@ -239,14 +222,13 @@ static int twl4030_vibra_probe(struct platform_device *pdev) | |||
239 | info->input_dev->name = "twl4030:vibrator"; | 222 | info->input_dev->name = "twl4030:vibrator"; |
240 | info->input_dev->id.version = 1; | 223 | info->input_dev->id.version = 1; |
241 | info->input_dev->dev.parent = pdev->dev.parent; | 224 | info->input_dev->dev.parent = pdev->dev.parent; |
242 | info->input_dev->open = twl4030_vibra_open; | ||
243 | info->input_dev->close = twl4030_vibra_close; | 225 | info->input_dev->close = twl4030_vibra_close; |
244 | __set_bit(FF_RUMBLE, info->input_dev->ffbit); | 226 | __set_bit(FF_RUMBLE, info->input_dev->ffbit); |
245 | 227 | ||
246 | ret = input_ff_create_memless(info->input_dev, NULL, vibra_play); | 228 | ret = input_ff_create_memless(info->input_dev, NULL, vibra_play); |
247 | if (ret < 0) { | 229 | if (ret < 0) { |
248 | dev_dbg(&pdev->dev, "couldn't register vibrator to FF\n"); | 230 | dev_dbg(&pdev->dev, "couldn't register vibrator to FF\n"); |
249 | goto err_ialloc; | 231 | return ret; |
250 | } | 232 | } |
251 | 233 | ||
252 | ret = input_register_device(info->input_dev); | 234 | ret = input_register_device(info->input_dev); |
@@ -262,28 +244,11 @@ static int twl4030_vibra_probe(struct platform_device *pdev) | |||
262 | 244 | ||
263 | err_iff: | 245 | err_iff: |
264 | input_ff_destroy(info->input_dev); | 246 | input_ff_destroy(info->input_dev); |
265 | err_ialloc: | ||
266 | input_free_device(info->input_dev); | ||
267 | err_kzalloc: | ||
268 | kfree(info); | ||
269 | return ret; | 247 | return ret; |
270 | } | 248 | } |
271 | 249 | ||
272 | static int twl4030_vibra_remove(struct platform_device *pdev) | ||
273 | { | ||
274 | struct vibra_info *info = platform_get_drvdata(pdev); | ||
275 | |||
276 | /* this also free ff-memless and calls close if needed */ | ||
277 | input_unregister_device(info->input_dev); | ||
278 | kfree(info); | ||
279 | platform_set_drvdata(pdev, NULL); | ||
280 | |||
281 | return 0; | ||
282 | } | ||
283 | |||
284 | static struct platform_driver twl4030_vibra_driver = { | 250 | static struct platform_driver twl4030_vibra_driver = { |
285 | .probe = twl4030_vibra_probe, | 251 | .probe = twl4030_vibra_probe, |
286 | .remove = twl4030_vibra_remove, | ||
287 | .driver = { | 252 | .driver = { |
288 | .name = "twl4030-vibra", | 253 | .name = "twl4030-vibra", |
289 | .owner = THIS_MODULE, | 254 | .owner = THIS_MODULE, |
diff --git a/drivers/input/misc/twl6040-vibra.c b/drivers/input/misc/twl6040-vibra.c index 71a28ee699f3..0c2dfc8e9691 100644 --- a/drivers/input/misc/twl6040-vibra.c +++ b/drivers/input/misc/twl6040-vibra.c | |||
@@ -275,7 +275,7 @@ static int twl6040_vibra_probe(struct platform_device *pdev) | |||
275 | return -EINVAL; | 275 | return -EINVAL; |
276 | } | 276 | } |
277 | 277 | ||
278 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 278 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); |
279 | if (!info) { | 279 | if (!info) { |
280 | dev_err(&pdev->dev, "couldn't allocate memory\n"); | 280 | dev_err(&pdev->dev, "couldn't allocate memory\n"); |
281 | return -ENOMEM; | 281 | return -ENOMEM; |
@@ -309,53 +309,23 @@ static int twl6040_vibra_probe(struct platform_device *pdev) | |||
309 | if ((!info->vibldrv_res && !info->viblmotor_res) || | 309 | if ((!info->vibldrv_res && !info->viblmotor_res) || |
310 | (!info->vibrdrv_res && !info->vibrmotor_res)) { | 310 | (!info->vibrdrv_res && !info->vibrmotor_res)) { |
311 | dev_err(info->dev, "invalid vibra driver/motor resistance\n"); | 311 | dev_err(info->dev, "invalid vibra driver/motor resistance\n"); |
312 | ret = -EINVAL; | 312 | return -EINVAL; |
313 | goto err_kzalloc; | ||
314 | } | 313 | } |
315 | 314 | ||
316 | info->irq = platform_get_irq(pdev, 0); | 315 | info->irq = platform_get_irq(pdev, 0); |
317 | if (info->irq < 0) { | 316 | if (info->irq < 0) { |
318 | dev_err(info->dev, "invalid irq\n"); | 317 | dev_err(info->dev, "invalid irq\n"); |
319 | ret = -EINVAL; | 318 | return -EINVAL; |
320 | goto err_kzalloc; | ||
321 | } | 319 | } |
322 | 320 | ||
323 | mutex_init(&info->mutex); | 321 | mutex_init(&info->mutex); |
324 | 322 | ||
325 | info->input_dev = input_allocate_device(); | 323 | ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL, |
326 | if (info->input_dev == NULL) { | 324 | twl6040_vib_irq_handler, 0, |
327 | dev_err(info->dev, "couldn't allocate input device\n"); | 325 | "twl6040_irq_vib", info); |
328 | ret = -ENOMEM; | ||
329 | goto err_kzalloc; | ||
330 | } | ||
331 | |||
332 | input_set_drvdata(info->input_dev, info); | ||
333 | |||
334 | info->input_dev->name = "twl6040:vibrator"; | ||
335 | info->input_dev->id.version = 1; | ||
336 | info->input_dev->dev.parent = pdev->dev.parent; | ||
337 | info->input_dev->close = twl6040_vibra_close; | ||
338 | __set_bit(FF_RUMBLE, info->input_dev->ffbit); | ||
339 | |||
340 | ret = input_ff_create_memless(info->input_dev, NULL, vibra_play); | ||
341 | if (ret < 0) { | ||
342 | dev_err(info->dev, "couldn't register vibrator to FF\n"); | ||
343 | goto err_ialloc; | ||
344 | } | ||
345 | |||
346 | ret = input_register_device(info->input_dev); | ||
347 | if (ret < 0) { | ||
348 | dev_err(info->dev, "couldn't register input device\n"); | ||
349 | goto err_iff; | ||
350 | } | ||
351 | |||
352 | platform_set_drvdata(pdev, info); | ||
353 | |||
354 | ret = request_threaded_irq(info->irq, NULL, twl6040_vib_irq_handler, 0, | ||
355 | "twl6040_irq_vib", info); | ||
356 | if (ret) { | 326 | if (ret) { |
357 | dev_err(info->dev, "VIB IRQ request failed: %d\n", ret); | 327 | dev_err(info->dev, "VIB IRQ request failed: %d\n", ret); |
358 | goto err_irq; | 328 | return ret; |
359 | } | 329 | } |
360 | 330 | ||
361 | info->supplies[0].supply = "vddvibl"; | 331 | info->supplies[0].supply = "vddvibl"; |
@@ -368,7 +338,7 @@ static int twl6040_vibra_probe(struct platform_device *pdev) | |||
368 | ARRAY_SIZE(info->supplies), info->supplies); | 338 | ARRAY_SIZE(info->supplies), info->supplies); |
369 | if (ret) { | 339 | if (ret) { |
370 | dev_err(info->dev, "couldn't get regulators %d\n", ret); | 340 | dev_err(info->dev, "couldn't get regulators %d\n", ret); |
371 | goto err_regulator; | 341 | return ret; |
372 | } | 342 | } |
373 | 343 | ||
374 | if (vddvibl_uV) { | 344 | if (vddvibl_uV) { |
@@ -377,7 +347,7 @@ static int twl6040_vibra_probe(struct platform_device *pdev) | |||
377 | if (ret) { | 347 | if (ret) { |
378 | dev_err(info->dev, "failed to set VDDVIBL volt %d\n", | 348 | dev_err(info->dev, "failed to set VDDVIBL volt %d\n", |
379 | ret); | 349 | ret); |
380 | goto err_voltage; | 350 | goto err_regulator; |
381 | } | 351 | } |
382 | } | 352 | } |
383 | 353 | ||
@@ -387,34 +357,49 @@ static int twl6040_vibra_probe(struct platform_device *pdev) | |||
387 | if (ret) { | 357 | if (ret) { |
388 | dev_err(info->dev, "failed to set VDDVIBR volt %d\n", | 358 | dev_err(info->dev, "failed to set VDDVIBR volt %d\n", |
389 | ret); | 359 | ret); |
390 | goto err_voltage; | 360 | goto err_regulator; |
391 | } | 361 | } |
392 | } | 362 | } |
393 | 363 | ||
394 | info->workqueue = alloc_workqueue("twl6040-vibra", 0, 0); | 364 | INIT_WORK(&info->play_work, vibra_play_work); |
395 | if (info->workqueue == NULL) { | 365 | |
396 | dev_err(info->dev, "couldn't create workqueue\n"); | 366 | info->input_dev = input_allocate_device(); |
367 | if (info->input_dev == NULL) { | ||
368 | dev_err(info->dev, "couldn't allocate input device\n"); | ||
397 | ret = -ENOMEM; | 369 | ret = -ENOMEM; |
398 | goto err_voltage; | 370 | goto err_regulator; |
399 | } | 371 | } |
400 | INIT_WORK(&info->play_work, vibra_play_work); | 372 | |
373 | input_set_drvdata(info->input_dev, info); | ||
374 | |||
375 | info->input_dev->name = "twl6040:vibrator"; | ||
376 | info->input_dev->id.version = 1; | ||
377 | info->input_dev->dev.parent = pdev->dev.parent; | ||
378 | info->input_dev->close = twl6040_vibra_close; | ||
379 | __set_bit(FF_RUMBLE, info->input_dev->ffbit); | ||
380 | |||
381 | ret = input_ff_create_memless(info->input_dev, NULL, vibra_play); | ||
382 | if (ret < 0) { | ||
383 | dev_err(info->dev, "couldn't register vibrator to FF\n"); | ||
384 | goto err_ialloc; | ||
385 | } | ||
386 | |||
387 | ret = input_register_device(info->input_dev); | ||
388 | if (ret < 0) { | ||
389 | dev_err(info->dev, "couldn't register input device\n"); | ||
390 | goto err_iff; | ||
391 | } | ||
392 | |||
393 | platform_set_drvdata(pdev, info); | ||
401 | 394 | ||
402 | return 0; | 395 | return 0; |
403 | 396 | ||
404 | err_voltage: | ||
405 | regulator_bulk_free(ARRAY_SIZE(info->supplies), info->supplies); | ||
406 | err_regulator: | ||
407 | free_irq(info->irq, info); | ||
408 | err_irq: | ||
409 | input_unregister_device(info->input_dev); | ||
410 | info->input_dev = NULL; | ||
411 | err_iff: | 397 | err_iff: |
412 | if (info->input_dev) | 398 | input_ff_destroy(info->input_dev); |
413 | input_ff_destroy(info->input_dev); | ||
414 | err_ialloc: | 399 | err_ialloc: |
415 | input_free_device(info->input_dev); | 400 | input_free_device(info->input_dev); |
416 | err_kzalloc: | 401 | err_regulator: |
417 | kfree(info); | 402 | regulator_bulk_free(ARRAY_SIZE(info->supplies), info->supplies); |
418 | return ret; | 403 | return ret; |
419 | } | 404 | } |
420 | 405 | ||
@@ -423,10 +408,7 @@ static int twl6040_vibra_remove(struct platform_device *pdev) | |||
423 | struct vibra_info *info = platform_get_drvdata(pdev); | 408 | struct vibra_info *info = platform_get_drvdata(pdev); |
424 | 409 | ||
425 | input_unregister_device(info->input_dev); | 410 | input_unregister_device(info->input_dev); |
426 | free_irq(info->irq, info); | ||
427 | regulator_bulk_free(ARRAY_SIZE(info->supplies), info->supplies); | 411 | regulator_bulk_free(ARRAY_SIZE(info->supplies), info->supplies); |
428 | destroy_workqueue(info->workqueue); | ||
429 | kfree(info); | ||
430 | 412 | ||
431 | return 0; | 413 | return 0; |
432 | } | 414 | } |
diff --git a/drivers/input/misc/wm831x-on.c b/drivers/input/misc/wm831x-on.c index 558767d8ebf4..caa2c4068f09 100644 --- a/drivers/input/misc/wm831x-on.c +++ b/drivers/input/misc/wm831x-on.c | |||
@@ -86,7 +86,7 @@ static int wm831x_on_probe(struct platform_device *pdev) | |||
86 | wm831x_on->wm831x = wm831x; | 86 | wm831x_on->wm831x = wm831x; |
87 | INIT_DELAYED_WORK(&wm831x_on->work, wm831x_poll_on); | 87 | INIT_DELAYED_WORK(&wm831x_on->work, wm831x_poll_on); |
88 | 88 | ||
89 | wm831x_on->dev = input_allocate_device(); | 89 | wm831x_on->dev = devm_input_allocate_device(&pdev->dev); |
90 | if (!wm831x_on->dev) { | 90 | if (!wm831x_on->dev) { |
91 | dev_err(&pdev->dev, "Can't allocate input dev\n"); | 91 | dev_err(&pdev->dev, "Can't allocate input dev\n"); |
92 | ret = -ENOMEM; | 92 | ret = -ENOMEM; |
@@ -119,7 +119,6 @@ static int wm831x_on_probe(struct platform_device *pdev) | |||
119 | err_irq: | 119 | err_irq: |
120 | free_irq(irq, wm831x_on); | 120 | free_irq(irq, wm831x_on); |
121 | err_input_dev: | 121 | err_input_dev: |
122 | input_free_device(wm831x_on->dev); | ||
123 | err: | 122 | err: |
124 | return ret; | 123 | return ret; |
125 | } | 124 | } |
@@ -131,7 +130,6 @@ static int wm831x_on_remove(struct platform_device *pdev) | |||
131 | 130 | ||
132 | free_irq(irq, wm831x_on); | 131 | free_irq(irq, wm831x_on); |
133 | cancel_delayed_work_sync(&wm831x_on->work); | 132 | cancel_delayed_work_sync(&wm831x_on->work); |
134 | input_unregister_device(wm831x_on->dev); | ||
135 | 133 | ||
136 | return 0; | 134 | return 0; |
137 | } | 135 | } |
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index cd6268cf7cd5..802bd6a72d73 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig | |||
@@ -68,6 +68,16 @@ config MOUSE_PS2_SYNAPTICS | |||
68 | 68 | ||
69 | If unsure, say Y. | 69 | If unsure, say Y. |
70 | 70 | ||
71 | config MOUSE_PS2_CYPRESS | ||
72 | bool "Cypress PS/2 mouse protocol extension" if EXPERT | ||
73 | default y | ||
74 | depends on MOUSE_PS2 | ||
75 | help | ||
76 | Say Y here if you have a Cypress PS/2 Trackpad connected to | ||
77 | your system. | ||
78 | |||
79 | If unsure, say Y. | ||
80 | |||
71 | config MOUSE_PS2_LIFEBOOK | 81 | config MOUSE_PS2_LIFEBOOK |
72 | bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EXPERT | 82 | bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EXPERT |
73 | default y | 83 | default y |
@@ -193,6 +203,18 @@ config MOUSE_BCM5974 | |||
193 | To compile this driver as a module, choose M here: the | 203 | To compile this driver as a module, choose M here: the |
194 | module will be called bcm5974. | 204 | module will be called bcm5974. |
195 | 205 | ||
206 | config MOUSE_CYAPA | ||
207 | tristate "Cypress APA I2C Trackpad support" | ||
208 | depends on I2C | ||
209 | help | ||
210 | This driver adds support for Cypress All Points Addressable (APA) | ||
211 | I2C Trackpads, including the ones used in 2012 Samsung Chromebooks. | ||
212 | |||
213 | Say Y here if you have a Cypress APA I2C Trackpad. | ||
214 | |||
215 | To compile this driver as a module, choose M here: the module will be | ||
216 | called cyapa. | ||
217 | |||
196 | config MOUSE_INPORT | 218 | config MOUSE_INPORT |
197 | tristate "InPort/MS/ATIXL busmouse" | 219 | tristate "InPort/MS/ATIXL busmouse" |
198 | depends on ISA | 220 | depends on ISA |
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile index 46ba7556fd4f..c25efdb3f288 100644 --- a/drivers/input/mouse/Makefile +++ b/drivers/input/mouse/Makefile | |||
@@ -8,6 +8,7 @@ obj-$(CONFIG_MOUSE_AMIGA) += amimouse.o | |||
8 | obj-$(CONFIG_MOUSE_APPLETOUCH) += appletouch.o | 8 | obj-$(CONFIG_MOUSE_APPLETOUCH) += appletouch.o |
9 | obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o | 9 | obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o |
10 | obj-$(CONFIG_MOUSE_BCM5974) += bcm5974.o | 10 | obj-$(CONFIG_MOUSE_BCM5974) += bcm5974.o |
11 | obj-$(CONFIG_MOUSE_CYAPA) += cyapa.o | ||
11 | obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o | 12 | obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o |
12 | obj-$(CONFIG_MOUSE_INPORT) += inport.o | 13 | obj-$(CONFIG_MOUSE_INPORT) += inport.o |
13 | obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o | 14 | obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o |
@@ -32,3 +33,4 @@ psmouse-$(CONFIG_MOUSE_PS2_LIFEBOOK) += lifebook.o | |||
32 | psmouse-$(CONFIG_MOUSE_PS2_SENTELIC) += sentelic.o | 33 | psmouse-$(CONFIG_MOUSE_PS2_SENTELIC) += sentelic.o |
33 | psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o | 34 | psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o |
34 | psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT) += touchkit_ps2.o | 35 | psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT) += touchkit_ps2.o |
36 | psmouse-$(CONFIG_MOUSE_PS2_CYPRESS) += cypress_ps2.o | ||
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index e229fa3cad96..7b99fc7c9438 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -27,14 +27,11 @@ | |||
27 | /* | 27 | /* |
28 | * Definitions for ALPS version 3 and 4 command mode protocol | 28 | * Definitions for ALPS version 3 and 4 command mode protocol |
29 | */ | 29 | */ |
30 | #define ALPS_V3_X_MAX 2000 | ||
31 | #define ALPS_V3_Y_MAX 1400 | ||
32 | |||
33 | #define ALPS_BITMAP_X_BITS 15 | ||
34 | #define ALPS_BITMAP_Y_BITS 11 | ||
35 | |||
36 | #define ALPS_CMD_NIBBLE_10 0x01f2 | 30 | #define ALPS_CMD_NIBBLE_10 0x01f2 |
37 | 31 | ||
32 | #define ALPS_REG_BASE_RUSHMORE 0xc2c0 | ||
33 | #define ALPS_REG_BASE_PINNACLE 0x0000 | ||
34 | |||
38 | static const struct alps_nibble_commands alps_v3_nibble_commands[] = { | 35 | static const struct alps_nibble_commands alps_v3_nibble_commands[] = { |
39 | { PSMOUSE_CMD_SETPOLL, 0x00 }, /* 0 */ | 36 | { PSMOUSE_CMD_SETPOLL, 0x00 }, /* 0 */ |
40 | { PSMOUSE_CMD_RESET_DIS, 0x00 }, /* 1 */ | 37 | { PSMOUSE_CMD_RESET_DIS, 0x00 }, /* 1 */ |
@@ -109,11 +106,14 @@ static const struct alps_model_info alps_model_data[] = { | |||
109 | { { 0x73, 0x02, 0x50 }, 0x00, ALPS_PROTO_V2, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */ | 106 | { { 0x73, 0x02, 0x50 }, 0x00, ALPS_PROTO_V2, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */ |
110 | { { 0x52, 0x01, 0x14 }, 0x00, ALPS_PROTO_V2, 0xff, 0xff, | 107 | { { 0x52, 0x01, 0x14 }, 0x00, ALPS_PROTO_V2, 0xff, 0xff, |
111 | ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */ | 108 | ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */ |
112 | { { 0x73, 0x02, 0x64 }, 0x9b, ALPS_PROTO_V3, 0x8f, 0x8f, ALPS_DUALPOINT }, | ||
113 | { { 0x73, 0x02, 0x64 }, 0x9d, ALPS_PROTO_V3, 0x8f, 0x8f, ALPS_DUALPOINT }, | ||
114 | { { 0x73, 0x02, 0x64 }, 0x8a, ALPS_PROTO_V4, 0x8f, 0x8f, 0 }, | 109 | { { 0x73, 0x02, 0x64 }, 0x8a, ALPS_PROTO_V4, 0x8f, 0x8f, 0 }, |
115 | }; | 110 | }; |
116 | 111 | ||
112 | static void alps_set_abs_params_st(struct alps_data *priv, | ||
113 | struct input_dev *dev1); | ||
114 | static void alps_set_abs_params_mt(struct alps_data *priv, | ||
115 | struct input_dev *dev1); | ||
116 | |||
117 | /* | 117 | /* |
118 | * XXX - this entry is suspicious. First byte has zero lower nibble, | 118 | * XXX - this entry is suspicious. First byte has zero lower nibble, |
119 | * which is what a normal mouse would report. Also, the value 0x0e | 119 | * which is what a normal mouse would report. Also, the value 0x0e |
@@ -122,10 +122,10 @@ static const struct alps_model_info alps_model_data[] = { | |||
122 | 122 | ||
123 | /* Packet formats are described in Documentation/input/alps.txt */ | 123 | /* Packet formats are described in Documentation/input/alps.txt */ |
124 | 124 | ||
125 | static bool alps_is_valid_first_byte(const struct alps_model_info *model, | 125 | static bool alps_is_valid_first_byte(struct alps_data *priv, |
126 | unsigned char data) | 126 | unsigned char data) |
127 | { | 127 | { |
128 | return (data & model->mask0) == model->byte0; | 128 | return (data & priv->mask0) == priv->byte0; |
129 | } | 129 | } |
130 | 130 | ||
131 | static void alps_report_buttons(struct psmouse *psmouse, | 131 | static void alps_report_buttons(struct psmouse *psmouse, |
@@ -158,14 +158,13 @@ static void alps_report_buttons(struct psmouse *psmouse, | |||
158 | static void alps_process_packet_v1_v2(struct psmouse *psmouse) | 158 | static void alps_process_packet_v1_v2(struct psmouse *psmouse) |
159 | { | 159 | { |
160 | struct alps_data *priv = psmouse->private; | 160 | struct alps_data *priv = psmouse->private; |
161 | const struct alps_model_info *model = priv->i; | ||
162 | unsigned char *packet = psmouse->packet; | 161 | unsigned char *packet = psmouse->packet; |
163 | struct input_dev *dev = psmouse->dev; | 162 | struct input_dev *dev = psmouse->dev; |
164 | struct input_dev *dev2 = priv->dev2; | 163 | struct input_dev *dev2 = priv->dev2; |
165 | int x, y, z, ges, fin, left, right, middle; | 164 | int x, y, z, ges, fin, left, right, middle; |
166 | int back = 0, forward = 0; | 165 | int back = 0, forward = 0; |
167 | 166 | ||
168 | if (model->proto_version == ALPS_PROTO_V1) { | 167 | if (priv->proto_version == ALPS_PROTO_V1) { |
169 | left = packet[2] & 0x10; | 168 | left = packet[2] & 0x10; |
170 | right = packet[2] & 0x08; | 169 | right = packet[2] & 0x08; |
171 | middle = 0; | 170 | middle = 0; |
@@ -181,12 +180,12 @@ static void alps_process_packet_v1_v2(struct psmouse *psmouse) | |||
181 | z = packet[5]; | 180 | z = packet[5]; |
182 | } | 181 | } |
183 | 182 | ||
184 | if (model->flags & ALPS_FW_BK_1) { | 183 | if (priv->flags & ALPS_FW_BK_1) { |
185 | back = packet[0] & 0x10; | 184 | back = packet[0] & 0x10; |
186 | forward = packet[2] & 4; | 185 | forward = packet[2] & 4; |
187 | } | 186 | } |
188 | 187 | ||
189 | if (model->flags & ALPS_FW_BK_2) { | 188 | if (priv->flags & ALPS_FW_BK_2) { |
190 | back = packet[3] & 4; | 189 | back = packet[3] & 4; |
191 | forward = packet[2] & 4; | 190 | forward = packet[2] & 4; |
192 | if ((middle = forward && back)) | 191 | if ((middle = forward && back)) |
@@ -196,7 +195,7 @@ static void alps_process_packet_v1_v2(struct psmouse *psmouse) | |||
196 | ges = packet[2] & 1; | 195 | ges = packet[2] & 1; |
197 | fin = packet[2] & 2; | 196 | fin = packet[2] & 2; |
198 | 197 | ||
199 | if ((model->flags & ALPS_DUALPOINT) && z == 127) { | 198 | if ((priv->flags & ALPS_DUALPOINT) && z == 127) { |
200 | input_report_rel(dev2, REL_X, (x > 383 ? (x - 768) : x)); | 199 | input_report_rel(dev2, REL_X, (x > 383 ? (x - 768) : x)); |
201 | input_report_rel(dev2, REL_Y, -(y > 255 ? (y - 512) : y)); | 200 | input_report_rel(dev2, REL_Y, -(y > 255 ? (y - 512) : y)); |
202 | 201 | ||
@@ -239,15 +238,15 @@ static void alps_process_packet_v1_v2(struct psmouse *psmouse) | |||
239 | input_report_abs(dev, ABS_PRESSURE, z); | 238 | input_report_abs(dev, ABS_PRESSURE, z); |
240 | input_report_key(dev, BTN_TOOL_FINGER, z > 0); | 239 | input_report_key(dev, BTN_TOOL_FINGER, z > 0); |
241 | 240 | ||
242 | if (model->flags & ALPS_WHEEL) | 241 | if (priv->flags & ALPS_WHEEL) |
243 | input_report_rel(dev, REL_WHEEL, ((packet[2] << 1) & 0x08) - ((packet[0] >> 4) & 0x07)); | 242 | input_report_rel(dev, REL_WHEEL, ((packet[2] << 1) & 0x08) - ((packet[0] >> 4) & 0x07)); |
244 | 243 | ||
245 | if (model->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) { | 244 | if (priv->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) { |
246 | input_report_key(dev, BTN_FORWARD, forward); | 245 | input_report_key(dev, BTN_FORWARD, forward); |
247 | input_report_key(dev, BTN_BACK, back); | 246 | input_report_key(dev, BTN_BACK, back); |
248 | } | 247 | } |
249 | 248 | ||
250 | if (model->flags & ALPS_FOUR_BUTTONS) { | 249 | if (priv->flags & ALPS_FOUR_BUTTONS) { |
251 | input_report_key(dev, BTN_0, packet[2] & 4); | 250 | input_report_key(dev, BTN_0, packet[2] & 4); |
252 | input_report_key(dev, BTN_1, packet[0] & 0x10); | 251 | input_report_key(dev, BTN_1, packet[0] & 0x10); |
253 | input_report_key(dev, BTN_2, packet[3] & 4); | 252 | input_report_key(dev, BTN_2, packet[3] & 4); |
@@ -267,7 +266,8 @@ static void alps_process_packet_v1_v2(struct psmouse *psmouse) | |||
267 | * These points are returned in x1, y1, x2, and y2 when the return value | 266 | * These points are returned in x1, y1, x2, and y2 when the return value |
268 | * is greater than 0. | 267 | * is greater than 0. |
269 | */ | 268 | */ |
270 | static int alps_process_bitmap(unsigned int x_map, unsigned int y_map, | 269 | static int alps_process_bitmap(struct alps_data *priv, |
270 | unsigned int x_map, unsigned int y_map, | ||
271 | int *x1, int *y1, int *x2, int *y2) | 271 | int *x1, int *y1, int *x2, int *y2) |
272 | { | 272 | { |
273 | struct alps_bitmap_point { | 273 | struct alps_bitmap_point { |
@@ -309,7 +309,7 @@ static int alps_process_bitmap(unsigned int x_map, unsigned int y_map, | |||
309 | * y bitmap is reversed for what we need (lower positions are in | 309 | * y bitmap is reversed for what we need (lower positions are in |
310 | * higher bits), so we process from the top end. | 310 | * higher bits), so we process from the top end. |
311 | */ | 311 | */ |
312 | y_map = y_map << (sizeof(y_map) * BITS_PER_BYTE - ALPS_BITMAP_Y_BITS); | 312 | y_map = y_map << (sizeof(y_map) * BITS_PER_BYTE - priv->y_bits); |
313 | prev_bit = 0; | 313 | prev_bit = 0; |
314 | point = &y_low; | 314 | point = &y_low; |
315 | for (i = 0; y_map != 0; i++, y_map <<= 1) { | 315 | for (i = 0; y_map != 0; i++, y_map <<= 1) { |
@@ -355,16 +355,18 @@ static int alps_process_bitmap(unsigned int x_map, unsigned int y_map, | |||
355 | } | 355 | } |
356 | } | 356 | } |
357 | 357 | ||
358 | *x1 = (ALPS_V3_X_MAX * (2 * x_low.start_bit + x_low.num_bits - 1)) / | 358 | *x1 = (priv->x_max * (2 * x_low.start_bit + x_low.num_bits - 1)) / |
359 | (2 * (ALPS_BITMAP_X_BITS - 1)); | 359 | (2 * (priv->x_bits - 1)); |
360 | *y1 = (ALPS_V3_Y_MAX * (2 * y_low.start_bit + y_low.num_bits - 1)) / | 360 | *y1 = (priv->y_max * (2 * y_low.start_bit + y_low.num_bits - 1)) / |
361 | (2 * (ALPS_BITMAP_Y_BITS - 1)); | 361 | (2 * (priv->y_bits - 1)); |
362 | 362 | ||
363 | if (fingers > 1) { | 363 | if (fingers > 1) { |
364 | *x2 = (ALPS_V3_X_MAX * (2 * x_high.start_bit + x_high.num_bits - 1)) / | 364 | *x2 = (priv->x_max * |
365 | (2 * (ALPS_BITMAP_X_BITS - 1)); | 365 | (2 * x_high.start_bit + x_high.num_bits - 1)) / |
366 | *y2 = (ALPS_V3_Y_MAX * (2 * y_high.start_bit + y_high.num_bits - 1)) / | 366 | (2 * (priv->x_bits - 1)); |
367 | (2 * (ALPS_BITMAP_Y_BITS - 1)); | 367 | *y2 = (priv->y_max * |
368 | (2 * y_high.start_bit + y_high.num_bits - 1)) / | ||
369 | (2 * (priv->y_bits - 1)); | ||
368 | } | 370 | } |
369 | 371 | ||
370 | return fingers; | 372 | return fingers; |
@@ -448,17 +450,57 @@ static void alps_process_trackstick_packet_v3(struct psmouse *psmouse) | |||
448 | return; | 450 | return; |
449 | } | 451 | } |
450 | 452 | ||
453 | static void alps_decode_buttons_v3(struct alps_fields *f, unsigned char *p) | ||
454 | { | ||
455 | f->left = !!(p[3] & 0x01); | ||
456 | f->right = !!(p[3] & 0x02); | ||
457 | f->middle = !!(p[3] & 0x04); | ||
458 | |||
459 | f->ts_left = !!(p[3] & 0x10); | ||
460 | f->ts_right = !!(p[3] & 0x20); | ||
461 | f->ts_middle = !!(p[3] & 0x40); | ||
462 | } | ||
463 | |||
464 | static void alps_decode_pinnacle(struct alps_fields *f, unsigned char *p) | ||
465 | { | ||
466 | f->first_mp = !!(p[4] & 0x40); | ||
467 | f->is_mp = !!(p[0] & 0x40); | ||
468 | |||
469 | f->fingers = (p[5] & 0x3) + 1; | ||
470 | f->x_map = ((p[4] & 0x7e) << 8) | | ||
471 | ((p[1] & 0x7f) << 2) | | ||
472 | ((p[0] & 0x30) >> 4); | ||
473 | f->y_map = ((p[3] & 0x70) << 4) | | ||
474 | ((p[2] & 0x7f) << 1) | | ||
475 | (p[4] & 0x01); | ||
476 | |||
477 | f->x = ((p[1] & 0x7f) << 4) | ((p[4] & 0x30) >> 2) | | ||
478 | ((p[0] & 0x30) >> 4); | ||
479 | f->y = ((p[2] & 0x7f) << 4) | (p[4] & 0x0f); | ||
480 | f->z = p[5] & 0x7f; | ||
481 | |||
482 | alps_decode_buttons_v3(f, p); | ||
483 | } | ||
484 | |||
485 | static void alps_decode_rushmore(struct alps_fields *f, unsigned char *p) | ||
486 | { | ||
487 | alps_decode_pinnacle(f, p); | ||
488 | |||
489 | f->x_map |= (p[5] & 0x10) << 11; | ||
490 | f->y_map |= (p[5] & 0x20) << 6; | ||
491 | } | ||
492 | |||
451 | static void alps_process_touchpad_packet_v3(struct psmouse *psmouse) | 493 | static void alps_process_touchpad_packet_v3(struct psmouse *psmouse) |
452 | { | 494 | { |
453 | struct alps_data *priv = psmouse->private; | 495 | struct alps_data *priv = psmouse->private; |
454 | unsigned char *packet = psmouse->packet; | 496 | unsigned char *packet = psmouse->packet; |
455 | struct input_dev *dev = psmouse->dev; | 497 | struct input_dev *dev = psmouse->dev; |
456 | struct input_dev *dev2 = priv->dev2; | 498 | struct input_dev *dev2 = priv->dev2; |
457 | int x, y, z; | ||
458 | int left, right, middle; | ||
459 | int x1 = 0, y1 = 0, x2 = 0, y2 = 0; | 499 | int x1 = 0, y1 = 0, x2 = 0, y2 = 0; |
460 | int fingers = 0, bmap_fingers; | 500 | int fingers = 0, bmap_fingers; |
461 | unsigned int x_bitmap, y_bitmap; | 501 | struct alps_fields f; |
502 | |||
503 | priv->decode_fields(&f, packet); | ||
462 | 504 | ||
463 | /* | 505 | /* |
464 | * There's no single feature of touchpad position and bitmap packets | 506 | * There's no single feature of touchpad position and bitmap packets |
@@ -473,16 +515,10 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse) | |||
473 | * packet. Check for this, and when it happens process the | 515 | * packet. Check for this, and when it happens process the |
474 | * position packet as usual. | 516 | * position packet as usual. |
475 | */ | 517 | */ |
476 | if (packet[0] & 0x40) { | 518 | if (f.is_mp) { |
477 | fingers = (packet[5] & 0x3) + 1; | 519 | fingers = f.fingers; |
478 | x_bitmap = ((packet[4] & 0x7e) << 8) | | 520 | bmap_fingers = alps_process_bitmap(priv, |
479 | ((packet[1] & 0x7f) << 2) | | 521 | f.x_map, f.y_map, |
480 | ((packet[0] & 0x30) >> 4); | ||
481 | y_bitmap = ((packet[3] & 0x70) << 4) | | ||
482 | ((packet[2] & 0x7f) << 1) | | ||
483 | (packet[4] & 0x01); | ||
484 | |||
485 | bmap_fingers = alps_process_bitmap(x_bitmap, y_bitmap, | ||
486 | &x1, &y1, &x2, &y2); | 522 | &x1, &y1, &x2, &y2); |
487 | 523 | ||
488 | /* | 524 | /* |
@@ -493,7 +529,7 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse) | |||
493 | fingers = bmap_fingers; | 529 | fingers = bmap_fingers; |
494 | 530 | ||
495 | /* Now process position packet */ | 531 | /* Now process position packet */ |
496 | packet = priv->multi_data; | 532 | priv->decode_fields(&f, priv->multi_data); |
497 | } else { | 533 | } else { |
498 | priv->multi_packet = 0; | 534 | priv->multi_packet = 0; |
499 | } | 535 | } |
@@ -507,10 +543,10 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse) | |||
507 | * out misidentified bitmap packets, we reject anything with this | 543 | * out misidentified bitmap packets, we reject anything with this |
508 | * bit set. | 544 | * bit set. |
509 | */ | 545 | */ |
510 | if (packet[0] & 0x40) | 546 | if (f.is_mp) |
511 | return; | 547 | return; |
512 | 548 | ||
513 | if (!priv->multi_packet && (packet[4] & 0x40)) { | 549 | if (!priv->multi_packet && f.first_mp) { |
514 | priv->multi_packet = 1; | 550 | priv->multi_packet = 1; |
515 | memcpy(priv->multi_data, packet, sizeof(priv->multi_data)); | 551 | memcpy(priv->multi_data, packet, sizeof(priv->multi_data)); |
516 | return; | 552 | return; |
@@ -518,22 +554,13 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse) | |||
518 | 554 | ||
519 | priv->multi_packet = 0; | 555 | priv->multi_packet = 0; |
520 | 556 | ||
521 | left = packet[3] & 0x01; | ||
522 | right = packet[3] & 0x02; | ||
523 | middle = packet[3] & 0x04; | ||
524 | |||
525 | x = ((packet[1] & 0x7f) << 4) | ((packet[4] & 0x30) >> 2) | | ||
526 | ((packet[0] & 0x30) >> 4); | ||
527 | y = ((packet[2] & 0x7f) << 4) | (packet[4] & 0x0f); | ||
528 | z = packet[5] & 0x7f; | ||
529 | |||
530 | /* | 557 | /* |
531 | * Sometimes the hardware sends a single packet with z = 0 | 558 | * Sometimes the hardware sends a single packet with z = 0 |
532 | * in the middle of a stream. Real releases generate packets | 559 | * in the middle of a stream. Real releases generate packets |
533 | * with x, y, and z all zero, so these seem to be flukes. | 560 | * with x, y, and z all zero, so these seem to be flukes. |
534 | * Ignore them. | 561 | * Ignore them. |
535 | */ | 562 | */ |
536 | if (x && y && !z) | 563 | if (f.x && f.y && !f.z) |
537 | return; | 564 | return; |
538 | 565 | ||
539 | /* | 566 | /* |
@@ -541,12 +568,12 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse) | |||
541 | * to rely on ST data. | 568 | * to rely on ST data. |
542 | */ | 569 | */ |
543 | if (!fingers) { | 570 | if (!fingers) { |
544 | x1 = x; | 571 | x1 = f.x; |
545 | y1 = y; | 572 | y1 = f.y; |
546 | fingers = z > 0 ? 1 : 0; | 573 | fingers = f.z > 0 ? 1 : 0; |
547 | } | 574 | } |
548 | 575 | ||
549 | if (z >= 64) | 576 | if (f.z >= 64) |
550 | input_report_key(dev, BTN_TOUCH, 1); | 577 | input_report_key(dev, BTN_TOUCH, 1); |
551 | else | 578 | else |
552 | input_report_key(dev, BTN_TOUCH, 0); | 579 | input_report_key(dev, BTN_TOUCH, 0); |
@@ -555,26 +582,22 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse) | |||
555 | 582 | ||
556 | input_mt_report_finger_count(dev, fingers); | 583 | input_mt_report_finger_count(dev, fingers); |
557 | 584 | ||
558 | input_report_key(dev, BTN_LEFT, left); | 585 | input_report_key(dev, BTN_LEFT, f.left); |
559 | input_report_key(dev, BTN_RIGHT, right); | 586 | input_report_key(dev, BTN_RIGHT, f.right); |
560 | input_report_key(dev, BTN_MIDDLE, middle); | 587 | input_report_key(dev, BTN_MIDDLE, f.middle); |
561 | 588 | ||
562 | if (z > 0) { | 589 | if (f.z > 0) { |
563 | input_report_abs(dev, ABS_X, x); | 590 | input_report_abs(dev, ABS_X, f.x); |
564 | input_report_abs(dev, ABS_Y, y); | 591 | input_report_abs(dev, ABS_Y, f.y); |
565 | } | 592 | } |
566 | input_report_abs(dev, ABS_PRESSURE, z); | 593 | input_report_abs(dev, ABS_PRESSURE, f.z); |
567 | 594 | ||
568 | input_sync(dev); | 595 | input_sync(dev); |
569 | 596 | ||
570 | if (!(priv->quirks & ALPS_QUIRK_TRACKSTICK_BUTTONS)) { | 597 | if (!(priv->quirks & ALPS_QUIRK_TRACKSTICK_BUTTONS)) { |
571 | left = packet[3] & 0x10; | 598 | input_report_key(dev2, BTN_LEFT, f.ts_left); |
572 | right = packet[3] & 0x20; | 599 | input_report_key(dev2, BTN_RIGHT, f.ts_right); |
573 | middle = packet[3] & 0x40; | 600 | input_report_key(dev2, BTN_MIDDLE, f.ts_middle); |
574 | |||
575 | input_report_key(dev2, BTN_LEFT, left); | ||
576 | input_report_key(dev2, BTN_RIGHT, right); | ||
577 | input_report_key(dev2, BTN_MIDDLE, middle); | ||
578 | input_sync(dev2); | 601 | input_sync(dev2); |
579 | } | 602 | } |
580 | } | 603 | } |
@@ -639,7 +662,7 @@ static void alps_process_packet_v4(struct psmouse *psmouse) | |||
639 | ((priv->multi_data[3] & 0x1f) << 5) | | 662 | ((priv->multi_data[3] & 0x1f) << 5) | |
640 | (priv->multi_data[1] & 0x1f); | 663 | (priv->multi_data[1] & 0x1f); |
641 | 664 | ||
642 | fingers = alps_process_bitmap(x_bitmap, y_bitmap, | 665 | fingers = alps_process_bitmap(priv, x_bitmap, y_bitmap, |
643 | &x1, &y1, &x2, &y2); | 666 | &x1, &y1, &x2, &y2); |
644 | 667 | ||
645 | /* Store MT data.*/ | 668 | /* Store MT data.*/ |
@@ -696,25 +719,6 @@ static void alps_process_packet_v4(struct psmouse *psmouse) | |||
696 | input_sync(dev); | 719 | input_sync(dev); |
697 | } | 720 | } |
698 | 721 | ||
699 | static void alps_process_packet(struct psmouse *psmouse) | ||
700 | { | ||
701 | struct alps_data *priv = psmouse->private; | ||
702 | const struct alps_model_info *model = priv->i; | ||
703 | |||
704 | switch (model->proto_version) { | ||
705 | case ALPS_PROTO_V1: | ||
706 | case ALPS_PROTO_V2: | ||
707 | alps_process_packet_v1_v2(psmouse); | ||
708 | break; | ||
709 | case ALPS_PROTO_V3: | ||
710 | alps_process_packet_v3(psmouse); | ||
711 | break; | ||
712 | case ALPS_PROTO_V4: | ||
713 | alps_process_packet_v4(psmouse); | ||
714 | break; | ||
715 | } | ||
716 | } | ||
717 | |||
718 | static void alps_report_bare_ps2_packet(struct psmouse *psmouse, | 722 | static void alps_report_bare_ps2_packet(struct psmouse *psmouse, |
719 | unsigned char packet[], | 723 | unsigned char packet[], |
720 | bool report_buttons) | 724 | bool report_buttons) |
@@ -765,14 +769,14 @@ static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse) | |||
765 | if (((psmouse->packet[3] | | 769 | if (((psmouse->packet[3] | |
766 | psmouse->packet[4] | | 770 | psmouse->packet[4] | |
767 | psmouse->packet[5]) & 0x80) || | 771 | psmouse->packet[5]) & 0x80) || |
768 | (!alps_is_valid_first_byte(priv->i, psmouse->packet[6]))) { | 772 | (!alps_is_valid_first_byte(priv, psmouse->packet[6]))) { |
769 | psmouse_dbg(psmouse, | 773 | psmouse_dbg(psmouse, |
770 | "refusing packet %4ph (suspected interleaved ps/2)\n", | 774 | "refusing packet %4ph (suspected interleaved ps/2)\n", |
771 | psmouse->packet + 3); | 775 | psmouse->packet + 3); |
772 | return PSMOUSE_BAD_DATA; | 776 | return PSMOUSE_BAD_DATA; |
773 | } | 777 | } |
774 | 778 | ||
775 | alps_process_packet(psmouse); | 779 | priv->process_packet(psmouse); |
776 | 780 | ||
777 | /* Continue with the next packet */ | 781 | /* Continue with the next packet */ |
778 | psmouse->packet[0] = psmouse->packet[6]; | 782 | psmouse->packet[0] = psmouse->packet[6]; |
@@ -816,6 +820,7 @@ static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse) | |||
816 | static void alps_flush_packet(unsigned long data) | 820 | static void alps_flush_packet(unsigned long data) |
817 | { | 821 | { |
818 | struct psmouse *psmouse = (struct psmouse *)data; | 822 | struct psmouse *psmouse = (struct psmouse *)data; |
823 | struct alps_data *priv = psmouse->private; | ||
819 | 824 | ||
820 | serio_pause_rx(psmouse->ps2dev.serio); | 825 | serio_pause_rx(psmouse->ps2dev.serio); |
821 | 826 | ||
@@ -833,7 +838,7 @@ static void alps_flush_packet(unsigned long data) | |||
833 | "refusing packet %3ph (suspected interleaved ps/2)\n", | 838 | "refusing packet %3ph (suspected interleaved ps/2)\n", |
834 | psmouse->packet + 3); | 839 | psmouse->packet + 3); |
835 | } else { | 840 | } else { |
836 | alps_process_packet(psmouse); | 841 | priv->process_packet(psmouse); |
837 | } | 842 | } |
838 | psmouse->pktcnt = 0; | 843 | psmouse->pktcnt = 0; |
839 | } | 844 | } |
@@ -844,7 +849,6 @@ static void alps_flush_packet(unsigned long data) | |||
844 | static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) | 849 | static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) |
845 | { | 850 | { |
846 | struct alps_data *priv = psmouse->private; | 851 | struct alps_data *priv = psmouse->private; |
847 | const struct alps_model_info *model = priv->i; | ||
848 | 852 | ||
849 | if ((psmouse->packet[0] & 0xc8) == 0x08) { /* PS/2 packet */ | 853 | if ((psmouse->packet[0] & 0xc8) == 0x08) { /* PS/2 packet */ |
850 | if (psmouse->pktcnt == 3) { | 854 | if (psmouse->pktcnt == 3) { |
@@ -857,15 +861,15 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) | |||
857 | 861 | ||
858 | /* Check for PS/2 packet stuffed in the middle of ALPS packet. */ | 862 | /* Check for PS/2 packet stuffed in the middle of ALPS packet. */ |
859 | 863 | ||
860 | if ((model->flags & ALPS_PS2_INTERLEAVED) && | 864 | if ((priv->flags & ALPS_PS2_INTERLEAVED) && |
861 | psmouse->pktcnt >= 4 && (psmouse->packet[3] & 0x0f) == 0x0f) { | 865 | psmouse->pktcnt >= 4 && (psmouse->packet[3] & 0x0f) == 0x0f) { |
862 | return alps_handle_interleaved_ps2(psmouse); | 866 | return alps_handle_interleaved_ps2(psmouse); |
863 | } | 867 | } |
864 | 868 | ||
865 | if (!alps_is_valid_first_byte(model, psmouse->packet[0])) { | 869 | if (!alps_is_valid_first_byte(priv, psmouse->packet[0])) { |
866 | psmouse_dbg(psmouse, | 870 | psmouse_dbg(psmouse, |
867 | "refusing packet[0] = %x (mask0 = %x, byte0 = %x)\n", | 871 | "refusing packet[0] = %x (mask0 = %x, byte0 = %x)\n", |
868 | psmouse->packet[0], model->mask0, model->byte0); | 872 | psmouse->packet[0], priv->mask0, priv->byte0); |
869 | return PSMOUSE_BAD_DATA; | 873 | return PSMOUSE_BAD_DATA; |
870 | } | 874 | } |
871 | 875 | ||
@@ -879,7 +883,7 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) | |||
879 | } | 883 | } |
880 | 884 | ||
881 | if (psmouse->pktcnt == psmouse->pktsize) { | 885 | if (psmouse->pktcnt == psmouse->pktsize) { |
882 | alps_process_packet(psmouse); | 886 | priv->process_packet(psmouse); |
883 | return PSMOUSE_FULL_PACKET; | 887 | return PSMOUSE_FULL_PACKET; |
884 | } | 888 | } |
885 | 889 | ||
@@ -967,24 +971,42 @@ static int alps_command_mode_write_reg(struct psmouse *psmouse, int addr, | |||
967 | return __alps_command_mode_write_reg(psmouse, value); | 971 | return __alps_command_mode_write_reg(psmouse, value); |
968 | } | 972 | } |
969 | 973 | ||
974 | static int alps_rpt_cmd(struct psmouse *psmouse, int init_command, | ||
975 | int repeated_command, unsigned char *param) | ||
976 | { | ||
977 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
978 | |||
979 | param[0] = 0; | ||
980 | if (init_command && ps2_command(ps2dev, param, init_command)) | ||
981 | return -EIO; | ||
982 | |||
983 | if (ps2_command(ps2dev, NULL, repeated_command) || | ||
984 | ps2_command(ps2dev, NULL, repeated_command) || | ||
985 | ps2_command(ps2dev, NULL, repeated_command)) | ||
986 | return -EIO; | ||
987 | |||
988 | param[0] = param[1] = param[2] = 0xff; | ||
989 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) | ||
990 | return -EIO; | ||
991 | |||
992 | psmouse_dbg(psmouse, "%2.2X report: %2.2x %2.2x %2.2x\n", | ||
993 | repeated_command, param[0], param[1], param[2]); | ||
994 | return 0; | ||
995 | } | ||
996 | |||
970 | static int alps_enter_command_mode(struct psmouse *psmouse, | 997 | static int alps_enter_command_mode(struct psmouse *psmouse, |
971 | unsigned char *resp) | 998 | unsigned char *resp) |
972 | { | 999 | { |
973 | unsigned char param[4]; | 1000 | unsigned char param[4]; |
974 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
975 | 1001 | ||
976 | if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP) || | 1002 | if (alps_rpt_cmd(psmouse, 0, PSMOUSE_CMD_RESET_WRAP, param)) { |
977 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP) || | ||
978 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP) || | ||
979 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) { | ||
980 | psmouse_err(psmouse, "failed to enter command mode\n"); | 1003 | psmouse_err(psmouse, "failed to enter command mode\n"); |
981 | return -1; | 1004 | return -1; |
982 | } | 1005 | } |
983 | 1006 | ||
984 | if (param[0] != 0x88 && param[1] != 0x07) { | 1007 | if (param[0] != 0x88 || (param[1] != 0x07 && param[1] != 0x08)) { |
985 | psmouse_dbg(psmouse, | 1008 | psmouse_dbg(psmouse, |
986 | "unknown response while entering command mode: %2.2x %2.2x %2.2x\n", | 1009 | "unknown response while entering command mode\n"); |
987 | param[0], param[1], param[2]); | ||
988 | return -1; | 1010 | return -1; |
989 | } | 1011 | } |
990 | 1012 | ||
@@ -1001,99 +1023,6 @@ static inline int alps_exit_command_mode(struct psmouse *psmouse) | |||
1001 | return 0; | 1023 | return 0; |
1002 | } | 1024 | } |
1003 | 1025 | ||
1004 | static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int *version) | ||
1005 | { | ||
1006 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
1007 | static const unsigned char rates[] = { 0, 10, 20, 40, 60, 80, 100, 200 }; | ||
1008 | unsigned char param[4]; | ||
1009 | const struct alps_model_info *model = NULL; | ||
1010 | int i; | ||
1011 | |||
1012 | /* | ||
1013 | * First try "E6 report". | ||
1014 | * ALPS should return 0,0,10 or 0,0,100 if no buttons are pressed. | ||
1015 | * The bits 0-2 of the first byte will be 1s if some buttons are | ||
1016 | * pressed. | ||
1017 | */ | ||
1018 | param[0] = 0; | ||
1019 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES) || | ||
1020 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || | ||
1021 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || | ||
1022 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11)) | ||
1023 | return NULL; | ||
1024 | |||
1025 | param[0] = param[1] = param[2] = 0xff; | ||
1026 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) | ||
1027 | return NULL; | ||
1028 | |||
1029 | psmouse_dbg(psmouse, "E6 report: %2.2x %2.2x %2.2x", | ||
1030 | param[0], param[1], param[2]); | ||
1031 | |||
1032 | if ((param[0] & 0xf8) != 0 || param[1] != 0 || | ||
1033 | (param[2] != 10 && param[2] != 100)) | ||
1034 | return NULL; | ||
1035 | |||
1036 | /* | ||
1037 | * Now try "E7 report". Allowed responses are in | ||
1038 | * alps_model_data[].signature | ||
1039 | */ | ||
1040 | param[0] = 0; | ||
1041 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES) || | ||
1042 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) || | ||
1043 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) || | ||
1044 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21)) | ||
1045 | return NULL; | ||
1046 | |||
1047 | param[0] = param[1] = param[2] = 0xff; | ||
1048 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) | ||
1049 | return NULL; | ||
1050 | |||
1051 | psmouse_dbg(psmouse, "E7 report: %2.2x %2.2x %2.2x", | ||
1052 | param[0], param[1], param[2]); | ||
1053 | |||
1054 | if (version) { | ||
1055 | for (i = 0; i < ARRAY_SIZE(rates) && param[2] != rates[i]; i++) | ||
1056 | /* empty */; | ||
1057 | *version = (param[0] << 8) | (param[1] << 4) | i; | ||
1058 | } | ||
1059 | |||
1060 | for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) { | ||
1061 | if (!memcmp(param, alps_model_data[i].signature, | ||
1062 | sizeof(alps_model_data[i].signature))) { | ||
1063 | model = alps_model_data + i; | ||
1064 | break; | ||
1065 | } | ||
1066 | } | ||
1067 | |||
1068 | if (model && model->proto_version > ALPS_PROTO_V2) { | ||
1069 | /* | ||
1070 | * Need to check command mode response to identify | ||
1071 | * model | ||
1072 | */ | ||
1073 | model = NULL; | ||
1074 | if (alps_enter_command_mode(psmouse, param)) { | ||
1075 | psmouse_warn(psmouse, | ||
1076 | "touchpad failed to enter command mode\n"); | ||
1077 | } else { | ||
1078 | for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) { | ||
1079 | if (alps_model_data[i].proto_version > ALPS_PROTO_V2 && | ||
1080 | alps_model_data[i].command_mode_resp == param[0]) { | ||
1081 | model = alps_model_data + i; | ||
1082 | break; | ||
1083 | } | ||
1084 | } | ||
1085 | alps_exit_command_mode(psmouse); | ||
1086 | |||
1087 | if (!model) | ||
1088 | psmouse_dbg(psmouse, | ||
1089 | "Unknown command mode response %2.2x\n", | ||
1090 | param[0]); | ||
1091 | } | ||
1092 | } | ||
1093 | |||
1094 | return model; | ||
1095 | } | ||
1096 | |||
1097 | /* | 1026 | /* |
1098 | * For DualPoint devices select the device that should respond to | 1027 | * For DualPoint devices select the device that should respond to |
1099 | * subsequent commands. It looks like glidepad is behind stickpointer, | 1028 | * subsequent commands. It looks like glidepad is behind stickpointer, |
@@ -1137,18 +1066,10 @@ static int alps_absolute_mode_v1_v2(struct psmouse *psmouse) | |||
1137 | 1066 | ||
1138 | static int alps_get_status(struct psmouse *psmouse, char *param) | 1067 | static int alps_get_status(struct psmouse *psmouse, char *param) |
1139 | { | 1068 | { |
1140 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
1141 | |||
1142 | /* Get status: 0xF5 0xF5 0xF5 0xE9 */ | 1069 | /* Get status: 0xF5 0xF5 0xF5 0xE9 */ |
1143 | if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) || | 1070 | if (alps_rpt_cmd(psmouse, 0, PSMOUSE_CMD_DISABLE, param)) |
1144 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) || | ||
1145 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) || | ||
1146 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) | ||
1147 | return -1; | 1071 | return -1; |
1148 | 1072 | ||
1149 | psmouse_dbg(psmouse, "Status: %2.2x %2.2x %2.2x", | ||
1150 | param[0], param[1], param[2]); | ||
1151 | |||
1152 | return 0; | 1073 | return 0; |
1153 | } | 1074 | } |
1154 | 1075 | ||
@@ -1190,16 +1111,16 @@ static int alps_poll(struct psmouse *psmouse) | |||
1190 | unsigned char buf[sizeof(psmouse->packet)]; | 1111 | unsigned char buf[sizeof(psmouse->packet)]; |
1191 | bool poll_failed; | 1112 | bool poll_failed; |
1192 | 1113 | ||
1193 | if (priv->i->flags & ALPS_PASS) | 1114 | if (priv->flags & ALPS_PASS) |
1194 | alps_passthrough_mode_v2(psmouse, true); | 1115 | alps_passthrough_mode_v2(psmouse, true); |
1195 | 1116 | ||
1196 | poll_failed = ps2_command(&psmouse->ps2dev, buf, | 1117 | poll_failed = ps2_command(&psmouse->ps2dev, buf, |
1197 | PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)) < 0; | 1118 | PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)) < 0; |
1198 | 1119 | ||
1199 | if (priv->i->flags & ALPS_PASS) | 1120 | if (priv->flags & ALPS_PASS) |
1200 | alps_passthrough_mode_v2(psmouse, false); | 1121 | alps_passthrough_mode_v2(psmouse, false); |
1201 | 1122 | ||
1202 | if (poll_failed || (buf[0] & priv->i->mask0) != priv->i->byte0) | 1123 | if (poll_failed || (buf[0] & priv->mask0) != priv->byte0) |
1203 | return -1; | 1124 | return -1; |
1204 | 1125 | ||
1205 | if ((psmouse->badbyte & 0xc8) == 0x08) { | 1126 | if ((psmouse->badbyte & 0xc8) == 0x08) { |
@@ -1217,9 +1138,8 @@ static int alps_poll(struct psmouse *psmouse) | |||
1217 | static int alps_hw_init_v1_v2(struct psmouse *psmouse) | 1138 | static int alps_hw_init_v1_v2(struct psmouse *psmouse) |
1218 | { | 1139 | { |
1219 | struct alps_data *priv = psmouse->private; | 1140 | struct alps_data *priv = psmouse->private; |
1220 | const struct alps_model_info *model = priv->i; | ||
1221 | 1141 | ||
1222 | if ((model->flags & ALPS_PASS) && | 1142 | if ((priv->flags & ALPS_PASS) && |
1223 | alps_passthrough_mode_v2(psmouse, true)) { | 1143 | alps_passthrough_mode_v2(psmouse, true)) { |
1224 | return -1; | 1144 | return -1; |
1225 | } | 1145 | } |
@@ -1234,7 +1154,7 @@ static int alps_hw_init_v1_v2(struct psmouse *psmouse) | |||
1234 | return -1; | 1154 | return -1; |
1235 | } | 1155 | } |
1236 | 1156 | ||
1237 | if ((model->flags & ALPS_PASS) && | 1157 | if ((priv->flags & ALPS_PASS) && |
1238 | alps_passthrough_mode_v2(psmouse, false)) { | 1158 | alps_passthrough_mode_v2(psmouse, false)) { |
1239 | return -1; | 1159 | return -1; |
1240 | } | 1160 | } |
@@ -1249,26 +1169,31 @@ static int alps_hw_init_v1_v2(struct psmouse *psmouse) | |||
1249 | } | 1169 | } |
1250 | 1170 | ||
1251 | /* | 1171 | /* |
1252 | * Enable or disable passthrough mode to the trackstick. Must be in | 1172 | * Enable or disable passthrough mode to the trackstick. |
1253 | * command mode when calling this function. | ||
1254 | */ | 1173 | */ |
1255 | static int alps_passthrough_mode_v3(struct psmouse *psmouse, bool enable) | 1174 | static int alps_passthrough_mode_v3(struct psmouse *psmouse, |
1175 | int reg_base, bool enable) | ||
1256 | { | 1176 | { |
1257 | int reg_val; | 1177 | int reg_val, ret = -1; |
1258 | 1178 | ||
1259 | reg_val = alps_command_mode_read_reg(psmouse, 0x0008); | 1179 | if (alps_enter_command_mode(psmouse, NULL)) |
1260 | if (reg_val == -1) | ||
1261 | return -1; | 1180 | return -1; |
1262 | 1181 | ||
1182 | reg_val = alps_command_mode_read_reg(psmouse, reg_base + 0x0008); | ||
1183 | if (reg_val == -1) | ||
1184 | goto error; | ||
1185 | |||
1263 | if (enable) | 1186 | if (enable) |
1264 | reg_val |= 0x01; | 1187 | reg_val |= 0x01; |
1265 | else | 1188 | else |
1266 | reg_val &= ~0x01; | 1189 | reg_val &= ~0x01; |
1267 | 1190 | ||
1268 | if (__alps_command_mode_write_reg(psmouse, reg_val)) | 1191 | ret = __alps_command_mode_write_reg(psmouse, reg_val); |
1269 | return -1; | ||
1270 | 1192 | ||
1271 | return 0; | 1193 | error: |
1194 | if (alps_exit_command_mode(psmouse)) | ||
1195 | ret = -1; | ||
1196 | return ret; | ||
1272 | } | 1197 | } |
1273 | 1198 | ||
1274 | /* Must be in command mode when calling this function */ | 1199 | /* Must be in command mode when calling this function */ |
@@ -1287,73 +1212,102 @@ static int alps_absolute_mode_v3(struct psmouse *psmouse) | |||
1287 | return 0; | 1212 | return 0; |
1288 | } | 1213 | } |
1289 | 1214 | ||
1290 | static int alps_hw_init_v3(struct psmouse *psmouse) | 1215 | static int alps_probe_trackstick_v3(struct psmouse *psmouse, int reg_base) |
1291 | { | 1216 | { |
1292 | struct alps_data *priv = psmouse->private; | 1217 | int ret = -EIO, reg_val; |
1293 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
1294 | int reg_val; | ||
1295 | unsigned char param[4]; | ||
1296 | |||
1297 | priv->nibble_commands = alps_v3_nibble_commands; | ||
1298 | priv->addr_command = PSMOUSE_CMD_RESET_WRAP; | ||
1299 | 1218 | ||
1300 | if (alps_enter_command_mode(psmouse, NULL)) | 1219 | if (alps_enter_command_mode(psmouse, NULL)) |
1301 | goto error; | 1220 | goto error; |
1302 | 1221 | ||
1303 | /* Check for trackstick */ | 1222 | reg_val = alps_command_mode_read_reg(psmouse, reg_base + 0x08); |
1304 | reg_val = alps_command_mode_read_reg(psmouse, 0x0008); | ||
1305 | if (reg_val == -1) | 1223 | if (reg_val == -1) |
1306 | goto error; | 1224 | goto error; |
1307 | if (reg_val & 0x80) { | 1225 | |
1308 | if (alps_passthrough_mode_v3(psmouse, true)) | 1226 | /* bit 7: trackstick is present */ |
1309 | goto error; | 1227 | ret = reg_val & 0x80 ? 0 : -ENODEV; |
1310 | if (alps_exit_command_mode(psmouse)) | 1228 | |
1311 | goto error; | 1229 | error: |
1230 | alps_exit_command_mode(psmouse); | ||
1231 | return ret; | ||
1232 | } | ||
1233 | |||
1234 | static int alps_setup_trackstick_v3(struct psmouse *psmouse, int reg_base) | ||
1235 | { | ||
1236 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
1237 | int ret = 0; | ||
1238 | unsigned char param[4]; | ||
1239 | |||
1240 | if (alps_passthrough_mode_v3(psmouse, reg_base, true)) | ||
1241 | return -EIO; | ||
1242 | |||
1243 | /* | ||
1244 | * E7 report for the trackstick | ||
1245 | * | ||
1246 | * There have been reports of failures to seem to trace back | ||
1247 | * to the above trackstick check failing. When these occur | ||
1248 | * this E7 report fails, so when that happens we continue | ||
1249 | * with the assumption that there isn't a trackstick after | ||
1250 | * all. | ||
1251 | */ | ||
1252 | if (alps_rpt_cmd(psmouse, 0, PSMOUSE_CMD_SETSCALE21, param)) { | ||
1253 | psmouse_warn(psmouse, "trackstick E7 report failed\n"); | ||
1254 | ret = -ENODEV; | ||
1255 | } else { | ||
1256 | psmouse_dbg(psmouse, | ||
1257 | "trackstick E7 report: %2.2x %2.2x %2.2x\n", | ||
1258 | param[0], param[1], param[2]); | ||
1312 | 1259 | ||
1313 | /* | 1260 | /* |
1314 | * E7 report for the trackstick | 1261 | * Not sure what this does, but it is absolutely |
1315 | * | 1262 | * essential. Without it, the touchpad does not |
1316 | * There have been reports of failures to seem to trace back | 1263 | * work at all and the trackstick just emits normal |
1317 | * to the above trackstick check failing. When these occur | 1264 | * PS/2 packets. |
1318 | * this E7 report fails, so when that happens we continue | ||
1319 | * with the assumption that there isn't a trackstick after | ||
1320 | * all. | ||
1321 | */ | 1265 | */ |
1322 | param[0] = 0x64; | 1266 | if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || |
1323 | if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) || | 1267 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || |
1324 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) || | 1268 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || |
1325 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) || | 1269 | alps_command_mode_send_nibble(psmouse, 0x9) || |
1326 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) { | 1270 | alps_command_mode_send_nibble(psmouse, 0x4)) { |
1327 | psmouse_warn(psmouse, "trackstick E7 report failed\n"); | 1271 | psmouse_err(psmouse, |
1328 | } else { | 1272 | "Error sending magic E6 sequence\n"); |
1329 | psmouse_dbg(psmouse, | 1273 | ret = -EIO; |
1330 | "trackstick E7 report: %2.2x %2.2x %2.2x\n", | 1274 | goto error; |
1331 | param[0], param[1], param[2]); | ||
1332 | |||
1333 | /* | ||
1334 | * Not sure what this does, but it is absolutely | ||
1335 | * essential. Without it, the touchpad does not | ||
1336 | * work at all and the trackstick just emits normal | ||
1337 | * PS/2 packets. | ||
1338 | */ | ||
1339 | if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || | ||
1340 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || | ||
1341 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || | ||
1342 | alps_command_mode_send_nibble(psmouse, 0x9) || | ||
1343 | alps_command_mode_send_nibble(psmouse, 0x4)) { | ||
1344 | psmouse_err(psmouse, | ||
1345 | "Error sending magic E6 sequence\n"); | ||
1346 | goto error_passthrough; | ||
1347 | } | ||
1348 | } | 1275 | } |
1349 | 1276 | ||
1350 | if (alps_enter_command_mode(psmouse, NULL)) | 1277 | /* |
1351 | goto error_passthrough; | 1278 | * This ensures the trackstick packets are in the format |
1352 | if (alps_passthrough_mode_v3(psmouse, false)) | 1279 | * supported by this driver. If bit 1 isn't set the packet |
1353 | goto error; | 1280 | * format is different. |
1281 | */ | ||
1282 | if (alps_enter_command_mode(psmouse, NULL) || | ||
1283 | alps_command_mode_write_reg(psmouse, | ||
1284 | reg_base + 0x08, 0x82) || | ||
1285 | alps_exit_command_mode(psmouse)) | ||
1286 | ret = -EIO; | ||
1354 | } | 1287 | } |
1355 | 1288 | ||
1356 | if (alps_absolute_mode_v3(psmouse)) { | 1289 | error: |
1290 | if (alps_passthrough_mode_v3(psmouse, reg_base, false)) | ||
1291 | ret = -EIO; | ||
1292 | |||
1293 | return ret; | ||
1294 | } | ||
1295 | |||
1296 | static int alps_hw_init_v3(struct psmouse *psmouse) | ||
1297 | { | ||
1298 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
1299 | int reg_val; | ||
1300 | unsigned char param[4]; | ||
1301 | |||
1302 | reg_val = alps_probe_trackstick_v3(psmouse, ALPS_REG_BASE_PINNACLE); | ||
1303 | if (reg_val == -EIO) | ||
1304 | goto error; | ||
1305 | if (reg_val == 0 && | ||
1306 | alps_setup_trackstick_v3(psmouse, ALPS_REG_BASE_PINNACLE) == -EIO) | ||
1307 | goto error; | ||
1308 | |||
1309 | if (alps_enter_command_mode(psmouse, NULL) || | ||
1310 | alps_absolute_mode_v3(psmouse)) { | ||
1357 | psmouse_err(psmouse, "Failed to enter absolute mode\n"); | 1311 | psmouse_err(psmouse, "Failed to enter absolute mode\n"); |
1358 | goto error; | 1312 | goto error; |
1359 | } | 1313 | } |
@@ -1390,14 +1344,6 @@ static int alps_hw_init_v3(struct psmouse *psmouse) | |||
1390 | if (alps_command_mode_write_reg(psmouse, 0x0162, 0x04)) | 1344 | if (alps_command_mode_write_reg(psmouse, 0x0162, 0x04)) |
1391 | goto error; | 1345 | goto error; |
1392 | 1346 | ||
1393 | /* | ||
1394 | * This ensures the trackstick packets are in the format | ||
1395 | * supported by this driver. If bit 1 isn't set the packet | ||
1396 | * format is different. | ||
1397 | */ | ||
1398 | if (alps_command_mode_write_reg(psmouse, 0x0008, 0x82)) | ||
1399 | goto error; | ||
1400 | |||
1401 | alps_exit_command_mode(psmouse); | 1347 | alps_exit_command_mode(psmouse); |
1402 | 1348 | ||
1403 | /* Set rate and enable data reporting */ | 1349 | /* Set rate and enable data reporting */ |
@@ -1410,10 +1356,6 @@ static int alps_hw_init_v3(struct psmouse *psmouse) | |||
1410 | 1356 | ||
1411 | return 0; | 1357 | return 0; |
1412 | 1358 | ||
1413 | error_passthrough: | ||
1414 | /* Something failed while in passthrough mode, so try to get out */ | ||
1415 | if (!alps_enter_command_mode(psmouse, NULL)) | ||
1416 | alps_passthrough_mode_v3(psmouse, false); | ||
1417 | error: | 1359 | error: |
1418 | /* | 1360 | /* |
1419 | * Leaving the touchpad in command mode will essentially render | 1361 | * Leaving the touchpad in command mode will essentially render |
@@ -1424,6 +1366,50 @@ error: | |||
1424 | return -1; | 1366 | return -1; |
1425 | } | 1367 | } |
1426 | 1368 | ||
1369 | static int alps_hw_init_rushmore_v3(struct psmouse *psmouse) | ||
1370 | { | ||
1371 | struct alps_data *priv = psmouse->private; | ||
1372 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
1373 | int reg_val, ret = -1; | ||
1374 | |||
1375 | if (priv->flags & ALPS_DUALPOINT) { | ||
1376 | reg_val = alps_setup_trackstick_v3(psmouse, | ||
1377 | ALPS_REG_BASE_RUSHMORE); | ||
1378 | if (reg_val == -EIO) | ||
1379 | goto error; | ||
1380 | if (reg_val == -ENODEV) | ||
1381 | priv->flags &= ~ALPS_DUALPOINT; | ||
1382 | } | ||
1383 | |||
1384 | if (alps_enter_command_mode(psmouse, NULL) || | ||
1385 | alps_command_mode_read_reg(psmouse, 0xc2d9) == -1 || | ||
1386 | alps_command_mode_write_reg(psmouse, 0xc2cb, 0x00)) | ||
1387 | goto error; | ||
1388 | |||
1389 | reg_val = alps_command_mode_read_reg(psmouse, 0xc2c6); | ||
1390 | if (reg_val == -1) | ||
1391 | goto error; | ||
1392 | if (__alps_command_mode_write_reg(psmouse, reg_val & 0xfd)) | ||
1393 | goto error; | ||
1394 | |||
1395 | if (alps_command_mode_write_reg(psmouse, 0xc2c9, 0x64)) | ||
1396 | goto error; | ||
1397 | |||
1398 | /* enter absolute mode */ | ||
1399 | reg_val = alps_command_mode_read_reg(psmouse, 0xc2c4); | ||
1400 | if (reg_val == -1) | ||
1401 | goto error; | ||
1402 | if (__alps_command_mode_write_reg(psmouse, reg_val | 0x02)) | ||
1403 | goto error; | ||
1404 | |||
1405 | alps_exit_command_mode(psmouse); | ||
1406 | return ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE); | ||
1407 | |||
1408 | error: | ||
1409 | alps_exit_command_mode(psmouse); | ||
1410 | return ret; | ||
1411 | } | ||
1412 | |||
1427 | /* Must be in command mode when calling this function */ | 1413 | /* Must be in command mode when calling this function */ |
1428 | static int alps_absolute_mode_v4(struct psmouse *psmouse) | 1414 | static int alps_absolute_mode_v4(struct psmouse *psmouse) |
1429 | { | 1415 | { |
@@ -1442,13 +1428,9 @@ static int alps_absolute_mode_v4(struct psmouse *psmouse) | |||
1442 | 1428 | ||
1443 | static int alps_hw_init_v4(struct psmouse *psmouse) | 1429 | static int alps_hw_init_v4(struct psmouse *psmouse) |
1444 | { | 1430 | { |
1445 | struct alps_data *priv = psmouse->private; | ||
1446 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 1431 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
1447 | unsigned char param[4]; | 1432 | unsigned char param[4]; |
1448 | 1433 | ||
1449 | priv->nibble_commands = alps_v4_nibble_commands; | ||
1450 | priv->addr_command = PSMOUSE_CMD_DISABLE; | ||
1451 | |||
1452 | if (alps_enter_command_mode(psmouse, NULL)) | 1434 | if (alps_enter_command_mode(psmouse, NULL)) |
1453 | goto error; | 1435 | goto error; |
1454 | 1436 | ||
@@ -1517,39 +1499,140 @@ error: | |||
1517 | return -1; | 1499 | return -1; |
1518 | } | 1500 | } |
1519 | 1501 | ||
1520 | static int alps_hw_init(struct psmouse *psmouse) | 1502 | static void alps_set_defaults(struct alps_data *priv) |
1521 | { | 1503 | { |
1522 | struct alps_data *priv = psmouse->private; | 1504 | priv->byte0 = 0x8f; |
1523 | const struct alps_model_info *model = priv->i; | 1505 | priv->mask0 = 0x8f; |
1524 | int ret = -1; | 1506 | priv->flags = ALPS_DUALPOINT; |
1507 | |||
1508 | priv->x_max = 2000; | ||
1509 | priv->y_max = 1400; | ||
1510 | priv->x_bits = 15; | ||
1511 | priv->y_bits = 11; | ||
1525 | 1512 | ||
1526 | switch (model->proto_version) { | 1513 | switch (priv->proto_version) { |
1527 | case ALPS_PROTO_V1: | 1514 | case ALPS_PROTO_V1: |
1528 | case ALPS_PROTO_V2: | 1515 | case ALPS_PROTO_V2: |
1529 | ret = alps_hw_init_v1_v2(psmouse); | 1516 | priv->hw_init = alps_hw_init_v1_v2; |
1517 | priv->process_packet = alps_process_packet_v1_v2; | ||
1518 | priv->set_abs_params = alps_set_abs_params_st; | ||
1530 | break; | 1519 | break; |
1531 | case ALPS_PROTO_V3: | 1520 | case ALPS_PROTO_V3: |
1532 | ret = alps_hw_init_v3(psmouse); | 1521 | priv->hw_init = alps_hw_init_v3; |
1522 | priv->process_packet = alps_process_packet_v3; | ||
1523 | priv->set_abs_params = alps_set_abs_params_mt; | ||
1524 | priv->decode_fields = alps_decode_pinnacle; | ||
1525 | priv->nibble_commands = alps_v3_nibble_commands; | ||
1526 | priv->addr_command = PSMOUSE_CMD_RESET_WRAP; | ||
1533 | break; | 1527 | break; |
1534 | case ALPS_PROTO_V4: | 1528 | case ALPS_PROTO_V4: |
1535 | ret = alps_hw_init_v4(psmouse); | 1529 | priv->hw_init = alps_hw_init_v4; |
1530 | priv->process_packet = alps_process_packet_v4; | ||
1531 | priv->set_abs_params = alps_set_abs_params_mt; | ||
1532 | priv->nibble_commands = alps_v4_nibble_commands; | ||
1533 | priv->addr_command = PSMOUSE_CMD_DISABLE; | ||
1536 | break; | 1534 | break; |
1537 | } | 1535 | } |
1536 | } | ||
1538 | 1537 | ||
1539 | return ret; | 1538 | static int alps_match_table(struct psmouse *psmouse, struct alps_data *priv, |
1539 | unsigned char *e7, unsigned char *ec) | ||
1540 | { | ||
1541 | const struct alps_model_info *model; | ||
1542 | int i; | ||
1543 | |||
1544 | for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) { | ||
1545 | model = &alps_model_data[i]; | ||
1546 | |||
1547 | if (!memcmp(e7, model->signature, sizeof(model->signature)) && | ||
1548 | (!model->command_mode_resp || | ||
1549 | model->command_mode_resp == ec[2])) { | ||
1550 | |||
1551 | priv->proto_version = model->proto_version; | ||
1552 | alps_set_defaults(priv); | ||
1553 | |||
1554 | priv->flags = model->flags; | ||
1555 | priv->byte0 = model->byte0; | ||
1556 | priv->mask0 = model->mask0; | ||
1557 | |||
1558 | return 0; | ||
1559 | } | ||
1560 | } | ||
1561 | |||
1562 | return -EINVAL; | ||
1563 | } | ||
1564 | |||
1565 | static int alps_identify(struct psmouse *psmouse, struct alps_data *priv) | ||
1566 | { | ||
1567 | unsigned char e6[4], e7[4], ec[4]; | ||
1568 | |||
1569 | /* | ||
1570 | * First try "E6 report". | ||
1571 | * ALPS should return 0,0,10 or 0,0,100 if no buttons are pressed. | ||
1572 | * The bits 0-2 of the first byte will be 1s if some buttons are | ||
1573 | * pressed. | ||
1574 | */ | ||
1575 | if (alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES, | ||
1576 | PSMOUSE_CMD_SETSCALE11, e6)) | ||
1577 | return -EIO; | ||
1578 | |||
1579 | if ((e6[0] & 0xf8) != 0 || e6[1] != 0 || (e6[2] != 10 && e6[2] != 100)) | ||
1580 | return -EINVAL; | ||
1581 | |||
1582 | /* | ||
1583 | * Now get the "E7" and "EC" reports. These will uniquely identify | ||
1584 | * most ALPS touchpads. | ||
1585 | */ | ||
1586 | if (alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES, | ||
1587 | PSMOUSE_CMD_SETSCALE21, e7) || | ||
1588 | alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES, | ||
1589 | PSMOUSE_CMD_RESET_WRAP, ec) || | ||
1590 | alps_exit_command_mode(psmouse)) | ||
1591 | return -EIO; | ||
1592 | |||
1593 | if (alps_match_table(psmouse, priv, e7, ec) == 0) { | ||
1594 | return 0; | ||
1595 | } else if (ec[0] == 0x88 && ec[1] == 0x08) { | ||
1596 | priv->proto_version = ALPS_PROTO_V3; | ||
1597 | alps_set_defaults(priv); | ||
1598 | |||
1599 | priv->hw_init = alps_hw_init_rushmore_v3; | ||
1600 | priv->decode_fields = alps_decode_rushmore; | ||
1601 | priv->x_bits = 16; | ||
1602 | priv->y_bits = 12; | ||
1603 | |||
1604 | /* hack to make addr_command, nibble_command available */ | ||
1605 | psmouse->private = priv; | ||
1606 | |||
1607 | if (alps_probe_trackstick_v3(psmouse, ALPS_REG_BASE_RUSHMORE)) | ||
1608 | priv->flags &= ~ALPS_DUALPOINT; | ||
1609 | |||
1610 | return 0; | ||
1611 | } else if (ec[0] == 0x88 && ec[1] == 0x07 && | ||
1612 | ec[2] >= 0x90 && ec[2] <= 0x9d) { | ||
1613 | priv->proto_version = ALPS_PROTO_V3; | ||
1614 | alps_set_defaults(priv); | ||
1615 | |||
1616 | return 0; | ||
1617 | } | ||
1618 | |||
1619 | psmouse_info(psmouse, | ||
1620 | "Unknown ALPS touchpad: E7=%2.2x %2.2x %2.2x, EC=%2.2x %2.2x %2.2x\n", | ||
1621 | e7[0], e7[1], e7[2], ec[0], ec[1], ec[2]); | ||
1622 | |||
1623 | return -EINVAL; | ||
1540 | } | 1624 | } |
1541 | 1625 | ||
1542 | static int alps_reconnect(struct psmouse *psmouse) | 1626 | static int alps_reconnect(struct psmouse *psmouse) |
1543 | { | 1627 | { |
1544 | const struct alps_model_info *model; | 1628 | struct alps_data *priv = psmouse->private; |
1545 | 1629 | ||
1546 | psmouse_reset(psmouse); | 1630 | psmouse_reset(psmouse); |
1547 | 1631 | ||
1548 | model = alps_get_model(psmouse, NULL); | 1632 | if (alps_identify(psmouse, priv) < 0) |
1549 | if (!model) | ||
1550 | return -1; | 1633 | return -1; |
1551 | 1634 | ||
1552 | return alps_hw_init(psmouse); | 1635 | return priv->hw_init(psmouse); |
1553 | } | 1636 | } |
1554 | 1637 | ||
1555 | static void alps_disconnect(struct psmouse *psmouse) | 1638 | static void alps_disconnect(struct psmouse *psmouse) |
@@ -1562,12 +1645,33 @@ static void alps_disconnect(struct psmouse *psmouse) | |||
1562 | kfree(priv); | 1645 | kfree(priv); |
1563 | } | 1646 | } |
1564 | 1647 | ||
1648 | static void alps_set_abs_params_st(struct alps_data *priv, | ||
1649 | struct input_dev *dev1) | ||
1650 | { | ||
1651 | input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0); | ||
1652 | input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0); | ||
1653 | } | ||
1654 | |||
1655 | static void alps_set_abs_params_mt(struct alps_data *priv, | ||
1656 | struct input_dev *dev1) | ||
1657 | { | ||
1658 | set_bit(INPUT_PROP_SEMI_MT, dev1->propbit); | ||
1659 | input_mt_init_slots(dev1, 2, 0); | ||
1660 | input_set_abs_params(dev1, ABS_MT_POSITION_X, 0, priv->x_max, 0, 0); | ||
1661 | input_set_abs_params(dev1, ABS_MT_POSITION_Y, 0, priv->y_max, 0, 0); | ||
1662 | |||
1663 | set_bit(BTN_TOOL_DOUBLETAP, dev1->keybit); | ||
1664 | set_bit(BTN_TOOL_TRIPLETAP, dev1->keybit); | ||
1665 | set_bit(BTN_TOOL_QUADTAP, dev1->keybit); | ||
1666 | |||
1667 | input_set_abs_params(dev1, ABS_X, 0, priv->x_max, 0, 0); | ||
1668 | input_set_abs_params(dev1, ABS_Y, 0, priv->y_max, 0, 0); | ||
1669 | } | ||
1670 | |||
1565 | int alps_init(struct psmouse *psmouse) | 1671 | int alps_init(struct psmouse *psmouse) |
1566 | { | 1672 | { |
1567 | struct alps_data *priv; | 1673 | struct alps_data *priv; |
1568 | const struct alps_model_info *model; | ||
1569 | struct input_dev *dev1 = psmouse->dev, *dev2; | 1674 | struct input_dev *dev1 = psmouse->dev, *dev2; |
1570 | int version; | ||
1571 | 1675 | ||
1572 | priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL); | 1676 | priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL); |
1573 | dev2 = input_allocate_device(); | 1677 | dev2 = input_allocate_device(); |
@@ -1581,13 +1685,10 @@ int alps_init(struct psmouse *psmouse) | |||
1581 | 1685 | ||
1582 | psmouse_reset(psmouse); | 1686 | psmouse_reset(psmouse); |
1583 | 1687 | ||
1584 | model = alps_get_model(psmouse, &version); | 1688 | if (alps_identify(psmouse, priv) < 0) |
1585 | if (!model) | ||
1586 | goto init_fail; | 1689 | goto init_fail; |
1587 | 1690 | ||
1588 | priv->i = model; | 1691 | if (priv->hw_init(psmouse)) |
1589 | |||
1590 | if (alps_hw_init(psmouse)) | ||
1591 | goto init_fail; | 1692 | goto init_fail; |
1592 | 1693 | ||
1593 | /* | 1694 | /* |
@@ -1609,41 +1710,20 @@ int alps_init(struct psmouse *psmouse) | |||
1609 | 1710 | ||
1610 | dev1->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS); | 1711 | dev1->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS); |
1611 | 1712 | ||
1612 | switch (model->proto_version) { | 1713 | priv->set_abs_params(priv, dev1); |
1613 | case ALPS_PROTO_V1: | ||
1614 | case ALPS_PROTO_V2: | ||
1615 | input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0); | ||
1616 | input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0); | ||
1617 | break; | ||
1618 | case ALPS_PROTO_V3: | ||
1619 | case ALPS_PROTO_V4: | ||
1620 | set_bit(INPUT_PROP_SEMI_MT, dev1->propbit); | ||
1621 | input_mt_init_slots(dev1, 2, 0); | ||
1622 | input_set_abs_params(dev1, ABS_MT_POSITION_X, 0, ALPS_V3_X_MAX, 0, 0); | ||
1623 | input_set_abs_params(dev1, ABS_MT_POSITION_Y, 0, ALPS_V3_Y_MAX, 0, 0); | ||
1624 | |||
1625 | set_bit(BTN_TOOL_DOUBLETAP, dev1->keybit); | ||
1626 | set_bit(BTN_TOOL_TRIPLETAP, dev1->keybit); | ||
1627 | set_bit(BTN_TOOL_QUADTAP, dev1->keybit); | ||
1628 | |||
1629 | input_set_abs_params(dev1, ABS_X, 0, ALPS_V3_X_MAX, 0, 0); | ||
1630 | input_set_abs_params(dev1, ABS_Y, 0, ALPS_V3_Y_MAX, 0, 0); | ||
1631 | break; | ||
1632 | } | ||
1633 | |||
1634 | input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0); | 1714 | input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0); |
1635 | 1715 | ||
1636 | if (model->flags & ALPS_WHEEL) { | 1716 | if (priv->flags & ALPS_WHEEL) { |
1637 | dev1->evbit[BIT_WORD(EV_REL)] |= BIT_MASK(EV_REL); | 1717 | dev1->evbit[BIT_WORD(EV_REL)] |= BIT_MASK(EV_REL); |
1638 | dev1->relbit[BIT_WORD(REL_WHEEL)] |= BIT_MASK(REL_WHEEL); | 1718 | dev1->relbit[BIT_WORD(REL_WHEEL)] |= BIT_MASK(REL_WHEEL); |
1639 | } | 1719 | } |
1640 | 1720 | ||
1641 | if (model->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) { | 1721 | if (priv->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) { |
1642 | dev1->keybit[BIT_WORD(BTN_FORWARD)] |= BIT_MASK(BTN_FORWARD); | 1722 | dev1->keybit[BIT_WORD(BTN_FORWARD)] |= BIT_MASK(BTN_FORWARD); |
1643 | dev1->keybit[BIT_WORD(BTN_BACK)] |= BIT_MASK(BTN_BACK); | 1723 | dev1->keybit[BIT_WORD(BTN_BACK)] |= BIT_MASK(BTN_BACK); |
1644 | } | 1724 | } |
1645 | 1725 | ||
1646 | if (model->flags & ALPS_FOUR_BUTTONS) { | 1726 | if (priv->flags & ALPS_FOUR_BUTTONS) { |
1647 | dev1->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_0); | 1727 | dev1->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_0); |
1648 | dev1->keybit[BIT_WORD(BTN_1)] |= BIT_MASK(BTN_1); | 1728 | dev1->keybit[BIT_WORD(BTN_1)] |= BIT_MASK(BTN_1); |
1649 | dev1->keybit[BIT_WORD(BTN_2)] |= BIT_MASK(BTN_2); | 1729 | dev1->keybit[BIT_WORD(BTN_2)] |= BIT_MASK(BTN_2); |
@@ -1654,7 +1734,8 @@ int alps_init(struct psmouse *psmouse) | |||
1654 | 1734 | ||
1655 | snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys); | 1735 | snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys); |
1656 | dev2->phys = priv->phys; | 1736 | dev2->phys = priv->phys; |
1657 | dev2->name = (model->flags & ALPS_DUALPOINT) ? "DualPoint Stick" : "PS/2 Mouse"; | 1737 | dev2->name = (priv->flags & ALPS_DUALPOINT) ? |
1738 | "DualPoint Stick" : "PS/2 Mouse"; | ||
1658 | dev2->id.bustype = BUS_I8042; | 1739 | dev2->id.bustype = BUS_I8042; |
1659 | dev2->id.vendor = 0x0002; | 1740 | dev2->id.vendor = 0x0002; |
1660 | dev2->id.product = PSMOUSE_ALPS; | 1741 | dev2->id.product = PSMOUSE_ALPS; |
@@ -1673,7 +1754,7 @@ int alps_init(struct psmouse *psmouse) | |||
1673 | psmouse->poll = alps_poll; | 1754 | psmouse->poll = alps_poll; |
1674 | psmouse->disconnect = alps_disconnect; | 1755 | psmouse->disconnect = alps_disconnect; |
1675 | psmouse->reconnect = alps_reconnect; | 1756 | psmouse->reconnect = alps_reconnect; |
1676 | psmouse->pktsize = model->proto_version == ALPS_PROTO_V4 ? 8 : 6; | 1757 | psmouse->pktsize = priv->proto_version == ALPS_PROTO_V4 ? 8 : 6; |
1677 | 1758 | ||
1678 | /* We are having trouble resyncing ALPS touchpads so disable it for now */ | 1759 | /* We are having trouble resyncing ALPS touchpads so disable it for now */ |
1679 | psmouse->resync_time = 0; | 1760 | psmouse->resync_time = 0; |
@@ -1690,18 +1771,16 @@ init_fail: | |||
1690 | 1771 | ||
1691 | int alps_detect(struct psmouse *psmouse, bool set_properties) | 1772 | int alps_detect(struct psmouse *psmouse, bool set_properties) |
1692 | { | 1773 | { |
1693 | int version; | 1774 | struct alps_data dummy; |
1694 | const struct alps_model_info *model; | ||
1695 | 1775 | ||
1696 | model = alps_get_model(psmouse, &version); | 1776 | if (alps_identify(psmouse, &dummy) < 0) |
1697 | if (!model) | ||
1698 | return -1; | 1777 | return -1; |
1699 | 1778 | ||
1700 | if (set_properties) { | 1779 | if (set_properties) { |
1701 | psmouse->vendor = "ALPS"; | 1780 | psmouse->vendor = "ALPS"; |
1702 | psmouse->name = model->flags & ALPS_DUALPOINT ? | 1781 | psmouse->name = dummy.flags & ALPS_DUALPOINT ? |
1703 | "DualPoint TouchPad" : "GlidePoint"; | 1782 | "DualPoint TouchPad" : "GlidePoint"; |
1704 | psmouse->model = version; | 1783 | psmouse->model = dummy.proto_version << 8; |
1705 | } | 1784 | } |
1706 | return 0; | 1785 | return 0; |
1707 | } | 1786 | } |
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h index ae1ac354c778..970480551b6e 100644 --- a/drivers/input/mouse/alps.h +++ b/drivers/input/mouse/alps.h | |||
@@ -12,35 +12,146 @@ | |||
12 | #ifndef _ALPS_H | 12 | #ifndef _ALPS_H |
13 | #define _ALPS_H | 13 | #define _ALPS_H |
14 | 14 | ||
15 | #define ALPS_PROTO_V1 0 | 15 | #define ALPS_PROTO_V1 1 |
16 | #define ALPS_PROTO_V2 1 | 16 | #define ALPS_PROTO_V2 2 |
17 | #define ALPS_PROTO_V3 2 | 17 | #define ALPS_PROTO_V3 3 |
18 | #define ALPS_PROTO_V4 3 | 18 | #define ALPS_PROTO_V4 4 |
19 | 19 | ||
20 | /** | ||
21 | * struct alps_model_info - touchpad ID table | ||
22 | * @signature: E7 response string to match. | ||
23 | * @command_mode_resp: For V3/V4 touchpads, the final byte of the EC response | ||
24 | * (aka command mode response) identifies the firmware minor version. This | ||
25 | * can be used to distinguish different hardware models which are not | ||
26 | * uniquely identifiable through their E7 responses. | ||
27 | * @proto_version: Indicates V1/V2/V3/... | ||
28 | * @byte0: Helps figure out whether a position report packet matches the | ||
29 | * known format for this model. The first byte of the report, ANDed with | ||
30 | * mask0, should match byte0. | ||
31 | * @mask0: The mask used to check the first byte of the report. | ||
32 | * @flags: Additional device capabilities (passthrough port, trackstick, etc.). | ||
33 | * | ||
34 | * Many (but not all) ALPS touchpads can be identified by looking at the | ||
35 | * values returned in the "E7 report" and/or the "EC report." This table | ||
36 | * lists a number of such touchpads. | ||
37 | */ | ||
20 | struct alps_model_info { | 38 | struct alps_model_info { |
21 | unsigned char signature[3]; | 39 | unsigned char signature[3]; |
22 | unsigned char command_mode_resp; /* v3/v4 only */ | 40 | unsigned char command_mode_resp; |
23 | unsigned char proto_version; | 41 | unsigned char proto_version; |
24 | unsigned char byte0, mask0; | 42 | unsigned char byte0, mask0; |
25 | unsigned char flags; | 43 | unsigned char flags; |
26 | }; | 44 | }; |
27 | 45 | ||
46 | /** | ||
47 | * struct alps_nibble_commands - encodings for register accesses | ||
48 | * @command: PS/2 command used for the nibble | ||
49 | * @data: Data supplied as an argument to the PS/2 command, if applicable | ||
50 | * | ||
51 | * The ALPS protocol uses magic sequences to transmit binary data to the | ||
52 | * touchpad, as it is generally not OK to send arbitrary bytes out the | ||
53 | * PS/2 port. Each of the sequences in this table sends one nibble of the | ||
54 | * register address or (write) data. Different versions of the ALPS protocol | ||
55 | * use slightly different encodings. | ||
56 | */ | ||
28 | struct alps_nibble_commands { | 57 | struct alps_nibble_commands { |
29 | int command; | 58 | int command; |
30 | unsigned char data; | 59 | unsigned char data; |
31 | }; | 60 | }; |
32 | 61 | ||
62 | /** | ||
63 | * struct alps_fields - decoded version of the report packet | ||
64 | * @x_map: Bitmap of active X positions for MT. | ||
65 | * @y_map: Bitmap of active Y positions for MT. | ||
66 | * @fingers: Number of fingers for MT. | ||
67 | * @x: X position for ST. | ||
68 | * @y: Y position for ST. | ||
69 | * @z: Z position for ST. | ||
70 | * @first_mp: Packet is the first of a multi-packet report. | ||
71 | * @is_mp: Packet is part of a multi-packet report. | ||
72 | * @left: Left touchpad button is active. | ||
73 | * @right: Right touchpad button is active. | ||
74 | * @middle: Middle touchpad button is active. | ||
75 | * @ts_left: Left trackstick button is active. | ||
76 | * @ts_right: Right trackstick button is active. | ||
77 | * @ts_middle: Middle trackstick button is active. | ||
78 | */ | ||
79 | struct alps_fields { | ||
80 | unsigned int x_map; | ||
81 | unsigned int y_map; | ||
82 | unsigned int fingers; | ||
83 | unsigned int x; | ||
84 | unsigned int y; | ||
85 | unsigned int z; | ||
86 | unsigned int first_mp:1; | ||
87 | unsigned int is_mp:1; | ||
88 | |||
89 | unsigned int left:1; | ||
90 | unsigned int right:1; | ||
91 | unsigned int middle:1; | ||
92 | |||
93 | unsigned int ts_left:1; | ||
94 | unsigned int ts_right:1; | ||
95 | unsigned int ts_middle:1; | ||
96 | }; | ||
97 | |||
98 | /** | ||
99 | * struct alps_data - private data structure for the ALPS driver | ||
100 | * @dev2: "Relative" device used to report trackstick or mouse activity. | ||
101 | * @phys: Physical path for the relative device. | ||
102 | * @nibble_commands: Command mapping used for touchpad register accesses. | ||
103 | * @addr_command: Command used to tell the touchpad that a register address | ||
104 | * follows. | ||
105 | * @proto_version: Indicates V1/V2/V3/... | ||
106 | * @byte0: Helps figure out whether a position report packet matches the | ||
107 | * known format for this model. The first byte of the report, ANDed with | ||
108 | * mask0, should match byte0. | ||
109 | * @mask0: The mask used to check the first byte of the report. | ||
110 | * @flags: Additional device capabilities (passthrough port, trackstick, etc.). | ||
111 | * @x_max: Largest possible X position value. | ||
112 | * @y_max: Largest possible Y position value. | ||
113 | * @x_bits: Number of X bits in the MT bitmap. | ||
114 | * @y_bits: Number of Y bits in the MT bitmap. | ||
115 | * @hw_init: Protocol-specific hardware init function. | ||
116 | * @process_packet: Protocol-specific function to process a report packet. | ||
117 | * @decode_fields: Protocol-specific function to read packet bitfields. | ||
118 | * @set_abs_params: Protocol-specific function to configure the input_dev. | ||
119 | * @prev_fin: Finger bit from previous packet. | ||
120 | * @multi_packet: Multi-packet data in progress. | ||
121 | * @multi_data: Saved multi-packet data. | ||
122 | * @x1: First X coordinate from last MT report. | ||
123 | * @x2: Second X coordinate from last MT report. | ||
124 | * @y1: First Y coordinate from last MT report. | ||
125 | * @y2: Second Y coordinate from last MT report. | ||
126 | * @fingers: Number of fingers from last MT report. | ||
127 | * @quirks: Bitmap of ALPS_QUIRK_*. | ||
128 | * @timer: Timer for flushing out the final report packet in the stream. | ||
129 | */ | ||
33 | struct alps_data { | 130 | struct alps_data { |
34 | struct input_dev *dev2; /* Relative device */ | 131 | struct input_dev *dev2; |
35 | char phys[32]; /* Phys */ | 132 | char phys[32]; |
36 | const struct alps_model_info *i;/* Info */ | 133 | |
134 | /* these are autodetected when the device is identified */ | ||
37 | const struct alps_nibble_commands *nibble_commands; | 135 | const struct alps_nibble_commands *nibble_commands; |
38 | int addr_command; /* Command to set register address */ | 136 | int addr_command; |
39 | int prev_fin; /* Finger bit from previous packet */ | 137 | unsigned char proto_version; |
40 | int multi_packet; /* Multi-packet data in progress */ | 138 | unsigned char byte0, mask0; |
41 | unsigned char multi_data[6]; /* Saved multi-packet data */ | 139 | unsigned char flags; |
42 | int x1, x2, y1, y2; /* Coordinates from last MT report */ | 140 | int x_max; |
43 | int fingers; /* Number of fingers from MT report */ | 141 | int y_max; |
142 | int x_bits; | ||
143 | int y_bits; | ||
144 | |||
145 | int (*hw_init)(struct psmouse *psmouse); | ||
146 | void (*process_packet)(struct psmouse *psmouse); | ||
147 | void (*decode_fields)(struct alps_fields *f, unsigned char *p); | ||
148 | void (*set_abs_params)(struct alps_data *priv, struct input_dev *dev1); | ||
149 | |||
150 | int prev_fin; | ||
151 | int multi_packet; | ||
152 | unsigned char multi_data[6]; | ||
153 | int x1, x2, y1, y2; | ||
154 | int fingers; | ||
44 | u8 quirks; | 155 | u8 quirks; |
45 | struct timer_list timer; | 156 | struct timer_list timer; |
46 | }; | 157 | }; |
diff --git a/drivers/input/mouse/cyapa.c b/drivers/input/mouse/cyapa.c new file mode 100644 index 000000000000..b409c3d7d4fb --- /dev/null +++ b/drivers/input/mouse/cyapa.c | |||
@@ -0,0 +1,973 @@ | |||
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-2012 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/interrupt.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/slab.h> | ||
24 | |||
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 | |||
156 | enum 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 | |||
165 | struct 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 | |||
182 | struct 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 */ | ||
203 | struct 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 | int irq; | ||
210 | bool irq_wake; /* irq wake is enabled */ | ||
211 | bool smbus; | ||
212 | |||
213 | /* read from query data region. */ | ||
214 | char product_id[16]; | ||
215 | u8 btn_capability; | ||
216 | u8 gen; | ||
217 | int max_abs_x; | ||
218 | int max_abs_y; | ||
219 | int physical_size_x; | ||
220 | int physical_size_y; | ||
221 | }; | ||
222 | |||
223 | static const u8 bl_deactivate[] = { 0x00, 0xff, 0x3b, 0x00, 0x01, 0x02, 0x03, | ||
224 | 0x04, 0x05, 0x06, 0x07 }; | ||
225 | static const u8 bl_exit[] = { 0x00, 0xff, 0xa5, 0x00, 0x01, 0x02, 0x03, 0x04, | ||
226 | 0x05, 0x06, 0x07 }; | ||
227 | |||
228 | struct cyapa_cmd_len { | ||
229 | u8 cmd; | ||
230 | u8 len; | ||
231 | }; | ||
232 | |||
233 | #define CYAPA_ADAPTER_FUNC_NONE 0 | ||
234 | #define CYAPA_ADAPTER_FUNC_I2C 1 | ||
235 | #define CYAPA_ADAPTER_FUNC_SMBUS 2 | ||
236 | #define CYAPA_ADAPTER_FUNC_BOTH 3 | ||
237 | |||
238 | /* | ||
239 | * macros for SMBus communication | ||
240 | */ | ||
241 | #define SMBUS_READ 0x01 | ||
242 | #define SMBUS_WRITE 0x00 | ||
243 | #define SMBUS_ENCODE_IDX(cmd, idx) ((cmd) | (((idx) & 0x03) << 1)) | ||
244 | #define SMBUS_ENCODE_RW(cmd, rw) ((cmd) | ((rw) & 0x01)) | ||
245 | #define SMBUS_BYTE_BLOCK_CMD_MASK 0x80 | ||
246 | #define SMBUS_GROUP_BLOCK_CMD_MASK 0x40 | ||
247 | |||
248 | /* for byte read/write command */ | ||
249 | #define CMD_RESET 0 | ||
250 | #define CMD_POWER_MODE 1 | ||
251 | #define CMD_DEV_STATUS 2 | ||
252 | #define SMBUS_BYTE_CMD(cmd) (((cmd) & 0x3f) << 1) | ||
253 | #define CYAPA_SMBUS_RESET SMBUS_BYTE_CMD(CMD_RESET) | ||
254 | #define CYAPA_SMBUS_POWER_MODE SMBUS_BYTE_CMD(CMD_POWER_MODE) | ||
255 | #define CYAPA_SMBUS_DEV_STATUS SMBUS_BYTE_CMD(CMD_DEV_STATUS) | ||
256 | |||
257 | /* for group registers read/write command */ | ||
258 | #define REG_GROUP_DATA 0 | ||
259 | #define REG_GROUP_CMD 2 | ||
260 | #define REG_GROUP_QUERY 3 | ||
261 | #define SMBUS_GROUP_CMD(grp) (0x80 | (((grp) & 0x07) << 3)) | ||
262 | #define CYAPA_SMBUS_GROUP_DATA SMBUS_GROUP_CMD(REG_GROUP_DATA) | ||
263 | #define CYAPA_SMBUS_GROUP_CMD SMBUS_GROUP_CMD(REG_GROUP_CMD) | ||
264 | #define CYAPA_SMBUS_GROUP_QUERY SMBUS_GROUP_CMD(REG_GROUP_QUERY) | ||
265 | |||
266 | /* for register block read/write command */ | ||
267 | #define CMD_BL_STATUS 0 | ||
268 | #define CMD_BL_HEAD 1 | ||
269 | #define CMD_BL_CMD 2 | ||
270 | #define CMD_BL_DATA 3 | ||
271 | #define CMD_BL_ALL 4 | ||
272 | #define CMD_BLK_PRODUCT_ID 5 | ||
273 | #define CMD_BLK_HEAD 6 | ||
274 | #define SMBUS_BLOCK_CMD(cmd) (0xc0 | (((cmd) & 0x1f) << 1)) | ||
275 | |||
276 | /* register block read/write command in bootloader mode */ | ||
277 | #define CYAPA_SMBUS_BL_STATUS SMBUS_BLOCK_CMD(CMD_BL_STATUS) | ||
278 | #define CYAPA_SMBUS_BL_HEAD SMBUS_BLOCK_CMD(CMD_BL_HEAD) | ||
279 | #define CYAPA_SMBUS_BL_CMD SMBUS_BLOCK_CMD(CMD_BL_CMD) | ||
280 | #define CYAPA_SMBUS_BL_DATA SMBUS_BLOCK_CMD(CMD_BL_DATA) | ||
281 | #define CYAPA_SMBUS_BL_ALL SMBUS_BLOCK_CMD(CMD_BL_ALL) | ||
282 | |||
283 | /* register block read/write command in operational mode */ | ||
284 | #define CYAPA_SMBUS_BLK_PRODUCT_ID SMBUS_BLOCK_CMD(CMD_BLK_PRODUCT_ID) | ||
285 | #define CYAPA_SMBUS_BLK_HEAD SMBUS_BLOCK_CMD(CMD_BLK_HEAD) | ||
286 | |||
287 | static const struct cyapa_cmd_len cyapa_i2c_cmds[] = { | ||
288 | { CYAPA_OFFSET_SOFT_RESET, 1 }, | ||
289 | { REG_OFFSET_COMMAND_BASE + 1, 1 }, | ||
290 | { REG_OFFSET_DATA_BASE, 1 }, | ||
291 | { REG_OFFSET_DATA_BASE, sizeof(struct cyapa_reg_data) }, | ||
292 | { REG_OFFSET_COMMAND_BASE, 0 }, | ||
293 | { REG_OFFSET_QUERY_BASE, QUERY_DATA_SIZE }, | ||
294 | { BL_HEAD_OFFSET, 3 }, | ||
295 | { BL_HEAD_OFFSET, 16 }, | ||
296 | { BL_HEAD_OFFSET, 16 }, | ||
297 | { BL_DATA_OFFSET, 16 }, | ||
298 | { BL_HEAD_OFFSET, 32 }, | ||
299 | { REG_OFFSET_QUERY_BASE, PRODUCT_ID_SIZE }, | ||
300 | { REG_OFFSET_DATA_BASE, 32 } | ||
301 | }; | ||
302 | |||
303 | static const struct cyapa_cmd_len cyapa_smbus_cmds[] = { | ||
304 | { CYAPA_SMBUS_RESET, 1 }, | ||
305 | { CYAPA_SMBUS_POWER_MODE, 1 }, | ||
306 | { CYAPA_SMBUS_DEV_STATUS, 1 }, | ||
307 | { CYAPA_SMBUS_GROUP_DATA, sizeof(struct cyapa_reg_data) }, | ||
308 | { CYAPA_SMBUS_GROUP_CMD, 2 }, | ||
309 | { CYAPA_SMBUS_GROUP_QUERY, QUERY_DATA_SIZE }, | ||
310 | { CYAPA_SMBUS_BL_STATUS, 3 }, | ||
311 | { CYAPA_SMBUS_BL_HEAD, 16 }, | ||
312 | { CYAPA_SMBUS_BL_CMD, 16 }, | ||
313 | { CYAPA_SMBUS_BL_DATA, 16 }, | ||
314 | { CYAPA_SMBUS_BL_ALL, 32 }, | ||
315 | { CYAPA_SMBUS_BLK_PRODUCT_ID, PRODUCT_ID_SIZE }, | ||
316 | { CYAPA_SMBUS_BLK_HEAD, 16 }, | ||
317 | }; | ||
318 | |||
319 | static ssize_t cyapa_i2c_reg_read_block(struct cyapa *cyapa, u8 reg, size_t len, | ||
320 | u8 *values) | ||
321 | { | ||
322 | return i2c_smbus_read_i2c_block_data(cyapa->client, reg, len, values); | ||
323 | } | ||
324 | |||
325 | static ssize_t cyapa_i2c_reg_write_block(struct cyapa *cyapa, u8 reg, | ||
326 | size_t len, const u8 *values) | ||
327 | { | ||
328 | return i2c_smbus_write_i2c_block_data(cyapa->client, reg, len, values); | ||
329 | } | ||
330 | |||
331 | /* | ||
332 | * cyapa_smbus_read_block - perform smbus block read command | ||
333 | * @cyapa - private data structure of the driver | ||
334 | * @cmd - the properly encoded smbus command | ||
335 | * @len - expected length of smbus command result | ||
336 | * @values - buffer to store smbus command result | ||
337 | * | ||
338 | * Returns negative errno, else the number of bytes written. | ||
339 | * | ||
340 | * Note: | ||
341 | * In trackpad device, the memory block allocated for I2C register map | ||
342 | * is 256 bytes, so the max read block for I2C bus is 256 bytes. | ||
343 | */ | ||
344 | static ssize_t cyapa_smbus_read_block(struct cyapa *cyapa, u8 cmd, size_t len, | ||
345 | u8 *values) | ||
346 | { | ||
347 | ssize_t ret; | ||
348 | u8 index; | ||
349 | u8 smbus_cmd; | ||
350 | u8 *buf; | ||
351 | struct i2c_client *client = cyapa->client; | ||
352 | |||
353 | if (!(SMBUS_BYTE_BLOCK_CMD_MASK & cmd)) | ||
354 | return -EINVAL; | ||
355 | |||
356 | if (SMBUS_GROUP_BLOCK_CMD_MASK & cmd) { | ||
357 | /* read specific block registers command. */ | ||
358 | smbus_cmd = SMBUS_ENCODE_RW(cmd, SMBUS_READ); | ||
359 | ret = i2c_smbus_read_block_data(client, smbus_cmd, values); | ||
360 | goto out; | ||
361 | } | ||
362 | |||
363 | ret = 0; | ||
364 | for (index = 0; index * I2C_SMBUS_BLOCK_MAX < len; index++) { | ||
365 | smbus_cmd = SMBUS_ENCODE_IDX(cmd, index); | ||
366 | smbus_cmd = SMBUS_ENCODE_RW(smbus_cmd, SMBUS_READ); | ||
367 | buf = values + I2C_SMBUS_BLOCK_MAX * index; | ||
368 | ret = i2c_smbus_read_block_data(client, smbus_cmd, buf); | ||
369 | if (ret < 0) | ||
370 | goto out; | ||
371 | } | ||
372 | |||
373 | out: | ||
374 | return ret > 0 ? len : ret; | ||
375 | } | ||
376 | |||
377 | static s32 cyapa_read_byte(struct cyapa *cyapa, u8 cmd_idx) | ||
378 | { | ||
379 | u8 cmd; | ||
380 | |||
381 | if (cyapa->smbus) { | ||
382 | cmd = cyapa_smbus_cmds[cmd_idx].cmd; | ||
383 | cmd = SMBUS_ENCODE_RW(cmd, SMBUS_READ); | ||
384 | } else { | ||
385 | cmd = cyapa_i2c_cmds[cmd_idx].cmd; | ||
386 | } | ||
387 | return i2c_smbus_read_byte_data(cyapa->client, cmd); | ||
388 | } | ||
389 | |||
390 | static s32 cyapa_write_byte(struct cyapa *cyapa, u8 cmd_idx, u8 value) | ||
391 | { | ||
392 | u8 cmd; | ||
393 | |||
394 | if (cyapa->smbus) { | ||
395 | cmd = cyapa_smbus_cmds[cmd_idx].cmd; | ||
396 | cmd = SMBUS_ENCODE_RW(cmd, SMBUS_WRITE); | ||
397 | } else { | ||
398 | cmd = cyapa_i2c_cmds[cmd_idx].cmd; | ||
399 | } | ||
400 | return i2c_smbus_write_byte_data(cyapa->client, cmd, value); | ||
401 | } | ||
402 | |||
403 | static ssize_t cyapa_read_block(struct cyapa *cyapa, u8 cmd_idx, u8 *values) | ||
404 | { | ||
405 | u8 cmd; | ||
406 | size_t len; | ||
407 | |||
408 | if (cyapa->smbus) { | ||
409 | cmd = cyapa_smbus_cmds[cmd_idx].cmd; | ||
410 | len = cyapa_smbus_cmds[cmd_idx].len; | ||
411 | return cyapa_smbus_read_block(cyapa, cmd, len, values); | ||
412 | } else { | ||
413 | cmd = cyapa_i2c_cmds[cmd_idx].cmd; | ||
414 | len = cyapa_i2c_cmds[cmd_idx].len; | ||
415 | return cyapa_i2c_reg_read_block(cyapa, cmd, len, values); | ||
416 | } | ||
417 | } | ||
418 | |||
419 | /* | ||
420 | * Query device for its current operating state. | ||
421 | * | ||
422 | */ | ||
423 | static int cyapa_get_state(struct cyapa *cyapa) | ||
424 | { | ||
425 | int ret; | ||
426 | u8 status[BL_STATUS_SIZE]; | ||
427 | |||
428 | cyapa->state = CYAPA_STATE_NO_DEVICE; | ||
429 | |||
430 | /* | ||
431 | * Get trackpad status by reading 3 registers starting from 0. | ||
432 | * If the device is in the bootloader, this will be BL_HEAD. | ||
433 | * If the device is in operation mode, this will be the DATA regs. | ||
434 | * | ||
435 | */ | ||
436 | ret = cyapa_i2c_reg_read_block(cyapa, BL_HEAD_OFFSET, BL_STATUS_SIZE, | ||
437 | status); | ||
438 | |||
439 | /* | ||
440 | * On smbus systems in OP mode, the i2c_reg_read will fail with | ||
441 | * -ETIMEDOUT. In this case, try again using the smbus equivalent | ||
442 | * command. This should return a BL_HEAD indicating CYAPA_STATE_OP. | ||
443 | */ | ||
444 | if (cyapa->smbus && (ret == -ETIMEDOUT || ret == -ENXIO)) | ||
445 | ret = cyapa_read_block(cyapa, CYAPA_CMD_BL_STATUS, status); | ||
446 | |||
447 | if (ret != BL_STATUS_SIZE) | ||
448 | goto error; | ||
449 | |||
450 | if ((status[REG_OP_STATUS] & OP_STATUS_SRC) == OP_STATUS_SRC) { | ||
451 | switch (status[REG_OP_STATUS] & OP_STATUS_DEV) { | ||
452 | case CYAPA_DEV_NORMAL: | ||
453 | case CYAPA_DEV_BUSY: | ||
454 | cyapa->state = CYAPA_STATE_OP; | ||
455 | break; | ||
456 | default: | ||
457 | ret = -EAGAIN; | ||
458 | goto error; | ||
459 | } | ||
460 | } else { | ||
461 | if (status[REG_BL_STATUS] & BL_STATUS_BUSY) | ||
462 | cyapa->state = CYAPA_STATE_BL_BUSY; | ||
463 | else if (status[REG_BL_ERROR] & BL_ERROR_BOOTLOADING) | ||
464 | cyapa->state = CYAPA_STATE_BL_ACTIVE; | ||
465 | else | ||
466 | cyapa->state = CYAPA_STATE_BL_IDLE; | ||
467 | } | ||
468 | |||
469 | return 0; | ||
470 | error: | ||
471 | return (ret < 0) ? ret : -EAGAIN; | ||
472 | } | ||
473 | |||
474 | /* | ||
475 | * Poll device for its status in a loop, waiting up to timeout for a response. | ||
476 | * | ||
477 | * When the device switches state, it usually takes ~300 ms. | ||
478 | * However, when running a new firmware image, the device must calibrate its | ||
479 | * sensors, which can take as long as 2 seconds. | ||
480 | * | ||
481 | * Note: The timeout has granularity of the polling rate, which is 100 ms. | ||
482 | * | ||
483 | * Returns: | ||
484 | * 0 when the device eventually responds with a valid non-busy state. | ||
485 | * -ETIMEDOUT if device never responds (too many -EAGAIN) | ||
486 | * < 0 other errors | ||
487 | */ | ||
488 | static int cyapa_poll_state(struct cyapa *cyapa, unsigned int timeout) | ||
489 | { | ||
490 | int ret; | ||
491 | int tries = timeout / 100; | ||
492 | |||
493 | ret = cyapa_get_state(cyapa); | ||
494 | while ((ret || cyapa->state >= CYAPA_STATE_BL_BUSY) && tries--) { | ||
495 | msleep(100); | ||
496 | ret = cyapa_get_state(cyapa); | ||
497 | } | ||
498 | return (ret == -EAGAIN || ret == -ETIMEDOUT) ? -ETIMEDOUT : ret; | ||
499 | } | ||
500 | |||
501 | static int cyapa_bl_deactivate(struct cyapa *cyapa) | ||
502 | { | ||
503 | int ret; | ||
504 | |||
505 | ret = cyapa_i2c_reg_write_block(cyapa, 0, sizeof(bl_deactivate), | ||
506 | bl_deactivate); | ||
507 | if (ret < 0) | ||
508 | return ret; | ||
509 | |||
510 | /* wait for bootloader to switch to idle state; should take < 100ms */ | ||
511 | msleep(100); | ||
512 | ret = cyapa_poll_state(cyapa, 500); | ||
513 | if (ret < 0) | ||
514 | return ret; | ||
515 | if (cyapa->state != CYAPA_STATE_BL_IDLE) | ||
516 | return -EAGAIN; | ||
517 | return 0; | ||
518 | } | ||
519 | |||
520 | /* | ||
521 | * Exit bootloader | ||
522 | * | ||
523 | * Send bl_exit command, then wait 50 - 100 ms to let device transition to | ||
524 | * operational mode. If this is the first time the device's firmware is | ||
525 | * running, it can take up to 2 seconds to calibrate its sensors. So, poll | ||
526 | * the device's new state for up to 2 seconds. | ||
527 | * | ||
528 | * Returns: | ||
529 | * -EIO failure while reading from device | ||
530 | * -EAGAIN device is stuck in bootloader, b/c it has invalid firmware | ||
531 | * 0 device is supported and in operational mode | ||
532 | */ | ||
533 | static int cyapa_bl_exit(struct cyapa *cyapa) | ||
534 | { | ||
535 | int ret; | ||
536 | |||
537 | ret = cyapa_i2c_reg_write_block(cyapa, 0, sizeof(bl_exit), bl_exit); | ||
538 | if (ret < 0) | ||
539 | return ret; | ||
540 | |||
541 | /* | ||
542 | * Wait for bootloader to exit, and operation mode to start. | ||
543 | * Normally, this takes at least 50 ms. | ||
544 | */ | ||
545 | usleep_range(50000, 100000); | ||
546 | /* | ||
547 | * In addition, when a device boots for the first time after being | ||
548 | * updated to new firmware, it must first calibrate its sensors, which | ||
549 | * can take up to an additional 2 seconds. | ||
550 | */ | ||
551 | ret = cyapa_poll_state(cyapa, 2000); | ||
552 | if (ret < 0) | ||
553 | return ret; | ||
554 | if (cyapa->state != CYAPA_STATE_OP) | ||
555 | return -EAGAIN; | ||
556 | |||
557 | return 0; | ||
558 | } | ||
559 | |||
560 | /* | ||
561 | * Set device power mode | ||
562 | * | ||
563 | */ | ||
564 | static int cyapa_set_power_mode(struct cyapa *cyapa, u8 power_mode) | ||
565 | { | ||
566 | struct device *dev = &cyapa->client->dev; | ||
567 | int ret; | ||
568 | u8 power; | ||
569 | |||
570 | if (cyapa->state != CYAPA_STATE_OP) | ||
571 | return 0; | ||
572 | |||
573 | ret = cyapa_read_byte(cyapa, CYAPA_CMD_POWER_MODE); | ||
574 | if (ret < 0) | ||
575 | return ret; | ||
576 | |||
577 | power = ret & ~PWR_MODE_MASK; | ||
578 | power |= power_mode & PWR_MODE_MASK; | ||
579 | ret = cyapa_write_byte(cyapa, CYAPA_CMD_POWER_MODE, power); | ||
580 | if (ret < 0) | ||
581 | dev_err(dev, "failed to set power_mode 0x%02x err = %d\n", | ||
582 | power_mode, ret); | ||
583 | return ret; | ||
584 | } | ||
585 | |||
586 | static int cyapa_get_query_data(struct cyapa *cyapa) | ||
587 | { | ||
588 | u8 query_data[QUERY_DATA_SIZE]; | ||
589 | int ret; | ||
590 | |||
591 | if (cyapa->state != CYAPA_STATE_OP) | ||
592 | return -EBUSY; | ||
593 | |||
594 | ret = cyapa_read_block(cyapa, CYAPA_CMD_GROUP_QUERY, query_data); | ||
595 | if (ret < 0) | ||
596 | return ret; | ||
597 | if (ret != QUERY_DATA_SIZE) | ||
598 | return -EIO; | ||
599 | |||
600 | memcpy(&cyapa->product_id[0], &query_data[0], 5); | ||
601 | cyapa->product_id[5] = '-'; | ||
602 | memcpy(&cyapa->product_id[6], &query_data[5], 6); | ||
603 | cyapa->product_id[12] = '-'; | ||
604 | memcpy(&cyapa->product_id[13], &query_data[11], 2); | ||
605 | cyapa->product_id[15] = '\0'; | ||
606 | |||
607 | cyapa->btn_capability = query_data[19] & CAPABILITY_BTN_MASK; | ||
608 | |||
609 | cyapa->gen = query_data[20] & 0x0f; | ||
610 | |||
611 | cyapa->max_abs_x = ((query_data[21] & 0xf0) << 4) | query_data[22]; | ||
612 | cyapa->max_abs_y = ((query_data[21] & 0x0f) << 8) | query_data[23]; | ||
613 | |||
614 | cyapa->physical_size_x = | ||
615 | ((query_data[24] & 0xf0) << 4) | query_data[25]; | ||
616 | cyapa->physical_size_y = | ||
617 | ((query_data[24] & 0x0f) << 8) | query_data[26]; | ||
618 | |||
619 | return 0; | ||
620 | } | ||
621 | |||
622 | /* | ||
623 | * Check if device is operational. | ||
624 | * | ||
625 | * An operational device is responding, has exited bootloader, and has | ||
626 | * firmware supported by this driver. | ||
627 | * | ||
628 | * Returns: | ||
629 | * -EBUSY no device or in bootloader | ||
630 | * -EIO failure while reading from device | ||
631 | * -EAGAIN device is still in bootloader | ||
632 | * if ->state = CYAPA_STATE_BL_IDLE, device has invalid firmware | ||
633 | * -EINVAL device is in operational mode, but not supported by this driver | ||
634 | * 0 device is supported | ||
635 | */ | ||
636 | static int cyapa_check_is_operational(struct cyapa *cyapa) | ||
637 | { | ||
638 | struct device *dev = &cyapa->client->dev; | ||
639 | static const char unique_str[] = "CYTRA"; | ||
640 | int ret; | ||
641 | |||
642 | ret = cyapa_poll_state(cyapa, 2000); | ||
643 | if (ret < 0) | ||
644 | return ret; | ||
645 | switch (cyapa->state) { | ||
646 | case CYAPA_STATE_BL_ACTIVE: | ||
647 | ret = cyapa_bl_deactivate(cyapa); | ||
648 | if (ret) | ||
649 | return ret; | ||
650 | |||
651 | /* Fallthrough state */ | ||
652 | case CYAPA_STATE_BL_IDLE: | ||
653 | ret = cyapa_bl_exit(cyapa); | ||
654 | if (ret) | ||
655 | return ret; | ||
656 | |||
657 | /* Fallthrough state */ | ||
658 | case CYAPA_STATE_OP: | ||
659 | ret = cyapa_get_query_data(cyapa); | ||
660 | if (ret < 0) | ||
661 | return ret; | ||
662 | |||
663 | /* only support firmware protocol gen3 */ | ||
664 | if (cyapa->gen != CYAPA_GEN3) { | ||
665 | dev_err(dev, "unsupported protocol version (%d)", | ||
666 | cyapa->gen); | ||
667 | return -EINVAL; | ||
668 | } | ||
669 | |||
670 | /* only support product ID starting with CYTRA */ | ||
671 | if (memcmp(cyapa->product_id, unique_str, | ||
672 | sizeof(unique_str) - 1) != 0) { | ||
673 | dev_err(dev, "unsupported product ID (%s)\n", | ||
674 | cyapa->product_id); | ||
675 | return -EINVAL; | ||
676 | } | ||
677 | return 0; | ||
678 | |||
679 | default: | ||
680 | return -EIO; | ||
681 | } | ||
682 | return 0; | ||
683 | } | ||
684 | |||
685 | static irqreturn_t cyapa_irq(int irq, void *dev_id) | ||
686 | { | ||
687 | struct cyapa *cyapa = dev_id; | ||
688 | struct device *dev = &cyapa->client->dev; | ||
689 | struct input_dev *input = cyapa->input; | ||
690 | struct cyapa_reg_data data; | ||
691 | int i; | ||
692 | int ret; | ||
693 | int num_fingers; | ||
694 | |||
695 | if (device_may_wakeup(dev)) | ||
696 | pm_wakeup_event(dev, 0); | ||
697 | |||
698 | ret = cyapa_read_block(cyapa, CYAPA_CMD_GROUP_DATA, (u8 *)&data); | ||
699 | if (ret != sizeof(data)) | ||
700 | goto out; | ||
701 | |||
702 | if ((data.device_status & OP_STATUS_SRC) != OP_STATUS_SRC || | ||
703 | (data.device_status & OP_STATUS_DEV) != CYAPA_DEV_NORMAL || | ||
704 | (data.finger_btn & OP_DATA_VALID) != OP_DATA_VALID) { | ||
705 | goto out; | ||
706 | } | ||
707 | |||
708 | num_fingers = (data.finger_btn >> 4) & 0x0f; | ||
709 | for (i = 0; i < num_fingers; i++) { | ||
710 | const struct cyapa_touch *touch = &data.touches[i]; | ||
711 | /* Note: touch->id range is 1 to 15; slots are 0 to 14. */ | ||
712 | int slot = touch->id - 1; | ||
713 | |||
714 | input_mt_slot(input, slot); | ||
715 | input_mt_report_slot_state(input, MT_TOOL_FINGER, true); | ||
716 | input_report_abs(input, ABS_MT_POSITION_X, | ||
717 | ((touch->xy_hi & 0xf0) << 4) | touch->x_lo); | ||
718 | input_report_abs(input, ABS_MT_POSITION_Y, | ||
719 | ((touch->xy_hi & 0x0f) << 8) | touch->y_lo); | ||
720 | input_report_abs(input, ABS_MT_PRESSURE, touch->pressure); | ||
721 | } | ||
722 | |||
723 | input_mt_sync_frame(input); | ||
724 | |||
725 | if (cyapa->btn_capability & CAPABILITY_LEFT_BTN_MASK) | ||
726 | input_report_key(input, BTN_LEFT, | ||
727 | data.finger_btn & OP_DATA_LEFT_BTN); | ||
728 | |||
729 | if (cyapa->btn_capability & CAPABILITY_MIDDLE_BTN_MASK) | ||
730 | input_report_key(input, BTN_MIDDLE, | ||
731 | data.finger_btn & OP_DATA_MIDDLE_BTN); | ||
732 | |||
733 | if (cyapa->btn_capability & CAPABILITY_RIGHT_BTN_MASK) | ||
734 | input_report_key(input, BTN_RIGHT, | ||
735 | data.finger_btn & OP_DATA_RIGHT_BTN); | ||
736 | |||
737 | input_sync(input); | ||
738 | |||
739 | out: | ||
740 | return IRQ_HANDLED; | ||
741 | } | ||
742 | |||
743 | static u8 cyapa_check_adapter_functionality(struct i2c_client *client) | ||
744 | { | ||
745 | u8 ret = CYAPA_ADAPTER_FUNC_NONE; | ||
746 | |||
747 | if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) | ||
748 | ret |= CYAPA_ADAPTER_FUNC_I2C; | ||
749 | if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | | ||
750 | I2C_FUNC_SMBUS_BLOCK_DATA | | ||
751 | I2C_FUNC_SMBUS_I2C_BLOCK)) | ||
752 | ret |= CYAPA_ADAPTER_FUNC_SMBUS; | ||
753 | return ret; | ||
754 | } | ||
755 | |||
756 | static int cyapa_create_input_dev(struct cyapa *cyapa) | ||
757 | { | ||
758 | struct device *dev = &cyapa->client->dev; | ||
759 | int ret; | ||
760 | struct input_dev *input; | ||
761 | |||
762 | if (!cyapa->physical_size_x || !cyapa->physical_size_y) | ||
763 | return -EINVAL; | ||
764 | |||
765 | input = cyapa->input = input_allocate_device(); | ||
766 | if (!input) { | ||
767 | dev_err(dev, "allocate memory for input device failed\n"); | ||
768 | return -ENOMEM; | ||
769 | } | ||
770 | |||
771 | input->name = CYAPA_NAME; | ||
772 | input->phys = cyapa->phys; | ||
773 | input->id.bustype = BUS_I2C; | ||
774 | input->id.version = 1; | ||
775 | input->id.product = 0; /* means any product in eventcomm. */ | ||
776 | input->dev.parent = &cyapa->client->dev; | ||
777 | |||
778 | input_set_drvdata(input, cyapa); | ||
779 | |||
780 | __set_bit(EV_ABS, input->evbit); | ||
781 | |||
782 | /* finger position */ | ||
783 | input_set_abs_params(input, ABS_MT_POSITION_X, 0, cyapa->max_abs_x, 0, | ||
784 | 0); | ||
785 | input_set_abs_params(input, ABS_MT_POSITION_Y, 0, cyapa->max_abs_y, 0, | ||
786 | 0); | ||
787 | input_set_abs_params(input, ABS_MT_PRESSURE, 0, 255, 0, 0); | ||
788 | |||
789 | input_abs_set_res(input, ABS_MT_POSITION_X, | ||
790 | cyapa->max_abs_x / cyapa->physical_size_x); | ||
791 | input_abs_set_res(input, ABS_MT_POSITION_Y, | ||
792 | cyapa->max_abs_y / cyapa->physical_size_y); | ||
793 | |||
794 | if (cyapa->btn_capability & CAPABILITY_LEFT_BTN_MASK) | ||
795 | __set_bit(BTN_LEFT, input->keybit); | ||
796 | if (cyapa->btn_capability & CAPABILITY_MIDDLE_BTN_MASK) | ||
797 | __set_bit(BTN_MIDDLE, input->keybit); | ||
798 | if (cyapa->btn_capability & CAPABILITY_RIGHT_BTN_MASK) | ||
799 | __set_bit(BTN_RIGHT, input->keybit); | ||
800 | |||
801 | if (cyapa->btn_capability == CAPABILITY_LEFT_BTN_MASK) | ||
802 | __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); | ||
803 | |||
804 | /* handle pointer emulation and unused slots in core */ | ||
805 | ret = input_mt_init_slots(input, CYAPA_MAX_MT_SLOTS, | ||
806 | INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED); | ||
807 | if (ret) { | ||
808 | dev_err(dev, "allocate memory for MT slots failed, %d\n", ret); | ||
809 | goto err_free_device; | ||
810 | } | ||
811 | |||
812 | /* Register the device in input subsystem */ | ||
813 | ret = input_register_device(input); | ||
814 | if (ret) { | ||
815 | dev_err(dev, "input device register failed, %d\n", ret); | ||
816 | goto err_free_device; | ||
817 | } | ||
818 | return 0; | ||
819 | |||
820 | err_free_device: | ||
821 | input_free_device(input); | ||
822 | cyapa->input = NULL; | ||
823 | return ret; | ||
824 | } | ||
825 | |||
826 | static int cyapa_probe(struct i2c_client *client, | ||
827 | const struct i2c_device_id *dev_id) | ||
828 | { | ||
829 | int ret; | ||
830 | u8 adapter_func; | ||
831 | struct cyapa *cyapa; | ||
832 | struct device *dev = &client->dev; | ||
833 | |||
834 | adapter_func = cyapa_check_adapter_functionality(client); | ||
835 | if (adapter_func == CYAPA_ADAPTER_FUNC_NONE) { | ||
836 | dev_err(dev, "not a supported I2C/SMBus adapter\n"); | ||
837 | return -EIO; | ||
838 | } | ||
839 | |||
840 | cyapa = kzalloc(sizeof(struct cyapa), GFP_KERNEL); | ||
841 | if (!cyapa) { | ||
842 | dev_err(dev, "allocate memory for cyapa failed\n"); | ||
843 | return -ENOMEM; | ||
844 | } | ||
845 | |||
846 | cyapa->gen = CYAPA_GEN3; | ||
847 | cyapa->client = client; | ||
848 | i2c_set_clientdata(client, cyapa); | ||
849 | sprintf(cyapa->phys, "i2c-%d-%04x/input0", client->adapter->nr, | ||
850 | client->addr); | ||
851 | |||
852 | /* i2c isn't supported, use smbus */ | ||
853 | if (adapter_func == CYAPA_ADAPTER_FUNC_SMBUS) | ||
854 | cyapa->smbus = true; | ||
855 | cyapa->state = CYAPA_STATE_NO_DEVICE; | ||
856 | ret = cyapa_check_is_operational(cyapa); | ||
857 | if (ret) { | ||
858 | dev_err(dev, "device not operational, %d\n", ret); | ||
859 | goto err_mem_free; | ||
860 | } | ||
861 | |||
862 | ret = cyapa_create_input_dev(cyapa); | ||
863 | if (ret) { | ||
864 | dev_err(dev, "create input_dev instance failed, %d\n", ret); | ||
865 | goto err_mem_free; | ||
866 | } | ||
867 | |||
868 | ret = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE); | ||
869 | if (ret) { | ||
870 | dev_err(dev, "set active power failed, %d\n", ret); | ||
871 | goto err_unregister_device; | ||
872 | } | ||
873 | |||
874 | cyapa->irq = client->irq; | ||
875 | ret = request_threaded_irq(cyapa->irq, | ||
876 | NULL, | ||
877 | cyapa_irq, | ||
878 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
879 | "cyapa", | ||
880 | cyapa); | ||
881 | if (ret) { | ||
882 | dev_err(dev, "IRQ request failed: %d\n, ", ret); | ||
883 | goto err_unregister_device; | ||
884 | } | ||
885 | |||
886 | return 0; | ||
887 | |||
888 | err_unregister_device: | ||
889 | input_unregister_device(cyapa->input); | ||
890 | err_mem_free: | ||
891 | kfree(cyapa); | ||
892 | |||
893 | return ret; | ||
894 | } | ||
895 | |||
896 | static int cyapa_remove(struct i2c_client *client) | ||
897 | { | ||
898 | struct cyapa *cyapa = i2c_get_clientdata(client); | ||
899 | |||
900 | free_irq(cyapa->irq, cyapa); | ||
901 | input_unregister_device(cyapa->input); | ||
902 | cyapa_set_power_mode(cyapa, PWR_MODE_OFF); | ||
903 | kfree(cyapa); | ||
904 | |||
905 | return 0; | ||
906 | } | ||
907 | |||
908 | #ifdef CONFIG_PM_SLEEP | ||
909 | static int cyapa_suspend(struct device *dev) | ||
910 | { | ||
911 | int ret; | ||
912 | u8 power_mode; | ||
913 | struct cyapa *cyapa = dev_get_drvdata(dev); | ||
914 | |||
915 | disable_irq(cyapa->irq); | ||
916 | |||
917 | /* | ||
918 | * Set trackpad device to idle mode if wakeup is allowed, | ||
919 | * otherwise turn off. | ||
920 | */ | ||
921 | power_mode = device_may_wakeup(dev) ? PWR_MODE_IDLE | ||
922 | : PWR_MODE_OFF; | ||
923 | ret = cyapa_set_power_mode(cyapa, power_mode); | ||
924 | if (ret < 0) | ||
925 | dev_err(dev, "set power mode failed, %d\n", ret); | ||
926 | |||
927 | if (device_may_wakeup(dev)) | ||
928 | cyapa->irq_wake = (enable_irq_wake(cyapa->irq) == 0); | ||
929 | return 0; | ||
930 | } | ||
931 | |||
932 | static int cyapa_resume(struct device *dev) | ||
933 | { | ||
934 | int ret; | ||
935 | struct cyapa *cyapa = dev_get_drvdata(dev); | ||
936 | |||
937 | if (device_may_wakeup(dev) && cyapa->irq_wake) | ||
938 | disable_irq_wake(cyapa->irq); | ||
939 | |||
940 | ret = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE); | ||
941 | if (ret) | ||
942 | dev_warn(dev, "resume active power failed, %d\n", ret); | ||
943 | |||
944 | enable_irq(cyapa->irq); | ||
945 | return 0; | ||
946 | } | ||
947 | #endif /* CONFIG_PM_SLEEP */ | ||
948 | |||
949 | static SIMPLE_DEV_PM_OPS(cyapa_pm_ops, cyapa_suspend, cyapa_resume); | ||
950 | |||
951 | static const struct i2c_device_id cyapa_id_table[] = { | ||
952 | { "cyapa", 0 }, | ||
953 | { }, | ||
954 | }; | ||
955 | MODULE_DEVICE_TABLE(i2c, cyapa_id_table); | ||
956 | |||
957 | static struct i2c_driver cyapa_driver = { | ||
958 | .driver = { | ||
959 | .name = "cyapa", | ||
960 | .owner = THIS_MODULE, | ||
961 | .pm = &cyapa_pm_ops, | ||
962 | }, | ||
963 | |||
964 | .probe = cyapa_probe, | ||
965 | .remove = cyapa_remove, | ||
966 | .id_table = cyapa_id_table, | ||
967 | }; | ||
968 | |||
969 | module_i2c_driver(cyapa_driver); | ||
970 | |||
971 | MODULE_DESCRIPTION("Cypress APA I2C Trackpad Driver"); | ||
972 | MODULE_AUTHOR("Dudley Du <dudl@cypress.com>"); | ||
973 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/mouse/cypress_ps2.c b/drivers/input/mouse/cypress_ps2.c new file mode 100644 index 000000000000..1673dc6c8092 --- /dev/null +++ b/drivers/input/mouse/cypress_ps2.c | |||
@@ -0,0 +1,725 @@ | |||
1 | /* | ||
2 | * Cypress Trackpad PS/2 mouse driver | ||
3 | * | ||
4 | * Copyright (c) 2012 Cypress Semiconductor Corporation. | ||
5 | * | ||
6 | * Author: | ||
7 | * Dudley Du <dudl@cypress.com> | ||
8 | * | ||
9 | * Additional contributors include: | ||
10 | * Kamal Mostafa <kamal@canonical.com> | ||
11 | * Kyle Fazzari <git@status.e4ward.com> | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify it | ||
14 | * under the terms of the GNU General Public License version 2 as published by | ||
15 | * the Free Software Foundation. | ||
16 | */ | ||
17 | |||
18 | #include <linux/init.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/serio.h> | ||
23 | #include <linux/libps2.h> | ||
24 | #include <linux/input.h> | ||
25 | #include <linux/input/mt.h> | ||
26 | #include <linux/sched.h> | ||
27 | #include <linux/wait.h> | ||
28 | |||
29 | #include "cypress_ps2.h" | ||
30 | |||
31 | #undef CYTP_DEBUG_VERBOSE /* define this and DEBUG for more verbose dump */ | ||
32 | |||
33 | static void cypress_set_packet_size(struct psmouse *psmouse, unsigned int n) | ||
34 | { | ||
35 | struct cytp_data *cytp = psmouse->private; | ||
36 | cytp->pkt_size = n; | ||
37 | } | ||
38 | |||
39 | static const unsigned char cytp_rate[] = {10, 20, 40, 60, 100, 200}; | ||
40 | static const unsigned char cytp_resolution[] = {0x00, 0x01, 0x02, 0x03}; | ||
41 | |||
42 | static int cypress_ps2_sendbyte(struct psmouse *psmouse, int value) | ||
43 | { | ||
44 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
45 | |||
46 | if (ps2_sendbyte(ps2dev, value & 0xff, CYTP_CMD_TIMEOUT) < 0) { | ||
47 | psmouse_dbg(psmouse, | ||
48 | "sending command 0x%02x failed, resp 0x%02x\n", | ||
49 | value & 0xff, ps2dev->nak); | ||
50 | if (ps2dev->nak == CYTP_PS2_RETRY) | ||
51 | return CYTP_PS2_RETRY; | ||
52 | else | ||
53 | return CYTP_PS2_ERROR; | ||
54 | } | ||
55 | |||
56 | #ifdef CYTP_DEBUG_VERBOSE | ||
57 | psmouse_dbg(psmouse, "sending command 0x%02x succeeded, resp 0xfa\n", | ||
58 | value & 0xff); | ||
59 | #endif | ||
60 | |||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static int cypress_ps2_ext_cmd(struct psmouse *psmouse, unsigned short cmd, | ||
65 | unsigned char data) | ||
66 | { | ||
67 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
68 | int tries = CYTP_PS2_CMD_TRIES; | ||
69 | int rc; | ||
70 | |||
71 | ps2_begin_command(ps2dev); | ||
72 | |||
73 | do { | ||
74 | /* | ||
75 | * Send extension command byte (0xE8 or 0xF3). | ||
76 | * If sending the command fails, send recovery command | ||
77 | * to make the device return to the ready state. | ||
78 | */ | ||
79 | rc = cypress_ps2_sendbyte(psmouse, cmd & 0xff); | ||
80 | if (rc == CYTP_PS2_RETRY) { | ||
81 | rc = cypress_ps2_sendbyte(psmouse, 0x00); | ||
82 | if (rc == CYTP_PS2_RETRY) | ||
83 | rc = cypress_ps2_sendbyte(psmouse, 0x0a); | ||
84 | } | ||
85 | if (rc == CYTP_PS2_ERROR) | ||
86 | continue; | ||
87 | |||
88 | rc = cypress_ps2_sendbyte(psmouse, data); | ||
89 | if (rc == CYTP_PS2_RETRY) | ||
90 | rc = cypress_ps2_sendbyte(psmouse, data); | ||
91 | if (rc == CYTP_PS2_ERROR) | ||
92 | continue; | ||
93 | else | ||
94 | break; | ||
95 | } while (--tries > 0); | ||
96 | |||
97 | ps2_end_command(ps2dev); | ||
98 | |||
99 | return rc; | ||
100 | } | ||
101 | |||
102 | static int cypress_ps2_read_cmd_status(struct psmouse *psmouse, | ||
103 | unsigned char cmd, | ||
104 | unsigned char *param) | ||
105 | { | ||
106 | int rc; | ||
107 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
108 | enum psmouse_state old_state; | ||
109 | int pktsize; | ||
110 | |||
111 | ps2_begin_command(&psmouse->ps2dev); | ||
112 | |||
113 | old_state = psmouse->state; | ||
114 | psmouse->state = PSMOUSE_CMD_MODE; | ||
115 | psmouse->pktcnt = 0; | ||
116 | |||
117 | pktsize = (cmd == CYTP_CMD_READ_TP_METRICS) ? 8 : 3; | ||
118 | memset(param, 0, pktsize); | ||
119 | |||
120 | rc = cypress_ps2_sendbyte(psmouse, 0xe9); | ||
121 | if (rc < 0) | ||
122 | goto out; | ||
123 | |||
124 | wait_event_timeout(ps2dev->wait, | ||
125 | (psmouse->pktcnt >= pktsize), | ||
126 | msecs_to_jiffies(CYTP_CMD_TIMEOUT)); | ||
127 | |||
128 | memcpy(param, psmouse->packet, pktsize); | ||
129 | |||
130 | psmouse_dbg(psmouse, "Command 0x%02x response data (0x): %*ph\n", | ||
131 | cmd, pktsize, param); | ||
132 | |||
133 | out: | ||
134 | psmouse->state = old_state; | ||
135 | psmouse->pktcnt = 0; | ||
136 | |||
137 | ps2_end_command(&psmouse->ps2dev); | ||
138 | |||
139 | return rc; | ||
140 | } | ||
141 | |||
142 | static bool cypress_verify_cmd_state(struct psmouse *psmouse, | ||
143 | unsigned char cmd, unsigned char *param) | ||
144 | { | ||
145 | bool rate_match = false; | ||
146 | bool resolution_match = false; | ||
147 | int i; | ||
148 | |||
149 | /* callers will do further checking. */ | ||
150 | if (cmd == CYTP_CMD_READ_CYPRESS_ID || | ||
151 | cmd == CYTP_CMD_STANDARD_MODE || | ||
152 | cmd == CYTP_CMD_READ_TP_METRICS) | ||
153 | return true; | ||
154 | |||
155 | if ((~param[0] & DFLT_RESP_BITS_VALID) == DFLT_RESP_BITS_VALID && | ||
156 | (param[0] & DFLT_RESP_BIT_MODE) == DFLT_RESP_STREAM_MODE) { | ||
157 | for (i = 0; i < sizeof(cytp_resolution); i++) | ||
158 | if (cytp_resolution[i] == param[1]) | ||
159 | resolution_match = true; | ||
160 | |||
161 | for (i = 0; i < sizeof(cytp_rate); i++) | ||
162 | if (cytp_rate[i] == param[2]) | ||
163 | rate_match = true; | ||
164 | |||
165 | if (resolution_match && rate_match) | ||
166 | return true; | ||
167 | } | ||
168 | |||
169 | psmouse_dbg(psmouse, "verify cmd state failed.\n"); | ||
170 | return false; | ||
171 | } | ||
172 | |||
173 | static int cypress_send_ext_cmd(struct psmouse *psmouse, unsigned char cmd, | ||
174 | unsigned char *param) | ||
175 | { | ||
176 | int tries = CYTP_PS2_CMD_TRIES; | ||
177 | int rc; | ||
178 | |||
179 | psmouse_dbg(psmouse, "send extension cmd 0x%02x, [%d %d %d %d]\n", | ||
180 | cmd, DECODE_CMD_AA(cmd), DECODE_CMD_BB(cmd), | ||
181 | DECODE_CMD_CC(cmd), DECODE_CMD_DD(cmd)); | ||
182 | |||
183 | do { | ||
184 | cypress_ps2_ext_cmd(psmouse, | ||
185 | PSMOUSE_CMD_SETRES, DECODE_CMD_DD(cmd)); | ||
186 | cypress_ps2_ext_cmd(psmouse, | ||
187 | PSMOUSE_CMD_SETRES, DECODE_CMD_CC(cmd)); | ||
188 | cypress_ps2_ext_cmd(psmouse, | ||
189 | PSMOUSE_CMD_SETRES, DECODE_CMD_BB(cmd)); | ||
190 | cypress_ps2_ext_cmd(psmouse, | ||
191 | PSMOUSE_CMD_SETRES, DECODE_CMD_AA(cmd)); | ||
192 | |||
193 | rc = cypress_ps2_read_cmd_status(psmouse, cmd, param); | ||
194 | if (rc) | ||
195 | continue; | ||
196 | |||
197 | if (cypress_verify_cmd_state(psmouse, cmd, param)) | ||
198 | return 0; | ||
199 | |||
200 | } while (--tries > 0); | ||
201 | |||
202 | return -EIO; | ||
203 | } | ||
204 | |||
205 | int cypress_detect(struct psmouse *psmouse, bool set_properties) | ||
206 | { | ||
207 | unsigned char param[3]; | ||
208 | |||
209 | if (cypress_send_ext_cmd(psmouse, CYTP_CMD_READ_CYPRESS_ID, param)) | ||
210 | return -ENODEV; | ||
211 | |||
212 | /* Check for Cypress Trackpad signature bytes: 0x33 0xCC */ | ||
213 | if (param[0] != 0x33 || param[1] != 0xCC) | ||
214 | return -ENODEV; | ||
215 | |||
216 | if (set_properties) { | ||
217 | psmouse->vendor = "Cypress"; | ||
218 | psmouse->name = "Trackpad"; | ||
219 | } | ||
220 | |||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | static int cypress_read_fw_version(struct psmouse *psmouse) | ||
225 | { | ||
226 | struct cytp_data *cytp = psmouse->private; | ||
227 | unsigned char param[3]; | ||
228 | |||
229 | if (cypress_send_ext_cmd(psmouse, CYTP_CMD_READ_CYPRESS_ID, param)) | ||
230 | return -ENODEV; | ||
231 | |||
232 | /* Check for Cypress Trackpad signature bytes: 0x33 0xCC */ | ||
233 | if (param[0] != 0x33 || param[1] != 0xCC) | ||
234 | return -ENODEV; | ||
235 | |||
236 | cytp->fw_version = param[2] & FW_VERSION_MASX; | ||
237 | cytp->tp_metrics_supported = (param[2] & TP_METRICS_MASK) ? 1 : 0; | ||
238 | |||
239 | psmouse_dbg(psmouse, "cytp->fw_version = %d\n", cytp->fw_version); | ||
240 | psmouse_dbg(psmouse, "cytp->tp_metrics_supported = %d\n", | ||
241 | cytp->tp_metrics_supported); | ||
242 | |||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | static int cypress_read_tp_metrics(struct psmouse *psmouse) | ||
247 | { | ||
248 | struct cytp_data *cytp = psmouse->private; | ||
249 | unsigned char param[8]; | ||
250 | |||
251 | /* set default values for tp metrics. */ | ||
252 | cytp->tp_width = CYTP_DEFAULT_WIDTH; | ||
253 | cytp->tp_high = CYTP_DEFAULT_HIGH; | ||
254 | cytp->tp_max_abs_x = CYTP_ABS_MAX_X; | ||
255 | cytp->tp_max_abs_y = CYTP_ABS_MAX_Y; | ||
256 | cytp->tp_min_pressure = CYTP_MIN_PRESSURE; | ||
257 | cytp->tp_max_pressure = CYTP_MAX_PRESSURE; | ||
258 | cytp->tp_res_x = cytp->tp_max_abs_x / cytp->tp_width; | ||
259 | cytp->tp_res_y = cytp->tp_max_abs_y / cytp->tp_high; | ||
260 | |||
261 | memset(param, 0, sizeof(param)); | ||
262 | if (cypress_send_ext_cmd(psmouse, CYTP_CMD_READ_TP_METRICS, param) == 0) { | ||
263 | /* Update trackpad parameters. */ | ||
264 | cytp->tp_max_abs_x = (param[1] << 8) | param[0]; | ||
265 | cytp->tp_max_abs_y = (param[3] << 8) | param[2]; | ||
266 | cytp->tp_min_pressure = param[4]; | ||
267 | cytp->tp_max_pressure = param[5]; | ||
268 | } | ||
269 | |||
270 | if (!cytp->tp_max_pressure || | ||
271 | cytp->tp_max_pressure < cytp->tp_min_pressure || | ||
272 | !cytp->tp_width || !cytp->tp_high || | ||
273 | !cytp->tp_max_abs_x || | ||
274 | cytp->tp_max_abs_x < cytp->tp_width || | ||
275 | !cytp->tp_max_abs_y || | ||
276 | cytp->tp_max_abs_y < cytp->tp_high) | ||
277 | return -EINVAL; | ||
278 | |||
279 | cytp->tp_res_x = cytp->tp_max_abs_x / cytp->tp_width; | ||
280 | cytp->tp_res_y = cytp->tp_max_abs_y / cytp->tp_high; | ||
281 | |||
282 | #ifdef CYTP_DEBUG_VERBOSE | ||
283 | psmouse_dbg(psmouse, "Dump trackpad hardware configuration as below:\n"); | ||
284 | psmouse_dbg(psmouse, "cytp->tp_width = %d\n", cytp->tp_width); | ||
285 | psmouse_dbg(psmouse, "cytp->tp_high = %d\n", cytp->tp_high); | ||
286 | psmouse_dbg(psmouse, "cytp->tp_max_abs_x = %d\n", cytp->tp_max_abs_x); | ||
287 | psmouse_dbg(psmouse, "cytp->tp_max_abs_y = %d\n", cytp->tp_max_abs_y); | ||
288 | psmouse_dbg(psmouse, "cytp->tp_min_pressure = %d\n", cytp->tp_min_pressure); | ||
289 | psmouse_dbg(psmouse, "cytp->tp_max_pressure = %d\n", cytp->tp_max_pressure); | ||
290 | psmouse_dbg(psmouse, "cytp->tp_res_x = %d\n", cytp->tp_res_x); | ||
291 | psmouse_dbg(psmouse, "cytp->tp_res_y = %d\n", cytp->tp_res_y); | ||
292 | |||
293 | psmouse_dbg(psmouse, "tp_type_APA = %d\n", | ||
294 | (param[6] & TP_METRICS_BIT_APA) ? 1 : 0); | ||
295 | psmouse_dbg(psmouse, "tp_type_MTG = %d\n", | ||
296 | (param[6] & TP_METRICS_BIT_MTG) ? 1 : 0); | ||
297 | psmouse_dbg(psmouse, "tp_palm = %d\n", | ||
298 | (param[6] & TP_METRICS_BIT_PALM) ? 1 : 0); | ||
299 | psmouse_dbg(psmouse, "tp_stubborn = %d\n", | ||
300 | (param[6] & TP_METRICS_BIT_STUBBORN) ? 1 : 0); | ||
301 | psmouse_dbg(psmouse, "tp_1f_jitter = %d\n", | ||
302 | (param[6] & TP_METRICS_BIT_1F_JITTER) >> 2); | ||
303 | psmouse_dbg(psmouse, "tp_2f_jitter = %d\n", | ||
304 | (param[6] & TP_METRICS_BIT_2F_JITTER) >> 4); | ||
305 | psmouse_dbg(psmouse, "tp_1f_spike = %d\n", | ||
306 | param[7] & TP_METRICS_BIT_1F_SPIKE); | ||
307 | psmouse_dbg(psmouse, "tp_2f_spike = %d\n", | ||
308 | (param[7] & TP_METRICS_BIT_2F_SPIKE) >> 2); | ||
309 | psmouse_dbg(psmouse, "tp_abs_packet_format_set = %d\n", | ||
310 | (param[7] & TP_METRICS_BIT_ABS_PKT_FORMAT_SET) >> 4); | ||
311 | #endif | ||
312 | |||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | static int cypress_query_hardware(struct psmouse *psmouse) | ||
317 | { | ||
318 | struct cytp_data *cytp = psmouse->private; | ||
319 | int ret; | ||
320 | |||
321 | ret = cypress_read_fw_version(psmouse); | ||
322 | if (ret) | ||
323 | return ret; | ||
324 | |||
325 | if (cytp->tp_metrics_supported) { | ||
326 | ret = cypress_read_tp_metrics(psmouse); | ||
327 | if (ret) | ||
328 | return ret; | ||
329 | } | ||
330 | |||
331 | return 0; | ||
332 | } | ||
333 | |||
334 | static int cypress_set_absolute_mode(struct psmouse *psmouse) | ||
335 | { | ||
336 | struct cytp_data *cytp = psmouse->private; | ||
337 | unsigned char param[3]; | ||
338 | |||
339 | if (cypress_send_ext_cmd(psmouse, CYTP_CMD_ABS_WITH_PRESSURE_MODE, param) < 0) | ||
340 | return -1; | ||
341 | |||
342 | cytp->mode = (cytp->mode & ~CYTP_BIT_ABS_REL_MASK) | ||
343 | | CYTP_BIT_ABS_PRESSURE; | ||
344 | cypress_set_packet_size(psmouse, 5); | ||
345 | |||
346 | return 0; | ||
347 | } | ||
348 | |||
349 | /* | ||
350 | * Reset trackpad device. | ||
351 | * This is also the default mode when trackpad powered on. | ||
352 | */ | ||
353 | static void cypress_reset(struct psmouse *psmouse) | ||
354 | { | ||
355 | struct cytp_data *cytp = psmouse->private; | ||
356 | |||
357 | cytp->mode = 0; | ||
358 | |||
359 | psmouse_reset(psmouse); | ||
360 | } | ||
361 | |||
362 | static int cypress_set_input_params(struct input_dev *input, | ||
363 | struct cytp_data *cytp) | ||
364 | { | ||
365 | int ret; | ||
366 | |||
367 | if (!cytp->tp_res_x || !cytp->tp_res_y) | ||
368 | return -EINVAL; | ||
369 | |||
370 | __set_bit(EV_ABS, input->evbit); | ||
371 | input_set_abs_params(input, ABS_X, 0, cytp->tp_max_abs_x, 0, 0); | ||
372 | input_set_abs_params(input, ABS_Y, 0, cytp->tp_max_abs_y, 0, 0); | ||
373 | input_set_abs_params(input, ABS_PRESSURE, | ||
374 | cytp->tp_min_pressure, cytp->tp_max_pressure, 0, 0); | ||
375 | input_set_abs_params(input, ABS_TOOL_WIDTH, 0, 255, 0, 0); | ||
376 | |||
377 | /* finger position */ | ||
378 | input_set_abs_params(input, ABS_MT_POSITION_X, 0, cytp->tp_max_abs_x, 0, 0); | ||
379 | input_set_abs_params(input, ABS_MT_POSITION_Y, 0, cytp->tp_max_abs_y, 0, 0); | ||
380 | input_set_abs_params(input, ABS_MT_PRESSURE, 0, 255, 0, 0); | ||
381 | |||
382 | ret = input_mt_init_slots(input, CYTP_MAX_MT_SLOTS, | ||
383 | INPUT_MT_DROP_UNUSED|INPUT_MT_TRACK); | ||
384 | if (ret < 0) | ||
385 | return ret; | ||
386 | |||
387 | __set_bit(INPUT_PROP_SEMI_MT, input->propbit); | ||
388 | |||
389 | input_abs_set_res(input, ABS_X, cytp->tp_res_x); | ||
390 | input_abs_set_res(input, ABS_Y, cytp->tp_res_y); | ||
391 | |||
392 | input_abs_set_res(input, ABS_MT_POSITION_X, cytp->tp_res_x); | ||
393 | input_abs_set_res(input, ABS_MT_POSITION_Y, cytp->tp_res_y); | ||
394 | |||
395 | __set_bit(BTN_TOUCH, input->keybit); | ||
396 | __set_bit(BTN_TOOL_FINGER, input->keybit); | ||
397 | __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); | ||
398 | __set_bit(BTN_TOOL_TRIPLETAP, input->keybit); | ||
399 | __set_bit(BTN_TOOL_QUADTAP, input->keybit); | ||
400 | __set_bit(BTN_TOOL_QUINTTAP, input->keybit); | ||
401 | |||
402 | __clear_bit(EV_REL, input->evbit); | ||
403 | __clear_bit(REL_X, input->relbit); | ||
404 | __clear_bit(REL_Y, input->relbit); | ||
405 | |||
406 | __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); | ||
407 | __set_bit(EV_KEY, input->evbit); | ||
408 | __set_bit(BTN_LEFT, input->keybit); | ||
409 | __set_bit(BTN_RIGHT, input->keybit); | ||
410 | __set_bit(BTN_MIDDLE, input->keybit); | ||
411 | |||
412 | input_set_drvdata(input, cytp); | ||
413 | |||
414 | return 0; | ||
415 | } | ||
416 | |||
417 | static int cypress_get_finger_count(unsigned char header_byte) | ||
418 | { | ||
419 | unsigned char bits6_7; | ||
420 | int finger_count; | ||
421 | |||
422 | bits6_7 = header_byte >> 6; | ||
423 | finger_count = bits6_7 & 0x03; | ||
424 | |||
425 | if (finger_count == 1) | ||
426 | return 1; | ||
427 | |||
428 | if (header_byte & ABS_HSCROLL_BIT) { | ||
429 | /* HSCROLL gets added on to 0 finger count. */ | ||
430 | switch (finger_count) { | ||
431 | case 0: return 4; | ||
432 | case 2: return 5; | ||
433 | default: | ||
434 | /* Invalid contact (e.g. palm). Ignore it. */ | ||
435 | return -1; | ||
436 | } | ||
437 | } | ||
438 | |||
439 | return finger_count; | ||
440 | } | ||
441 | |||
442 | |||
443 | static int cypress_parse_packet(struct psmouse *psmouse, | ||
444 | struct cytp_data *cytp, struct cytp_report_data *report_data) | ||
445 | { | ||
446 | unsigned char *packet = psmouse->packet; | ||
447 | unsigned char header_byte = packet[0]; | ||
448 | int contact_cnt; | ||
449 | |||
450 | memset(report_data, 0, sizeof(struct cytp_report_data)); | ||
451 | |||
452 | contact_cnt = cypress_get_finger_count(header_byte); | ||
453 | |||
454 | if (contact_cnt < 0) /* e.g. palm detect */ | ||
455 | return -EINVAL; | ||
456 | |||
457 | report_data->contact_cnt = contact_cnt; | ||
458 | |||
459 | report_data->tap = (header_byte & ABS_MULTIFINGER_TAP) ? 1 : 0; | ||
460 | |||
461 | if (report_data->contact_cnt == 1) { | ||
462 | report_data->contacts[0].x = | ||
463 | ((packet[1] & 0x70) << 4) | packet[2]; | ||
464 | report_data->contacts[0].y = | ||
465 | ((packet[1] & 0x07) << 8) | packet[3]; | ||
466 | if (cytp->mode & CYTP_BIT_ABS_PRESSURE) | ||
467 | report_data->contacts[0].z = packet[4]; | ||
468 | |||
469 | } else if (report_data->contact_cnt >= 2) { | ||
470 | report_data->contacts[0].x = | ||
471 | ((packet[1] & 0x70) << 4) | packet[2]; | ||
472 | report_data->contacts[0].y = | ||
473 | ((packet[1] & 0x07) << 8) | packet[3]; | ||
474 | if (cytp->mode & CYTP_BIT_ABS_PRESSURE) | ||
475 | report_data->contacts[0].z = packet[4]; | ||
476 | |||
477 | report_data->contacts[1].x = | ||
478 | ((packet[5] & 0xf0) << 4) | packet[6]; | ||
479 | report_data->contacts[1].y = | ||
480 | ((packet[5] & 0x0f) << 8) | packet[7]; | ||
481 | if (cytp->mode & CYTP_BIT_ABS_PRESSURE) | ||
482 | report_data->contacts[1].z = report_data->contacts[0].z; | ||
483 | } | ||
484 | |||
485 | report_data->left = (header_byte & BTN_LEFT_BIT) ? 1 : 0; | ||
486 | report_data->right = (header_byte & BTN_RIGHT_BIT) ? 1 : 0; | ||
487 | |||
488 | /* | ||
489 | * This is only true if one of the mouse buttons were tapped. Make | ||
490 | * sure it doesn't turn into a click. The regular tap-to-click | ||
491 | * functionality will handle that on its own. If we don't do this, | ||
492 | * disabling tap-to-click won't affect the mouse button zones. | ||
493 | */ | ||
494 | if (report_data->tap) | ||
495 | report_data->left = 0; | ||
496 | |||
497 | #ifdef CYTP_DEBUG_VERBOSE | ||
498 | { | ||
499 | int i; | ||
500 | int n = report_data->contact_cnt; | ||
501 | psmouse_dbg(psmouse, "Dump parsed report data as below:\n"); | ||
502 | psmouse_dbg(psmouse, "contact_cnt = %d\n", | ||
503 | report_data->contact_cnt); | ||
504 | if (n > CYTP_MAX_MT_SLOTS) | ||
505 | n = CYTP_MAX_MT_SLOTS; | ||
506 | for (i = 0; i < n; i++) | ||
507 | psmouse_dbg(psmouse, "contacts[%d] = {%d, %d, %d}\n", i, | ||
508 | report_data->contacts[i].x, | ||
509 | report_data->contacts[i].y, | ||
510 | report_data->contacts[i].z); | ||
511 | psmouse_dbg(psmouse, "left = %d\n", report_data->left); | ||
512 | psmouse_dbg(psmouse, "right = %d\n", report_data->right); | ||
513 | psmouse_dbg(psmouse, "middle = %d\n", report_data->middle); | ||
514 | } | ||
515 | #endif | ||
516 | |||
517 | return 0; | ||
518 | } | ||
519 | |||
520 | static void cypress_process_packet(struct psmouse *psmouse, bool zero_pkt) | ||
521 | { | ||
522 | int i; | ||
523 | struct input_dev *input = psmouse->dev; | ||
524 | struct cytp_data *cytp = psmouse->private; | ||
525 | struct cytp_report_data report_data; | ||
526 | struct cytp_contact *contact; | ||
527 | struct input_mt_pos pos[CYTP_MAX_MT_SLOTS]; | ||
528 | int slots[CYTP_MAX_MT_SLOTS]; | ||
529 | int n; | ||
530 | |||
531 | if (cypress_parse_packet(psmouse, cytp, &report_data)) | ||
532 | return; | ||
533 | |||
534 | n = report_data.contact_cnt; | ||
535 | |||
536 | if (n > CYTP_MAX_MT_SLOTS) | ||
537 | n = CYTP_MAX_MT_SLOTS; | ||
538 | |||
539 | for (i = 0; i < n; i++) { | ||
540 | contact = &report_data.contacts[i]; | ||
541 | pos[i].x = contact->x; | ||
542 | pos[i].y = contact->y; | ||
543 | } | ||
544 | |||
545 | input_mt_assign_slots(input, slots, pos, n); | ||
546 | |||
547 | for (i = 0; i < n; i++) { | ||
548 | contact = &report_data.contacts[i]; | ||
549 | input_mt_slot(input, slots[i]); | ||
550 | input_mt_report_slot_state(input, MT_TOOL_FINGER, true); | ||
551 | input_report_abs(input, ABS_MT_POSITION_X, contact->x); | ||
552 | input_report_abs(input, ABS_MT_POSITION_Y, contact->y); | ||
553 | input_report_abs(input, ABS_MT_PRESSURE, contact->z); | ||
554 | } | ||
555 | |||
556 | input_mt_sync_frame(input); | ||
557 | |||
558 | input_mt_report_finger_count(input, report_data.contact_cnt); | ||
559 | |||
560 | input_report_key(input, BTN_LEFT, report_data.left); | ||
561 | input_report_key(input, BTN_RIGHT, report_data.right); | ||
562 | input_report_key(input, BTN_MIDDLE, report_data.middle); | ||
563 | |||
564 | input_sync(input); | ||
565 | } | ||
566 | |||
567 | static psmouse_ret_t cypress_validate_byte(struct psmouse *psmouse) | ||
568 | { | ||
569 | int contact_cnt; | ||
570 | int index = psmouse->pktcnt - 1; | ||
571 | unsigned char *packet = psmouse->packet; | ||
572 | struct cytp_data *cytp = psmouse->private; | ||
573 | |||
574 | if (index < 0 || index > cytp->pkt_size) | ||
575 | return PSMOUSE_BAD_DATA; | ||
576 | |||
577 | if (index == 0 && (packet[0] & 0xfc) == 0) { | ||
578 | /* call packet process for reporting finger leave. */ | ||
579 | cypress_process_packet(psmouse, 1); | ||
580 | return PSMOUSE_FULL_PACKET; | ||
581 | } | ||
582 | |||
583 | /* | ||
584 | * Perform validation (and adjust packet size) based only on the | ||
585 | * first byte; allow all further bytes through. | ||
586 | */ | ||
587 | if (index != 0) | ||
588 | return PSMOUSE_GOOD_DATA; | ||
589 | |||
590 | /* | ||
591 | * If absolute/relative mode bit has not been set yet, just pass | ||
592 | * the byte through. | ||
593 | */ | ||
594 | if ((cytp->mode & CYTP_BIT_ABS_REL_MASK) == 0) | ||
595 | return PSMOUSE_GOOD_DATA; | ||
596 | |||
597 | if ((packet[0] & 0x08) == 0x08) | ||
598 | return PSMOUSE_BAD_DATA; | ||
599 | |||
600 | contact_cnt = cypress_get_finger_count(packet[0]); | ||
601 | |||
602 | if (contact_cnt < 0) | ||
603 | return PSMOUSE_BAD_DATA; | ||
604 | |||
605 | if (cytp->mode & CYTP_BIT_ABS_NO_PRESSURE) | ||
606 | cypress_set_packet_size(psmouse, contact_cnt == 2 ? 7 : 4); | ||
607 | else | ||
608 | cypress_set_packet_size(psmouse, contact_cnt == 2 ? 8 : 5); | ||
609 | |||
610 | return PSMOUSE_GOOD_DATA; | ||
611 | } | ||
612 | |||
613 | static psmouse_ret_t cypress_protocol_handler(struct psmouse *psmouse) | ||
614 | { | ||
615 | struct cytp_data *cytp = psmouse->private; | ||
616 | |||
617 | if (psmouse->pktcnt >= cytp->pkt_size) { | ||
618 | cypress_process_packet(psmouse, 0); | ||
619 | return PSMOUSE_FULL_PACKET; | ||
620 | } | ||
621 | |||
622 | return cypress_validate_byte(psmouse); | ||
623 | } | ||
624 | |||
625 | static void cypress_set_rate(struct psmouse *psmouse, unsigned int rate) | ||
626 | { | ||
627 | struct cytp_data *cytp = psmouse->private; | ||
628 | |||
629 | if (rate >= 80) { | ||
630 | psmouse->rate = 80; | ||
631 | cytp->mode |= CYTP_BIT_HIGH_RATE; | ||
632 | } else { | ||
633 | psmouse->rate = 40; | ||
634 | cytp->mode &= ~CYTP_BIT_HIGH_RATE; | ||
635 | } | ||
636 | |||
637 | ps2_command(&psmouse->ps2dev, (unsigned char *)&psmouse->rate, | ||
638 | PSMOUSE_CMD_SETRATE); | ||
639 | } | ||
640 | |||
641 | static void cypress_disconnect(struct psmouse *psmouse) | ||
642 | { | ||
643 | cypress_reset(psmouse); | ||
644 | kfree(psmouse->private); | ||
645 | psmouse->private = NULL; | ||
646 | } | ||
647 | |||
648 | static int cypress_reconnect(struct psmouse *psmouse) | ||
649 | { | ||
650 | int tries = CYTP_PS2_CMD_TRIES; | ||
651 | int rc; | ||
652 | |||
653 | do { | ||
654 | cypress_reset(psmouse); | ||
655 | rc = cypress_detect(psmouse, false); | ||
656 | } while (rc && (--tries > 0)); | ||
657 | |||
658 | if (rc) { | ||
659 | psmouse_err(psmouse, "Reconnect: unable to detect trackpad.\n"); | ||
660 | return -1; | ||
661 | } | ||
662 | |||
663 | if (cypress_set_absolute_mode(psmouse)) { | ||
664 | psmouse_err(psmouse, "Reconnect: Unable to initialize Cypress absolute mode.\n"); | ||
665 | return -1; | ||
666 | } | ||
667 | |||
668 | return 0; | ||
669 | } | ||
670 | |||
671 | int cypress_init(struct psmouse *psmouse) | ||
672 | { | ||
673 | struct cytp_data *cytp; | ||
674 | |||
675 | cytp = (struct cytp_data *)kzalloc(sizeof(struct cytp_data), GFP_KERNEL); | ||
676 | psmouse->private = (void *)cytp; | ||
677 | if (cytp == NULL) | ||
678 | return -ENOMEM; | ||
679 | |||
680 | cypress_reset(psmouse); | ||
681 | |||
682 | psmouse->pktsize = 8; | ||
683 | |||
684 | if (cypress_query_hardware(psmouse)) { | ||
685 | psmouse_err(psmouse, "Unable to query Trackpad hardware.\n"); | ||
686 | goto err_exit; | ||
687 | } | ||
688 | |||
689 | if (cypress_set_absolute_mode(psmouse)) { | ||
690 | psmouse_err(psmouse, "init: Unable to initialize Cypress absolute mode.\n"); | ||
691 | goto err_exit; | ||
692 | } | ||
693 | |||
694 | if (cypress_set_input_params(psmouse->dev, cytp) < 0) { | ||
695 | psmouse_err(psmouse, "init: Unable to set input params.\n"); | ||
696 | goto err_exit; | ||
697 | } | ||
698 | |||
699 | psmouse->model = 1; | ||
700 | psmouse->protocol_handler = cypress_protocol_handler; | ||
701 | psmouse->set_rate = cypress_set_rate; | ||
702 | psmouse->disconnect = cypress_disconnect; | ||
703 | psmouse->reconnect = cypress_reconnect; | ||
704 | psmouse->cleanup = cypress_reset; | ||
705 | psmouse->resync_time = 0; | ||
706 | |||
707 | return 0; | ||
708 | |||
709 | err_exit: | ||
710 | /* | ||
711 | * Reset Cypress Trackpad as a standard mouse. Then | ||
712 | * let psmouse driver commmunicating with it as default PS2 mouse. | ||
713 | */ | ||
714 | cypress_reset(psmouse); | ||
715 | |||
716 | psmouse->private = NULL; | ||
717 | kfree(cytp); | ||
718 | |||
719 | return -1; | ||
720 | } | ||
721 | |||
722 | bool cypress_supported(void) | ||
723 | { | ||
724 | return true; | ||
725 | } | ||
diff --git a/drivers/input/mouse/cypress_ps2.h b/drivers/input/mouse/cypress_ps2.h new file mode 100644 index 000000000000..4720f21d2d70 --- /dev/null +++ b/drivers/input/mouse/cypress_ps2.h | |||
@@ -0,0 +1,191 @@ | |||
1 | #ifndef _CYPRESS_PS2_H | ||
2 | #define _CYPRESS_PS2_H | ||
3 | |||
4 | #include "psmouse.h" | ||
5 | |||
6 | #define CMD_BITS_MASK 0x03 | ||
7 | #define COMPOSIT(x, s) (((x) & CMD_BITS_MASK) << (s)) | ||
8 | |||
9 | #define ENCODE_CMD(aa, bb, cc, dd) \ | ||
10 | (COMPOSIT((aa), 6) | COMPOSIT((bb), 4) | COMPOSIT((cc), 2) | COMPOSIT((dd), 0)) | ||
11 | #define CYTP_CMD_ABS_NO_PRESSURE_MODE ENCODE_CMD(0, 1, 0, 0) | ||
12 | #define CYTP_CMD_ABS_WITH_PRESSURE_MODE ENCODE_CMD(0, 1, 0, 1) | ||
13 | #define CYTP_CMD_SMBUS_MODE ENCODE_CMD(0, 1, 1, 0) | ||
14 | #define CYTP_CMD_STANDARD_MODE ENCODE_CMD(0, 2, 0, 0) /* not implemented yet. */ | ||
15 | #define CYTP_CMD_CYPRESS_REL_MODE ENCODE_CMD(1, 1, 1, 1) /* not implemented yet. */ | ||
16 | #define CYTP_CMD_READ_CYPRESS_ID ENCODE_CMD(0, 0, 0, 0) | ||
17 | #define CYTP_CMD_READ_TP_METRICS ENCODE_CMD(0, 0, 0, 1) | ||
18 | #define CYTP_CMD_SET_HSCROLL_WIDTH(w) ENCODE_CMD(1, 1, 0, (w)) | ||
19 | #define CYTP_CMD_SET_HSCROLL_MASK ENCODE_CMD(1, 1, 0, 0) | ||
20 | #define CYTP_CMD_SET_VSCROLL_WIDTH(w) ENCODE_CMD(1, 2, 0, (w)) | ||
21 | #define CYTP_CMD_SET_VSCROLL_MASK ENCODE_CMD(1, 2, 0, 0) | ||
22 | #define CYTP_CMD_SET_PALM_GEOMETRY(e) ENCODE_CMD(1, 2, 1, (e)) | ||
23 | #define CYTP_CMD_PALM_GEMMETRY_MASK ENCODE_CMD(1, 2, 1, 0) | ||
24 | #define CYTP_CMD_SET_PALM_SENSITIVITY(s) ENCODE_CMD(1, 2, 2, (s)) | ||
25 | #define CYTP_CMD_PALM_SENSITIVITY_MASK ENCODE_CMD(1, 2, 2, 0) | ||
26 | #define CYTP_CMD_SET_MOUSE_SENSITIVITY(s) ENCODE_CMD(1, 3, ((s) >> 2), (s)) | ||
27 | #define CYTP_CMD_MOUSE_SENSITIVITY_MASK ENCODE_CMD(1, 3, 0, 0) | ||
28 | #define CYTP_CMD_REQUEST_BASELINE_STATUS ENCODE_CMD(2, 0, 0, 1) | ||
29 | #define CYTP_CMD_REQUEST_RECALIBRATION ENCODE_CMD(2, 0, 0, 3) | ||
30 | |||
31 | #define DECODE_CMD_AA(x) (((x) >> 6) & CMD_BITS_MASK) | ||
32 | #define DECODE_CMD_BB(x) (((x) >> 4) & CMD_BITS_MASK) | ||
33 | #define DECODE_CMD_CC(x) (((x) >> 2) & CMD_BITS_MASK) | ||
34 | #define DECODE_CMD_DD(x) ((x) & CMD_BITS_MASK) | ||
35 | |||
36 | /* Cypress trackpad working mode. */ | ||
37 | #define CYTP_BIT_ABS_PRESSURE (1 << 3) | ||
38 | #define CYTP_BIT_ABS_NO_PRESSURE (1 << 2) | ||
39 | #define CYTP_BIT_CYPRESS_REL (1 << 1) | ||
40 | #define CYTP_BIT_STANDARD_REL (1 << 0) | ||
41 | #define CYTP_BIT_REL_MASK (CYTP_BIT_CYPRESS_REL | CYTP_BIT_STANDARD_REL) | ||
42 | #define CYTP_BIT_ABS_MASK (CYTP_BIT_ABS_PRESSURE | CYTP_BIT_ABS_NO_PRESSURE) | ||
43 | #define CYTP_BIT_ABS_REL_MASK (CYTP_BIT_ABS_MASK | CYTP_BIT_REL_MASK) | ||
44 | |||
45 | #define CYTP_BIT_HIGH_RATE (1 << 4) | ||
46 | /* | ||
47 | * report mode bit is set, firmware working in Remote Mode. | ||
48 | * report mode bit is cleared, firmware working in Stream Mode. | ||
49 | */ | ||
50 | #define CYTP_BIT_REPORT_MODE (1 << 5) | ||
51 | |||
52 | /* scrolling width values for set HSCROLL and VSCROLL width command. */ | ||
53 | #define SCROLL_WIDTH_NARROW 1 | ||
54 | #define SCROLL_WIDTH_NORMAL 2 | ||
55 | #define SCROLL_WIDTH_WIDE 3 | ||
56 | |||
57 | #define PALM_GEOMETRY_ENABLE 1 | ||
58 | #define PALM_GEOMETRY_DISABLE 0 | ||
59 | |||
60 | #define TP_METRICS_MASK 0x80 | ||
61 | #define FW_VERSION_MASX 0x7f | ||
62 | #define FW_VER_HIGH_MASK 0x70 | ||
63 | #define FW_VER_LOW_MASK 0x0f | ||
64 | |||
65 | /* Times to retry a ps2_command and millisecond delay between tries. */ | ||
66 | #define CYTP_PS2_CMD_TRIES 3 | ||
67 | #define CYTP_PS2_CMD_DELAY 500 | ||
68 | |||
69 | /* time out for PS/2 command only in milliseconds. */ | ||
70 | #define CYTP_CMD_TIMEOUT 200 | ||
71 | #define CYTP_DATA_TIMEOUT 30 | ||
72 | |||
73 | #define CYTP_EXT_CMD 0xe8 | ||
74 | #define CYTP_PS2_RETRY 0xfe | ||
75 | #define CYTP_PS2_ERROR 0xfc | ||
76 | |||
77 | #define CYTP_RESP_RETRY 0x01 | ||
78 | #define CYTP_RESP_ERROR 0xfe | ||
79 | |||
80 | |||
81 | #define CYTP_105001_WIDTH 97 /* Dell XPS 13 */ | ||
82 | #define CYTP_105001_HIGH 59 | ||
83 | #define CYTP_DEFAULT_WIDTH (CYTP_105001_WIDTH) | ||
84 | #define CYTP_DEFAULT_HIGH (CYTP_105001_HIGH) | ||
85 | |||
86 | #define CYTP_ABS_MAX_X 1600 | ||
87 | #define CYTP_ABS_MAX_Y 900 | ||
88 | #define CYTP_MAX_PRESSURE 255 | ||
89 | #define CYTP_MIN_PRESSURE 0 | ||
90 | |||
91 | /* header byte bits of relative package. */ | ||
92 | #define BTN_LEFT_BIT 0x01 | ||
93 | #define BTN_RIGHT_BIT 0x02 | ||
94 | #define BTN_MIDDLE_BIT 0x04 | ||
95 | #define REL_X_SIGN_BIT 0x10 | ||
96 | #define REL_Y_SIGN_BIT 0x20 | ||
97 | |||
98 | /* header byte bits of absolute package. */ | ||
99 | #define ABS_VSCROLL_BIT 0x10 | ||
100 | #define ABS_HSCROLL_BIT 0x20 | ||
101 | #define ABS_MULTIFINGER_TAP 0x04 | ||
102 | #define ABS_EDGE_MOTION_MASK 0x80 | ||
103 | |||
104 | #define DFLT_RESP_BITS_VALID 0x88 /* SMBus bit should not be set. */ | ||
105 | #define DFLT_RESP_SMBUS_BIT 0x80 | ||
106 | #define DFLT_SMBUS_MODE 0x80 | ||
107 | #define DFLT_PS2_MODE 0x00 | ||
108 | #define DFLT_RESP_BIT_MODE 0x40 | ||
109 | #define DFLT_RESP_REMOTE_MODE 0x40 | ||
110 | #define DFLT_RESP_STREAM_MODE 0x00 | ||
111 | #define DFLT_RESP_BIT_REPORTING 0x20 | ||
112 | #define DFLT_RESP_BIT_SCALING 0x10 | ||
113 | |||
114 | #define TP_METRICS_BIT_PALM 0x80 | ||
115 | #define TP_METRICS_BIT_STUBBORN 0x40 | ||
116 | #define TP_METRICS_BIT_2F_JITTER 0x30 | ||
117 | #define TP_METRICS_BIT_1F_JITTER 0x0c | ||
118 | #define TP_METRICS_BIT_APA 0x02 | ||
119 | #define TP_METRICS_BIT_MTG 0x01 | ||
120 | #define TP_METRICS_BIT_ABS_PKT_FORMAT_SET 0xf0 | ||
121 | #define TP_METRICS_BIT_2F_SPIKE 0x0c | ||
122 | #define TP_METRICS_BIT_1F_SPIKE 0x03 | ||
123 | |||
124 | /* bits of first byte response of E9h-Status Request command. */ | ||
125 | #define RESP_BTN_RIGHT_BIT 0x01 | ||
126 | #define RESP_BTN_MIDDLE_BIT 0x02 | ||
127 | #define RESP_BTN_LEFT_BIT 0x04 | ||
128 | #define RESP_SCALING_BIT 0x10 | ||
129 | #define RESP_ENABLE_BIT 0x20 | ||
130 | #define RESP_REMOTE_BIT 0x40 | ||
131 | #define RESP_SMBUS_BIT 0x80 | ||
132 | |||
133 | #define CYTP_MAX_MT_SLOTS 2 | ||
134 | |||
135 | struct cytp_contact { | ||
136 | int x; | ||
137 | int y; | ||
138 | int z; /* also named as touch pressure. */ | ||
139 | }; | ||
140 | |||
141 | /* The structure of Cypress Trackpad event data. */ | ||
142 | struct cytp_report_data { | ||
143 | int contact_cnt; | ||
144 | struct cytp_contact contacts[CYTP_MAX_MT_SLOTS]; | ||
145 | unsigned int left:1; | ||
146 | unsigned int right:1; | ||
147 | unsigned int middle:1; | ||
148 | unsigned int tap:1; /* multi-finger tap detected. */ | ||
149 | }; | ||
150 | |||
151 | /* The structure of Cypress Trackpad device private data. */ | ||
152 | struct cytp_data { | ||
153 | int fw_version; | ||
154 | |||
155 | int pkt_size; | ||
156 | int mode; | ||
157 | |||
158 | int tp_min_pressure; | ||
159 | int tp_max_pressure; | ||
160 | int tp_width; /* X direction physical size in mm. */ | ||
161 | int tp_high; /* Y direction physical size in mm. */ | ||
162 | int tp_max_abs_x; /* Max X absolute units that can be reported. */ | ||
163 | int tp_max_abs_y; /* Max Y absolute units that can be reported. */ | ||
164 | |||
165 | int tp_res_x; /* X resolution in units/mm. */ | ||
166 | int tp_res_y; /* Y resolution in units/mm. */ | ||
167 | |||
168 | int tp_metrics_supported; | ||
169 | }; | ||
170 | |||
171 | |||
172 | #ifdef CONFIG_MOUSE_PS2_CYPRESS | ||
173 | int cypress_detect(struct psmouse *psmouse, bool set_properties); | ||
174 | int cypress_init(struct psmouse *psmouse); | ||
175 | bool cypress_supported(void); | ||
176 | #else | ||
177 | inline int cypress_detect(struct psmouse *psmouse, bool set_properties) | ||
178 | { | ||
179 | return -ENOSYS; | ||
180 | } | ||
181 | inline int cypress_init(struct psmouse *psmouse) | ||
182 | { | ||
183 | return -ENOSYS; | ||
184 | } | ||
185 | inline bool cypress_supported(void) | ||
186 | { | ||
187 | return 0; | ||
188 | } | ||
189 | #endif /* CONFIG_MOUSE_PS2_CYPRESS */ | ||
190 | |||
191 | #endif /* _CYPRESS_PS2_H */ | ||
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 22fe2547e169..cff065f6261c 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "touchkit_ps2.h" | 34 | #include "touchkit_ps2.h" |
35 | #include "elantech.h" | 35 | #include "elantech.h" |
36 | #include "sentelic.h" | 36 | #include "sentelic.h" |
37 | #include "cypress_ps2.h" | ||
37 | 38 | ||
38 | #define DRIVER_DESC "PS/2 mouse driver" | 39 | #define DRIVER_DESC "PS/2 mouse driver" |
39 | 40 | ||
@@ -759,6 +760,28 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
759 | } | 760 | } |
760 | 761 | ||
761 | /* | 762 | /* |
763 | * Try Cypress Trackpad. | ||
764 | * Must try it before Finger Sensing Pad because Finger Sensing Pad probe | ||
765 | * upsets some modules of Cypress Trackpads. | ||
766 | */ | ||
767 | if (max_proto > PSMOUSE_IMEX && | ||
768 | cypress_detect(psmouse, set_properties) == 0) { | ||
769 | if (cypress_supported()) { | ||
770 | if (cypress_init(psmouse) == 0) | ||
771 | return PSMOUSE_CYPRESS; | ||
772 | |||
773 | /* | ||
774 | * Finger Sensing Pad probe upsets some modules of | ||
775 | * Cypress Trackpad, must avoid Finger Sensing Pad | ||
776 | * probe if Cypress Trackpad device detected. | ||
777 | */ | ||
778 | return PSMOUSE_PS2; | ||
779 | } | ||
780 | |||
781 | max_proto = PSMOUSE_IMEX; | ||
782 | } | ||
783 | |||
784 | /* | ||
762 | * Try ALPS TouchPad | 785 | * Try ALPS TouchPad |
763 | */ | 786 | */ |
764 | if (max_proto > PSMOUSE_IMEX) { | 787 | if (max_proto > PSMOUSE_IMEX) { |
@@ -896,6 +919,15 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
896 | .alias = "thinkps", | 919 | .alias = "thinkps", |
897 | .detect = thinking_detect, | 920 | .detect = thinking_detect, |
898 | }, | 921 | }, |
922 | #ifdef CONFIG_MOUSE_PS2_CYPRESS | ||
923 | { | ||
924 | .type = PSMOUSE_CYPRESS, | ||
925 | .name = "CyPS/2", | ||
926 | .alias = "cypress", | ||
927 | .detect = cypress_detect, | ||
928 | .init = cypress_init, | ||
929 | }, | ||
930 | #endif | ||
899 | { | 931 | { |
900 | .type = PSMOUSE_GENPS, | 932 | .type = PSMOUSE_GENPS, |
901 | .name = "GenPS/2", | 933 | .name = "GenPS/2", |
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h index fe1df231ba4c..2f0b39d59a9b 100644 --- a/drivers/input/mouse/psmouse.h +++ b/drivers/input/mouse/psmouse.h | |||
@@ -95,6 +95,7 @@ enum psmouse_type { | |||
95 | PSMOUSE_ELANTECH, | 95 | PSMOUSE_ELANTECH, |
96 | PSMOUSE_FSP, | 96 | PSMOUSE_FSP, |
97 | PSMOUSE_SYNAPTICS_RELATIVE, | 97 | PSMOUSE_SYNAPTICS_RELATIVE, |
98 | PSMOUSE_CYPRESS, | ||
98 | PSMOUSE_AUTO /* This one should always be last */ | 99 | PSMOUSE_AUTO /* This one should always be last */ |
99 | }; | 100 | }; |
100 | 101 | ||
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 12d12ca3fee0..2f78538e09d0 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -722,11 +722,13 @@ static void synaptics_report_mt_data(struct psmouse *psmouse, | |||
722 | default: | 722 | default: |
723 | /* | 723 | /* |
724 | * If the finger slot contained in SGM is valid, and either | 724 | * If the finger slot contained in SGM is valid, and either |
725 | * hasn't changed, or is new, then report SGM in MTB slot 0. | 725 | * hasn't changed, or is new, or the old SGM has now moved to |
726 | * AGM, then report SGM in MTB slot 0. | ||
726 | * Otherwise, empty MTB slot 0. | 727 | * Otherwise, empty MTB slot 0. |
727 | */ | 728 | */ |
728 | if (mt_state->sgm != -1 && | 729 | if (mt_state->sgm != -1 && |
729 | (mt_state->sgm == old->sgm || old->sgm == -1)) | 730 | (mt_state->sgm == old->sgm || |
731 | old->sgm == -1 || mt_state->agm == old->sgm)) | ||
730 | synaptics_report_slot(dev, 0, sgm); | 732 | synaptics_report_slot(dev, 0, sgm); |
731 | else | 733 | else |
732 | synaptics_report_slot(dev, 0, NULL); | 734 | synaptics_report_slot(dev, 0, NULL); |
@@ -735,9 +737,31 @@ static void synaptics_report_mt_data(struct psmouse *psmouse, | |||
735 | * If the finger slot contained in AGM is valid, and either | 737 | * If the finger slot contained in AGM is valid, and either |
736 | * hasn't changed, or is new, then report AGM in MTB slot 1. | 738 | * hasn't changed, or is new, then report AGM in MTB slot 1. |
737 | * Otherwise, empty MTB slot 1. | 739 | * Otherwise, empty MTB slot 1. |
740 | * | ||
741 | * However, in the case where the AGM is new, make sure that | ||
742 | * that it is either the same as the old SGM, or there was no | ||
743 | * SGM. | ||
744 | * | ||
745 | * Otherwise, if the SGM was just 1, and the new AGM is 2, then | ||
746 | * the new AGM will keep the old SGM's tracking ID, which can | ||
747 | * cause apparent drumroll. This happens if in the following | ||
748 | * valid finger sequence: | ||
749 | * | ||
750 | * Action SGM AGM (MTB slot:Contact) | ||
751 | * 1. Touch contact 0 (0:0) | ||
752 | * 2. Touch contact 1 (0:0, 1:1) | ||
753 | * 3. Lift contact 0 (1:1) | ||
754 | * 4. Touch contacts 2,3 (0:2, 1:3) | ||
755 | * | ||
756 | * In step 4, contact 3, in AGM must not be given the same | ||
757 | * tracking ID as contact 1 had in step 3. To avoid this, | ||
758 | * the first agm with contact 3 is dropped and slot 1 is | ||
759 | * invalidated (tracking ID = -1). | ||
738 | */ | 760 | */ |
739 | if (mt_state->agm != -1 && | 761 | if (mt_state->agm != -1 && |
740 | (mt_state->agm == old->agm || old->agm == -1)) | 762 | (mt_state->agm == old->agm || |
763 | (old->agm == -1 && | ||
764 | (old->sgm == -1 || mt_state->agm == old->sgm)))) | ||
741 | synaptics_report_slot(dev, 1, agm); | 765 | synaptics_report_slot(dev, 1, agm); |
742 | else | 766 | else |
743 | synaptics_report_slot(dev, 1, NULL); | 767 | synaptics_report_slot(dev, 1, NULL); |
@@ -1247,11 +1271,11 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | |||
1247 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); | 1271 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); |
1248 | 1272 | ||
1249 | if (SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) { | 1273 | if (SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) { |
1250 | input_mt_init_slots(dev, 2, 0); | ||
1251 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, | 1274 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, |
1252 | ABS_MT_POSITION_Y); | 1275 | ABS_MT_POSITION_Y); |
1253 | /* Image sensors can report per-contact pressure */ | 1276 | /* Image sensors can report per-contact pressure */ |
1254 | input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 255, 0, 0); | 1277 | input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 255, 0, 0); |
1278 | input_mt_init_slots(dev, 2, INPUT_MT_POINTER); | ||
1255 | 1279 | ||
1256 | /* Image sensors can signal 4 and 5 finger clicks */ | 1280 | /* Image sensors can signal 4 and 5 finger clicks */ |
1257 | __set_bit(BTN_TOOL_QUADTAP, dev->keybit); | 1281 | __set_bit(BTN_TOOL_QUADTAP, dev->keybit); |
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index 4a4e182c33e7..560c243bfcaf 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig | |||
@@ -236,6 +236,7 @@ config SERIO_PS2MULT | |||
236 | 236 | ||
237 | config SERIO_ARC_PS2 | 237 | config SERIO_ARC_PS2 |
238 | tristate "ARC PS/2 support" | 238 | tristate "ARC PS/2 support" |
239 | depends on GENERIC_HARDIRQS | ||
239 | help | 240 | help |
240 | Say Y here if you have an ARC FPGA platform with a PS/2 | 241 | Say Y here if you have an ARC FPGA platform with a PS/2 |
241 | controller in it. | 242 | controller in it. |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 264138f3217e..41b6fbf60112 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -359,6 +359,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) | |||
359 | case 0x802: /* Intuos4 General Pen */ | 359 | case 0x802: /* Intuos4 General Pen */ |
360 | case 0x804: /* Intuos4 Marker Pen */ | 360 | case 0x804: /* Intuos4 Marker Pen */ |
361 | case 0x40802: /* Intuos4 Classic Pen */ | 361 | case 0x40802: /* Intuos4 Classic Pen */ |
362 | case 0x18803: /* DTH2242 Grip Pen */ | ||
362 | case 0x022: | 363 | case 0x022: |
363 | wacom->tool[idx] = BTN_TOOL_PEN; | 364 | wacom->tool[idx] = BTN_TOOL_PEN; |
364 | break; | 365 | break; |
@@ -538,6 +539,13 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
538 | input_report_key(input, wacom->tool[1], 0); | 539 | input_report_key(input, wacom->tool[1], 0); |
539 | input_report_abs(input, ABS_MISC, 0); | 540 | input_report_abs(input, ABS_MISC, 0); |
540 | } | 541 | } |
542 | } else if (features->type == DTK) { | ||
543 | input_report_key(input, BTN_0, (data[6] & 0x01)); | ||
544 | input_report_key(input, BTN_1, (data[6] & 0x02)); | ||
545 | input_report_key(input, BTN_2, (data[6] & 0x04)); | ||
546 | input_report_key(input, BTN_3, (data[6] & 0x08)); | ||
547 | input_report_key(input, BTN_4, (data[6] & 0x10)); | ||
548 | input_report_key(input, BTN_5, (data[6] & 0x20)); | ||
541 | } else if (features->type == WACOM_24HD) { | 549 | } else if (features->type == WACOM_24HD) { |
542 | input_report_key(input, BTN_0, (data[6] & 0x01)); | 550 | input_report_key(input, BTN_0, (data[6] & 0x01)); |
543 | input_report_key(input, BTN_1, (data[6] & 0x02)); | 551 | input_report_key(input, BTN_1, (data[6] & 0x02)); |
@@ -785,25 +793,6 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
785 | return 1; | 793 | return 1; |
786 | } | 794 | } |
787 | 795 | ||
788 | static int find_slot_from_contactid(struct wacom_wac *wacom, int contactid) | ||
789 | { | ||
790 | int touch_max = wacom->features.touch_max; | ||
791 | int i; | ||
792 | |||
793 | if (!wacom->slots) | ||
794 | return -1; | ||
795 | |||
796 | for (i = 0; i < touch_max; ++i) { | ||
797 | if (wacom->slots[i] == contactid) | ||
798 | return i; | ||
799 | } | ||
800 | for (i = 0; i < touch_max; ++i) { | ||
801 | if (wacom->slots[i] == -1) | ||
802 | return i; | ||
803 | } | ||
804 | return -1; | ||
805 | } | ||
806 | |||
807 | static int int_dist(int x1, int y1, int x2, int y2) | 796 | static int int_dist(int x1, int y1, int x2, int y2) |
808 | { | 797 | { |
809 | int x = x2 - x1; | 798 | int x = x2 - x1; |
@@ -833,8 +822,7 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom) | |||
833 | for (i = 0; i < contacts_to_send; i++) { | 822 | for (i = 0; i < contacts_to_send; i++) { |
834 | int offset = (WACOM_BYTES_PER_24HDT_PACKET * i) + 1; | 823 | int offset = (WACOM_BYTES_PER_24HDT_PACKET * i) + 1; |
835 | bool touch = data[offset] & 0x1 && !wacom->shared->stylus_in_proximity; | 824 | bool touch = data[offset] & 0x1 && !wacom->shared->stylus_in_proximity; |
836 | int id = data[offset + 1]; | 825 | int slot = input_mt_get_slot_by_key(input, data[offset + 1]); |
837 | int slot = find_slot_from_contactid(wacom, id); | ||
838 | 826 | ||
839 | if (slot < 0) | 827 | if (slot < 0) |
840 | continue; | 828 | continue; |
@@ -856,9 +844,7 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom) | |||
856 | input_report_abs(input, ABS_MT_WIDTH_MINOR, min(w, h)); | 844 | input_report_abs(input, ABS_MT_WIDTH_MINOR, min(w, h)); |
857 | input_report_abs(input, ABS_MT_ORIENTATION, w > h); | 845 | input_report_abs(input, ABS_MT_ORIENTATION, w > h); |
858 | } | 846 | } |
859 | wacom->slots[slot] = touch ? id : -1; | ||
860 | } | 847 | } |
861 | |||
862 | input_mt_report_pointer_emulation(input, true); | 848 | input_mt_report_pointer_emulation(input, true); |
863 | 849 | ||
864 | wacom->num_contacts_left -= contacts_to_send; | 850 | wacom->num_contacts_left -= contacts_to_send; |
@@ -895,7 +881,7 @@ static int wacom_mt_touch(struct wacom_wac *wacom) | |||
895 | int offset = (WACOM_BYTES_PER_MT_PACKET + x_offset) * i + 3; | 881 | int offset = (WACOM_BYTES_PER_MT_PACKET + x_offset) * i + 3; |
896 | bool touch = data[offset] & 0x1; | 882 | bool touch = data[offset] & 0x1; |
897 | int id = le16_to_cpup((__le16 *)&data[offset + 1]); | 883 | int id = le16_to_cpup((__le16 *)&data[offset + 1]); |
898 | int slot = find_slot_from_contactid(wacom, id); | 884 | int slot = input_mt_get_slot_by_key(input, id); |
899 | 885 | ||
900 | if (slot < 0) | 886 | if (slot < 0) |
901 | continue; | 887 | continue; |
@@ -908,9 +894,7 @@ static int wacom_mt_touch(struct wacom_wac *wacom) | |||
908 | input_report_abs(input, ABS_MT_POSITION_X, x); | 894 | input_report_abs(input, ABS_MT_POSITION_X, x); |
909 | input_report_abs(input, ABS_MT_POSITION_Y, y); | 895 | input_report_abs(input, ABS_MT_POSITION_Y, y); |
910 | } | 896 | } |
911 | wacom->slots[slot] = touch ? id : -1; | ||
912 | } | 897 | } |
913 | |||
914 | input_mt_report_pointer_emulation(input, true); | 898 | input_mt_report_pointer_emulation(input, true); |
915 | 899 | ||
916 | wacom->num_contacts_left -= contacts_to_send; | 900 | wacom->num_contacts_left -= contacts_to_send; |
@@ -942,12 +926,11 @@ static int wacom_tpc_mt_touch(struct wacom_wac *wacom) | |||
942 | contact_with_no_pen_down_count++; | 926 | contact_with_no_pen_down_count++; |
943 | } | 927 | } |
944 | } | 928 | } |
929 | input_mt_report_pointer_emulation(input, true); | ||
945 | 930 | ||
946 | /* keep touch state for pen event */ | 931 | /* keep touch state for pen event */ |
947 | wacom->shared->touch_down = (contact_with_no_pen_down_count > 0); | 932 | wacom->shared->touch_down = (contact_with_no_pen_down_count > 0); |
948 | 933 | ||
949 | input_mt_report_pointer_emulation(input, true); | ||
950 | |||
951 | return 1; | 934 | return 1; |
952 | } | 935 | } |
953 | 936 | ||
@@ -1104,12 +1087,15 @@ static int wacom_bpt_touch(struct wacom_wac *wacom) | |||
1104 | static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data) | 1087 | static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data) |
1105 | { | 1088 | { |
1106 | struct input_dev *input = wacom->input; | 1089 | struct input_dev *input = wacom->input; |
1107 | int slot_id = data[0] - 2; /* data[0] is between 2 and 17 */ | ||
1108 | bool touch = data[1] & 0x80; | 1090 | bool touch = data[1] & 0x80; |
1091 | int slot = input_mt_get_slot_by_key(input, data[0]); | ||
1092 | |||
1093 | if (slot < 0) | ||
1094 | return; | ||
1109 | 1095 | ||
1110 | touch = touch && !wacom->shared->stylus_in_proximity; | 1096 | touch = touch && !wacom->shared->stylus_in_proximity; |
1111 | 1097 | ||
1112 | input_mt_slot(input, slot_id); | 1098 | input_mt_slot(input, slot); |
1113 | input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); | 1099 | input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); |
1114 | 1100 | ||
1115 | if (touch) { | 1101 | if (touch) { |
@@ -1162,7 +1148,6 @@ static int wacom_bpt3_touch(struct wacom_wac *wacom) | |||
1162 | wacom_bpt3_button_msg(wacom, data + offset); | 1148 | wacom_bpt3_button_msg(wacom, data + offset); |
1163 | 1149 | ||
1164 | } | 1150 | } |
1165 | |||
1166 | input_mt_report_pointer_emulation(input, true); | 1151 | input_mt_report_pointer_emulation(input, true); |
1167 | 1152 | ||
1168 | input_sync(input); | 1153 | input_sync(input); |
@@ -1319,6 +1304,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | |||
1319 | case WACOM_21UX2: | 1304 | case WACOM_21UX2: |
1320 | case WACOM_22HD: | 1305 | case WACOM_22HD: |
1321 | case WACOM_24HD: | 1306 | case WACOM_24HD: |
1307 | case DTK: | ||
1322 | sync = wacom_intuos_irq(wacom_wac); | 1308 | sync = wacom_intuos_irq(wacom_wac); |
1323 | break; | 1309 | break; |
1324 | 1310 | ||
@@ -1444,39 +1430,64 @@ static unsigned int wacom_calculate_touch_res(unsigned int logical_max, | |||
1444 | return (logical_max * 100) / physical_max; | 1430 | return (logical_max * 100) / physical_max; |
1445 | } | 1431 | } |
1446 | 1432 | ||
1447 | int wacom_setup_input_capabilities(struct input_dev *input_dev, | 1433 | static void wacom_abs_set_axis(struct input_dev *input_dev, |
1448 | struct wacom_wac *wacom_wac) | 1434 | struct wacom_wac *wacom_wac) |
1449 | { | 1435 | { |
1450 | struct wacom_features *features = &wacom_wac->features; | 1436 | struct wacom_features *features = &wacom_wac->features; |
1451 | int i; | ||
1452 | |||
1453 | input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
1454 | |||
1455 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
1456 | |||
1457 | input_set_abs_params(input_dev, ABS_X, 0, features->x_max, | ||
1458 | features->x_fuzz, 0); | ||
1459 | input_set_abs_params(input_dev, ABS_Y, 0, features->y_max, | ||
1460 | features->y_fuzz, 0); | ||
1461 | 1437 | ||
1462 | if (features->device_type == BTN_TOOL_PEN) { | 1438 | if (features->device_type == BTN_TOOL_PEN) { |
1463 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max, | 1439 | input_set_abs_params(input_dev, ABS_X, 0, features->x_max, |
1464 | features->pressure_fuzz, 0); | 1440 | features->x_fuzz, 0); |
1441 | input_set_abs_params(input_dev, ABS_Y, 0, features->y_max, | ||
1442 | features->y_fuzz, 0); | ||
1443 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, | ||
1444 | features->pressure_max, features->pressure_fuzz, 0); | ||
1465 | 1445 | ||
1466 | /* penabled devices have fixed resolution for each model */ | 1446 | /* penabled devices have fixed resolution for each model */ |
1467 | input_abs_set_res(input_dev, ABS_X, features->x_resolution); | 1447 | input_abs_set_res(input_dev, ABS_X, features->x_resolution); |
1468 | input_abs_set_res(input_dev, ABS_Y, features->y_resolution); | 1448 | input_abs_set_res(input_dev, ABS_Y, features->y_resolution); |
1469 | } else { | 1449 | } else { |
1470 | input_abs_set_res(input_dev, ABS_X, | 1450 | if (features->touch_max <= 2) { |
1471 | wacom_calculate_touch_res(features->x_max, | 1451 | input_set_abs_params(input_dev, ABS_X, 0, |
1472 | features->x_phy)); | 1452 | features->x_max, features->x_fuzz, 0); |
1473 | input_abs_set_res(input_dev, ABS_Y, | 1453 | input_set_abs_params(input_dev, ABS_Y, 0, |
1474 | wacom_calculate_touch_res(features->y_max, | 1454 | features->y_max, features->y_fuzz, 0); |
1475 | features->y_phy)); | 1455 | input_abs_set_res(input_dev, ABS_X, |
1456 | wacom_calculate_touch_res(features->x_max, | ||
1457 | features->x_phy)); | ||
1458 | input_abs_set_res(input_dev, ABS_Y, | ||
1459 | wacom_calculate_touch_res(features->y_max, | ||
1460 | features->y_phy)); | ||
1461 | } | ||
1462 | |||
1463 | if (features->touch_max > 1) { | ||
1464 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, | ||
1465 | features->x_max, features->x_fuzz, 0); | ||
1466 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, | ||
1467 | features->y_max, features->y_fuzz, 0); | ||
1468 | input_abs_set_res(input_dev, ABS_MT_POSITION_X, | ||
1469 | wacom_calculate_touch_res(features->x_max, | ||
1470 | features->x_phy)); | ||
1471 | input_abs_set_res(input_dev, ABS_MT_POSITION_Y, | ||
1472 | wacom_calculate_touch_res(features->y_max, | ||
1473 | features->y_phy)); | ||
1474 | } | ||
1476 | } | 1475 | } |
1476 | } | ||
1477 | 1477 | ||
1478 | int wacom_setup_input_capabilities(struct input_dev *input_dev, | ||
1479 | struct wacom_wac *wacom_wac) | ||
1480 | { | ||
1481 | struct wacom_features *features = &wacom_wac->features; | ||
1482 | int i; | ||
1483 | |||
1484 | input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
1485 | |||
1486 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
1478 | __set_bit(ABS_MISC, input_dev->absbit); | 1487 | __set_bit(ABS_MISC, input_dev->absbit); |
1479 | 1488 | ||
1489 | wacom_abs_set_axis(input_dev, wacom_wac); | ||
1490 | |||
1480 | switch (wacom_wac->features.type) { | 1491 | switch (wacom_wac->features.type) { |
1481 | case WACOM_MO: | 1492 | case WACOM_MO: |
1482 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); | 1493 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); |
@@ -1513,12 +1524,17 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1513 | __set_bit(BTN_Y, input_dev->keybit); | 1524 | __set_bit(BTN_Y, input_dev->keybit); |
1514 | __set_bit(BTN_Z, input_dev->keybit); | 1525 | __set_bit(BTN_Z, input_dev->keybit); |
1515 | 1526 | ||
1516 | for (i = 0; i < 10; i++) | 1527 | for (i = 6; i < 10; i++) |
1517 | __set_bit(BTN_0 + i, input_dev->keybit); | 1528 | __set_bit(BTN_0 + i, input_dev->keybit); |
1518 | 1529 | ||
1519 | __set_bit(KEY_PROG1, input_dev->keybit); | 1530 | __set_bit(KEY_PROG1, input_dev->keybit); |
1520 | __set_bit(KEY_PROG2, input_dev->keybit); | 1531 | __set_bit(KEY_PROG2, input_dev->keybit); |
1521 | __set_bit(KEY_PROG3, input_dev->keybit); | 1532 | __set_bit(KEY_PROG3, input_dev->keybit); |
1533 | /* fall through */ | ||
1534 | |||
1535 | case DTK: | ||
1536 | for (i = 0; i < 6; i++) | ||
1537 | __set_bit(BTN_0 + i, input_dev->keybit); | ||
1522 | 1538 | ||
1523 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | 1539 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); |
1524 | input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0); | 1540 | input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0); |
@@ -1614,24 +1630,11 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1614 | } else if (features->device_type == BTN_TOOL_FINGER) { | 1630 | } else if (features->device_type == BTN_TOOL_FINGER) { |
1615 | __clear_bit(ABS_MISC, input_dev->absbit); | 1631 | __clear_bit(ABS_MISC, input_dev->absbit); |
1616 | 1632 | ||
1617 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | ||
1618 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); | ||
1619 | __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); | ||
1620 | __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit); | ||
1621 | |||
1622 | input_mt_init_slots(input_dev, features->touch_max, 0); | ||
1623 | |||
1624 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, | 1633 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, |
1625 | 0, features->x_max, 0, 0); | 1634 | 0, features->x_max, 0, 0); |
1626 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR, | 1635 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR, |
1627 | 0, features->y_max, 0, 0); | 1636 | 0, features->y_max, 0, 0); |
1628 | 1637 | input_mt_init_slots(input_dev, features->touch_max, INPUT_MT_POINTER); | |
1629 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | ||
1630 | 0, features->x_max, | ||
1631 | features->x_fuzz, 0); | ||
1632 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, | ||
1633 | 0, features->y_max, | ||
1634 | features->y_fuzz, 0); | ||
1635 | } | 1638 | } |
1636 | break; | 1639 | break; |
1637 | 1640 | ||
@@ -1662,27 +1665,14 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1662 | 1665 | ||
1663 | case MTSCREEN: | 1666 | case MTSCREEN: |
1664 | case MTTPC: | 1667 | case MTTPC: |
1665 | if (features->device_type == BTN_TOOL_FINGER) { | ||
1666 | wacom_wac->slots = kmalloc(features->touch_max * | ||
1667 | sizeof(int), | ||
1668 | GFP_KERNEL); | ||
1669 | if (!wacom_wac->slots) | ||
1670 | return -ENOMEM; | ||
1671 | |||
1672 | for (i = 0; i < features->touch_max; i++) | ||
1673 | wacom_wac->slots[i] = -1; | ||
1674 | } | ||
1675 | /* fall through */ | ||
1676 | |||
1677 | case TABLETPC2FG: | 1668 | case TABLETPC2FG: |
1678 | if (features->device_type == BTN_TOOL_FINGER) { | 1669 | if (features->device_type == BTN_TOOL_FINGER) { |
1679 | input_mt_init_slots(input_dev, features->touch_max, 0); | 1670 | unsigned int flags = INPUT_MT_DIRECT; |
1680 | input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE, | 1671 | |
1681 | 0, MT_TOOL_MAX, 0, 0); | 1672 | if (wacom_wac->features.type == TABLETPC2FG) |
1682 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | 1673 | flags = 0; |
1683 | 0, features->x_max, 0, 0); | 1674 | |
1684 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, | 1675 | input_mt_init_slots(input_dev, features->touch_max, flags); |
1685 | 0, features->y_max, 0, 0); | ||
1686 | } | 1676 | } |
1687 | /* fall through */ | 1677 | /* fall through */ |
1688 | 1678 | ||
@@ -1725,35 +1715,26 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1725 | __set_bit(INPUT_PROP_POINTER, input_dev->propbit); | 1715 | __set_bit(INPUT_PROP_POINTER, input_dev->propbit); |
1726 | 1716 | ||
1727 | if (features->device_type == BTN_TOOL_FINGER) { | 1717 | if (features->device_type == BTN_TOOL_FINGER) { |
1718 | unsigned int flags = INPUT_MT_POINTER; | ||
1719 | |||
1728 | __set_bit(BTN_LEFT, input_dev->keybit); | 1720 | __set_bit(BTN_LEFT, input_dev->keybit); |
1729 | __set_bit(BTN_FORWARD, input_dev->keybit); | 1721 | __set_bit(BTN_FORWARD, input_dev->keybit); |
1730 | __set_bit(BTN_BACK, input_dev->keybit); | 1722 | __set_bit(BTN_BACK, input_dev->keybit); |
1731 | __set_bit(BTN_RIGHT, input_dev->keybit); | 1723 | __set_bit(BTN_RIGHT, input_dev->keybit); |
1732 | 1724 | ||
1733 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | ||
1734 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); | ||
1735 | input_mt_init_slots(input_dev, features->touch_max, 0); | ||
1736 | |||
1737 | if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) { | 1725 | if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) { |
1738 | __set_bit(BTN_TOOL_TRIPLETAP, | ||
1739 | input_dev->keybit); | ||
1740 | __set_bit(BTN_TOOL_QUADTAP, | ||
1741 | input_dev->keybit); | ||
1742 | |||
1743 | input_set_abs_params(input_dev, | 1726 | input_set_abs_params(input_dev, |
1744 | ABS_MT_TOUCH_MAJOR, | 1727 | ABS_MT_TOUCH_MAJOR, |
1745 | 0, features->x_max, 0, 0); | 1728 | 0, features->x_max, 0, 0); |
1746 | input_set_abs_params(input_dev, | 1729 | input_set_abs_params(input_dev, |
1747 | ABS_MT_TOUCH_MINOR, | 1730 | ABS_MT_TOUCH_MINOR, |
1748 | 0, features->y_max, 0, 0); | 1731 | 0, features->y_max, 0, 0); |
1732 | } else { | ||
1733 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | ||
1734 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); | ||
1735 | flags = 0; | ||
1749 | } | 1736 | } |
1750 | 1737 | input_mt_init_slots(input_dev, features->touch_max, flags); | |
1751 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | ||
1752 | 0, features->x_max, | ||
1753 | features->x_fuzz, 0); | ||
1754 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, | ||
1755 | 0, features->y_max, | ||
1756 | features->y_fuzz, 0); | ||
1757 | } else if (features->device_type == BTN_TOOL_PEN) { | 1738 | } else if (features->device_type == BTN_TOOL_PEN) { |
1758 | __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); | 1739 | __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); |
1759 | __set_bit(BTN_TOOL_PEN, input_dev->keybit); | 1740 | __set_bit(BTN_TOOL_PEN, input_dev->keybit); |
@@ -1978,6 +1959,13 @@ static const struct wacom_features wacom_features_0xCE = | |||
1978 | static const struct wacom_features wacom_features_0xF0 = | 1959 | static const struct wacom_features wacom_features_0xF0 = |
1979 | { "Wacom DTU1631", WACOM_PKGLEN_GRAPHIRE, 34623, 19553, 511, | 1960 | { "Wacom DTU1631", WACOM_PKGLEN_GRAPHIRE, 34623, 19553, 511, |
1980 | 0, DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1961 | 0, DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
1962 | static const struct wacom_features wacom_features_0x59 = /* Pen */ | ||
1963 | { "Wacom DTH2242", WACOM_PKGLEN_INTUOS, 95840, 54260, 2047, | ||
1964 | 63, DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | ||
1965 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5D }; | ||
1966 | static const struct wacom_features wacom_features_0x5D = /* Touch */ | ||
1967 | { "Wacom DTH2242", .type = WACOM_24HDT, | ||
1968 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x59, .touch_max = 10 }; | ||
1981 | static const struct wacom_features wacom_features_0xCC = | 1969 | static const struct wacom_features wacom_features_0xCC = |
1982 | { "Wacom Cintiq 21UX2", WACOM_PKGLEN_INTUOS, 87200, 65600, 2047, | 1970 | { "Wacom Cintiq 21UX2", WACOM_PKGLEN_INTUOS, 87200, 65600, 2047, |
1983 | 63, WACOM_21UX2, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 1971 | 63, WACOM_21UX2, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; |
@@ -2152,6 +2140,8 @@ const struct usb_device_id wacom_ids[] = { | |||
2152 | { USB_DEVICE_WACOM(0x43) }, | 2140 | { USB_DEVICE_WACOM(0x43) }, |
2153 | { USB_DEVICE_WACOM(0x44) }, | 2141 | { USB_DEVICE_WACOM(0x44) }, |
2154 | { USB_DEVICE_WACOM(0x45) }, | 2142 | { USB_DEVICE_WACOM(0x45) }, |
2143 | { USB_DEVICE_WACOM(0x59) }, | ||
2144 | { USB_DEVICE_WACOM(0x5D) }, | ||
2155 | { USB_DEVICE_WACOM(0xB0) }, | 2145 | { USB_DEVICE_WACOM(0xB0) }, |
2156 | { USB_DEVICE_WACOM(0xB1) }, | 2146 | { USB_DEVICE_WACOM(0xB1) }, |
2157 | { USB_DEVICE_WACOM(0xB2) }, | 2147 | { USB_DEVICE_WACOM(0xB2) }, |
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index 9396d7769f86..5f9a7721e16c 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h | |||
@@ -78,6 +78,7 @@ enum { | |||
78 | INTUOS5L, | 78 | INTUOS5L, |
79 | WACOM_21UX2, | 79 | WACOM_21UX2, |
80 | WACOM_22HD, | 80 | WACOM_22HD, |
81 | DTK, | ||
81 | WACOM_24HD, | 82 | WACOM_24HD, |
82 | CINTIQ, | 83 | CINTIQ, |
83 | WACOM_BEE, | 84 | WACOM_BEE, |
@@ -135,7 +136,6 @@ struct wacom_wac { | |||
135 | int pid; | 136 | int pid; |
136 | int battery_capacity; | 137 | int battery_capacity; |
137 | int num_contacts_left; | 138 | int num_contacts_left; |
138 | int *slots; | ||
139 | }; | 139 | }; |
140 | 140 | ||
141 | #endif | 141 | #endif |
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 515cfe790543..f9a5fd89bc02 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
@@ -359,7 +359,7 @@ config TOUCHSCREEN_MCS5000 | |||
359 | 359 | ||
360 | config TOUCHSCREEN_MMS114 | 360 | config TOUCHSCREEN_MMS114 |
361 | tristate "MELFAS MMS114 touchscreen" | 361 | tristate "MELFAS MMS114 touchscreen" |
362 | depends on I2C | 362 | depends on I2C && GENERIC_HARDIRQS |
363 | help | 363 | help |
364 | Say Y here if you have the MELFAS MMS114 touchscreen controller | 364 | Say Y here if you have the MELFAS MMS114 touchscreen controller |
365 | chip in your system. | 365 | chip in your system. |
diff --git a/drivers/input/touchscreen/cyttsp_spi.c b/drivers/input/touchscreen/cyttsp_spi.c index 638e20310f12..861b7f77605b 100644 --- a/drivers/input/touchscreen/cyttsp_spi.c +++ b/drivers/input/touchscreen/cyttsp_spi.c | |||
@@ -193,7 +193,6 @@ static struct spi_driver cyttsp_spi_driver = { | |||
193 | 193 | ||
194 | module_spi_driver(cyttsp_spi_driver); | 194 | module_spi_driver(cyttsp_spi_driver); |
195 | 195 | ||
196 | MODULE_ALIAS("spi:cyttsp"); | ||
197 | MODULE_LICENSE("GPL"); | 196 | MODULE_LICENSE("GPL"); |
198 | MODULE_DESCRIPTION("Cypress TrueTouch(R) Standard Product (TTSP) SPI driver"); | 197 | MODULE_DESCRIPTION("Cypress TrueTouch(R) Standard Product (TTSP) SPI driver"); |
199 | MODULE_AUTHOR("Cypress"); | 198 | MODULE_AUTHOR("Cypress"); |
diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c index 98841d8aa635..4a29ddf6bf1e 100644 --- a/drivers/input/touchscreen/mms114.c +++ b/drivers/input/touchscreen/mms114.c | |||
@@ -429,12 +429,12 @@ static int mms114_probe(struct i2c_client *client, | |||
429 | return -ENODEV; | 429 | return -ENODEV; |
430 | } | 430 | } |
431 | 431 | ||
432 | data = kzalloc(sizeof(struct mms114_data), GFP_KERNEL); | 432 | data = devm_kzalloc(&client->dev, sizeof(struct mms114_data), |
433 | input_dev = input_allocate_device(); | 433 | GFP_KERNEL); |
434 | input_dev = devm_input_allocate_device(&client->dev); | ||
434 | if (!data || !input_dev) { | 435 | if (!data || !input_dev) { |
435 | dev_err(&client->dev, "Failed to allocate memory\n"); | 436 | dev_err(&client->dev, "Failed to allocate memory\n"); |
436 | error = -ENOMEM; | 437 | return -ENOMEM; |
437 | goto err_free_mem; | ||
438 | } | 438 | } |
439 | 439 | ||
440 | data->client = client; | 440 | data->client = client; |
@@ -466,57 +466,36 @@ static int mms114_probe(struct i2c_client *client, | |||
466 | input_set_drvdata(input_dev, data); | 466 | input_set_drvdata(input_dev, data); |
467 | i2c_set_clientdata(client, data); | 467 | i2c_set_clientdata(client, data); |
468 | 468 | ||
469 | data->core_reg = regulator_get(&client->dev, "avdd"); | 469 | data->core_reg = devm_regulator_get(&client->dev, "avdd"); |
470 | if (IS_ERR(data->core_reg)) { | 470 | if (IS_ERR(data->core_reg)) { |
471 | error = PTR_ERR(data->core_reg); | 471 | error = PTR_ERR(data->core_reg); |
472 | dev_err(&client->dev, | 472 | dev_err(&client->dev, |
473 | "Unable to get the Core regulator (%d)\n", error); | 473 | "Unable to get the Core regulator (%d)\n", error); |
474 | goto err_free_mem; | 474 | return error; |
475 | } | 475 | } |
476 | 476 | ||
477 | data->io_reg = regulator_get(&client->dev, "vdd"); | 477 | data->io_reg = devm_regulator_get(&client->dev, "vdd"); |
478 | if (IS_ERR(data->io_reg)) { | 478 | if (IS_ERR(data->io_reg)) { |
479 | error = PTR_ERR(data->io_reg); | 479 | error = PTR_ERR(data->io_reg); |
480 | dev_err(&client->dev, | 480 | dev_err(&client->dev, |
481 | "Unable to get the IO regulator (%d)\n", error); | 481 | "Unable to get the IO regulator (%d)\n", error); |
482 | goto err_core_reg; | 482 | return error; |
483 | } | 483 | } |
484 | 484 | ||
485 | error = request_threaded_irq(client->irq, NULL, mms114_interrupt, | 485 | error = devm_request_threaded_irq(&client->dev, client->irq, NULL, |
486 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "mms114", data); | 486 | mms114_interrupt, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, |
487 | dev_name(&client->dev), data); | ||
487 | if (error) { | 488 | if (error) { |
488 | dev_err(&client->dev, "Failed to register interrupt\n"); | 489 | dev_err(&client->dev, "Failed to register interrupt\n"); |
489 | goto err_io_reg; | 490 | return error; |
490 | } | 491 | } |
491 | disable_irq(client->irq); | 492 | disable_irq(client->irq); |
492 | 493 | ||
493 | error = input_register_device(data->input_dev); | 494 | error = input_register_device(data->input_dev); |
494 | if (error) | 495 | if (error) { |
495 | goto err_free_irq; | 496 | dev_err(&client->dev, "Failed to register input device\n"); |
496 | 497 | return error; | |
497 | return 0; | 498 | } |
498 | |||
499 | err_free_irq: | ||
500 | free_irq(client->irq, data); | ||
501 | err_io_reg: | ||
502 | regulator_put(data->io_reg); | ||
503 | err_core_reg: | ||
504 | regulator_put(data->core_reg); | ||
505 | err_free_mem: | ||
506 | input_free_device(input_dev); | ||
507 | kfree(data); | ||
508 | return error; | ||
509 | } | ||
510 | |||
511 | static int mms114_remove(struct i2c_client *client) | ||
512 | { | ||
513 | struct mms114_data *data = i2c_get_clientdata(client); | ||
514 | |||
515 | free_irq(client->irq, data); | ||
516 | regulator_put(data->io_reg); | ||
517 | regulator_put(data->core_reg); | ||
518 | input_unregister_device(data->input_dev); | ||
519 | kfree(data); | ||
520 | 499 | ||
521 | return 0; | 500 | return 0; |
522 | } | 501 | } |
@@ -590,7 +569,6 @@ static struct i2c_driver mms114_driver = { | |||
590 | .of_match_table = of_match_ptr(mms114_dt_match), | 569 | .of_match_table = of_match_ptr(mms114_dt_match), |
591 | }, | 570 | }, |
592 | .probe = mms114_probe, | 571 | .probe = mms114_probe, |
593 | .remove = mms114_remove, | ||
594 | .id_table = mms114_id, | 572 | .id_table = mms114_id, |
595 | }; | 573 | }; |
596 | 574 | ||
diff --git a/drivers/input/touchscreen/stmpe-ts.c b/drivers/input/touchscreen/stmpe-ts.c index 84d884b4ec3e..59e81b00f244 100644 --- a/drivers/input/touchscreen/stmpe-ts.c +++ b/drivers/input/touchscreen/stmpe-ts.c | |||
@@ -120,6 +120,7 @@ static void stmpe_work(struct work_struct *work) | |||
120 | __stmpe_reset_fifo(ts->stmpe); | 120 | __stmpe_reset_fifo(ts->stmpe); |
121 | 121 | ||
122 | input_report_abs(ts->idev, ABS_PRESSURE, 0); | 122 | input_report_abs(ts->idev, ABS_PRESSURE, 0); |
123 | input_report_key(ts->idev, BTN_TOUCH, 0); | ||
123 | input_sync(ts->idev); | 124 | input_sync(ts->idev); |
124 | } | 125 | } |
125 | 126 | ||
@@ -153,6 +154,7 @@ static irqreturn_t stmpe_ts_handler(int irq, void *data) | |||
153 | input_report_abs(ts->idev, ABS_X, x); | 154 | input_report_abs(ts->idev, ABS_X, x); |
154 | input_report_abs(ts->idev, ABS_Y, y); | 155 | input_report_abs(ts->idev, ABS_Y, y); |
155 | input_report_abs(ts->idev, ABS_PRESSURE, z); | 156 | input_report_abs(ts->idev, ABS_PRESSURE, z); |
157 | input_report_key(ts->idev, BTN_TOUCH, 1); | ||
156 | input_sync(ts->idev); | 158 | input_sync(ts->idev); |
157 | 159 | ||
158 | /* flush the FIFO after we have read out our values. */ | 160 | /* flush the FIFO after we have read out our values. */ |
diff --git a/drivers/input/touchscreen/tsc2005.c b/drivers/input/touchscreen/tsc2005.c index 9c0cdc7ea449..7213e8b07e79 100644 --- a/drivers/input/touchscreen/tsc2005.c +++ b/drivers/input/touchscreen/tsc2005.c | |||
@@ -753,3 +753,4 @@ module_spi_driver(tsc2005_driver); | |||
753 | MODULE_AUTHOR("Lauri Leukkunen <lauri.leukkunen@nokia.com>"); | 753 | MODULE_AUTHOR("Lauri Leukkunen <lauri.leukkunen@nokia.com>"); |
754 | MODULE_DESCRIPTION("TSC2005 Touchscreen Driver"); | 754 | MODULE_DESCRIPTION("TSC2005 Touchscreen Driver"); |
755 | MODULE_LICENSE("GPL"); | 755 | MODULE_LICENSE("GPL"); |
756 | MODULE_ALIAS("spi:tsc2005"); | ||
diff --git a/drivers/input/touchscreen/wm831x-ts.c b/drivers/input/touchscreen/wm831x-ts.c index f88fab56178c..6be2eb6a153a 100644 --- a/drivers/input/touchscreen/wm831x-ts.c +++ b/drivers/input/touchscreen/wm831x-ts.c | |||
@@ -247,7 +247,7 @@ static int wm831x_ts_probe(struct platform_device *pdev) | |||
247 | 247 | ||
248 | wm831x_ts = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_ts), | 248 | wm831x_ts = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_ts), |
249 | GFP_KERNEL); | 249 | GFP_KERNEL); |
250 | input_dev = input_allocate_device(); | 250 | input_dev = devm_input_allocate_device(&pdev->dev); |
251 | if (!wm831x_ts || !input_dev) { | 251 | if (!wm831x_ts || !input_dev) { |
252 | error = -ENOMEM; | 252 | error = -ENOMEM; |
253 | goto err_alloc; | 253 | goto err_alloc; |
@@ -376,7 +376,6 @@ err_pd_irq: | |||
376 | err_data_irq: | 376 | err_data_irq: |
377 | free_irq(wm831x_ts->data_irq, wm831x_ts); | 377 | free_irq(wm831x_ts->data_irq, wm831x_ts); |
378 | err_alloc: | 378 | err_alloc: |
379 | input_free_device(input_dev); | ||
380 | 379 | ||
381 | return error; | 380 | return error; |
382 | } | 381 | } |
@@ -387,7 +386,6 @@ static int wm831x_ts_remove(struct platform_device *pdev) | |||
387 | 386 | ||
388 | free_irq(wm831x_ts->pd_irq, wm831x_ts); | 387 | free_irq(wm831x_ts->pd_irq, wm831x_ts); |
389 | free_irq(wm831x_ts->data_irq, wm831x_ts); | 388 | free_irq(wm831x_ts->data_irq, wm831x_ts); |
390 | input_unregister_device(wm831x_ts->input_dev); | ||
391 | 389 | ||
392 | return 0; | 390 | return 0; |
393 | } | 391 | } |
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 40e5b3919e27..814655ee2d61 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
43 | #include <linux/input.h> | 43 | #include <linux/input.h> |
44 | #include <linux/uaccess.h> | 44 | #include <linux/uaccess.h> |
45 | #include <linux/moduleparam.h> | ||
45 | 46 | ||
46 | #include <asm/ptrace.h> | 47 | #include <asm/ptrace.h> |
47 | #include <asm/irq_regs.h> | 48 | #include <asm/irq_regs.h> |
@@ -578,8 +579,71 @@ struct sysrq_state { | |||
578 | bool active; | 579 | bool active; |
579 | bool need_reinject; | 580 | bool need_reinject; |
580 | bool reinjecting; | 581 | bool reinjecting; |
582 | |||
583 | /* reset sequence handling */ | ||
584 | bool reset_canceled; | ||
585 | unsigned long reset_keybit[BITS_TO_LONGS(KEY_CNT)]; | ||
586 | int reset_seq_len; | ||
587 | int reset_seq_cnt; | ||
588 | int reset_seq_version; | ||
581 | }; | 589 | }; |
582 | 590 | ||
591 | #define SYSRQ_KEY_RESET_MAX 20 /* Should be plenty */ | ||
592 | static unsigned short sysrq_reset_seq[SYSRQ_KEY_RESET_MAX]; | ||
593 | static unsigned int sysrq_reset_seq_len; | ||
594 | static unsigned int sysrq_reset_seq_version = 1; | ||
595 | |||
596 | static void sysrq_parse_reset_sequence(struct sysrq_state *state) | ||
597 | { | ||
598 | int i; | ||
599 | unsigned short key; | ||
600 | |||
601 | state->reset_seq_cnt = 0; | ||
602 | |||
603 | for (i = 0; i < sysrq_reset_seq_len; i++) { | ||
604 | key = sysrq_reset_seq[i]; | ||
605 | |||
606 | if (key == KEY_RESERVED || key > KEY_MAX) | ||
607 | break; | ||
608 | |||
609 | __set_bit(key, state->reset_keybit); | ||
610 | state->reset_seq_len++; | ||
611 | |||
612 | if (test_bit(key, state->key_down)) | ||
613 | state->reset_seq_cnt++; | ||
614 | } | ||
615 | |||
616 | /* Disable reset until old keys are not released */ | ||
617 | state->reset_canceled = state->reset_seq_cnt != 0; | ||
618 | |||
619 | state->reset_seq_version = sysrq_reset_seq_version; | ||
620 | } | ||
621 | |||
622 | static bool sysrq_detect_reset_sequence(struct sysrq_state *state, | ||
623 | unsigned int code, int value) | ||
624 | { | ||
625 | if (!test_bit(code, state->reset_keybit)) { | ||
626 | /* | ||
627 | * Pressing any key _not_ in reset sequence cancels | ||
628 | * the reset sequence. | ||
629 | */ | ||
630 | if (value && state->reset_seq_cnt) | ||
631 | state->reset_canceled = true; | ||
632 | } else if (value == 0) { | ||
633 | /* key release */ | ||
634 | if (--state->reset_seq_cnt == 0) | ||
635 | state->reset_canceled = false; | ||
636 | } else if (value == 1) { | ||
637 | /* key press, not autorepeat */ | ||
638 | if (++state->reset_seq_cnt == state->reset_seq_len && | ||
639 | !state->reset_canceled) { | ||
640 | return true; | ||
641 | } | ||
642 | } | ||
643 | |||
644 | return false; | ||
645 | } | ||
646 | |||
583 | static void sysrq_reinject_alt_sysrq(struct work_struct *work) | 647 | static void sysrq_reinject_alt_sysrq(struct work_struct *work) |
584 | { | 648 | { |
585 | struct sysrq_state *sysrq = | 649 | struct sysrq_state *sysrq = |
@@ -606,100 +670,121 @@ static void sysrq_reinject_alt_sysrq(struct work_struct *work) | |||
606 | } | 670 | } |
607 | } | 671 | } |
608 | 672 | ||
609 | static bool sysrq_filter(struct input_handle *handle, | 673 | static bool sysrq_handle_keypress(struct sysrq_state *sysrq, |
610 | unsigned int type, unsigned int code, int value) | 674 | unsigned int code, int value) |
611 | { | 675 | { |
612 | struct sysrq_state *sysrq = handle->private; | ||
613 | bool was_active = sysrq->active; | 676 | bool was_active = sysrq->active; |
614 | bool suppress; | 677 | bool suppress; |
615 | 678 | ||
616 | /* | 679 | switch (code) { |
617 | * Do not filter anything if we are in the process of re-injecting | ||
618 | * Alt+SysRq combination. | ||
619 | */ | ||
620 | if (sysrq->reinjecting) | ||
621 | return false; | ||
622 | 680 | ||
623 | switch (type) { | 681 | case KEY_LEFTALT: |
682 | case KEY_RIGHTALT: | ||
683 | if (!value) { | ||
684 | /* One of ALTs is being released */ | ||
685 | if (sysrq->active && code == sysrq->alt_use) | ||
686 | sysrq->active = false; | ||
624 | 687 | ||
625 | case EV_SYN: | 688 | sysrq->alt = KEY_RESERVED; |
626 | suppress = false; | 689 | |
690 | } else if (value != 2) { | ||
691 | sysrq->alt = code; | ||
692 | sysrq->need_reinject = false; | ||
693 | } | ||
627 | break; | 694 | break; |
628 | 695 | ||
629 | case EV_KEY: | 696 | case KEY_SYSRQ: |
630 | switch (code) { | 697 | if (value == 1 && sysrq->alt != KEY_RESERVED) { |
698 | sysrq->active = true; | ||
699 | sysrq->alt_use = sysrq->alt; | ||
700 | /* | ||
701 | * If nothing else will be pressed we'll need | ||
702 | * to re-inject Alt-SysRq keysroke. | ||
703 | */ | ||
704 | sysrq->need_reinject = true; | ||
705 | } | ||
631 | 706 | ||
632 | case KEY_LEFTALT: | 707 | /* |
633 | case KEY_RIGHTALT: | 708 | * Pretend that sysrq was never pressed at all. This |
634 | if (!value) { | 709 | * is needed to properly handle KGDB which will try |
635 | /* One of ALTs is being released */ | 710 | * to release all keys after exiting debugger. If we |
636 | if (sysrq->active && code == sysrq->alt_use) | 711 | * do not clear key bit it KGDB will end up sending |
637 | sysrq->active = false; | 712 | * release events for Alt and SysRq, potentially |
713 | * triggering print screen function. | ||
714 | */ | ||
715 | if (sysrq->active) | ||
716 | clear_bit(KEY_SYSRQ, sysrq->handle.dev->key); | ||
638 | 717 | ||
639 | sysrq->alt = KEY_RESERVED; | 718 | break; |
640 | 719 | ||
641 | } else if (value != 2) { | 720 | default: |
642 | sysrq->alt = code; | 721 | if (sysrq->active && value && value != 2) { |
643 | sysrq->need_reinject = false; | 722 | sysrq->need_reinject = false; |
644 | } | 723 | __handle_sysrq(sysrq_xlate[code], true); |
645 | break; | 724 | } |
725 | break; | ||
726 | } | ||
646 | 727 | ||
647 | case KEY_SYSRQ: | 728 | suppress = sysrq->active; |
648 | if (value == 1 && sysrq->alt != KEY_RESERVED) { | ||
649 | sysrq->active = true; | ||
650 | sysrq->alt_use = sysrq->alt; | ||
651 | /* | ||
652 | * If nothing else will be pressed we'll need | ||
653 | * to re-inject Alt-SysRq keysroke. | ||
654 | */ | ||
655 | sysrq->need_reinject = true; | ||
656 | } | ||
657 | 729 | ||
658 | /* | 730 | if (!sysrq->active) { |
659 | * Pretend that sysrq was never pressed at all. This | ||
660 | * is needed to properly handle KGDB which will try | ||
661 | * to release all keys after exiting debugger. If we | ||
662 | * do not clear key bit it KGDB will end up sending | ||
663 | * release events for Alt and SysRq, potentially | ||
664 | * triggering print screen function. | ||
665 | */ | ||
666 | if (sysrq->active) | ||
667 | clear_bit(KEY_SYSRQ, handle->dev->key); | ||
668 | 731 | ||
669 | break; | 732 | /* |
733 | * See if reset sequence has changed since the last time. | ||
734 | */ | ||
735 | if (sysrq->reset_seq_version != sysrq_reset_seq_version) | ||
736 | sysrq_parse_reset_sequence(sysrq); | ||
670 | 737 | ||
671 | default: | 738 | /* |
672 | if (sysrq->active && value && value != 2) { | 739 | * If we are not suppressing key presses keep track of |
673 | sysrq->need_reinject = false; | 740 | * keyboard state so we can release keys that have been |
674 | __handle_sysrq(sysrq_xlate[code], true); | 741 | * pressed before entering SysRq mode. |
675 | } | 742 | */ |
676 | break; | 743 | if (value) |
744 | set_bit(code, sysrq->key_down); | ||
745 | else | ||
746 | clear_bit(code, sysrq->key_down); | ||
747 | |||
748 | if (was_active) | ||
749 | schedule_work(&sysrq->reinject_work); | ||
750 | |||
751 | if (sysrq_detect_reset_sequence(sysrq, code, value)) { | ||
752 | /* Force emergency reboot */ | ||
753 | __handle_sysrq(sysrq_xlate[KEY_B], false); | ||
677 | } | 754 | } |
678 | 755 | ||
679 | suppress = sysrq->active; | 756 | } else if (value == 0 && test_and_clear_bit(code, sysrq->key_down)) { |
757 | /* | ||
758 | * Pass on release events for keys that was pressed before | ||
759 | * entering SysRq mode. | ||
760 | */ | ||
761 | suppress = false; | ||
762 | } | ||
680 | 763 | ||
681 | if (!sysrq->active) { | 764 | return suppress; |
682 | /* | 765 | } |
683 | * If we are not suppressing key presses keep track of | ||
684 | * keyboard state so we can release keys that have been | ||
685 | * pressed before entering SysRq mode. | ||
686 | */ | ||
687 | if (value) | ||
688 | set_bit(code, sysrq->key_down); | ||
689 | else | ||
690 | clear_bit(code, sysrq->key_down); | ||
691 | 766 | ||
692 | if (was_active) | 767 | static bool sysrq_filter(struct input_handle *handle, |
693 | schedule_work(&sysrq->reinject_work); | 768 | unsigned int type, unsigned int code, int value) |
769 | { | ||
770 | struct sysrq_state *sysrq = handle->private; | ||
771 | bool suppress; | ||
694 | 772 | ||
695 | } else if (value == 0 && | 773 | /* |
696 | test_and_clear_bit(code, sysrq->key_down)) { | 774 | * Do not filter anything if we are in the process of re-injecting |
697 | /* | 775 | * Alt+SysRq combination. |
698 | * Pass on release events for keys that was pressed before | 776 | */ |
699 | * entering SysRq mode. | 777 | if (sysrq->reinjecting) |
700 | */ | 778 | return false; |
701 | suppress = false; | 779 | |
702 | } | 780 | switch (type) { |
781 | |||
782 | case EV_SYN: | ||
783 | suppress = false; | ||
784 | break; | ||
785 | |||
786 | case EV_KEY: | ||
787 | suppress = sysrq_handle_keypress(sysrq, code, value); | ||
703 | break; | 788 | break; |
704 | 789 | ||
705 | default: | 790 | default: |
@@ -787,7 +872,20 @@ static bool sysrq_handler_registered; | |||
787 | 872 | ||
788 | static inline void sysrq_register_handler(void) | 873 | static inline void sysrq_register_handler(void) |
789 | { | 874 | { |
875 | extern unsigned short platform_sysrq_reset_seq[] __weak; | ||
876 | unsigned short key; | ||
790 | int error; | 877 | int error; |
878 | int i; | ||
879 | |||
880 | if (platform_sysrq_reset_seq) { | ||
881 | for (i = 0; i < ARRAY_SIZE(sysrq_reset_seq); i++) { | ||
882 | key = platform_sysrq_reset_seq[i]; | ||
883 | if (key == KEY_RESERVED || key > KEY_MAX) | ||
884 | break; | ||
885 | |||
886 | sysrq_reset_seq[sysrq_reset_seq_len++] = key; | ||
887 | } | ||
888 | } | ||
791 | 889 | ||
792 | error = input_register_handler(&sysrq_handler); | 890 | error = input_register_handler(&sysrq_handler); |
793 | if (error) | 891 | if (error) |
@@ -804,6 +902,36 @@ static inline void sysrq_unregister_handler(void) | |||
804 | } | 902 | } |
805 | } | 903 | } |
806 | 904 | ||
905 | static int sysrq_reset_seq_param_set(const char *buffer, | ||
906 | const struct kernel_param *kp) | ||
907 | { | ||
908 | unsigned long val; | ||
909 | int error; | ||
910 | |||
911 | error = strict_strtoul(buffer, 0, &val); | ||
912 | if (error < 0) | ||
913 | return error; | ||
914 | |||
915 | if (val > KEY_MAX) | ||
916 | return -EINVAL; | ||
917 | |||
918 | *((unsigned short *)kp->arg) = val; | ||
919 | sysrq_reset_seq_version++; | ||
920 | |||
921 | return 0; | ||
922 | } | ||
923 | |||
924 | static struct kernel_param_ops param_ops_sysrq_reset_seq = { | ||
925 | .get = param_get_ushort, | ||
926 | .set = sysrq_reset_seq_param_set, | ||
927 | }; | ||
928 | |||
929 | #define param_check_sysrq_reset_seq(name, p) \ | ||
930 | __param_check(name, p, unsigned short) | ||
931 | |||
932 | module_param_array_named(reset_seq, sysrq_reset_seq, sysrq_reset_seq, | ||
933 | &sysrq_reset_seq_len, 0644); | ||
934 | |||
807 | #else | 935 | #else |
808 | 936 | ||
809 | static inline void sysrq_register_handler(void) | 937 | static inline void sysrq_register_handler(void) |
diff --git a/include/linux/bma150.h b/include/linux/bma150.h index 7911fda23bb4..97ade7cdc870 100644 --- a/include/linux/bma150.h +++ b/include/linux/bma150.h | |||
@@ -22,6 +22,18 @@ | |||
22 | 22 | ||
23 | #define BMA150_DRIVER "bma150" | 23 | #define BMA150_DRIVER "bma150" |
24 | 24 | ||
25 | #define BMA150_RANGE_2G 0 | ||
26 | #define BMA150_RANGE_4G 1 | ||
27 | #define BMA150_RANGE_8G 2 | ||
28 | |||
29 | #define BMA150_BW_25HZ 0 | ||
30 | #define BMA150_BW_50HZ 1 | ||
31 | #define BMA150_BW_100HZ 2 | ||
32 | #define BMA150_BW_190HZ 3 | ||
33 | #define BMA150_BW_375HZ 4 | ||
34 | #define BMA150_BW_750HZ 5 | ||
35 | #define BMA150_BW_1500HZ 6 | ||
36 | |||
25 | struct bma150_cfg { | 37 | struct bma150_cfg { |
26 | bool any_motion_int; /* Set to enable any-motion interrupt */ | 38 | bool any_motion_int; /* Set to enable any-motion interrupt */ |
27 | bool hg_int; /* Set to enable high-G interrupt */ | 39 | bool hg_int; /* Set to enable high-G interrupt */ |
@@ -34,8 +46,8 @@ struct bma150_cfg { | |||
34 | unsigned char lg_hyst; /* Low-G hysterisis */ | 46 | unsigned char lg_hyst; /* Low-G hysterisis */ |
35 | unsigned char lg_dur; /* Low-G duration */ | 47 | unsigned char lg_dur; /* Low-G duration */ |
36 | unsigned char lg_thres; /* Low-G threshold */ | 48 | unsigned char lg_thres; /* Low-G threshold */ |
37 | unsigned char range; /* BMA0150_RANGE_xxx (in G) */ | 49 | unsigned char range; /* one of BMA0150_RANGE_xxx */ |
38 | unsigned char bandwidth; /* BMA0150_BW_xxx (in Hz) */ | 50 | unsigned char bandwidth; /* one of BMA0150_BW_xxx */ |
39 | }; | 51 | }; |
40 | 52 | ||
41 | struct bma150_platform_data { | 53 | struct bma150_platform_data { |
diff --git a/include/linux/input/adxl34x.h b/include/linux/input/adxl34x.h index 57e01a7cb006..010d98175efa 100644 --- a/include/linux/input/adxl34x.h +++ b/include/linux/input/adxl34x.h | |||
@@ -13,6 +13,8 @@ | |||
13 | #ifndef __LINUX_INPUT_ADXL34X_H__ | 13 | #ifndef __LINUX_INPUT_ADXL34X_H__ |
14 | #define __LINUX_INPUT_ADXL34X_H__ | 14 | #define __LINUX_INPUT_ADXL34X_H__ |
15 | 15 | ||
16 | #include <linux/input.h> | ||
17 | |||
16 | struct adxl34x_platform_data { | 18 | struct adxl34x_platform_data { |
17 | 19 | ||
18 | /* | 20 | /* |
diff --git a/include/linux/input/tegra_kbc.h b/include/linux/input/tegra_kbc.h deleted file mode 100644 index a13025612939..000000000000 --- a/include/linux/input/tegra_kbc.h +++ /dev/null | |||
@@ -1,62 +0,0 @@ | |||
1 | /* | ||
2 | * Platform definitions for tegra-kbc keyboard input driver | ||
3 | * | ||
4 | * Copyright (c) 2010-2011, NVIDIA Corporation. | ||
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, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef ASMARM_ARCH_TEGRA_KBC_H | ||
22 | #define ASMARM_ARCH_TEGRA_KBC_H | ||
23 | |||
24 | #include <linux/types.h> | ||
25 | #include <linux/input/matrix_keypad.h> | ||
26 | |||
27 | #define KBC_MAX_GPIO 24 | ||
28 | #define KBC_MAX_KPENT 8 | ||
29 | |||
30 | #define KBC_MAX_ROW 16 | ||
31 | #define KBC_MAX_COL 8 | ||
32 | #define KBC_MAX_KEY (KBC_MAX_ROW * KBC_MAX_COL) | ||
33 | |||
34 | enum tegra_pin_type { | ||
35 | PIN_CFG_IGNORE, | ||
36 | PIN_CFG_COL, | ||
37 | PIN_CFG_ROW, | ||
38 | }; | ||
39 | |||
40 | struct tegra_kbc_pin_cfg { | ||
41 | enum tegra_pin_type type; | ||
42 | unsigned char num; | ||
43 | }; | ||
44 | |||
45 | struct tegra_kbc_wake_key { | ||
46 | u8 row:4; | ||
47 | u8 col:4; | ||
48 | }; | ||
49 | |||
50 | struct tegra_kbc_platform_data { | ||
51 | unsigned int debounce_cnt; | ||
52 | unsigned int repeat_cnt; | ||
53 | |||
54 | struct tegra_kbc_pin_cfg pin_cfg[KBC_MAX_GPIO]; | ||
55 | const struct matrix_keymap_data *keymap_data; | ||
56 | |||
57 | u32 wakeup_key; | ||
58 | bool wakeup; | ||
59 | bool use_fn_map; | ||
60 | bool use_ghost_filter; | ||
61 | }; | ||
62 | #endif | ||
diff --git a/include/linux/libps2.h b/include/linux/libps2.h index 79603a6c356f..4ad06e824f76 100644 --- a/include/linux/libps2.h +++ b/include/linux/libps2.h | |||
@@ -36,7 +36,7 @@ struct ps2dev { | |||
36 | wait_queue_head_t wait; | 36 | wait_queue_head_t wait; |
37 | 37 | ||
38 | unsigned long flags; | 38 | unsigned long flags; |
39 | unsigned char cmdbuf[6]; | 39 | unsigned char cmdbuf[8]; |
40 | unsigned char cmdcnt; | 40 | unsigned char cmdcnt; |
41 | unsigned char nak; | 41 | unsigned char nak; |
42 | }; | 42 | }; |