diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-21 15:59:04 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-21 15:59:04 -0500 |
commit | 1acd2de5facd7fbea499aea64a3a3d0ec7bb9b51 (patch) | |
tree | 21e5aed9925f3171d2c8c472193b1a5b635d8fdd /drivers/input | |
parent | b5ccb078c806f4804aaf85bb59faa9b6fedf85a7 (diff) | |
parent | 4c971aa78314253cce914ed29e3d90df3326d646 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull more input updates from Dmitry Torokhov:
"The second round of updates for the input subsystem.
Updates to ALPS an bfin_roraty drivers and a couple oother fixups"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
Input: psmouse - use IS_ENABLED instead of homegrown code
Input: bfin_rotary - introduce open and close methods
Input: bfin_rotary - convert to use managed resources
Input: bfin_rotary - use generic IO functions
Input: bfin_rotary - move pin lists into into platform data
Input: bfin_rotary - move platform header to linux/platform_data
Input: bfin_rotary - mark suspend and resume code as __maybe_unused
Input: bfin_rotary - fix potential oops in interrupt handler
Input: ALPS - move v7 packet info to Documentation and v6 packet info
Input: ALPS - fix confusing comment in protocol data
Input: ALPS - do not mix trackstick and external PS/2 mouse data
Input: ALPS - fix trackstick detection on some Dell Latitudes
Input: ALPS - consolidate setting protocol parameters
Input: ALPS - split protocol data from model info
Input: ALPS - make Rushmore a separate protocol
Input: ALPS - renumber protocol numbers
Input: adi - remove an unnecessary check
Input: pxa27x_keypad - remove an unneeded NULL check
Input: soc_button_array - use "Windows" key for "Home"
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/joystick/adi.c | 3 | ||||
-rw-r--r-- | drivers/input/keyboard/pxa27x_keypad.c | 4 | ||||
-rw-r--r-- | drivers/input/misc/bfin_rotary.c | 208 | ||||
-rw-r--r-- | drivers/input/misc/soc_button_array.c | 2 | ||||
-rw-r--r-- | drivers/input/mouse/alps.c | 516 | ||||
-rw-r--r-- | drivers/input/mouse/alps.h | 65 | ||||
-rw-r--r-- | drivers/input/mouse/cypress_ps2.c | 5 | ||||
-rw-r--r-- | drivers/input/mouse/cypress_ps2.h | 5 | ||||
-rw-r--r-- | drivers/input/mouse/focaltech.c | 10 | ||||
-rw-r--r-- | drivers/input/mouse/focaltech.h | 1 | ||||
-rw-r--r-- | drivers/input/mouse/psmouse-base.c | 6 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics.c | 10 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics.h | 1 |
13 files changed, 470 insertions, 366 deletions
diff --git a/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c index b78425765d3e..d09cefa37931 100644 --- a/drivers/input/joystick/adi.c +++ b/drivers/input/joystick/adi.c | |||
@@ -535,8 +535,7 @@ static int adi_connect(struct gameport *gameport, struct gameport_driver *drv) | |||
535 | } | 535 | } |
536 | } | 536 | } |
537 | fail2: for (i = 0; i < 2; i++) | 537 | fail2: for (i = 0; i < 2; i++) |
538 | if (port->adi[i].dev) | 538 | input_free_device(port->adi[i].dev); |
539 | input_free_device(port->adi[i].dev); | ||
540 | gameport_close(gameport); | 539 | gameport_close(gameport); |
541 | fail1: gameport_set_drvdata(gameport, NULL); | 540 | fail1: gameport_set_drvdata(gameport, NULL); |
542 | kfree(port); | 541 | kfree(port); |
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index a89488aa1aa4..fcef5d1365e2 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c | |||
@@ -345,13 +345,11 @@ static int pxa27x_keypad_build_keycode(struct pxa27x_keypad *keypad) | |||
345 | { | 345 | { |
346 | const struct pxa27x_keypad_platform_data *pdata = keypad->pdata; | 346 | const struct pxa27x_keypad_platform_data *pdata = keypad->pdata; |
347 | struct input_dev *input_dev = keypad->input_dev; | 347 | struct input_dev *input_dev = keypad->input_dev; |
348 | const struct matrix_keymap_data *keymap_data = | ||
349 | pdata ? pdata->matrix_keymap_data : NULL; | ||
350 | unsigned short keycode; | 348 | unsigned short keycode; |
351 | int i; | 349 | int i; |
352 | int error; | 350 | int error; |
353 | 351 | ||
354 | error = matrix_keypad_build_keymap(keymap_data, NULL, | 352 | error = matrix_keypad_build_keymap(pdata->matrix_keymap_data, NULL, |
355 | pdata->matrix_key_rows, | 353 | pdata->matrix_key_rows, |
356 | pdata->matrix_key_cols, | 354 | pdata->matrix_key_cols, |
357 | keypad->keycodes, input_dev); | 355 | keypad->keycodes, input_dev); |
diff --git a/drivers/input/misc/bfin_rotary.c b/drivers/input/misc/bfin_rotary.c index 3f4351579372..a0fc18fdfc0c 100644 --- a/drivers/input/misc/bfin_rotary.c +++ b/drivers/input/misc/bfin_rotary.c | |||
@@ -7,29 +7,37 @@ | |||
7 | 7 | ||
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/interrupt.h> | 9 | #include <linux/interrupt.h> |
10 | #include <linux/io.h> | ||
10 | #include <linux/irq.h> | 11 | #include <linux/irq.h> |
11 | #include <linux/pm.h> | 12 | #include <linux/pm.h> |
12 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
13 | #include <linux/input.h> | 14 | #include <linux/input.h> |
14 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/platform_data/bfin_rotary.h> | ||
15 | 17 | ||
16 | #include <asm/portmux.h> | 18 | #include <asm/portmux.h> |
17 | #include <asm/bfin_rotary.h> | ||
18 | 19 | ||
19 | static const u16 per_cnt[] = { | 20 | #define CNT_CONFIG_OFF 0 /* CNT Config Offset */ |
20 | P_CNT_CUD, | 21 | #define CNT_IMASK_OFF 4 /* CNT Interrupt Mask Offset */ |
21 | P_CNT_CDG, | 22 | #define CNT_STATUS_OFF 8 /* CNT Status Offset */ |
22 | P_CNT_CZM, | 23 | #define CNT_COMMAND_OFF 12 /* CNT Command Offset */ |
23 | 0 | 24 | #define CNT_DEBOUNCE_OFF 16 /* CNT Debounce Offset */ |
24 | }; | 25 | #define CNT_COUNTER_OFF 20 /* CNT Counter Offset */ |
26 | #define CNT_MAX_OFF 24 /* CNT Maximum Count Offset */ | ||
27 | #define CNT_MIN_OFF 28 /* CNT Minimum Count Offset */ | ||
25 | 28 | ||
26 | struct bfin_rot { | 29 | struct bfin_rot { |
27 | struct input_dev *input; | 30 | struct input_dev *input; |
31 | void __iomem *base; | ||
28 | int irq; | 32 | int irq; |
29 | unsigned int up_key; | 33 | unsigned int up_key; |
30 | unsigned int down_key; | 34 | unsigned int down_key; |
31 | unsigned int button_key; | 35 | unsigned int button_key; |
32 | unsigned int rel_code; | 36 | unsigned int rel_code; |
37 | |||
38 | unsigned short mode; | ||
39 | unsigned short debounce; | ||
40 | |||
33 | unsigned short cnt_config; | 41 | unsigned short cnt_config; |
34 | unsigned short cnt_imask; | 42 | unsigned short cnt_imask; |
35 | unsigned short cnt_debounce; | 43 | unsigned short cnt_debounce; |
@@ -59,18 +67,17 @@ static void report_rotary_event(struct bfin_rot *rotary, int delta) | |||
59 | 67 | ||
60 | static irqreturn_t bfin_rotary_isr(int irq, void *dev_id) | 68 | static irqreturn_t bfin_rotary_isr(int irq, void *dev_id) |
61 | { | 69 | { |
62 | struct platform_device *pdev = dev_id; | 70 | struct bfin_rot *rotary = dev_id; |
63 | struct bfin_rot *rotary = platform_get_drvdata(pdev); | ||
64 | int delta; | 71 | int delta; |
65 | 72 | ||
66 | switch (bfin_read_CNT_STATUS()) { | 73 | switch (readw(rotary->base + CNT_STATUS_OFF)) { |
67 | 74 | ||
68 | case ICII: | 75 | case ICII: |
69 | break; | 76 | break; |
70 | 77 | ||
71 | case UCII: | 78 | case UCII: |
72 | case DCII: | 79 | case DCII: |
73 | delta = bfin_read_CNT_COUNTER(); | 80 | delta = readl(rotary->base + CNT_COUNTER_OFF); |
74 | if (delta) | 81 | if (delta) |
75 | report_rotary_event(rotary, delta); | 82 | report_rotary_event(rotary, delta); |
76 | break; | 83 | break; |
@@ -83,16 +90,52 @@ static irqreturn_t bfin_rotary_isr(int irq, void *dev_id) | |||
83 | break; | 90 | break; |
84 | } | 91 | } |
85 | 92 | ||
86 | bfin_write_CNT_COMMAND(W1LCNT_ZERO); /* Clear COUNTER */ | 93 | writew(W1LCNT_ZERO, rotary->base + CNT_COMMAND_OFF); /* Clear COUNTER */ |
87 | bfin_write_CNT_STATUS(-1); /* Clear STATUS */ | 94 | writew(-1, rotary->base + CNT_STATUS_OFF); /* Clear STATUS */ |
88 | 95 | ||
89 | return IRQ_HANDLED; | 96 | return IRQ_HANDLED; |
90 | } | 97 | } |
91 | 98 | ||
99 | static int bfin_rotary_open(struct input_dev *input) | ||
100 | { | ||
101 | struct bfin_rot *rotary = input_get_drvdata(input); | ||
102 | unsigned short val; | ||
103 | |||
104 | if (rotary->mode & ROT_DEBE) | ||
105 | writew(rotary->debounce & DPRESCALE, | ||
106 | rotary->base + CNT_DEBOUNCE_OFF); | ||
107 | |||
108 | writew(rotary->mode & ~CNTE, rotary->base + CNT_CONFIG_OFF); | ||
109 | |||
110 | val = UCIE | DCIE; | ||
111 | if (rotary->button_key) | ||
112 | val |= CZMIE; | ||
113 | writew(val, rotary->base + CNT_IMASK_OFF); | ||
114 | |||
115 | writew(rotary->mode | CNTE, rotary->base + CNT_CONFIG_OFF); | ||
116 | |||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | static void bfin_rotary_close(struct input_dev *input) | ||
121 | { | ||
122 | struct bfin_rot *rotary = input_get_drvdata(input); | ||
123 | |||
124 | writew(0, rotary->base + CNT_CONFIG_OFF); | ||
125 | writew(0, rotary->base + CNT_IMASK_OFF); | ||
126 | } | ||
127 | |||
128 | static void bfin_rotary_free_action(void *data) | ||
129 | { | ||
130 | peripheral_free_list(data); | ||
131 | } | ||
132 | |||
92 | static int bfin_rotary_probe(struct platform_device *pdev) | 133 | static int bfin_rotary_probe(struct platform_device *pdev) |
93 | { | 134 | { |
94 | struct bfin_rotary_platform_data *pdata = dev_get_platdata(&pdev->dev); | 135 | struct device *dev = &pdev->dev; |
136 | const struct bfin_rotary_platform_data *pdata = dev_get_platdata(dev); | ||
95 | struct bfin_rot *rotary; | 137 | struct bfin_rot *rotary; |
138 | struct resource *res; | ||
96 | struct input_dev *input; | 139 | struct input_dev *input; |
97 | int error; | 140 | int error; |
98 | 141 | ||
@@ -102,18 +145,37 @@ static int bfin_rotary_probe(struct platform_device *pdev) | |||
102 | return -EINVAL; | 145 | return -EINVAL; |
103 | } | 146 | } |
104 | 147 | ||
105 | error = peripheral_request_list(per_cnt, dev_name(&pdev->dev)); | 148 | if (pdata->pin_list) { |
106 | if (error) { | 149 | error = peripheral_request_list(pdata->pin_list, |
107 | dev_err(&pdev->dev, "requesting peripherals failed\n"); | 150 | dev_name(&pdev->dev)); |
108 | return error; | 151 | if (error) { |
152 | dev_err(dev, "requesting peripherals failed: %d\n", | ||
153 | error); | ||
154 | return error; | ||
155 | } | ||
156 | |||
157 | error = devm_add_action(dev, bfin_rotary_free_action, | ||
158 | pdata->pin_list); | ||
159 | if (error) { | ||
160 | dev_err(dev, "setting cleanup action failed: %d\n", | ||
161 | error); | ||
162 | peripheral_free_list(pdata->pin_list); | ||
163 | return error; | ||
164 | } | ||
109 | } | 165 | } |
110 | 166 | ||
111 | rotary = kzalloc(sizeof(struct bfin_rot), GFP_KERNEL); | 167 | rotary = devm_kzalloc(dev, sizeof(struct bfin_rot), GFP_KERNEL); |
112 | input = input_allocate_device(); | 168 | if (!rotary) |
113 | if (!rotary || !input) { | 169 | return -ENOMEM; |
114 | error = -ENOMEM; | 170 | |
115 | goto out1; | 171 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
116 | } | 172 | rotary->base = devm_ioremap_resource(dev, res); |
173 | if (IS_ERR(rotary->base)) | ||
174 | return PTR_ERR(rotary->base); | ||
175 | |||
176 | input = devm_input_allocate_device(dev); | ||
177 | if (!input) | ||
178 | return -ENOMEM; | ||
117 | 179 | ||
118 | rotary->input = input; | 180 | rotary->input = input; |
119 | 181 | ||
@@ -122,9 +184,8 @@ static int bfin_rotary_probe(struct platform_device *pdev) | |||
122 | rotary->button_key = pdata->rotary_button_key; | 184 | rotary->button_key = pdata->rotary_button_key; |
123 | rotary->rel_code = pdata->rotary_rel_code; | 185 | rotary->rel_code = pdata->rotary_rel_code; |
124 | 186 | ||
125 | error = rotary->irq = platform_get_irq(pdev, 0); | 187 | rotary->mode = pdata->mode; |
126 | if (error < 0) | 188 | rotary->debounce = pdata->debounce; |
127 | goto out1; | ||
128 | 189 | ||
129 | input->name = pdev->name; | 190 | input->name = pdev->name; |
130 | input->phys = "bfin-rotary/input0"; | 191 | input->phys = "bfin-rotary/input0"; |
@@ -137,6 +198,9 @@ static int bfin_rotary_probe(struct platform_device *pdev) | |||
137 | input->id.product = 0x0001; | 198 | input->id.product = 0x0001; |
138 | input->id.version = 0x0100; | 199 | input->id.version = 0x0100; |
139 | 200 | ||
201 | input->open = bfin_rotary_open; | ||
202 | input->close = bfin_rotary_close; | ||
203 | |||
140 | if (rotary->up_key) { | 204 | if (rotary->up_key) { |
141 | __set_bit(EV_KEY, input->evbit); | 205 | __set_bit(EV_KEY, input->evbit); |
142 | __set_bit(rotary->up_key, input->keybit); | 206 | __set_bit(rotary->up_key, input->keybit); |
@@ -151,75 +215,43 @@ static int bfin_rotary_probe(struct platform_device *pdev) | |||
151 | __set_bit(rotary->button_key, input->keybit); | 215 | __set_bit(rotary->button_key, input->keybit); |
152 | } | 216 | } |
153 | 217 | ||
154 | error = request_irq(rotary->irq, bfin_rotary_isr, | 218 | /* Quiesce the device before requesting irq */ |
155 | 0, dev_name(&pdev->dev), pdev); | 219 | bfin_rotary_close(input); |
220 | |||
221 | rotary->irq = platform_get_irq(pdev, 0); | ||
222 | if (rotary->irq < 0) { | ||
223 | dev_err(dev, "No rotary IRQ specified\n"); | ||
224 | return -ENOENT; | ||
225 | } | ||
226 | |||
227 | error = devm_request_irq(dev, rotary->irq, bfin_rotary_isr, | ||
228 | 0, dev_name(dev), rotary); | ||
156 | if (error) { | 229 | if (error) { |
157 | dev_err(&pdev->dev, | 230 | dev_err(dev, "unable to claim irq %d; error %d\n", |
158 | "unable to claim irq %d; error %d\n", | ||
159 | rotary->irq, error); | 231 | rotary->irq, error); |
160 | goto out1; | 232 | return error; |
161 | } | 233 | } |
162 | 234 | ||
163 | error = input_register_device(input); | 235 | error = input_register_device(input); |
164 | if (error) { | 236 | if (error) { |
165 | dev_err(&pdev->dev, | 237 | dev_err(dev, "unable to register input device (%d)\n", error); |
166 | "unable to register input device (%d)\n", error); | 238 | return error; |
167 | goto out2; | ||
168 | } | 239 | } |
169 | 240 | ||
170 | if (pdata->rotary_button_key) | ||
171 | bfin_write_CNT_IMASK(CZMIE); | ||
172 | |||
173 | if (pdata->mode & ROT_DEBE) | ||
174 | bfin_write_CNT_DEBOUNCE(pdata->debounce & DPRESCALE); | ||
175 | |||
176 | if (pdata->mode) | ||
177 | bfin_write_CNT_CONFIG(bfin_read_CNT_CONFIG() | | ||
178 | (pdata->mode & ~CNTE)); | ||
179 | |||
180 | bfin_write_CNT_IMASK(bfin_read_CNT_IMASK() | UCIE | DCIE); | ||
181 | bfin_write_CNT_CONFIG(bfin_read_CNT_CONFIG() | CNTE); | ||
182 | |||
183 | platform_set_drvdata(pdev, rotary); | 241 | platform_set_drvdata(pdev, rotary); |
184 | device_init_wakeup(&pdev->dev, 1); | 242 | device_init_wakeup(&pdev->dev, 1); |
185 | 243 | ||
186 | return 0; | 244 | return 0; |
187 | |||
188 | out2: | ||
189 | free_irq(rotary->irq, pdev); | ||
190 | out1: | ||
191 | input_free_device(input); | ||
192 | kfree(rotary); | ||
193 | peripheral_free_list(per_cnt); | ||
194 | |||
195 | return error; | ||
196 | } | 245 | } |
197 | 246 | ||
198 | static int bfin_rotary_remove(struct platform_device *pdev) | 247 | static int __maybe_unused bfin_rotary_suspend(struct device *dev) |
199 | { | ||
200 | struct bfin_rot *rotary = platform_get_drvdata(pdev); | ||
201 | |||
202 | bfin_write_CNT_CONFIG(0); | ||
203 | bfin_write_CNT_IMASK(0); | ||
204 | |||
205 | free_irq(rotary->irq, pdev); | ||
206 | input_unregister_device(rotary->input); | ||
207 | peripheral_free_list(per_cnt); | ||
208 | |||
209 | kfree(rotary); | ||
210 | |||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | #ifdef CONFIG_PM | ||
215 | static int bfin_rotary_suspend(struct device *dev) | ||
216 | { | 248 | { |
217 | struct platform_device *pdev = to_platform_device(dev); | 249 | struct platform_device *pdev = to_platform_device(dev); |
218 | struct bfin_rot *rotary = platform_get_drvdata(pdev); | 250 | struct bfin_rot *rotary = platform_get_drvdata(pdev); |
219 | 251 | ||
220 | rotary->cnt_config = bfin_read_CNT_CONFIG(); | 252 | rotary->cnt_config = readw(rotary->base + CNT_CONFIG_OFF); |
221 | rotary->cnt_imask = bfin_read_CNT_IMASK(); | 253 | rotary->cnt_imask = readw(rotary->base + CNT_IMASK_OFF); |
222 | rotary->cnt_debounce = bfin_read_CNT_DEBOUNCE(); | 254 | rotary->cnt_debounce = readw(rotary->base + CNT_DEBOUNCE_OFF); |
223 | 255 | ||
224 | if (device_may_wakeup(&pdev->dev)) | 256 | if (device_may_wakeup(&pdev->dev)) |
225 | enable_irq_wake(rotary->irq); | 257 | enable_irq_wake(rotary->irq); |
@@ -227,38 +259,32 @@ static int bfin_rotary_suspend(struct device *dev) | |||
227 | return 0; | 259 | return 0; |
228 | } | 260 | } |
229 | 261 | ||
230 | static int bfin_rotary_resume(struct device *dev) | 262 | static int __maybe_unused bfin_rotary_resume(struct device *dev) |
231 | { | 263 | { |
232 | struct platform_device *pdev = to_platform_device(dev); | 264 | struct platform_device *pdev = to_platform_device(dev); |
233 | struct bfin_rot *rotary = platform_get_drvdata(pdev); | 265 | struct bfin_rot *rotary = platform_get_drvdata(pdev); |
234 | 266 | ||
235 | bfin_write_CNT_DEBOUNCE(rotary->cnt_debounce); | 267 | writew(rotary->cnt_debounce, rotary->base + CNT_DEBOUNCE_OFF); |
236 | bfin_write_CNT_IMASK(rotary->cnt_imask); | 268 | writew(rotary->cnt_imask, rotary->base + CNT_IMASK_OFF); |
237 | bfin_write_CNT_CONFIG(rotary->cnt_config & ~CNTE); | 269 | writew(rotary->cnt_config & ~CNTE, rotary->base + CNT_CONFIG_OFF); |
238 | 270 | ||
239 | if (device_may_wakeup(&pdev->dev)) | 271 | if (device_may_wakeup(&pdev->dev)) |
240 | disable_irq_wake(rotary->irq); | 272 | disable_irq_wake(rotary->irq); |
241 | 273 | ||
242 | if (rotary->cnt_config & CNTE) | 274 | if (rotary->cnt_config & CNTE) |
243 | bfin_write_CNT_CONFIG(rotary->cnt_config); | 275 | writew(rotary->cnt_config, rotary->base + CNT_CONFIG_OFF); |
244 | 276 | ||
245 | return 0; | 277 | return 0; |
246 | } | 278 | } |
247 | 279 | ||
248 | static const struct dev_pm_ops bfin_rotary_pm_ops = { | 280 | static SIMPLE_DEV_PM_OPS(bfin_rotary_pm_ops, |
249 | .suspend = bfin_rotary_suspend, | 281 | bfin_rotary_suspend, bfin_rotary_resume); |
250 | .resume = bfin_rotary_resume, | ||
251 | }; | ||
252 | #endif | ||
253 | 282 | ||
254 | static struct platform_driver bfin_rotary_device_driver = { | 283 | static struct platform_driver bfin_rotary_device_driver = { |
255 | .probe = bfin_rotary_probe, | 284 | .probe = bfin_rotary_probe, |
256 | .remove = bfin_rotary_remove, | ||
257 | .driver = { | 285 | .driver = { |
258 | .name = "bfin-rotary", | 286 | .name = "bfin-rotary", |
259 | #ifdef CONFIG_PM | ||
260 | .pm = &bfin_rotary_pm_ops, | 287 | .pm = &bfin_rotary_pm_ops, |
261 | #endif | ||
262 | }, | 288 | }, |
263 | }; | 289 | }; |
264 | module_platform_driver(bfin_rotary_device_driver); | 290 | module_platform_driver(bfin_rotary_device_driver); |
diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c index 79cc0f79896f..e8e010a85484 100644 --- a/drivers/input/misc/soc_button_array.c +++ b/drivers/input/misc/soc_button_array.c | |||
@@ -195,7 +195,7 @@ static int soc_button_probe(struct platform_device *pdev) | |||
195 | 195 | ||
196 | static struct soc_button_info soc_button_PNP0C40[] = { | 196 | static struct soc_button_info soc_button_PNP0C40[] = { |
197 | { "power", 0, EV_KEY, KEY_POWER, false, true }, | 197 | { "power", 0, EV_KEY, KEY_POWER, false, true }, |
198 | { "home", 1, EV_KEY, KEY_HOME, false, true }, | 198 | { "home", 1, EV_KEY, KEY_LEFTMETA, false, true }, |
199 | { "volume_up", 2, EV_KEY, KEY_VOLUMEUP, true, false }, | 199 | { "volume_up", 2, EV_KEY, KEY_VOLUMEUP, true, false }, |
200 | { "volume_down", 3, EV_KEY, KEY_VOLUMEDOWN, true, false }, | 200 | { "volume_down", 3, EV_KEY, KEY_VOLUMEDOWN, true, false }, |
201 | { "rotation_lock", 4, EV_SW, SW_ROTATE_LOCK, false, false }, | 201 | { "rotation_lock", 4, EV_SW, SW_ROTATE_LOCK, false, false }, |
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index f205b8be2ce4..d28726a0ef85 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -99,36 +99,58 @@ static const struct alps_nibble_commands alps_v6_nibble_commands[] = { | |||
99 | #define ALPS_FOUR_BUTTONS 0x40 /* 4 direction button present */ | 99 | #define ALPS_FOUR_BUTTONS 0x40 /* 4 direction button present */ |
100 | #define ALPS_PS2_INTERLEAVED 0x80 /* 3-byte PS/2 packet interleaved with | 100 | #define ALPS_PS2_INTERLEAVED 0x80 /* 3-byte PS/2 packet interleaved with |
101 | 6-byte ALPS packet */ | 101 | 6-byte ALPS packet */ |
102 | #define ALPS_IS_RUSHMORE 0x100 /* device is a rushmore */ | ||
103 | #define ALPS_BUTTONPAD 0x200 /* device is a clickpad */ | 102 | #define ALPS_BUTTONPAD 0x200 /* device is a clickpad */ |
104 | 103 | ||
105 | static const struct alps_model_info alps_model_data[] = { | 104 | static const struct alps_model_info alps_model_data[] = { |
106 | { { 0x32, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */ | 105 | { { 0x32, 0x02, 0x14 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT } }, /* Toshiba Salellite Pro M10 */ |
107 | { { 0x33, 0x02, 0x0a }, 0x00, ALPS_PROTO_V1, 0x88, 0xf8, 0 }, /* UMAX-530T */ | 106 | { { 0x33, 0x02, 0x0a }, 0x00, { ALPS_PROTO_V1, 0x88, 0xf8, 0 } }, /* UMAX-530T */ |
108 | { { 0x53, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 }, | 107 | { { 0x53, 0x02, 0x0a }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } }, |
109 | { { 0x53, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 }, | 108 | { { 0x53, 0x02, 0x14 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } }, |
110 | { { 0x60, 0x03, 0xc8 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 }, /* HP ze1115 */ | 109 | { { 0x60, 0x03, 0xc8 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } }, /* HP ze1115 */ |
111 | { { 0x63, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 }, | 110 | { { 0x63, 0x02, 0x0a }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } }, |
112 | { { 0x63, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 }, | 111 | { { 0x63, 0x02, 0x14 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } }, |
113 | { { 0x63, 0x02, 0x28 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Fujitsu Siemens S6010 */ | 112 | { { 0x63, 0x02, 0x28 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 } }, /* Fujitsu Siemens S6010 */ |
114 | { { 0x63, 0x02, 0x3c }, 0x00, ALPS_PROTO_V2, 0x8f, 0x8f, ALPS_WHEEL }, /* Toshiba Satellite S2400-103 */ | 113 | { { 0x63, 0x02, 0x3c }, 0x00, { ALPS_PROTO_V2, 0x8f, 0x8f, ALPS_WHEEL } }, /* Toshiba Satellite S2400-103 */ |
115 | { { 0x63, 0x02, 0x50 }, 0x00, ALPS_PROTO_V2, 0xef, 0xef, ALPS_FW_BK_1 }, /* NEC Versa L320 */ | 114 | { { 0x63, 0x02, 0x50 }, 0x00, { ALPS_PROTO_V2, 0xef, 0xef, ALPS_FW_BK_1 } }, /* NEC Versa L320 */ |
116 | { { 0x63, 0x02, 0x64 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 }, | 115 | { { 0x63, 0x02, 0x64 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } }, |
117 | { { 0x63, 0x03, 0xc8 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D800 */ | 116 | { { 0x63, 0x03, 0xc8 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT } }, /* Dell Latitude D800 */ |
118 | { { 0x73, 0x00, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_DUALPOINT }, /* ThinkPad R61 8918-5QG */ | 117 | { { 0x73, 0x00, 0x0a }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_DUALPOINT } }, /* ThinkPad R61 8918-5QG */ |
119 | { { 0x73, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 }, | 118 | { { 0x73, 0x02, 0x0a }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } }, |
120 | { { 0x73, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Ahtec Laptop */ | 119 | { { 0x73, 0x02, 0x14 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 } }, /* Ahtec Laptop */ |
121 | { { 0x20, 0x02, 0x0e }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */ | 120 | |
122 | { { 0x22, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, | 121 | /* |
123 | { { 0x22, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */ | 122 | * XXX This entry is suspicious. First byte has zero lower nibble, |
123 | * which is what a normal mouse would report. Also, the value 0x0e | ||
124 | * isn't valid per PS/2 spec. | ||
125 | */ | ||
126 | { { 0x20, 0x02, 0x0e }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT } }, | ||
127 | |||
128 | { { 0x22, 0x02, 0x0a }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT } }, | ||
129 | { { 0x22, 0x02, 0x14 }, 0x00, { ALPS_PROTO_V2, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT } }, /* Dell Latitude D600 */ | ||
124 | /* Dell Latitude E5500, E6400, E6500, Precision M4400 */ | 130 | /* Dell Latitude E5500, E6400, E6500, Precision M4400 */ |
125 | { { 0x62, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xcf, 0xcf, | 131 | { { 0x62, 0x02, 0x14 }, 0x00, { ALPS_PROTO_V2, 0xcf, 0xcf, |
126 | ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, | 132 | ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED } }, |
127 | { { 0x73, 0x00, 0x14 }, 0x00, ALPS_PROTO_V6, 0xff, 0xff, ALPS_DUALPOINT }, /* Dell XT2 */ | 133 | { { 0x73, 0x00, 0x14 }, 0x00, { ALPS_PROTO_V6, 0xff, 0xff, ALPS_DUALPOINT } }, /* Dell XT2 */ |
128 | { { 0x73, 0x02, 0x50 }, 0x00, ALPS_PROTO_V2, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */ | 134 | { { 0x73, 0x02, 0x50 }, 0x00, { ALPS_PROTO_V2, 0xcf, 0xcf, ALPS_FOUR_BUTTONS } }, /* Dell Vostro 1400 */ |
129 | { { 0x52, 0x01, 0x14 }, 0x00, ALPS_PROTO_V2, 0xff, 0xff, | 135 | { { 0x52, 0x01, 0x14 }, 0x00, { ALPS_PROTO_V2, 0xff, 0xff, |
130 | ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */ | 136 | ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED } }, /* Toshiba Tecra A11-11L */ |
131 | { { 0x73, 0x02, 0x64 }, 0x8a, ALPS_PROTO_V4, 0x8f, 0x8f, 0 }, | 137 | { { 0x73, 0x02, 0x64 }, 0x8a, { ALPS_PROTO_V4, 0x8f, 0x8f, 0 } }, |
138 | }; | ||
139 | |||
140 | static const struct alps_protocol_info alps_v3_protocol_data = { | ||
141 | ALPS_PROTO_V3, 0x8f, 0x8f, ALPS_DUALPOINT | ||
142 | }; | ||
143 | |||
144 | static const struct alps_protocol_info alps_v3_rushmore_data = { | ||
145 | ALPS_PROTO_V3_RUSHMORE, 0x8f, 0x8f, ALPS_DUALPOINT | ||
146 | }; | ||
147 | |||
148 | static const struct alps_protocol_info alps_v5_protocol_data = { | ||
149 | ALPS_PROTO_V5, 0xc8, 0xd8, 0 | ||
150 | }; | ||
151 | |||
152 | static const struct alps_protocol_info alps_v7_protocol_data = { | ||
153 | ALPS_PROTO_V7, 0x48, 0x48, ALPS_DUALPOINT | ||
132 | }; | 154 | }; |
133 | 155 | ||
134 | static void alps_set_abs_params_st(struct alps_data *priv, | 156 | static void alps_set_abs_params_st(struct alps_data *priv, |
@@ -136,12 +158,6 @@ static void alps_set_abs_params_st(struct alps_data *priv, | |||
136 | static void alps_set_abs_params_mt(struct alps_data *priv, | 158 | static void alps_set_abs_params_mt(struct alps_data *priv, |
137 | struct input_dev *dev1); | 159 | struct input_dev *dev1); |
138 | 160 | ||
139 | /* | ||
140 | * XXX - this entry is suspicious. First byte has zero lower nibble, | ||
141 | * which is what a normal mouse would report. Also, the value 0x0e | ||
142 | * isn't valid per PS/2 spec. | ||
143 | */ | ||
144 | |||
145 | /* Packet formats are described in Documentation/input/alps.txt */ | 161 | /* Packet formats are described in Documentation/input/alps.txt */ |
146 | 162 | ||
147 | static bool alps_is_valid_first_byte(struct alps_data *priv, | 163 | static bool alps_is_valid_first_byte(struct alps_data *priv, |
@@ -150,8 +166,7 @@ static bool alps_is_valid_first_byte(struct alps_data *priv, | |||
150 | return (data & priv->mask0) == priv->byte0; | 166 | return (data & priv->mask0) == priv->byte0; |
151 | } | 167 | } |
152 | 168 | ||
153 | static void alps_report_buttons(struct psmouse *psmouse, | 169 | static void alps_report_buttons(struct input_dev *dev1, struct input_dev *dev2, |
154 | struct input_dev *dev1, struct input_dev *dev2, | ||
155 | int left, int right, int middle) | 170 | int left, int right, int middle) |
156 | { | 171 | { |
157 | struct input_dev *dev; | 172 | struct input_dev *dev; |
@@ -161,20 +176,21 @@ static void alps_report_buttons(struct psmouse *psmouse, | |||
161 | * other device (dev2) then this event should be also | 176 | * other device (dev2) then this event should be also |
162 | * sent through that device. | 177 | * sent through that device. |
163 | */ | 178 | */ |
164 | dev = test_bit(BTN_LEFT, dev2->key) ? dev2 : dev1; | 179 | dev = (dev2 && test_bit(BTN_LEFT, dev2->key)) ? dev2 : dev1; |
165 | input_report_key(dev, BTN_LEFT, left); | 180 | input_report_key(dev, BTN_LEFT, left); |
166 | 181 | ||
167 | dev = test_bit(BTN_RIGHT, dev2->key) ? dev2 : dev1; | 182 | dev = (dev2 && test_bit(BTN_RIGHT, dev2->key)) ? dev2 : dev1; |
168 | input_report_key(dev, BTN_RIGHT, right); | 183 | input_report_key(dev, BTN_RIGHT, right); |
169 | 184 | ||
170 | dev = test_bit(BTN_MIDDLE, dev2->key) ? dev2 : dev1; | 185 | dev = (dev2 && test_bit(BTN_MIDDLE, dev2->key)) ? dev2 : dev1; |
171 | input_report_key(dev, BTN_MIDDLE, middle); | 186 | input_report_key(dev, BTN_MIDDLE, middle); |
172 | 187 | ||
173 | /* | 188 | /* |
174 | * Sync the _other_ device now, we'll do the first | 189 | * Sync the _other_ device now, we'll do the first |
175 | * device later once we report the rest of the events. | 190 | * device later once we report the rest of the events. |
176 | */ | 191 | */ |
177 | input_sync(dev2); | 192 | if (dev2) |
193 | input_sync(dev2); | ||
178 | } | 194 | } |
179 | 195 | ||
180 | static void alps_process_packet_v1_v2(struct psmouse *psmouse) | 196 | static void alps_process_packet_v1_v2(struct psmouse *psmouse) |
@@ -221,13 +237,13 @@ static void alps_process_packet_v1_v2(struct psmouse *psmouse) | |||
221 | input_report_rel(dev2, REL_X, (x > 383 ? (x - 768) : x)); | 237 | input_report_rel(dev2, REL_X, (x > 383 ? (x - 768) : x)); |
222 | input_report_rel(dev2, REL_Y, -(y > 255 ? (y - 512) : y)); | 238 | input_report_rel(dev2, REL_Y, -(y > 255 ? (y - 512) : y)); |
223 | 239 | ||
224 | alps_report_buttons(psmouse, dev2, dev, left, right, middle); | 240 | alps_report_buttons(dev2, dev, left, right, middle); |
225 | 241 | ||
226 | input_sync(dev2); | 242 | input_sync(dev2); |
227 | return; | 243 | return; |
228 | } | 244 | } |
229 | 245 | ||
230 | alps_report_buttons(psmouse, dev, dev2, left, right, middle); | 246 | alps_report_buttons(dev, dev2, left, right, middle); |
231 | 247 | ||
232 | /* Convert hardware tap to a reasonable Z value */ | 248 | /* Convert hardware tap to a reasonable Z value */ |
233 | if (ges && !fin) | 249 | if (ges && !fin) |
@@ -412,7 +428,7 @@ static int alps_process_bitmap(struct alps_data *priv, | |||
412 | (2 * (priv->y_bits - 1)); | 428 | (2 * (priv->y_bits - 1)); |
413 | 429 | ||
414 | /* y-bitmap order is reversed, except on rushmore */ | 430 | /* y-bitmap order is reversed, except on rushmore */ |
415 | if (!(priv->flags & ALPS_IS_RUSHMORE)) { | 431 | if (priv->proto_version != ALPS_PROTO_V3_RUSHMORE) { |
416 | fields->mt[0].y = priv->y_max - fields->mt[0].y; | 432 | fields->mt[0].y = priv->y_max - fields->mt[0].y; |
417 | fields->mt[1].y = priv->y_max - fields->mt[1].y; | 433 | fields->mt[1].y = priv->y_max - fields->mt[1].y; |
418 | } | 434 | } |
@@ -648,7 +664,8 @@ static void alps_process_touchpad_packet_v3_v5(struct psmouse *psmouse) | |||
648 | */ | 664 | */ |
649 | if (f->is_mp) { | 665 | if (f->is_mp) { |
650 | fingers = f->fingers; | 666 | fingers = f->fingers; |
651 | if (priv->proto_version == ALPS_PROTO_V3) { | 667 | if (priv->proto_version == ALPS_PROTO_V3 || |
668 | priv->proto_version == ALPS_PROTO_V3_RUSHMORE) { | ||
652 | if (alps_process_bitmap(priv, f) == 0) | 669 | if (alps_process_bitmap(priv, f) == 0) |
653 | fingers = 0; /* Use st data */ | 670 | fingers = 0; /* Use st data */ |
654 | 671 | ||
@@ -892,34 +909,6 @@ static void alps_get_finger_coordinate_v7(struct input_mt_pos *mt, | |||
892 | unsigned char *pkt, | 909 | unsigned char *pkt, |
893 | unsigned char pkt_id) | 910 | unsigned char pkt_id) |
894 | { | 911 | { |
895 | /* | ||
896 | * packet-fmt b7 b6 b5 b4 b3 b2 b1 b0 | ||
897 | * Byte0 TWO & MULTI L 1 R M 1 Y0-2 Y0-1 Y0-0 | ||
898 | * Byte0 NEW L 1 X1-5 1 1 Y0-2 Y0-1 Y0-0 | ||
899 | * Byte1 Y0-10 Y0-9 Y0-8 Y0-7 Y0-6 Y0-5 Y0-4 Y0-3 | ||
900 | * Byte2 X0-11 1 X0-10 X0-9 X0-8 X0-7 X0-6 X0-5 | ||
901 | * Byte3 X1-11 1 X0-4 X0-3 1 X0-2 X0-1 X0-0 | ||
902 | * Byte4 TWO X1-10 TWO X1-9 X1-8 X1-7 X1-6 X1-5 X1-4 | ||
903 | * Byte4 MULTI X1-10 TWO X1-9 X1-8 X1-7 X1-6 Y1-5 1 | ||
904 | * Byte4 NEW X1-10 TWO X1-9 X1-8 X1-7 X1-6 0 0 | ||
905 | * Byte5 TWO & NEW Y1-10 0 Y1-9 Y1-8 Y1-7 Y1-6 Y1-5 Y1-4 | ||
906 | * Byte5 MULTI Y1-10 0 Y1-9 Y1-8 Y1-7 Y1-6 F-1 F-0 | ||
907 | * L: Left button | ||
908 | * R / M: Non-clickpads: Right / Middle button | ||
909 | * Clickpads: When > 2 fingers are down, and some fingers | ||
910 | * are in the button area, then the 2 coordinates reported | ||
911 | * are for fingers outside the button area and these report | ||
912 | * extra fingers being present in the right / left button | ||
913 | * area. Note these fingers are not added to the F field! | ||
914 | * so if a TWO packet is received and R = 1 then there are | ||
915 | * 3 fingers down, etc. | ||
916 | * TWO: 1: Two touches present, byte 0/4/5 are in TWO fmt | ||
917 | * 0: If byte 4 bit 0 is 1, then byte 0/4/5 are in MULTI fmt | ||
918 | * otherwise byte 0 bit 4 must be set and byte 0/4/5 are | ||
919 | * in NEW fmt | ||
920 | * F: Number of fingers - 3, 0 means 3 fingers, 1 means 4 ... | ||
921 | */ | ||
922 | |||
923 | mt[0].x = ((pkt[2] & 0x80) << 4); | 912 | mt[0].x = ((pkt[2] & 0x80) << 4); |
924 | mt[0].x |= ((pkt[2] & 0x3F) << 5); | 913 | mt[0].x |= ((pkt[2] & 0x3F) << 5); |
925 | mt[0].x |= ((pkt[3] & 0x30) >> 1); | 914 | mt[0].x |= ((pkt[3] & 0x30) >> 1); |
@@ -1044,17 +1033,6 @@ static void alps_process_trackstick_packet_v7(struct psmouse *psmouse) | |||
1044 | return; | 1033 | return; |
1045 | } | 1034 | } |
1046 | 1035 | ||
1047 | /* | ||
1048 | * b7 b6 b5 b4 b3 b2 b1 b0 | ||
1049 | * Byte0 0 1 0 0 1 0 0 0 | ||
1050 | * Byte1 1 1 * * 1 M R L | ||
1051 | * Byte2 X7 1 X5 X4 X3 X2 X1 X0 | ||
1052 | * Byte3 Z6 1 Y6 X6 1 Y2 Y1 Y0 | ||
1053 | * Byte4 Y7 0 Y5 Y4 Y3 1 1 0 | ||
1054 | * Byte5 T&P 0 Z5 Z4 Z3 Z2 Z1 Z0 | ||
1055 | * M / R / L: Middle / Right / Left button | ||
1056 | */ | ||
1057 | |||
1058 | x = ((packet[2] & 0xbf)) | ((packet[3] & 0x10) << 2); | 1036 | x = ((packet[2] & 0xbf)) | ((packet[3] & 0x10) << 2); |
1059 | y = (packet[3] & 0x07) | (packet[4] & 0xb8) | | 1037 | y = (packet[3] & 0x07) | (packet[4] & 0xb8) | |
1060 | ((packet[3] & 0x20) << 1); | 1038 | ((packet[3] & 0x20) << 1); |
@@ -1107,23 +1085,89 @@ static void alps_process_packet_v7(struct psmouse *psmouse) | |||
1107 | alps_process_touchpad_packet_v7(psmouse); | 1085 | alps_process_touchpad_packet_v7(psmouse); |
1108 | } | 1086 | } |
1109 | 1087 | ||
1110 | static void alps_report_bare_ps2_packet(struct psmouse *psmouse, | 1088 | static DEFINE_MUTEX(alps_mutex); |
1089 | |||
1090 | static void alps_register_bare_ps2_mouse(struct work_struct *work) | ||
1091 | { | ||
1092 | struct alps_data *priv = | ||
1093 | container_of(work, struct alps_data, dev3_register_work.work); | ||
1094 | struct psmouse *psmouse = priv->psmouse; | ||
1095 | struct input_dev *dev3; | ||
1096 | int error = 0; | ||
1097 | |||
1098 | mutex_lock(&alps_mutex); | ||
1099 | |||
1100 | if (priv->dev3) | ||
1101 | goto out; | ||
1102 | |||
1103 | dev3 = input_allocate_device(); | ||
1104 | if (!dev3) { | ||
1105 | psmouse_err(psmouse, "failed to allocate secondary device\n"); | ||
1106 | error = -ENOMEM; | ||
1107 | goto out; | ||
1108 | } | ||
1109 | |||
1110 | snprintf(priv->phys3, sizeof(priv->phys3), "%s/%s", | ||
1111 | psmouse->ps2dev.serio->phys, | ||
1112 | (priv->dev2 ? "input2" : "input1")); | ||
1113 | dev3->phys = priv->phys3; | ||
1114 | |||
1115 | /* | ||
1116 | * format of input device name is: "protocol vendor name" | ||
1117 | * see function psmouse_switch_protocol() in psmouse-base.c | ||
1118 | */ | ||
1119 | dev3->name = "PS/2 ALPS Mouse"; | ||
1120 | |||
1121 | dev3->id.bustype = BUS_I8042; | ||
1122 | dev3->id.vendor = 0x0002; | ||
1123 | dev3->id.product = PSMOUSE_PS2; | ||
1124 | dev3->id.version = 0x0000; | ||
1125 | dev3->dev.parent = &psmouse->ps2dev.serio->dev; | ||
1126 | |||
1127 | input_set_capability(dev3, EV_REL, REL_X); | ||
1128 | input_set_capability(dev3, EV_REL, REL_Y); | ||
1129 | input_set_capability(dev3, EV_KEY, BTN_LEFT); | ||
1130 | input_set_capability(dev3, EV_KEY, BTN_RIGHT); | ||
1131 | input_set_capability(dev3, EV_KEY, BTN_MIDDLE); | ||
1132 | |||
1133 | __set_bit(INPUT_PROP_POINTER, dev3->propbit); | ||
1134 | |||
1135 | error = input_register_device(dev3); | ||
1136 | if (error) { | ||
1137 | psmouse_err(psmouse, | ||
1138 | "failed to register secondary device: %d\n", | ||
1139 | error); | ||
1140 | input_free_device(dev3); | ||
1141 | goto out; | ||
1142 | } | ||
1143 | |||
1144 | priv->dev3 = dev3; | ||
1145 | |||
1146 | out: | ||
1147 | /* | ||
1148 | * Save the error code so that we can detect that we | ||
1149 | * already tried to create the device. | ||
1150 | */ | ||
1151 | if (error) | ||
1152 | priv->dev3 = ERR_PTR(error); | ||
1153 | |||
1154 | mutex_unlock(&alps_mutex); | ||
1155 | } | ||
1156 | |||
1157 | static void alps_report_bare_ps2_packet(struct input_dev *dev, | ||
1111 | unsigned char packet[], | 1158 | unsigned char packet[], |
1112 | bool report_buttons) | 1159 | bool report_buttons) |
1113 | { | 1160 | { |
1114 | struct alps_data *priv = psmouse->private; | ||
1115 | struct input_dev *dev2 = priv->dev2; | ||
1116 | |||
1117 | if (report_buttons) | 1161 | if (report_buttons) |
1118 | alps_report_buttons(psmouse, dev2, psmouse->dev, | 1162 | alps_report_buttons(dev, NULL, |
1119 | packet[0] & 1, packet[0] & 2, packet[0] & 4); | 1163 | packet[0] & 1, packet[0] & 2, packet[0] & 4); |
1120 | 1164 | ||
1121 | input_report_rel(dev2, REL_X, | 1165 | input_report_rel(dev, REL_X, |
1122 | packet[1] ? packet[1] - ((packet[0] << 4) & 0x100) : 0); | 1166 | packet[1] ? packet[1] - ((packet[0] << 4) & 0x100) : 0); |
1123 | input_report_rel(dev2, REL_Y, | 1167 | input_report_rel(dev, REL_Y, |
1124 | packet[2] ? ((packet[0] << 3) & 0x100) - packet[2] : 0); | 1168 | packet[2] ? ((packet[0] << 3) & 0x100) - packet[2] : 0); |
1125 | 1169 | ||
1126 | input_sync(dev2); | 1170 | input_sync(dev); |
1127 | } | 1171 | } |
1128 | 1172 | ||
1129 | static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse) | 1173 | static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse) |
@@ -1188,8 +1232,8 @@ static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse) | |||
1188 | * de-synchronization. | 1232 | * de-synchronization. |
1189 | */ | 1233 | */ |
1190 | 1234 | ||
1191 | alps_report_bare_ps2_packet(psmouse, &psmouse->packet[3], | 1235 | alps_report_bare_ps2_packet(priv->dev2, |
1192 | false); | 1236 | &psmouse->packet[3], false); |
1193 | 1237 | ||
1194 | /* | 1238 | /* |
1195 | * Continue with the standard ALPS protocol handling, | 1239 | * Continue with the standard ALPS protocol handling, |
@@ -1245,9 +1289,18 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) | |||
1245 | * properly we only do this if the device is fully synchronized. | 1289 | * properly we only do this if the device is fully synchronized. |
1246 | */ | 1290 | */ |
1247 | if (!psmouse->out_of_sync_cnt && (psmouse->packet[0] & 0xc8) == 0x08) { | 1291 | if (!psmouse->out_of_sync_cnt && (psmouse->packet[0] & 0xc8) == 0x08) { |
1292 | |||
1293 | /* Register dev3 mouse if we received PS/2 packet first time */ | ||
1294 | if (unlikely(!priv->dev3)) | ||
1295 | psmouse_queue_work(psmouse, | ||
1296 | &priv->dev3_register_work, 0); | ||
1297 | |||
1248 | if (psmouse->pktcnt == 3) { | 1298 | if (psmouse->pktcnt == 3) { |
1249 | alps_report_bare_ps2_packet(psmouse, psmouse->packet, | 1299 | /* Once dev3 mouse device is registered report data */ |
1250 | true); | 1300 | if (likely(!IS_ERR_OR_NULL(priv->dev3))) |
1301 | alps_report_bare_ps2_packet(priv->dev3, | ||
1302 | psmouse->packet, | ||
1303 | true); | ||
1251 | return PSMOUSE_FULL_PACKET; | 1304 | return PSMOUSE_FULL_PACKET; |
1252 | } | 1305 | } |
1253 | return PSMOUSE_GOOD_DATA; | 1306 | return PSMOUSE_GOOD_DATA; |
@@ -1275,7 +1328,7 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) | |||
1275 | psmouse->pktcnt - 1, | 1328 | psmouse->pktcnt - 1, |
1276 | psmouse->packet[psmouse->pktcnt - 1]); | 1329 | psmouse->packet[psmouse->pktcnt - 1]); |
1277 | 1330 | ||
1278 | if (priv->proto_version == ALPS_PROTO_V3 && | 1331 | if (priv->proto_version == ALPS_PROTO_V3_RUSHMORE && |
1279 | psmouse->pktcnt == psmouse->pktsize) { | 1332 | psmouse->pktcnt == psmouse->pktsize) { |
1280 | /* | 1333 | /* |
1281 | * Some Dell boxes, such as Latitude E6440 or E7440 | 1334 | * Some Dell boxes, such as Latitude E6440 or E7440 |
@@ -1780,7 +1833,7 @@ static int alps_setup_trackstick_v3(struct psmouse *psmouse, int reg_base) | |||
1780 | * all. | 1833 | * all. |
1781 | */ | 1834 | */ |
1782 | if (alps_rpt_cmd(psmouse, 0, PSMOUSE_CMD_SETSCALE21, param)) { | 1835 | if (alps_rpt_cmd(psmouse, 0, PSMOUSE_CMD_SETSCALE21, param)) { |
1783 | psmouse_warn(psmouse, "trackstick E7 report failed\n"); | 1836 | psmouse_warn(psmouse, "Failed to initialize trackstick (E7 report failed)\n"); |
1784 | ret = -ENODEV; | 1837 | ret = -ENODEV; |
1785 | } else { | 1838 | } else { |
1786 | psmouse_dbg(psmouse, "trackstick E7 report: %3ph\n", param); | 1839 | psmouse_dbg(psmouse, "trackstick E7 report: %3ph\n", param); |
@@ -1945,8 +1998,6 @@ static int alps_hw_init_rushmore_v3(struct psmouse *psmouse) | |||
1945 | ALPS_REG_BASE_RUSHMORE); | 1998 | ALPS_REG_BASE_RUSHMORE); |
1946 | if (reg_val == -EIO) | 1999 | if (reg_val == -EIO) |
1947 | goto error; | 2000 | goto error; |
1948 | if (reg_val == -ENODEV) | ||
1949 | priv->flags &= ~ALPS_DUALPOINT; | ||
1950 | } | 2001 | } |
1951 | 2002 | ||
1952 | if (alps_enter_command_mode(psmouse) || | 2003 | if (alps_enter_command_mode(psmouse) || |
@@ -2162,11 +2213,18 @@ error: | |||
2162 | return ret; | 2213 | return ret; |
2163 | } | 2214 | } |
2164 | 2215 | ||
2165 | static void alps_set_defaults(struct alps_data *priv) | 2216 | static int alps_set_protocol(struct psmouse *psmouse, |
2217 | struct alps_data *priv, | ||
2218 | const struct alps_protocol_info *protocol) | ||
2166 | { | 2219 | { |
2167 | priv->byte0 = 0x8f; | 2220 | psmouse->private = priv; |
2168 | priv->mask0 = 0x8f; | 2221 | |
2169 | priv->flags = ALPS_DUALPOINT; | 2222 | setup_timer(&priv->timer, alps_flush_packet, (unsigned long)psmouse); |
2223 | |||
2224 | priv->proto_version = protocol->version; | ||
2225 | priv->byte0 = protocol->byte0; | ||
2226 | priv->mask0 = protocol->mask0; | ||
2227 | priv->flags = protocol->flags; | ||
2170 | 2228 | ||
2171 | priv->x_max = 2000; | 2229 | priv->x_max = 2000; |
2172 | priv->y_max = 1400; | 2230 | priv->y_max = 1400; |
@@ -2182,6 +2240,7 @@ static void alps_set_defaults(struct alps_data *priv) | |||
2182 | priv->x_max = 1023; | 2240 | priv->x_max = 1023; |
2183 | priv->y_max = 767; | 2241 | priv->y_max = 767; |
2184 | break; | 2242 | break; |
2243 | |||
2185 | case ALPS_PROTO_V3: | 2244 | case ALPS_PROTO_V3: |
2186 | priv->hw_init = alps_hw_init_v3; | 2245 | priv->hw_init = alps_hw_init_v3; |
2187 | priv->process_packet = alps_process_packet_v3; | 2246 | priv->process_packet = alps_process_packet_v3; |
@@ -2190,6 +2249,23 @@ static void alps_set_defaults(struct alps_data *priv) | |||
2190 | priv->nibble_commands = alps_v3_nibble_commands; | 2249 | priv->nibble_commands = alps_v3_nibble_commands; |
2191 | priv->addr_command = PSMOUSE_CMD_RESET_WRAP; | 2250 | priv->addr_command = PSMOUSE_CMD_RESET_WRAP; |
2192 | break; | 2251 | break; |
2252 | |||
2253 | case ALPS_PROTO_V3_RUSHMORE: | ||
2254 | priv->hw_init = alps_hw_init_rushmore_v3; | ||
2255 | priv->process_packet = alps_process_packet_v3; | ||
2256 | priv->set_abs_params = alps_set_abs_params_mt; | ||
2257 | priv->decode_fields = alps_decode_rushmore; | ||
2258 | priv->nibble_commands = alps_v3_nibble_commands; | ||
2259 | priv->addr_command = PSMOUSE_CMD_RESET_WRAP; | ||
2260 | priv->x_bits = 16; | ||
2261 | priv->y_bits = 12; | ||
2262 | |||
2263 | if (alps_probe_trackstick_v3(psmouse, | ||
2264 | ALPS_REG_BASE_RUSHMORE) < 0) | ||
2265 | priv->flags &= ~ALPS_DUALPOINT; | ||
2266 | |||
2267 | break; | ||
2268 | |||
2193 | case ALPS_PROTO_V4: | 2269 | case ALPS_PROTO_V4: |
2194 | priv->hw_init = alps_hw_init_v4; | 2270 | priv->hw_init = alps_hw_init_v4; |
2195 | priv->process_packet = alps_process_packet_v4; | 2271 | priv->process_packet = alps_process_packet_v4; |
@@ -2197,6 +2273,7 @@ static void alps_set_defaults(struct alps_data *priv) | |||
2197 | priv->nibble_commands = alps_v4_nibble_commands; | 2273 | priv->nibble_commands = alps_v4_nibble_commands; |
2198 | priv->addr_command = PSMOUSE_CMD_DISABLE; | 2274 | priv->addr_command = PSMOUSE_CMD_DISABLE; |
2199 | break; | 2275 | break; |
2276 | |||
2200 | case ALPS_PROTO_V5: | 2277 | case ALPS_PROTO_V5: |
2201 | priv->hw_init = alps_hw_init_dolphin_v1; | 2278 | priv->hw_init = alps_hw_init_dolphin_v1; |
2202 | priv->process_packet = alps_process_touchpad_packet_v3_v5; | 2279 | priv->process_packet = alps_process_touchpad_packet_v3_v5; |
@@ -2204,14 +2281,12 @@ static void alps_set_defaults(struct alps_data *priv) | |||
2204 | priv->set_abs_params = alps_set_abs_params_mt; | 2281 | priv->set_abs_params = alps_set_abs_params_mt; |
2205 | priv->nibble_commands = alps_v3_nibble_commands; | 2282 | priv->nibble_commands = alps_v3_nibble_commands; |
2206 | priv->addr_command = PSMOUSE_CMD_RESET_WRAP; | 2283 | priv->addr_command = PSMOUSE_CMD_RESET_WRAP; |
2207 | priv->byte0 = 0xc8; | ||
2208 | priv->mask0 = 0xd8; | ||
2209 | priv->flags = 0; | ||
2210 | priv->x_max = 1360; | 2284 | priv->x_max = 1360; |
2211 | priv->y_max = 660; | 2285 | priv->y_max = 660; |
2212 | priv->x_bits = 23; | 2286 | priv->x_bits = 23; |
2213 | priv->y_bits = 12; | 2287 | priv->y_bits = 12; |
2214 | break; | 2288 | break; |
2289 | |||
2215 | case ALPS_PROTO_V6: | 2290 | case ALPS_PROTO_V6: |
2216 | priv->hw_init = alps_hw_init_v6; | 2291 | priv->hw_init = alps_hw_init_v6; |
2217 | priv->process_packet = alps_process_packet_v6; | 2292 | priv->process_packet = alps_process_packet_v6; |
@@ -2220,6 +2295,7 @@ static void alps_set_defaults(struct alps_data *priv) | |||
2220 | priv->x_max = 2047; | 2295 | priv->x_max = 2047; |
2221 | priv->y_max = 1535; | 2296 | priv->y_max = 1535; |
2222 | break; | 2297 | break; |
2298 | |||
2223 | case ALPS_PROTO_V7: | 2299 | case ALPS_PROTO_V7: |
2224 | priv->hw_init = alps_hw_init_v7; | 2300 | priv->hw_init = alps_hw_init_v7; |
2225 | priv->process_packet = alps_process_packet_v7; | 2301 | priv->process_packet = alps_process_packet_v7; |
@@ -2227,19 +2303,21 @@ static void alps_set_defaults(struct alps_data *priv) | |||
2227 | priv->set_abs_params = alps_set_abs_params_mt; | 2303 | priv->set_abs_params = alps_set_abs_params_mt; |
2228 | priv->nibble_commands = alps_v3_nibble_commands; | 2304 | priv->nibble_commands = alps_v3_nibble_commands; |
2229 | priv->addr_command = PSMOUSE_CMD_RESET_WRAP; | 2305 | priv->addr_command = PSMOUSE_CMD_RESET_WRAP; |
2230 | priv->x_max = 0xfff; | 2306 | |
2231 | priv->y_max = 0x7ff; | 2307 | if (alps_dolphin_get_device_area(psmouse, priv)) |
2232 | priv->byte0 = 0x48; | 2308 | return -EIO; |
2233 | priv->mask0 = 0x48; | ||
2234 | 2309 | ||
2235 | if (priv->fw_ver[1] != 0xba) | 2310 | if (priv->fw_ver[1] != 0xba) |
2236 | priv->flags |= ALPS_BUTTONPAD; | 2311 | priv->flags |= ALPS_BUTTONPAD; |
2312 | |||
2237 | break; | 2313 | break; |
2238 | } | 2314 | } |
2315 | |||
2316 | return 0; | ||
2239 | } | 2317 | } |
2240 | 2318 | ||
2241 | static int alps_match_table(struct psmouse *psmouse, struct alps_data *priv, | 2319 | static const struct alps_protocol_info *alps_match_table(unsigned char *e7, |
2242 | unsigned char *e7, unsigned char *ec) | 2320 | unsigned char *ec) |
2243 | { | 2321 | { |
2244 | const struct alps_model_info *model; | 2322 | const struct alps_model_info *model; |
2245 | int i; | 2323 | int i; |
@@ -2251,23 +2329,18 @@ static int alps_match_table(struct psmouse *psmouse, struct alps_data *priv, | |||
2251 | (!model->command_mode_resp || | 2329 | (!model->command_mode_resp || |
2252 | model->command_mode_resp == ec[2])) { | 2330 | model->command_mode_resp == ec[2])) { |
2253 | 2331 | ||
2254 | priv->proto_version = model->proto_version; | 2332 | return &model->protocol_info; |
2255 | alps_set_defaults(priv); | ||
2256 | |||
2257 | priv->flags = model->flags; | ||
2258 | priv->byte0 = model->byte0; | ||
2259 | priv->mask0 = model->mask0; | ||
2260 | |||
2261 | return 0; | ||
2262 | } | 2333 | } |
2263 | } | 2334 | } |
2264 | 2335 | ||
2265 | return -EINVAL; | 2336 | return NULL; |
2266 | } | 2337 | } |
2267 | 2338 | ||
2268 | static int alps_identify(struct psmouse *psmouse, struct alps_data *priv) | 2339 | static int alps_identify(struct psmouse *psmouse, struct alps_data *priv) |
2269 | { | 2340 | { |
2341 | const struct alps_protocol_info *protocol; | ||
2270 | unsigned char e6[4], e7[4], ec[4]; | 2342 | unsigned char e6[4], e7[4], ec[4]; |
2343 | int error; | ||
2271 | 2344 | ||
2272 | /* | 2345 | /* |
2273 | * First try "E6 report". | 2346 | * First try "E6 report". |
@@ -2293,54 +2366,35 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv) | |||
2293 | alps_exit_command_mode(psmouse)) | 2366 | alps_exit_command_mode(psmouse)) |
2294 | return -EIO; | 2367 | return -EIO; |
2295 | 2368 | ||
2296 | /* Save the Firmware version */ | 2369 | protocol = alps_match_table(e7, ec); |
2297 | memcpy(priv->fw_ver, ec, 3); | 2370 | if (!protocol) { |
2298 | 2371 | if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 && | |
2299 | if (alps_match_table(psmouse, priv, e7, ec) == 0) { | 2372 | ec[0] == 0x73 && (ec[1] == 0x01 || ec[1] == 0x02)) { |
2300 | return 0; | 2373 | protocol = &alps_v5_protocol_data; |
2301 | } else if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 && | 2374 | } else if (ec[0] == 0x88 && |
2302 | ec[0] == 0x73 && (ec[1] == 0x01 || ec[1] == 0x02)) { | 2375 | ((ec[1] & 0xf0) == 0xb0 || (ec[1] & 0xf0) == 0xc0)) { |
2303 | priv->proto_version = ALPS_PROTO_V5; | 2376 | protocol = &alps_v7_protocol_data; |
2304 | alps_set_defaults(priv); | 2377 | } else if (ec[0] == 0x88 && ec[1] == 0x08) { |
2305 | if (alps_dolphin_get_device_area(psmouse, priv)) | 2378 | protocol = &alps_v3_rushmore_data; |
2306 | return -EIO; | 2379 | } else if (ec[0] == 0x88 && ec[1] == 0x07 && |
2307 | else | 2380 | ec[2] >= 0x90 && ec[2] <= 0x9d) { |
2308 | return 0; | 2381 | protocol = &alps_v3_protocol_data; |
2309 | } else if (ec[0] == 0x88 && | 2382 | } else { |
2310 | ((ec[1] & 0xf0) == 0xb0 || (ec[1] & 0xf0) == 0xc0)) { | 2383 | psmouse_dbg(psmouse, |
2311 | priv->proto_version = ALPS_PROTO_V7; | 2384 | "Likely not an ALPS touchpad: E7=%3ph, EC=%3ph\n", e7, ec); |
2312 | alps_set_defaults(priv); | 2385 | return -EINVAL; |
2313 | 2386 | } | |
2314 | return 0; | ||
2315 | } else if (ec[0] == 0x88 && ec[1] == 0x08) { | ||
2316 | priv->proto_version = ALPS_PROTO_V3; | ||
2317 | alps_set_defaults(priv); | ||
2318 | |||
2319 | priv->hw_init = alps_hw_init_rushmore_v3; | ||
2320 | priv->decode_fields = alps_decode_rushmore; | ||
2321 | priv->x_bits = 16; | ||
2322 | priv->y_bits = 12; | ||
2323 | priv->flags |= ALPS_IS_RUSHMORE; | ||
2324 | |||
2325 | /* hack to make addr_command, nibble_command available */ | ||
2326 | psmouse->private = priv; | ||
2327 | |||
2328 | if (alps_probe_trackstick_v3(psmouse, ALPS_REG_BASE_RUSHMORE)) | ||
2329 | priv->flags &= ~ALPS_DUALPOINT; | ||
2330 | |||
2331 | return 0; | ||
2332 | } else if (ec[0] == 0x88 && ec[1] == 0x07 && | ||
2333 | ec[2] >= 0x90 && ec[2] <= 0x9d) { | ||
2334 | priv->proto_version = ALPS_PROTO_V3; | ||
2335 | alps_set_defaults(priv); | ||
2336 | |||
2337 | return 0; | ||
2338 | } | 2387 | } |
2339 | 2388 | ||
2340 | psmouse_dbg(psmouse, | 2389 | if (priv) { |
2341 | "Likely not an ALPS touchpad: E7=%3ph, EC=%3ph\n", e7, ec); | 2390 | /* Save the Firmware version */ |
2391 | memcpy(priv->fw_ver, ec, 3); | ||
2392 | error = alps_set_protocol(psmouse, priv, protocol); | ||
2393 | if (error) | ||
2394 | return error; | ||
2395 | } | ||
2342 | 2396 | ||
2343 | return -EINVAL; | 2397 | return 0; |
2344 | } | 2398 | } |
2345 | 2399 | ||
2346 | static int alps_reconnect(struct psmouse *psmouse) | 2400 | static int alps_reconnect(struct psmouse *psmouse) |
@@ -2361,7 +2415,10 @@ static void alps_disconnect(struct psmouse *psmouse) | |||
2361 | 2415 | ||
2362 | psmouse_reset(psmouse); | 2416 | psmouse_reset(psmouse); |
2363 | del_timer_sync(&priv->timer); | 2417 | del_timer_sync(&priv->timer); |
2364 | input_unregister_device(priv->dev2); | 2418 | if (priv->dev2) |
2419 | input_unregister_device(priv->dev2); | ||
2420 | if (!IS_ERR_OR_NULL(priv->dev3)) | ||
2421 | input_unregister_device(priv->dev3); | ||
2365 | kfree(priv); | 2422 | kfree(priv); |
2366 | } | 2423 | } |
2367 | 2424 | ||
@@ -2394,25 +2451,12 @@ static void alps_set_abs_params_mt(struct alps_data *priv, | |||
2394 | 2451 | ||
2395 | int alps_init(struct psmouse *psmouse) | 2452 | int alps_init(struct psmouse *psmouse) |
2396 | { | 2453 | { |
2397 | struct alps_data *priv; | 2454 | struct alps_data *priv = psmouse->private; |
2398 | struct input_dev *dev1 = psmouse->dev, *dev2; | 2455 | struct input_dev *dev1 = psmouse->dev; |
2399 | 2456 | int error; | |
2400 | priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL); | ||
2401 | dev2 = input_allocate_device(); | ||
2402 | if (!priv || !dev2) | ||
2403 | goto init_fail; | ||
2404 | |||
2405 | priv->dev2 = dev2; | ||
2406 | setup_timer(&priv->timer, alps_flush_packet, (unsigned long)psmouse); | ||
2407 | |||
2408 | psmouse->private = priv; | ||
2409 | |||
2410 | psmouse_reset(psmouse); | ||
2411 | |||
2412 | if (alps_identify(psmouse, priv) < 0) | ||
2413 | goto init_fail; | ||
2414 | 2457 | ||
2415 | if (priv->hw_init(psmouse)) | 2458 | error = priv->hw_init(psmouse); |
2459 | if (error) | ||
2416 | goto init_fail; | 2460 | goto init_fail; |
2417 | 2461 | ||
2418 | /* | 2462 | /* |
@@ -2462,36 +2506,57 @@ int alps_init(struct psmouse *psmouse) | |||
2462 | } | 2506 | } |
2463 | 2507 | ||
2464 | if (priv->flags & ALPS_DUALPOINT) { | 2508 | if (priv->flags & ALPS_DUALPOINT) { |
2509 | struct input_dev *dev2; | ||
2510 | |||
2511 | dev2 = input_allocate_device(); | ||
2512 | if (!dev2) { | ||
2513 | psmouse_err(psmouse, | ||
2514 | "failed to allocate trackstick device\n"); | ||
2515 | error = -ENOMEM; | ||
2516 | goto init_fail; | ||
2517 | } | ||
2518 | |||
2519 | snprintf(priv->phys2, sizeof(priv->phys2), "%s/input1", | ||
2520 | psmouse->ps2dev.serio->phys); | ||
2521 | dev2->phys = priv->phys2; | ||
2522 | |||
2465 | /* | 2523 | /* |
2466 | * format of input device name is: "protocol vendor name" | 2524 | * format of input device name is: "protocol vendor name" |
2467 | * see function psmouse_switch_protocol() in psmouse-base.c | 2525 | * see function psmouse_switch_protocol() in psmouse-base.c |
2468 | */ | 2526 | */ |
2469 | dev2->name = "AlpsPS/2 ALPS DualPoint Stick"; | 2527 | dev2->name = "AlpsPS/2 ALPS DualPoint Stick"; |
2528 | |||
2529 | dev2->id.bustype = BUS_I8042; | ||
2530 | dev2->id.vendor = 0x0002; | ||
2470 | dev2->id.product = PSMOUSE_ALPS; | 2531 | dev2->id.product = PSMOUSE_ALPS; |
2471 | dev2->id.version = priv->proto_version; | 2532 | dev2->id.version = priv->proto_version; |
2472 | } else { | 2533 | dev2->dev.parent = &psmouse->ps2dev.serio->dev; |
2473 | dev2->name = "PS/2 ALPS Mouse"; | ||
2474 | dev2->id.product = PSMOUSE_PS2; | ||
2475 | dev2->id.version = 0x0000; | ||
2476 | } | ||
2477 | 2534 | ||
2478 | snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys); | 2535 | input_set_capability(dev2, EV_REL, REL_X); |
2479 | dev2->phys = priv->phys; | 2536 | input_set_capability(dev2, EV_REL, REL_Y); |
2480 | dev2->id.bustype = BUS_I8042; | 2537 | input_set_capability(dev2, EV_KEY, BTN_LEFT); |
2481 | dev2->id.vendor = 0x0002; | 2538 | input_set_capability(dev2, EV_KEY, BTN_RIGHT); |
2482 | dev2->dev.parent = &psmouse->ps2dev.serio->dev; | 2539 | input_set_capability(dev2, EV_KEY, BTN_MIDDLE); |
2483 | 2540 | ||
2484 | dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); | 2541 | __set_bit(INPUT_PROP_POINTER, dev2->propbit); |
2485 | dev2->relbit[BIT_WORD(REL_X)] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); | ||
2486 | dev2->keybit[BIT_WORD(BTN_LEFT)] = | ||
2487 | BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); | ||
2488 | |||
2489 | __set_bit(INPUT_PROP_POINTER, dev2->propbit); | ||
2490 | if (priv->flags & ALPS_DUALPOINT) | ||
2491 | __set_bit(INPUT_PROP_POINTING_STICK, dev2->propbit); | 2542 | __set_bit(INPUT_PROP_POINTING_STICK, dev2->propbit); |
2492 | 2543 | ||
2493 | if (input_register_device(priv->dev2)) | 2544 | error = input_register_device(dev2); |
2494 | goto init_fail; | 2545 | if (error) { |
2546 | psmouse_err(psmouse, | ||
2547 | "failed to register trackstick device: %d\n", | ||
2548 | error); | ||
2549 | input_free_device(dev2); | ||
2550 | goto init_fail; | ||
2551 | } | ||
2552 | |||
2553 | priv->dev2 = dev2; | ||
2554 | } | ||
2555 | |||
2556 | priv->psmouse = psmouse; | ||
2557 | |||
2558 | INIT_DELAYED_WORK(&priv->dev3_register_work, | ||
2559 | alps_register_bare_ps2_mouse); | ||
2495 | 2560 | ||
2496 | psmouse->protocol_handler = alps_process_byte; | 2561 | psmouse->protocol_handler = alps_process_byte; |
2497 | psmouse->poll = alps_poll; | 2562 | psmouse->poll = alps_poll; |
@@ -2509,25 +2574,56 @@ int alps_init(struct psmouse *psmouse) | |||
2509 | 2574 | ||
2510 | init_fail: | 2575 | init_fail: |
2511 | psmouse_reset(psmouse); | 2576 | psmouse_reset(psmouse); |
2512 | input_free_device(dev2); | 2577 | /* |
2513 | kfree(priv); | 2578 | * Even though we did not allocate psmouse->private we do free |
2579 | * it here. | ||
2580 | */ | ||
2581 | kfree(psmouse->private); | ||
2514 | psmouse->private = NULL; | 2582 | psmouse->private = NULL; |
2515 | return -1; | 2583 | return error; |
2516 | } | 2584 | } |
2517 | 2585 | ||
2518 | int alps_detect(struct psmouse *psmouse, bool set_properties) | 2586 | int alps_detect(struct psmouse *psmouse, bool set_properties) |
2519 | { | 2587 | { |
2520 | struct alps_data dummy; | 2588 | struct alps_data *priv; |
2589 | int error; | ||
2521 | 2590 | ||
2522 | if (alps_identify(psmouse, &dummy) < 0) | 2591 | error = alps_identify(psmouse, NULL); |
2523 | return -1; | 2592 | if (error) |
2593 | return error; | ||
2594 | |||
2595 | /* | ||
2596 | * Reset the device to make sure it is fully operational: | ||
2597 | * on some laptops, like certain Dell Latitudes, we may | ||
2598 | * fail to properly detect presence of trackstick if device | ||
2599 | * has not been reset. | ||
2600 | */ | ||
2601 | psmouse_reset(psmouse); | ||
2602 | |||
2603 | priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL); | ||
2604 | if (!priv) | ||
2605 | return -ENOMEM; | ||
2606 | |||
2607 | error = alps_identify(psmouse, priv); | ||
2608 | if (error) | ||
2609 | return error; | ||
2524 | 2610 | ||
2525 | if (set_properties) { | 2611 | if (set_properties) { |
2526 | psmouse->vendor = "ALPS"; | 2612 | psmouse->vendor = "ALPS"; |
2527 | psmouse->name = dummy.flags & ALPS_DUALPOINT ? | 2613 | psmouse->name = priv->flags & ALPS_DUALPOINT ? |
2528 | "DualPoint TouchPad" : "GlidePoint"; | 2614 | "DualPoint TouchPad" : "GlidePoint"; |
2529 | psmouse->model = dummy.proto_version << 8; | 2615 | psmouse->model = priv->proto_version; |
2616 | } else { | ||
2617 | /* | ||
2618 | * Destroy alps_data structure we allocated earlier since | ||
2619 | * this was just a "trial run". Otherwise we'll keep it | ||
2620 | * to be used by alps_init() which has to be called if | ||
2621 | * we succeed and set_properties is true. | ||
2622 | */ | ||
2623 | kfree(priv); | ||
2624 | psmouse->private = NULL; | ||
2530 | } | 2625 | } |
2626 | |||
2531 | return 0; | 2627 | return 0; |
2532 | } | 2628 | } |
2533 | 2629 | ||
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h index 66240b47819a..02513c0502fc 100644 --- a/drivers/input/mouse/alps.h +++ b/drivers/input/mouse/alps.h | |||
@@ -14,13 +14,14 @@ | |||
14 | 14 | ||
15 | #include <linux/input/mt.h> | 15 | #include <linux/input/mt.h> |
16 | 16 | ||
17 | #define ALPS_PROTO_V1 1 | 17 | #define ALPS_PROTO_V1 0x100 |
18 | #define ALPS_PROTO_V2 2 | 18 | #define ALPS_PROTO_V2 0x200 |
19 | #define ALPS_PROTO_V3 3 | 19 | #define ALPS_PROTO_V3 0x300 |
20 | #define ALPS_PROTO_V4 4 | 20 | #define ALPS_PROTO_V3_RUSHMORE 0x310 |
21 | #define ALPS_PROTO_V5 5 | 21 | #define ALPS_PROTO_V4 0x400 |
22 | #define ALPS_PROTO_V6 6 | 22 | #define ALPS_PROTO_V5 0x500 |
23 | #define ALPS_PROTO_V7 7 /* t3btl t4s */ | 23 | #define ALPS_PROTO_V6 0x600 |
24 | #define ALPS_PROTO_V7 0x700 /* t3btl t4s */ | ||
24 | 25 | ||
25 | #define MAX_TOUCHES 2 | 26 | #define MAX_TOUCHES 2 |
26 | 27 | ||
@@ -46,29 +47,37 @@ enum V7_PACKET_ID { | |||
46 | }; | 47 | }; |
47 | 48 | ||
48 | /** | 49 | /** |
50 | * struct alps_protocol_info - information about protocol used by a device | ||
51 | * @version: Indicates V1/V2/V3/... | ||
52 | * @byte0: Helps figure out whether a position report packet matches the | ||
53 | * known format for this model. The first byte of the report, ANDed with | ||
54 | * mask0, should match byte0. | ||
55 | * @mask0: The mask used to check the first byte of the report. | ||
56 | * @flags: Additional device capabilities (passthrough port, trackstick, etc.). | ||
57 | */ | ||
58 | struct alps_protocol_info { | ||
59 | u16 version; | ||
60 | u8 byte0, mask0; | ||
61 | unsigned int flags; | ||
62 | }; | ||
63 | |||
64 | /** | ||
49 | * struct alps_model_info - touchpad ID table | 65 | * struct alps_model_info - touchpad ID table |
50 | * @signature: E7 response string to match. | 66 | * @signature: E7 response string to match. |
51 | * @command_mode_resp: For V3/V4 touchpads, the final byte of the EC response | 67 | * @command_mode_resp: For V3/V4 touchpads, the final byte of the EC response |
52 | * (aka command mode response) identifies the firmware minor version. This | 68 | * (aka command mode response) identifies the firmware minor version. This |
53 | * can be used to distinguish different hardware models which are not | 69 | * can be used to distinguish different hardware models which are not |
54 | * uniquely identifiable through their E7 responses. | 70 | * uniquely identifiable through their E7 responses. |
55 | * @proto_version: Indicates V1/V2/V3/... | 71 | * @protocol_info: information about protcol used by the device. |
56 | * @byte0: Helps figure out whether a position report packet matches the | ||
57 | * known format for this model. The first byte of the report, ANDed with | ||
58 | * mask0, should match byte0. | ||
59 | * @mask0: The mask used to check the first byte of the report. | ||
60 | * @flags: Additional device capabilities (passthrough port, trackstick, etc.). | ||
61 | * | 72 | * |
62 | * Many (but not all) ALPS touchpads can be identified by looking at the | 73 | * Many (but not all) ALPS touchpads can be identified by looking at the |
63 | * values returned in the "E7 report" and/or the "EC report." This table | 74 | * values returned in the "E7 report" and/or the "EC report." This table |
64 | * lists a number of such touchpads. | 75 | * lists a number of such touchpads. |
65 | */ | 76 | */ |
66 | struct alps_model_info { | 77 | struct alps_model_info { |
67 | unsigned char signature[3]; | 78 | u8 signature[3]; |
68 | unsigned char command_mode_resp; | 79 | u8 command_mode_resp; |
69 | unsigned char proto_version; | 80 | struct alps_protocol_info protocol_info; |
70 | unsigned char byte0, mask0; | ||
71 | int flags; | ||
72 | }; | 81 | }; |
73 | 82 | ||
74 | /** | 83 | /** |
@@ -132,8 +141,12 @@ struct alps_fields { | |||
132 | 141 | ||
133 | /** | 142 | /** |
134 | * struct alps_data - private data structure for the ALPS driver | 143 | * struct alps_data - private data structure for the ALPS driver |
135 | * @dev2: "Relative" device used to report trackstick or mouse activity. | 144 | * @psmouse: Pointer to parent psmouse device |
136 | * @phys: Physical path for the relative device. | 145 | * @dev2: Trackstick device (can be NULL). |
146 | * @dev3: Generic PS/2 mouse (can be NULL, delayed registering). | ||
147 | * @phys2: Physical path for the trackstick device. | ||
148 | * @phys3: Physical path for the generic PS/2 mouse. | ||
149 | * @dev3_register_work: Delayed work for registering PS/2 mouse. | ||
137 | * @nibble_commands: Command mapping used for touchpad register accesses. | 150 | * @nibble_commands: Command mapping used for touchpad register accesses. |
138 | * @addr_command: Command used to tell the touchpad that a register address | 151 | * @addr_command: Command used to tell the touchpad that a register address |
139 | * follows. | 152 | * follows. |
@@ -160,15 +173,19 @@ struct alps_fields { | |||
160 | * @timer: Timer for flushing out the final report packet in the stream. | 173 | * @timer: Timer for flushing out the final report packet in the stream. |
161 | */ | 174 | */ |
162 | struct alps_data { | 175 | struct alps_data { |
176 | struct psmouse *psmouse; | ||
163 | struct input_dev *dev2; | 177 | struct input_dev *dev2; |
164 | char phys[32]; | 178 | struct input_dev *dev3; |
179 | char phys2[32]; | ||
180 | char phys3[32]; | ||
181 | struct delayed_work dev3_register_work; | ||
165 | 182 | ||
166 | /* these are autodetected when the device is identified */ | 183 | /* these are autodetected when the device is identified */ |
167 | const struct alps_nibble_commands *nibble_commands; | 184 | const struct alps_nibble_commands *nibble_commands; |
168 | int addr_command; | 185 | int addr_command; |
169 | unsigned char proto_version; | 186 | u16 proto_version; |
170 | unsigned char byte0, mask0; | 187 | u8 byte0, mask0; |
171 | unsigned char fw_ver[3]; | 188 | u8 fw_ver[3]; |
172 | int flags; | 189 | int flags; |
173 | int x_max; | 190 | int x_max; |
174 | int y_max; | 191 | int y_max; |
diff --git a/drivers/input/mouse/cypress_ps2.c b/drivers/input/mouse/cypress_ps2.c index 9118a1861a45..28dcfc822bf6 100644 --- a/drivers/input/mouse/cypress_ps2.c +++ b/drivers/input/mouse/cypress_ps2.c | |||
@@ -710,8 +710,3 @@ err_exit: | |||
710 | 710 | ||
711 | return -1; | 711 | return -1; |
712 | } | 712 | } |
713 | |||
714 | bool cypress_supported(void) | ||
715 | { | ||
716 | return true; | ||
717 | } | ||
diff --git a/drivers/input/mouse/cypress_ps2.h b/drivers/input/mouse/cypress_ps2.h index 4720f21d2d70..81f68aaed7c8 100644 --- a/drivers/input/mouse/cypress_ps2.h +++ b/drivers/input/mouse/cypress_ps2.h | |||
@@ -172,7 +172,6 @@ struct cytp_data { | |||
172 | #ifdef CONFIG_MOUSE_PS2_CYPRESS | 172 | #ifdef CONFIG_MOUSE_PS2_CYPRESS |
173 | int cypress_detect(struct psmouse *psmouse, bool set_properties); | 173 | int cypress_detect(struct psmouse *psmouse, bool set_properties); |
174 | int cypress_init(struct psmouse *psmouse); | 174 | int cypress_init(struct psmouse *psmouse); |
175 | bool cypress_supported(void); | ||
176 | #else | 175 | #else |
177 | inline int cypress_detect(struct psmouse *psmouse, bool set_properties) | 176 | inline int cypress_detect(struct psmouse *psmouse, bool set_properties) |
178 | { | 177 | { |
@@ -182,10 +181,6 @@ inline int cypress_init(struct psmouse *psmouse) | |||
182 | { | 181 | { |
183 | return -ENOSYS; | 182 | return -ENOSYS; |
184 | } | 183 | } |
185 | inline bool cypress_supported(void) | ||
186 | { | ||
187 | return 0; | ||
188 | } | ||
189 | #endif /* CONFIG_MOUSE_PS2_CYPRESS */ | 184 | #endif /* CONFIG_MOUSE_PS2_CYPRESS */ |
190 | 185 | ||
191 | #endif /* _CYPRESS_PS2_H */ | 186 | #endif /* _CYPRESS_PS2_H */ |
diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c index fca38ba63bbe..757f78a94aec 100644 --- a/drivers/input/mouse/focaltech.c +++ b/drivers/input/mouse/focaltech.c | |||
@@ -424,11 +424,6 @@ fail: | |||
424 | return error; | 424 | return error; |
425 | } | 425 | } |
426 | 426 | ||
427 | bool focaltech_supported(void) | ||
428 | { | ||
429 | return true; | ||
430 | } | ||
431 | |||
432 | #else /* CONFIG_MOUSE_PS2_FOCALTECH */ | 427 | #else /* CONFIG_MOUSE_PS2_FOCALTECH */ |
433 | 428 | ||
434 | int focaltech_init(struct psmouse *psmouse) | 429 | int focaltech_init(struct psmouse *psmouse) |
@@ -438,9 +433,4 @@ int focaltech_init(struct psmouse *psmouse) | |||
438 | return 0; | 433 | return 0; |
439 | } | 434 | } |
440 | 435 | ||
441 | bool focaltech_supported(void) | ||
442 | { | ||
443 | return false; | ||
444 | } | ||
445 | |||
446 | #endif /* CONFIG_MOUSE_PS2_FOCALTECH */ | 436 | #endif /* CONFIG_MOUSE_PS2_FOCALTECH */ |
diff --git a/drivers/input/mouse/focaltech.h b/drivers/input/mouse/focaltech.h index 71870a9b548a..ca61ebff373e 100644 --- a/drivers/input/mouse/focaltech.h +++ b/drivers/input/mouse/focaltech.h | |||
@@ -19,6 +19,5 @@ | |||
19 | 19 | ||
20 | int focaltech_detect(struct psmouse *psmouse, bool set_properties); | 20 | int focaltech_detect(struct psmouse *psmouse, bool set_properties); |
21 | int focaltech_init(struct psmouse *psmouse); | 21 | int focaltech_init(struct psmouse *psmouse); |
22 | bool focaltech_supported(void); | ||
23 | 22 | ||
24 | #endif | 23 | #endif |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 68469feda470..4ccd01d7a48d 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -727,7 +727,7 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
727 | if (psmouse_do_detect(focaltech_detect, psmouse, set_properties) == 0) { | 727 | if (psmouse_do_detect(focaltech_detect, psmouse, set_properties) == 0) { |
728 | if (max_proto > PSMOUSE_IMEX) { | 728 | if (max_proto > PSMOUSE_IMEX) { |
729 | if (!set_properties || focaltech_init(psmouse) == 0) { | 729 | if (!set_properties || focaltech_init(psmouse) == 0) { |
730 | if (focaltech_supported()) | 730 | if (IS_ENABLED(CONFIG_MOUSE_PS2_FOCALTECH)) |
731 | return PSMOUSE_FOCALTECH; | 731 | return PSMOUSE_FOCALTECH; |
732 | /* | 732 | /* |
733 | * Note that we need to also restrict | 733 | * Note that we need to also restrict |
@@ -776,7 +776,7 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
776 | * Try activating protocol, but check if support is enabled first, since | 776 | * Try activating protocol, but check if support is enabled first, since |
777 | * we try detecting Synaptics even when protocol is disabled. | 777 | * we try detecting Synaptics even when protocol is disabled. |
778 | */ | 778 | */ |
779 | if (synaptics_supported() && | 779 | if (IS_ENABLED(CONFIG_MOUSE_PS2_SYNAPTICS) && |
780 | (!set_properties || synaptics_init(psmouse) == 0)) { | 780 | (!set_properties || synaptics_init(psmouse) == 0)) { |
781 | return PSMOUSE_SYNAPTICS; | 781 | return PSMOUSE_SYNAPTICS; |
782 | } | 782 | } |
@@ -801,7 +801,7 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
801 | */ | 801 | */ |
802 | if (max_proto > PSMOUSE_IMEX && | 802 | if (max_proto > PSMOUSE_IMEX && |
803 | cypress_detect(psmouse, set_properties) == 0) { | 803 | cypress_detect(psmouse, set_properties) == 0) { |
804 | if (cypress_supported()) { | 804 | if (IS_ENABLED(CONFIG_MOUSE_PS2_CYPRESS)) { |
805 | if (cypress_init(psmouse) == 0) | 805 | if (cypress_init(psmouse) == 0) |
806 | return PSMOUSE_CYPRESS; | 806 | return PSMOUSE_CYPRESS; |
807 | 807 | ||
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 7e705ee90b86..f2cceb6493a0 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -1454,11 +1454,6 @@ int synaptics_init_relative(struct psmouse *psmouse) | |||
1454 | return __synaptics_init(psmouse, false); | 1454 | return __synaptics_init(psmouse, false); |
1455 | } | 1455 | } |
1456 | 1456 | ||
1457 | bool synaptics_supported(void) | ||
1458 | { | ||
1459 | return true; | ||
1460 | } | ||
1461 | |||
1462 | #else /* CONFIG_MOUSE_PS2_SYNAPTICS */ | 1457 | #else /* CONFIG_MOUSE_PS2_SYNAPTICS */ |
1463 | 1458 | ||
1464 | void __init synaptics_module_init(void) | 1459 | void __init synaptics_module_init(void) |
@@ -1470,9 +1465,4 @@ int synaptics_init(struct psmouse *psmouse) | |||
1470 | return -ENOSYS; | 1465 | return -ENOSYS; |
1471 | } | 1466 | } |
1472 | 1467 | ||
1473 | bool synaptics_supported(void) | ||
1474 | { | ||
1475 | return false; | ||
1476 | } | ||
1477 | |||
1478 | #endif /* CONFIG_MOUSE_PS2_SYNAPTICS */ | 1468 | #endif /* CONFIG_MOUSE_PS2_SYNAPTICS */ |
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index 6faf9bb7c117..aedc3299b14e 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h | |||
@@ -175,6 +175,5 @@ int synaptics_detect(struct psmouse *psmouse, bool set_properties); | |||
175 | int synaptics_init(struct psmouse *psmouse); | 175 | int synaptics_init(struct psmouse *psmouse); |
176 | int synaptics_init_relative(struct psmouse *psmouse); | 176 | int synaptics_init_relative(struct psmouse *psmouse); |
177 | void synaptics_reset(struct psmouse *psmouse); | 177 | void synaptics_reset(struct psmouse *psmouse); |
178 | bool synaptics_supported(void); | ||
179 | 178 | ||
180 | #endif /* _SYNAPTICS_H */ | 179 | #endif /* _SYNAPTICS_H */ |