aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-02-21 15:59:04 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-21 15:59:04 -0500
commit1acd2de5facd7fbea499aea64a3a3d0ec7bb9b51 (patch)
tree21e5aed9925f3171d2c8c472193b1a5b635d8fdd /drivers/input
parentb5ccb078c806f4804aaf85bb59faa9b6fedf85a7 (diff)
parent4c971aa78314253cce914ed29e3d90df3326d646 (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.c3
-rw-r--r--drivers/input/keyboard/pxa27x_keypad.c4
-rw-r--r--drivers/input/misc/bfin_rotary.c208
-rw-r--r--drivers/input/misc/soc_button_array.c2
-rw-r--r--drivers/input/mouse/alps.c516
-rw-r--r--drivers/input/mouse/alps.h65
-rw-r--r--drivers/input/mouse/cypress_ps2.c5
-rw-r--r--drivers/input/mouse/cypress_ps2.h5
-rw-r--r--drivers/input/mouse/focaltech.c10
-rw-r--r--drivers/input/mouse/focaltech.h1
-rw-r--r--drivers/input/mouse/psmouse-base.c6
-rw-r--r--drivers/input/mouse/synaptics.c10
-rw-r--r--drivers/input/mouse/synaptics.h1
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
19static 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
26struct bfin_rot { 29struct 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
60static irqreturn_t bfin_rotary_isr(int irq, void *dev_id) 68static 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
99static 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
120static 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
128static void bfin_rotary_free_action(void *data)
129{
130 peripheral_free_list(data);
131}
132
92static int bfin_rotary_probe(struct platform_device *pdev) 133static 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
188out2:
189 free_irq(rotary->irq, pdev);
190out1:
191 input_free_device(input);
192 kfree(rotary);
193 peripheral_free_list(per_cnt);
194
195 return error;
196} 245}
197 246
198static int bfin_rotary_remove(struct platform_device *pdev) 247static 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
215static 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
230static int bfin_rotary_resume(struct device *dev) 262static 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
248static const struct dev_pm_ops bfin_rotary_pm_ops = { 280static 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
254static struct platform_driver bfin_rotary_device_driver = { 283static 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};
264module_platform_driver(bfin_rotary_device_driver); 290module_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
196static struct soc_button_info soc_button_PNP0C40[] = { 196static 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
105static const struct alps_model_info alps_model_data[] = { 104static 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
140static const struct alps_protocol_info alps_v3_protocol_data = {
141 ALPS_PROTO_V3, 0x8f, 0x8f, ALPS_DUALPOINT
142};
143
144static const struct alps_protocol_info alps_v3_rushmore_data = {
145 ALPS_PROTO_V3_RUSHMORE, 0x8f, 0x8f, ALPS_DUALPOINT
146};
147
148static const struct alps_protocol_info alps_v5_protocol_data = {
149 ALPS_PROTO_V5, 0xc8, 0xd8, 0
150};
151
152static const struct alps_protocol_info alps_v7_protocol_data = {
153 ALPS_PROTO_V7, 0x48, 0x48, ALPS_DUALPOINT
132}; 154};
133 155
134static void alps_set_abs_params_st(struct alps_data *priv, 156static 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,
136static void alps_set_abs_params_mt(struct alps_data *priv, 158static 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
147static bool alps_is_valid_first_byte(struct alps_data *priv, 163static 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
153static void alps_report_buttons(struct psmouse *psmouse, 169static 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
180static void alps_process_packet_v1_v2(struct psmouse *psmouse) 196static 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
1110static void alps_report_bare_ps2_packet(struct psmouse *psmouse, 1088static DEFINE_MUTEX(alps_mutex);
1089
1090static 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
1146out:
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
1157static 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
1129static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse) 1173static 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
2165static void alps_set_defaults(struct alps_data *priv) 2216static 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
2241static int alps_match_table(struct psmouse *psmouse, struct alps_data *priv, 2319static 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
2268static int alps_identify(struct psmouse *psmouse, struct alps_data *priv) 2339static 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
2346static int alps_reconnect(struct psmouse *psmouse) 2400static 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
2395int alps_init(struct psmouse *psmouse) 2452int 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
2510init_fail: 2575init_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
2518int alps_detect(struct psmouse *psmouse, bool set_properties) 2586int 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 */
58struct 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 */
66struct alps_model_info { 77struct 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 */
162struct alps_data { 175struct 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
714bool 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
173int cypress_detect(struct psmouse *psmouse, bool set_properties); 173int cypress_detect(struct psmouse *psmouse, bool set_properties);
174int cypress_init(struct psmouse *psmouse); 174int cypress_init(struct psmouse *psmouse);
175bool cypress_supported(void);
176#else 175#else
177inline int cypress_detect(struct psmouse *psmouse, bool set_properties) 176inline 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}
185inline 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
427bool focaltech_supported(void)
428{
429 return true;
430}
431
432#else /* CONFIG_MOUSE_PS2_FOCALTECH */ 427#else /* CONFIG_MOUSE_PS2_FOCALTECH */
433 428
434int focaltech_init(struct psmouse *psmouse) 429int 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
441bool 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
20int focaltech_detect(struct psmouse *psmouse, bool set_properties); 20int focaltech_detect(struct psmouse *psmouse, bool set_properties);
21int focaltech_init(struct psmouse *psmouse); 21int focaltech_init(struct psmouse *psmouse);
22bool 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
1457bool synaptics_supported(void)
1458{
1459 return true;
1460}
1461
1462#else /* CONFIG_MOUSE_PS2_SYNAPTICS */ 1457#else /* CONFIG_MOUSE_PS2_SYNAPTICS */
1463 1458
1464void __init synaptics_module_init(void) 1459void __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
1473bool 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);
175int synaptics_init(struct psmouse *psmouse); 175int synaptics_init(struct psmouse *psmouse);
176int synaptics_init_relative(struct psmouse *psmouse); 176int synaptics_init_relative(struct psmouse *psmouse);
177void synaptics_reset(struct psmouse *psmouse); 177void synaptics_reset(struct psmouse *psmouse);
178bool synaptics_supported(void);
179 178
180#endif /* _SYNAPTICS_H */ 179#endif /* _SYNAPTICS_H */