diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-07 17:45:47 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-07 17:45:47 -0500 |
commit | 31b6ca0af758a88e5e769b48cc6dde037ee37b96 (patch) | |
tree | e1968d7168affb25e33e2be2d1d102f94af98af0 | |
parent | 56b85f32d530d09d6805488ad00775d4e0e3baab (diff) | |
parent | 554738da71004d96e06fb75f4772dfc3b0f47810 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (58 commits)
Input: wacom_w8001 - support pen or touch only devices
Input: wacom_w8001 - use __set_bit to set keybits
Input: bu21013_ts - fix misuse of logical operation in place of bitop
Input: i8042 - add Acer Aspire 5100 to the Dritek list
Input: wacom - add support for digitizer in Lenovo W700
Input: psmouse - disable the synaptics extension on OLPC machines
Input: psmouse - fix up Synaptics comment
Input: synaptics - ignore bogus mt packet
Input: synaptics - add multi-finger and semi-mt support
Input: synaptics - report clickpad property
input: mt: Document interface updates
Input: fix double equality sign in uevent
Input: introduce device properties
hid: egalax: Add support for Wetab (726b)
Input: include MT library as source for kerneldoc
MAINTAINERS: Update input-mt entry
hid: egalax: Add support for Samsung NB30 netbook
hid: egalax: Document the new devices in Kconfig
hid: egalax: Add support for Wetab
hid: egalax: Convert to MT slots
...
Fixed up trivial conflict in drivers/input/keyboard/Kconfig
64 files changed, 3209 insertions, 753 deletions
diff --git a/Documentation/DocBook/device-drivers.tmpl b/Documentation/DocBook/device-drivers.tmpl index 22edcbb9ddaf..35447e081736 100644 --- a/Documentation/DocBook/device-drivers.tmpl +++ b/Documentation/DocBook/device-drivers.tmpl | |||
@@ -304,6 +304,10 @@ X!Idrivers/video/console/fonts.c | |||
304 | !Edrivers/input/ff-core.c | 304 | !Edrivers/input/ff-core.c |
305 | !Edrivers/input/ff-memless.c | 305 | !Edrivers/input/ff-memless.c |
306 | </sect1> | 306 | </sect1> |
307 | <sect1><title>Multitouch Library</title> | ||
308 | !Iinclude/linux/input/mt.h | ||
309 | !Edrivers/input/input-mt.c | ||
310 | </sect1> | ||
307 | <sect1><title>Polled input devices</title> | 311 | <sect1><title>Polled input devices</title> |
308 | !Iinclude/linux/input-polldev.h | 312 | !Iinclude/linux/input-polldev.h |
309 | !Edrivers/input/input-polldev.c | 313 | !Edrivers/input/input-polldev.c |
diff --git a/Documentation/input/cma3000_d0x.txt b/Documentation/input/cma3000_d0x.txt new file mode 100644 index 000000000000..29d088db4afd --- /dev/null +++ b/Documentation/input/cma3000_d0x.txt | |||
@@ -0,0 +1,115 @@ | |||
1 | Kernel driver for CMA3000-D0x | ||
2 | ============================ | ||
3 | |||
4 | Supported chips: | ||
5 | * VTI CMA3000-D0x | ||
6 | Datasheet: | ||
7 | CMA3000-D0X Product Family Specification 8281000A.02.pdf | ||
8 | <http://www.vti.fi/en/> | ||
9 | |||
10 | Author: Hemanth V <hemanthv@ti.com> | ||
11 | |||
12 | |||
13 | Description | ||
14 | ----------- | ||
15 | CMA3000 Tri-axis accelerometer supports Motion detect, Measurement and | ||
16 | Free fall modes. | ||
17 | |||
18 | Motion Detect Mode: Its the low power mode where interrupts are generated only | ||
19 | when motion exceeds the defined thresholds. | ||
20 | |||
21 | Measurement Mode: This mode is used to read the acceleration data on X,Y,Z | ||
22 | axis and supports 400, 100, 40 Hz sample frequency. | ||
23 | |||
24 | Free fall Mode: This mode is intended to save system resources. | ||
25 | |||
26 | Threshold values: Chip supports defining threshold values for above modes | ||
27 | which includes time and g value. Refer product specifications for more details. | ||
28 | |||
29 | CMA3000 chip supports mutually exclusive I2C and SPI interfaces for | ||
30 | communication, currently the driver supports I2C based communication only. | ||
31 | Initial configuration for bus mode is set in non volatile memory and can later | ||
32 | be modified through bus interface command. | ||
33 | |||
34 | Driver reports acceleration data through input subsystem. It generates ABS_MISC | ||
35 | event with value 1 when free fall is detected. | ||
36 | |||
37 | Platform data need to be configured for initial default values. | ||
38 | |||
39 | Platform Data | ||
40 | ------------- | ||
41 | fuzz_x: Noise on X Axis | ||
42 | |||
43 | fuzz_y: Noise on Y Axis | ||
44 | |||
45 | fuzz_z: Noise on Z Axis | ||
46 | |||
47 | g_range: G range in milli g i.e 2000 or 8000 | ||
48 | |||
49 | mode: Default Operating mode | ||
50 | |||
51 | mdthr: Motion detect g range threshold value | ||
52 | |||
53 | mdfftmr: Motion detect and free fall time threshold value | ||
54 | |||
55 | ffthr: Free fall g range threshold value | ||
56 | |||
57 | Input Interface | ||
58 | -------------- | ||
59 | Input driver version is 1.0.0 | ||
60 | Input device ID: bus 0x18 vendor 0x0 product 0x0 version 0x0 | ||
61 | Input device name: "cma3000-accelerometer" | ||
62 | Supported events: | ||
63 | Event type 0 (Sync) | ||
64 | Event type 3 (Absolute) | ||
65 | Event code 0 (X) | ||
66 | Value 47 | ||
67 | Min -8000 | ||
68 | Max 8000 | ||
69 | Fuzz 200 | ||
70 | Event code 1 (Y) | ||
71 | Value -28 | ||
72 | Min -8000 | ||
73 | Max 8000 | ||
74 | Fuzz 200 | ||
75 | Event code 2 (Z) | ||
76 | Value 905 | ||
77 | Min -8000 | ||
78 | Max 8000 | ||
79 | Fuzz 200 | ||
80 | Event code 40 (Misc) | ||
81 | Value 0 | ||
82 | Min 0 | ||
83 | Max 1 | ||
84 | Event type 4 (Misc) | ||
85 | |||
86 | |||
87 | Register/Platform parameters Description | ||
88 | ---------------------------------------- | ||
89 | |||
90 | mode: | ||
91 | 0: power down mode | ||
92 | 1: 100 Hz Measurement mode | ||
93 | 2: 400 Hz Measurement mode | ||
94 | 3: 40 Hz Measurement mode | ||
95 | 4: Motion Detect mode (default) | ||
96 | 5: 100 Hz Free fall mode | ||
97 | 6: 40 Hz Free fall mode | ||
98 | 7: Power off mode | ||
99 | |||
100 | grange: | ||
101 | 2000: 2000 mg or 2G Range | ||
102 | 8000: 8000 mg or 8G Range | ||
103 | |||
104 | mdthr: | ||
105 | X: X * 71mg (8G Range) | ||
106 | X: X * 18mg (2G Range) | ||
107 | |||
108 | mdfftmr: | ||
109 | X: (X & 0x70) * 100 ms (MDTMR) | ||
110 | (X & 0x0F) * 2.5 ms (FFTMR 400 Hz) | ||
111 | (X & 0x0F) * 10 ms (FFTMR 100 Hz) | ||
112 | |||
113 | ffthr: | ||
114 | X: (X >> 2) * 18mg (2G Range) | ||
115 | X: (X & 0x0F) * 71 mg (8G Range) | ||
diff --git a/Documentation/input/multi-touch-protocol.txt b/Documentation/input/multi-touch-protocol.txt index bdcba154b83e..71536e78406f 100644 --- a/Documentation/input/multi-touch-protocol.txt +++ b/Documentation/input/multi-touch-protocol.txt | |||
@@ -1,6 +1,6 @@ | |||
1 | Multi-touch (MT) Protocol | 1 | Multi-touch (MT) Protocol |
2 | ------------------------- | 2 | ------------------------- |
3 | Copyright (C) 2009 Henrik Rydberg <rydberg@euromail.se> | 3 | Copyright (C) 2009-2010 Henrik Rydberg <rydberg@euromail.se> |
4 | 4 | ||
5 | 5 | ||
6 | Introduction | 6 | Introduction |
@@ -161,19 +161,24 @@ against the glass. The inner region will increase, and in general, the | |||
161 | ratio ABS_MT_TOUCH_MAJOR / ABS_MT_WIDTH_MAJOR, which is always smaller than | 161 | ratio ABS_MT_TOUCH_MAJOR / ABS_MT_WIDTH_MAJOR, which is always smaller than |
162 | unity, is related to the contact pressure. For pressure-based devices, | 162 | unity, is related to the contact pressure. For pressure-based devices, |
163 | ABS_MT_PRESSURE may be used to provide the pressure on the contact area | 163 | ABS_MT_PRESSURE may be used to provide the pressure on the contact area |
164 | instead. | 164 | instead. Devices capable of contact hovering can use ABS_MT_DISTANCE to |
165 | indicate the distance between the contact and the surface. | ||
165 | 166 | ||
166 | In addition to the MAJOR parameters, the oval shape of the contact can be | 167 | In addition to the MAJOR parameters, the oval shape of the contact can be |
167 | described by adding the MINOR parameters, such that MAJOR and MINOR are the | 168 | described by adding the MINOR parameters, such that MAJOR and MINOR are the |
168 | major and minor axis of an ellipse. Finally, the orientation of the oval | 169 | major and minor axis of an ellipse. Finally, the orientation of the oval |
169 | shape can be describe with the ORIENTATION parameter. | 170 | shape can be describe with the ORIENTATION parameter. |
170 | 171 | ||
172 | For type A devices, further specification of the touch shape is possible | ||
173 | via ABS_MT_BLOB_ID. | ||
174 | |||
171 | The ABS_MT_TOOL_TYPE may be used to specify whether the touching tool is a | 175 | The ABS_MT_TOOL_TYPE may be used to specify whether the touching tool is a |
172 | contact or a pen or something else. Devices with more granular information | 176 | finger or a pen or something else. Finally, the ABS_MT_TRACKING_ID event |
173 | may specify general shapes as blobs, i.e., as a sequence of rectangular | 177 | may be used to track identified contacts over time [5]. |
174 | shapes grouped together by an ABS_MT_BLOB_ID. Finally, for the few devices | 178 | |
175 | that currently support it, the ABS_MT_TRACKING_ID event may be used to | 179 | In the type B protocol, ABS_MT_TOOL_TYPE and ABS_MT_TRACKING_ID are |
176 | report contact tracking from hardware [5]. | 180 | implicitly handled by input core; drivers should instead call |
181 | input_mt_report_slot_state(). | ||
177 | 182 | ||
178 | 183 | ||
179 | Event Semantics | 184 | Event Semantics |
@@ -213,6 +218,12 @@ The pressure, in arbitrary units, on the contact area. May be used instead | |||
213 | of TOUCH and WIDTH for pressure-based devices or any device with a spatial | 218 | of TOUCH and WIDTH for pressure-based devices or any device with a spatial |
214 | signal intensity distribution. | 219 | signal intensity distribution. |
215 | 220 | ||
221 | ABS_MT_DISTANCE | ||
222 | |||
223 | The distance, in surface units, between the contact and the surface. Zero | ||
224 | distance means the contact is touching the surface. A positive number means | ||
225 | the contact is hovering above the surface. | ||
226 | |||
216 | ABS_MT_ORIENTATION | 227 | ABS_MT_ORIENTATION |
217 | 228 | ||
218 | The orientation of the ellipse. The value should describe a signed quarter | 229 | The orientation of the ellipse. The value should describe a signed quarter |
@@ -240,21 +251,24 @@ ABS_MT_TOOL_TYPE | |||
240 | The type of approaching tool. A lot of kernel drivers cannot distinguish | 251 | The type of approaching tool. A lot of kernel drivers cannot distinguish |
241 | between different tool types, such as a finger or a pen. In such cases, the | 252 | between different tool types, such as a finger or a pen. In such cases, the |
242 | event should be omitted. The protocol currently supports MT_TOOL_FINGER and | 253 | event should be omitted. The protocol currently supports MT_TOOL_FINGER and |
243 | MT_TOOL_PEN [2]. | 254 | MT_TOOL_PEN [2]. For type B devices, this event is handled by input core; |
255 | drivers should instead use input_mt_report_slot_state(). | ||
244 | 256 | ||
245 | ABS_MT_BLOB_ID | 257 | ABS_MT_BLOB_ID |
246 | 258 | ||
247 | The BLOB_ID groups several packets together into one arbitrarily shaped | 259 | The BLOB_ID groups several packets together into one arbitrarily shaped |
248 | contact. This is a low-level anonymous grouping for type A devices, and | 260 | contact. The sequence of points forms a polygon which defines the shape of |
261 | the contact. This is a low-level anonymous grouping for type A devices, and | ||
249 | should not be confused with the high-level trackingID [5]. Most type A | 262 | should not be confused with the high-level trackingID [5]. Most type A |
250 | devices do not have blob capability, so drivers can safely omit this event. | 263 | devices do not have blob capability, so drivers can safely omit this event. |
251 | 264 | ||
252 | ABS_MT_TRACKING_ID | 265 | ABS_MT_TRACKING_ID |
253 | 266 | ||
254 | The TRACKING_ID identifies an initiated contact throughout its life cycle | 267 | The TRACKING_ID identifies an initiated contact throughout its life cycle |
255 | [5]. This event is mandatory for type B devices. The value range of the | 268 | [5]. The value range of the TRACKING_ID should be large enough to ensure |
256 | TRACKING_ID should be large enough to ensure unique identification of a | 269 | unique identification of a contact maintained over an extended period of |
257 | contact maintained over an extended period of time. | 270 | time. For type B devices, this event is handled by input core; drivers |
271 | should instead use input_mt_report_slot_state(). | ||
258 | 272 | ||
259 | 273 | ||
260 | Event Computation | 274 | Event Computation |
@@ -301,18 +315,19 @@ and with ORIENTATION, one can detect twisting of fingers. | |||
301 | Notes | 315 | Notes |
302 | ----- | 316 | ----- |
303 | 317 | ||
304 | In order to stay compatible with existing applications, the data | 318 | In order to stay compatible with existing applications, the data reported |
305 | reported in a finger packet must not be recognized as single-touch | 319 | in a finger packet must not be recognized as single-touch events. |
306 | events. In addition, all finger data must bypass input filtering, | 320 | |
307 | since subsequent events of the same type refer to different fingers. | 321 | For type A devices, all finger data bypasses input filtering, since |
322 | subsequent events of the same type refer to different fingers. | ||
308 | 323 | ||
309 | The first kernel driver to utilize the MT protocol is the bcm5974 driver, | 324 | For example usage of the type A protocol, see the bcm5974 driver. For |
310 | where examples can be found. | 325 | example usage of the type B protocol, see the hid-egalax driver. |
311 | 326 | ||
312 | [1] With the extension ABS_MT_APPROACH_X and ABS_MT_APPROACH_Y, the | 327 | [1] With the extension ABS_MT_APPROACH_X and ABS_MT_APPROACH_Y, the |
313 | difference between the contact position and the approaching tool position | 328 | difference between the contact position and the approaching tool position |
314 | could be used to derive tilt. | 329 | could be used to derive tilt. |
315 | [2] The list can of course be extended. | 330 | [2] The list can of course be extended. |
316 | [3] Multitouch X driver project: http://bitmath.org/code/multitouch/. | 331 | [3] The mtdev project: http://bitmath.org/code/mtdev/. |
317 | [4] See the section on event computation. | 332 | [4] See the section on event computation. |
318 | [5] See the section on finger tracking. | 333 | [5] See the section on finger tracking. |
diff --git a/MAINTAINERS b/MAINTAINERS index bcb78306b62f..78d317c545b9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -3065,8 +3065,10 @@ F: drivers/input/ | |||
3065 | INPUT MULTITOUCH (MT) PROTOCOL | 3065 | INPUT MULTITOUCH (MT) PROTOCOL |
3066 | M: Henrik Rydberg <rydberg@euromail.se> | 3066 | M: Henrik Rydberg <rydberg@euromail.se> |
3067 | L: linux-input@vger.kernel.org | 3067 | L: linux-input@vger.kernel.org |
3068 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/rydberg/input-mt.git | ||
3068 | S: Maintained | 3069 | S: Maintained |
3069 | F: Documentation/input/multi-touch-protocol.txt | 3070 | F: Documentation/input/multi-touch-protocol.txt |
3071 | F: drivers/input/input-mt.c | ||
3070 | K: \b(ABS|SYN)_MT_ | 3072 | K: \b(ABS|SYN)_MT_ |
3071 | 3073 | ||
3072 | INTEL IDLE DRIVER | 3074 | INTEL IDLE DRIVER |
diff --git a/arch/arm/plat-spear/include/plat/keyboard.h b/arch/arm/plat-spear/include/plat/keyboard.h new file mode 100644 index 000000000000..68b5394fc583 --- /dev/null +++ b/arch/arm/plat-spear/include/plat/keyboard.h | |||
@@ -0,0 +1,141 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 ST Microelectronics | ||
3 | * Rajeev Kumar<rajeev-dlh.kumar@st.com> | ||
4 | * | ||
5 | * This file is licensed under the terms of the GNU General Public | ||
6 | * License version 2. This program is licensed "as is" without any | ||
7 | * warranty of any kind, whether express or implied. | ||
8 | */ | ||
9 | |||
10 | #ifndef __PLAT_KEYBOARD_H | ||
11 | #define __PLAT_KEYBOARD_H | ||
12 | |||
13 | #include <linux/bitops.h> | ||
14 | #include <linux/input.h> | ||
15 | #include <linux/input/matrix_keypad.h> | ||
16 | #include <linux/types.h> | ||
17 | |||
18 | #define DECLARE_KEYMAP(_name) \ | ||
19 | int _name[] = { \ | ||
20 | KEY(0, 0, KEY_ESC), \ | ||
21 | KEY(0, 1, KEY_1), \ | ||
22 | KEY(0, 2, KEY_2), \ | ||
23 | KEY(0, 3, KEY_3), \ | ||
24 | KEY(0, 4, KEY_4), \ | ||
25 | KEY(0, 5, KEY_5), \ | ||
26 | KEY(0, 6, KEY_6), \ | ||
27 | KEY(0, 7, KEY_7), \ | ||
28 | KEY(0, 8, KEY_8), \ | ||
29 | KEY(1, 0, KEY_9), \ | ||
30 | KEY(1, 1, KEY_MINUS), \ | ||
31 | KEY(1, 2, KEY_EQUAL), \ | ||
32 | KEY(1, 3, KEY_BACKSPACE), \ | ||
33 | KEY(1, 4, KEY_TAB), \ | ||
34 | KEY(1, 5, KEY_Q), \ | ||
35 | KEY(1, 6, KEY_W), \ | ||
36 | KEY(1, 7, KEY_E), \ | ||
37 | KEY(1, 8, KEY_R), \ | ||
38 | KEY(2, 0, KEY_T), \ | ||
39 | KEY(2, 1, KEY_Y), \ | ||
40 | KEY(2, 2, KEY_U), \ | ||
41 | KEY(2, 3, KEY_I), \ | ||
42 | KEY(2, 4, KEY_O), \ | ||
43 | KEY(2, 5, KEY_P), \ | ||
44 | KEY(2, 6, KEY_LEFTBRACE), \ | ||
45 | KEY(2, 7, KEY_RIGHTBRACE), \ | ||
46 | KEY(2, 8, KEY_ENTER), \ | ||
47 | KEY(3, 0, KEY_LEFTCTRL), \ | ||
48 | KEY(3, 1, KEY_A), \ | ||
49 | KEY(3, 2, KEY_S), \ | ||
50 | KEY(3, 3, KEY_D), \ | ||
51 | KEY(3, 4, KEY_F), \ | ||
52 | KEY(3, 5, KEY_G), \ | ||
53 | KEY(3, 6, KEY_H), \ | ||
54 | KEY(3, 7, KEY_J), \ | ||
55 | KEY(3, 8, KEY_K), \ | ||
56 | KEY(4, 0, KEY_L), \ | ||
57 | KEY(4, 1, KEY_SEMICOLON), \ | ||
58 | KEY(4, 2, KEY_APOSTROPHE), \ | ||
59 | KEY(4, 3, KEY_GRAVE), \ | ||
60 | KEY(4, 4, KEY_LEFTSHIFT), \ | ||
61 | KEY(4, 5, KEY_BACKSLASH), \ | ||
62 | KEY(4, 6, KEY_Z), \ | ||
63 | KEY(4, 7, KEY_X), \ | ||
64 | KEY(4, 8, KEY_C), \ | ||
65 | KEY(4, 0, KEY_L), \ | ||
66 | KEY(4, 1, KEY_SEMICOLON), \ | ||
67 | KEY(4, 2, KEY_APOSTROPHE), \ | ||
68 | KEY(4, 3, KEY_GRAVE), \ | ||
69 | KEY(4, 4, KEY_LEFTSHIFT), \ | ||
70 | KEY(4, 5, KEY_BACKSLASH), \ | ||
71 | KEY(4, 6, KEY_Z), \ | ||
72 | KEY(4, 7, KEY_X), \ | ||
73 | KEY(4, 8, KEY_C), \ | ||
74 | KEY(4, 0, KEY_L), \ | ||
75 | KEY(4, 1, KEY_SEMICOLON), \ | ||
76 | KEY(4, 2, KEY_APOSTROPHE), \ | ||
77 | KEY(4, 3, KEY_GRAVE), \ | ||
78 | KEY(4, 4, KEY_LEFTSHIFT), \ | ||
79 | KEY(4, 5, KEY_BACKSLASH), \ | ||
80 | KEY(4, 6, KEY_Z), \ | ||
81 | KEY(4, 7, KEY_X), \ | ||
82 | KEY(4, 8, KEY_C), \ | ||
83 | KEY(5, 0, KEY_V), \ | ||
84 | KEY(5, 1, KEY_B), \ | ||
85 | KEY(5, 2, KEY_N), \ | ||
86 | KEY(5, 3, KEY_M), \ | ||
87 | KEY(5, 4, KEY_COMMA), \ | ||
88 | KEY(5, 5, KEY_DOT), \ | ||
89 | KEY(5, 6, KEY_SLASH), \ | ||
90 | KEY(5, 7, KEY_RIGHTSHIFT), \ | ||
91 | KEY(5, 8, KEY_KPASTERISK), \ | ||
92 | KEY(6, 0, KEY_LEFTALT), \ | ||
93 | KEY(6, 1, KEY_SPACE), \ | ||
94 | KEY(6, 2, KEY_CAPSLOCK), \ | ||
95 | KEY(6, 3, KEY_F1), \ | ||
96 | KEY(6, 4, KEY_F2), \ | ||
97 | KEY(6, 5, KEY_F3), \ | ||
98 | KEY(6, 6, KEY_F4), \ | ||
99 | KEY(6, 7, KEY_F5), \ | ||
100 | KEY(6, 8, KEY_F6), \ | ||
101 | KEY(7, 0, KEY_F7), \ | ||
102 | KEY(7, 1, KEY_F8), \ | ||
103 | KEY(7, 2, KEY_F9), \ | ||
104 | KEY(7, 3, KEY_F10), \ | ||
105 | KEY(7, 4, KEY_NUMLOCK), \ | ||
106 | KEY(7, 5, KEY_SCROLLLOCK), \ | ||
107 | KEY(7, 6, KEY_KP7), \ | ||
108 | KEY(7, 7, KEY_KP8), \ | ||
109 | KEY(7, 8, KEY_KP9), \ | ||
110 | KEY(8, 0, KEY_KPMINUS), \ | ||
111 | KEY(8, 1, KEY_KP4), \ | ||
112 | KEY(8, 2, KEY_KP5), \ | ||
113 | KEY(8, 3, KEY_KP6), \ | ||
114 | KEY(8, 4, KEY_KPPLUS), \ | ||
115 | KEY(8, 5, KEY_KP1), \ | ||
116 | KEY(8, 6, KEY_KP2), \ | ||
117 | KEY(8, 7, KEY_KP3), \ | ||
118 | KEY(8, 8, KEY_KP0), \ | ||
119 | } | ||
120 | |||
121 | /** | ||
122 | * struct kbd_platform_data - spear keyboard platform data | ||
123 | * keymap: pointer to keymap data (table and size) | ||
124 | * rep: enables key autorepeat | ||
125 | * | ||
126 | * This structure is supposed to be used by platform code to supply | ||
127 | * keymaps to drivers that implement keyboards. | ||
128 | */ | ||
129 | struct kbd_platform_data { | ||
130 | const struct matrix_keymap_data *keymap; | ||
131 | bool rep; | ||
132 | }; | ||
133 | |||
134 | /* This function is used to set platform data field of pdev->dev */ | ||
135 | static inline void | ||
136 | kbd_set_plat_data(struct platform_device *pdev, struct kbd_platform_data *data) | ||
137 | { | ||
138 | pdev->dev.platform_data = data; | ||
139 | } | ||
140 | |||
141 | #endif /* __PLAT_KEYBOARD_H */ | ||
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 3052e2969ad0..401acecc7f32 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
@@ -154,7 +154,8 @@ config HID_EGALAX | |||
154 | tristate "eGalax multi-touch panel" | 154 | tristate "eGalax multi-touch panel" |
155 | depends on USB_HID | 155 | depends on USB_HID |
156 | ---help--- | 156 | ---help--- |
157 | Support for the eGalax dual-touch panel. | 157 | Support for the eGalax dual-touch panels, including the |
158 | Joojoo and Wetab tablets. | ||
158 | 159 | ||
159 | config HID_ELECOM | 160 | config HID_ELECOM |
160 | tristate "ELECOM BM084 bluetooth mouse" | 161 | tristate "ELECOM BM084 bluetooth mouse" |
diff --git a/drivers/hid/hid-3m-pct.c b/drivers/hid/hid-3m-pct.c index 02d8cd3b1b1b..4fb7c7528d16 100644 --- a/drivers/hid/hid-3m-pct.c +++ b/drivers/hid/hid-3m-pct.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/usb.h> | 21 | #include <linux/usb.h> |
22 | #include <linux/input/mt.h> | ||
22 | 23 | ||
23 | MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>"); | 24 | MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>"); |
24 | MODULE_DESCRIPTION("3M PCT multitouch panels"); | 25 | MODULE_DESCRIPTION("3M PCT multitouch panels"); |
@@ -27,8 +28,6 @@ MODULE_LICENSE("GPL"); | |||
27 | #include "hid-ids.h" | 28 | #include "hid-ids.h" |
28 | 29 | ||
29 | #define MAX_SLOTS 60 | 30 | #define MAX_SLOTS 60 |
30 | #define MAX_TRKID USHRT_MAX | ||
31 | #define MAX_EVENTS 360 | ||
32 | 31 | ||
33 | /* estimated signal-to-noise ratios */ | 32 | /* estimated signal-to-noise ratios */ |
34 | #define SN_MOVE 2048 | 33 | #define SN_MOVE 2048 |
@@ -36,14 +35,11 @@ MODULE_LICENSE("GPL"); | |||
36 | 35 | ||
37 | struct mmm_finger { | 36 | struct mmm_finger { |
38 | __s32 x, y, w, h; | 37 | __s32 x, y, w, h; |
39 | __u16 id; | ||
40 | bool prev_touch; | ||
41 | bool touch, valid; | 38 | bool touch, valid; |
42 | }; | 39 | }; |
43 | 40 | ||
44 | struct mmm_data { | 41 | struct mmm_data { |
45 | struct mmm_finger f[MAX_SLOTS]; | 42 | struct mmm_finger f[MAX_SLOTS]; |
46 | __u16 id; | ||
47 | __u8 curid; | 43 | __u8 curid; |
48 | __u8 nexp, nreal; | 44 | __u8 nexp, nreal; |
49 | bool touch, valid; | 45 | bool touch, valid; |
@@ -117,14 +113,7 @@ static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
117 | 0, 1, 0, 0); | 113 | 0, 1, 0, 0); |
118 | return 1; | 114 | return 1; |
119 | case HID_DG_CONTACTID: | 115 | case HID_DG_CONTACTID: |
120 | field->logical_maximum = MAX_TRKID; | 116 | input_mt_init_slots(hi->input, MAX_SLOTS); |
121 | hid_map_usage(hi, usage, bit, max, | ||
122 | EV_ABS, ABS_MT_TRACKING_ID); | ||
123 | input_set_abs_params(hi->input, ABS_MT_TRACKING_ID, | ||
124 | 0, MAX_TRKID, 0, 0); | ||
125 | if (!hi->input->mt) | ||
126 | input_mt_create_slots(hi->input, MAX_SLOTS); | ||
127 | input_set_events_per_packet(hi->input, MAX_EVENTS); | ||
128 | return 1; | 117 | return 1; |
129 | } | 118 | } |
130 | /* let hid-input decide for the others */ | 119 | /* let hid-input decide for the others */ |
@@ -154,7 +143,6 @@ static int mmm_input_mapped(struct hid_device *hdev, struct hid_input *hi, | |||
154 | */ | 143 | */ |
155 | static void mmm_filter_event(struct mmm_data *md, struct input_dev *input) | 144 | static void mmm_filter_event(struct mmm_data *md, struct input_dev *input) |
156 | { | 145 | { |
157 | struct mmm_finger *oldest = 0; | ||
158 | int i; | 146 | int i; |
159 | for (i = 0; i < MAX_SLOTS; ++i) { | 147 | for (i = 0; i < MAX_SLOTS; ++i) { |
160 | struct mmm_finger *f = &md->f[i]; | 148 | struct mmm_finger *f = &md->f[i]; |
@@ -163,6 +151,7 @@ static void mmm_filter_event(struct mmm_data *md, struct input_dev *input) | |||
163 | continue; | 151 | continue; |
164 | } | 152 | } |
165 | input_mt_slot(input, i); | 153 | input_mt_slot(input, i); |
154 | input_mt_report_slot_state(input, MT_TOOL_FINGER, f->touch); | ||
166 | if (f->touch) { | 155 | if (f->touch) { |
167 | /* this finger is on the screen */ | 156 | /* this finger is on the screen */ |
168 | int wide = (f->w > f->h); | 157 | int wide = (f->w > f->h); |
@@ -170,33 +159,16 @@ static void mmm_filter_event(struct mmm_data *md, struct input_dev *input) | |||
170 | int major = max(f->w, f->h) >> 1; | 159 | int major = max(f->w, f->h) >> 1; |
171 | int minor = min(f->w, f->h) >> 1; | 160 | int minor = min(f->w, f->h) >> 1; |
172 | 161 | ||
173 | if (!f->prev_touch) | ||
174 | f->id = md->id++; | ||
175 | input_event(input, EV_ABS, ABS_MT_TRACKING_ID, f->id); | ||
176 | input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x); | 162 | input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x); |
177 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y); | 163 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y); |
178 | input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); | 164 | input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); |
179 | input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); | 165 | input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); |
180 | input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); | 166 | input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); |
181 | /* touchscreen emulation: pick the oldest contact */ | ||
182 | if (!oldest || ((f->id - oldest->id) & (SHRT_MAX + 1))) | ||
183 | oldest = f; | ||
184 | } else { | ||
185 | /* this finger took off the screen */ | ||
186 | input_event(input, EV_ABS, ABS_MT_TRACKING_ID, -1); | ||
187 | } | 167 | } |
188 | f->prev_touch = f->touch; | ||
189 | f->valid = 0; | 168 | f->valid = 0; |
190 | } | 169 | } |
191 | 170 | ||
192 | /* touchscreen emulation */ | 171 | input_mt_report_pointer_emulation(input, true); |
193 | if (oldest) { | ||
194 | input_event(input, EV_KEY, BTN_TOUCH, 1); | ||
195 | input_event(input, EV_ABS, ABS_X, oldest->x); | ||
196 | input_event(input, EV_ABS, ABS_Y, oldest->y); | ||
197 | } else { | ||
198 | input_event(input, EV_KEY, BTN_TOUCH, 0); | ||
199 | } | ||
200 | input_sync(input); | 172 | input_sync(input); |
201 | } | 173 | } |
202 | 174 | ||
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index ed1adc20c8eb..3f9673d94da9 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1300,6 +1300,9 @@ static const struct hid_device_id hid_blacklist[] = { | |||
1300 | { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, | 1300 | { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, |
1301 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, | 1301 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, |
1302 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) }, | 1302 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) }, |
1303 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) }, | ||
1304 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) }, | ||
1305 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) }, | ||
1303 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, | 1306 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, |
1304 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, | 1307 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, |
1305 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, | 1308 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, |
diff --git a/drivers/hid/hid-egalax.c b/drivers/hid/hid-egalax.c index 5a1b52e0eb85..8fbff2358eb6 100644 --- a/drivers/hid/hid-egalax.c +++ b/drivers/hid/hid-egalax.c | |||
@@ -2,6 +2,8 @@ | |||
2 | * HID driver for eGalax dual-touch panels | 2 | * HID driver for eGalax dual-touch panels |
3 | * | 3 | * |
4 | * Copyright (c) 2010 Stephane Chatty <chatty@enac.fr> | 4 | * Copyright (c) 2010 Stephane Chatty <chatty@enac.fr> |
5 | * Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se> | ||
6 | * Copyright (c) 2010 Canonical, Ltd. | ||
5 | * | 7 | * |
6 | */ | 8 | */ |
7 | 9 | ||
@@ -16,6 +18,7 @@ | |||
16 | #include <linux/hid.h> | 18 | #include <linux/hid.h> |
17 | #include <linux/module.h> | 19 | #include <linux/module.h> |
18 | #include <linux/usb.h> | 20 | #include <linux/usb.h> |
21 | #include <linux/input/mt.h> | ||
19 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
20 | #include "usbhid/usbhid.h" | 23 | #include "usbhid/usbhid.h" |
21 | 24 | ||
@@ -25,38 +28,53 @@ MODULE_LICENSE("GPL"); | |||
25 | 28 | ||
26 | #include "hid-ids.h" | 29 | #include "hid-ids.h" |
27 | 30 | ||
31 | #define MAX_SLOTS 2 | ||
32 | |||
33 | /* estimated signal-to-noise ratios */ | ||
34 | #define SN_MOVE 4096 | ||
35 | #define SN_PRESSURE 32 | ||
36 | |||
28 | struct egalax_data { | 37 | struct egalax_data { |
29 | __u16 x, y, z; | 38 | int valid; |
30 | __u8 id; | 39 | int slot; |
31 | bool first; /* is this the first finger in the frame? */ | 40 | int touch; |
32 | bool valid; /* valid finger data, or just placeholder? */ | 41 | int x, y, z; |
33 | bool activity; /* at least one active finger previously? */ | ||
34 | __u16 lastx, lasty, lastz; /* latest valid (x, y, z) in the frame */ | ||
35 | }; | 42 | }; |
36 | 43 | ||
44 | static void set_abs(struct input_dev *input, unsigned int code, | ||
45 | struct hid_field *field, int snratio) | ||
46 | { | ||
47 | int fmin = field->logical_minimum; | ||
48 | int fmax = field->logical_maximum; | ||
49 | int fuzz = snratio ? (fmax - fmin) / snratio : 0; | ||
50 | input_set_abs_params(input, code, fmin, fmax, fuzz, 0); | ||
51 | } | ||
52 | |||
37 | static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 53 | static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
38 | struct hid_field *field, struct hid_usage *usage, | 54 | struct hid_field *field, struct hid_usage *usage, |
39 | unsigned long **bit, int *max) | 55 | unsigned long **bit, int *max) |
40 | { | 56 | { |
57 | struct input_dev *input = hi->input; | ||
58 | |||
41 | switch (usage->hid & HID_USAGE_PAGE) { | 59 | switch (usage->hid & HID_USAGE_PAGE) { |
42 | 60 | ||
43 | case HID_UP_GENDESK: | 61 | case HID_UP_GENDESK: |
44 | switch (usage->hid) { | 62 | switch (usage->hid) { |
45 | case HID_GD_X: | 63 | case HID_GD_X: |
64 | field->logical_maximum = 32760; | ||
46 | hid_map_usage(hi, usage, bit, max, | 65 | hid_map_usage(hi, usage, bit, max, |
47 | EV_ABS, ABS_MT_POSITION_X); | 66 | EV_ABS, ABS_MT_POSITION_X); |
67 | set_abs(input, ABS_MT_POSITION_X, field, SN_MOVE); | ||
48 | /* touchscreen emulation */ | 68 | /* touchscreen emulation */ |
49 | input_set_abs_params(hi->input, ABS_X, | 69 | set_abs(input, ABS_X, field, SN_MOVE); |
50 | field->logical_minimum, | ||
51 | field->logical_maximum, 0, 0); | ||
52 | return 1; | 70 | return 1; |
53 | case HID_GD_Y: | 71 | case HID_GD_Y: |
72 | field->logical_maximum = 32760; | ||
54 | hid_map_usage(hi, usage, bit, max, | 73 | hid_map_usage(hi, usage, bit, max, |
55 | EV_ABS, ABS_MT_POSITION_Y); | 74 | EV_ABS, ABS_MT_POSITION_Y); |
75 | set_abs(input, ABS_MT_POSITION_Y, field, SN_MOVE); | ||
56 | /* touchscreen emulation */ | 76 | /* touchscreen emulation */ |
57 | input_set_abs_params(hi->input, ABS_Y, | 77 | set_abs(input, ABS_Y, field, SN_MOVE); |
58 | field->logical_minimum, | ||
59 | field->logical_maximum, 0, 0); | ||
60 | return 1; | 78 | return 1; |
61 | } | 79 | } |
62 | return 0; | 80 | return 0; |
@@ -66,6 +84,7 @@ static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
66 | case HID_DG_TIPSWITCH: | 84 | case HID_DG_TIPSWITCH: |
67 | /* touchscreen emulation */ | 85 | /* touchscreen emulation */ |
68 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); | 86 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); |
87 | input_set_capability(input, EV_KEY, BTN_TOUCH); | ||
69 | return 1; | 88 | return 1; |
70 | case HID_DG_INRANGE: | 89 | case HID_DG_INRANGE: |
71 | case HID_DG_CONFIDENCE: | 90 | case HID_DG_CONFIDENCE: |
@@ -73,16 +92,15 @@ static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
73 | case HID_DG_CONTACTMAX: | 92 | case HID_DG_CONTACTMAX: |
74 | return -1; | 93 | return -1; |
75 | case HID_DG_CONTACTID: | 94 | case HID_DG_CONTACTID: |
76 | hid_map_usage(hi, usage, bit, max, | 95 | input_mt_init_slots(input, MAX_SLOTS); |
77 | EV_ABS, ABS_MT_TRACKING_ID); | ||
78 | return 1; | 96 | return 1; |
79 | case HID_DG_TIPPRESSURE: | 97 | case HID_DG_TIPPRESSURE: |
98 | field->logical_minimum = 0; | ||
80 | hid_map_usage(hi, usage, bit, max, | 99 | hid_map_usage(hi, usage, bit, max, |
81 | EV_ABS, ABS_MT_PRESSURE); | 100 | EV_ABS, ABS_MT_PRESSURE); |
101 | set_abs(input, ABS_MT_PRESSURE, field, SN_PRESSURE); | ||
82 | /* touchscreen emulation */ | 102 | /* touchscreen emulation */ |
83 | input_set_abs_params(hi->input, ABS_PRESSURE, | 103 | set_abs(input, ABS_PRESSURE, field, SN_PRESSURE); |
84 | field->logical_minimum, | ||
85 | field->logical_maximum, 0, 0); | ||
86 | return 1; | 104 | return 1; |
87 | } | 105 | } |
88 | return 0; | 106 | return 0; |
@@ -96,10 +114,10 @@ static int egalax_input_mapped(struct hid_device *hdev, struct hid_input *hi, | |||
96 | struct hid_field *field, struct hid_usage *usage, | 114 | struct hid_field *field, struct hid_usage *usage, |
97 | unsigned long **bit, int *max) | 115 | unsigned long **bit, int *max) |
98 | { | 116 | { |
117 | /* tell hid-input to skip setup of these event types */ | ||
99 | if (usage->type == EV_KEY || usage->type == EV_ABS) | 118 | if (usage->type == EV_KEY || usage->type == EV_ABS) |
100 | clear_bit(usage->code, *bit); | 119 | set_bit(usage->type, hi->input->evbit); |
101 | 120 | return -1; | |
102 | return 0; | ||
103 | } | 121 | } |
104 | 122 | ||
105 | /* | 123 | /* |
@@ -108,58 +126,16 @@ static int egalax_input_mapped(struct hid_device *hdev, struct hid_input *hi, | |||
108 | */ | 126 | */ |
109 | static void egalax_filter_event(struct egalax_data *td, struct input_dev *input) | 127 | static void egalax_filter_event(struct egalax_data *td, struct input_dev *input) |
110 | { | 128 | { |
111 | td->first = !td->first; /* touchscreen emulation */ | 129 | input_mt_slot(input, td->slot); |
112 | 130 | input_mt_report_slot_state(input, MT_TOOL_FINGER, td->touch); | |
113 | if (td->valid) { | 131 | if (td->touch) { |
114 | /* emit multitouch events */ | 132 | input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x); |
115 | input_event(input, EV_ABS, ABS_MT_TRACKING_ID, td->id); | 133 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y); |
116 | input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x >> 3); | ||
117 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y >> 3); | ||
118 | input_event(input, EV_ABS, ABS_MT_PRESSURE, td->z); | 134 | input_event(input, EV_ABS, ABS_MT_PRESSURE, td->z); |
119 | |||
120 | input_mt_sync(input); | ||
121 | |||
122 | /* | ||
123 | * touchscreen emulation: store (x, y) as | ||
124 | * the last valid values in this frame | ||
125 | */ | ||
126 | td->lastx = td->x; | ||
127 | td->lasty = td->y; | ||
128 | td->lastz = td->z; | ||
129 | } | ||
130 | |||
131 | /* | ||
132 | * touchscreen emulation: if this is the second finger and at least | ||
133 | * one in this frame is valid, the latest valid in the frame is | ||
134 | * the oldest on the panel, the one we want for single touch | ||
135 | */ | ||
136 | if (!td->first && td->activity) { | ||
137 | input_event(input, EV_ABS, ABS_X, td->lastx >> 3); | ||
138 | input_event(input, EV_ABS, ABS_Y, td->lasty >> 3); | ||
139 | input_event(input, EV_ABS, ABS_PRESSURE, td->lastz); | ||
140 | } | ||
141 | |||
142 | if (!td->valid) { | ||
143 | /* | ||
144 | * touchscreen emulation: if the first finger is invalid | ||
145 | * and there previously was finger activity, this is a release | ||
146 | */ | ||
147 | if (td->first && td->activity) { | ||
148 | input_event(input, EV_KEY, BTN_TOUCH, 0); | ||
149 | td->activity = false; | ||
150 | } | ||
151 | return; | ||
152 | } | ||
153 | |||
154 | |||
155 | /* touchscreen emulation: if no previous activity, emit touch event */ | ||
156 | if (!td->activity) { | ||
157 | input_event(input, EV_KEY, BTN_TOUCH, 1); | ||
158 | td->activity = true; | ||
159 | } | 135 | } |
136 | input_mt_report_pointer_emulation(input, true); | ||
160 | } | 137 | } |
161 | 138 | ||
162 | |||
163 | static int egalax_event(struct hid_device *hid, struct hid_field *field, | 139 | static int egalax_event(struct hid_device *hid, struct hid_field *field, |
164 | struct hid_usage *usage, __s32 value) | 140 | struct hid_usage *usage, __s32 value) |
165 | { | 141 | { |
@@ -169,25 +145,26 @@ static int egalax_event(struct hid_device *hid, struct hid_field *field, | |||
169 | * uses a standard parallel multitouch protocol (product ID == | 145 | * uses a standard parallel multitouch protocol (product ID == |
170 | * 48xx). The second is capacitive and uses an unusual "serial" | 146 | * 48xx). The second is capacitive and uses an unusual "serial" |
171 | * protocol with a different message for each multitouch finger | 147 | * protocol with a different message for each multitouch finger |
172 | * (product ID == 72xx). We do not yet generate a correct event | 148 | * (product ID == 72xx). |
173 | * sequence for the capacitive/serial protocol. | ||
174 | */ | 149 | */ |
175 | if (hid->claimed & HID_CLAIMED_INPUT) { | 150 | if (hid->claimed & HID_CLAIMED_INPUT) { |
176 | struct input_dev *input = field->hidinput->input; | 151 | struct input_dev *input = field->hidinput->input; |
177 | 152 | ||
178 | switch (usage->hid) { | 153 | switch (usage->hid) { |
179 | case HID_DG_INRANGE: | 154 | case HID_DG_INRANGE: |
155 | td->valid = value; | ||
156 | break; | ||
180 | case HID_DG_CONFIDENCE: | 157 | case HID_DG_CONFIDENCE: |
181 | /* avoid interference from generic hidinput handling */ | 158 | /* avoid interference from generic hidinput handling */ |
182 | break; | 159 | break; |
183 | case HID_DG_TIPSWITCH: | 160 | case HID_DG_TIPSWITCH: |
184 | td->valid = value; | 161 | td->touch = value; |
185 | break; | 162 | break; |
186 | case HID_DG_TIPPRESSURE: | 163 | case HID_DG_TIPPRESSURE: |
187 | td->z = value; | 164 | td->z = value; |
188 | break; | 165 | break; |
189 | case HID_DG_CONTACTID: | 166 | case HID_DG_CONTACTID: |
190 | td->id = value; | 167 | td->slot = clamp_val(value, 0, MAX_SLOTS - 1); |
191 | break; | 168 | break; |
192 | case HID_GD_X: | 169 | case HID_GD_X: |
193 | td->x = value; | 170 | td->x = value; |
@@ -195,11 +172,11 @@ static int egalax_event(struct hid_device *hid, struct hid_field *field, | |||
195 | case HID_GD_Y: | 172 | case HID_GD_Y: |
196 | td->y = value; | 173 | td->y = value; |
197 | /* this is the last field in a finger */ | 174 | /* this is the last field in a finger */ |
198 | egalax_filter_event(td, input); | 175 | if (td->valid) |
176 | egalax_filter_event(td, input); | ||
199 | break; | 177 | break; |
200 | case HID_DG_CONTACTCOUNT: | 178 | case HID_DG_CONTACTCOUNT: |
201 | /* touch emulation: this is the last field in a frame */ | 179 | /* touch emulation: this is the last field in a frame */ |
202 | td->first = false; | ||
203 | break; | 180 | break; |
204 | 181 | ||
205 | default: | 182 | default: |
@@ -261,6 +238,12 @@ static const struct hid_device_id egalax_devices[] = { | |||
261 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, | 238 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, |
262 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 239 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, |
263 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) }, | 240 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) }, |
241 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
242 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) }, | ||
243 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
244 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) }, | ||
245 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
246 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) }, | ||
264 | { } | 247 | { } |
265 | }; | 248 | }; |
266 | MODULE_DEVICE_TABLE(hid, egalax_devices); | 249 | MODULE_DEVICE_TABLE(hid, egalax_devices); |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 5a559de22282..8e11af86b014 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -196,6 +196,9 @@ | |||
196 | #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 | 196 | #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 |
197 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH 0x480d | 197 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH 0x480d |
198 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1 0x720c | 198 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1 0x720c |
199 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2 0x72a1 | ||
200 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3 0x480e | ||
201 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4 0x726b | ||
199 | 202 | ||
200 | #define USB_VENDOR_ID_ELECOM 0x056e | 203 | #define USB_VENDOR_ID_ELECOM 0x056e |
201 | #define USB_DEVICE_ID_ELECOM_BM084 0x0061 | 204 | #define USB_DEVICE_ID_ELECOM_BM084 0x0061 |
diff --git a/drivers/input/Makefile b/drivers/input/Makefile index 7ad212d31f99..09614ce74961 100644 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile | |||
@@ -5,7 +5,7 @@ | |||
5 | # Each configuration option enables a list of files. | 5 | # Each configuration option enables a list of files. |
6 | 6 | ||
7 | obj-$(CONFIG_INPUT) += input-core.o | 7 | obj-$(CONFIG_INPUT) += input-core.o |
8 | input-core-objs := input.o input-compat.o ff-core.o | 8 | input-core-y := input.o input-compat.o input-mt.o ff-core.o |
9 | 9 | ||
10 | obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o | 10 | obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o |
11 | obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o | 11 | obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o |
diff --git a/drivers/input/apm-power.c b/drivers/input/apm-power.c index 7d61a9660806..e90ee3d30613 100644 --- a/drivers/input/apm-power.c +++ b/drivers/input/apm-power.c | |||
@@ -9,6 +9,8 @@ | |||
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
13 | |||
12 | #include <linux/module.h> | 14 | #include <linux/module.h> |
13 | #include <linux/input.h> | 15 | #include <linux/input.h> |
14 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
@@ -23,8 +25,7 @@ static void system_power_event(unsigned int keycode) | |||
23 | switch (keycode) { | 25 | switch (keycode) { |
24 | case KEY_SUSPEND: | 26 | case KEY_SUSPEND: |
25 | apm_queue_event(APM_USER_SUSPEND); | 27 | apm_queue_event(APM_USER_SUSPEND); |
26 | 28 | pr_info("Requesting system suspend...\n"); | |
27 | printk(KERN_INFO "apm-power: Requesting system suspend...\n"); | ||
28 | break; | 29 | break; |
29 | default: | 30 | default: |
30 | break; | 31 | break; |
@@ -65,18 +66,15 @@ static int apmpower_connect(struct input_handler *handler, | |||
65 | 66 | ||
66 | error = input_register_handle(handle); | 67 | error = input_register_handle(handle); |
67 | if (error) { | 68 | if (error) { |
68 | printk(KERN_ERR | 69 | pr_err("Failed to register input power handler, error %d\n", |
69 | "apm-power: Failed to register input power handler, " | 70 | error); |
70 | "error %d\n", error); | ||
71 | kfree(handle); | 71 | kfree(handle); |
72 | return error; | 72 | return error; |
73 | } | 73 | } |
74 | 74 | ||
75 | error = input_open_device(handle); | 75 | error = input_open_device(handle); |
76 | if (error) { | 76 | if (error) { |
77 | printk(KERN_ERR | 77 | pr_err("Failed to open input power device, error %d\n", error); |
78 | "apm-power: Failed to open input power device, " | ||
79 | "error %d\n", error); | ||
80 | input_unregister_handle(handle); | 78 | input_unregister_handle(handle); |
81 | kfree(handle); | 79 | kfree(handle); |
82 | return error; | 80 | return error; |
diff --git a/drivers/input/evbug.c b/drivers/input/evbug.c index f7c5c14ec12a..cd4e6679d61a 100644 --- a/drivers/input/evbug.c +++ b/drivers/input/evbug.c | |||
@@ -26,6 +26,8 @@ | |||
26 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic | 26 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
30 | |||
29 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
30 | #include <linux/module.h> | 32 | #include <linux/module.h> |
31 | #include <linux/input.h> | 33 | #include <linux/input.h> |
@@ -38,8 +40,8 @@ MODULE_LICENSE("GPL"); | |||
38 | 40 | ||
39 | static void evbug_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) | 41 | static void evbug_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) |
40 | { | 42 | { |
41 | printk(KERN_DEBUG "evbug.c: Event. Dev: %s, Type: %d, Code: %d, Value: %d\n", | 43 | printk(KERN_DEBUG pr_fmt("Event. Dev: %s, Type: %d, Code: %d, Value: %d\n"), |
42 | dev_name(&handle->dev->dev), type, code, value); | 44 | dev_name(&handle->dev->dev), type, code, value); |
43 | } | 45 | } |
44 | 46 | ||
45 | static int evbug_connect(struct input_handler *handler, struct input_dev *dev, | 47 | static int evbug_connect(struct input_handler *handler, struct input_dev *dev, |
@@ -64,10 +66,10 @@ static int evbug_connect(struct input_handler *handler, struct input_dev *dev, | |||
64 | if (error) | 66 | if (error) |
65 | goto err_unregister_handle; | 67 | goto err_unregister_handle; |
66 | 68 | ||
67 | printk(KERN_DEBUG "evbug.c: Connected device: %s (%s at %s)\n", | 69 | printk(KERN_DEBUG pr_fmt("Connected device: %s (%s at %s)\n"), |
68 | dev_name(&dev->dev), | 70 | dev_name(&dev->dev), |
69 | dev->name ?: "unknown", | 71 | dev->name ?: "unknown", |
70 | dev->phys ?: "unknown"); | 72 | dev->phys ?: "unknown"); |
71 | 73 | ||
72 | return 0; | 74 | return 0; |
73 | 75 | ||
@@ -80,8 +82,8 @@ static int evbug_connect(struct input_handler *handler, struct input_dev *dev, | |||
80 | 82 | ||
81 | static void evbug_disconnect(struct input_handle *handle) | 83 | static void evbug_disconnect(struct input_handle *handle) |
82 | { | 84 | { |
83 | printk(KERN_DEBUG "evbug.c: Disconnected device: %s\n", | 85 | printk(KERN_DEBUG pr_fmt("Disconnected device: %s\n"), |
84 | dev_name(&handle->dev->dev)); | 86 | dev_name(&handle->dev->dev)); |
85 | 87 | ||
86 | input_close_device(handle); | 88 | input_close_device(handle); |
87 | input_unregister_handle(handle); | 89 | input_unregister_handle(handle); |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 68f09a868434..c8471a2552e7 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -8,6 +8,8 @@ | |||
8 | * the Free Software Foundation. | 8 | * the Free Software Foundation. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
12 | |||
11 | #define EVDEV_MINOR_BASE 64 | 13 | #define EVDEV_MINOR_BASE 64 |
12 | #define EVDEV_MINORS 32 | 14 | #define EVDEV_MINORS 32 |
13 | #define EVDEV_MIN_BUFFER_SIZE 64U | 15 | #define EVDEV_MIN_BUFFER_SIZE 64U |
@@ -522,12 +524,11 @@ static int handle_eviocgbit(struct input_dev *dev, | |||
522 | if (type == EV_KEY && size == OLD_KEY_MAX) { | 524 | if (type == EV_KEY && size == OLD_KEY_MAX) { |
523 | len = OLD_KEY_MAX; | 525 | len = OLD_KEY_MAX; |
524 | if (printk_timed_ratelimit(&keymax_warn_time, 10 * 1000)) | 526 | if (printk_timed_ratelimit(&keymax_warn_time, 10 * 1000)) |
525 | printk(KERN_WARNING | 527 | pr_warning("(EVIOCGBIT): Suspicious buffer size %u, " |
526 | "evdev.c(EVIOCGBIT): Suspicious buffer size %u, " | 528 | "limiting output to %zu bytes. See " |
527 | "limiting output to %zu bytes. See " | 529 | "http://userweb.kernel.org/~dtor/eviocgbit-bug.html\n", |
528 | "http://userweb.kernel.org/~dtor/eviocgbit-bug.html\n", | 530 | OLD_KEY_MAX, |
529 | OLD_KEY_MAX, | 531 | BITS_TO_LONGS(OLD_KEY_MAX) * sizeof(long)); |
530 | BITS_TO_LONGS(OLD_KEY_MAX) * sizeof(long)); | ||
531 | } | 532 | } |
532 | 533 | ||
533 | return bits_to_user(bits, len, size, p, compat_mode); | 534 | return bits_to_user(bits, len, size, p, compat_mode); |
@@ -686,6 +687,10 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
686 | #define EVIOC_MASK_SIZE(nr) ((nr) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) | 687 | #define EVIOC_MASK_SIZE(nr) ((nr) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) |
687 | switch (EVIOC_MASK_SIZE(cmd)) { | 688 | switch (EVIOC_MASK_SIZE(cmd)) { |
688 | 689 | ||
690 | case EVIOCGPROP(0): | ||
691 | return bits_to_user(dev->propbit, INPUT_PROP_MAX, | ||
692 | size, p, compat_mode); | ||
693 | |||
689 | case EVIOCGKEY(0): | 694 | case EVIOCGKEY(0): |
690 | return bits_to_user(dev->key, KEY_MAX, size, p, compat_mode); | 695 | return bits_to_user(dev->key, KEY_MAX, size, p, compat_mode); |
691 | 696 | ||
@@ -897,7 +902,7 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev, | |||
897 | break; | 902 | break; |
898 | 903 | ||
899 | if (minor == EVDEV_MINORS) { | 904 | if (minor == EVDEV_MINORS) { |
900 | printk(KERN_ERR "evdev: no more free evdev devices\n"); | 905 | pr_err("no more free evdev devices\n"); |
901 | return -ENFILE; | 906 | return -ENFILE; |
902 | } | 907 | } |
903 | 908 | ||
diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c index 03078c08309a..3367f760d75a 100644 --- a/drivers/input/ff-core.c +++ b/drivers/input/ff-core.c | |||
@@ -23,7 +23,7 @@ | |||
23 | 23 | ||
24 | /* #define DEBUG */ | 24 | /* #define DEBUG */ |
25 | 25 | ||
26 | #define debug(format, arg...) pr_debug("ff-core: " format "\n", ## arg) | 26 | #define pr_fmt(fmt) KBUILD_BASENAME ": " fmt |
27 | 27 | ||
28 | #include <linux/input.h> | 28 | #include <linux/input.h> |
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
@@ -116,7 +116,7 @@ int input_ff_upload(struct input_dev *dev, struct ff_effect *effect, | |||
116 | 116 | ||
117 | if (effect->type < FF_EFFECT_MIN || effect->type > FF_EFFECT_MAX || | 117 | if (effect->type < FF_EFFECT_MIN || effect->type > FF_EFFECT_MAX || |
118 | !test_bit(effect->type, dev->ffbit)) { | 118 | !test_bit(effect->type, dev->ffbit)) { |
119 | debug("invalid or not supported effect type in upload"); | 119 | pr_debug("invalid or not supported effect type in upload\n"); |
120 | return -EINVAL; | 120 | return -EINVAL; |
121 | } | 121 | } |
122 | 122 | ||
@@ -124,7 +124,7 @@ int input_ff_upload(struct input_dev *dev, struct ff_effect *effect, | |||
124 | (effect->u.periodic.waveform < FF_WAVEFORM_MIN || | 124 | (effect->u.periodic.waveform < FF_WAVEFORM_MIN || |
125 | effect->u.periodic.waveform > FF_WAVEFORM_MAX || | 125 | effect->u.periodic.waveform > FF_WAVEFORM_MAX || |
126 | !test_bit(effect->u.periodic.waveform, dev->ffbit))) { | 126 | !test_bit(effect->u.periodic.waveform, dev->ffbit))) { |
127 | debug("invalid or not supported wave form in upload"); | 127 | pr_debug("invalid or not supported wave form in upload\n"); |
128 | return -EINVAL; | 128 | return -EINVAL; |
129 | } | 129 | } |
130 | 130 | ||
@@ -246,7 +246,7 @@ static int flush_effects(struct input_dev *dev, struct file *file) | |||
246 | struct ff_device *ff = dev->ff; | 246 | struct ff_device *ff = dev->ff; |
247 | int i; | 247 | int i; |
248 | 248 | ||
249 | debug("flushing now"); | 249 | pr_debug("flushing now\n"); |
250 | 250 | ||
251 | mutex_lock(&ff->mutex); | 251 | mutex_lock(&ff->mutex); |
252 | 252 | ||
@@ -315,8 +315,7 @@ int input_ff_create(struct input_dev *dev, int max_effects) | |||
315 | int i; | 315 | int i; |
316 | 316 | ||
317 | if (!max_effects) { | 317 | if (!max_effects) { |
318 | printk(KERN_ERR | 318 | pr_err("cannot allocate device without any effects\n"); |
319 | "ff-core: cannot allocate device without any effects\n"); | ||
320 | return -EINVAL; | 319 | return -EINVAL; |
321 | } | 320 | } |
322 | 321 | ||
diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c index 1d881c96ba8f..117a59aaa70e 100644 --- a/drivers/input/ff-memless.c +++ b/drivers/input/ff-memless.c | |||
@@ -23,7 +23,7 @@ | |||
23 | 23 | ||
24 | /* #define DEBUG */ | 24 | /* #define DEBUG */ |
25 | 25 | ||
26 | #define debug(format, arg...) pr_debug("ff-memless: " format "\n", ## arg) | 26 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
27 | 27 | ||
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/input.h> | 29 | #include <linux/input.h> |
@@ -129,7 +129,7 @@ static void ml_schedule_timer(struct ml_device *ml) | |||
129 | int events = 0; | 129 | int events = 0; |
130 | int i; | 130 | int i; |
131 | 131 | ||
132 | debug("calculating next timer"); | 132 | pr_debug("calculating next timer\n"); |
133 | 133 | ||
134 | for (i = 0; i < FF_MEMLESS_EFFECTS; i++) { | 134 | for (i = 0; i < FF_MEMLESS_EFFECTS; i++) { |
135 | 135 | ||
@@ -149,10 +149,10 @@ static void ml_schedule_timer(struct ml_device *ml) | |||
149 | } | 149 | } |
150 | 150 | ||
151 | if (!events) { | 151 | if (!events) { |
152 | debug("no actions"); | 152 | pr_debug("no actions\n"); |
153 | del_timer(&ml->timer); | 153 | del_timer(&ml->timer); |
154 | } else { | 154 | } else { |
155 | debug("timer set"); | 155 | pr_debug("timer set\n"); |
156 | mod_timer(&ml->timer, earliest); | 156 | mod_timer(&ml->timer, earliest); |
157 | } | 157 | } |
158 | } | 158 | } |
@@ -173,8 +173,8 @@ static int apply_envelope(struct ml_effect_state *state, int value, | |||
173 | if (envelope->attack_length && | 173 | if (envelope->attack_length && |
174 | time_before(now, | 174 | time_before(now, |
175 | state->play_at + msecs_to_jiffies(envelope->attack_length))) { | 175 | state->play_at + msecs_to_jiffies(envelope->attack_length))) { |
176 | debug("value = 0x%x, attack_level = 0x%x", value, | 176 | pr_debug("value = 0x%x, attack_level = 0x%x\n", |
177 | envelope->attack_level); | 177 | value, envelope->attack_level); |
178 | time_from_level = jiffies_to_msecs(now - state->play_at); | 178 | time_from_level = jiffies_to_msecs(now - state->play_at); |
179 | time_of_envelope = envelope->attack_length; | 179 | time_of_envelope = envelope->attack_length; |
180 | envelope_level = min_t(__s16, envelope->attack_level, 0x7fff); | 180 | envelope_level = min_t(__s16, envelope->attack_level, 0x7fff); |
@@ -191,13 +191,13 @@ static int apply_envelope(struct ml_effect_state *state, int value, | |||
191 | 191 | ||
192 | difference = abs(value) - envelope_level; | 192 | difference = abs(value) - envelope_level; |
193 | 193 | ||
194 | debug("difference = %d", difference); | 194 | pr_debug("difference = %d\n", difference); |
195 | debug("time_from_level = 0x%x", time_from_level); | 195 | pr_debug("time_from_level = 0x%x\n", time_from_level); |
196 | debug("time_of_envelope = 0x%x", time_of_envelope); | 196 | pr_debug("time_of_envelope = 0x%x\n", time_of_envelope); |
197 | 197 | ||
198 | difference = difference * time_from_level / time_of_envelope; | 198 | difference = difference * time_from_level / time_of_envelope; |
199 | 199 | ||
200 | debug("difference = %d", difference); | 200 | pr_debug("difference = %d\n", difference); |
201 | 201 | ||
202 | return value < 0 ? | 202 | return value < 0 ? |
203 | -(difference + envelope_level) : (difference + envelope_level); | 203 | -(difference + envelope_level) : (difference + envelope_level); |
@@ -215,8 +215,7 @@ static int get_compatible_type(struct ff_device *ff, int effect_type) | |||
215 | if (effect_type == FF_PERIODIC && test_bit(FF_RUMBLE, ff->ffbit)) | 215 | if (effect_type == FF_PERIODIC && test_bit(FF_RUMBLE, ff->ffbit)) |
216 | return FF_RUMBLE; | 216 | return FF_RUMBLE; |
217 | 217 | ||
218 | printk(KERN_ERR | 218 | pr_err("invalid type in get_compatible_type()\n"); |
219 | "ff-memless: invalid type in get_compatible_type()\n"); | ||
220 | 219 | ||
221 | return 0; | 220 | return 0; |
222 | } | 221 | } |
@@ -312,7 +311,7 @@ static void ml_combine_effects(struct ff_effect *effect, | |||
312 | break; | 311 | break; |
313 | 312 | ||
314 | default: | 313 | default: |
315 | printk(KERN_ERR "ff-memless: invalid type in ml_combine_effects()\n"); | 314 | pr_err("invalid type in ml_combine_effects()\n"); |
316 | break; | 315 | break; |
317 | } | 316 | } |
318 | 317 | ||
@@ -406,7 +405,7 @@ static void ml_effect_timer(unsigned long timer_data) | |||
406 | struct ml_device *ml = dev->ff->private; | 405 | struct ml_device *ml = dev->ff->private; |
407 | unsigned long flags; | 406 | unsigned long flags; |
408 | 407 | ||
409 | debug("timer: updating effects"); | 408 | pr_debug("timer: updating effects\n"); |
410 | 409 | ||
411 | spin_lock_irqsave(&dev->event_lock, flags); | 410 | spin_lock_irqsave(&dev->event_lock, flags); |
412 | ml_play_effects(ml); | 411 | ml_play_effects(ml); |
@@ -438,7 +437,7 @@ static int ml_ff_playback(struct input_dev *dev, int effect_id, int value) | |||
438 | struct ml_effect_state *state = &ml->states[effect_id]; | 437 | struct ml_effect_state *state = &ml->states[effect_id]; |
439 | 438 | ||
440 | if (value > 0) { | 439 | if (value > 0) { |
441 | debug("initiated play"); | 440 | pr_debug("initiated play\n"); |
442 | 441 | ||
443 | __set_bit(FF_EFFECT_STARTED, &state->flags); | 442 | __set_bit(FF_EFFECT_STARTED, &state->flags); |
444 | state->count = value; | 443 | state->count = value; |
@@ -449,7 +448,7 @@ static int ml_ff_playback(struct input_dev *dev, int effect_id, int value) | |||
449 | state->adj_at = state->play_at; | 448 | state->adj_at = state->play_at; |
450 | 449 | ||
451 | } else { | 450 | } else { |
452 | debug("initiated stop"); | 451 | pr_debug("initiated stop\n"); |
453 | 452 | ||
454 | if (test_bit(FF_EFFECT_PLAYING, &state->flags)) | 453 | if (test_bit(FF_EFFECT_PLAYING, &state->flags)) |
455 | __set_bit(FF_EFFECT_ABORTING, &state->flags); | 454 | __set_bit(FF_EFFECT_ABORTING, &state->flags); |
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index 46239e47a260..dbf741c95835 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c | |||
@@ -18,13 +18,11 @@ | |||
18 | #include <linux/ioport.h> | 18 | #include <linux/ioport.h> |
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/gameport.h> | 20 | #include <linux/gameport.h> |
21 | #include <linux/wait.h> | ||
22 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
23 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
24 | #include <linux/kthread.h> | 23 | #include <linux/workqueue.h> |
25 | #include <linux/sched.h> /* HZ */ | 24 | #include <linux/sched.h> /* HZ */ |
26 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
27 | #include <linux/freezer.h> | ||
28 | 26 | ||
29 | /*#include <asm/io.h>*/ | 27 | /*#include <asm/io.h>*/ |
30 | 28 | ||
@@ -234,58 +232,22 @@ struct gameport_event { | |||
234 | 232 | ||
235 | static DEFINE_SPINLOCK(gameport_event_lock); /* protects gameport_event_list */ | 233 | static DEFINE_SPINLOCK(gameport_event_lock); /* protects gameport_event_list */ |
236 | static LIST_HEAD(gameport_event_list); | 234 | static LIST_HEAD(gameport_event_list); |
237 | static DECLARE_WAIT_QUEUE_HEAD(gameport_wait); | ||
238 | static struct task_struct *gameport_task; | ||
239 | 235 | ||
240 | static int gameport_queue_event(void *object, struct module *owner, | 236 | static struct gameport_event *gameport_get_event(void) |
241 | enum gameport_event_type event_type) | ||
242 | { | 237 | { |
238 | struct gameport_event *event = NULL; | ||
243 | unsigned long flags; | 239 | unsigned long flags; |
244 | struct gameport_event *event; | ||
245 | int retval = 0; | ||
246 | 240 | ||
247 | spin_lock_irqsave(&gameport_event_lock, flags); | 241 | spin_lock_irqsave(&gameport_event_lock, flags); |
248 | 242 | ||
249 | /* | 243 | if (!list_empty(&gameport_event_list)) { |
250 | * Scan event list for the other events for the same gameport port, | 244 | event = list_first_entry(&gameport_event_list, |
251 | * starting with the most recent one. If event is the same we | 245 | struct gameport_event, node); |
252 | * do not need add new one. If event is of different type we | 246 | list_del_init(&event->node); |
253 | * need to add this event and should not look further because | ||
254 | * we need to preseve sequence of distinct events. | ||
255 | */ | ||
256 | list_for_each_entry_reverse(event, &gameport_event_list, node) { | ||
257 | if (event->object == object) { | ||
258 | if (event->type == event_type) | ||
259 | goto out; | ||
260 | break; | ||
261 | } | ||
262 | } | ||
263 | |||
264 | event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC); | ||
265 | if (!event) { | ||
266 | pr_err("Not enough memory to queue event %d\n", event_type); | ||
267 | retval = -ENOMEM; | ||
268 | goto out; | ||
269 | } | ||
270 | |||
271 | if (!try_module_get(owner)) { | ||
272 | pr_warning("Can't get module reference, dropping event %d\n", | ||
273 | event_type); | ||
274 | kfree(event); | ||
275 | retval = -EINVAL; | ||
276 | goto out; | ||
277 | } | 247 | } |
278 | 248 | ||
279 | event->type = event_type; | ||
280 | event->object = object; | ||
281 | event->owner = owner; | ||
282 | |||
283 | list_add_tail(&event->node, &gameport_event_list); | ||
284 | wake_up(&gameport_wait); | ||
285 | |||
286 | out: | ||
287 | spin_unlock_irqrestore(&gameport_event_lock, flags); | 249 | spin_unlock_irqrestore(&gameport_event_lock, flags); |
288 | return retval; | 250 | return event; |
289 | } | 251 | } |
290 | 252 | ||
291 | static void gameport_free_event(struct gameport_event *event) | 253 | static void gameport_free_event(struct gameport_event *event) |
@@ -319,24 +281,8 @@ static void gameport_remove_duplicate_events(struct gameport_event *event) | |||
319 | spin_unlock_irqrestore(&gameport_event_lock, flags); | 281 | spin_unlock_irqrestore(&gameport_event_lock, flags); |
320 | } | 282 | } |
321 | 283 | ||
322 | static struct gameport_event *gameport_get_event(void) | ||
323 | { | ||
324 | struct gameport_event *event = NULL; | ||
325 | unsigned long flags; | ||
326 | |||
327 | spin_lock_irqsave(&gameport_event_lock, flags); | ||
328 | |||
329 | if (!list_empty(&gameport_event_list)) { | ||
330 | event = list_first_entry(&gameport_event_list, | ||
331 | struct gameport_event, node); | ||
332 | list_del_init(&event->node); | ||
333 | } | ||
334 | |||
335 | spin_unlock_irqrestore(&gameport_event_lock, flags); | ||
336 | return event; | ||
337 | } | ||
338 | 284 | ||
339 | static void gameport_handle_event(void) | 285 | static void gameport_handle_events(struct work_struct *work) |
340 | { | 286 | { |
341 | struct gameport_event *event; | 287 | struct gameport_event *event; |
342 | 288 | ||
@@ -368,6 +314,59 @@ static void gameport_handle_event(void) | |||
368 | mutex_unlock(&gameport_mutex); | 314 | mutex_unlock(&gameport_mutex); |
369 | } | 315 | } |
370 | 316 | ||
317 | static DECLARE_WORK(gameport_event_work, gameport_handle_events); | ||
318 | |||
319 | static int gameport_queue_event(void *object, struct module *owner, | ||
320 | enum gameport_event_type event_type) | ||
321 | { | ||
322 | unsigned long flags; | ||
323 | struct gameport_event *event; | ||
324 | int retval = 0; | ||
325 | |||
326 | spin_lock_irqsave(&gameport_event_lock, flags); | ||
327 | |||
328 | /* | ||
329 | * Scan event list for the other events for the same gameport port, | ||
330 | * starting with the most recent one. If event is the same we | ||
331 | * do not need add new one. If event is of different type we | ||
332 | * need to add this event and should not look further because | ||
333 | * we need to preserve sequence of distinct events. | ||
334 | */ | ||
335 | list_for_each_entry_reverse(event, &gameport_event_list, node) { | ||
336 | if (event->object == object) { | ||
337 | if (event->type == event_type) | ||
338 | goto out; | ||
339 | break; | ||
340 | } | ||
341 | } | ||
342 | |||
343 | event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC); | ||
344 | if (!event) { | ||
345 | pr_err("Not enough memory to queue event %d\n", event_type); | ||
346 | retval = -ENOMEM; | ||
347 | goto out; | ||
348 | } | ||
349 | |||
350 | if (!try_module_get(owner)) { | ||
351 | pr_warning("Can't get module reference, dropping event %d\n", | ||
352 | event_type); | ||
353 | kfree(event); | ||
354 | retval = -EINVAL; | ||
355 | goto out; | ||
356 | } | ||
357 | |||
358 | event->type = event_type; | ||
359 | event->object = object; | ||
360 | event->owner = owner; | ||
361 | |||
362 | list_add_tail(&event->node, &gameport_event_list); | ||
363 | schedule_work(&gameport_event_work); | ||
364 | |||
365 | out: | ||
366 | spin_unlock_irqrestore(&gameport_event_lock, flags); | ||
367 | return retval; | ||
368 | } | ||
369 | |||
371 | /* | 370 | /* |
372 | * Remove all events that have been submitted for a given object, | 371 | * Remove all events that have been submitted for a given object, |
373 | * be it a gameport port or a driver. | 372 | * be it a gameport port or a driver. |
@@ -419,19 +418,6 @@ static struct gameport *gameport_get_pending_child(struct gameport *parent) | |||
419 | return child; | 418 | return child; |
420 | } | 419 | } |
421 | 420 | ||
422 | static int gameport_thread(void *nothing) | ||
423 | { | ||
424 | set_freezable(); | ||
425 | do { | ||
426 | gameport_handle_event(); | ||
427 | wait_event_freezable(gameport_wait, | ||
428 | kthread_should_stop() || !list_empty(&gameport_event_list)); | ||
429 | } while (!kthread_should_stop()); | ||
430 | |||
431 | return 0; | ||
432 | } | ||
433 | |||
434 | |||
435 | /* | 421 | /* |
436 | * Gameport port operations | 422 | * Gameport port operations |
437 | */ | 423 | */ |
@@ -814,13 +800,6 @@ static int __init gameport_init(void) | |||
814 | return error; | 800 | return error; |
815 | } | 801 | } |
816 | 802 | ||
817 | gameport_task = kthread_run(gameport_thread, NULL, "kgameportd"); | ||
818 | if (IS_ERR(gameport_task)) { | ||
819 | bus_unregister(&gameport_bus); | ||
820 | error = PTR_ERR(gameport_task); | ||
821 | pr_err("Failed to start kgameportd, error: %d\n", error); | ||
822 | return error; | ||
823 | } | ||
824 | 803 | ||
825 | return 0; | 804 | return 0; |
826 | } | 805 | } |
@@ -828,7 +807,12 @@ static int __init gameport_init(void) | |||
828 | static void __exit gameport_exit(void) | 807 | static void __exit gameport_exit(void) |
829 | { | 808 | { |
830 | bus_unregister(&gameport_bus); | 809 | bus_unregister(&gameport_bus); |
831 | kthread_stop(gameport_task); | 810 | |
811 | /* | ||
812 | * There should not be any outstanding events but work may | ||
813 | * still be scheduled so simply cancel it. | ||
814 | */ | ||
815 | cancel_work_sync(&gameport_event_work); | ||
832 | } | 816 | } |
833 | 817 | ||
834 | subsys_initcall(gameport_init); | 818 | subsys_initcall(gameport_init); |
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c new file mode 100644 index 000000000000..c48c81f0308d --- /dev/null +++ b/drivers/input/input-mt.c | |||
@@ -0,0 +1,170 @@ | |||
1 | /* | ||
2 | * Input Multitouch Library | ||
3 | * | ||
4 | * Copyright (c) 2008-2010 Henrik Rydberg | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License version 2 as published by | ||
8 | * the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/input/mt.h> | ||
12 | #include <linux/slab.h> | ||
13 | |||
14 | #define TRKID_SGN ((TRKID_MAX + 1) >> 1) | ||
15 | |||
16 | /** | ||
17 | * input_mt_init_slots() - initialize MT input slots | ||
18 | * @dev: input device supporting MT events and finger tracking | ||
19 | * @num_slots: number of slots used by the device | ||
20 | * | ||
21 | * This function allocates all necessary memory for MT slot handling | ||
22 | * in the input device, prepares the ABS_MT_SLOT and | ||
23 | * ABS_MT_TRACKING_ID events for use and sets up appropriate buffers. | ||
24 | * May be called repeatedly. Returns -EINVAL if attempting to | ||
25 | * reinitialize with a different number of slots. | ||
26 | */ | ||
27 | int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots) | ||
28 | { | ||
29 | int i; | ||
30 | |||
31 | if (!num_slots) | ||
32 | return 0; | ||
33 | if (dev->mt) | ||
34 | return dev->mtsize != num_slots ? -EINVAL : 0; | ||
35 | |||
36 | dev->mt = kcalloc(num_slots, sizeof(struct input_mt_slot), GFP_KERNEL); | ||
37 | if (!dev->mt) | ||
38 | return -ENOMEM; | ||
39 | |||
40 | dev->mtsize = num_slots; | ||
41 | input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0); | ||
42 | input_set_abs_params(dev, ABS_MT_TRACKING_ID, 0, TRKID_MAX, 0, 0); | ||
43 | input_set_events_per_packet(dev, 6 * num_slots); | ||
44 | |||
45 | /* Mark slots as 'unused' */ | ||
46 | for (i = 0; i < num_slots; i++) | ||
47 | input_mt_set_value(&dev->mt[i], ABS_MT_TRACKING_ID, -1); | ||
48 | |||
49 | return 0; | ||
50 | } | ||
51 | EXPORT_SYMBOL(input_mt_init_slots); | ||
52 | |||
53 | /** | ||
54 | * input_mt_destroy_slots() - frees the MT slots of the input device | ||
55 | * @dev: input device with allocated MT slots | ||
56 | * | ||
57 | * This function is only needed in error path as the input core will | ||
58 | * automatically free the MT slots when the device is destroyed. | ||
59 | */ | ||
60 | void input_mt_destroy_slots(struct input_dev *dev) | ||
61 | { | ||
62 | kfree(dev->mt); | ||
63 | dev->mt = NULL; | ||
64 | dev->mtsize = 0; | ||
65 | dev->slot = 0; | ||
66 | dev->trkid = 0; | ||
67 | } | ||
68 | EXPORT_SYMBOL(input_mt_destroy_slots); | ||
69 | |||
70 | /** | ||
71 | * input_mt_report_slot_state() - report contact state | ||
72 | * @dev: input device with allocated MT slots | ||
73 | * @tool_type: the tool type to use in this slot | ||
74 | * @active: true if contact is active, false otherwise | ||
75 | * | ||
76 | * Reports a contact via ABS_MT_TRACKING_ID, and optionally | ||
77 | * ABS_MT_TOOL_TYPE. If active is true and the slot is currently | ||
78 | * inactive, or if the tool type is changed, a new tracking id is | ||
79 | * assigned to the slot. The tool type is only reported if the | ||
80 | * corresponding absbit field is set. | ||
81 | */ | ||
82 | void input_mt_report_slot_state(struct input_dev *dev, | ||
83 | unsigned int tool_type, bool active) | ||
84 | { | ||
85 | struct input_mt_slot *mt; | ||
86 | int id; | ||
87 | |||
88 | if (!dev->mt || !active) { | ||
89 | input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1); | ||
90 | return; | ||
91 | } | ||
92 | |||
93 | mt = &dev->mt[dev->slot]; | ||
94 | id = input_mt_get_value(mt, ABS_MT_TRACKING_ID); | ||
95 | if (id < 0 || input_mt_get_value(mt, ABS_MT_TOOL_TYPE) != tool_type) | ||
96 | id = input_mt_new_trkid(dev); | ||
97 | |||
98 | input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, id); | ||
99 | input_event(dev, EV_ABS, ABS_MT_TOOL_TYPE, tool_type); | ||
100 | } | ||
101 | EXPORT_SYMBOL(input_mt_report_slot_state); | ||
102 | |||
103 | /** | ||
104 | * input_mt_report_finger_count() - report contact count | ||
105 | * @dev: input device with allocated MT slots | ||
106 | * @count: the number of contacts | ||
107 | * | ||
108 | * Reports the contact count via BTN_TOOL_FINGER, BTN_TOOL_DOUBLETAP, | ||
109 | * BTN_TOOL_TRIPLETAP and BTN_TOOL_QUADTAP. | ||
110 | * | ||
111 | * The input core ensures only the KEY events already setup for | ||
112 | * this device will produce output. | ||
113 | */ | ||
114 | void input_mt_report_finger_count(struct input_dev *dev, int count) | ||
115 | { | ||
116 | input_event(dev, EV_KEY, BTN_TOOL_FINGER, count == 1); | ||
117 | input_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, count == 2); | ||
118 | input_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, count == 3); | ||
119 | input_event(dev, EV_KEY, BTN_TOOL_QUADTAP, count == 4); | ||
120 | } | ||
121 | EXPORT_SYMBOL(input_mt_report_finger_count); | ||
122 | |||
123 | /** | ||
124 | * input_mt_report_pointer_emulation() - common pointer emulation | ||
125 | * @dev: input device with allocated MT slots | ||
126 | * @use_count: report number of active contacts as finger count | ||
127 | * | ||
128 | * Performs legacy pointer emulation via BTN_TOUCH, ABS_X, ABS_Y and | ||
129 | * ABS_PRESSURE. Touchpad finger count is emulated if use_count is true. | ||
130 | * | ||
131 | * The input core ensures only the KEY and ABS axes already setup for | ||
132 | * this device will produce output. | ||
133 | */ | ||
134 | void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count) | ||
135 | { | ||
136 | struct input_mt_slot *oldest = 0; | ||
137 | int oldid = dev->trkid; | ||
138 | int count = 0; | ||
139 | int i; | ||
140 | |||
141 | for (i = 0; i < dev->mtsize; ++i) { | ||
142 | struct input_mt_slot *ps = &dev->mt[i]; | ||
143 | int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID); | ||
144 | |||
145 | if (id < 0) | ||
146 | continue; | ||
147 | if ((id - oldid) & TRKID_SGN) { | ||
148 | oldest = ps; | ||
149 | oldid = id; | ||
150 | } | ||
151 | count++; | ||
152 | } | ||
153 | |||
154 | input_event(dev, EV_KEY, BTN_TOUCH, count > 0); | ||
155 | if (use_count) | ||
156 | input_mt_report_finger_count(dev, count); | ||
157 | |||
158 | if (oldest) { | ||
159 | int x = input_mt_get_value(oldest, ABS_MT_POSITION_X); | ||
160 | int y = input_mt_get_value(oldest, ABS_MT_POSITION_Y); | ||
161 | int p = input_mt_get_value(oldest, ABS_MT_PRESSURE); | ||
162 | |||
163 | input_event(dev, EV_ABS, ABS_X, x); | ||
164 | input_event(dev, EV_ABS, ABS_Y, y); | ||
165 | input_event(dev, EV_ABS, ABS_PRESSURE, p); | ||
166 | } else { | ||
167 | input_event(dev, EV_ABS, ABS_PRESSURE, 0); | ||
168 | } | ||
169 | } | ||
170 | EXPORT_SYMBOL(input_mt_report_pointer_emulation); | ||
diff --git a/drivers/input/input-polldev.c b/drivers/input/input-polldev.c index 10c9b0a845f0..0559e309bac9 100644 --- a/drivers/input/input-polldev.c +++ b/drivers/input/input-polldev.c | |||
@@ -8,6 +8,8 @@ | |||
8 | * the Free Software Foundation. | 8 | * the Free Software Foundation. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
12 | |||
11 | #include <linux/jiffies.h> | 13 | #include <linux/jiffies.h> |
12 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
13 | #include <linux/mutex.h> | 15 | #include <linux/mutex.h> |
@@ -33,8 +35,7 @@ static int input_polldev_start_workqueue(void) | |||
33 | if (!polldev_users) { | 35 | if (!polldev_users) { |
34 | polldev_wq = create_singlethread_workqueue("ipolldevd"); | 36 | polldev_wq = create_singlethread_workqueue("ipolldevd"); |
35 | if (!polldev_wq) { | 37 | if (!polldev_wq) { |
36 | printk(KERN_ERR "input-polldev: failed to create " | 38 | pr_err("failed to create ipolldevd workqueue\n"); |
37 | "ipolldevd workqueue\n"); | ||
38 | retval = -ENOMEM; | 39 | retval = -ENOMEM; |
39 | goto out; | 40 | goto out; |
40 | } | 41 | } |
diff --git a/drivers/input/input.c b/drivers/input/input.c index db409d6bd5d2..7985114beac7 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -10,9 +10,11 @@ | |||
10 | * the Free Software Foundation. | 10 | * the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #define pr_fmt(fmt) KBUILD_BASENAME ": " fmt | ||
14 | |||
13 | #include <linux/init.h> | 15 | #include <linux/init.h> |
14 | #include <linux/types.h> | 16 | #include <linux/types.h> |
15 | #include <linux/input.h> | 17 | #include <linux/input/mt.h> |
16 | #include <linux/module.h> | 18 | #include <linux/module.h> |
17 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
18 | #include <linux/random.h> | 20 | #include <linux/random.h> |
@@ -958,10 +960,8 @@ static int input_attach_handler(struct input_dev *dev, struct input_handler *han | |||
958 | 960 | ||
959 | error = handler->connect(handler, dev, id); | 961 | error = handler->connect(handler, dev, id); |
960 | if (error && error != -ENODEV) | 962 | if (error && error != -ENODEV) |
961 | printk(KERN_ERR | 963 | pr_err("failed to attach handler %s to device %s, error: %d\n", |
962 | "input: failed to attach handler %s to device %s, " | 964 | handler->name, kobject_name(&dev->dev.kobj), error); |
963 | "error: %d\n", | ||
964 | handler->name, kobject_name(&dev->dev.kobj), error); | ||
965 | 965 | ||
966 | return error; | 966 | return error; |
967 | } | 967 | } |
@@ -1109,6 +1109,8 @@ static int input_devices_seq_show(struct seq_file *seq, void *v) | |||
1109 | seq_printf(seq, "%s ", handle->name); | 1109 | seq_printf(seq, "%s ", handle->name); |
1110 | seq_putc(seq, '\n'); | 1110 | seq_putc(seq, '\n'); |
1111 | 1111 | ||
1112 | input_seq_print_bitmap(seq, "PROP", dev->propbit, INPUT_PROP_MAX); | ||
1113 | |||
1112 | input_seq_print_bitmap(seq, "EV", dev->evbit, EV_MAX); | 1114 | input_seq_print_bitmap(seq, "EV", dev->evbit, EV_MAX); |
1113 | if (test_bit(EV_KEY, dev->evbit)) | 1115 | if (test_bit(EV_KEY, dev->evbit)) |
1114 | input_seq_print_bitmap(seq, "KEY", dev->keybit, KEY_MAX); | 1116 | input_seq_print_bitmap(seq, "KEY", dev->keybit, KEY_MAX); |
@@ -1332,11 +1334,26 @@ static ssize_t input_dev_show_modalias(struct device *dev, | |||
1332 | } | 1334 | } |
1333 | static DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL); | 1335 | static DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL); |
1334 | 1336 | ||
1337 | static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap, | ||
1338 | int max, int add_cr); | ||
1339 | |||
1340 | static ssize_t input_dev_show_properties(struct device *dev, | ||
1341 | struct device_attribute *attr, | ||
1342 | char *buf) | ||
1343 | { | ||
1344 | struct input_dev *input_dev = to_input_dev(dev); | ||
1345 | int len = input_print_bitmap(buf, PAGE_SIZE, input_dev->propbit, | ||
1346 | INPUT_PROP_MAX, true); | ||
1347 | return min_t(int, len, PAGE_SIZE); | ||
1348 | } | ||
1349 | static DEVICE_ATTR(properties, S_IRUGO, input_dev_show_properties, NULL); | ||
1350 | |||
1335 | static struct attribute *input_dev_attrs[] = { | 1351 | static struct attribute *input_dev_attrs[] = { |
1336 | &dev_attr_name.attr, | 1352 | &dev_attr_name.attr, |
1337 | &dev_attr_phys.attr, | 1353 | &dev_attr_phys.attr, |
1338 | &dev_attr_uniq.attr, | 1354 | &dev_attr_uniq.attr, |
1339 | &dev_attr_modalias.attr, | 1355 | &dev_attr_modalias.attr, |
1356 | &dev_attr_properties.attr, | ||
1340 | NULL | 1357 | NULL |
1341 | }; | 1358 | }; |
1342 | 1359 | ||
@@ -1470,7 +1487,7 @@ static int input_add_uevent_bm_var(struct kobj_uevent_env *env, | |||
1470 | { | 1487 | { |
1471 | int len; | 1488 | int len; |
1472 | 1489 | ||
1473 | if (add_uevent_var(env, "%s=", name)) | 1490 | if (add_uevent_var(env, "%s", name)) |
1474 | return -ENOMEM; | 1491 | return -ENOMEM; |
1475 | 1492 | ||
1476 | len = input_print_bitmap(&env->buf[env->buflen - 1], | 1493 | len = input_print_bitmap(&env->buf[env->buflen - 1], |
@@ -1536,6 +1553,8 @@ static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env) | |||
1536 | if (dev->uniq) | 1553 | if (dev->uniq) |
1537 | INPUT_ADD_HOTPLUG_VAR("UNIQ=\"%s\"", dev->uniq); | 1554 | INPUT_ADD_HOTPLUG_VAR("UNIQ=\"%s\"", dev->uniq); |
1538 | 1555 | ||
1556 | INPUT_ADD_HOTPLUG_BM_VAR("PROP=", dev->propbit, INPUT_PROP_MAX); | ||
1557 | |||
1539 | INPUT_ADD_HOTPLUG_BM_VAR("EV=", dev->evbit, EV_MAX); | 1558 | INPUT_ADD_HOTPLUG_BM_VAR("EV=", dev->evbit, EV_MAX); |
1540 | if (test_bit(EV_KEY, dev->evbit)) | 1559 | if (test_bit(EV_KEY, dev->evbit)) |
1541 | INPUT_ADD_HOTPLUG_BM_VAR("KEY=", dev->keybit, KEY_MAX); | 1560 | INPUT_ADD_HOTPLUG_BM_VAR("KEY=", dev->keybit, KEY_MAX); |
@@ -1725,52 +1744,6 @@ void input_free_device(struct input_dev *dev) | |||
1725 | EXPORT_SYMBOL(input_free_device); | 1744 | EXPORT_SYMBOL(input_free_device); |
1726 | 1745 | ||
1727 | /** | 1746 | /** |
1728 | * input_mt_create_slots() - create MT input slots | ||
1729 | * @dev: input device supporting MT events and finger tracking | ||
1730 | * @num_slots: number of slots used by the device | ||
1731 | * | ||
1732 | * This function allocates all necessary memory for MT slot handling in the | ||
1733 | * input device, and adds ABS_MT_SLOT to the device capabilities. All slots | ||
1734 | * are initially marked as unused by setting ABS_MT_TRACKING_ID to -1. | ||
1735 | */ | ||
1736 | int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots) | ||
1737 | { | ||
1738 | int i; | ||
1739 | |||
1740 | if (!num_slots) | ||
1741 | return 0; | ||
1742 | |||
1743 | dev->mt = kcalloc(num_slots, sizeof(struct input_mt_slot), GFP_KERNEL); | ||
1744 | if (!dev->mt) | ||
1745 | return -ENOMEM; | ||
1746 | |||
1747 | dev->mtsize = num_slots; | ||
1748 | input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0); | ||
1749 | |||
1750 | /* Mark slots as 'unused' */ | ||
1751 | for (i = 0; i < num_slots; i++) | ||
1752 | dev->mt[i].abs[ABS_MT_TRACKING_ID - ABS_MT_FIRST] = -1; | ||
1753 | |||
1754 | return 0; | ||
1755 | } | ||
1756 | EXPORT_SYMBOL(input_mt_create_slots); | ||
1757 | |||
1758 | /** | ||
1759 | * input_mt_destroy_slots() - frees the MT slots of the input device | ||
1760 | * @dev: input device with allocated MT slots | ||
1761 | * | ||
1762 | * This function is only needed in error path as the input core will | ||
1763 | * automatically free the MT slots when the device is destroyed. | ||
1764 | */ | ||
1765 | void input_mt_destroy_slots(struct input_dev *dev) | ||
1766 | { | ||
1767 | kfree(dev->mt); | ||
1768 | dev->mt = NULL; | ||
1769 | dev->mtsize = 0; | ||
1770 | } | ||
1771 | EXPORT_SYMBOL(input_mt_destroy_slots); | ||
1772 | |||
1773 | /** | ||
1774 | * input_set_capability - mark device as capable of a certain event | 1747 | * input_set_capability - mark device as capable of a certain event |
1775 | * @dev: device that is capable of emitting or accepting event | 1748 | * @dev: device that is capable of emitting or accepting event |
1776 | * @type: type of the event (EV_KEY, EV_REL, etc...) | 1749 | * @type: type of the event (EV_KEY, EV_REL, etc...) |
@@ -1819,9 +1792,8 @@ void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int | |||
1819 | break; | 1792 | break; |
1820 | 1793 | ||
1821 | default: | 1794 | default: |
1822 | printk(KERN_ERR | 1795 | pr_err("input_set_capability: unknown type %u (code %u)\n", |
1823 | "input_set_capability: unknown type %u (code %u)\n", | 1796 | type, code); |
1824 | type, code); | ||
1825 | dump_stack(); | 1797 | dump_stack(); |
1826 | return; | 1798 | return; |
1827 | } | 1799 | } |
@@ -1903,8 +1875,9 @@ int input_register_device(struct input_dev *dev) | |||
1903 | return error; | 1875 | return error; |
1904 | 1876 | ||
1905 | path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL); | 1877 | path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL); |
1906 | printk(KERN_INFO "input: %s as %s\n", | 1878 | pr_info("%s as %s\n", |
1907 | dev->name ? dev->name : "Unspecified device", path ? path : "N/A"); | 1879 | dev->name ? dev->name : "Unspecified device", |
1880 | path ? path : "N/A"); | ||
1908 | kfree(path); | 1881 | kfree(path); |
1909 | 1882 | ||
1910 | error = mutex_lock_interruptible(&input_mutex); | 1883 | error = mutex_lock_interruptible(&input_mutex); |
@@ -2186,7 +2159,7 @@ static int __init input_init(void) | |||
2186 | 2159 | ||
2187 | err = class_register(&input_class); | 2160 | err = class_register(&input_class); |
2188 | if (err) { | 2161 | if (err) { |
2189 | printk(KERN_ERR "input: unable to register input_dev class\n"); | 2162 | pr_err("unable to register input_dev class\n"); |
2190 | return err; | 2163 | return err; |
2191 | } | 2164 | } |
2192 | 2165 | ||
@@ -2196,7 +2169,7 @@ static int __init input_init(void) | |||
2196 | 2169 | ||
2197 | err = register_chrdev(INPUT_MAJOR, "input", &input_fops); | 2170 | err = register_chrdev(INPUT_MAJOR, "input", &input_fops); |
2198 | if (err) { | 2171 | if (err) { |
2199 | printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR); | 2172 | pr_err("unable to register char major %d", INPUT_MAJOR); |
2200 | goto fail2; | 2173 | goto fail2; |
2201 | } | 2174 | } |
2202 | 2175 | ||
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 9d424cebfd2c..3182c9cd1b0e 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c | |||
@@ -10,6 +10,8 @@ | |||
10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
14 | |||
13 | #include <asm/io.h> | 15 | #include <asm/io.h> |
14 | #include <asm/system.h> | 16 | #include <asm/system.h> |
15 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
@@ -806,7 +808,7 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev, | |||
806 | break; | 808 | break; |
807 | 809 | ||
808 | if (minor == JOYDEV_MINORS) { | 810 | if (minor == JOYDEV_MINORS) { |
809 | printk(KERN_ERR "joydev: no more free joydev devices\n"); | 811 | pr_err("no more free joydev devices\n"); |
810 | return -ENFILE; | 812 | return -ENFILE; |
811 | } | 813 | } |
812 | 814 | ||
diff --git a/drivers/input/joystick/iforce/Makefile b/drivers/input/joystick/iforce/Makefile index 74daff49ab6e..bc5bda22f15e 100644 --- a/drivers/input/joystick/iforce/Makefile +++ b/drivers/input/joystick/iforce/Makefile | |||
@@ -4,17 +4,8 @@ | |||
4 | # By Johann Deneux <johann.deneux@gmail.com> | 4 | # By Johann Deneux <johann.deneux@gmail.com> |
5 | # | 5 | # |
6 | 6 | ||
7 | # Goal definition | ||
8 | iforce-objs := iforce-ff.o iforce-main.o iforce-packets.o | ||
9 | |||
10 | obj-$(CONFIG_JOYSTICK_IFORCE) += iforce.o | 7 | obj-$(CONFIG_JOYSTICK_IFORCE) += iforce.o |
11 | 8 | ||
12 | ifeq ($(CONFIG_JOYSTICK_IFORCE_232),y) | 9 | iforce-y := iforce-ff.o iforce-main.o iforce-packets.o |
13 | iforce-objs += iforce-serio.o | 10 | iforce-$(CONFIG_JOYSTICK_IFORCE_232) += iforce-serio.o |
14 | endif | 11 | iforce-$(CONFIG_JOYSTICK_IFORCE_USB) += iforce-usb.o |
15 | |||
16 | ifeq ($(CONFIG_JOYSTICK_IFORCE_USB),y) | ||
17 | iforce-objs += iforce-usb.o | ||
18 | endif | ||
19 | |||
20 | EXTRA_CFLAGS = -Werror-implicit-function-declaration | ||
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index f9fb7fa10af3..56abf3d0e911 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
@@ -543,21 +543,25 @@ exit: | |||
543 | static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) | 543 | static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) |
544 | { | 544 | { |
545 | struct usb_endpoint_descriptor *ep_irq_out; | 545 | struct usb_endpoint_descriptor *ep_irq_out; |
546 | int error = -ENOMEM; | 546 | int error; |
547 | 547 | ||
548 | if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX) | 548 | if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX) |
549 | return 0; | 549 | return 0; |
550 | 550 | ||
551 | xpad->odata = usb_alloc_coherent(xpad->udev, XPAD_PKT_LEN, | 551 | xpad->odata = usb_alloc_coherent(xpad->udev, XPAD_PKT_LEN, |
552 | GFP_KERNEL, &xpad->odata_dma); | 552 | GFP_KERNEL, &xpad->odata_dma); |
553 | if (!xpad->odata) | 553 | if (!xpad->odata) { |
554 | error = -ENOMEM; | ||
554 | goto fail1; | 555 | goto fail1; |
556 | } | ||
555 | 557 | ||
556 | mutex_init(&xpad->odata_mutex); | 558 | mutex_init(&xpad->odata_mutex); |
557 | 559 | ||
558 | xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL); | 560 | xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL); |
559 | if (!xpad->irq_out) | 561 | if (!xpad->irq_out) { |
562 | error = -ENOMEM; | ||
560 | goto fail2; | 563 | goto fail2; |
564 | } | ||
561 | 565 | ||
562 | ep_irq_out = &intf->cur_altsetting->endpoint[1].desc; | 566 | ep_irq_out = &intf->cur_altsetting->endpoint[1].desc; |
563 | usb_fill_int_urb(xpad->irq_out, xpad->udev, | 567 | usb_fill_int_urb(xpad->irq_out, xpad->udev, |
@@ -728,7 +732,7 @@ static void xpad_led_disconnect(struct usb_xpad *xpad) | |||
728 | 732 | ||
729 | if (xpad_led) { | 733 | if (xpad_led) { |
730 | led_classdev_unregister(&xpad_led->led_cdev); | 734 | led_classdev_unregister(&xpad_led->led_cdev); |
731 | kfree(xpad_led->name); | 735 | kfree(xpad_led); |
732 | } | 736 | } |
733 | } | 737 | } |
734 | #else | 738 | #else |
@@ -756,8 +760,9 @@ static void xpad_close(struct input_dev *dev) | |||
756 | { | 760 | { |
757 | struct usb_xpad *xpad = input_get_drvdata(dev); | 761 | struct usb_xpad *xpad = input_get_drvdata(dev); |
758 | 762 | ||
759 | if(xpad->xtype != XTYPE_XBOX360W) | 763 | if (xpad->xtype != XTYPE_XBOX360W) |
760 | usb_kill_urb(xpad->irq_in); | 764 | usb_kill_urb(xpad->irq_in); |
765 | |||
761 | xpad_stop_output(xpad); | 766 | xpad_stop_output(xpad); |
762 | } | 767 | } |
763 | 768 | ||
@@ -789,8 +794,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
789 | struct usb_xpad *xpad; | 794 | struct usb_xpad *xpad; |
790 | struct input_dev *input_dev; | 795 | struct input_dev *input_dev; |
791 | struct usb_endpoint_descriptor *ep_irq_in; | 796 | struct usb_endpoint_descriptor *ep_irq_in; |
792 | int i; | 797 | int i, error; |
793 | int error = -ENOMEM; | ||
794 | 798 | ||
795 | for (i = 0; xpad_device[i].idVendor; i++) { | 799 | for (i = 0; xpad_device[i].idVendor; i++) { |
796 | if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) && | 800 | if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) && |
@@ -800,17 +804,23 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
800 | 804 | ||
801 | xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL); | 805 | xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL); |
802 | input_dev = input_allocate_device(); | 806 | input_dev = input_allocate_device(); |
803 | if (!xpad || !input_dev) | 807 | if (!xpad || !input_dev) { |
808 | error = -ENOMEM; | ||
804 | goto fail1; | 809 | goto fail1; |
810 | } | ||
805 | 811 | ||
806 | xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN, | 812 | xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN, |
807 | GFP_KERNEL, &xpad->idata_dma); | 813 | GFP_KERNEL, &xpad->idata_dma); |
808 | if (!xpad->idata) | 814 | if (!xpad->idata) { |
815 | error = -ENOMEM; | ||
809 | goto fail1; | 816 | goto fail1; |
817 | } | ||
810 | 818 | ||
811 | xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL); | 819 | xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL); |
812 | if (!xpad->irq_in) | 820 | if (!xpad->irq_in) { |
821 | error = -ENOMEM; | ||
813 | goto fail2; | 822 | goto fail2; |
823 | } | ||
814 | 824 | ||
815 | xpad->udev = udev; | 825 | xpad->udev = udev; |
816 | xpad->mapping = xpad_device[i].mapping; | 826 | xpad->mapping = xpad_device[i].mapping; |
@@ -887,15 +897,15 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
887 | 897 | ||
888 | error = xpad_init_output(intf, xpad); | 898 | error = xpad_init_output(intf, xpad); |
889 | if (error) | 899 | if (error) |
890 | goto fail2; | 900 | goto fail3; |
891 | 901 | ||
892 | error = xpad_init_ff(xpad); | 902 | error = xpad_init_ff(xpad); |
893 | if (error) | 903 | if (error) |
894 | goto fail3; | 904 | goto fail4; |
895 | 905 | ||
896 | error = xpad_led_probe(xpad); | 906 | error = xpad_led_probe(xpad); |
897 | if (error) | 907 | if (error) |
898 | goto fail3; | 908 | goto fail5; |
899 | 909 | ||
900 | ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; | 910 | ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; |
901 | usb_fill_int_urb(xpad->irq_in, udev, | 911 | usb_fill_int_urb(xpad->irq_in, udev, |
@@ -907,34 +917,26 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
907 | 917 | ||
908 | error = input_register_device(xpad->dev); | 918 | error = input_register_device(xpad->dev); |
909 | if (error) | 919 | if (error) |
910 | goto fail4; | 920 | goto fail6; |
911 | 921 | ||
912 | usb_set_intfdata(intf, xpad); | 922 | usb_set_intfdata(intf, xpad); |
913 | 923 | ||
914 | /* | ||
915 | * Submit the int URB immediatly rather than waiting for open | ||
916 | * because we get status messages from the device whether | ||
917 | * or not any controllers are attached. In fact, it's | ||
918 | * exactly the message that a controller has arrived that | ||
919 | * we're waiting for. | ||
920 | */ | ||
921 | if (xpad->xtype == XTYPE_XBOX360W) { | 924 | if (xpad->xtype == XTYPE_XBOX360W) { |
922 | xpad->irq_in->dev = xpad->udev; | ||
923 | error = usb_submit_urb(xpad->irq_in, GFP_KERNEL); | ||
924 | if (error) | ||
925 | goto fail4; | ||
926 | |||
927 | /* | 925 | /* |
928 | * Setup the message to set the LEDs on the | 926 | * Setup the message to set the LEDs on the |
929 | * controller when it shows up | 927 | * controller when it shows up |
930 | */ | 928 | */ |
931 | xpad->bulk_out = usb_alloc_urb(0, GFP_KERNEL); | 929 | xpad->bulk_out = usb_alloc_urb(0, GFP_KERNEL); |
932 | if(!xpad->bulk_out) | 930 | if (!xpad->bulk_out) { |
933 | goto fail5; | 931 | error = -ENOMEM; |
932 | goto fail7; | ||
933 | } | ||
934 | 934 | ||
935 | xpad->bdata = kzalloc(XPAD_PKT_LEN, GFP_KERNEL); | 935 | xpad->bdata = kzalloc(XPAD_PKT_LEN, GFP_KERNEL); |
936 | if(!xpad->bdata) | 936 | if (!xpad->bdata) { |
937 | goto fail6; | 937 | error = -ENOMEM; |
938 | goto fail8; | ||
939 | } | ||
938 | 940 | ||
939 | xpad->bdata[2] = 0x08; | 941 | xpad->bdata[2] = 0x08; |
940 | switch (intf->cur_altsetting->desc.bInterfaceNumber) { | 942 | switch (intf->cur_altsetting->desc.bInterfaceNumber) { |
@@ -955,14 +957,31 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
955 | usb_fill_bulk_urb(xpad->bulk_out, udev, | 957 | usb_fill_bulk_urb(xpad->bulk_out, udev, |
956 | usb_sndbulkpipe(udev, ep_irq_in->bEndpointAddress), | 958 | usb_sndbulkpipe(udev, ep_irq_in->bEndpointAddress), |
957 | xpad->bdata, XPAD_PKT_LEN, xpad_bulk_out, xpad); | 959 | xpad->bdata, XPAD_PKT_LEN, xpad_bulk_out, xpad); |
960 | |||
961 | /* | ||
962 | * Submit the int URB immediately rather than waiting for open | ||
963 | * because we get status messages from the device whether | ||
964 | * or not any controllers are attached. In fact, it's | ||
965 | * exactly the message that a controller has arrived that | ||
966 | * we're waiting for. | ||
967 | */ | ||
968 | xpad->irq_in->dev = xpad->udev; | ||
969 | error = usb_submit_urb(xpad->irq_in, GFP_KERNEL); | ||
970 | if (error) | ||
971 | goto fail9; | ||
958 | } | 972 | } |
959 | 973 | ||
960 | return 0; | 974 | return 0; |
961 | 975 | ||
962 | fail6: usb_free_urb(xpad->bulk_out); | 976 | fail9: kfree(xpad->bdata); |
963 | fail5: usb_kill_urb(xpad->irq_in); | 977 | fail8: usb_free_urb(xpad->bulk_out); |
964 | fail4: usb_free_urb(xpad->irq_in); | 978 | fail7: input_unregister_device(input_dev); |
965 | fail3: xpad_deinit_output(xpad); | 979 | input_dev = NULL; |
980 | fail6: xpad_led_disconnect(xpad); | ||
981 | fail5: if (input_dev) | ||
982 | input_ff_destroy(input_dev); | ||
983 | fail4: xpad_deinit_output(xpad); | ||
984 | fail3: usb_free_urb(xpad->irq_in); | ||
966 | fail2: usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); | 985 | fail2: usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); |
967 | fail1: input_free_device(input_dev); | 986 | fail1: input_free_device(input_dev); |
968 | kfree(xpad); | 987 | kfree(xpad); |
@@ -974,21 +993,24 @@ static void xpad_disconnect(struct usb_interface *intf) | |||
974 | { | 993 | { |
975 | struct usb_xpad *xpad = usb_get_intfdata (intf); | 994 | struct usb_xpad *xpad = usb_get_intfdata (intf); |
976 | 995 | ||
977 | usb_set_intfdata(intf, NULL); | 996 | xpad_led_disconnect(xpad); |
978 | if (xpad) { | 997 | input_unregister_device(xpad->dev); |
979 | xpad_led_disconnect(xpad); | 998 | xpad_deinit_output(xpad); |
980 | input_unregister_device(xpad->dev); | 999 | |
981 | xpad_deinit_output(xpad); | 1000 | if (xpad->xtype == XTYPE_XBOX360W) { |
982 | if (xpad->xtype == XTYPE_XBOX360W) { | 1001 | usb_kill_urb(xpad->bulk_out); |
983 | usb_kill_urb(xpad->bulk_out); | 1002 | usb_free_urb(xpad->bulk_out); |
984 | usb_free_urb(xpad->bulk_out); | 1003 | usb_kill_urb(xpad->irq_in); |
985 | usb_kill_urb(xpad->irq_in); | ||
986 | } | ||
987 | usb_free_urb(xpad->irq_in); | ||
988 | usb_free_coherent(xpad->udev, XPAD_PKT_LEN, | ||
989 | xpad->idata, xpad->idata_dma); | ||
990 | kfree(xpad); | ||
991 | } | 1004 | } |
1005 | |||
1006 | usb_free_urb(xpad->irq_in); | ||
1007 | usb_free_coherent(xpad->udev, XPAD_PKT_LEN, | ||
1008 | xpad->idata, xpad->idata_dma); | ||
1009 | |||
1010 | kfree(xpad->bdata); | ||
1011 | kfree(xpad); | ||
1012 | |||
1013 | usb_set_intfdata(intf, NULL); | ||
992 | } | 1014 | } |
993 | 1015 | ||
994 | static struct usb_driver xpad_driver = { | 1016 | static struct usb_driver xpad_driver = { |
@@ -1000,10 +1022,7 @@ static struct usb_driver xpad_driver = { | |||
1000 | 1022 | ||
1001 | static int __init usb_xpad_init(void) | 1023 | static int __init usb_xpad_init(void) |
1002 | { | 1024 | { |
1003 | int result = usb_register(&xpad_driver); | 1025 | return usb_register(&xpad_driver); |
1004 | if (result == 0) | ||
1005 | printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n"); | ||
1006 | return result; | ||
1007 | } | 1026 | } |
1008 | 1027 | ||
1009 | static void __exit usb_xpad_exit(void) | 1028 | static void __exit usb_xpad_exit(void) |
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index c76bd3183beb..f829998fabe6 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -196,20 +196,22 @@ config KEYBOARD_GPIO_POLLED | |||
196 | module will be called gpio_keys_polled. | 196 | module will be called gpio_keys_polled. |
197 | 197 | ||
198 | config KEYBOARD_TCA6416 | 198 | config KEYBOARD_TCA6416 |
199 | tristate "TCA6416 Keypad Support" | 199 | tristate "TCA6416/TCA6408A Keypad Support" |
200 | depends on I2C | 200 | depends on I2C |
201 | help | 201 | help |
202 | This driver implements basic keypad functionality | 202 | This driver implements basic keypad functionality |
203 | for keys connected through TCA6416 IO expander | 203 | for keys connected through TCA6416/TCA6408A IO expanders. |
204 | 204 | ||
205 | Say Y here if your device has keys connected to | 205 | Say Y here if your device has keys connected to |
206 | TCA6416 IO expander. Your board-specific setup logic | 206 | TCA6416/TCA6408A IO expander. Your board-specific setup logic |
207 | must also provide pin-mask details(of which TCA6416 pins | 207 | must also provide pin-mask details(of which TCA6416 pins |
208 | are used for keypad). | 208 | are used for keypad). |
209 | 209 | ||
210 | If enabled the complete TCA6416 device will be managed through | 210 | If enabled the entire TCA6416 device will be managed through |
211 | this driver. | 211 | this driver. |
212 | 212 | ||
213 | To compile this driver as a module, choose M here: the | ||
214 | module will be called tca6416_keypad. | ||
213 | 215 | ||
214 | config KEYBOARD_MATRIX | 216 | config KEYBOARD_MATRIX |
215 | tristate "GPIO driven matrix keypad support" | 217 | tristate "GPIO driven matrix keypad support" |
@@ -459,6 +461,15 @@ config KEYBOARD_OMAP4 | |||
459 | To compile this driver as a module, choose M here: the | 461 | To compile this driver as a module, choose M here: the |
460 | module will be called omap4-keypad. | 462 | module will be called omap4-keypad. |
461 | 463 | ||
464 | config KEYBOARD_SPEAR | ||
465 | tristate "ST SPEAR keyboard support" | ||
466 | depends on PLAT_SPEAR | ||
467 | help | ||
468 | Say Y here if you want to use the SPEAR keyboard. | ||
469 | |||
470 | To compile this driver as a module, choose M here: the | ||
471 | module will be called spear-keboard. | ||
472 | |||
462 | config KEYBOARD_TC3589X | 473 | config KEYBOARD_TC3589X |
463 | tristate "TC3589X Keypad support" | 474 | tristate "TC3589X Keypad support" |
464 | depends on MFD_TC3589X | 475 | depends on MFD_TC3589X |
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 2aa6ce248b71..8933e9ca938d 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
@@ -38,6 +38,7 @@ obj-$(CONFIG_KEYBOARD_PXA930_ROTARY) += pxa930_rotary.o | |||
38 | obj-$(CONFIG_KEYBOARD_QT2160) += qt2160.o | 38 | obj-$(CONFIG_KEYBOARD_QT2160) += qt2160.o |
39 | obj-$(CONFIG_KEYBOARD_SAMSUNG) += samsung-keypad.o | 39 | obj-$(CONFIG_KEYBOARD_SAMSUNG) += samsung-keypad.o |
40 | obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o | 40 | obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o |
41 | obj-$(CONFIG_KEYBOARD_SPEAR) += spear-keyboard.o | ||
41 | obj-$(CONFIG_KEYBOARD_STMPE) += stmpe-keypad.o | 42 | obj-$(CONFIG_KEYBOARD_STMPE) += stmpe-keypad.o |
42 | obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o | 43 | obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o |
43 | obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o | 44 | obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o |
diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c new file mode 100644 index 000000000000..bee03d64c453 --- /dev/null +++ b/drivers/input/keyboard/spear-keyboard.c | |||
@@ -0,0 +1,344 @@ | |||
1 | /* | ||
2 | * SPEAr Keyboard Driver | ||
3 | * Based on omap-keypad driver | ||
4 | * | ||
5 | * Copyright (C) 2010 ST Microelectronics | ||
6 | * Rajeev Kumar<rajeev-dlh.kumar@st.com> | ||
7 | * | ||
8 | * This file is licensed under the terms of the GNU General Public | ||
9 | * License version 2. This program is licensed "as is" without any | ||
10 | * warranty of any kind, whether express or implied. | ||
11 | */ | ||
12 | |||
13 | #include <linux/clk.h> | ||
14 | #include <linux/errno.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/interrupt.h> | ||
17 | #include <linux/input.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/irq.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/pm_wakeup.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/types.h> | ||
26 | #include <plat/keyboard.h> | ||
27 | |||
28 | /* Keyboard Registers */ | ||
29 | #define MODE_REG 0x00 /* 16 bit reg */ | ||
30 | #define STATUS_REG 0x0C /* 2 bit reg */ | ||
31 | #define DATA_REG 0x10 /* 8 bit reg */ | ||
32 | #define INTR_MASK 0x54 | ||
33 | |||
34 | /* Register Values */ | ||
35 | /* | ||
36 | * pclk freq mask = (APB FEQ -1)= 82 MHZ.Programme bit 15-9 in mode | ||
37 | * control register as 1010010(82MHZ) | ||
38 | */ | ||
39 | #define PCLK_FREQ_MSK 0xA400 /* 82 MHz */ | ||
40 | #define START_SCAN 0x0100 | ||
41 | #define SCAN_RATE_10 0x0000 | ||
42 | #define SCAN_RATE_20 0x0004 | ||
43 | #define SCAN_RATE_40 0x0008 | ||
44 | #define SCAN_RATE_80 0x000C | ||
45 | #define MODE_KEYBOARD 0x0002 | ||
46 | #define DATA_AVAIL 0x2 | ||
47 | |||
48 | #define KEY_MASK 0xFF000000 | ||
49 | #define KEY_VALUE 0x00FFFFFF | ||
50 | #define ROW_MASK 0xF0 | ||
51 | #define COLUMN_MASK 0x0F | ||
52 | #define ROW_SHIFT 4 | ||
53 | |||
54 | struct spear_kbd { | ||
55 | struct input_dev *input; | ||
56 | struct resource *res; | ||
57 | void __iomem *io_base; | ||
58 | struct clk *clk; | ||
59 | unsigned int irq; | ||
60 | unsigned short last_key; | ||
61 | unsigned short keycodes[256]; | ||
62 | }; | ||
63 | |||
64 | static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id) | ||
65 | { | ||
66 | struct spear_kbd *kbd = dev_id; | ||
67 | struct input_dev *input = kbd->input; | ||
68 | unsigned int key; | ||
69 | u8 sts, val; | ||
70 | |||
71 | sts = readb(kbd->io_base + STATUS_REG); | ||
72 | if (sts & DATA_AVAIL) | ||
73 | return IRQ_NONE; | ||
74 | |||
75 | if (kbd->last_key != KEY_RESERVED) { | ||
76 | input_report_key(input, kbd->last_key, 0); | ||
77 | kbd->last_key = KEY_RESERVED; | ||
78 | } | ||
79 | |||
80 | /* following reads active (row, col) pair */ | ||
81 | val = readb(kbd->io_base + DATA_REG); | ||
82 | key = kbd->keycodes[val]; | ||
83 | |||
84 | input_event(input, EV_MSC, MSC_SCAN, val); | ||
85 | input_report_key(input, key, 1); | ||
86 | input_sync(input); | ||
87 | |||
88 | kbd->last_key = key; | ||
89 | |||
90 | /* clear interrupt */ | ||
91 | writeb(0, kbd->io_base + STATUS_REG); | ||
92 | |||
93 | return IRQ_HANDLED; | ||
94 | } | ||
95 | |||
96 | static int spear_kbd_open(struct input_dev *dev) | ||
97 | { | ||
98 | struct spear_kbd *kbd = input_get_drvdata(dev); | ||
99 | int error; | ||
100 | u16 val; | ||
101 | |||
102 | kbd->last_key = KEY_RESERVED; | ||
103 | |||
104 | error = clk_enable(kbd->clk); | ||
105 | if (error) | ||
106 | return error; | ||
107 | |||
108 | /* program keyboard */ | ||
109 | val = SCAN_RATE_80 | MODE_KEYBOARD | PCLK_FREQ_MSK; | ||
110 | writew(val, kbd->io_base + MODE_REG); | ||
111 | writeb(1, kbd->io_base + STATUS_REG); | ||
112 | |||
113 | /* start key scan */ | ||
114 | val = readw(kbd->io_base + MODE_REG); | ||
115 | val |= START_SCAN; | ||
116 | writew(val, kbd->io_base + MODE_REG); | ||
117 | |||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | static void spear_kbd_close(struct input_dev *dev) | ||
122 | { | ||
123 | struct spear_kbd *kbd = input_get_drvdata(dev); | ||
124 | u16 val; | ||
125 | |||
126 | /* stop key scan */ | ||
127 | val = readw(kbd->io_base + MODE_REG); | ||
128 | val &= ~START_SCAN; | ||
129 | writew(val, kbd->io_base + MODE_REG); | ||
130 | |||
131 | clk_disable(kbd->clk); | ||
132 | |||
133 | kbd->last_key = KEY_RESERVED; | ||
134 | } | ||
135 | |||
136 | static int __devinit spear_kbd_probe(struct platform_device *pdev) | ||
137 | { | ||
138 | const struct kbd_platform_data *pdata = pdev->dev.platform_data; | ||
139 | const struct matrix_keymap_data *keymap; | ||
140 | struct spear_kbd *kbd; | ||
141 | struct input_dev *input_dev; | ||
142 | struct resource *res; | ||
143 | int irq; | ||
144 | int error; | ||
145 | |||
146 | if (!pdata) { | ||
147 | dev_err(&pdev->dev, "Invalid platform data\n"); | ||
148 | return -EINVAL; | ||
149 | } | ||
150 | |||
151 | keymap = pdata->keymap; | ||
152 | if (!keymap) { | ||
153 | dev_err(&pdev->dev, "no keymap defined\n"); | ||
154 | return -EINVAL; | ||
155 | } | ||
156 | |||
157 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
158 | if (!res) { | ||
159 | dev_err(&pdev->dev, "no keyboard resource defined\n"); | ||
160 | return -EBUSY; | ||
161 | } | ||
162 | |||
163 | irq = platform_get_irq(pdev, 0); | ||
164 | if (irq < 0) { | ||
165 | dev_err(&pdev->dev, "not able to get irq for the device\n"); | ||
166 | return irq; | ||
167 | } | ||
168 | |||
169 | kbd = kzalloc(sizeof(*kbd), GFP_KERNEL); | ||
170 | input_dev = input_allocate_device(); | ||
171 | if (!kbd || !input_dev) { | ||
172 | dev_err(&pdev->dev, "out of memory\n"); | ||
173 | error = -ENOMEM; | ||
174 | goto err_free_mem; | ||
175 | } | ||
176 | |||
177 | kbd->input = input_dev; | ||
178 | kbd->irq = irq; | ||
179 | kbd->res = request_mem_region(res->start, resource_size(res), | ||
180 | pdev->name); | ||
181 | if (!kbd->res) { | ||
182 | dev_err(&pdev->dev, "keyboard region already claimed\n"); | ||
183 | error = -EBUSY; | ||
184 | goto err_free_mem; | ||
185 | } | ||
186 | |||
187 | kbd->io_base = ioremap(res->start, resource_size(res)); | ||
188 | if (!kbd->io_base) { | ||
189 | dev_err(&pdev->dev, "ioremap failed for kbd_region\n"); | ||
190 | error = -ENOMEM; | ||
191 | goto err_release_mem_region; | ||
192 | } | ||
193 | |||
194 | kbd->clk = clk_get(&pdev->dev, NULL); | ||
195 | if (IS_ERR(kbd->clk)) { | ||
196 | error = PTR_ERR(kbd->clk); | ||
197 | goto err_iounmap; | ||
198 | } | ||
199 | |||
200 | input_dev->name = "Spear Keyboard"; | ||
201 | input_dev->phys = "keyboard/input0"; | ||
202 | input_dev->dev.parent = &pdev->dev; | ||
203 | input_dev->id.bustype = BUS_HOST; | ||
204 | input_dev->id.vendor = 0x0001; | ||
205 | input_dev->id.product = 0x0001; | ||
206 | input_dev->id.version = 0x0100; | ||
207 | input_dev->open = spear_kbd_open; | ||
208 | input_dev->close = spear_kbd_close; | ||
209 | |||
210 | __set_bit(EV_KEY, input_dev->evbit); | ||
211 | if (pdata->rep) | ||
212 | __set_bit(EV_REP, input_dev->evbit); | ||
213 | input_set_capability(input_dev, EV_MSC, MSC_SCAN); | ||
214 | |||
215 | input_dev->keycode = kbd->keycodes; | ||
216 | input_dev->keycodesize = sizeof(kbd->keycodes[0]); | ||
217 | input_dev->keycodemax = ARRAY_SIZE(kbd->keycodes); | ||
218 | |||
219 | matrix_keypad_build_keymap(keymap, ROW_SHIFT, | ||
220 | input_dev->keycode, input_dev->keybit); | ||
221 | |||
222 | input_set_drvdata(input_dev, kbd); | ||
223 | |||
224 | error = request_irq(irq, spear_kbd_interrupt, 0, "keyboard", kbd); | ||
225 | if (error) { | ||
226 | dev_err(&pdev->dev, "request_irq fail\n"); | ||
227 | goto err_put_clk; | ||
228 | } | ||
229 | |||
230 | error = input_register_device(input_dev); | ||
231 | if (error) { | ||
232 | dev_err(&pdev->dev, "Unable to register keyboard device\n"); | ||
233 | goto err_free_irq; | ||
234 | } | ||
235 | |||
236 | device_init_wakeup(&pdev->dev, 1); | ||
237 | platform_set_drvdata(pdev, kbd); | ||
238 | |||
239 | return 0; | ||
240 | |||
241 | err_free_irq: | ||
242 | free_irq(kbd->irq, kbd); | ||
243 | err_put_clk: | ||
244 | clk_put(kbd->clk); | ||
245 | err_iounmap: | ||
246 | iounmap(kbd->io_base); | ||
247 | err_release_mem_region: | ||
248 | release_mem_region(res->start, resource_size(res)); | ||
249 | err_free_mem: | ||
250 | input_free_device(input_dev); | ||
251 | kfree(kbd); | ||
252 | |||
253 | return error; | ||
254 | } | ||
255 | |||
256 | static int __devexit spear_kbd_remove(struct platform_device *pdev) | ||
257 | { | ||
258 | struct spear_kbd *kbd = platform_get_drvdata(pdev); | ||
259 | |||
260 | free_irq(kbd->irq, kbd); | ||
261 | input_unregister_device(kbd->input); | ||
262 | clk_put(kbd->clk); | ||
263 | iounmap(kbd->io_base); | ||
264 | release_mem_region(kbd->res->start, resource_size(kbd->res)); | ||
265 | kfree(kbd); | ||
266 | |||
267 | device_init_wakeup(&pdev->dev, 1); | ||
268 | platform_set_drvdata(pdev, NULL); | ||
269 | |||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | #ifdef CONFIG_PM | ||
274 | static int spear_kbd_suspend(struct device *dev) | ||
275 | { | ||
276 | struct platform_device *pdev = to_platform_device(dev); | ||
277 | struct spear_kbd *kbd = platform_get_drvdata(pdev); | ||
278 | struct input_dev *input_dev = kbd->input; | ||
279 | |||
280 | mutex_lock(&input_dev->mutex); | ||
281 | |||
282 | if (input_dev->users) | ||
283 | clk_enable(kbd->clk); | ||
284 | |||
285 | if (device_may_wakeup(&pdev->dev)) | ||
286 | enable_irq_wake(kbd->irq); | ||
287 | |||
288 | mutex_unlock(&input_dev->mutex); | ||
289 | |||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | static int spear_kbd_resume(struct device *dev) | ||
294 | { | ||
295 | struct platform_device *pdev = to_platform_device(dev); | ||
296 | struct spear_kbd *kbd = platform_get_drvdata(pdev); | ||
297 | struct input_dev *input_dev = kbd->input; | ||
298 | |||
299 | mutex_lock(&input_dev->mutex); | ||
300 | |||
301 | if (device_may_wakeup(&pdev->dev)) | ||
302 | disable_irq_wake(kbd->irq); | ||
303 | |||
304 | if (input_dev->users) | ||
305 | clk_enable(kbd->clk); | ||
306 | |||
307 | mutex_unlock(&input_dev->mutex); | ||
308 | |||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | static const struct dev_pm_ops spear_kbd_pm_ops = { | ||
313 | .suspend = spear_kbd_suspend, | ||
314 | .resume = spear_kbd_resume, | ||
315 | }; | ||
316 | #endif | ||
317 | |||
318 | static struct platform_driver spear_kbd_driver = { | ||
319 | .probe = spear_kbd_probe, | ||
320 | .remove = __devexit_p(spear_kbd_remove), | ||
321 | .driver = { | ||
322 | .name = "keyboard", | ||
323 | .owner = THIS_MODULE, | ||
324 | #ifdef CONFIG_PM | ||
325 | .pm = &spear_kbd_pm_ops, | ||
326 | #endif | ||
327 | }, | ||
328 | }; | ||
329 | |||
330 | static int __init spear_kbd_init(void) | ||
331 | { | ||
332 | return platform_driver_register(&spear_kbd_driver); | ||
333 | } | ||
334 | module_init(spear_kbd_init); | ||
335 | |||
336 | static void __exit spear_kbd_exit(void) | ||
337 | { | ||
338 | platform_driver_unregister(&spear_kbd_driver); | ||
339 | } | ||
340 | module_exit(spear_kbd_exit); | ||
341 | |||
342 | MODULE_AUTHOR("Rajeev Kumar"); | ||
343 | MODULE_DESCRIPTION("SPEAr Keyboard Driver"); | ||
344 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/keyboard/tca6416-keypad.c b/drivers/input/keyboard/tca6416-keypad.c index 00137bebcf97..800fbccf1f0f 100644 --- a/drivers/input/keyboard/tca6416-keypad.c +++ b/drivers/input/keyboard/tca6416-keypad.c | |||
@@ -29,6 +29,7 @@ | |||
29 | 29 | ||
30 | static const struct i2c_device_id tca6416_id[] = { | 30 | static const struct i2c_device_id tca6416_id[] = { |
31 | { "tca6416-keys", 16, }, | 31 | { "tca6416-keys", 16, }, |
32 | { "tca6408-keys", 8, }, | ||
32 | { } | 33 | { } |
33 | }; | 34 | }; |
34 | MODULE_DEVICE_TABLE(i2c, tca6416_id); | 35 | MODULE_DEVICE_TABLE(i2c, tca6416_id); |
@@ -46,8 +47,9 @@ struct tca6416_keypad_chip { | |||
46 | struct i2c_client *client; | 47 | struct i2c_client *client; |
47 | struct input_dev *input; | 48 | struct input_dev *input; |
48 | struct delayed_work dwork; | 49 | struct delayed_work dwork; |
49 | u16 pinmask; | 50 | int io_size; |
50 | int irqnum; | 51 | int irqnum; |
52 | u16 pinmask; | ||
51 | bool use_polling; | 53 | bool use_polling; |
52 | struct tca6416_button buttons[0]; | 54 | struct tca6416_button buttons[0]; |
53 | }; | 55 | }; |
@@ -56,7 +58,9 @@ static int tca6416_write_reg(struct tca6416_keypad_chip *chip, int reg, u16 val) | |||
56 | { | 58 | { |
57 | int error; | 59 | int error; |
58 | 60 | ||
59 | error = i2c_smbus_write_word_data(chip->client, reg << 1, val); | 61 | error = chip->io_size > 8 ? |
62 | i2c_smbus_write_word_data(chip->client, reg << 1, val) : | ||
63 | i2c_smbus_write_byte_data(chip->client, reg, val); | ||
60 | if (error < 0) { | 64 | if (error < 0) { |
61 | dev_err(&chip->client->dev, | 65 | dev_err(&chip->client->dev, |
62 | "%s failed, reg: %d, val: %d, error: %d\n", | 66 | "%s failed, reg: %d, val: %d, error: %d\n", |
@@ -71,7 +75,9 @@ static int tca6416_read_reg(struct tca6416_keypad_chip *chip, int reg, u16 *val) | |||
71 | { | 75 | { |
72 | int retval; | 76 | int retval; |
73 | 77 | ||
74 | retval = i2c_smbus_read_word_data(chip->client, reg << 1); | 78 | retval = chip->io_size > 8 ? |
79 | i2c_smbus_read_word_data(chip->client, reg << 1) : | ||
80 | i2c_smbus_read_byte_data(chip->client, reg); | ||
75 | if (retval < 0) { | 81 | if (retval < 0) { |
76 | dev_err(&chip->client->dev, "%s failed, reg: %d, error: %d\n", | 82 | dev_err(&chip->client->dev, "%s failed, reg: %d, error: %d\n", |
77 | __func__, reg, retval); | 83 | __func__, reg, retval); |
@@ -224,6 +230,7 @@ static int __devinit tca6416_keypad_probe(struct i2c_client *client, | |||
224 | 230 | ||
225 | chip->client = client; | 231 | chip->client = client; |
226 | chip->input = input; | 232 | chip->input = input; |
233 | chip->io_size = id->driver_data; | ||
227 | chip->pinmask = pdata->pinmask; | 234 | chip->pinmask = pdata->pinmask; |
228 | chip->use_polling = pdata->use_polling; | 235 | chip->use_polling = pdata->use_polling; |
229 | 236 | ||
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index c1a81bcdb319..b0c6772851a9 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig | |||
@@ -430,4 +430,28 @@ config INPUT_ADXL34X_SPI | |||
430 | To compile this driver as a module, choose M here: the | 430 | To compile this driver as a module, choose M here: the |
431 | module will be called adxl34x-spi. | 431 | module will be called adxl34x-spi. |
432 | 432 | ||
433 | config INPUT_CMA3000 | ||
434 | tristate "VTI CMA3000 Tri-axis accelerometer" | ||
435 | help | ||
436 | Say Y here if you want to use VTI CMA3000_D0x Accelerometer | ||
437 | driver | ||
438 | |||
439 | This driver currently only supports I2C interface to the | ||
440 | controller. Also select the I2C method. | ||
441 | |||
442 | If unsure, say N | ||
443 | |||
444 | To compile this driver as a module, choose M here: the | ||
445 | module will be called cma3000_d0x. | ||
446 | |||
447 | config INPUT_CMA3000_I2C | ||
448 | tristate "Support I2C bus connection" | ||
449 | depends on INPUT_CMA3000 && I2C | ||
450 | help | ||
451 | Say Y here if you want to use VTI CMA3000_D0x Accelerometer | ||
452 | through I2C interface. | ||
453 | |||
454 | To compile this driver as a module, choose M here: the | ||
455 | module will be called cma3000_d0x_i2c. | ||
456 | |||
433 | endif | 457 | endif |
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 06b2b5154038..9b4797112c9a 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile | |||
@@ -18,6 +18,8 @@ obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o | |||
18 | obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o | 18 | obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o |
19 | obj-$(CONFIG_INPUT_BFIN_ROTARY) += bfin_rotary.o | 19 | obj-$(CONFIG_INPUT_BFIN_ROTARY) += bfin_rotary.o |
20 | obj-$(CONFIG_INPUT_CM109) += cm109.o | 20 | obj-$(CONFIG_INPUT_CM109) += cm109.o |
21 | obj-$(CONFIG_INPUT_CMA3000) += cma3000_d0x.o | ||
22 | obj-$(CONFIG_INPUT_CMA3000_I2C) += cma3000_d0x_i2c.o | ||
21 | obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o | 23 | obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o |
22 | obj-$(CONFIG_INPUT_DM355EVM) += dm355evm_keys.o | 24 | obj-$(CONFIG_INPUT_DM355EVM) += dm355evm_keys.o |
23 | obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o | 25 | obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o |
diff --git a/drivers/input/misc/cma3000_d0x.c b/drivers/input/misc/cma3000_d0x.c new file mode 100644 index 000000000000..1633b6342267 --- /dev/null +++ b/drivers/input/misc/cma3000_d0x.c | |||
@@ -0,0 +1,398 @@ | |||
1 | /* | ||
2 | * VTI CMA3000_D0x Accelerometer driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Texas Instruments | ||
5 | * Author: Hemanth V <hemanthv@ti.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published by | ||
9 | * the Free Software Foundation. | ||
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 with | ||
17 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #include <linux/types.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/input.h> | ||
25 | #include <linux/input/cma3000.h> | ||
26 | |||
27 | #include "cma3000_d0x.h" | ||
28 | |||
29 | #define CMA3000_WHOAMI 0x00 | ||
30 | #define CMA3000_REVID 0x01 | ||
31 | #define CMA3000_CTRL 0x02 | ||
32 | #define CMA3000_STATUS 0x03 | ||
33 | #define CMA3000_RSTR 0x04 | ||
34 | #define CMA3000_INTSTATUS 0x05 | ||
35 | #define CMA3000_DOUTX 0x06 | ||
36 | #define CMA3000_DOUTY 0x07 | ||
37 | #define CMA3000_DOUTZ 0x08 | ||
38 | #define CMA3000_MDTHR 0x09 | ||
39 | #define CMA3000_MDFFTMR 0x0A | ||
40 | #define CMA3000_FFTHR 0x0B | ||
41 | |||
42 | #define CMA3000_RANGE2G (1 << 7) | ||
43 | #define CMA3000_RANGE8G (0 << 7) | ||
44 | #define CMA3000_BUSI2C (0 << 4) | ||
45 | #define CMA3000_MODEMASK (7 << 1) | ||
46 | #define CMA3000_GRANGEMASK (1 << 7) | ||
47 | |||
48 | #define CMA3000_STATUS_PERR 1 | ||
49 | #define CMA3000_INTSTATUS_FFDET (1 << 2) | ||
50 | |||
51 | /* Settling time delay in ms */ | ||
52 | #define CMA3000_SETDELAY 30 | ||
53 | |||
54 | /* Delay for clearing interrupt in us */ | ||
55 | #define CMA3000_INTDELAY 44 | ||
56 | |||
57 | |||
58 | /* | ||
59 | * Bit weights in mg for bit 0, other bits need | ||
60 | * multipy factor 2^n. Eight bit is the sign bit. | ||
61 | */ | ||
62 | #define BIT_TO_2G 18 | ||
63 | #define BIT_TO_8G 71 | ||
64 | |||
65 | struct cma3000_accl_data { | ||
66 | const struct cma3000_bus_ops *bus_ops; | ||
67 | const struct cma3000_platform_data *pdata; | ||
68 | |||
69 | struct device *dev; | ||
70 | struct input_dev *input_dev; | ||
71 | |||
72 | int bit_to_mg; | ||
73 | int irq; | ||
74 | |||
75 | int g_range; | ||
76 | u8 mode; | ||
77 | |||
78 | struct mutex mutex; | ||
79 | bool opened; | ||
80 | bool suspended; | ||
81 | }; | ||
82 | |||
83 | #define CMA3000_READ(data, reg, msg) \ | ||
84 | (data->bus_ops->read(data->dev, reg, msg)) | ||
85 | #define CMA3000_SET(data, reg, val, msg) \ | ||
86 | ((data)->bus_ops->write(data->dev, reg, val, msg)) | ||
87 | |||
88 | /* | ||
89 | * Conversion for each of the eight modes to g, depending | ||
90 | * on G range i.e 2G or 8G. Some modes always operate in | ||
91 | * 8G. | ||
92 | */ | ||
93 | |||
94 | static int mode_to_mg[8][2] = { | ||
95 | { 0, 0 }, | ||
96 | { BIT_TO_8G, BIT_TO_2G }, | ||
97 | { BIT_TO_8G, BIT_TO_2G }, | ||
98 | { BIT_TO_8G, BIT_TO_8G }, | ||
99 | { BIT_TO_8G, BIT_TO_8G }, | ||
100 | { BIT_TO_8G, BIT_TO_2G }, | ||
101 | { BIT_TO_8G, BIT_TO_2G }, | ||
102 | { 0, 0}, | ||
103 | }; | ||
104 | |||
105 | static void decode_mg(struct cma3000_accl_data *data, int *datax, | ||
106 | int *datay, int *dataz) | ||
107 | { | ||
108 | /* Data in 2's complement, convert to mg */ | ||
109 | *datax = ((s8)*datax) * data->bit_to_mg; | ||
110 | *datay = ((s8)*datay) * data->bit_to_mg; | ||
111 | *dataz = ((s8)*dataz) * data->bit_to_mg; | ||
112 | } | ||
113 | |||
114 | static irqreturn_t cma3000_thread_irq(int irq, void *dev_id) | ||
115 | { | ||
116 | struct cma3000_accl_data *data = dev_id; | ||
117 | int datax, datay, dataz; | ||
118 | u8 ctrl, mode, range, intr_status; | ||
119 | |||
120 | intr_status = CMA3000_READ(data, CMA3000_INTSTATUS, "interrupt status"); | ||
121 | if (intr_status < 0) | ||
122 | return IRQ_NONE; | ||
123 | |||
124 | /* Check if free fall is detected, report immediately */ | ||
125 | if (intr_status & CMA3000_INTSTATUS_FFDET) { | ||
126 | input_report_abs(data->input_dev, ABS_MISC, 1); | ||
127 | input_sync(data->input_dev); | ||
128 | } else { | ||
129 | input_report_abs(data->input_dev, ABS_MISC, 0); | ||
130 | } | ||
131 | |||
132 | datax = CMA3000_READ(data, CMA3000_DOUTX, "X"); | ||
133 | datay = CMA3000_READ(data, CMA3000_DOUTY, "Y"); | ||
134 | dataz = CMA3000_READ(data, CMA3000_DOUTZ, "Z"); | ||
135 | |||
136 | ctrl = CMA3000_READ(data, CMA3000_CTRL, "ctrl"); | ||
137 | mode = (ctrl & CMA3000_MODEMASK) >> 1; | ||
138 | range = (ctrl & CMA3000_GRANGEMASK) >> 7; | ||
139 | |||
140 | data->bit_to_mg = mode_to_mg[mode][range]; | ||
141 | |||
142 | /* Interrupt not for this device */ | ||
143 | if (data->bit_to_mg == 0) | ||
144 | return IRQ_NONE; | ||
145 | |||
146 | /* Decode register values to milli g */ | ||
147 | decode_mg(data, &datax, &datay, &dataz); | ||
148 | |||
149 | input_report_abs(data->input_dev, ABS_X, datax); | ||
150 | input_report_abs(data->input_dev, ABS_Y, datay); | ||
151 | input_report_abs(data->input_dev, ABS_Z, dataz); | ||
152 | input_sync(data->input_dev); | ||
153 | |||
154 | return IRQ_HANDLED; | ||
155 | } | ||
156 | |||
157 | static int cma3000_reset(struct cma3000_accl_data *data) | ||
158 | { | ||
159 | int val; | ||
160 | |||
161 | /* Reset sequence */ | ||
162 | CMA3000_SET(data, CMA3000_RSTR, 0x02, "Reset"); | ||
163 | CMA3000_SET(data, CMA3000_RSTR, 0x0A, "Reset"); | ||
164 | CMA3000_SET(data, CMA3000_RSTR, 0x04, "Reset"); | ||
165 | |||
166 | /* Settling time delay */ | ||
167 | mdelay(10); | ||
168 | |||
169 | val = CMA3000_READ(data, CMA3000_STATUS, "Status"); | ||
170 | if (val < 0) { | ||
171 | dev_err(data->dev, "Reset failed\n"); | ||
172 | return val; | ||
173 | } | ||
174 | |||
175 | if (val & CMA3000_STATUS_PERR) { | ||
176 | dev_err(data->dev, "Parity Error\n"); | ||
177 | return -EIO; | ||
178 | } | ||
179 | |||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | static int cma3000_poweron(struct cma3000_accl_data *data) | ||
184 | { | ||
185 | const struct cma3000_platform_data *pdata = data->pdata; | ||
186 | u8 ctrl = 0; | ||
187 | int ret; | ||
188 | |||
189 | if (data->g_range == CMARANGE_2G) { | ||
190 | ctrl = (data->mode << 1) | CMA3000_RANGE2G; | ||
191 | } else if (data->g_range == CMARANGE_8G) { | ||
192 | ctrl = (data->mode << 1) | CMA3000_RANGE8G; | ||
193 | } else { | ||
194 | dev_info(data->dev, | ||
195 | "Invalid G range specified, assuming 8G\n"); | ||
196 | ctrl = (data->mode << 1) | CMA3000_RANGE8G; | ||
197 | } | ||
198 | |||
199 | ctrl |= data->bus_ops->ctrl_mod; | ||
200 | |||
201 | CMA3000_SET(data, CMA3000_MDTHR, pdata->mdthr, | ||
202 | "Motion Detect Threshold"); | ||
203 | CMA3000_SET(data, CMA3000_MDFFTMR, pdata->mdfftmr, | ||
204 | "Time register"); | ||
205 | CMA3000_SET(data, CMA3000_FFTHR, pdata->ffthr, | ||
206 | "Free fall threshold"); | ||
207 | ret = CMA3000_SET(data, CMA3000_CTRL, ctrl, "Mode setting"); | ||
208 | if (ret < 0) | ||
209 | return -EIO; | ||
210 | |||
211 | msleep(CMA3000_SETDELAY); | ||
212 | |||
213 | return 0; | ||
214 | } | ||
215 | |||
216 | static int cma3000_poweroff(struct cma3000_accl_data *data) | ||
217 | { | ||
218 | int ret; | ||
219 | |||
220 | ret = CMA3000_SET(data, CMA3000_CTRL, CMAMODE_POFF, "Mode setting"); | ||
221 | msleep(CMA3000_SETDELAY); | ||
222 | |||
223 | return ret; | ||
224 | } | ||
225 | |||
226 | static int cma3000_open(struct input_dev *input_dev) | ||
227 | { | ||
228 | struct cma3000_accl_data *data = input_get_drvdata(input_dev); | ||
229 | |||
230 | mutex_lock(&data->mutex); | ||
231 | |||
232 | if (!data->suspended) | ||
233 | cma3000_poweron(data); | ||
234 | |||
235 | data->opened = true; | ||
236 | |||
237 | mutex_unlock(&data->mutex); | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | static void cma3000_close(struct input_dev *input_dev) | ||
243 | { | ||
244 | struct cma3000_accl_data *data = input_get_drvdata(input_dev); | ||
245 | |||
246 | mutex_lock(&data->mutex); | ||
247 | |||
248 | if (!data->suspended) | ||
249 | cma3000_poweroff(data); | ||
250 | |||
251 | data->opened = false; | ||
252 | |||
253 | mutex_unlock(&data->mutex); | ||
254 | } | ||
255 | |||
256 | void cma3000_suspend(struct cma3000_accl_data *data) | ||
257 | { | ||
258 | mutex_lock(&data->mutex); | ||
259 | |||
260 | if (!data->suspended && data->opened) | ||
261 | cma3000_poweroff(data); | ||
262 | |||
263 | data->suspended = true; | ||
264 | |||
265 | mutex_unlock(&data->mutex); | ||
266 | } | ||
267 | EXPORT_SYMBOL(cma3000_suspend); | ||
268 | |||
269 | |||
270 | void cma3000_resume(struct cma3000_accl_data *data) | ||
271 | { | ||
272 | mutex_lock(&data->mutex); | ||
273 | |||
274 | if (data->suspended && data->opened) | ||
275 | cma3000_poweron(data); | ||
276 | |||
277 | data->suspended = false; | ||
278 | |||
279 | mutex_unlock(&data->mutex); | ||
280 | } | ||
281 | EXPORT_SYMBOL(cma3000_resume); | ||
282 | |||
283 | struct cma3000_accl_data *cma3000_init(struct device *dev, int irq, | ||
284 | const struct cma3000_bus_ops *bops) | ||
285 | { | ||
286 | const struct cma3000_platform_data *pdata = dev->platform_data; | ||
287 | struct cma3000_accl_data *data; | ||
288 | struct input_dev *input_dev; | ||
289 | int rev; | ||
290 | int error; | ||
291 | |||
292 | if (!pdata) { | ||
293 | dev_err(dev, "platform data not found\n"); | ||
294 | error = -EINVAL; | ||
295 | goto err_out; | ||
296 | } | ||
297 | |||
298 | |||
299 | /* if no IRQ return error */ | ||
300 | if (irq == 0) { | ||
301 | error = -EINVAL; | ||
302 | goto err_out; | ||
303 | } | ||
304 | |||
305 | data = kzalloc(sizeof(struct cma3000_accl_data), GFP_KERNEL); | ||
306 | input_dev = input_allocate_device(); | ||
307 | if (!data || !input_dev) { | ||
308 | error = -ENOMEM; | ||
309 | goto err_free_mem; | ||
310 | } | ||
311 | |||
312 | data->dev = dev; | ||
313 | data->input_dev = input_dev; | ||
314 | data->bus_ops = bops; | ||
315 | data->pdata = pdata; | ||
316 | data->irq = irq; | ||
317 | mutex_init(&data->mutex); | ||
318 | |||
319 | data->mode = pdata->mode; | ||
320 | if (data->mode < CMAMODE_DEFAULT || data->mode > CMAMODE_POFF) { | ||
321 | data->mode = CMAMODE_MOTDET; | ||
322 | dev_warn(dev, | ||
323 | "Invalid mode specified, assuming Motion Detect\n"); | ||
324 | } | ||
325 | |||
326 | data->g_range = pdata->g_range; | ||
327 | if (data->g_range != CMARANGE_2G && data->g_range != CMARANGE_8G) { | ||
328 | dev_info(dev, | ||
329 | "Invalid G range specified, assuming 8G\n"); | ||
330 | data->g_range = CMARANGE_8G; | ||
331 | } | ||
332 | |||
333 | input_dev->name = "cma3000-accelerometer"; | ||
334 | input_dev->id.bustype = bops->bustype; | ||
335 | input_dev->open = cma3000_open; | ||
336 | input_dev->close = cma3000_close; | ||
337 | |||
338 | __set_bit(EV_ABS, input_dev->evbit); | ||
339 | |||
340 | input_set_abs_params(input_dev, ABS_X, | ||
341 | -data->g_range, data->g_range, pdata->fuzz_x, 0); | ||
342 | input_set_abs_params(input_dev, ABS_Y, | ||
343 | -data->g_range, data->g_range, pdata->fuzz_y, 0); | ||
344 | input_set_abs_params(input_dev, ABS_Z, | ||
345 | -data->g_range, data->g_range, pdata->fuzz_z, 0); | ||
346 | input_set_abs_params(input_dev, ABS_MISC, 0, 1, 0, 0); | ||
347 | |||
348 | input_set_drvdata(input_dev, data); | ||
349 | |||
350 | error = cma3000_reset(data); | ||
351 | if (error) | ||
352 | goto err_free_mem; | ||
353 | |||
354 | rev = CMA3000_READ(data, CMA3000_REVID, "Revid"); | ||
355 | if (rev < 0) { | ||
356 | error = rev; | ||
357 | goto err_free_mem; | ||
358 | } | ||
359 | |||
360 | pr_info("CMA3000 Accelerometer: Revision %x\n", rev); | ||
361 | |||
362 | error = request_threaded_irq(irq, NULL, cma3000_thread_irq, | ||
363 | pdata->irqflags | IRQF_ONESHOT, | ||
364 | "cma3000_d0x", data); | ||
365 | if (error) { | ||
366 | dev_err(dev, "request_threaded_irq failed\n"); | ||
367 | goto err_free_mem; | ||
368 | } | ||
369 | |||
370 | error = input_register_device(data->input_dev); | ||
371 | if (error) { | ||
372 | dev_err(dev, "Unable to register input device\n"); | ||
373 | goto err_free_irq; | ||
374 | } | ||
375 | |||
376 | return data; | ||
377 | |||
378 | err_free_irq: | ||
379 | free_irq(irq, data); | ||
380 | err_free_mem: | ||
381 | input_free_device(input_dev); | ||
382 | kfree(data); | ||
383 | err_out: | ||
384 | return ERR_PTR(error); | ||
385 | } | ||
386 | EXPORT_SYMBOL(cma3000_init); | ||
387 | |||
388 | void cma3000_exit(struct cma3000_accl_data *data) | ||
389 | { | ||
390 | free_irq(data->irq, data); | ||
391 | input_unregister_device(data->input_dev); | ||
392 | kfree(data); | ||
393 | } | ||
394 | EXPORT_SYMBOL(cma3000_exit); | ||
395 | |||
396 | MODULE_DESCRIPTION("CMA3000-D0x Accelerometer Driver"); | ||
397 | MODULE_LICENSE("GPL"); | ||
398 | MODULE_AUTHOR("Hemanth V <hemanthv@ti.com>"); | ||
diff --git a/drivers/input/misc/cma3000_d0x.h b/drivers/input/misc/cma3000_d0x.h new file mode 100644 index 000000000000..2304ce306e1c --- /dev/null +++ b/drivers/input/misc/cma3000_d0x.h | |||
@@ -0,0 +1,42 @@ | |||
1 | /* | ||
2 | * VTI CMA3000_D0x Accelerometer driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Texas Instruments | ||
5 | * Author: Hemanth V <hemanthv@ti.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published by | ||
9 | * the Free Software Foundation. | ||
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 with | ||
17 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #ifndef _INPUT_CMA3000_H | ||
21 | #define _INPUT_CMA3000_H | ||
22 | |||
23 | #include <linux/types.h> | ||
24 | #include <linux/input.h> | ||
25 | |||
26 | struct device; | ||
27 | struct cma3000_accl_data; | ||
28 | |||
29 | struct cma3000_bus_ops { | ||
30 | u16 bustype; | ||
31 | u8 ctrl_mod; | ||
32 | int (*read)(struct device *, u8, char *); | ||
33 | int (*write)(struct device *, u8, u8, char *); | ||
34 | }; | ||
35 | |||
36 | struct cma3000_accl_data *cma3000_init(struct device *dev, int irq, | ||
37 | const struct cma3000_bus_ops *bops); | ||
38 | void cma3000_exit(struct cma3000_accl_data *); | ||
39 | void cma3000_suspend(struct cma3000_accl_data *); | ||
40 | void cma3000_resume(struct cma3000_accl_data *); | ||
41 | |||
42 | #endif | ||
diff --git a/drivers/input/misc/cma3000_d0x_i2c.c b/drivers/input/misc/cma3000_d0x_i2c.c new file mode 100644 index 000000000000..d100cc5c5783 --- /dev/null +++ b/drivers/input/misc/cma3000_d0x_i2c.c | |||
@@ -0,0 +1,143 @@ | |||
1 | /* | ||
2 | * Implements I2C interface for VTI CMA300_D0x Accelerometer driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Texas Instruments | ||
5 | * Author: Hemanth V <hemanthv@ti.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published by | ||
9 | * the Free Software Foundation. | ||
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 with | ||
17 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #include <linux/module.h> | ||
21 | #include <linux/i2c.h> | ||
22 | #include <linux/input/cma3000.h> | ||
23 | #include "cma3000_d0x.h" | ||
24 | |||
25 | static int cma3000_i2c_set(struct device *dev, | ||
26 | u8 reg, u8 val, char *msg) | ||
27 | { | ||
28 | struct i2c_client *client = to_i2c_client(dev); | ||
29 | int ret; | ||
30 | |||
31 | ret = i2c_smbus_write_byte_data(client, reg, val); | ||
32 | if (ret < 0) | ||
33 | dev_err(&client->dev, | ||
34 | "%s failed (%s, %d)\n", __func__, msg, ret); | ||
35 | return ret; | ||
36 | } | ||
37 | |||
38 | static int cma3000_i2c_read(struct device *dev, u8 reg, char *msg) | ||
39 | { | ||
40 | struct i2c_client *client = to_i2c_client(dev); | ||
41 | int ret; | ||
42 | |||
43 | ret = i2c_smbus_read_byte_data(client, reg); | ||
44 | if (ret < 0) | ||
45 | dev_err(&client->dev, | ||
46 | "%s failed (%s, %d)\n", __func__, msg, ret); | ||
47 | return ret; | ||
48 | } | ||
49 | |||
50 | static const struct cma3000_bus_ops cma3000_i2c_bops = { | ||
51 | .bustype = BUS_I2C, | ||
52 | #define CMA3000_BUSI2C (0 << 4) | ||
53 | .ctrl_mod = CMA3000_BUSI2C, | ||
54 | .read = cma3000_i2c_read, | ||
55 | .write = cma3000_i2c_set, | ||
56 | }; | ||
57 | |||
58 | static int __devinit cma3000_i2c_probe(struct i2c_client *client, | ||
59 | const struct i2c_device_id *id) | ||
60 | { | ||
61 | struct cma3000_accl_data *data; | ||
62 | |||
63 | data = cma3000_init(&client->dev, client->irq, &cma3000_i2c_bops); | ||
64 | if (IS_ERR(data)) | ||
65 | return PTR_ERR(data); | ||
66 | |||
67 | i2c_set_clientdata(client, data); | ||
68 | |||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | static int __devexit cma3000_i2c_remove(struct i2c_client *client) | ||
73 | { | ||
74 | struct cma3000_accl_data *data = i2c_get_clientdata(client); | ||
75 | |||
76 | cma3000_exit(data); | ||
77 | |||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | #ifdef CONFIG_PM | ||
82 | static int cma3000_i2c_suspend(struct device *dev) | ||
83 | { | ||
84 | struct i2c_client *client = to_i2c_client(dev); | ||
85 | struct cma3000_accl_data *data = i2c_get_clientdata(client); | ||
86 | |||
87 | cma3000_suspend(data); | ||
88 | |||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | static int cma3000_i2c_resume(struct device *dev) | ||
93 | { | ||
94 | struct i2c_client *client = to_i2c_client(dev); | ||
95 | struct cma3000_accl_data *data = i2c_get_clientdata(client); | ||
96 | |||
97 | cma3000_resume(data); | ||
98 | |||
99 | return 0; | ||
100 | } | ||
101 | |||
102 | static const struct dev_pm_ops cma3000_i2c_pm_ops = { | ||
103 | .suspend = cma3000_i2c_suspend, | ||
104 | .resume = cma3000_i2c_resume, | ||
105 | }; | ||
106 | #endif | ||
107 | |||
108 | static const struct i2c_device_id cma3000_i2c_id[] = { | ||
109 | { "cma3000_d01", 0 }, | ||
110 | { }, | ||
111 | }; | ||
112 | |||
113 | MODULE_DEVICE_TABLE(i2c, cma3000_i2c_id); | ||
114 | |||
115 | static struct i2c_driver cma3000_i2c_driver = { | ||
116 | .probe = cma3000_i2c_probe, | ||
117 | .remove = __devexit_p(cma3000_i2c_remove), | ||
118 | .id_table = cma3000_i2c_id, | ||
119 | .driver = { | ||
120 | .name = "cma3000_i2c_accl", | ||
121 | .owner = THIS_MODULE, | ||
122 | #ifdef CONFIG_PM | ||
123 | .pm = &cma3000_i2c_pm_ops, | ||
124 | #endif | ||
125 | }, | ||
126 | }; | ||
127 | |||
128 | static int __init cma3000_i2c_init(void) | ||
129 | { | ||
130 | return i2c_add_driver(&cma3000_i2c_driver); | ||
131 | } | ||
132 | |||
133 | static void __exit cma3000_i2c_exit(void) | ||
134 | { | ||
135 | i2c_del_driver(&cma3000_i2c_driver); | ||
136 | } | ||
137 | |||
138 | module_init(cma3000_i2c_init); | ||
139 | module_exit(cma3000_i2c_exit); | ||
140 | |||
141 | MODULE_DESCRIPTION("CMA3000-D0x Accelerometer I2C Driver"); | ||
142 | MODULE_LICENSE("GPL"); | ||
143 | MODULE_AUTHOR("Hemanth V <hemanthv@ti.com>"); | ||
diff --git a/drivers/input/misc/pcf8574_keypad.c b/drivers/input/misc/pcf8574_keypad.c index d1583aea1721..08be1a355956 100644 --- a/drivers/input/misc/pcf8574_keypad.c +++ b/drivers/input/misc/pcf8574_keypad.c | |||
@@ -169,19 +169,29 @@ static int __devexit pcf8574_kp_remove(struct i2c_client *client) | |||
169 | } | 169 | } |
170 | 170 | ||
171 | #ifdef CONFIG_PM | 171 | #ifdef CONFIG_PM |
172 | static int pcf8574_kp_resume(struct i2c_client *client) | 172 | static int pcf8574_kp_resume(struct device *dev) |
173 | { | 173 | { |
174 | struct i2c_client *client = to_i2c_client(dev); | ||
175 | |||
174 | enable_irq(client->irq); | 176 | enable_irq(client->irq); |
175 | 177 | ||
176 | return 0; | 178 | return 0; |
177 | } | 179 | } |
178 | 180 | ||
179 | static int pcf8574_kp_suspend(struct i2c_client *client, pm_message_t mesg) | 181 | static int pcf8574_kp_suspend(struct device *dev) |
180 | { | 182 | { |
183 | struct i2c_client *client = to_i2c_client(dev); | ||
184 | |||
181 | disable_irq(client->irq); | 185 | disable_irq(client->irq); |
182 | 186 | ||
183 | return 0; | 187 | return 0; |
184 | } | 188 | } |
189 | |||
190 | static const struct dev_pm_ops pcf8574_kp_pm_ops = { | ||
191 | .suspend = pcf8574_kp_suspend, | ||
192 | .resume = pcf8574_kp_resume, | ||
193 | }; | ||
194 | |||
185 | #else | 195 | #else |
186 | # define pcf8574_kp_resume NULL | 196 | # define pcf8574_kp_resume NULL |
187 | # define pcf8574_kp_suspend NULL | 197 | # define pcf8574_kp_suspend NULL |
@@ -197,11 +207,12 @@ static struct i2c_driver pcf8574_kp_driver = { | |||
197 | .driver = { | 207 | .driver = { |
198 | .name = DRV_NAME, | 208 | .name = DRV_NAME, |
199 | .owner = THIS_MODULE, | 209 | .owner = THIS_MODULE, |
210 | #ifdef CONFIG_PM | ||
211 | .pm = &pcf8574_kp_pm_ops, | ||
212 | #endif | ||
200 | }, | 213 | }, |
201 | .probe = pcf8574_kp_probe, | 214 | .probe = pcf8574_kp_probe, |
202 | .remove = __devexit_p(pcf8574_kp_remove), | 215 | .remove = __devexit_p(pcf8574_kp_remove), |
203 | .suspend = pcf8574_kp_suspend, | ||
204 | .resume = pcf8574_kp_resume, | ||
205 | .id_table = pcf8574_kp_id, | 216 | .id_table = pcf8574_kp_id, |
206 | }; | 217 | }; |
207 | 218 | ||
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index b9410784e6a1..82542a1c1098 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/fs.h> | 37 | #include <linux/fs.h> |
38 | #include <linux/miscdevice.h> | 38 | #include <linux/miscdevice.h> |
39 | #include <linux/uinput.h> | 39 | #include <linux/uinput.h> |
40 | #include <linux/input/mt.h> | ||
40 | #include "../input-compat.h" | 41 | #include "../input-compat.h" |
41 | 42 | ||
42 | static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 43 | static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) |
@@ -406,8 +407,7 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu | |||
406 | goto exit; | 407 | goto exit; |
407 | if (test_bit(ABS_MT_SLOT, dev->absbit)) { | 408 | if (test_bit(ABS_MT_SLOT, dev->absbit)) { |
408 | int nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1; | 409 | int nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1; |
409 | input_mt_create_slots(dev, nslot); | 410 | input_mt_init_slots(dev, nslot); |
410 | input_set_events_per_packet(dev, 6 * nslot); | ||
411 | } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) { | 411 | } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) { |
412 | input_set_events_per_packet(dev, 60); | 412 | input_set_events_per_packet(dev, 60); |
413 | } | 413 | } |
@@ -680,6 +680,10 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd, | |||
680 | retval = uinput_set_bit(arg, swbit, SW_MAX); | 680 | retval = uinput_set_bit(arg, swbit, SW_MAX); |
681 | break; | 681 | break; |
682 | 682 | ||
683 | case UI_SET_PROPBIT: | ||
684 | retval = uinput_set_bit(arg, propbit, INPUT_PROP_MAX); | ||
685 | break; | ||
686 | |||
683 | case UI_SET_PHYS: | 687 | case UI_SET_PHYS: |
684 | if (udev->state == UIST_CREATED) { | 688 | if (udev->state == UIST_CREATED) { |
685 | retval = -EINVAL; | 689 | retval = -EINVAL; |
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c index 1d2205b24800..95577c15ae56 100644 --- a/drivers/input/mouse/hgpk.c +++ b/drivers/input/mouse/hgpk.c | |||
@@ -40,6 +40,8 @@ | |||
40 | #include "psmouse.h" | 40 | #include "psmouse.h" |
41 | #include "hgpk.h" | 41 | #include "hgpk.h" |
42 | 42 | ||
43 | #define ILLEGAL_XY 999999 | ||
44 | |||
43 | static bool tpdebug; | 45 | static bool tpdebug; |
44 | module_param(tpdebug, bool, 0644); | 46 | module_param(tpdebug, bool, 0644); |
45 | MODULE_PARM_DESC(tpdebug, "enable debugging, dumping packets to KERN_DEBUG."); | 47 | MODULE_PARM_DESC(tpdebug, "enable debugging, dumping packets to KERN_DEBUG."); |
@@ -47,48 +49,150 @@ MODULE_PARM_DESC(tpdebug, "enable debugging, dumping packets to KERN_DEBUG."); | |||
47 | static int recalib_delta = 100; | 49 | static int recalib_delta = 100; |
48 | module_param(recalib_delta, int, 0644); | 50 | module_param(recalib_delta, int, 0644); |
49 | MODULE_PARM_DESC(recalib_delta, | 51 | MODULE_PARM_DESC(recalib_delta, |
50 | "packets containing a delta this large will cause a recalibration."); | 52 | "packets containing a delta this large will be discarded, and a " |
53 | "recalibration may be scheduled."); | ||
51 | 54 | ||
52 | static int jumpy_delay = 1000; | 55 | static int jumpy_delay = 20; |
53 | module_param(jumpy_delay, int, 0644); | 56 | module_param(jumpy_delay, int, 0644); |
54 | MODULE_PARM_DESC(jumpy_delay, | 57 | MODULE_PARM_DESC(jumpy_delay, |
55 | "delay (ms) before recal after jumpiness detected"); | 58 | "delay (ms) before recal after jumpiness detected"); |
56 | 59 | ||
57 | static int spew_delay = 1000; | 60 | static int spew_delay = 1; |
58 | module_param(spew_delay, int, 0644); | 61 | module_param(spew_delay, int, 0644); |
59 | MODULE_PARM_DESC(spew_delay, | 62 | MODULE_PARM_DESC(spew_delay, |
60 | "delay (ms) before recal after packet spew detected"); | 63 | "delay (ms) before recal after packet spew detected"); |
61 | 64 | ||
62 | static int recal_guard_time = 2000; | 65 | static int recal_guard_time; |
63 | module_param(recal_guard_time, int, 0644); | 66 | module_param(recal_guard_time, int, 0644); |
64 | MODULE_PARM_DESC(recal_guard_time, | 67 | MODULE_PARM_DESC(recal_guard_time, |
65 | "interval (ms) during which recal will be restarted if packet received"); | 68 | "interval (ms) during which recal will be restarted if packet received"); |
66 | 69 | ||
67 | static int post_interrupt_delay = 1000; | 70 | static int post_interrupt_delay = 40; |
68 | module_param(post_interrupt_delay, int, 0644); | 71 | module_param(post_interrupt_delay, int, 0644); |
69 | MODULE_PARM_DESC(post_interrupt_delay, | 72 | MODULE_PARM_DESC(post_interrupt_delay, |
70 | "delay (ms) before recal after recal interrupt detected"); | 73 | "delay (ms) before recal after recal interrupt detected"); |
71 | 74 | ||
75 | static bool autorecal = true; | ||
76 | module_param(autorecal, bool, 0644); | ||
77 | MODULE_PARM_DESC(autorecal, "enable recalibration in the driver"); | ||
78 | |||
79 | static char hgpk_mode_name[16]; | ||
80 | module_param_string(hgpk_mode, hgpk_mode_name, sizeof(hgpk_mode_name), 0644); | ||
81 | MODULE_PARM_DESC(hgpk_mode, | ||
82 | "default hgpk mode: mouse, glidesensor or pentablet"); | ||
83 | |||
84 | static int hgpk_default_mode = HGPK_MODE_MOUSE; | ||
85 | |||
86 | static const char * const hgpk_mode_names[] = { | ||
87 | [HGPK_MODE_MOUSE] = "Mouse", | ||
88 | [HGPK_MODE_GLIDESENSOR] = "GlideSensor", | ||
89 | [HGPK_MODE_PENTABLET] = "PenTablet", | ||
90 | }; | ||
91 | |||
92 | static int hgpk_mode_from_name(const char *buf, int len) | ||
93 | { | ||
94 | int i; | ||
95 | |||
96 | for (i = 0; i < ARRAY_SIZE(hgpk_mode_names); i++) { | ||
97 | const char *name = hgpk_mode_names[i]; | ||
98 | if (strlen(name) == len && !strncasecmp(name, buf, len)) | ||
99 | return i; | ||
100 | } | ||
101 | |||
102 | return HGPK_MODE_INVALID; | ||
103 | } | ||
104 | |||
105 | /* | ||
106 | * see if new value is within 20% of half of old value | ||
107 | */ | ||
108 | static int approx_half(int curr, int prev) | ||
109 | { | ||
110 | int belowhalf, abovehalf; | ||
111 | |||
112 | if (curr < 5 || prev < 5) | ||
113 | return 0; | ||
114 | |||
115 | belowhalf = (prev * 8) / 20; | ||
116 | abovehalf = (prev * 12) / 20; | ||
117 | |||
118 | return belowhalf < curr && curr <= abovehalf; | ||
119 | } | ||
120 | |||
72 | /* | 121 | /* |
73 | * When the touchpad gets ultra-sensitive, one can keep their finger 1/2" | 122 | * Throw out oddly large delta packets, and any that immediately follow whose |
74 | * above the pad and still have it send packets. This causes a jump cursor | 123 | * values are each approximately half of the previous. It seems that the ALPS |
75 | * when one places their finger on the pad. We can probably detect the | 124 | * firmware emits errant packets, and they get averaged out slowly. |
76 | * jump as we see a large deltas (>= 100px). In mouse mode, I've been | ||
77 | * unable to even come close to 100px deltas during normal usage, so I think | ||
78 | * this threshold is safe. If a large delta occurs, trigger a recalibration. | ||
79 | */ | 125 | */ |
80 | static void hgpk_jumpy_hack(struct psmouse *psmouse, int x, int y) | 126 | static int hgpk_discard_decay_hack(struct psmouse *psmouse, int x, int y) |
81 | { | 127 | { |
82 | struct hgpk_data *priv = psmouse->private; | 128 | struct hgpk_data *priv = psmouse->private; |
129 | int avx, avy; | ||
130 | bool do_recal = false; | ||
131 | |||
132 | avx = abs(x); | ||
133 | avy = abs(y); | ||
134 | |||
135 | /* discard if too big, or half that but > 4 times the prev delta */ | ||
136 | if (avx > recalib_delta || | ||
137 | (avx > recalib_delta / 2 && ((avx / 4) > priv->xlast))) { | ||
138 | hgpk_err(psmouse, "detected %dpx jump in x\n", x); | ||
139 | priv->xbigj = avx; | ||
140 | } else if (approx_half(avx, priv->xbigj)) { | ||
141 | hgpk_err(psmouse, "detected secondary %dpx jump in x\n", x); | ||
142 | priv->xbigj = avx; | ||
143 | priv->xsaw_secondary++; | ||
144 | } else { | ||
145 | if (priv->xbigj && priv->xsaw_secondary > 1) | ||
146 | do_recal = true; | ||
147 | priv->xbigj = 0; | ||
148 | priv->xsaw_secondary = 0; | ||
149 | } | ||
150 | |||
151 | if (avy > recalib_delta || | ||
152 | (avy > recalib_delta / 2 && ((avy / 4) > priv->ylast))) { | ||
153 | hgpk_err(psmouse, "detected %dpx jump in y\n", y); | ||
154 | priv->ybigj = avy; | ||
155 | } else if (approx_half(avy, priv->ybigj)) { | ||
156 | hgpk_err(psmouse, "detected secondary %dpx jump in y\n", y); | ||
157 | priv->ybigj = avy; | ||
158 | priv->ysaw_secondary++; | ||
159 | } else { | ||
160 | if (priv->ybigj && priv->ysaw_secondary > 1) | ||
161 | do_recal = true; | ||
162 | priv->ybigj = 0; | ||
163 | priv->ysaw_secondary = 0; | ||
164 | } | ||
83 | 165 | ||
84 | if (abs(x) > recalib_delta || abs(y) > recalib_delta) { | 166 | priv->xlast = avx; |
85 | hgpk_err(psmouse, ">%dpx jump detected (%d,%d)\n", | 167 | priv->ylast = avy; |
86 | recalib_delta, x, y); | 168 | |
87 | /* My car gets forty rods to the hogshead and that's the | 169 | if (do_recal && jumpy_delay) { |
88 | * way I likes it! */ | 170 | hgpk_err(psmouse, "scheduling recalibration\n"); |
89 | psmouse_queue_work(psmouse, &priv->recalib_wq, | 171 | psmouse_queue_work(psmouse, &priv->recalib_wq, |
90 | msecs_to_jiffies(jumpy_delay)); | 172 | msecs_to_jiffies(jumpy_delay)); |
91 | } | 173 | } |
174 | |||
175 | return priv->xbigj || priv->ybigj; | ||
176 | } | ||
177 | |||
178 | static void hgpk_reset_spew_detection(struct hgpk_data *priv) | ||
179 | { | ||
180 | priv->spew_count = 0; | ||
181 | priv->dupe_count = 0; | ||
182 | priv->x_tally = 0; | ||
183 | priv->y_tally = 0; | ||
184 | priv->spew_flag = NO_SPEW; | ||
185 | } | ||
186 | |||
187 | static void hgpk_reset_hack_state(struct psmouse *psmouse) | ||
188 | { | ||
189 | struct hgpk_data *priv = psmouse->private; | ||
190 | |||
191 | priv->abs_x = priv->abs_y = -1; | ||
192 | priv->xlast = priv->ylast = ILLEGAL_XY; | ||
193 | priv->xbigj = priv->ybigj = 0; | ||
194 | priv->xsaw_secondary = priv->ysaw_secondary = 0; | ||
195 | hgpk_reset_spew_detection(priv); | ||
92 | } | 196 | } |
93 | 197 | ||
94 | /* | 198 | /* |
@@ -116,20 +220,57 @@ static void hgpk_spewing_hack(struct psmouse *psmouse, | |||
116 | if (l || r) | 220 | if (l || r) |
117 | return; | 221 | return; |
118 | 222 | ||
223 | /* don't track spew if the workaround feature has been turned off */ | ||
224 | if (!spew_delay) | ||
225 | return; | ||
226 | |||
227 | if (abs(x) > 3 || abs(y) > 3) { | ||
228 | /* no spew, or spew ended */ | ||
229 | hgpk_reset_spew_detection(priv); | ||
230 | return; | ||
231 | } | ||
232 | |||
233 | /* Keep a tally of the overall delta to the cursor position caused by | ||
234 | * the spew */ | ||
119 | priv->x_tally += x; | 235 | priv->x_tally += x; |
120 | priv->y_tally += y; | 236 | priv->y_tally += y; |
121 | 237 | ||
122 | if (++priv->count > 100) { | 238 | switch (priv->spew_flag) { |
239 | case NO_SPEW: | ||
240 | /* we're not spewing, but this packet might be the start */ | ||
241 | priv->spew_flag = MAYBE_SPEWING; | ||
242 | |||
243 | /* fall-through */ | ||
244 | |||
245 | case MAYBE_SPEWING: | ||
246 | priv->spew_count++; | ||
247 | |||
248 | if (priv->spew_count < SPEW_WATCH_COUNT) | ||
249 | break; | ||
250 | |||
251 | /* excessive spew detected, request recalibration */ | ||
252 | priv->spew_flag = SPEW_DETECTED; | ||
253 | |||
254 | /* fall-through */ | ||
255 | |||
256 | case SPEW_DETECTED: | ||
257 | /* only recalibrate when the overall delta to the cursor | ||
258 | * is really small. if the spew is causing significant cursor | ||
259 | * movement, it is probably a case of the user moving the | ||
260 | * cursor very slowly across the screen. */ | ||
123 | if (abs(priv->x_tally) < 3 && abs(priv->y_tally) < 3) { | 261 | if (abs(priv->x_tally) < 3 && abs(priv->y_tally) < 3) { |
124 | hgpk_dbg(psmouse, "packet spew detected (%d,%d)\n", | 262 | hgpk_err(psmouse, "packet spew detected (%d,%d)\n", |
125 | priv->x_tally, priv->y_tally); | 263 | priv->x_tally, priv->y_tally); |
264 | priv->spew_flag = RECALIBRATING; | ||
126 | psmouse_queue_work(psmouse, &priv->recalib_wq, | 265 | psmouse_queue_work(psmouse, &priv->recalib_wq, |
127 | msecs_to_jiffies(spew_delay)); | 266 | msecs_to_jiffies(spew_delay)); |
128 | } | 267 | } |
129 | /* reset every 100 packets */ | 268 | |
130 | priv->count = 0; | 269 | break; |
131 | priv->x_tally = 0; | 270 | case RECALIBRATING: |
132 | priv->y_tally = 0; | 271 | /* we already detected a spew and requested a recalibration, |
272 | * just wait for the queue to kick into action. */ | ||
273 | break; | ||
133 | } | 274 | } |
134 | } | 275 | } |
135 | 276 | ||
@@ -143,25 +284,168 @@ static void hgpk_spewing_hack(struct psmouse *psmouse, | |||
143 | * swr/swl are the left/right buttons. | 284 | * swr/swl are the left/right buttons. |
144 | * x-neg/y-neg are the x and y delta negative bits | 285 | * x-neg/y-neg are the x and y delta negative bits |
145 | * x-over/y-over are the x and y overflow bits | 286 | * x-over/y-over are the x and y overflow bits |
287 | * | ||
288 | * --- | ||
289 | * | ||
290 | * HGPK Advanced Mode - single-mode format | ||
291 | * | ||
292 | * byte 0(PT): 1 1 0 0 1 1 1 1 | ||
293 | * byte 0(GS): 1 1 1 1 1 1 1 1 | ||
294 | * byte 1: 0 x6 x5 x4 x3 x2 x1 x0 | ||
295 | * byte 2(PT): 0 0 x9 x8 x7 ? pt-dsw 0 | ||
296 | * byte 2(GS): 0 x10 x9 x8 x7 ? gs-dsw pt-dsw | ||
297 | * byte 3: 0 y9 y8 y7 1 0 swr swl | ||
298 | * byte 4: 0 y6 y5 y4 y3 y2 y1 y0 | ||
299 | * byte 5: 0 z6 z5 z4 z3 z2 z1 z0 | ||
300 | * | ||
301 | * ?'s are not defined in the protocol spec, may vary between models. | ||
302 | * | ||
303 | * swr/swl are the left/right buttons. | ||
304 | * | ||
305 | * pt-dsw/gs-dsw indicate that the pt/gs sensor is detecting a | ||
306 | * pen/finger | ||
146 | */ | 307 | */ |
147 | static int hgpk_validate_byte(unsigned char *packet) | 308 | static bool hgpk_is_byte_valid(struct psmouse *psmouse, unsigned char *packet) |
148 | { | 309 | { |
149 | return (packet[0] & 0x0C) != 0x08; | 310 | struct hgpk_data *priv = psmouse->private; |
311 | int pktcnt = psmouse->pktcnt; | ||
312 | bool valid; | ||
313 | |||
314 | switch (priv->mode) { | ||
315 | case HGPK_MODE_MOUSE: | ||
316 | valid = (packet[0] & 0x0C) == 0x08; | ||
317 | break; | ||
318 | |||
319 | case HGPK_MODE_GLIDESENSOR: | ||
320 | valid = pktcnt == 1 ? | ||
321 | packet[0] == HGPK_GS : !(packet[pktcnt - 1] & 0x80); | ||
322 | break; | ||
323 | |||
324 | case HGPK_MODE_PENTABLET: | ||
325 | valid = pktcnt == 1 ? | ||
326 | packet[0] == HGPK_PT : !(packet[pktcnt - 1] & 0x80); | ||
327 | break; | ||
328 | |||
329 | default: | ||
330 | valid = false; | ||
331 | break; | ||
332 | } | ||
333 | |||
334 | if (!valid) | ||
335 | hgpk_dbg(psmouse, | ||
336 | "bad data, mode %d (%d) %02x %02x %02x %02x %02x %02x\n", | ||
337 | priv->mode, pktcnt, | ||
338 | psmouse->packet[0], psmouse->packet[1], | ||
339 | psmouse->packet[2], psmouse->packet[3], | ||
340 | psmouse->packet[4], psmouse->packet[5]); | ||
341 | |||
342 | return valid; | ||
150 | } | 343 | } |
151 | 344 | ||
152 | static void hgpk_process_packet(struct psmouse *psmouse) | 345 | static void hgpk_process_advanced_packet(struct psmouse *psmouse) |
153 | { | 346 | { |
154 | struct input_dev *dev = psmouse->dev; | 347 | struct hgpk_data *priv = psmouse->private; |
348 | struct input_dev *idev = psmouse->dev; | ||
155 | unsigned char *packet = psmouse->packet; | 349 | unsigned char *packet = psmouse->packet; |
156 | int x, y, left, right; | 350 | int down = !!(packet[2] & 2); |
351 | int left = !!(packet[3] & 1); | ||
352 | int right = !!(packet[3] & 2); | ||
353 | int x = packet[1] | ((packet[2] & 0x78) << 4); | ||
354 | int y = packet[4] | ((packet[3] & 0x70) << 3); | ||
355 | |||
356 | if (priv->mode == HGPK_MODE_GLIDESENSOR) { | ||
357 | int pt_down = !!(packet[2] & 1); | ||
358 | int finger_down = !!(packet[2] & 2); | ||
359 | int z = packet[5]; | ||
360 | |||
361 | input_report_abs(idev, ABS_PRESSURE, z); | ||
362 | if (tpdebug) | ||
363 | hgpk_dbg(psmouse, "pd=%d fd=%d z=%d", | ||
364 | pt_down, finger_down, z); | ||
365 | } else { | ||
366 | /* | ||
367 | * PenTablet mode does not report pressure, so we don't | ||
368 | * report it here | ||
369 | */ | ||
370 | if (tpdebug) | ||
371 | hgpk_dbg(psmouse, "pd=%d ", down); | ||
372 | } | ||
373 | |||
374 | if (tpdebug) | ||
375 | hgpk_dbg(psmouse, "l=%d r=%d x=%d y=%d\n", left, right, x, y); | ||
376 | |||
377 | input_report_key(idev, BTN_TOUCH, down); | ||
378 | input_report_key(idev, BTN_LEFT, left); | ||
379 | input_report_key(idev, BTN_RIGHT, right); | ||
380 | |||
381 | /* | ||
382 | * If this packet says that the finger was removed, reset our position | ||
383 | * tracking so that we don't erroneously detect a jump on next press. | ||
384 | */ | ||
385 | if (!down) { | ||
386 | hgpk_reset_hack_state(psmouse); | ||
387 | goto done; | ||
388 | } | ||
389 | |||
390 | /* | ||
391 | * Weed out duplicate packets (we get quite a few, and they mess up | ||
392 | * our jump detection) | ||
393 | */ | ||
394 | if (x == priv->abs_x && y == priv->abs_y) { | ||
395 | if (++priv->dupe_count > SPEW_WATCH_COUNT) { | ||
396 | if (tpdebug) | ||
397 | hgpk_dbg(psmouse, "hard spew detected\n"); | ||
398 | priv->spew_flag = RECALIBRATING; | ||
399 | psmouse_queue_work(psmouse, &priv->recalib_wq, | ||
400 | msecs_to_jiffies(spew_delay)); | ||
401 | } | ||
402 | goto done; | ||
403 | } | ||
157 | 404 | ||
158 | left = packet[0] & 1; | 405 | /* not a duplicate, continue with position reporting */ |
159 | right = (packet[0] >> 1) & 1; | 406 | priv->dupe_count = 0; |
407 | |||
408 | /* Don't apply hacks in PT mode, it seems reliable */ | ||
409 | if (priv->mode != HGPK_MODE_PENTABLET && priv->abs_x != -1) { | ||
410 | int x_diff = priv->abs_x - x; | ||
411 | int y_diff = priv->abs_y - y; | ||
412 | if (hgpk_discard_decay_hack(psmouse, x_diff, y_diff)) { | ||
413 | if (tpdebug) | ||
414 | hgpk_dbg(psmouse, "discarding\n"); | ||
415 | goto done; | ||
416 | } | ||
417 | hgpk_spewing_hack(psmouse, left, right, x_diff, y_diff); | ||
418 | } | ||
160 | 419 | ||
161 | x = packet[1] - ((packet[0] << 4) & 0x100); | 420 | input_report_abs(idev, ABS_X, x); |
162 | y = ((packet[0] << 3) & 0x100) - packet[2]; | 421 | input_report_abs(idev, ABS_Y, y); |
422 | priv->abs_x = x; | ||
423 | priv->abs_y = y; | ||
424 | |||
425 | done: | ||
426 | input_sync(idev); | ||
427 | } | ||
428 | |||
429 | static void hgpk_process_simple_packet(struct psmouse *psmouse) | ||
430 | { | ||
431 | struct input_dev *dev = psmouse->dev; | ||
432 | unsigned char *packet = psmouse->packet; | ||
433 | int left = packet[0] & 1; | ||
434 | int right = (packet[0] >> 1) & 1; | ||
435 | int x = packet[1] - ((packet[0] << 4) & 0x100); | ||
436 | int y = ((packet[0] << 3) & 0x100) - packet[2]; | ||
437 | |||
438 | if (packet[0] & 0xc0) | ||
439 | hgpk_dbg(psmouse, | ||
440 | "overflow -- 0x%02x 0x%02x 0x%02x\n", | ||
441 | packet[0], packet[1], packet[2]); | ||
442 | |||
443 | if (hgpk_discard_decay_hack(psmouse, x, y)) { | ||
444 | if (tpdebug) | ||
445 | hgpk_dbg(psmouse, "discarding\n"); | ||
446 | return; | ||
447 | } | ||
163 | 448 | ||
164 | hgpk_jumpy_hack(psmouse, x, y); | ||
165 | hgpk_spewing_hack(psmouse, left, right, x, y); | 449 | hgpk_spewing_hack(psmouse, left, right, x, y); |
166 | 450 | ||
167 | if (tpdebug) | 451 | if (tpdebug) |
@@ -180,15 +464,14 @@ static psmouse_ret_t hgpk_process_byte(struct psmouse *psmouse) | |||
180 | { | 464 | { |
181 | struct hgpk_data *priv = psmouse->private; | 465 | struct hgpk_data *priv = psmouse->private; |
182 | 466 | ||
183 | if (hgpk_validate_byte(psmouse->packet)) { | 467 | if (!hgpk_is_byte_valid(psmouse, psmouse->packet)) |
184 | hgpk_dbg(psmouse, "%s: (%d) %02x %02x %02x\n", | ||
185 | __func__, psmouse->pktcnt, psmouse->packet[0], | ||
186 | psmouse->packet[1], psmouse->packet[2]); | ||
187 | return PSMOUSE_BAD_DATA; | 468 | return PSMOUSE_BAD_DATA; |
188 | } | ||
189 | 469 | ||
190 | if (psmouse->pktcnt >= psmouse->pktsize) { | 470 | if (psmouse->pktcnt >= psmouse->pktsize) { |
191 | hgpk_process_packet(psmouse); | 471 | if (priv->mode == HGPK_MODE_MOUSE) |
472 | hgpk_process_simple_packet(psmouse); | ||
473 | else | ||
474 | hgpk_process_advanced_packet(psmouse); | ||
192 | return PSMOUSE_FULL_PACKET; | 475 | return PSMOUSE_FULL_PACKET; |
193 | } | 476 | } |
194 | 477 | ||
@@ -210,33 +493,176 @@ static psmouse_ret_t hgpk_process_byte(struct psmouse *psmouse) | |||
210 | return PSMOUSE_GOOD_DATA; | 493 | return PSMOUSE_GOOD_DATA; |
211 | } | 494 | } |
212 | 495 | ||
496 | static int hgpk_select_mode(struct psmouse *psmouse) | ||
497 | { | ||
498 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
499 | struct hgpk_data *priv = psmouse->private; | ||
500 | int i; | ||
501 | int cmd; | ||
502 | |||
503 | /* | ||
504 | * 4 disables to enable advanced mode | ||
505 | * then 3 0xf2 bytes as the preamble for GS/PT selection | ||
506 | */ | ||
507 | const int advanced_init[] = { | ||
508 | PSMOUSE_CMD_DISABLE, PSMOUSE_CMD_DISABLE, | ||
509 | PSMOUSE_CMD_DISABLE, PSMOUSE_CMD_DISABLE, | ||
510 | 0xf2, 0xf2, 0xf2, | ||
511 | }; | ||
512 | |||
513 | switch (priv->mode) { | ||
514 | case HGPK_MODE_MOUSE: | ||
515 | psmouse->pktsize = 3; | ||
516 | break; | ||
517 | |||
518 | case HGPK_MODE_GLIDESENSOR: | ||
519 | case HGPK_MODE_PENTABLET: | ||
520 | psmouse->pktsize = 6; | ||
521 | |||
522 | /* Switch to 'Advanced mode.', four disables in a row. */ | ||
523 | for (i = 0; i < ARRAY_SIZE(advanced_init); i++) | ||
524 | if (ps2_command(ps2dev, NULL, advanced_init[i])) | ||
525 | return -EIO; | ||
526 | |||
527 | /* select between GlideSensor (mouse) or PenTablet */ | ||
528 | cmd = priv->mode == HGPK_MODE_GLIDESENSOR ? | ||
529 | PSMOUSE_CMD_SETSCALE11 : PSMOUSE_CMD_SETSCALE21; | ||
530 | |||
531 | if (ps2_command(ps2dev, NULL, cmd)) | ||
532 | return -EIO; | ||
533 | break; | ||
534 | |||
535 | default: | ||
536 | return -EINVAL; | ||
537 | } | ||
538 | |||
539 | return 0; | ||
540 | } | ||
541 | |||
542 | static void hgpk_setup_input_device(struct input_dev *input, | ||
543 | struct input_dev *old_input, | ||
544 | enum hgpk_mode mode) | ||
545 | { | ||
546 | if (old_input) { | ||
547 | input->name = old_input->name; | ||
548 | input->phys = old_input->phys; | ||
549 | input->id = old_input->id; | ||
550 | input->dev.parent = old_input->dev.parent; | ||
551 | } | ||
552 | |||
553 | memset(input->evbit, 0, sizeof(input->evbit)); | ||
554 | memset(input->relbit, 0, sizeof(input->relbit)); | ||
555 | memset(input->keybit, 0, sizeof(input->keybit)); | ||
556 | |||
557 | /* All modes report left and right buttons */ | ||
558 | __set_bit(EV_KEY, input->evbit); | ||
559 | __set_bit(BTN_LEFT, input->keybit); | ||
560 | __set_bit(BTN_RIGHT, input->keybit); | ||
561 | |||
562 | switch (mode) { | ||
563 | case HGPK_MODE_MOUSE: | ||
564 | __set_bit(EV_REL, input->evbit); | ||
565 | __set_bit(REL_X, input->relbit); | ||
566 | __set_bit(REL_Y, input->relbit); | ||
567 | break; | ||
568 | |||
569 | case HGPK_MODE_GLIDESENSOR: | ||
570 | __set_bit(BTN_TOUCH, input->keybit); | ||
571 | __set_bit(BTN_TOOL_FINGER, input->keybit); | ||
572 | |||
573 | __set_bit(EV_ABS, input->evbit); | ||
574 | |||
575 | /* GlideSensor has pressure sensor, PenTablet does not */ | ||
576 | input_set_abs_params(input, ABS_PRESSURE, 0, 15, 0, 0); | ||
577 | |||
578 | /* From device specs */ | ||
579 | input_set_abs_params(input, ABS_X, 0, 399, 0, 0); | ||
580 | input_set_abs_params(input, ABS_Y, 0, 290, 0, 0); | ||
581 | |||
582 | /* Calculated by hand based on usable size (52mm x 38mm) */ | ||
583 | input_abs_set_res(input, ABS_X, 8); | ||
584 | input_abs_set_res(input, ABS_Y, 8); | ||
585 | break; | ||
586 | |||
587 | case HGPK_MODE_PENTABLET: | ||
588 | __set_bit(BTN_TOUCH, input->keybit); | ||
589 | __set_bit(BTN_TOOL_FINGER, input->keybit); | ||
590 | |||
591 | __set_bit(EV_ABS, input->evbit); | ||
592 | |||
593 | /* From device specs */ | ||
594 | input_set_abs_params(input, ABS_X, 0, 999, 0, 0); | ||
595 | input_set_abs_params(input, ABS_Y, 5, 239, 0, 0); | ||
596 | |||
597 | /* Calculated by hand based on usable size (156mm x 38mm) */ | ||
598 | input_abs_set_res(input, ABS_X, 6); | ||
599 | input_abs_set_res(input, ABS_Y, 8); | ||
600 | break; | ||
601 | |||
602 | default: | ||
603 | BUG(); | ||
604 | } | ||
605 | } | ||
606 | |||
607 | static int hgpk_reset_device(struct psmouse *psmouse, bool recalibrate) | ||
608 | { | ||
609 | int err; | ||
610 | |||
611 | psmouse_reset(psmouse); | ||
612 | |||
613 | if (recalibrate) { | ||
614 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
615 | |||
616 | /* send the recalibrate request */ | ||
617 | if (ps2_command(ps2dev, NULL, 0xf5) || | ||
618 | ps2_command(ps2dev, NULL, 0xf5) || | ||
619 | ps2_command(ps2dev, NULL, 0xe6) || | ||
620 | ps2_command(ps2dev, NULL, 0xf5)) { | ||
621 | return -1; | ||
622 | } | ||
623 | |||
624 | /* according to ALPS, 150mS is required for recalibration */ | ||
625 | msleep(150); | ||
626 | } | ||
627 | |||
628 | err = hgpk_select_mode(psmouse); | ||
629 | if (err) { | ||
630 | hgpk_err(psmouse, "failed to select mode\n"); | ||
631 | return err; | ||
632 | } | ||
633 | |||
634 | hgpk_reset_hack_state(psmouse); | ||
635 | |||
636 | return 0; | ||
637 | } | ||
638 | |||
213 | static int hgpk_force_recalibrate(struct psmouse *psmouse) | 639 | static int hgpk_force_recalibrate(struct psmouse *psmouse) |
214 | { | 640 | { |
215 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 641 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
216 | struct hgpk_data *priv = psmouse->private; | 642 | struct hgpk_data *priv = psmouse->private; |
643 | int err; | ||
217 | 644 | ||
218 | /* C-series touchpads added the recalibrate command */ | 645 | /* C-series touchpads added the recalibrate command */ |
219 | if (psmouse->model < HGPK_MODEL_C) | 646 | if (psmouse->model < HGPK_MODEL_C) |
220 | return 0; | 647 | return 0; |
221 | 648 | ||
649 | if (!autorecal) { | ||
650 | hgpk_dbg(psmouse, "recalibrations disabled, ignoring\n"); | ||
651 | return 0; | ||
652 | } | ||
653 | |||
654 | hgpk_dbg(psmouse, "recalibrating touchpad..\n"); | ||
655 | |||
222 | /* we don't want to race with the irq handler, nor with resyncs */ | 656 | /* we don't want to race with the irq handler, nor with resyncs */ |
223 | psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); | 657 | psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); |
224 | 658 | ||
225 | /* start by resetting the device */ | 659 | /* start by resetting the device */ |
226 | psmouse_reset(psmouse); | 660 | err = hgpk_reset_device(psmouse, true); |
227 | 661 | if (err) | |
228 | /* send the recalibrate request */ | 662 | return err; |
229 | if (ps2_command(ps2dev, NULL, 0xf5) || | ||
230 | ps2_command(ps2dev, NULL, 0xf5) || | ||
231 | ps2_command(ps2dev, NULL, 0xe6) || | ||
232 | ps2_command(ps2dev, NULL, 0xf5)) { | ||
233 | return -1; | ||
234 | } | ||
235 | |||
236 | /* according to ALPS, 150mS is required for recalibration */ | ||
237 | msleep(150); | ||
238 | 663 | ||
239 | /* XXX: If a finger is down during this delay, recalibration will | 664 | /* |
665 | * XXX: If a finger is down during this delay, recalibration will | ||
240 | * detect capacitance incorrectly. This is a hardware bug, and | 666 | * detect capacitance incorrectly. This is a hardware bug, and |
241 | * we don't have a good way to deal with it. The 2s window stuff | 667 | * we don't have a good way to deal with it. The 2s window stuff |
242 | * (below) is our best option for now. | 668 | * (below) is our best option for now. |
@@ -247,25 +673,35 @@ static int hgpk_force_recalibrate(struct psmouse *psmouse) | |||
247 | 673 | ||
248 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); | 674 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); |
249 | 675 | ||
250 | /* After we recalibrate, we shouldn't get any packets for 2s. If | 676 | if (tpdebug) |
251 | * we do, it's likely that someone's finger was on the touchpad. | 677 | hgpk_dbg(psmouse, "touchpad reactivated\n"); |
252 | * If someone's finger *was* on the touchpad, it's probably | 678 | |
253 | * miscalibrated. So, we should schedule another recalibration | 679 | /* |
680 | * If we get packets right away after recalibrating, it's likely | ||
681 | * that a finger was on the touchpad. If so, it's probably | ||
682 | * miscalibrated, so we optionally schedule another. | ||
254 | */ | 683 | */ |
255 | priv->recalib_window = jiffies + msecs_to_jiffies(recal_guard_time); | 684 | if (recal_guard_time) |
685 | priv->recalib_window = jiffies + | ||
686 | msecs_to_jiffies(recal_guard_time); | ||
256 | 687 | ||
257 | return 0; | 688 | return 0; |
258 | } | 689 | } |
259 | 690 | ||
260 | /* | 691 | /* |
261 | * This kills power to the touchpad; according to ALPS, current consumption | 692 | * This puts the touchpad in a power saving mode; according to ALPS, current |
262 | * goes down to 50uA after running this. To turn power back on, we drive | 693 | * consumption goes down to 50uA after running this. To turn power back on, |
263 | * MS-DAT low. | 694 | * we drive MS-DAT low. Measuring with a 1mA resolution ammeter says that |
695 | * the current on the SUS_3.3V rail drops from 3mA or 4mA to 0 when we do this. | ||
696 | * | ||
697 | * We have no formal spec that details this operation -- the low-power | ||
698 | * sequence came from a long-lost email trail. | ||
264 | */ | 699 | */ |
265 | static int hgpk_toggle_power(struct psmouse *psmouse, int enable) | 700 | static int hgpk_toggle_powersave(struct psmouse *psmouse, int enable) |
266 | { | 701 | { |
267 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 702 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
268 | int timeo; | 703 | int timeo; |
704 | int err; | ||
269 | 705 | ||
270 | /* Added on D-series touchpads */ | 706 | /* Added on D-series touchpads */ |
271 | if (psmouse->model < HGPK_MODEL_D) | 707 | if (psmouse->model < HGPK_MODEL_D) |
@@ -279,24 +715,27 @@ static int hgpk_toggle_power(struct psmouse *psmouse, int enable) | |||
279 | * the controller. Once we get an ACK back from it, it | 715 | * the controller. Once we get an ACK back from it, it |
280 | * means we can continue with the touchpad re-init. ALPS | 716 | * means we can continue with the touchpad re-init. ALPS |
281 | * tells us that 1s should be long enough, so set that as | 717 | * tells us that 1s should be long enough, so set that as |
282 | * the upper bound. | 718 | * the upper bound. (in practice, it takes about 3 loops.) |
283 | */ | 719 | */ |
284 | for (timeo = 20; timeo > 0; timeo--) { | 720 | for (timeo = 20; timeo > 0; timeo--) { |
285 | if (!ps2_sendbyte(&psmouse->ps2dev, | 721 | if (!ps2_sendbyte(&psmouse->ps2dev, |
286 | PSMOUSE_CMD_DISABLE, 20)) | 722 | PSMOUSE_CMD_DISABLE, 20)) |
287 | break; | 723 | break; |
288 | msleep(50); | 724 | msleep(25); |
289 | } | 725 | } |
290 | 726 | ||
291 | psmouse_reset(psmouse); | 727 | err = hgpk_reset_device(psmouse, false); |
728 | if (err) { | ||
729 | hgpk_err(psmouse, "Failed to reset device!\n"); | ||
730 | return err; | ||
731 | } | ||
292 | 732 | ||
293 | /* should be all set, enable the touchpad */ | 733 | /* should be all set, enable the touchpad */ |
294 | ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE); | 734 | ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE); |
295 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); | 735 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); |
296 | 736 | hgpk_dbg(psmouse, "Touchpad powered up.\n"); | |
297 | } else { | 737 | } else { |
298 | hgpk_dbg(psmouse, "Powering off touchpad.\n"); | 738 | hgpk_dbg(psmouse, "Powering off touchpad.\n"); |
299 | psmouse_set_state(psmouse, PSMOUSE_IGNORE); | ||
300 | 739 | ||
301 | if (ps2_command(ps2dev, NULL, 0xec) || | 740 | if (ps2_command(ps2dev, NULL, 0xec) || |
302 | ps2_command(ps2dev, NULL, 0xec) || | 741 | ps2_command(ps2dev, NULL, 0xec) || |
@@ -304,6 +743,8 @@ static int hgpk_toggle_power(struct psmouse *psmouse, int enable) | |||
304 | return -1; | 743 | return -1; |
305 | } | 744 | } |
306 | 745 | ||
746 | psmouse_set_state(psmouse, PSMOUSE_IGNORE); | ||
747 | |||
307 | /* probably won't see an ACK, the touchpad will be off */ | 748 | /* probably won't see an ACK, the touchpad will be off */ |
308 | ps2_sendbyte(&psmouse->ps2dev, 0xec, 20); | 749 | ps2_sendbyte(&psmouse->ps2dev, 0xec, 20); |
309 | } | 750 | } |
@@ -319,17 +760,20 @@ static int hgpk_poll(struct psmouse *psmouse) | |||
319 | 760 | ||
320 | static int hgpk_reconnect(struct psmouse *psmouse) | 761 | static int hgpk_reconnect(struct psmouse *psmouse) |
321 | { | 762 | { |
322 | /* During suspend/resume the ps2 rails remain powered. We don't want | 763 | struct hgpk_data *priv = psmouse->private; |
764 | |||
765 | /* | ||
766 | * During suspend/resume the ps2 rails remain powered. We don't want | ||
323 | * to do a reset because it's flush data out of buffers; however, | 767 | * to do a reset because it's flush data out of buffers; however, |
324 | * earlier prototypes (B1) had some brokenness that required a reset. */ | 768 | * earlier prototypes (B1) had some brokenness that required a reset. |
769 | */ | ||
325 | if (olpc_board_at_least(olpc_board(0xb2))) | 770 | if (olpc_board_at_least(olpc_board(0xb2))) |
326 | if (psmouse->ps2dev.serio->dev.power.power_state.event != | 771 | if (psmouse->ps2dev.serio->dev.power.power_state.event != |
327 | PM_EVENT_ON) | 772 | PM_EVENT_ON) |
328 | return 0; | 773 | return 0; |
329 | 774 | ||
330 | psmouse_reset(psmouse); | 775 | priv->powered = 1; |
331 | 776 | return hgpk_reset_device(psmouse, false); | |
332 | return 0; | ||
333 | } | 777 | } |
334 | 778 | ||
335 | static ssize_t hgpk_show_powered(struct psmouse *psmouse, void *data, char *buf) | 779 | static ssize_t hgpk_show_powered(struct psmouse *psmouse, void *data, char *buf) |
@@ -355,7 +799,7 @@ static ssize_t hgpk_set_powered(struct psmouse *psmouse, void *data, | |||
355 | * hgpk_toggle_power will deal w/ state so | 799 | * hgpk_toggle_power will deal w/ state so |
356 | * we're not racing w/ irq | 800 | * we're not racing w/ irq |
357 | */ | 801 | */ |
358 | err = hgpk_toggle_power(psmouse, value); | 802 | err = hgpk_toggle_powersave(psmouse, value); |
359 | if (!err) | 803 | if (!err) |
360 | priv->powered = value; | 804 | priv->powered = value; |
361 | } | 805 | } |
@@ -366,6 +810,65 @@ static ssize_t hgpk_set_powered(struct psmouse *psmouse, void *data, | |||
366 | __PSMOUSE_DEFINE_ATTR(powered, S_IWUSR | S_IRUGO, NULL, | 810 | __PSMOUSE_DEFINE_ATTR(powered, S_IWUSR | S_IRUGO, NULL, |
367 | hgpk_show_powered, hgpk_set_powered, false); | 811 | hgpk_show_powered, hgpk_set_powered, false); |
368 | 812 | ||
813 | static ssize_t attr_show_mode(struct psmouse *psmouse, void *data, char *buf) | ||
814 | { | ||
815 | struct hgpk_data *priv = psmouse->private; | ||
816 | |||
817 | return sprintf(buf, "%s\n", hgpk_mode_names[priv->mode]); | ||
818 | } | ||
819 | |||
820 | static ssize_t attr_set_mode(struct psmouse *psmouse, void *data, | ||
821 | const char *buf, size_t len) | ||
822 | { | ||
823 | struct hgpk_data *priv = psmouse->private; | ||
824 | enum hgpk_mode old_mode = priv->mode; | ||
825 | enum hgpk_mode new_mode = hgpk_mode_from_name(buf, len); | ||
826 | struct input_dev *old_dev = psmouse->dev; | ||
827 | struct input_dev *new_dev; | ||
828 | int err; | ||
829 | |||
830 | if (new_mode == HGPK_MODE_INVALID) | ||
831 | return -EINVAL; | ||
832 | |||
833 | if (old_mode == new_mode) | ||
834 | return len; | ||
835 | |||
836 | new_dev = input_allocate_device(); | ||
837 | if (!new_dev) | ||
838 | return -ENOMEM; | ||
839 | |||
840 | psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); | ||
841 | |||
842 | /* Switch device into the new mode */ | ||
843 | priv->mode = new_mode; | ||
844 | err = hgpk_reset_device(psmouse, false); | ||
845 | if (err) | ||
846 | goto err_try_restore; | ||
847 | |||
848 | hgpk_setup_input_device(new_dev, old_dev, new_mode); | ||
849 | |||
850 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); | ||
851 | |||
852 | err = input_register_device(new_dev); | ||
853 | if (err) | ||
854 | goto err_try_restore; | ||
855 | |||
856 | psmouse->dev = new_dev; | ||
857 | input_unregister_device(old_dev); | ||
858 | |||
859 | return len; | ||
860 | |||
861 | err_try_restore: | ||
862 | input_free_device(new_dev); | ||
863 | priv->mode = old_mode; | ||
864 | hgpk_reset_device(psmouse, false); | ||
865 | |||
866 | return err; | ||
867 | } | ||
868 | |||
869 | PSMOUSE_DEFINE_ATTR(hgpk_mode, S_IWUSR | S_IRUGO, NULL, | ||
870 | attr_show_mode, attr_set_mode); | ||
871 | |||
369 | static ssize_t hgpk_trigger_recal_show(struct psmouse *psmouse, | 872 | static ssize_t hgpk_trigger_recal_show(struct psmouse *psmouse, |
370 | void *data, char *buf) | 873 | void *data, char *buf) |
371 | { | 874 | { |
@@ -401,6 +904,8 @@ static void hgpk_disconnect(struct psmouse *psmouse) | |||
401 | 904 | ||
402 | device_remove_file(&psmouse->ps2dev.serio->dev, | 905 | device_remove_file(&psmouse->ps2dev.serio->dev, |
403 | &psmouse_attr_powered.dattr); | 906 | &psmouse_attr_powered.dattr); |
907 | device_remove_file(&psmouse->ps2dev.serio->dev, | ||
908 | &psmouse_attr_hgpk_mode.dattr); | ||
404 | 909 | ||
405 | if (psmouse->model >= HGPK_MODEL_C) | 910 | if (psmouse->model >= HGPK_MODEL_C) |
406 | device_remove_file(&psmouse->ps2dev.serio->dev, | 911 | device_remove_file(&psmouse->ps2dev.serio->dev, |
@@ -416,14 +921,13 @@ static void hgpk_recalib_work(struct work_struct *work) | |||
416 | struct hgpk_data *priv = container_of(w, struct hgpk_data, recalib_wq); | 921 | struct hgpk_data *priv = container_of(w, struct hgpk_data, recalib_wq); |
417 | struct psmouse *psmouse = priv->psmouse; | 922 | struct psmouse *psmouse = priv->psmouse; |
418 | 923 | ||
419 | hgpk_dbg(psmouse, "recalibrating touchpad..\n"); | ||
420 | |||
421 | if (hgpk_force_recalibrate(psmouse)) | 924 | if (hgpk_force_recalibrate(psmouse)) |
422 | hgpk_err(psmouse, "recalibration failed!\n"); | 925 | hgpk_err(psmouse, "recalibration failed!\n"); |
423 | } | 926 | } |
424 | 927 | ||
425 | static int hgpk_register(struct psmouse *psmouse) | 928 | static int hgpk_register(struct psmouse *psmouse) |
426 | { | 929 | { |
930 | struct hgpk_data *priv = psmouse->private; | ||
427 | int err; | 931 | int err; |
428 | 932 | ||
429 | /* register handlers */ | 933 | /* register handlers */ |
@@ -431,13 +935,14 @@ static int hgpk_register(struct psmouse *psmouse) | |||
431 | psmouse->poll = hgpk_poll; | 935 | psmouse->poll = hgpk_poll; |
432 | psmouse->disconnect = hgpk_disconnect; | 936 | psmouse->disconnect = hgpk_disconnect; |
433 | psmouse->reconnect = hgpk_reconnect; | 937 | psmouse->reconnect = hgpk_reconnect; |
434 | psmouse->pktsize = 3; | ||
435 | 938 | ||
436 | /* Disable the idle resync. */ | 939 | /* Disable the idle resync. */ |
437 | psmouse->resync_time = 0; | 940 | psmouse->resync_time = 0; |
438 | /* Reset after a lot of bad bytes. */ | 941 | /* Reset after a lot of bad bytes. */ |
439 | psmouse->resetafter = 1024; | 942 | psmouse->resetafter = 1024; |
440 | 943 | ||
944 | hgpk_setup_input_device(psmouse->dev, NULL, priv->mode); | ||
945 | |||
441 | err = device_create_file(&psmouse->ps2dev.serio->dev, | 946 | err = device_create_file(&psmouse->ps2dev.serio->dev, |
442 | &psmouse_attr_powered.dattr); | 947 | &psmouse_attr_powered.dattr); |
443 | if (err) { | 948 | if (err) { |
@@ -445,6 +950,13 @@ static int hgpk_register(struct psmouse *psmouse) | |||
445 | return err; | 950 | return err; |
446 | } | 951 | } |
447 | 952 | ||
953 | err = device_create_file(&psmouse->ps2dev.serio->dev, | ||
954 | &psmouse_attr_hgpk_mode.dattr); | ||
955 | if (err) { | ||
956 | hgpk_err(psmouse, "Failed creating 'hgpk_mode' sysfs node\n"); | ||
957 | goto err_remove_powered; | ||
958 | } | ||
959 | |||
448 | /* C-series touchpads added the recalibrate command */ | 960 | /* C-series touchpads added the recalibrate command */ |
449 | if (psmouse->model >= HGPK_MODEL_C) { | 961 | if (psmouse->model >= HGPK_MODEL_C) { |
450 | err = device_create_file(&psmouse->ps2dev.serio->dev, | 962 | err = device_create_file(&psmouse->ps2dev.serio->dev, |
@@ -452,30 +964,40 @@ static int hgpk_register(struct psmouse *psmouse) | |||
452 | if (err) { | 964 | if (err) { |
453 | hgpk_err(psmouse, | 965 | hgpk_err(psmouse, |
454 | "Failed creating 'recalibrate' sysfs node\n"); | 966 | "Failed creating 'recalibrate' sysfs node\n"); |
455 | device_remove_file(&psmouse->ps2dev.serio->dev, | 967 | goto err_remove_mode; |
456 | &psmouse_attr_powered.dattr); | ||
457 | return err; | ||
458 | } | 968 | } |
459 | } | 969 | } |
460 | 970 | ||
461 | return 0; | 971 | return 0; |
972 | |||
973 | err_remove_mode: | ||
974 | device_remove_file(&psmouse->ps2dev.serio->dev, | ||
975 | &psmouse_attr_hgpk_mode.dattr); | ||
976 | err_remove_powered: | ||
977 | device_remove_file(&psmouse->ps2dev.serio->dev, | ||
978 | &psmouse_attr_powered.dattr); | ||
979 | return err; | ||
462 | } | 980 | } |
463 | 981 | ||
464 | int hgpk_init(struct psmouse *psmouse) | 982 | int hgpk_init(struct psmouse *psmouse) |
465 | { | 983 | { |
466 | struct hgpk_data *priv; | 984 | struct hgpk_data *priv; |
467 | int err = -ENOMEM; | 985 | int err; |
468 | 986 | ||
469 | priv = kzalloc(sizeof(struct hgpk_data), GFP_KERNEL); | 987 | priv = kzalloc(sizeof(struct hgpk_data), GFP_KERNEL); |
470 | if (!priv) | 988 | if (!priv) { |
989 | err = -ENOMEM; | ||
471 | goto alloc_fail; | 990 | goto alloc_fail; |
991 | } | ||
472 | 992 | ||
473 | psmouse->private = priv; | 993 | psmouse->private = priv; |
994 | |||
474 | priv->psmouse = psmouse; | 995 | priv->psmouse = psmouse; |
475 | priv->powered = true; | 996 | priv->powered = true; |
997 | priv->mode = hgpk_default_mode; | ||
476 | INIT_DELAYED_WORK(&priv->recalib_wq, hgpk_recalib_work); | 998 | INIT_DELAYED_WORK(&priv->recalib_wq, hgpk_recalib_work); |
477 | 999 | ||
478 | err = psmouse_reset(psmouse); | 1000 | err = hgpk_reset_device(psmouse, false); |
479 | if (err) | 1001 | if (err) |
480 | goto init_fail; | 1002 | goto init_fail; |
481 | 1003 | ||
@@ -531,3 +1053,14 @@ int hgpk_detect(struct psmouse *psmouse, bool set_properties) | |||
531 | 1053 | ||
532 | return 0; | 1054 | return 0; |
533 | } | 1055 | } |
1056 | |||
1057 | void hgpk_module_init(void) | ||
1058 | { | ||
1059 | hgpk_default_mode = hgpk_mode_from_name(hgpk_mode_name, | ||
1060 | strlen(hgpk_mode_name)); | ||
1061 | if (hgpk_default_mode == HGPK_MODE_INVALID) { | ||
1062 | hgpk_default_mode = HGPK_MODE_MOUSE; | ||
1063 | strlcpy(hgpk_mode_name, hgpk_mode_names[HGPK_MODE_MOUSE], | ||
1064 | sizeof(hgpk_mode_name)); | ||
1065 | } | ||
1066 | } | ||
diff --git a/drivers/input/mouse/hgpk.h b/drivers/input/mouse/hgpk.h index d61cfd3ee9cb..311c0e87fcbf 100644 --- a/drivers/input/mouse/hgpk.h +++ b/drivers/input/mouse/hgpk.h | |||
@@ -5,6 +5,9 @@ | |||
5 | #ifndef _HGPK_H | 5 | #ifndef _HGPK_H |
6 | #define _HGPK_H | 6 | #define _HGPK_H |
7 | 7 | ||
8 | #define HGPK_GS 0xff /* The GlideSensor */ | ||
9 | #define HGPK_PT 0xcf /* The PenTablet */ | ||
10 | |||
8 | enum hgpk_model_t { | 11 | enum hgpk_model_t { |
9 | HGPK_MODEL_PREA = 0x0a, /* pre-B1s */ | 12 | HGPK_MODEL_PREA = 0x0a, /* pre-B1s */ |
10 | HGPK_MODEL_A = 0x14, /* found on B1s, PT disabled in hardware */ | 13 | HGPK_MODEL_A = 0x14, /* found on B1s, PT disabled in hardware */ |
@@ -13,12 +16,34 @@ enum hgpk_model_t { | |||
13 | HGPK_MODEL_D = 0x50, /* C1, mass production */ | 16 | HGPK_MODEL_D = 0x50, /* C1, mass production */ |
14 | }; | 17 | }; |
15 | 18 | ||
19 | enum hgpk_spew_flag { | ||
20 | NO_SPEW, | ||
21 | MAYBE_SPEWING, | ||
22 | SPEW_DETECTED, | ||
23 | RECALIBRATING, | ||
24 | }; | ||
25 | |||
26 | #define SPEW_WATCH_COUNT 42 /* at 12ms/packet, this is 1/2 second */ | ||
27 | |||
28 | enum hgpk_mode { | ||
29 | HGPK_MODE_MOUSE, | ||
30 | HGPK_MODE_GLIDESENSOR, | ||
31 | HGPK_MODE_PENTABLET, | ||
32 | HGPK_MODE_INVALID | ||
33 | }; | ||
34 | |||
16 | struct hgpk_data { | 35 | struct hgpk_data { |
17 | struct psmouse *psmouse; | 36 | struct psmouse *psmouse; |
37 | enum hgpk_mode mode; | ||
18 | bool powered; | 38 | bool powered; |
19 | int count, x_tally, y_tally; /* hardware workaround stuff */ | 39 | enum hgpk_spew_flag spew_flag; |
40 | int spew_count, x_tally, y_tally; /* spew detection */ | ||
20 | unsigned long recalib_window; | 41 | unsigned long recalib_window; |
21 | struct delayed_work recalib_wq; | 42 | struct delayed_work recalib_wq; |
43 | int abs_x, abs_y; | ||
44 | int dupe_count; | ||
45 | int xbigj, ybigj, xlast, ylast; /* jumpiness detection */ | ||
46 | int xsaw_secondary, ysaw_secondary; /* jumpiness detection */ | ||
22 | }; | 47 | }; |
23 | 48 | ||
24 | #define hgpk_dbg(psmouse, format, arg...) \ | 49 | #define hgpk_dbg(psmouse, format, arg...) \ |
@@ -33,9 +58,13 @@ struct hgpk_data { | |||
33 | dev_notice(&(psmouse)->ps2dev.serio->dev, format, ## arg) | 58 | dev_notice(&(psmouse)->ps2dev.serio->dev, format, ## arg) |
34 | 59 | ||
35 | #ifdef CONFIG_MOUSE_PS2_OLPC | 60 | #ifdef CONFIG_MOUSE_PS2_OLPC |
61 | void hgpk_module_init(void); | ||
36 | int hgpk_detect(struct psmouse *psmouse, bool set_properties); | 62 | int hgpk_detect(struct psmouse *psmouse, bool set_properties); |
37 | int hgpk_init(struct psmouse *psmouse); | 63 | int hgpk_init(struct psmouse *psmouse); |
38 | #else | 64 | #else |
65 | static inline void hgpk_module_init(void) | ||
66 | { | ||
67 | } | ||
39 | static inline int hgpk_detect(struct psmouse *psmouse, bool set_properties) | 68 | static inline int hgpk_detect(struct psmouse *psmouse, bool set_properties) |
40 | { | 69 | { |
41 | return -ENODEV; | 70 | return -ENODEV; |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index cd9d0c97e429..3f74baee102b 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -1711,6 +1711,7 @@ static int __init psmouse_init(void) | |||
1711 | 1711 | ||
1712 | lifebook_module_init(); | 1712 | lifebook_module_init(); |
1713 | synaptics_module_init(); | 1713 | synaptics_module_init(); |
1714 | hgpk_module_init(); | ||
1714 | 1715 | ||
1715 | kpsmoused_wq = create_singlethread_workqueue("kpsmoused"); | 1716 | kpsmoused_wq = create_singlethread_workqueue("kpsmoused"); |
1716 | if (!kpsmoused_wq) { | 1717 | if (!kpsmoused_wq) { |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 2e300a460556..da392c22fc6c 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -25,7 +25,7 @@ | |||
25 | 25 | ||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/dmi.h> | 27 | #include <linux/dmi.h> |
28 | #include <linux/input.h> | 28 | #include <linux/input/mt.h> |
29 | #include <linux/serio.h> | 29 | #include <linux/serio.h> |
30 | #include <linux/libps2.h> | 30 | #include <linux/libps2.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
@@ -279,6 +279,25 @@ static void synaptics_set_rate(struct psmouse *psmouse, unsigned int rate) | |||
279 | synaptics_mode_cmd(psmouse, priv->mode); | 279 | synaptics_mode_cmd(psmouse, priv->mode); |
280 | } | 280 | } |
281 | 281 | ||
282 | static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse) | ||
283 | { | ||
284 | static unsigned char param = 0xc8; | ||
285 | struct synaptics_data *priv = psmouse->private; | ||
286 | |||
287 | if (!SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) | ||
288 | return 0; | ||
289 | |||
290 | if (psmouse_sliced_command(psmouse, SYN_QUE_MODEL)) | ||
291 | return -1; | ||
292 | if (ps2_command(&psmouse->ps2dev, ¶m, PSMOUSE_CMD_SETRATE)) | ||
293 | return -1; | ||
294 | |||
295 | /* Advanced gesture mode also sends multi finger data */ | ||
296 | priv->capabilities |= BIT(1); | ||
297 | |||
298 | return 0; | ||
299 | } | ||
300 | |||
282 | /***************************************************************************** | 301 | /***************************************************************************** |
283 | * Synaptics pass-through PS/2 port support | 302 | * Synaptics pass-through PS/2 port support |
284 | ****************************************************************************/ | 303 | ****************************************************************************/ |
@@ -380,7 +399,9 @@ static void synaptics_pt_create(struct psmouse *psmouse) | |||
380 | * Functions to interpret the absolute mode packets | 399 | * Functions to interpret the absolute mode packets |
381 | ****************************************************************************/ | 400 | ****************************************************************************/ |
382 | 401 | ||
383 | static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data *priv, struct synaptics_hw_state *hw) | 402 | static int synaptics_parse_hw_state(const unsigned char buf[], |
403 | struct synaptics_data *priv, | ||
404 | struct synaptics_hw_state *hw) | ||
384 | { | 405 | { |
385 | memset(hw, 0, sizeof(struct synaptics_hw_state)); | 406 | memset(hw, 0, sizeof(struct synaptics_hw_state)); |
386 | 407 | ||
@@ -397,6 +418,14 @@ static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data | |||
397 | ((buf[0] & 0x04) >> 1) | | 418 | ((buf[0] & 0x04) >> 1) | |
398 | ((buf[3] & 0x04) >> 2)); | 419 | ((buf[3] & 0x04) >> 2)); |
399 | 420 | ||
421 | if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) && hw->w == 2) { | ||
422 | /* Gesture packet: (x, y, z) at half resolution */ | ||
423 | priv->mt.x = (((buf[4] & 0x0f) << 8) | buf[1]) << 1; | ||
424 | priv->mt.y = (((buf[4] & 0xf0) << 4) | buf[2]) << 1; | ||
425 | priv->mt.z = ((buf[3] & 0x30) | (buf[5] & 0x0f)) << 1; | ||
426 | return 1; | ||
427 | } | ||
428 | |||
400 | hw->left = (buf[0] & 0x01) ? 1 : 0; | 429 | hw->left = (buf[0] & 0x01) ? 1 : 0; |
401 | hw->right = (buf[0] & 0x02) ? 1 : 0; | 430 | hw->right = (buf[0] & 0x02) ? 1 : 0; |
402 | 431 | ||
@@ -452,6 +481,36 @@ static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data | |||
452 | hw->left = (buf[0] & 0x01) ? 1 : 0; | 481 | hw->left = (buf[0] & 0x01) ? 1 : 0; |
453 | hw->right = (buf[0] & 0x02) ? 1 : 0; | 482 | hw->right = (buf[0] & 0x02) ? 1 : 0; |
454 | } | 483 | } |
484 | |||
485 | return 0; | ||
486 | } | ||
487 | |||
488 | static void set_slot(struct input_dev *dev, int slot, bool active, int x, int y) | ||
489 | { | ||
490 | input_mt_slot(dev, slot); | ||
491 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, active); | ||
492 | if (active) { | ||
493 | input_report_abs(dev, ABS_MT_POSITION_X, x); | ||
494 | input_report_abs(dev, ABS_MT_POSITION_Y, | ||
495 | YMAX_NOMINAL + YMIN_NOMINAL - y); | ||
496 | } | ||
497 | } | ||
498 | |||
499 | static void synaptics_report_semi_mt_data(struct input_dev *dev, | ||
500 | const struct synaptics_hw_state *a, | ||
501 | const struct synaptics_hw_state *b, | ||
502 | int num_fingers) | ||
503 | { | ||
504 | if (num_fingers >= 2) { | ||
505 | set_slot(dev, 0, true, min(a->x, b->x), min(a->y, b->y)); | ||
506 | set_slot(dev, 1, true, max(a->x, b->x), max(a->y, b->y)); | ||
507 | } else if (num_fingers == 1) { | ||
508 | set_slot(dev, 0, true, a->x, a->y); | ||
509 | set_slot(dev, 1, false, 0, 0); | ||
510 | } else { | ||
511 | set_slot(dev, 0, false, 0, 0); | ||
512 | set_slot(dev, 1, false, 0, 0); | ||
513 | } | ||
455 | } | 514 | } |
456 | 515 | ||
457 | /* | 516 | /* |
@@ -466,7 +525,8 @@ static void synaptics_process_packet(struct psmouse *psmouse) | |||
466 | int finger_width; | 525 | int finger_width; |
467 | int i; | 526 | int i; |
468 | 527 | ||
469 | synaptics_parse_hw_state(psmouse->packet, priv, &hw); | 528 | if (synaptics_parse_hw_state(psmouse->packet, priv, &hw)) |
529 | return; | ||
470 | 530 | ||
471 | if (hw.scroll) { | 531 | if (hw.scroll) { |
472 | priv->scroll += hw.scroll; | 532 | priv->scroll += hw.scroll; |
@@ -488,7 +548,7 @@ static void synaptics_process_packet(struct psmouse *psmouse) | |||
488 | return; | 548 | return; |
489 | } | 549 | } |
490 | 550 | ||
491 | if (hw.z > 0) { | 551 | if (hw.z > 0 && hw.x > 1) { |
492 | num_fingers = 1; | 552 | num_fingers = 1; |
493 | finger_width = 5; | 553 | finger_width = 5; |
494 | if (SYN_CAP_EXTENDED(priv->capabilities)) { | 554 | if (SYN_CAP_EXTENDED(priv->capabilities)) { |
@@ -512,6 +572,9 @@ static void synaptics_process_packet(struct psmouse *psmouse) | |||
512 | finger_width = 0; | 572 | finger_width = 0; |
513 | } | 573 | } |
514 | 574 | ||
575 | if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) | ||
576 | synaptics_report_semi_mt_data(dev, &hw, &priv->mt, num_fingers); | ||
577 | |||
515 | /* Post events | 578 | /* Post events |
516 | * BTN_TOUCH has to be first as mousedev relies on it when doing | 579 | * BTN_TOUCH has to be first as mousedev relies on it when doing |
517 | * absolute -> relative conversion | 580 | * absolute -> relative conversion |
@@ -519,7 +582,7 @@ static void synaptics_process_packet(struct psmouse *psmouse) | |||
519 | if (hw.z > 30) input_report_key(dev, BTN_TOUCH, 1); | 582 | if (hw.z > 30) input_report_key(dev, BTN_TOUCH, 1); |
520 | if (hw.z < 25) input_report_key(dev, BTN_TOUCH, 0); | 583 | if (hw.z < 25) input_report_key(dev, BTN_TOUCH, 0); |
521 | 584 | ||
522 | if (hw.z > 0) { | 585 | if (num_fingers > 0) { |
523 | input_report_abs(dev, ABS_X, hw.x); | 586 | input_report_abs(dev, ABS_X, hw.x); |
524 | input_report_abs(dev, ABS_Y, YMAX_NOMINAL + YMIN_NOMINAL - hw.y); | 587 | input_report_abs(dev, ABS_Y, YMAX_NOMINAL + YMIN_NOMINAL - hw.y); |
525 | } | 588 | } |
@@ -622,6 +685,8 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | |||
622 | { | 685 | { |
623 | int i; | 686 | int i; |
624 | 687 | ||
688 | __set_bit(INPUT_PROP_POINTER, dev->propbit); | ||
689 | |||
625 | __set_bit(EV_ABS, dev->evbit); | 690 | __set_bit(EV_ABS, dev->evbit); |
626 | input_set_abs_params(dev, ABS_X, | 691 | input_set_abs_params(dev, ABS_X, |
627 | XMIN_NOMINAL, priv->x_max ?: XMAX_NOMINAL, 0, 0); | 692 | XMIN_NOMINAL, priv->x_max ?: XMAX_NOMINAL, 0, 0); |
@@ -629,6 +694,15 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | |||
629 | YMIN_NOMINAL, priv->y_max ?: YMAX_NOMINAL, 0, 0); | 694 | YMIN_NOMINAL, priv->y_max ?: YMAX_NOMINAL, 0, 0); |
630 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); | 695 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); |
631 | 696 | ||
697 | if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) { | ||
698 | __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); | ||
699 | input_mt_init_slots(dev, 2); | ||
700 | input_set_abs_params(dev, ABS_MT_POSITION_X, XMIN_NOMINAL, | ||
701 | priv->x_max ?: XMAX_NOMINAL, 0, 0); | ||
702 | input_set_abs_params(dev, ABS_MT_POSITION_Y, YMIN_NOMINAL, | ||
703 | priv->y_max ?: YMAX_NOMINAL, 0, 0); | ||
704 | } | ||
705 | |||
632 | if (SYN_CAP_PALMDETECT(priv->capabilities)) | 706 | if (SYN_CAP_PALMDETECT(priv->capabilities)) |
633 | input_set_abs_params(dev, ABS_TOOL_WIDTH, 0, 15, 0, 0); | 707 | input_set_abs_params(dev, ABS_TOOL_WIDTH, 0, 15, 0, 0); |
634 | 708 | ||
@@ -663,6 +737,7 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | |||
663 | input_abs_set_res(dev, ABS_Y, priv->y_res); | 737 | input_abs_set_res(dev, ABS_Y, priv->y_res); |
664 | 738 | ||
665 | if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { | 739 | if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { |
740 | __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); | ||
666 | /* Clickpads report only left button */ | 741 | /* Clickpads report only left button */ |
667 | __clear_bit(BTN_RIGHT, dev->keybit); | 742 | __clear_bit(BTN_RIGHT, dev->keybit); |
668 | __clear_bit(BTN_MIDDLE, dev->keybit); | 743 | __clear_bit(BTN_MIDDLE, dev->keybit); |
@@ -702,6 +777,11 @@ static int synaptics_reconnect(struct psmouse *psmouse) | |||
702 | return -1; | 777 | return -1; |
703 | } | 778 | } |
704 | 779 | ||
780 | if (synaptics_set_advanced_gesture_mode(psmouse)) { | ||
781 | printk(KERN_ERR "Advanced gesture mode reconnect failed.\n"); | ||
782 | return -1; | ||
783 | } | ||
784 | |||
705 | return 0; | 785 | return 0; |
706 | } | 786 | } |
707 | 787 | ||
@@ -744,15 +824,45 @@ static const struct dmi_system_id __initconst toshiba_dmi_table[] = { | |||
744 | #endif | 824 | #endif |
745 | }; | 825 | }; |
746 | 826 | ||
827 | static bool broken_olpc_ec; | ||
828 | |||
829 | static const struct dmi_system_id __initconst olpc_dmi_table[] = { | ||
830 | #if defined(CONFIG_DMI) && defined(CONFIG_OLPC) | ||
831 | { | ||
832 | /* OLPC XO-1 or XO-1.5 */ | ||
833 | .matches = { | ||
834 | DMI_MATCH(DMI_SYS_VENDOR, "OLPC"), | ||
835 | DMI_MATCH(DMI_PRODUCT_NAME, "XO"), | ||
836 | }, | ||
837 | }, | ||
838 | { } | ||
839 | #endif | ||
840 | }; | ||
841 | |||
747 | void __init synaptics_module_init(void) | 842 | void __init synaptics_module_init(void) |
748 | { | 843 | { |
749 | impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table); | 844 | impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table); |
845 | broken_olpc_ec = dmi_check_system(olpc_dmi_table); | ||
750 | } | 846 | } |
751 | 847 | ||
752 | int synaptics_init(struct psmouse *psmouse) | 848 | int synaptics_init(struct psmouse *psmouse) |
753 | { | 849 | { |
754 | struct synaptics_data *priv; | 850 | struct synaptics_data *priv; |
755 | 851 | ||
852 | /* | ||
853 | * The OLPC XO has issues with Synaptics' absolute mode; similarly to | ||
854 | * the HGPK, it quickly degrades and the hardware becomes jumpy and | ||
855 | * overly sensitive. Not only that, but the constant packet spew | ||
856 | * (even at a lowered 40pps rate) overloads the EC such that key | ||
857 | * presses on the keyboard are missed. Given all of that, don't | ||
858 | * even attempt to use Synaptics mode. Relative mode seems to work | ||
859 | * just fine. | ||
860 | */ | ||
861 | if (broken_olpc_ec) { | ||
862 | printk(KERN_INFO "synaptics: OLPC XO detected, not enabling Synaptics protocol.\n"); | ||
863 | return -ENODEV; | ||
864 | } | ||
865 | |||
756 | psmouse->private = priv = kzalloc(sizeof(struct synaptics_data), GFP_KERNEL); | 866 | psmouse->private = priv = kzalloc(sizeof(struct synaptics_data), GFP_KERNEL); |
757 | if (!priv) | 867 | if (!priv) |
758 | return -ENOMEM; | 868 | return -ENOMEM; |
@@ -769,6 +879,11 @@ int synaptics_init(struct psmouse *psmouse) | |||
769 | goto init_fail; | 879 | goto init_fail; |
770 | } | 880 | } |
771 | 881 | ||
882 | if (synaptics_set_advanced_gesture_mode(psmouse)) { | ||
883 | printk(KERN_ERR "Advanced gesture mode init failed.\n"); | ||
884 | goto init_fail; | ||
885 | } | ||
886 | |||
772 | priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; | 887 | priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; |
773 | 888 | ||
774 | printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx\n", | 889 | printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx\n", |
@@ -802,8 +917,8 @@ int synaptics_init(struct psmouse *psmouse) | |||
802 | 917 | ||
803 | /* | 918 | /* |
804 | * Toshiba's KBC seems to have trouble handling data from | 919 | * Toshiba's KBC seems to have trouble handling data from |
805 | * Synaptics as full rate, switch to lower rate which is roughly | 920 | * Synaptics at full rate. Switch to a lower rate (roughly |
806 | * thye same as rate of standard PS/2 mouse. | 921 | * the same rate as a standard PS/2 mouse). |
807 | */ | 922 | */ |
808 | if (psmouse->rate >= 80 && impaired_toshiba_kbc) { | 923 | if (psmouse->rate >= 80 && impaired_toshiba_kbc) { |
809 | printk(KERN_INFO "synaptics: Toshiba %s detected, limiting rate to 40pps.\n", | 924 | printk(KERN_INFO "synaptics: Toshiba %s detected, limiting rate to 40pps.\n", |
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index 0aefaa885871..25e5d042a72c 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h | |||
@@ -54,6 +54,7 @@ | |||
54 | #define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */ | 54 | #define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */ |
55 | #define SYN_CAP_CLICKPAD2BTN(ex0c) ((ex0c) & 0x000100) /* 2-button ClickPad */ | 55 | #define SYN_CAP_CLICKPAD2BTN(ex0c) ((ex0c) & 0x000100) /* 2-button ClickPad */ |
56 | #define SYN_CAP_MAX_DIMENSIONS(ex0c) ((ex0c) & 0x020000) | 56 | #define SYN_CAP_MAX_DIMENSIONS(ex0c) ((ex0c) & 0x020000) |
57 | #define SYN_CAP_ADV_GESTURE(ex0c) ((ex0c) & 0x080000) | ||
57 | 58 | ||
58 | /* synaptics modes query bits */ | 59 | /* synaptics modes query bits */ |
59 | #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) | 60 | #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) |
@@ -113,6 +114,8 @@ struct synaptics_data { | |||
113 | int scroll; | 114 | int scroll; |
114 | 115 | ||
115 | struct serio *pt_port; /* Pass-through serio port */ | 116 | struct serio *pt_port; /* Pass-through serio port */ |
117 | |||
118 | struct synaptics_hw_state mt; /* current gesture packet */ | ||
116 | }; | 119 | }; |
117 | 120 | ||
118 | void synaptics_module_init(void); | 121 | void synaptics_module_init(void); |
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 2a00ddf4f23a..7630273e9474 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c | |||
@@ -9,6 +9,8 @@ | |||
9 | * the Free Software Foundation. | 9 | * the Free Software Foundation. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
13 | |||
12 | #define MOUSEDEV_MINOR_BASE 32 | 14 | #define MOUSEDEV_MINOR_BASE 32 |
13 | #define MOUSEDEV_MINORS 32 | 15 | #define MOUSEDEV_MINORS 32 |
14 | #define MOUSEDEV_MIX 31 | 16 | #define MOUSEDEV_MIX 31 |
@@ -977,7 +979,7 @@ static int mousedev_connect(struct input_handler *handler, | |||
977 | break; | 979 | break; |
978 | 980 | ||
979 | if (minor == MOUSEDEV_MINORS) { | 981 | if (minor == MOUSEDEV_MINORS) { |
980 | printk(KERN_ERR "mousedev: no more free mousedev devices\n"); | 982 | pr_err("no more free mousedev devices\n"); |
981 | return -ENFILE; | 983 | return -ENFILE; |
982 | } | 984 | } |
983 | 985 | ||
@@ -1087,13 +1089,13 @@ static int __init mousedev_init(void) | |||
1087 | #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX | 1089 | #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX |
1088 | error = misc_register(&psaux_mouse); | 1090 | error = misc_register(&psaux_mouse); |
1089 | if (error) | 1091 | if (error) |
1090 | printk(KERN_WARNING "mice: could not register psaux device, " | 1092 | pr_warning("could not register psaux device, error: %d\n", |
1091 | "error: %d\n", error); | 1093 | error); |
1092 | else | 1094 | else |
1093 | psaux_registered = 1; | 1095 | psaux_registered = 1; |
1094 | #endif | 1096 | #endif |
1095 | 1097 | ||
1096 | printk(KERN_INFO "mice: PS/2 mouse device common for all mice\n"); | 1098 | pr_info("PS/2 mouse device common for all mice\n"); |
1097 | 1099 | ||
1098 | return 0; | 1100 | return 0; |
1099 | } | 1101 | } |
diff --git a/drivers/input/serio/ams_delta_serio.c b/drivers/input/serio/ams_delta_serio.c index 8f1770e1e08b..ebe955325677 100644 --- a/drivers/input/serio/ams_delta_serio.c +++ b/drivers/input/serio/ams_delta_serio.c | |||
@@ -172,6 +172,5 @@ static void __exit ams_delta_serio_exit(void) | |||
172 | free_irq(OMAP_GPIO_IRQ(AMS_DELTA_GPIO_PIN_KEYBRD_CLK), 0); | 172 | free_irq(OMAP_GPIO_IRQ(AMS_DELTA_GPIO_PIN_KEYBRD_CLK), 0); |
173 | gpio_free(AMS_DELTA_GPIO_PIN_KEYBRD_CLK); | 173 | gpio_free(AMS_DELTA_GPIO_PIN_KEYBRD_CLK); |
174 | gpio_free(AMS_DELTA_GPIO_PIN_KEYBRD_DATA); | 174 | gpio_free(AMS_DELTA_GPIO_PIN_KEYBRD_DATA); |
175 | kfree(ams_delta_serio); | ||
176 | } | 175 | } |
177 | module_exit(ams_delta_serio_exit); | 176 | module_exit(ams_delta_serio_exit); |
diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c index 4a3084695c00..448c7724beb9 100644 --- a/drivers/input/serio/ct82c710.c +++ b/drivers/input/serio/ct82c710.c | |||
@@ -191,6 +191,9 @@ static int __devinit ct82c710_probe(struct platform_device *dev) | |||
191 | 191 | ||
192 | serio_register_port(ct82c710_port); | 192 | serio_register_port(ct82c710_port); |
193 | 193 | ||
194 | printk(KERN_INFO "serio: C&T 82c710 mouse port at %#llx irq %d\n", | ||
195 | (unsigned long long)CT82C710_DATA, CT82C710_IRQ); | ||
196 | |||
194 | return 0; | 197 | return 0; |
195 | } | 198 | } |
196 | 199 | ||
@@ -237,11 +240,6 @@ static int __init ct82c710_init(void) | |||
237 | if (error) | 240 | if (error) |
238 | goto err_free_device; | 241 | goto err_free_device; |
239 | 242 | ||
240 | serio_register_port(ct82c710_port); | ||
241 | |||
242 | printk(KERN_INFO "serio: C&T 82c710 mouse port at %#llx irq %d\n", | ||
243 | (unsigned long long)CT82C710_DATA, CT82C710_IRQ); | ||
244 | |||
245 | return 0; | 243 | return 0; |
246 | 244 | ||
247 | err_free_device: | 245 | err_free_device: |
diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c index e5624d8f1709..bfd3865d886b 100644 --- a/drivers/input/serio/hil_mlc.c +++ b/drivers/input/serio/hil_mlc.c | |||
@@ -932,6 +932,11 @@ int hil_mlc_register(hil_mlc *mlc) | |||
932 | hil_mlc_copy_di_scratch(mlc, i); | 932 | hil_mlc_copy_di_scratch(mlc, i); |
933 | mlc_serio = kzalloc(sizeof(*mlc_serio), GFP_KERNEL); | 933 | mlc_serio = kzalloc(sizeof(*mlc_serio), GFP_KERNEL); |
934 | mlc->serio[i] = mlc_serio; | 934 | mlc->serio[i] = mlc_serio; |
935 | if (!mlc->serio[i]) { | ||
936 | for (; i >= 0; i--) | ||
937 | kfree(mlc->serio[i]); | ||
938 | return -ENOMEM; | ||
939 | } | ||
935 | snprintf(mlc_serio->name, sizeof(mlc_serio->name)-1, "HIL_SERIO%d", i); | 940 | snprintf(mlc_serio->name, sizeof(mlc_serio->name)-1, "HIL_SERIO%d", i); |
936 | snprintf(mlc_serio->phys, sizeof(mlc_serio->phys)-1, "HIL%d", i); | 941 | snprintf(mlc_serio->phys, sizeof(mlc_serio->phys)-1, "HIL%d", i); |
937 | mlc_serio->id = hil_mlc_serio_id; | 942 | mlc_serio->id = hil_mlc_serio_id; |
diff --git a/drivers/input/serio/hp_sdc_mlc.c b/drivers/input/serio/hp_sdc_mlc.c index 7d2b820ef58d..d50f0678bf47 100644 --- a/drivers/input/serio/hp_sdc_mlc.c +++ b/drivers/input/serio/hp_sdc_mlc.c | |||
@@ -305,6 +305,7 @@ static void hp_sdc_mlc_out(hil_mlc *mlc) | |||
305 | static int __init hp_sdc_mlc_init(void) | 305 | static int __init hp_sdc_mlc_init(void) |
306 | { | 306 | { |
307 | hil_mlc *mlc = &hp_sdc_mlc; | 307 | hil_mlc *mlc = &hp_sdc_mlc; |
308 | int err; | ||
308 | 309 | ||
309 | #ifdef __mc68000__ | 310 | #ifdef __mc68000__ |
310 | if (!MACH_IS_HP300) | 311 | if (!MACH_IS_HP300) |
@@ -323,22 +324,21 @@ static int __init hp_sdc_mlc_init(void) | |||
323 | mlc->out = &hp_sdc_mlc_out; | 324 | mlc->out = &hp_sdc_mlc_out; |
324 | mlc->priv = &hp_sdc_mlc_priv; | 325 | mlc->priv = &hp_sdc_mlc_priv; |
325 | 326 | ||
326 | if (hil_mlc_register(mlc)) { | 327 | err = hil_mlc_register(mlc); |
328 | if (err) { | ||
327 | printk(KERN_WARNING PREFIX "Failed to register MLC structure with hil_mlc\n"); | 329 | printk(KERN_WARNING PREFIX "Failed to register MLC structure with hil_mlc\n"); |
328 | goto err0; | 330 | return err; |
329 | } | 331 | } |
330 | 332 | ||
331 | if (hp_sdc_request_hil_irq(&hp_sdc_mlc_isr)) { | 333 | if (hp_sdc_request_hil_irq(&hp_sdc_mlc_isr)) { |
332 | printk(KERN_WARNING PREFIX "Request for raw HIL ISR hook denied\n"); | 334 | printk(KERN_WARNING PREFIX "Request for raw HIL ISR hook denied\n"); |
333 | goto err1; | 335 | if (hil_mlc_unregister(mlc)) |
336 | printk(KERN_ERR PREFIX "Failed to unregister MLC structure with hil_mlc.\n" | ||
337 | "This is bad. Could cause an oops.\n"); | ||
338 | return -EBUSY; | ||
334 | } | 339 | } |
340 | |||
335 | return 0; | 341 | return 0; |
336 | err1: | ||
337 | if (hil_mlc_unregister(mlc)) | ||
338 | printk(KERN_ERR PREFIX "Failed to unregister MLC structure with hil_mlc.\n" | ||
339 | "This is bad. Could cause an oops.\n"); | ||
340 | err0: | ||
341 | return -EBUSY; | ||
342 | } | 342 | } |
343 | 343 | ||
344 | static void __exit hp_sdc_mlc_exit(void) | 344 | static void __exit hp_sdc_mlc_exit(void) |
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index a5475b577086..5ae0fc4578fe 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -553,6 +553,13 @@ static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = { | |||
553 | */ | 553 | */ |
554 | static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = { | 554 | static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = { |
555 | { | 555 | { |
556 | /* Acer Aspire 5100 */ | ||
557 | .matches = { | ||
558 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
559 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"), | ||
560 | }, | ||
561 | }, | ||
562 | { | ||
556 | /* Acer Aspire 5610 */ | 563 | /* Acer Aspire 5610 */ |
557 | .matches = { | 564 | .matches = { |
558 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 565 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
@@ -752,7 +759,7 @@ static int __init i8042_pnp_init(void) | |||
752 | #endif | 759 | #endif |
753 | 760 | ||
754 | if (i8042_nopnp) { | 761 | if (i8042_nopnp) { |
755 | printk(KERN_INFO "i8042: PNP detection disabled\n"); | 762 | pr_info("PNP detection disabled\n"); |
756 | return 0; | 763 | return 0; |
757 | } | 764 | } |
758 | 765 | ||
@@ -769,7 +776,7 @@ static int __init i8042_pnp_init(void) | |||
769 | #if defined(__ia64__) | 776 | #if defined(__ia64__) |
770 | return -ENODEV; | 777 | return -ENODEV; |
771 | #else | 778 | #else |
772 | printk(KERN_INFO "PNP: No PS/2 controller found. Probing ports directly.\n"); | 779 | pr_info("PNP: No PS/2 controller found. Probing ports directly.\n"); |
773 | return 0; | 780 | return 0; |
774 | #endif | 781 | #endif |
775 | } | 782 | } |
@@ -781,7 +788,7 @@ static int __init i8042_pnp_init(void) | |||
781 | snprintf(aux_irq_str, sizeof(aux_irq_str), | 788 | snprintf(aux_irq_str, sizeof(aux_irq_str), |
782 | "%d", i8042_pnp_aux_irq); | 789 | "%d", i8042_pnp_aux_irq); |
783 | 790 | ||
784 | printk(KERN_INFO "PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %s%s%s\n", | 791 | pr_info("PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %s%s%s\n", |
785 | i8042_pnp_kbd_name, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "", | 792 | i8042_pnp_kbd_name, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "", |
786 | i8042_pnp_aux_name, | 793 | i8042_pnp_aux_name, |
787 | i8042_pnp_data_reg, i8042_pnp_command_reg, | 794 | i8042_pnp_data_reg, i8042_pnp_command_reg, |
@@ -798,9 +805,7 @@ static int __init i8042_pnp_init(void) | |||
798 | if (((i8042_pnp_data_reg & ~0xf) == (i8042_data_reg & ~0xf) && | 805 | if (((i8042_pnp_data_reg & ~0xf) == (i8042_data_reg & ~0xf) && |
799 | i8042_pnp_data_reg != i8042_data_reg) || | 806 | i8042_pnp_data_reg != i8042_data_reg) || |
800 | !i8042_pnp_data_reg) { | 807 | !i8042_pnp_data_reg) { |
801 | printk(KERN_WARNING | 808 | pr_warn("PNP: PS/2 controller has invalid data port %#x; using default %#x\n", |
802 | "PNP: PS/2 controller has invalid data port %#x; " | ||
803 | "using default %#x\n", | ||
804 | i8042_pnp_data_reg, i8042_data_reg); | 809 | i8042_pnp_data_reg, i8042_data_reg); |
805 | i8042_pnp_data_reg = i8042_data_reg; | 810 | i8042_pnp_data_reg = i8042_data_reg; |
806 | pnp_data_busted = true; | 811 | pnp_data_busted = true; |
@@ -809,33 +814,27 @@ static int __init i8042_pnp_init(void) | |||
809 | if (((i8042_pnp_command_reg & ~0xf) == (i8042_command_reg & ~0xf) && | 814 | if (((i8042_pnp_command_reg & ~0xf) == (i8042_command_reg & ~0xf) && |
810 | i8042_pnp_command_reg != i8042_command_reg) || | 815 | i8042_pnp_command_reg != i8042_command_reg) || |
811 | !i8042_pnp_command_reg) { | 816 | !i8042_pnp_command_reg) { |
812 | printk(KERN_WARNING | 817 | pr_warn("PNP: PS/2 controller has invalid command port %#x; using default %#x\n", |
813 | "PNP: PS/2 controller has invalid command port %#x; " | ||
814 | "using default %#x\n", | ||
815 | i8042_pnp_command_reg, i8042_command_reg); | 818 | i8042_pnp_command_reg, i8042_command_reg); |
816 | i8042_pnp_command_reg = i8042_command_reg; | 819 | i8042_pnp_command_reg = i8042_command_reg; |
817 | pnp_data_busted = true; | 820 | pnp_data_busted = true; |
818 | } | 821 | } |
819 | 822 | ||
820 | if (!i8042_nokbd && !i8042_pnp_kbd_irq) { | 823 | if (!i8042_nokbd && !i8042_pnp_kbd_irq) { |
821 | printk(KERN_WARNING | 824 | pr_warn("PNP: PS/2 controller doesn't have KBD irq; using default %d\n", |
822 | "PNP: PS/2 controller doesn't have KBD irq; " | 825 | i8042_kbd_irq); |
823 | "using default %d\n", i8042_kbd_irq); | ||
824 | i8042_pnp_kbd_irq = i8042_kbd_irq; | 826 | i8042_pnp_kbd_irq = i8042_kbd_irq; |
825 | pnp_data_busted = true; | 827 | pnp_data_busted = true; |
826 | } | 828 | } |
827 | 829 | ||
828 | if (!i8042_noaux && !i8042_pnp_aux_irq) { | 830 | if (!i8042_noaux && !i8042_pnp_aux_irq) { |
829 | if (!pnp_data_busted && i8042_pnp_kbd_irq) { | 831 | if (!pnp_data_busted && i8042_pnp_kbd_irq) { |
830 | printk(KERN_WARNING | 832 | pr_warn("PNP: PS/2 appears to have AUX port disabled, " |
831 | "PNP: PS/2 appears to have AUX port disabled, " | 833 | "if this is incorrect please boot with i8042.nopnp\n"); |
832 | "if this is incorrect please boot with " | ||
833 | "i8042.nopnp\n"); | ||
834 | i8042_noaux = true; | 834 | i8042_noaux = true; |
835 | } else { | 835 | } else { |
836 | printk(KERN_WARNING | 836 | pr_warn("PNP: PS/2 controller doesn't have AUX irq; using default %d\n", |
837 | "PNP: PS/2 controller doesn't have AUX irq; " | 837 | i8042_aux_irq); |
838 | "using default %d\n", i8042_aux_irq); | ||
839 | i8042_pnp_aux_irq = i8042_aux_irq; | 838 | i8042_pnp_aux_irq = i8042_aux_irq; |
840 | } | 839 | } |
841 | } | 840 | } |
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 18db5a8c7478..c04ff00a3663 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -10,6 +10,8 @@ | |||
10 | * the Free Software Foundation. | 10 | * the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
14 | |||
13 | #include <linux/types.h> | 15 | #include <linux/types.h> |
14 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
15 | #include <linux/module.h> | 17 | #include <linux/module.h> |
@@ -225,8 +227,8 @@ static int i8042_flush(void) | |||
225 | udelay(50); | 227 | udelay(50); |
226 | data = i8042_read_data(); | 228 | data = i8042_read_data(); |
227 | i++; | 229 | i++; |
228 | dbg("%02x <- i8042 (flush, %s)", data, | 230 | dbg("%02x <- i8042 (flush, %s)\n", |
229 | str & I8042_STR_AUXDATA ? "aux" : "kbd"); | 231 | data, str & I8042_STR_AUXDATA ? "aux" : "kbd"); |
230 | } | 232 | } |
231 | 233 | ||
232 | spin_unlock_irqrestore(&i8042_lock, flags); | 234 | spin_unlock_irqrestore(&i8042_lock, flags); |
@@ -253,32 +255,32 @@ static int __i8042_command(unsigned char *param, int command) | |||
253 | if (error) | 255 | if (error) |
254 | return error; | 256 | return error; |
255 | 257 | ||
256 | dbg("%02x -> i8042 (command)", command & 0xff); | 258 | dbg("%02x -> i8042 (command)\n", command & 0xff); |
257 | i8042_write_command(command & 0xff); | 259 | i8042_write_command(command & 0xff); |
258 | 260 | ||
259 | for (i = 0; i < ((command >> 12) & 0xf); i++) { | 261 | for (i = 0; i < ((command >> 12) & 0xf); i++) { |
260 | error = i8042_wait_write(); | 262 | error = i8042_wait_write(); |
261 | if (error) | 263 | if (error) |
262 | return error; | 264 | return error; |
263 | dbg("%02x -> i8042 (parameter)", param[i]); | 265 | dbg("%02x -> i8042 (parameter)\n", param[i]); |
264 | i8042_write_data(param[i]); | 266 | i8042_write_data(param[i]); |
265 | } | 267 | } |
266 | 268 | ||
267 | for (i = 0; i < ((command >> 8) & 0xf); i++) { | 269 | for (i = 0; i < ((command >> 8) & 0xf); i++) { |
268 | error = i8042_wait_read(); | 270 | error = i8042_wait_read(); |
269 | if (error) { | 271 | if (error) { |
270 | dbg(" -- i8042 (timeout)"); | 272 | dbg(" -- i8042 (timeout)\n"); |
271 | return error; | 273 | return error; |
272 | } | 274 | } |
273 | 275 | ||
274 | if (command == I8042_CMD_AUX_LOOP && | 276 | if (command == I8042_CMD_AUX_LOOP && |
275 | !(i8042_read_status() & I8042_STR_AUXDATA)) { | 277 | !(i8042_read_status() & I8042_STR_AUXDATA)) { |
276 | dbg(" -- i8042 (auxerr)"); | 278 | dbg(" -- i8042 (auxerr)\n"); |
277 | return -1; | 279 | return -1; |
278 | } | 280 | } |
279 | 281 | ||
280 | param[i] = i8042_read_data(); | 282 | param[i] = i8042_read_data(); |
281 | dbg("%02x <- i8042 (return)", param[i]); | 283 | dbg("%02x <- i8042 (return)\n", param[i]); |
282 | } | 284 | } |
283 | 285 | ||
284 | return 0; | 286 | return 0; |
@@ -309,7 +311,7 @@ static int i8042_kbd_write(struct serio *port, unsigned char c) | |||
309 | spin_lock_irqsave(&i8042_lock, flags); | 311 | spin_lock_irqsave(&i8042_lock, flags); |
310 | 312 | ||
311 | if (!(retval = i8042_wait_write())) { | 313 | if (!(retval = i8042_wait_write())) { |
312 | dbg("%02x -> i8042 (kbd-data)", c); | 314 | dbg("%02x -> i8042 (kbd-data)\n", c); |
313 | i8042_write_data(c); | 315 | i8042_write_data(c); |
314 | } | 316 | } |
315 | 317 | ||
@@ -355,17 +357,14 @@ static void i8042_port_close(struct serio *serio) | |||
355 | 357 | ||
356 | i8042_ctr &= ~irq_bit; | 358 | i8042_ctr &= ~irq_bit; |
357 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) | 359 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) |
358 | printk(KERN_WARNING | 360 | pr_warn("Can't write CTR while closing %s port\n", port_name); |
359 | "i8042.c: Can't write CTR while closing %s port.\n", | ||
360 | port_name); | ||
361 | 361 | ||
362 | udelay(50); | 362 | udelay(50); |
363 | 363 | ||
364 | i8042_ctr &= ~disable_bit; | 364 | i8042_ctr &= ~disable_bit; |
365 | i8042_ctr |= irq_bit; | 365 | i8042_ctr |= irq_bit; |
366 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) | 366 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) |
367 | printk(KERN_ERR "i8042.c: Can't reactivate %s port.\n", | 367 | pr_err("Can't reactivate %s port\n", port_name); |
368 | port_name); | ||
369 | 368 | ||
370 | /* | 369 | /* |
371 | * See if there is any data appeared while we were messing with | 370 | * See if there is any data appeared while we were messing with |
@@ -456,7 +455,8 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) | |||
456 | str = i8042_read_status(); | 455 | str = i8042_read_status(); |
457 | if (unlikely(~str & I8042_STR_OBF)) { | 456 | if (unlikely(~str & I8042_STR_OBF)) { |
458 | spin_unlock_irqrestore(&i8042_lock, flags); | 457 | spin_unlock_irqrestore(&i8042_lock, flags); |
459 | if (irq) dbg("Interrupt %d, without any data", irq); | 458 | if (irq) |
459 | dbg("Interrupt %d, without any data\n", irq); | ||
460 | ret = 0; | 460 | ret = 0; |
461 | goto out; | 461 | goto out; |
462 | } | 462 | } |
@@ -469,7 +469,8 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) | |||
469 | 469 | ||
470 | dfl = 0; | 470 | dfl = 0; |
471 | if (str & I8042_STR_MUXERR) { | 471 | if (str & I8042_STR_MUXERR) { |
472 | dbg("MUX error, status is %02x, data is %02x", str, data); | 472 | dbg("MUX error, status is %02x, data is %02x\n", |
473 | str, data); | ||
473 | /* | 474 | /* |
474 | * When MUXERR condition is signalled the data register can only contain | 475 | * When MUXERR condition is signalled the data register can only contain |
475 | * 0xfd, 0xfe or 0xff if implementation follows the spec. Unfortunately | 476 | * 0xfd, 0xfe or 0xff if implementation follows the spec. Unfortunately |
@@ -512,7 +513,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) | |||
512 | port = &i8042_ports[port_no]; | 513 | port = &i8042_ports[port_no]; |
513 | serio = port->exists ? port->serio : NULL; | 514 | serio = port->exists ? port->serio : NULL; |
514 | 515 | ||
515 | dbg("%02x <- i8042 (interrupt, %d, %d%s%s)", | 516 | dbg("%02x <- i8042 (interrupt, %d, %d%s%s)\n", |
516 | data, port_no, irq, | 517 | data, port_no, irq, |
517 | dfl & SERIO_PARITY ? ", bad parity" : "", | 518 | dfl & SERIO_PARITY ? ", bad parity" : "", |
518 | dfl & SERIO_TIMEOUT ? ", timeout" : ""); | 519 | dfl & SERIO_TIMEOUT ? ", timeout" : ""); |
@@ -540,7 +541,7 @@ static int i8042_enable_kbd_port(void) | |||
540 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { | 541 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { |
541 | i8042_ctr &= ~I8042_CTR_KBDINT; | 542 | i8042_ctr &= ~I8042_CTR_KBDINT; |
542 | i8042_ctr |= I8042_CTR_KBDDIS; | 543 | i8042_ctr |= I8042_CTR_KBDDIS; |
543 | printk(KERN_ERR "i8042.c: Failed to enable KBD port.\n"); | 544 | pr_err("Failed to enable KBD port\n"); |
544 | return -EIO; | 545 | return -EIO; |
545 | } | 546 | } |
546 | 547 | ||
@@ -559,7 +560,7 @@ static int i8042_enable_aux_port(void) | |||
559 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { | 560 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { |
560 | i8042_ctr &= ~I8042_CTR_AUXINT; | 561 | i8042_ctr &= ~I8042_CTR_AUXINT; |
561 | i8042_ctr |= I8042_CTR_AUXDIS; | 562 | i8042_ctr |= I8042_CTR_AUXDIS; |
562 | printk(KERN_ERR "i8042.c: Failed to enable AUX port.\n"); | 563 | pr_err("Failed to enable AUX port\n"); |
563 | return -EIO; | 564 | return -EIO; |
564 | } | 565 | } |
565 | 566 | ||
@@ -641,7 +642,7 @@ static int __init i8042_check_mux(void) | |||
641 | if (i8042_set_mux_mode(true, &mux_version)) | 642 | if (i8042_set_mux_mode(true, &mux_version)) |
642 | return -1; | 643 | return -1; |
643 | 644 | ||
644 | printk(KERN_INFO "i8042.c: Detected active multiplexing controller, rev %d.%d.\n", | 645 | pr_info("Detected active multiplexing controller, rev %d.%d\n", |
645 | (mux_version >> 4) & 0xf, mux_version & 0xf); | 646 | (mux_version >> 4) & 0xf, mux_version & 0xf); |
646 | 647 | ||
647 | /* | 648 | /* |
@@ -651,7 +652,7 @@ static int __init i8042_check_mux(void) | |||
651 | i8042_ctr &= ~I8042_CTR_AUXINT; | 652 | i8042_ctr &= ~I8042_CTR_AUXINT; |
652 | 653 | ||
653 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { | 654 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { |
654 | printk(KERN_ERR "i8042.c: Failed to disable AUX port, can't use MUX.\n"); | 655 | pr_err("Failed to disable AUX port, can't use MUX\n"); |
655 | return -EIO; | 656 | return -EIO; |
656 | } | 657 | } |
657 | 658 | ||
@@ -676,8 +677,8 @@ static irqreturn_t __init i8042_aux_test_irq(int irq, void *dev_id) | |||
676 | str = i8042_read_status(); | 677 | str = i8042_read_status(); |
677 | if (str & I8042_STR_OBF) { | 678 | if (str & I8042_STR_OBF) { |
678 | data = i8042_read_data(); | 679 | data = i8042_read_data(); |
679 | dbg("%02x <- i8042 (aux_test_irq, %s)", | 680 | dbg("%02x <- i8042 (aux_test_irq, %s)\n", |
680 | data, str & I8042_STR_AUXDATA ? "aux" : "kbd"); | 681 | data, str & I8042_STR_AUXDATA ? "aux" : "kbd"); |
681 | if (i8042_irq_being_tested && | 682 | if (i8042_irq_being_tested && |
682 | data == 0xa5 && (str & I8042_STR_AUXDATA)) | 683 | data == 0xa5 && (str & I8042_STR_AUXDATA)) |
683 | complete(&i8042_aux_irq_delivered); | 684 | complete(&i8042_aux_irq_delivered); |
@@ -770,8 +771,8 @@ static int __init i8042_check_aux(void) | |||
770 | */ | 771 | */ |
771 | 772 | ||
772 | if (i8042_toggle_aux(false)) { | 773 | if (i8042_toggle_aux(false)) { |
773 | printk(KERN_WARNING "Failed to disable AUX port, but continuing anyway... Is this a SiS?\n"); | 774 | pr_warn("Failed to disable AUX port, but continuing anyway... Is this a SiS?\n"); |
774 | printk(KERN_WARNING "If AUX port is really absent please use the 'i8042.noaux' option.\n"); | 775 | pr_warn("If AUX port is really absent please use the 'i8042.noaux' option\n"); |
775 | } | 776 | } |
776 | 777 | ||
777 | if (i8042_toggle_aux(true)) | 778 | if (i8042_toggle_aux(true)) |
@@ -819,7 +820,7 @@ static int __init i8042_check_aux(void) | |||
819 | * AUX IRQ was never delivered so we need to flush the controller to | 820 | * AUX IRQ was never delivered so we need to flush the controller to |
820 | * get rid of the byte we put there; otherwise keyboard may not work. | 821 | * get rid of the byte we put there; otherwise keyboard may not work. |
821 | */ | 822 | */ |
822 | dbg(" -- i8042 (aux irq test timeout)"); | 823 | dbg(" -- i8042 (aux irq test timeout)\n"); |
823 | i8042_flush(); | 824 | i8042_flush(); |
824 | retval = -1; | 825 | retval = -1; |
825 | } | 826 | } |
@@ -845,7 +846,7 @@ static int __init i8042_check_aux(void) | |||
845 | static int i8042_controller_check(void) | 846 | static int i8042_controller_check(void) |
846 | { | 847 | { |
847 | if (i8042_flush() == I8042_BUFFER_SIZE) { | 848 | if (i8042_flush() == I8042_BUFFER_SIZE) { |
848 | printk(KERN_ERR "i8042.c: No controller found.\n"); | 849 | pr_err("No controller found\n"); |
849 | return -ENODEV; | 850 | return -ENODEV; |
850 | } | 851 | } |
851 | 852 | ||
@@ -864,15 +865,15 @@ static int i8042_controller_selftest(void) | |||
864 | do { | 865 | do { |
865 | 866 | ||
866 | if (i8042_command(¶m, I8042_CMD_CTL_TEST)) { | 867 | if (i8042_command(¶m, I8042_CMD_CTL_TEST)) { |
867 | printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n"); | 868 | pr_err("i8042 controller self test timeout\n"); |
868 | return -ENODEV; | 869 | return -ENODEV; |
869 | } | 870 | } |
870 | 871 | ||
871 | if (param == I8042_RET_CTL_TEST) | 872 | if (param == I8042_RET_CTL_TEST) |
872 | return 0; | 873 | return 0; |
873 | 874 | ||
874 | printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n", | 875 | pr_err("i8042 controller selftest failed. (%#x != %#x)\n", |
875 | param, I8042_RET_CTL_TEST); | 876 | param, I8042_RET_CTL_TEST); |
876 | msleep(50); | 877 | msleep(50); |
877 | } while (i++ < 5); | 878 | } while (i++ < 5); |
878 | 879 | ||
@@ -883,8 +884,7 @@ static int i8042_controller_selftest(void) | |||
883 | * and user will still get a working keyboard. This is especially | 884 | * and user will still get a working keyboard. This is especially |
884 | * important on netbooks. On other arches we trust hardware more. | 885 | * important on netbooks. On other arches we trust hardware more. |
885 | */ | 886 | */ |
886 | printk(KERN_INFO | 887 | pr_info("giving up on controller selftest, continuing anyway...\n"); |
887 | "i8042: giving up on controller selftest, continuing anyway...\n"); | ||
888 | return 0; | 888 | return 0; |
889 | #else | 889 | #else |
890 | return -EIO; | 890 | return -EIO; |
@@ -909,8 +909,7 @@ static int i8042_controller_init(void) | |||
909 | 909 | ||
910 | do { | 910 | do { |
911 | if (n >= 10) { | 911 | if (n >= 10) { |
912 | printk(KERN_ERR | 912 | pr_err("Unable to get stable CTR read\n"); |
913 | "i8042.c: Unable to get stable CTR read.\n"); | ||
914 | return -EIO; | 913 | return -EIO; |
915 | } | 914 | } |
916 | 915 | ||
@@ -918,8 +917,7 @@ static int i8042_controller_init(void) | |||
918 | udelay(50); | 917 | udelay(50); |
919 | 918 | ||
920 | if (i8042_command(&ctr[n++ % 2], I8042_CMD_CTL_RCTR)) { | 919 | if (i8042_command(&ctr[n++ % 2], I8042_CMD_CTL_RCTR)) { |
921 | printk(KERN_ERR | 920 | pr_err("Can't read CTR while initializing i8042\n"); |
922 | "i8042.c: Can't read CTR while initializing i8042.\n"); | ||
923 | return -EIO; | 921 | return -EIO; |
924 | } | 922 | } |
925 | 923 | ||
@@ -943,7 +941,7 @@ static int i8042_controller_init(void) | |||
943 | if (i8042_unlock) | 941 | if (i8042_unlock) |
944 | i8042_ctr |= I8042_CTR_IGNKEYLOCK; | 942 | i8042_ctr |= I8042_CTR_IGNKEYLOCK; |
945 | else | 943 | else |
946 | printk(KERN_WARNING "i8042.c: Warning: Keylock active.\n"); | 944 | pr_warn("Warning: Keylock active\n"); |
947 | } | 945 | } |
948 | spin_unlock_irqrestore(&i8042_lock, flags); | 946 | spin_unlock_irqrestore(&i8042_lock, flags); |
949 | 947 | ||
@@ -970,7 +968,7 @@ static int i8042_controller_init(void) | |||
970 | */ | 968 | */ |
971 | 969 | ||
972 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { | 970 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { |
973 | printk(KERN_ERR "i8042.c: Can't write CTR while initializing i8042.\n"); | 971 | pr_err("Can't write CTR while initializing i8042\n"); |
974 | return -EIO; | 972 | return -EIO; |
975 | } | 973 | } |
976 | 974 | ||
@@ -1000,7 +998,7 @@ static void i8042_controller_reset(void) | |||
1000 | i8042_ctr &= ~(I8042_CTR_KBDINT | I8042_CTR_AUXINT); | 998 | i8042_ctr &= ~(I8042_CTR_KBDINT | I8042_CTR_AUXINT); |
1001 | 999 | ||
1002 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) | 1000 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) |
1003 | printk(KERN_WARNING "i8042.c: Can't write CTR while resetting.\n"); | 1001 | pr_warn("Can't write CTR while resetting\n"); |
1004 | 1002 | ||
1005 | /* | 1003 | /* |
1006 | * Disable MUX mode if present. | 1004 | * Disable MUX mode if present. |
@@ -1021,7 +1019,7 @@ static void i8042_controller_reset(void) | |||
1021 | */ | 1019 | */ |
1022 | 1020 | ||
1023 | if (i8042_command(&i8042_initial_ctr, I8042_CMD_CTL_WCTR)) | 1021 | if (i8042_command(&i8042_initial_ctr, I8042_CMD_CTL_WCTR)) |
1024 | printk(KERN_WARNING "i8042.c: Can't restore CTR.\n"); | 1022 | pr_warn("Can't restore CTR\n"); |
1025 | } | 1023 | } |
1026 | 1024 | ||
1027 | 1025 | ||
@@ -1045,14 +1043,14 @@ static long i8042_panic_blink(int state) | |||
1045 | led = (state) ? 0x01 | 0x04 : 0; | 1043 | led = (state) ? 0x01 | 0x04 : 0; |
1046 | while (i8042_read_status() & I8042_STR_IBF) | 1044 | while (i8042_read_status() & I8042_STR_IBF) |
1047 | DELAY; | 1045 | DELAY; |
1048 | dbg("%02x -> i8042 (panic blink)", 0xed); | 1046 | dbg("%02x -> i8042 (panic blink)\n", 0xed); |
1049 | i8042_suppress_kbd_ack = 2; | 1047 | i8042_suppress_kbd_ack = 2; |
1050 | i8042_write_data(0xed); /* set leds */ | 1048 | i8042_write_data(0xed); /* set leds */ |
1051 | DELAY; | 1049 | DELAY; |
1052 | while (i8042_read_status() & I8042_STR_IBF) | 1050 | while (i8042_read_status() & I8042_STR_IBF) |
1053 | DELAY; | 1051 | DELAY; |
1054 | DELAY; | 1052 | DELAY; |
1055 | dbg("%02x -> i8042 (panic blink)", led); | 1053 | dbg("%02x -> i8042 (panic blink)\n", led); |
1056 | i8042_write_data(led); | 1054 | i8042_write_data(led); |
1057 | DELAY; | 1055 | DELAY; |
1058 | return delay; | 1056 | return delay; |
@@ -1068,9 +1066,7 @@ static void i8042_dritek_enable(void) | |||
1068 | 1066 | ||
1069 | error = i8042_command(¶m, 0x1059); | 1067 | error = i8042_command(¶m, 0x1059); |
1070 | if (error) | 1068 | if (error) |
1071 | printk(KERN_WARNING | 1069 | pr_warn("Failed to enable DRITEK extension: %d\n", error); |
1072 | "Failed to enable DRITEK extension: %d\n", | ||
1073 | error); | ||
1074 | } | 1070 | } |
1075 | #endif | 1071 | #endif |
1076 | 1072 | ||
@@ -1105,10 +1101,10 @@ static int i8042_controller_resume(bool force_reset) | |||
1105 | i8042_ctr |= I8042_CTR_AUXDIS | I8042_CTR_KBDDIS; | 1101 | i8042_ctr |= I8042_CTR_AUXDIS | I8042_CTR_KBDDIS; |
1106 | i8042_ctr &= ~(I8042_CTR_AUXINT | I8042_CTR_KBDINT); | 1102 | i8042_ctr &= ~(I8042_CTR_AUXINT | I8042_CTR_KBDINT); |
1107 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { | 1103 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { |
1108 | printk(KERN_WARNING "i8042: Can't write CTR to resume, retrying...\n"); | 1104 | pr_warn("Can't write CTR to resume, retrying...\n"); |
1109 | msleep(50); | 1105 | msleep(50); |
1110 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { | 1106 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { |
1111 | printk(KERN_ERR "i8042: CTR write retry failed\n"); | 1107 | pr_err("CTR write retry failed\n"); |
1112 | return -EIO; | 1108 | return -EIO; |
1113 | } | 1109 | } |
1114 | } | 1110 | } |
@@ -1121,9 +1117,7 @@ static int i8042_controller_resume(bool force_reset) | |||
1121 | 1117 | ||
1122 | if (i8042_mux_present) { | 1118 | if (i8042_mux_present) { |
1123 | if (i8042_set_mux_mode(true, NULL) || i8042_enable_mux_ports()) | 1119 | if (i8042_set_mux_mode(true, NULL) || i8042_enable_mux_ports()) |
1124 | printk(KERN_WARNING | 1120 | pr_warn("failed to resume active multiplexor, mouse won't work\n"); |
1125 | "i8042: failed to resume active multiplexor, " | ||
1126 | "mouse won't work.\n"); | ||
1127 | } else if (i8042_ports[I8042_AUX_PORT_NO].serio) | 1121 | } else if (i8042_ports[I8042_AUX_PORT_NO].serio) |
1128 | i8042_enable_aux_port(); | 1122 | i8042_enable_aux_port(); |
1129 | 1123 | ||
diff --git a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h index cbc1beb66574..ac1d759d0f55 100644 --- a/drivers/input/serio/i8042.h +++ b/drivers/input/serio/i8042.h | |||
@@ -89,15 +89,19 @@ | |||
89 | #ifdef DEBUG | 89 | #ifdef DEBUG |
90 | static unsigned long i8042_start_time; | 90 | static unsigned long i8042_start_time; |
91 | #define dbg_init() do { i8042_start_time = jiffies; } while (0) | 91 | #define dbg_init() do { i8042_start_time = jiffies; } while (0) |
92 | #define dbg(format, arg...) \ | 92 | #define dbg(format, arg...) \ |
93 | do { \ | 93 | do { \ |
94 | if (i8042_debug) \ | 94 | if (i8042_debug) \ |
95 | printk(KERN_DEBUG __FILE__ ": " format " [%d]\n" , \ | 95 | printk(KERN_DEBUG KBUILD_MODNAME ": [%d] " format, \ |
96 | ## arg, (int) (jiffies - i8042_start_time)); \ | 96 | (int) (jiffies - i8042_start_time), ##arg); \ |
97 | } while (0) | 97 | } while (0) |
98 | #else | 98 | #else |
99 | #define dbg_init() do { } while (0) | 99 | #define dbg_init() do { } while (0) |
100 | #define dbg(format, arg...) do {} while (0) | 100 | #define dbg(format, arg...) \ |
101 | do { \ | ||
102 | if (0) \ | ||
103 | printk(KERN_DEBUG pr_fmt(format), ##arg); \ | ||
104 | } while (0) | ||
101 | #endif | 105 | #endif |
102 | 106 | ||
103 | #endif /* _I8042_H */ | 107 | #endif /* _I8042_H */ |
diff --git a/drivers/input/serio/ps2mult.c b/drivers/input/serio/ps2mult.c index 6bce22e4e495..15aa81c9f1fb 100644 --- a/drivers/input/serio/ps2mult.c +++ b/drivers/input/serio/ps2mult.c | |||
@@ -207,7 +207,7 @@ static int ps2mult_connect(struct serio *serio, struct serio_driver *drv) | |||
207 | err_out: | 207 | err_out: |
208 | while (--i >= 0) | 208 | while (--i >= 0) |
209 | kfree(psm->ports[i].serio); | 209 | kfree(psm->ports[i].serio); |
210 | kfree(serio); | 210 | kfree(psm); |
211 | return error; | 211 | return error; |
212 | } | 212 | } |
213 | 213 | ||
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 405bf214527c..db5b0bca1a1a 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c | |||
@@ -32,10 +32,9 @@ | |||
32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | #include <linux/serio.h> | 33 | #include <linux/serio.h> |
34 | #include <linux/errno.h> | 34 | #include <linux/errno.h> |
35 | #include <linux/wait.h> | ||
36 | #include <linux/sched.h> | 35 | #include <linux/sched.h> |
37 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
38 | #include <linux/kthread.h> | 37 | #include <linux/workqueue.h> |
39 | #include <linux/mutex.h> | 38 | #include <linux/mutex.h> |
40 | 39 | ||
41 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); | 40 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); |
@@ -44,7 +43,7 @@ MODULE_LICENSE("GPL"); | |||
44 | 43 | ||
45 | /* | 44 | /* |
46 | * serio_mutex protects entire serio subsystem and is taken every time | 45 | * serio_mutex protects entire serio subsystem and is taken every time |
47 | * serio port or driver registrered or unregistered. | 46 | * serio port or driver registered or unregistered. |
48 | */ | 47 | */ |
49 | static DEFINE_MUTEX(serio_mutex); | 48 | static DEFINE_MUTEX(serio_mutex); |
50 | 49 | ||
@@ -165,58 +164,22 @@ struct serio_event { | |||
165 | 164 | ||
166 | static DEFINE_SPINLOCK(serio_event_lock); /* protects serio_event_list */ | 165 | static DEFINE_SPINLOCK(serio_event_lock); /* protects serio_event_list */ |
167 | static LIST_HEAD(serio_event_list); | 166 | static LIST_HEAD(serio_event_list); |
168 | static DECLARE_WAIT_QUEUE_HEAD(serio_wait); | ||
169 | static struct task_struct *serio_task; | ||
170 | 167 | ||
171 | static int serio_queue_event(void *object, struct module *owner, | 168 | static struct serio_event *serio_get_event(void) |
172 | enum serio_event_type event_type) | ||
173 | { | 169 | { |
170 | struct serio_event *event = NULL; | ||
174 | unsigned long flags; | 171 | unsigned long flags; |
175 | struct serio_event *event; | ||
176 | int retval = 0; | ||
177 | 172 | ||
178 | spin_lock_irqsave(&serio_event_lock, flags); | 173 | spin_lock_irqsave(&serio_event_lock, flags); |
179 | 174 | ||
180 | /* | 175 | if (!list_empty(&serio_event_list)) { |
181 | * Scan event list for the other events for the same serio port, | 176 | event = list_first_entry(&serio_event_list, |
182 | * starting with the most recent one. If event is the same we | 177 | struct serio_event, node); |
183 | * do not need add new one. If event is of different type we | 178 | list_del_init(&event->node); |
184 | * need to add this event and should not look further because | ||
185 | * we need to preseve sequence of distinct events. | ||
186 | */ | ||
187 | list_for_each_entry_reverse(event, &serio_event_list, node) { | ||
188 | if (event->object == object) { | ||
189 | if (event->type == event_type) | ||
190 | goto out; | ||
191 | break; | ||
192 | } | ||
193 | } | ||
194 | |||
195 | event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC); | ||
196 | if (!event) { | ||
197 | pr_err("Not enough memory to queue event %d\n", event_type); | ||
198 | retval = -ENOMEM; | ||
199 | goto out; | ||
200 | } | ||
201 | |||
202 | if (!try_module_get(owner)) { | ||
203 | pr_warning("Can't get module reference, dropping event %d\n", | ||
204 | event_type); | ||
205 | kfree(event); | ||
206 | retval = -EINVAL; | ||
207 | goto out; | ||
208 | } | 179 | } |
209 | 180 | ||
210 | event->type = event_type; | ||
211 | event->object = object; | ||
212 | event->owner = owner; | ||
213 | |||
214 | list_add_tail(&event->node, &serio_event_list); | ||
215 | wake_up(&serio_wait); | ||
216 | |||
217 | out: | ||
218 | spin_unlock_irqrestore(&serio_event_lock, flags); | 181 | spin_unlock_irqrestore(&serio_event_lock, flags); |
219 | return retval; | 182 | return event; |
220 | } | 183 | } |
221 | 184 | ||
222 | static void serio_free_event(struct serio_event *event) | 185 | static void serio_free_event(struct serio_event *event) |
@@ -250,25 +213,7 @@ static void serio_remove_duplicate_events(struct serio_event *event) | |||
250 | spin_unlock_irqrestore(&serio_event_lock, flags); | 213 | spin_unlock_irqrestore(&serio_event_lock, flags); |
251 | } | 214 | } |
252 | 215 | ||
253 | 216 | static void serio_handle_event(struct work_struct *work) | |
254 | static struct serio_event *serio_get_event(void) | ||
255 | { | ||
256 | struct serio_event *event = NULL; | ||
257 | unsigned long flags; | ||
258 | |||
259 | spin_lock_irqsave(&serio_event_lock, flags); | ||
260 | |||
261 | if (!list_empty(&serio_event_list)) { | ||
262 | event = list_first_entry(&serio_event_list, | ||
263 | struct serio_event, node); | ||
264 | list_del_init(&event->node); | ||
265 | } | ||
266 | |||
267 | spin_unlock_irqrestore(&serio_event_lock, flags); | ||
268 | return event; | ||
269 | } | ||
270 | |||
271 | static void serio_handle_event(void) | ||
272 | { | 217 | { |
273 | struct serio_event *event; | 218 | struct serio_event *event; |
274 | 219 | ||
@@ -307,6 +252,59 @@ static void serio_handle_event(void) | |||
307 | mutex_unlock(&serio_mutex); | 252 | mutex_unlock(&serio_mutex); |
308 | } | 253 | } |
309 | 254 | ||
255 | static DECLARE_WORK(serio_event_work, serio_handle_event); | ||
256 | |||
257 | static int serio_queue_event(void *object, struct module *owner, | ||
258 | enum serio_event_type event_type) | ||
259 | { | ||
260 | unsigned long flags; | ||
261 | struct serio_event *event; | ||
262 | int retval = 0; | ||
263 | |||
264 | spin_lock_irqsave(&serio_event_lock, flags); | ||
265 | |||
266 | /* | ||
267 | * Scan event list for the other events for the same serio port, | ||
268 | * starting with the most recent one. If event is the same we | ||
269 | * do not need add new one. If event is of different type we | ||
270 | * need to add this event and should not look further because | ||
271 | * we need to preseve sequence of distinct events. | ||
272 | */ | ||
273 | list_for_each_entry_reverse(event, &serio_event_list, node) { | ||
274 | if (event->object == object) { | ||
275 | if (event->type == event_type) | ||
276 | goto out; | ||
277 | break; | ||
278 | } | ||
279 | } | ||
280 | |||
281 | event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC); | ||
282 | if (!event) { | ||
283 | pr_err("Not enough memory to queue event %d\n", event_type); | ||
284 | retval = -ENOMEM; | ||
285 | goto out; | ||
286 | } | ||
287 | |||
288 | if (!try_module_get(owner)) { | ||
289 | pr_warning("Can't get module reference, dropping event %d\n", | ||
290 | event_type); | ||
291 | kfree(event); | ||
292 | retval = -EINVAL; | ||
293 | goto out; | ||
294 | } | ||
295 | |||
296 | event->type = event_type; | ||
297 | event->object = object; | ||
298 | event->owner = owner; | ||
299 | |||
300 | list_add_tail(&event->node, &serio_event_list); | ||
301 | schedule_work(&serio_event_work); | ||
302 | |||
303 | out: | ||
304 | spin_unlock_irqrestore(&serio_event_lock, flags); | ||
305 | return retval; | ||
306 | } | ||
307 | |||
310 | /* | 308 | /* |
311 | * Remove all events that have been submitted for a given | 309 | * Remove all events that have been submitted for a given |
312 | * object, be it serio port or driver. | 310 | * object, be it serio port or driver. |
@@ -356,18 +354,6 @@ static struct serio *serio_get_pending_child(struct serio *parent) | |||
356 | return child; | 354 | return child; |
357 | } | 355 | } |
358 | 356 | ||
359 | static int serio_thread(void *nothing) | ||
360 | { | ||
361 | do { | ||
362 | serio_handle_event(); | ||
363 | wait_event_interruptible(serio_wait, | ||
364 | kthread_should_stop() || !list_empty(&serio_event_list)); | ||
365 | } while (!kthread_should_stop()); | ||
366 | |||
367 | return 0; | ||
368 | } | ||
369 | |||
370 | |||
371 | /* | 357 | /* |
372 | * Serio port operations | 358 | * Serio port operations |
373 | */ | 359 | */ |
@@ -1040,21 +1026,18 @@ static int __init serio_init(void) | |||
1040 | return error; | 1026 | return error; |
1041 | } | 1027 | } |
1042 | 1028 | ||
1043 | serio_task = kthread_run(serio_thread, NULL, "kseriod"); | ||
1044 | if (IS_ERR(serio_task)) { | ||
1045 | bus_unregister(&serio_bus); | ||
1046 | error = PTR_ERR(serio_task); | ||
1047 | pr_err("Failed to start kseriod, error: %d\n", error); | ||
1048 | return error; | ||
1049 | } | ||
1050 | |||
1051 | return 0; | 1029 | return 0; |
1052 | } | 1030 | } |
1053 | 1031 | ||
1054 | static void __exit serio_exit(void) | 1032 | static void __exit serio_exit(void) |
1055 | { | 1033 | { |
1056 | bus_unregister(&serio_bus); | 1034 | bus_unregister(&serio_bus); |
1057 | kthread_stop(serio_task); | 1035 | |
1036 | /* | ||
1037 | * There should not be any outstanding events but work may | ||
1038 | * still be scheduled so simply cancel it. | ||
1039 | */ | ||
1040 | cancel_work_sync(&serio_event_work); | ||
1058 | } | 1041 | } |
1059 | 1042 | ||
1060 | subsys_initcall(serio_init); | 1043 | subsys_initcall(serio_init); |
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h index de5adb109030..23317bd09c82 100644 --- a/drivers/input/tablet/wacom.h +++ b/drivers/input/tablet/wacom.h | |||
@@ -103,6 +103,7 @@ MODULE_DESCRIPTION(DRIVER_DESC); | |||
103 | MODULE_LICENSE(DRIVER_LICENSE); | 103 | MODULE_LICENSE(DRIVER_LICENSE); |
104 | 104 | ||
105 | #define USB_VENDOR_ID_WACOM 0x056a | 105 | #define USB_VENDOR_ID_WACOM 0x056a |
106 | #define USB_VENDOR_ID_LENOVO 0x17ef | ||
106 | 107 | ||
107 | struct wacom { | 108 | struct wacom { |
108 | dma_addr_t data_dma; | 109 | dma_addr_t data_dma; |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 435b0af401e4..518782999fea 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -14,6 +14,7 @@ | |||
14 | 14 | ||
15 | #include "wacom_wac.h" | 15 | #include "wacom_wac.h" |
16 | #include "wacom.h" | 16 | #include "wacom.h" |
17 | #include <linux/input/mt.h> | ||
17 | 18 | ||
18 | static int wacom_penpartner_irq(struct wacom_wac *wacom) | 19 | static int wacom_penpartner_irq(struct wacom_wac *wacom) |
19 | { | 20 | { |
@@ -862,19 +863,21 @@ static int wacom_bpt_touch(struct wacom_wac *wacom) | |||
862 | struct wacom_features *features = &wacom->features; | 863 | struct wacom_features *features = &wacom->features; |
863 | struct input_dev *input = wacom->input; | 864 | struct input_dev *input = wacom->input; |
864 | unsigned char *data = wacom->data; | 865 | unsigned char *data = wacom->data; |
865 | int sp = 0, sx = 0, sy = 0, count = 0; | ||
866 | int i; | 866 | int i; |
867 | 867 | ||
868 | for (i = 0; i < 2; i++) { | 868 | for (i = 0; i < 2; i++) { |
869 | int p = data[9 * i + 2]; | 869 | int p = data[9 * i + 2]; |
870 | bool touch = p && !wacom->shared->stylus_in_proximity; | ||
871 | |||
870 | input_mt_slot(input, i); | 872 | input_mt_slot(input, i); |
873 | input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); | ||
871 | /* | 874 | /* |
872 | * Touch events need to be disabled while stylus is | 875 | * Touch events need to be disabled while stylus is |
873 | * in proximity because user's hand is resting on touchpad | 876 | * in proximity because user's hand is resting on touchpad |
874 | * and sending unwanted events. User expects tablet buttons | 877 | * and sending unwanted events. User expects tablet buttons |
875 | * to continue working though. | 878 | * to continue working though. |
876 | */ | 879 | */ |
877 | if (p && !wacom->shared->stylus_in_proximity) { | 880 | if (touch) { |
878 | int x = get_unaligned_be16(&data[9 * i + 3]) & 0x7ff; | 881 | int x = get_unaligned_be16(&data[9 * i + 3]) & 0x7ff; |
879 | int y = get_unaligned_be16(&data[9 * i + 5]) & 0x7ff; | 882 | int y = get_unaligned_be16(&data[9 * i + 5]) & 0x7ff; |
880 | if (features->quirks & WACOM_QUIRK_BBTOUCH_LOWRES) { | 883 | if (features->quirks & WACOM_QUIRK_BBTOUCH_LOWRES) { |
@@ -884,23 +887,10 @@ static int wacom_bpt_touch(struct wacom_wac *wacom) | |||
884 | input_report_abs(input, ABS_MT_PRESSURE, p); | 887 | input_report_abs(input, ABS_MT_PRESSURE, p); |
885 | input_report_abs(input, ABS_MT_POSITION_X, x); | 888 | input_report_abs(input, ABS_MT_POSITION_X, x); |
886 | input_report_abs(input, ABS_MT_POSITION_Y, y); | 889 | input_report_abs(input, ABS_MT_POSITION_Y, y); |
887 | if (wacom->id[i] < 0) | ||
888 | wacom->id[i] = wacom->trk_id++ & MAX_TRACKING_ID; | ||
889 | if (!count++) | ||
890 | sp = p, sx = x, sy = y; | ||
891 | } else { | ||
892 | wacom->id[i] = -1; | ||
893 | } | 890 | } |
894 | input_report_abs(input, ABS_MT_TRACKING_ID, wacom->id[i]); | ||
895 | } | 891 | } |
896 | 892 | ||
897 | input_report_key(input, BTN_TOUCH, count > 0); | 893 | input_mt_report_pointer_emulation(input, true); |
898 | input_report_key(input, BTN_TOOL_FINGER, count == 1); | ||
899 | input_report_key(input, BTN_TOOL_DOUBLETAP, count == 2); | ||
900 | |||
901 | input_report_abs(input, ABS_PRESSURE, sp); | ||
902 | input_report_abs(input, ABS_X, sx); | ||
903 | input_report_abs(input, ABS_Y, sy); | ||
904 | 894 | ||
905 | input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0); | 895 | input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0); |
906 | input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0); | 896 | input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0); |
@@ -1272,7 +1262,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1272 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | 1262 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); |
1273 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); | 1263 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); |
1274 | 1264 | ||
1275 | input_mt_create_slots(input_dev, 2); | 1265 | input_mt_init_slots(input_dev, 2); |
1276 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | 1266 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, |
1277 | 0, features->x_max, | 1267 | 0, features->x_max, |
1278 | features->x_fuzz, 0); | 1268 | features->x_fuzz, 0); |
@@ -1282,8 +1272,6 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1282 | input_set_abs_params(input_dev, ABS_MT_PRESSURE, | 1272 | input_set_abs_params(input_dev, ABS_MT_PRESSURE, |
1283 | 0, features->pressure_max, | 1273 | 0, features->pressure_max, |
1284 | features->pressure_fuzz, 0); | 1274 | features->pressure_fuzz, 0); |
1285 | input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0, | ||
1286 | MAX_TRACKING_ID, 0, 0); | ||
1287 | } else if (features->device_type == BTN_TOOL_PEN) { | 1275 | } else if (features->device_type == BTN_TOOL_PEN) { |
1288 | __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); | 1276 | __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); |
1289 | __set_bit(BTN_TOOL_PEN, input_dev->keybit); | 1277 | __set_bit(BTN_TOOL_PEN, input_dev->keybit); |
@@ -1444,11 +1432,17 @@ static struct wacom_features wacom_features_0xDA = | |||
1444 | { "Wacom Bamboo 2FG 4x5 SE", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; | 1432 | { "Wacom Bamboo 2FG 4x5 SE", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; |
1445 | static struct wacom_features wacom_features_0xDB = | 1433 | static struct wacom_features wacom_features_0xDB = |
1446 | { "Wacom Bamboo 2FG 6x8 SE", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; | 1434 | { "Wacom Bamboo 2FG 6x8 SE", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; |
1435 | static const struct wacom_features wacom_features_0x6004 = | ||
1436 | { "ISD-V4", WACOM_PKGLEN_GRAPHIRE, 12800, 8000, 255, 0, TABLETPC }; | ||
1447 | 1437 | ||
1448 | #define USB_DEVICE_WACOM(prod) \ | 1438 | #define USB_DEVICE_WACOM(prod) \ |
1449 | USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \ | 1439 | USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \ |
1450 | .driver_info = (kernel_ulong_t)&wacom_features_##prod | 1440 | .driver_info = (kernel_ulong_t)&wacom_features_##prod |
1451 | 1441 | ||
1442 | #define USB_DEVICE_LENOVO(prod) \ | ||
1443 | USB_DEVICE(USB_VENDOR_ID_LENOVO, prod), \ | ||
1444 | .driver_info = (kernel_ulong_t)&wacom_features_##prod | ||
1445 | |||
1452 | const struct usb_device_id wacom_ids[] = { | 1446 | const struct usb_device_id wacom_ids[] = { |
1453 | { USB_DEVICE_WACOM(0x00) }, | 1447 | { USB_DEVICE_WACOM(0x00) }, |
1454 | { USB_DEVICE_WACOM(0x10) }, | 1448 | { USB_DEVICE_WACOM(0x10) }, |
@@ -1525,6 +1519,7 @@ const struct usb_device_id wacom_ids[] = { | |||
1525 | { USB_DEVICE_WACOM(0xE2) }, | 1519 | { USB_DEVICE_WACOM(0xE2) }, |
1526 | { USB_DEVICE_WACOM(0xE3) }, | 1520 | { USB_DEVICE_WACOM(0xE3) }, |
1527 | { USB_DEVICE_WACOM(0x47) }, | 1521 | { USB_DEVICE_WACOM(0x47) }, |
1522 | { USB_DEVICE_LENOVO(0x6004) }, | ||
1528 | { } | 1523 | { } |
1529 | }; | 1524 | }; |
1530 | MODULE_DEVICE_TABLE(usb, wacom_ids); | 1525 | MODULE_DEVICE_TABLE(usb, wacom_ids); |
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index 00ca01541d89..b1310ec9720c 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h | |||
@@ -42,9 +42,6 @@ | |||
42 | #define WACOM_QUIRK_MULTI_INPUT 0x0001 | 42 | #define WACOM_QUIRK_MULTI_INPUT 0x0001 |
43 | #define WACOM_QUIRK_BBTOUCH_LOWRES 0x0002 | 43 | #define WACOM_QUIRK_BBTOUCH_LOWRES 0x0002 |
44 | 44 | ||
45 | /* largest reported tracking id */ | ||
46 | #define MAX_TRACKING_ID 0xfff | ||
47 | |||
48 | enum { | 45 | enum { |
49 | PENPARTNER = 0, | 46 | PENPARTNER = 0, |
50 | GRAPHIRE, | 47 | GRAPHIRE, |
@@ -100,7 +97,6 @@ struct wacom_wac { | |||
100 | int id[3]; | 97 | int id[3]; |
101 | __u32 serial[2]; | 98 | __u32 serial[2]; |
102 | int last_finger; | 99 | int last_finger; |
103 | int trk_id; | ||
104 | struct wacom_features features; | 100 | struct wacom_features features; |
105 | struct wacom_shared *shared; | 101 | struct wacom_shared *shared; |
106 | struct input_dev *input; | 102 | struct input_dev *input; |
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 06ea8da95c62..07ac77d393a4 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
@@ -659,17 +659,17 @@ config TOUCHSCREEN_PCAP | |||
659 | To compile this driver as a module, choose M here: the | 659 | To compile this driver as a module, choose M here: the |
660 | module will be called pcap_ts. | 660 | module will be called pcap_ts. |
661 | 661 | ||
662 | config TOUCHSCREEN_TPS6507X | 662 | config TOUCHSCREEN_ST1232 |
663 | tristate "TPS6507x based touchscreens" | 663 | tristate "Sitronix ST1232 touchscreen controllers" |
664 | depends on I2C | 664 | depends on I2C |
665 | help | 665 | help |
666 | Say Y here if you have a TPS6507x based touchscreen | 666 | Say Y here if you want to support Sitronix ST1232 |
667 | controller. | 667 | touchscreen controller. |
668 | 668 | ||
669 | If unsure, say N. | 669 | If unsure, say N. |
670 | 670 | ||
671 | To compile this driver as a module, choose M here: the | 671 | To compile this driver as a module, choose M here: the |
672 | module will be called tps6507x_ts. | 672 | module will be called st1232_ts. |
673 | 673 | ||
674 | config TOUCHSCREEN_STMPE | 674 | config TOUCHSCREEN_STMPE |
675 | tristate "STMicroelectronics STMPE touchscreens" | 675 | tristate "STMicroelectronics STMPE touchscreens" |
@@ -681,4 +681,16 @@ config TOUCHSCREEN_STMPE | |||
681 | To compile this driver as a module, choose M here: the | 681 | To compile this driver as a module, choose M here: the |
682 | module will be called stmpe-ts. | 682 | module will be called stmpe-ts. |
683 | 683 | ||
684 | config TOUCHSCREEN_TPS6507X | ||
685 | tristate "TPS6507x based touchscreens" | ||
686 | depends on I2C | ||
687 | help | ||
688 | Say Y here if you have a TPS6507x based touchscreen | ||
689 | controller. | ||
690 | |||
691 | If unsure, say N. | ||
692 | |||
693 | To compile this driver as a module, choose M here: the | ||
694 | module will be called tps6507x_ts. | ||
695 | |||
684 | endif | 696 | endif |
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 7cc1b4f4b677..718bcc814952 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile | |||
@@ -39,6 +39,7 @@ obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o | |||
39 | obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o | 39 | obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o |
40 | obj-$(CONFIG_TOUCHSCREEN_QT602240) += qt602240_ts.o | 40 | obj-$(CONFIG_TOUCHSCREEN_QT602240) += qt602240_ts.o |
41 | obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o | 41 | obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o |
42 | obj-$(CONFIG_TOUCHSCREEN_ST1232) += st1232.o | ||
42 | obj-$(CONFIG_TOUCHSCREEN_STMPE) += stmpe-ts.o | 43 | obj-$(CONFIG_TOUCHSCREEN_STMPE) += stmpe-ts.o |
43 | obj-$(CONFIG_TOUCHSCREEN_TNETV107X) += tnetv107x-ts.o | 44 | obj-$(CONFIG_TOUCHSCREEN_TNETV107X) += tnetv107x-ts.o |
44 | obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o | 45 | obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o |
diff --git a/drivers/input/touchscreen/bu21013_ts.c b/drivers/input/touchscreen/bu21013_ts.c index 2ca9e5d66460..f7fa9ef4cd65 100644 --- a/drivers/input/touchscreen/bu21013_ts.c +++ b/drivers/input/touchscreen/bu21013_ts.c | |||
@@ -365,7 +365,7 @@ static int bu21013_init_chip(struct bu21013_ts_data *data) | |||
365 | } | 365 | } |
366 | 366 | ||
367 | retval = i2c_smbus_write_byte_data(i2c, BU21013_TH_OFF_REG, | 367 | retval = i2c_smbus_write_byte_data(i2c, BU21013_TH_OFF_REG, |
368 | BU21013_TH_OFF_4 || BU21013_TH_OFF_3); | 368 | BU21013_TH_OFF_4 | BU21013_TH_OFF_3); |
369 | if (retval < 0) { | 369 | if (retval < 0) { |
370 | dev_err(&i2c->dev, "BU21013_TH_OFF reg write failed\n"); | 370 | dev_err(&i2c->dev, "BU21013_TH_OFF reg write failed\n"); |
371 | return retval; | 371 | return retval; |
diff --git a/drivers/input/touchscreen/qt602240_ts.c b/drivers/input/touchscreen/qt602240_ts.c index 66b26ad3032a..4dcb0e872f6a 100644 --- a/drivers/input/touchscreen/qt602240_ts.c +++ b/drivers/input/touchscreen/qt602240_ts.c | |||
@@ -969,7 +969,7 @@ static int qt602240_initialize(struct qt602240_data *data) | |||
969 | return error; | 969 | return error; |
970 | 970 | ||
971 | data->object_table = kcalloc(info->object_num, | 971 | data->object_table = kcalloc(info->object_num, |
972 | sizeof(struct qt602240_data), | 972 | sizeof(struct qt602240_object), |
973 | GFP_KERNEL); | 973 | GFP_KERNEL); |
974 | if (!data->object_table) { | 974 | if (!data->object_table) { |
975 | dev_err(&client->dev, "Failed to allocate memory\n"); | 975 | dev_err(&client->dev, "Failed to allocate memory\n"); |
@@ -1324,8 +1324,9 @@ static int __devexit qt602240_remove(struct i2c_client *client) | |||
1324 | } | 1324 | } |
1325 | 1325 | ||
1326 | #ifdef CONFIG_PM | 1326 | #ifdef CONFIG_PM |
1327 | static int qt602240_suspend(struct i2c_client *client, pm_message_t mesg) | 1327 | static int qt602240_suspend(struct device *dev) |
1328 | { | 1328 | { |
1329 | struct i2c_client *client = to_i2c_client(dev); | ||
1329 | struct qt602240_data *data = i2c_get_clientdata(client); | 1330 | struct qt602240_data *data = i2c_get_clientdata(client); |
1330 | struct input_dev *input_dev = data->input_dev; | 1331 | struct input_dev *input_dev = data->input_dev; |
1331 | 1332 | ||
@@ -1339,8 +1340,9 @@ static int qt602240_suspend(struct i2c_client *client, pm_message_t mesg) | |||
1339 | return 0; | 1340 | return 0; |
1340 | } | 1341 | } |
1341 | 1342 | ||
1342 | static int qt602240_resume(struct i2c_client *client) | 1343 | static int qt602240_resume(struct device *dev) |
1343 | { | 1344 | { |
1345 | struct i2c_client *client = to_i2c_client(dev); | ||
1344 | struct qt602240_data *data = i2c_get_clientdata(client); | 1346 | struct qt602240_data *data = i2c_get_clientdata(client); |
1345 | struct input_dev *input_dev = data->input_dev; | 1347 | struct input_dev *input_dev = data->input_dev; |
1346 | 1348 | ||
@@ -1359,9 +1361,11 @@ static int qt602240_resume(struct i2c_client *client) | |||
1359 | 1361 | ||
1360 | return 0; | 1362 | return 0; |
1361 | } | 1363 | } |
1362 | #else | 1364 | |
1363 | #define qt602240_suspend NULL | 1365 | static const struct dev_pm_ops qt602240_pm_ops = { |
1364 | #define qt602240_resume NULL | 1366 | .suspend = qt602240_suspend, |
1367 | .resume = qt602240_resume, | ||
1368 | }; | ||
1365 | #endif | 1369 | #endif |
1366 | 1370 | ||
1367 | static const struct i2c_device_id qt602240_id[] = { | 1371 | static const struct i2c_device_id qt602240_id[] = { |
@@ -1374,11 +1378,12 @@ static struct i2c_driver qt602240_driver = { | |||
1374 | .driver = { | 1378 | .driver = { |
1375 | .name = "qt602240_ts", | 1379 | .name = "qt602240_ts", |
1376 | .owner = THIS_MODULE, | 1380 | .owner = THIS_MODULE, |
1381 | #ifdef CONFIG_PM | ||
1382 | .pm = &qt602240_pm_ops, | ||
1383 | #endif | ||
1377 | }, | 1384 | }, |
1378 | .probe = qt602240_probe, | 1385 | .probe = qt602240_probe, |
1379 | .remove = __devexit_p(qt602240_remove), | 1386 | .remove = __devexit_p(qt602240_remove), |
1380 | .suspend = qt602240_suspend, | ||
1381 | .resume = qt602240_resume, | ||
1382 | .id_table = qt602240_id, | 1387 | .id_table = qt602240_id, |
1383 | }; | 1388 | }; |
1384 | 1389 | ||
diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c new file mode 100644 index 000000000000..4ab371358b33 --- /dev/null +++ b/drivers/input/touchscreen/st1232.c | |||
@@ -0,0 +1,274 @@ | |||
1 | /* | ||
2 | * ST1232 Touchscreen Controller Driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Renesas Solutions Corp. | ||
5 | * Tony SIM <chinyeow.sim.xt@renesas.com> | ||
6 | * | ||
7 | * Using code from: | ||
8 | * - android.git.kernel.org: projects/kernel/common.git: synaptics_i2c_rmi.c | ||
9 | * Copyright (C) 2007 Google, Inc. | ||
10 | * | ||
11 | * This software is licensed under the terms of the GNU General Public | ||
12 | * License version 2, as published by the Free Software Foundation, and | ||
13 | * may be copied, distributed, and modified under those terms. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | */ | ||
20 | |||
21 | #include <linux/delay.h> | ||
22 | #include <linux/i2c.h> | ||
23 | #include <linux/input.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include <linux/types.h> | ||
28 | |||
29 | #define ST1232_TS_NAME "st1232-ts" | ||
30 | |||
31 | #define MIN_X 0x00 | ||
32 | #define MIN_Y 0x00 | ||
33 | #define MAX_X 0x31f /* (800 - 1) */ | ||
34 | #define MAX_Y 0x1df /* (480 - 1) */ | ||
35 | #define MAX_AREA 0xff | ||
36 | #define MAX_FINGERS 2 | ||
37 | |||
38 | struct st1232_ts_finger { | ||
39 | u16 x; | ||
40 | u16 y; | ||
41 | u8 t; | ||
42 | bool is_valid; | ||
43 | }; | ||
44 | |||
45 | struct st1232_ts_data { | ||
46 | struct i2c_client *client; | ||
47 | struct input_dev *input_dev; | ||
48 | struct st1232_ts_finger finger[MAX_FINGERS]; | ||
49 | }; | ||
50 | |||
51 | static int st1232_ts_read_data(struct st1232_ts_data *ts) | ||
52 | { | ||
53 | struct st1232_ts_finger *finger = ts->finger; | ||
54 | struct i2c_client *client = ts->client; | ||
55 | struct i2c_msg msg[2]; | ||
56 | int error; | ||
57 | u8 start_reg; | ||
58 | u8 buf[10]; | ||
59 | |||
60 | /* read touchscreen data from ST1232 */ | ||
61 | msg[0].addr = client->addr; | ||
62 | msg[0].flags = 0; | ||
63 | msg[0].len = 1; | ||
64 | msg[0].buf = &start_reg; | ||
65 | start_reg = 0x10; | ||
66 | |||
67 | msg[1].addr = ts->client->addr; | ||
68 | msg[1].flags = I2C_M_RD; | ||
69 | msg[1].len = sizeof(buf); | ||
70 | msg[1].buf = buf; | ||
71 | |||
72 | error = i2c_transfer(client->adapter, msg, 2); | ||
73 | if (error < 0) | ||
74 | return error; | ||
75 | |||
76 | /* get "valid" bits */ | ||
77 | finger[0].is_valid = buf[2] >> 7; | ||
78 | finger[1].is_valid = buf[5] >> 7; | ||
79 | |||
80 | /* get xy coordinate */ | ||
81 | if (finger[0].is_valid) { | ||
82 | finger[0].x = ((buf[2] & 0x0070) << 4) | buf[3]; | ||
83 | finger[0].y = ((buf[2] & 0x0007) << 8) | buf[4]; | ||
84 | finger[0].t = buf[8]; | ||
85 | } | ||
86 | |||
87 | if (finger[1].is_valid) { | ||
88 | finger[1].x = ((buf[5] & 0x0070) << 4) | buf[6]; | ||
89 | finger[1].y = ((buf[5] & 0x0007) << 8) | buf[7]; | ||
90 | finger[1].t = buf[9]; | ||
91 | } | ||
92 | |||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | static irqreturn_t st1232_ts_irq_handler(int irq, void *dev_id) | ||
97 | { | ||
98 | struct st1232_ts_data *ts = dev_id; | ||
99 | struct st1232_ts_finger *finger = ts->finger; | ||
100 | struct input_dev *input_dev = ts->input_dev; | ||
101 | int count = 0; | ||
102 | int i, ret; | ||
103 | |||
104 | ret = st1232_ts_read_data(ts); | ||
105 | if (ret < 0) | ||
106 | goto end; | ||
107 | |||
108 | /* multi touch protocol */ | ||
109 | for (i = 0; i < MAX_FINGERS; i++) { | ||
110 | if (!finger[i].is_valid) | ||
111 | continue; | ||
112 | |||
113 | input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, finger[i].t); | ||
114 | input_report_abs(input_dev, ABS_MT_POSITION_X, finger[i].x); | ||
115 | input_report_abs(input_dev, ABS_MT_POSITION_Y, finger[i].y); | ||
116 | input_mt_sync(input_dev); | ||
117 | count++; | ||
118 | } | ||
119 | |||
120 | /* SYN_MT_REPORT only if no contact */ | ||
121 | if (!count) | ||
122 | input_mt_sync(input_dev); | ||
123 | |||
124 | /* SYN_REPORT */ | ||
125 | input_sync(input_dev); | ||
126 | |||
127 | end: | ||
128 | return IRQ_HANDLED; | ||
129 | } | ||
130 | |||
131 | static int __devinit st1232_ts_probe(struct i2c_client *client, | ||
132 | const struct i2c_device_id *id) | ||
133 | { | ||
134 | struct st1232_ts_data *ts; | ||
135 | struct input_dev *input_dev; | ||
136 | int error; | ||
137 | |||
138 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { | ||
139 | dev_err(&client->dev, "need I2C_FUNC_I2C\n"); | ||
140 | return -EIO; | ||
141 | } | ||
142 | |||
143 | if (!client->irq) { | ||
144 | dev_err(&client->dev, "no IRQ?\n"); | ||
145 | return -EINVAL; | ||
146 | } | ||
147 | |||
148 | |||
149 | ts = kzalloc(sizeof(struct st1232_ts_data), GFP_KERNEL); | ||
150 | input_dev = input_allocate_device(); | ||
151 | if (!ts || !input_dev) { | ||
152 | error = -ENOMEM; | ||
153 | goto err_free_mem; | ||
154 | } | ||
155 | |||
156 | ts->client = client; | ||
157 | ts->input_dev = input_dev; | ||
158 | |||
159 | input_dev->name = "st1232-touchscreen"; | ||
160 | input_dev->id.bustype = BUS_I2C; | ||
161 | input_dev->dev.parent = &client->dev; | ||
162 | |||
163 | __set_bit(EV_SYN, input_dev->evbit); | ||
164 | __set_bit(EV_KEY, input_dev->evbit); | ||
165 | __set_bit(EV_ABS, input_dev->evbit); | ||
166 | |||
167 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, MAX_AREA, 0, 0); | ||
168 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, MIN_X, MAX_X, 0, 0); | ||
169 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, MIN_Y, MAX_Y, 0, 0); | ||
170 | |||
171 | error = request_threaded_irq(client->irq, NULL, st1232_ts_irq_handler, | ||
172 | IRQF_ONESHOT, client->name, ts); | ||
173 | if (error) { | ||
174 | dev_err(&client->dev, "Failed to register interrupt\n"); | ||
175 | goto err_free_mem; | ||
176 | } | ||
177 | |||
178 | error = input_register_device(ts->input_dev); | ||
179 | if (error) { | ||
180 | dev_err(&client->dev, "Unable to register %s input device\n", | ||
181 | input_dev->name); | ||
182 | goto err_free_irq; | ||
183 | } | ||
184 | |||
185 | i2c_set_clientdata(client, ts); | ||
186 | device_init_wakeup(&client->dev, 1); | ||
187 | |||
188 | return 0; | ||
189 | |||
190 | err_free_irq: | ||
191 | free_irq(client->irq, ts); | ||
192 | err_free_mem: | ||
193 | input_free_device(input_dev); | ||
194 | kfree(ts); | ||
195 | return error; | ||
196 | } | ||
197 | |||
198 | static int __devexit st1232_ts_remove(struct i2c_client *client) | ||
199 | { | ||
200 | struct st1232_ts_data *ts = i2c_get_clientdata(client); | ||
201 | |||
202 | device_init_wakeup(&client->dev, 0); | ||
203 | free_irq(client->irq, ts); | ||
204 | input_unregister_device(ts->input_dev); | ||
205 | kfree(ts); | ||
206 | |||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | #ifdef CONFIG_PM | ||
211 | static int st1232_ts_suspend(struct device *dev) | ||
212 | { | ||
213 | struct i2c_client *client = to_i2c_client(dev); | ||
214 | |||
215 | if (device_may_wakeup(&client->dev)) | ||
216 | enable_irq_wake(client->irq); | ||
217 | else | ||
218 | disable_irq(client->irq); | ||
219 | |||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | static int st1232_ts_resume(struct device *dev) | ||
224 | { | ||
225 | struct i2c_client *client = to_i2c_client(dev); | ||
226 | |||
227 | if (device_may_wakeup(&client->dev)) | ||
228 | disable_irq_wake(client->irq); | ||
229 | else | ||
230 | enable_irq(client->irq); | ||
231 | |||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | static const struct dev_pm_ops st1232_ts_pm_ops = { | ||
236 | .suspend = st1232_ts_suspend, | ||
237 | .resume = st1232_ts_resume, | ||
238 | }; | ||
239 | #endif | ||
240 | |||
241 | static const struct i2c_device_id st1232_ts_id[] = { | ||
242 | { ST1232_TS_NAME, 0 }, | ||
243 | { } | ||
244 | }; | ||
245 | MODULE_DEVICE_TABLE(i2c, st1232_ts_id); | ||
246 | |||
247 | static struct i2c_driver st1232_ts_driver = { | ||
248 | .probe = st1232_ts_probe, | ||
249 | .remove = __devexit_p(st1232_ts_remove), | ||
250 | .id_table = st1232_ts_id, | ||
251 | .driver = { | ||
252 | .name = ST1232_TS_NAME, | ||
253 | .owner = THIS_MODULE, | ||
254 | #ifdef CONFIG_PM | ||
255 | .pm = &st1232_ts_pm_ops, | ||
256 | #endif | ||
257 | }, | ||
258 | }; | ||
259 | |||
260 | static int __init st1232_ts_init(void) | ||
261 | { | ||
262 | return i2c_add_driver(&st1232_ts_driver); | ||
263 | } | ||
264 | module_init(st1232_ts_init); | ||
265 | |||
266 | static void __exit st1232_ts_exit(void) | ||
267 | { | ||
268 | i2c_del_driver(&st1232_ts_driver); | ||
269 | } | ||
270 | module_exit(st1232_ts_exit); | ||
271 | |||
272 | MODULE_AUTHOR("Tony SIM <chinyeow.sim.xt@renesas.com>"); | ||
273 | MODULE_DESCRIPTION("SITRONIX ST1232 Touchscreen Controller Driver"); | ||
274 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c index 9ae4c7b16ba7..8ed53aded2d3 100644 --- a/drivers/input/touchscreen/wacom_w8001.c +++ b/drivers/input/touchscreen/wacom_w8001.c | |||
@@ -15,10 +15,11 @@ | |||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/input.h> | 18 | #include <linux/input/mt.h> |
19 | #include <linux/serio.h> | 19 | #include <linux/serio.h> |
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <linux/ctype.h> | 21 | #include <linux/ctype.h> |
22 | #include <linux/delay.h> | ||
22 | 23 | ||
23 | #define DRIVER_DESC "Wacom W8001 serial touchscreen driver" | 24 | #define DRIVER_DESC "Wacom W8001 serial touchscreen driver" |
24 | 25 | ||
@@ -37,6 +38,7 @@ MODULE_LICENSE("GPL"); | |||
37 | 38 | ||
38 | #define W8001_QUERY_PACKET 0x20 | 39 | #define W8001_QUERY_PACKET 0x20 |
39 | 40 | ||
41 | #define W8001_CMD_STOP '0' | ||
40 | #define W8001_CMD_START '1' | 42 | #define W8001_CMD_START '1' |
41 | #define W8001_CMD_QUERY '*' | 43 | #define W8001_CMD_QUERY '*' |
42 | #define W8001_CMD_TOUCHQUERY '%' | 44 | #define W8001_CMD_TOUCHQUERY '%' |
@@ -48,8 +50,6 @@ MODULE_LICENSE("GPL"); | |||
48 | #define W8001_PKTLEN_TPCCTL 11 /* control packet */ | 50 | #define W8001_PKTLEN_TPCCTL 11 /* control packet */ |
49 | #define W8001_PKTLEN_TOUCH2FG 13 | 51 | #define W8001_PKTLEN_TOUCH2FG 13 |
50 | 52 | ||
51 | #define MAX_TRACKING_ID 0xFF /* arbitrarily chosen */ | ||
52 | |||
53 | struct w8001_coord { | 53 | struct w8001_coord { |
54 | u8 rdy; | 54 | u8 rdy; |
55 | u8 tsw; | 55 | u8 tsw; |
@@ -87,7 +87,6 @@ struct w8001 { | |||
87 | char phys[32]; | 87 | char phys[32]; |
88 | int type; | 88 | int type; |
89 | unsigned int pktlen; | 89 | unsigned int pktlen; |
90 | int trkid[2]; | ||
91 | }; | 90 | }; |
92 | 91 | ||
93 | static void parse_data(u8 *data, struct w8001_coord *coord) | 92 | static void parse_data(u8 *data, struct w8001_coord *coord) |
@@ -116,28 +115,23 @@ static void parse_data(u8 *data, struct w8001_coord *coord) | |||
116 | 115 | ||
117 | static void parse_touch(struct w8001 *w8001) | 116 | static void parse_touch(struct w8001 *w8001) |
118 | { | 117 | { |
119 | static int trkid; | ||
120 | struct input_dev *dev = w8001->dev; | 118 | struct input_dev *dev = w8001->dev; |
121 | unsigned char *data = w8001->data; | 119 | unsigned char *data = w8001->data; |
122 | int i; | 120 | int i; |
123 | 121 | ||
124 | for (i = 0; i < 2; i++) { | 122 | for (i = 0; i < 2; i++) { |
125 | input_mt_slot(dev, i); | 123 | bool touch = data[0] & (1 << i); |
126 | 124 | ||
127 | if (data[0] & (1 << i)) { | 125 | input_mt_slot(dev, i); |
126 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, touch); | ||
127 | if (touch) { | ||
128 | int x = (data[6 * i + 1] << 7) | (data[6 * i + 2]); | 128 | int x = (data[6 * i + 1] << 7) | (data[6 * i + 2]); |
129 | int y = (data[6 * i + 3] << 7) | (data[6 * i + 4]); | 129 | int y = (data[6 * i + 3] << 7) | (data[6 * i + 4]); |
130 | /* data[5,6] and [11,12] is finger capacity */ | 130 | /* data[5,6] and [11,12] is finger capacity */ |
131 | 131 | ||
132 | input_report_abs(dev, ABS_MT_POSITION_X, x); | 132 | input_report_abs(dev, ABS_MT_POSITION_X, x); |
133 | input_report_abs(dev, ABS_MT_POSITION_Y, y); | 133 | input_report_abs(dev, ABS_MT_POSITION_Y, y); |
134 | input_report_abs(dev, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER); | ||
135 | if (w8001->trkid[i] < 0) | ||
136 | w8001->trkid[i] = trkid++ & MAX_TRACKING_ID; | ||
137 | } else { | ||
138 | w8001->trkid[i] = -1; | ||
139 | } | 134 | } |
140 | input_report_abs(dev, ABS_MT_TRACKING_ID, w8001->trkid[i]); | ||
141 | } | 135 | } |
142 | 136 | ||
143 | input_sync(dev); | 137 | input_sync(dev); |
@@ -287,24 +281,46 @@ static int w8001_setup(struct w8001 *w8001) | |||
287 | struct w8001_coord coord; | 281 | struct w8001_coord coord; |
288 | int error; | 282 | int error; |
289 | 283 | ||
290 | error = w8001_command(w8001, W8001_CMD_QUERY, true); | 284 | error = w8001_command(w8001, W8001_CMD_STOP, false); |
291 | if (error) | 285 | if (error) |
292 | return error; | 286 | return error; |
293 | 287 | ||
294 | parse_data(w8001->response, &coord); | 288 | msleep(250); /* wait 250ms before querying the device */ |
295 | 289 | ||
296 | input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0); | 290 | /* penabled? */ |
297 | input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0); | 291 | error = w8001_command(w8001, W8001_CMD_QUERY, true); |
298 | input_set_abs_params(dev, ABS_PRESSURE, 0, coord.pen_pressure, 0, 0); | 292 | if (!error) { |
299 | input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0); | 293 | __set_bit(BTN_TOOL_PEN, dev->keybit); |
300 | input_set_abs_params(dev, ABS_TILT_Y, 0, coord.tilt_y, 0, 0); | 294 | __set_bit(BTN_TOOL_RUBBER, dev->keybit); |
295 | __set_bit(BTN_STYLUS, dev->keybit); | ||
296 | __set_bit(BTN_STYLUS2, dev->keybit); | ||
297 | parse_data(w8001->response, &coord); | ||
298 | |||
299 | input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0); | ||
300 | input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0); | ||
301 | input_set_abs_params(dev, ABS_PRESSURE, 0, coord.pen_pressure, 0, 0); | ||
302 | if (coord.tilt_x && coord.tilt_y) { | ||
303 | input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0); | ||
304 | input_set_abs_params(dev, ABS_TILT_Y, 0, coord.tilt_y, 0, 0); | ||
305 | } | ||
306 | } | ||
301 | 307 | ||
308 | /* Touch enabled? */ | ||
302 | error = w8001_command(w8001, W8001_CMD_TOUCHQUERY, true); | 309 | error = w8001_command(w8001, W8001_CMD_TOUCHQUERY, true); |
303 | if (!error) { | 310 | |
311 | /* | ||
312 | * Some non-touch devices may reply to the touch query. But their | ||
313 | * second byte is empty, which indicates touch is not supported. | ||
314 | */ | ||
315 | if (!error && w8001->response[1]) { | ||
304 | struct w8001_touch_query touch; | 316 | struct w8001_touch_query touch; |
305 | 317 | ||
306 | parse_touchquery(w8001->response, &touch); | 318 | parse_touchquery(w8001->response, &touch); |
307 | 319 | ||
320 | input_set_abs_params(dev, ABS_X, 0, touch.x, 0, 0); | ||
321 | input_set_abs_params(dev, ABS_Y, 0, touch.y, 0, 0); | ||
322 | __set_bit(BTN_TOOL_FINGER, dev->keybit); | ||
323 | |||
308 | switch (touch.sensor_id) { | 324 | switch (touch.sensor_id) { |
309 | case 0: | 325 | case 0: |
310 | case 2: | 326 | case 2: |
@@ -318,15 +334,13 @@ static int w8001_setup(struct w8001 *w8001) | |||
318 | case 5: | 334 | case 5: |
319 | w8001->pktlen = W8001_PKTLEN_TOUCH2FG; | 335 | w8001->pktlen = W8001_PKTLEN_TOUCH2FG; |
320 | 336 | ||
321 | input_mt_create_slots(dev, 2); | 337 | input_mt_init_slots(dev, 2); |
322 | input_set_abs_params(dev, ABS_MT_TRACKING_ID, | ||
323 | 0, MAX_TRACKING_ID, 0, 0); | ||
324 | input_set_abs_params(dev, ABS_MT_POSITION_X, | 338 | input_set_abs_params(dev, ABS_MT_POSITION_X, |
325 | 0, touch.x, 0, 0); | 339 | 0, touch.x, 0, 0); |
326 | input_set_abs_params(dev, ABS_MT_POSITION_Y, | 340 | input_set_abs_params(dev, ABS_MT_POSITION_Y, |
327 | 0, touch.y, 0, 0); | 341 | 0, touch.y, 0, 0); |
328 | input_set_abs_params(dev, ABS_MT_TOOL_TYPE, | 342 | input_set_abs_params(dev, ABS_MT_TOOL_TYPE, |
329 | 0, 0, 0, 0); | 343 | 0, MT_TOOL_MAX, 0, 0); |
330 | break; | 344 | break; |
331 | } | 345 | } |
332 | } | 346 | } |
@@ -372,7 +386,6 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv) | |||
372 | w8001->serio = serio; | 386 | w8001->serio = serio; |
373 | w8001->id = serio->id.id; | 387 | w8001->id = serio->id.id; |
374 | w8001->dev = input_dev; | 388 | w8001->dev = input_dev; |
375 | w8001->trkid[0] = w8001->trkid[1] = -1; | ||
376 | init_completion(&w8001->cmd_done); | 389 | init_completion(&w8001->cmd_done); |
377 | snprintf(w8001->phys, sizeof(w8001->phys), "%s/input0", serio->phys); | 390 | snprintf(w8001->phys, sizeof(w8001->phys), "%s/input0", serio->phys); |
378 | 391 | ||
@@ -385,11 +398,7 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv) | |||
385 | input_dev->dev.parent = &serio->dev; | 398 | input_dev->dev.parent = &serio->dev; |
386 | 399 | ||
387 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 400 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
388 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | 401 | __set_bit(BTN_TOUCH, input_dev->keybit); |
389 | input_dev->keybit[BIT_WORD(BTN_TOOL_PEN)] |= BIT_MASK(BTN_TOOL_PEN); | ||
390 | input_dev->keybit[BIT_WORD(BTN_TOOL_RUBBER)] |= BIT_MASK(BTN_TOOL_RUBBER); | ||
391 | input_dev->keybit[BIT_WORD(BTN_STYLUS)] |= BIT_MASK(BTN_STYLUS); | ||
392 | input_dev->keybit[BIT_WORD(BTN_STYLUS2)] |= BIT_MASK(BTN_STYLUS2); | ||
393 | 402 | ||
394 | serio_set_drvdata(serio, w8001); | 403 | serio_set_drvdata(serio, w8001); |
395 | err = serio_open(serio, drv); | 404 | err = serio_open(serio, drv); |
diff --git a/drivers/input/xen-kbdfront.c b/drivers/input/xen-kbdfront.c index e0c024db2ca5..7f85a862ad11 100644 --- a/drivers/input/xen-kbdfront.c +++ b/drivers/input/xen-kbdfront.c | |||
@@ -17,6 +17,8 @@ | |||
17 | * Switch to grant tables together with xen-fbfront.c. | 17 | * Switch to grant tables together with xen-fbfront.c. |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
21 | |||
20 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
21 | #include <linux/errno.h> | 23 | #include <linux/errno.h> |
22 | #include <linux/module.h> | 24 | #include <linux/module.h> |
@@ -84,9 +86,8 @@ static irqreturn_t input_handler(int rq, void *dev_id) | |||
84 | input_report_key(dev, event->key.keycode, | 86 | input_report_key(dev, event->key.keycode, |
85 | event->key.pressed); | 87 | event->key.pressed); |
86 | else | 88 | else |
87 | printk(KERN_WARNING | 89 | pr_warning("unhandled keycode 0x%x\n", |
88 | "xenkbd: unhandled keycode 0x%x\n", | 90 | event->key.keycode); |
89 | event->key.keycode); | ||
90 | break; | 91 | break; |
91 | case XENKBD_TYPE_POS: | 92 | case XENKBD_TYPE_POS: |
92 | input_report_abs(dev, ABS_X, event->pos.abs_x); | 93 | input_report_abs(dev, ABS_X, event->pos.abs_x); |
@@ -292,8 +293,7 @@ InitWait: | |||
292 | ret = xenbus_printf(XBT_NIL, info->xbdev->nodename, | 293 | ret = xenbus_printf(XBT_NIL, info->xbdev->nodename, |
293 | "request-abs-pointer", "1"); | 294 | "request-abs-pointer", "1"); |
294 | if (ret) | 295 | if (ret) |
295 | printk(KERN_WARNING | 296 | pr_warning("can't request abs-pointer\n"); |
296 | "xenkbd: can't request abs-pointer"); | ||
297 | } | 297 | } |
298 | xenbus_switch_state(dev, XenbusStateConnected); | 298 | xenbus_switch_state(dev, XenbusStateConnected); |
299 | break; | 299 | break; |
diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c index 067f9962f499..6a82388505f0 100644 --- a/drivers/macintosh/mac_hid.c +++ b/drivers/macintosh/mac_hid.c | |||
@@ -23,6 +23,8 @@ static int mouse_button3_keycode = KEY_RIGHTALT; /* right option key */ | |||
23 | 23 | ||
24 | static struct input_dev *mac_hid_emumouse_dev; | 24 | static struct input_dev *mac_hid_emumouse_dev; |
25 | 25 | ||
26 | static DEFINE_MUTEX(mac_hid_emumouse_mutex); | ||
27 | |||
26 | static int mac_hid_create_emumouse(void) | 28 | static int mac_hid_create_emumouse(void) |
27 | { | 29 | { |
28 | static struct lock_class_key mac_hid_emumouse_dev_event_class; | 30 | static struct lock_class_key mac_hid_emumouse_dev_event_class; |
@@ -187,6 +189,10 @@ static int mac_hid_toggle_emumouse(ctl_table *table, int write, | |||
187 | int old_val = *valp; | 189 | int old_val = *valp; |
188 | int rc; | 190 | int rc; |
189 | 191 | ||
192 | rc = mutex_lock_killable(&mac_hid_emumouse_mutex); | ||
193 | if (rc) | ||
194 | return rc; | ||
195 | |||
190 | rc = proc_dointvec(table, write, buffer, lenp, ppos); | 196 | rc = proc_dointvec(table, write, buffer, lenp, ppos); |
191 | 197 | ||
192 | if (rc == 0 && write && *valp != old_val) { | 198 | if (rc == 0 && write && *valp != old_val) { |
@@ -202,6 +208,8 @@ static int mac_hid_toggle_emumouse(ctl_table *table, int write, | |||
202 | if (rc) | 208 | if (rc) |
203 | *valp = old_val; | 209 | *valp = old_val; |
204 | 210 | ||
211 | mutex_unlock(&mac_hid_emumouse_mutex); | ||
212 | |||
205 | return rc; | 213 | return rc; |
206 | } | 214 | } |
207 | 215 | ||
diff --git a/include/linux/input.h b/include/linux/input.h index f7a6e1966df3..c4e9d91ec979 100644 --- a/include/linux/input.h +++ b/include/linux/input.h | |||
@@ -112,6 +112,7 @@ struct input_keymap_entry { | |||
112 | #define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len) /* get device name */ | 112 | #define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len) /* get device name */ |
113 | #define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len) /* get physical location */ | 113 | #define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len) /* get physical location */ |
114 | #define EVIOCGUNIQ(len) _IOC(_IOC_READ, 'E', 0x08, len) /* get unique identifier */ | 114 | #define EVIOCGUNIQ(len) _IOC(_IOC_READ, 'E', 0x08, len) /* get unique identifier */ |
115 | #define EVIOCGPROP(len) _IOC(_IOC_READ, 'E', 0x09, len) /* get device properties */ | ||
115 | 116 | ||
116 | #define EVIOCGKEY(len) _IOC(_IOC_READ, 'E', 0x18, len) /* get global key state */ | 117 | #define EVIOCGKEY(len) _IOC(_IOC_READ, 'E', 0x18, len) /* get global key state */ |
117 | #define EVIOCGLED(len) _IOC(_IOC_READ, 'E', 0x19, len) /* get all LEDs */ | 118 | #define EVIOCGLED(len) _IOC(_IOC_READ, 'E', 0x19, len) /* get all LEDs */ |
@@ -129,6 +130,18 @@ struct input_keymap_entry { | |||
129 | #define EVIOCGRAB _IOW('E', 0x90, int) /* Grab/Release device */ | 130 | #define EVIOCGRAB _IOW('E', 0x90, int) /* Grab/Release device */ |
130 | 131 | ||
131 | /* | 132 | /* |
133 | * Device properties and quirks | ||
134 | */ | ||
135 | |||
136 | #define INPUT_PROP_POINTER 0x00 /* needs a pointer */ | ||
137 | #define INPUT_PROP_DIRECT 0x01 /* direct input devices */ | ||
138 | #define INPUT_PROP_BUTTONPAD 0x02 /* has button(s) under pad */ | ||
139 | #define INPUT_PROP_SEMI_MT 0x03 /* touch rectangle only */ | ||
140 | |||
141 | #define INPUT_PROP_MAX 0x1f | ||
142 | #define INPUT_PROP_CNT (INPUT_PROP_MAX + 1) | ||
143 | |||
144 | /* | ||
132 | * Event types | 145 | * Event types |
133 | */ | 146 | */ |
134 | 147 | ||
@@ -760,11 +773,12 @@ struct input_keymap_entry { | |||
760 | #define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */ | 773 | #define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */ |
761 | #define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */ | 774 | #define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */ |
762 | #define ABS_MT_PRESSURE 0x3a /* Pressure on contact area */ | 775 | #define ABS_MT_PRESSURE 0x3a /* Pressure on contact area */ |
776 | #define ABS_MT_DISTANCE 0x3b /* Contact hover distance */ | ||
763 | 777 | ||
764 | #ifdef __KERNEL__ | 778 | #ifdef __KERNEL__ |
765 | /* Implementation details, userspace should not care about these */ | 779 | /* Implementation details, userspace should not care about these */ |
766 | #define ABS_MT_FIRST ABS_MT_TOUCH_MAJOR | 780 | #define ABS_MT_FIRST ABS_MT_TOUCH_MAJOR |
767 | #define ABS_MT_LAST ABS_MT_PRESSURE | 781 | #define ABS_MT_LAST ABS_MT_DISTANCE |
768 | #endif | 782 | #endif |
769 | 783 | ||
770 | #define ABS_MAX 0x3f | 784 | #define ABS_MAX 0x3f |
@@ -875,6 +889,7 @@ struct input_keymap_entry { | |||
875 | */ | 889 | */ |
876 | #define MT_TOOL_FINGER 0 | 890 | #define MT_TOOL_FINGER 0 |
877 | #define MT_TOOL_PEN 1 | 891 | #define MT_TOOL_PEN 1 |
892 | #define MT_TOOL_MAX 1 | ||
878 | 893 | ||
879 | /* | 894 | /* |
880 | * Values describing the status of a force-feedback effect | 895 | * Values describing the status of a force-feedback effect |
@@ -1110,19 +1125,12 @@ struct ff_effect { | |||
1110 | #include <linux/mod_devicetable.h> | 1125 | #include <linux/mod_devicetable.h> |
1111 | 1126 | ||
1112 | /** | 1127 | /** |
1113 | * struct input_mt_slot - represents the state of an input MT slot | ||
1114 | * @abs: holds current values of ABS_MT axes for this slot | ||
1115 | */ | ||
1116 | struct input_mt_slot { | ||
1117 | int abs[ABS_MT_LAST - ABS_MT_FIRST + 1]; | ||
1118 | }; | ||
1119 | |||
1120 | /** | ||
1121 | * struct input_dev - represents an input device | 1128 | * struct input_dev - represents an input device |
1122 | * @name: name of the device | 1129 | * @name: name of the device |
1123 | * @phys: physical path to the device in the system hierarchy | 1130 | * @phys: physical path to the device in the system hierarchy |
1124 | * @uniq: unique identification code for the device (if device has it) | 1131 | * @uniq: unique identification code for the device (if device has it) |
1125 | * @id: id of the device (struct input_id) | 1132 | * @id: id of the device (struct input_id) |
1133 | * @propbit: bitmap of device properties and quirks | ||
1126 | * @evbit: bitmap of types of events supported by the device (EV_KEY, | 1134 | * @evbit: bitmap of types of events supported by the device (EV_KEY, |
1127 | * EV_REL, etc.) | 1135 | * EV_REL, etc.) |
1128 | * @keybit: bitmap of keys/buttons this device has | 1136 | * @keybit: bitmap of keys/buttons this device has |
@@ -1157,6 +1165,7 @@ struct input_mt_slot { | |||
1157 | * of tracked contacts | 1165 | * of tracked contacts |
1158 | * @mtsize: number of MT slots the device uses | 1166 | * @mtsize: number of MT slots the device uses |
1159 | * @slot: MT slot currently being transmitted | 1167 | * @slot: MT slot currently being transmitted |
1168 | * @trkid: stores MT tracking ID for the current contact | ||
1160 | * @absinfo: array of &struct input_absinfo elements holding information | 1169 | * @absinfo: array of &struct input_absinfo elements holding information |
1161 | * about absolute axes (current value, min, max, flat, fuzz, | 1170 | * about absolute axes (current value, min, max, flat, fuzz, |
1162 | * resolution) | 1171 | * resolution) |
@@ -1205,6 +1214,8 @@ struct input_dev { | |||
1205 | const char *uniq; | 1214 | const char *uniq; |
1206 | struct input_id id; | 1215 | struct input_id id; |
1207 | 1216 | ||
1217 | unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)]; | ||
1218 | |||
1208 | unsigned long evbit[BITS_TO_LONGS(EV_CNT)]; | 1219 | unsigned long evbit[BITS_TO_LONGS(EV_CNT)]; |
1209 | unsigned long keybit[BITS_TO_LONGS(KEY_CNT)]; | 1220 | unsigned long keybit[BITS_TO_LONGS(KEY_CNT)]; |
1210 | unsigned long relbit[BITS_TO_LONGS(REL_CNT)]; | 1221 | unsigned long relbit[BITS_TO_LONGS(REL_CNT)]; |
@@ -1241,6 +1252,7 @@ struct input_dev { | |||
1241 | struct input_mt_slot *mt; | 1252 | struct input_mt_slot *mt; |
1242 | int mtsize; | 1253 | int mtsize; |
1243 | int slot; | 1254 | int slot; |
1255 | int trkid; | ||
1244 | 1256 | ||
1245 | struct input_absinfo *absinfo; | 1257 | struct input_absinfo *absinfo; |
1246 | 1258 | ||
@@ -1490,11 +1502,6 @@ static inline void input_mt_sync(struct input_dev *dev) | |||
1490 | input_event(dev, EV_SYN, SYN_MT_REPORT, 0); | 1502 | input_event(dev, EV_SYN, SYN_MT_REPORT, 0); |
1491 | } | 1503 | } |
1492 | 1504 | ||
1493 | static inline void input_mt_slot(struct input_dev *dev, int slot) | ||
1494 | { | ||
1495 | input_event(dev, EV_ABS, ABS_MT_SLOT, slot); | ||
1496 | } | ||
1497 | |||
1498 | void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code); | 1505 | void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code); |
1499 | 1506 | ||
1500 | /** | 1507 | /** |
@@ -1607,8 +1614,5 @@ int input_ff_erase(struct input_dev *dev, int effect_id, struct file *file); | |||
1607 | int input_ff_create_memless(struct input_dev *dev, void *data, | 1614 | int input_ff_create_memless(struct input_dev *dev, void *data, |
1608 | int (*play_effect)(struct input_dev *, void *, struct ff_effect *)); | 1615 | int (*play_effect)(struct input_dev *, void *, struct ff_effect *)); |
1609 | 1616 | ||
1610 | int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots); | ||
1611 | void input_mt_destroy_slots(struct input_dev *dev); | ||
1612 | |||
1613 | #endif | 1617 | #endif |
1614 | #endif | 1618 | #endif |
diff --git a/include/linux/input/cma3000.h b/include/linux/input/cma3000.h new file mode 100644 index 000000000000..cbbaac27d311 --- /dev/null +++ b/include/linux/input/cma3000.h | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | * VTI CMA3000_Dxx Accelerometer driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Texas Instruments | ||
5 | * Author: Hemanth V <hemanthv@ti.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published by | ||
9 | * the Free Software Foundation. | ||
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 with | ||
17 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #ifndef _LINUX_CMA3000_H | ||
21 | #define _LINUX_CMA3000_H | ||
22 | |||
23 | #define CMAMODE_DEFAULT 0 | ||
24 | #define CMAMODE_MEAS100 1 | ||
25 | #define CMAMODE_MEAS400 2 | ||
26 | #define CMAMODE_MEAS40 3 | ||
27 | #define CMAMODE_MOTDET 4 | ||
28 | #define CMAMODE_FF100 5 | ||
29 | #define CMAMODE_FF400 6 | ||
30 | #define CMAMODE_POFF 7 | ||
31 | |||
32 | #define CMARANGE_2G 2000 | ||
33 | #define CMARANGE_8G 8000 | ||
34 | |||
35 | /** | ||
36 | * struct cma3000_i2c_platform_data - CMA3000 Platform data | ||
37 | * @fuzz_x: Noise on X Axis | ||
38 | * @fuzz_y: Noise on Y Axis | ||
39 | * @fuzz_z: Noise on Z Axis | ||
40 | * @g_range: G range in milli g i.e 2000 or 8000 | ||
41 | * @mode: Operating mode | ||
42 | * @mdthr: Motion detect threshold value | ||
43 | * @mdfftmr: Motion detect and free fall time value | ||
44 | * @ffthr: Free fall threshold value | ||
45 | */ | ||
46 | |||
47 | struct cma3000_platform_data { | ||
48 | int fuzz_x; | ||
49 | int fuzz_y; | ||
50 | int fuzz_z; | ||
51 | int g_range; | ||
52 | uint8_t mode; | ||
53 | uint8_t mdthr; | ||
54 | uint8_t mdfftmr; | ||
55 | uint8_t ffthr; | ||
56 | unsigned long irqflags; | ||
57 | }; | ||
58 | |||
59 | #endif | ||
diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h new file mode 100644 index 000000000000..b3ac06a4435d --- /dev/null +++ b/include/linux/input/mt.h | |||
@@ -0,0 +1,57 @@ | |||
1 | #ifndef _INPUT_MT_H | ||
2 | #define _INPUT_MT_H | ||
3 | |||
4 | /* | ||
5 | * Input Multitouch Library | ||
6 | * | ||
7 | * Copyright (c) 2010 Henrik Rydberg | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License version 2 as published by | ||
11 | * the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/input.h> | ||
15 | |||
16 | #define TRKID_MAX 0xffff | ||
17 | |||
18 | /** | ||
19 | * struct input_mt_slot - represents the state of an input MT slot | ||
20 | * @abs: holds current values of ABS_MT axes for this slot | ||
21 | */ | ||
22 | struct input_mt_slot { | ||
23 | int abs[ABS_MT_LAST - ABS_MT_FIRST + 1]; | ||
24 | }; | ||
25 | |||
26 | static inline void input_mt_set_value(struct input_mt_slot *slot, | ||
27 | unsigned code, int value) | ||
28 | { | ||
29 | slot->abs[code - ABS_MT_FIRST] = value; | ||
30 | } | ||
31 | |||
32 | static inline int input_mt_get_value(const struct input_mt_slot *slot, | ||
33 | unsigned code) | ||
34 | { | ||
35 | return slot->abs[code - ABS_MT_FIRST]; | ||
36 | } | ||
37 | |||
38 | int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots); | ||
39 | void input_mt_destroy_slots(struct input_dev *dev); | ||
40 | |||
41 | static inline int input_mt_new_trkid(struct input_dev *dev) | ||
42 | { | ||
43 | return dev->trkid++ & TRKID_MAX; | ||
44 | } | ||
45 | |||
46 | static inline void input_mt_slot(struct input_dev *dev, int slot) | ||
47 | { | ||
48 | input_event(dev, EV_ABS, ABS_MT_SLOT, slot); | ||
49 | } | ||
50 | |||
51 | void input_mt_report_slot_state(struct input_dev *dev, | ||
52 | unsigned int tool_type, bool active); | ||
53 | |||
54 | void input_mt_report_finger_count(struct input_dev *dev, int count); | ||
55 | void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count); | ||
56 | |||
57 | #endif | ||
diff --git a/include/linux/uinput.h b/include/linux/uinput.h index 05f7fed2b173..d28c726ede4f 100644 --- a/include/linux/uinput.h +++ b/include/linux/uinput.h | |||
@@ -104,6 +104,7 @@ struct uinput_ff_erase { | |||
104 | #define UI_SET_FFBIT _IOW(UINPUT_IOCTL_BASE, 107, int) | 104 | #define UI_SET_FFBIT _IOW(UINPUT_IOCTL_BASE, 107, int) |
105 | #define UI_SET_PHYS _IOW(UINPUT_IOCTL_BASE, 108, char*) | 105 | #define UI_SET_PHYS _IOW(UINPUT_IOCTL_BASE, 108, char*) |
106 | #define UI_SET_SWBIT _IOW(UINPUT_IOCTL_BASE, 109, int) | 106 | #define UI_SET_SWBIT _IOW(UINPUT_IOCTL_BASE, 109, int) |
107 | #define UI_SET_PROPBIT _IOW(UINPUT_IOCTL_BASE, 110, int) | ||
107 | 108 | ||
108 | #define UI_BEGIN_FF_UPLOAD _IOWR(UINPUT_IOCTL_BASE, 200, struct uinput_ff_upload) | 109 | #define UI_BEGIN_FF_UPLOAD _IOWR(UINPUT_IOCTL_BASE, 200, struct uinput_ff_upload) |
109 | #define UI_END_FF_UPLOAD _IOW(UINPUT_IOCTL_BASE, 201, struct uinput_ff_upload) | 110 | #define UI_END_FF_UPLOAD _IOW(UINPUT_IOCTL_BASE, 201, struct uinput_ff_upload) |