aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse/alps.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/mouse/alps.c')
-rw-r--r--drivers/input/mouse/alps.c52
1 files changed, 31 insertions, 21 deletions
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 7bf4be733e9a..a12e98158a75 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -30,10 +30,11 @@
30 30
31#define ALPS_DUALPOINT 0x01 31#define ALPS_DUALPOINT 0x01
32#define ALPS_WHEEL 0x02 32#define ALPS_WHEEL 0x02
33#define ALPS_FW_BK 0x04 33#define ALPS_FW_BK_1 0x04
34#define ALPS_4BTN 0x08 34#define ALPS_4BTN 0x08
35#define ALPS_OLDPROTO 0x10 35#define ALPS_OLDPROTO 0x10
36#define ALPS_PASS 0x20 36#define ALPS_PASS 0x20
37#define ALPS_FW_BK_2 0x40
37 38
38static struct alps_model_info alps_model_data[] = { 39static struct alps_model_info alps_model_data[] = {
39 { { 0x33, 0x02, 0x0a }, 0x88, 0xf8, ALPS_OLDPROTO }, /* UMAX-530T */ 40 { { 0x33, 0x02, 0x0a }, 0x88, 0xf8, ALPS_OLDPROTO }, /* UMAX-530T */
@@ -43,11 +44,11 @@ static struct alps_model_info alps_model_data[] = {
43 { { 0x63, 0x02, 0x14 }, 0xf8, 0xf8, 0 }, 44 { { 0x63, 0x02, 0x14 }, 0xf8, 0xf8, 0 },
44 { { 0x63, 0x02, 0x28 }, 0xf8, 0xf8, 0 }, 45 { { 0x63, 0x02, 0x28 }, 0xf8, 0xf8, 0 },
45 { { 0x63, 0x02, 0x3c }, 0x8f, 0x8f, ALPS_WHEEL }, /* Toshiba Satellite S2400-103 */ 46 { { 0x63, 0x02, 0x3c }, 0x8f, 0x8f, ALPS_WHEEL }, /* Toshiba Satellite S2400-103 */
46 { { 0x63, 0x02, 0x50 }, 0xef, 0xef, ALPS_FW_BK }, /* NEC Versa L320 */ 47 { { 0x63, 0x02, 0x50 }, 0xef, 0xef, ALPS_FW_BK_1 }, /* NEC Versa L320 */
47 { { 0x63, 0x02, 0x64 }, 0xf8, 0xf8, 0 }, 48 { { 0x63, 0x02, 0x64 }, 0xf8, 0xf8, 0 },
48 { { 0x63, 0x03, 0xc8 }, 0xf8, 0xf8, ALPS_PASS }, /* Dell Latitude D800 */ 49 { { 0x63, 0x03, 0xc8 }, 0xf8, 0xf8, ALPS_PASS }, /* Dell Latitude D800 */
49 { { 0x73, 0x02, 0x0a }, 0xf8, 0xf8, 0 }, 50 { { 0x73, 0x02, 0x0a }, 0xf8, 0xf8, 0 },
50 { { 0x73, 0x02, 0x14 }, 0xf8, 0xf8, 0 }, 51 { { 0x73, 0x02, 0x14 }, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Ahtec Laptop */
51 { { 0x20, 0x02, 0x0e }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */ 52 { { 0x20, 0x02, 0x0e }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */
52 { { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, 53 { { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
53 { { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */ 54 { { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */
@@ -61,11 +62,11 @@ static struct alps_model_info alps_model_data[] = {
61 62
62/* 63/*
63 * ALPS abolute Mode - new format 64 * ALPS abolute Mode - new format
64 * 65 *
65 * byte 0: 1 ? ? ? 1 ? ? ? 66 * byte 0: 1 ? ? ? 1 ? ? ?
66 * byte 1: 0 x6 x5 x4 x3 x2 x1 x0 67 * byte 1: 0 x6 x5 x4 x3 x2 x1 x0
67 * byte 2: 0 x10 x9 x8 x7 ? fin ges 68 * byte 2: 0 x10 x9 x8 x7 ? fin ges
68 * byte 3: 0 y9 y8 y7 1 M R L 69 * byte 3: 0 y9 y8 y7 1 M R L
69 * byte 4: 0 y6 y5 y4 y3 y2 y1 y0 70 * byte 4: 0 y6 y5 y4 y3 y2 y1 y0
70 * byte 5: 0 z6 z5 z4 z3 z2 z1 z0 71 * byte 5: 0 z6 z5 z4 z3 z2 z1 z0
71 * 72 *
@@ -81,11 +82,12 @@ static void alps_process_packet(struct psmouse *psmouse, struct pt_regs *regs)
81 struct input_dev *dev = &psmouse->dev; 82 struct input_dev *dev = &psmouse->dev;
82 struct input_dev *dev2 = &priv->dev2; 83 struct input_dev *dev2 = &priv->dev2;
83 int x, y, z, ges, fin, left, right, middle; 84 int x, y, z, ges, fin, left, right, middle;
85 int back = 0, forward = 0;
84 86
85 input_regs(dev, regs); 87 input_regs(dev, regs);
86 88
87 if ((packet[0] & 0xc8) == 0x08) { /* 3-byte PS/2 packet */ 89 if ((packet[0] & 0xc8) == 0x08) { /* 3-byte PS/2 packet */
88 input_report_key(dev2, BTN_LEFT, packet[0] & 1); 90 input_report_key(dev2, BTN_LEFT, packet[0] & 1);
89 input_report_key(dev2, BTN_RIGHT, packet[0] & 2); 91 input_report_key(dev2, BTN_RIGHT, packet[0] & 2);
90 input_report_key(dev2, BTN_MIDDLE, packet[0] & 4); 92 input_report_key(dev2, BTN_MIDDLE, packet[0] & 4);
91 input_report_rel(dev2, REL_X, 93 input_report_rel(dev2, REL_X,
@@ -112,6 +114,18 @@ static void alps_process_packet(struct psmouse *psmouse, struct pt_regs *regs)
112 z = packet[5]; 114 z = packet[5];
113 } 115 }
114 116
117 if (priv->i->flags & ALPS_FW_BK_1) {
118 back = packet[2] & 4;
119 forward = packet[0] & 0x10;
120 }
121
122 if (priv->i->flags & ALPS_FW_BK_2) {
123 back = packet[3] & 4;
124 forward = packet[2] & 4;
125 if ((middle = forward && back))
126 forward = back = 0;
127 }
128
115 ges = packet[2] & 1; 129 ges = packet[2] & 1;
116 fin = packet[2] & 2; 130 fin = packet[2] & 2;
117 131
@@ -155,13 +169,12 @@ static void alps_process_packet(struct psmouse *psmouse, struct pt_regs *regs)
155 input_report_abs(dev, ABS_PRESSURE, z); 169 input_report_abs(dev, ABS_PRESSURE, z);
156 input_report_key(dev, BTN_TOOL_FINGER, z > 0); 170 input_report_key(dev, BTN_TOOL_FINGER, z > 0);
157 171
158
159 if (priv->i->flags & ALPS_WHEEL) 172 if (priv->i->flags & ALPS_WHEEL)
160 input_report_rel(dev, REL_WHEEL, ((packet[0] >> 4) & 0x07) | ((packet[2] >> 2) & 0x08)); 173 input_report_rel(dev, REL_WHEEL, ((packet[0] >> 4) & 0x07) | ((packet[2] >> 2) & 0x08));
161 174
162 if (priv->i->flags & ALPS_FW_BK) { 175 if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
163 input_report_key(dev, BTN_FORWARD, packet[0] & 0x10); 176 input_report_key(dev, BTN_FORWARD, forward);
164 input_report_key(dev, BTN_BACK, packet[2] & 0x04); 177 input_report_key(dev, BTN_BACK, back);
165 } 178 }
166 179
167 input_sync(dev); 180 input_sync(dev);
@@ -257,7 +270,6 @@ static struct alps_model_info *alps_get_model(struct psmouse *psmouse, int *vers
257static int alps_passthrough_mode(struct psmouse *psmouse, int enable) 270static int alps_passthrough_mode(struct psmouse *psmouse, int enable)
258{ 271{
259 struct ps2dev *ps2dev = &psmouse->ps2dev; 272 struct ps2dev *ps2dev = &psmouse->ps2dev;
260 unsigned char param[3];
261 int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11; 273 int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11;
262 274
263 if (ps2_command(ps2dev, NULL, cmd) || 275 if (ps2_command(ps2dev, NULL, cmd) ||
@@ -267,7 +279,7 @@ static int alps_passthrough_mode(struct psmouse *psmouse, int enable)
267 return -1; 279 return -1;
268 280
269 /* we may get 3 more bytes, just ignore them */ 281 /* we may get 3 more bytes, just ignore them */
270 ps2_command(ps2dev, param, 0x0300); 282 ps2_drain(ps2dev, 3, 100);
271 283
272 return 0; 284 return 0;
273} 285}
@@ -425,7 +437,7 @@ int alps_init(struct psmouse *psmouse)
425 psmouse->dev.relbit[LONG(REL_WHEEL)] |= BIT(REL_WHEEL); 437 psmouse->dev.relbit[LONG(REL_WHEEL)] |= BIT(REL_WHEEL);
426 } 438 }
427 439
428 if (priv->i->flags & ALPS_FW_BK) { 440 if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
429 psmouse->dev.keybit[LONG(BTN_FORWARD)] |= BIT(BTN_FORWARD); 441 psmouse->dev.keybit[LONG(BTN_FORWARD)] |= BIT(BTN_FORWARD);
430 psmouse->dev.keybit[LONG(BTN_BACK)] |= BIT(BTN_BACK); 442 psmouse->dev.keybit[LONG(BTN_BACK)] |= BIT(BTN_BACK);
431 } 443 }
@@ -436,8 +448,8 @@ int alps_init(struct psmouse *psmouse)
436 priv->dev2.id.bustype = BUS_I8042; 448 priv->dev2.id.bustype = BUS_I8042;
437 priv->dev2.id.vendor = 0x0002; 449 priv->dev2.id.vendor = 0x0002;
438 priv->dev2.id.product = PSMOUSE_ALPS; 450 priv->dev2.id.product = PSMOUSE_ALPS;
439 priv->dev2.id.version = 0x0000; 451 priv->dev2.id.version = 0x0000;
440 452
441 priv->dev2.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); 453 priv->dev2.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
442 priv->dev2.relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y); 454 priv->dev2.relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y);
443 priv->dev2.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); 455 priv->dev2.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
@@ -461,17 +473,15 @@ init_fail:
461int alps_detect(struct psmouse *psmouse, int set_properties) 473int alps_detect(struct psmouse *psmouse, int set_properties)
462{ 474{
463 int version; 475 int version;
464 struct alps_model_info *model; 476 struct alps_model_info *model;
465 477
466 if (!(model = alps_get_model(psmouse, &version))) 478 if (!(model = alps_get_model(psmouse, &version)))
467 return -1; 479 return -1;
468 480
469 if (set_properties) { 481 if (set_properties) {
470 psmouse->vendor = "ALPS"; 482 psmouse->vendor = "ALPS";
471 if (model->flags & ALPS_DUALPOINT) 483 psmouse->name = model->flags & ALPS_DUALPOINT ?
472 psmouse->name = "DualPoint TouchPad"; 484 "DualPoint TouchPad" : "GlidePoint";
473 else
474 psmouse->name = "GlidePoint";
475 psmouse->model = version; 485 psmouse->model = version;
476 } 486 }
477 return 0; 487 return 0;