Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2  * ALPS touchpad PS/2 mouse driver
  3  *
  4  * Copyright (c) 2003 Neil Brown <neilb@cse.unsw.edu.au>
  5  * Copyright (c) 2003-2005 Peter Osterlund <petero2@telia.com>
  6  * Copyright (c) 2004 Dmitry Torokhov <dtor@mail.ru>
  7  * Copyright (c) 2005 Vojtech Pavlik <vojtech@suse.cz>
  8  * Copyright (c) 2009 Sebastian Kapfer <sebastian_kapfer@gmx.net>
  9  *
 10  * ALPS detection, tap switching and status querying info is taken from
 11  * tpconfig utility (by C. Scott Ananian and Bruce Kall).
 12  *
 13  * This program is free software; you can redistribute it and/or modify it
 14  * under the terms of the GNU General Public License version 2 as published by
 15  * the Free Software Foundation.
 16  */
 17 
 18 #include <linux/input.h>
 19 #include <linux/serio.h>
 20 #include <linux/libps2.h>
 21 
 22 #include "psmouse.h"
 23 #include "alps.h"
 24 
 25 #undef DEBUG
 26 #ifdef DEBUG
 27 #define dbg(format, arg...) printk(KERN_INFO "alps.c: " format "\n", ## arg)
 28 #else
 29 #define dbg(format, arg...) do {} while (0)
 30 #endif
 31 
 32 #define ALPS_DUALPOINT  0x01
 33 #define ALPS_WHEEL      0x02
 34 #define ALPS_FW_BK_1    0x04
 35 #define ALPS_4BTN       0x08
 36 #define ALPS_OLDPROTO   0x10
 37 #define ALPS_PASS       0x20
 38 #define ALPS_FW_BK_2    0x40
 39 #define ALPS_PS2_INTERLEAVED    0x80    /* 3-byte PS/2 packet interleaved with
 40                                            6-byte ALPS packet */
 41 
 42 static const struct alps_model_info alps_model_data[] = {
 43         { { 0x32, 0x02, 0x14 }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */
 44         { { 0x33, 0x02, 0x0a }, 0x88, 0xf8, ALPS_OLDPROTO },              /* UMAX-530T */
 45         { { 0x53, 0x02, 0x0a }, 0xf8, 0xf8, 0 },
 46         { { 0x53, 0x02, 0x14 }, 0xf8, 0xf8, 0 },
 47         { { 0x60, 0x03, 0xc8 }, 0xf8, 0xf8, 0 },                          /* HP ze1115 */
 48         { { 0x63, 0x02, 0x0a }, 0xf8, 0xf8, 0 },
 49         { { 0x63, 0x02, 0x14 }, 0xf8, 0xf8, 0 },
 50         { { 0x63, 0x02, 0x28 }, 0xf8, 0xf8, ALPS_FW_BK_2 },               /* Fujitsu Siemens S6010 */
 51         { { 0x63, 0x02, 0x3c }, 0x8f, 0x8f, ALPS_WHEEL },                 /* Toshiba Satellite S2400-103 */
 52         { { 0x63, 0x02, 0x50 }, 0xef, 0xef, ALPS_FW_BK_1 },               /* NEC Versa L320 */
 53         { { 0x63, 0x02, 0x64 }, 0xf8, 0xf8, 0 },
 54         { { 0x63, 0x03, 0xc8 }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D800 */
 55         { { 0x73, 0x00, 0x0a }, 0xf8, 0xf8, ALPS_DUALPOINT },             /* ThinkPad R61 8918-5QG */
 56         { { 0x73, 0x02, 0x0a }, 0xf8, 0xf8, 0 },
 57         { { 0x73, 0x02, 0x14 }, 0xf8, 0xf8, ALPS_FW_BK_2 },               /* Ahtec Laptop */
 58         { { 0x20, 0x02, 0x0e }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */
 59         { { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
 60         { { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */
 61         /* Dell Latitude E5500, E6400, E6500, Precision M4400 */
 62         { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf,
 63                 ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },
 64         { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FW_BK_1 },               /* Dell Vostro 1400 */
 65 };
 66 
 67 /*
 68  * XXX - this entry is suspicious. First byte has zero lower nibble,
 69  * which is what a normal mouse would report. Also, the value 0x0e
 70  * isn't valid per PS/2 spec.
 71  */
 72 
 73 /*
 74  * PS/2 packet format
 75  *
 76  * byte 0:  0    0 YSGN XSGN    1    M    R    L
 77  * byte 1: X7   X6   X5   X4   X3   X2   X1   X0
 78  * byte 2: Y7   Y6   Y5   Y4   Y3   Y2   Y1   Y0
 79  *
 80  * Note that the device never signals overflow condition.
 81  *
 82  * ALPS absolute Mode - new format
 83  *
 84  * byte 0:  1    ?    ?    ?    1    ?    ?    ?
 85  * byte 1:  0   x6   x5   x4   x3   x2   x1   x0
 86  * byte 2:  0  x10   x9   x8   x7    ?  fin  ges
 87  * byte 3:  0   y9   y8   y7    1    M    R    L
 88  * byte 4:  0   y6   y5   y4   y3   y2   y1   y0
 89  * byte 5:  0   z6   z5   z4   z3   z2   z1   z0
 90  *
 91  * Dualpoint device -- interleaved packet format
 92  *
 93  * byte 0:    1    1    0    0    1    1    1    1
 94  * byte 1:    0   x6   x5   x4   x3   x2   x1   x0
 95  * byte 2:    0  x10   x9   x8   x7    0  fin  ges
 96  * byte 3:    0    0 YSGN XSGN    1    1    1    1
 97  * byte 4:   X7   X6   X5   X4   X3   X2   X1   X0
 98  * byte 5:   Y7   Y6   Y5   Y4   Y3   Y2   Y1   Y0
 99  * byte 6:    0   y9   y8   y7    1    m    r    l
100  * byte 7:    0   y6   y5   y4   y3   y2   y1   y0
101  * byte 8:    0   z6   z5   z4   z3   z2   z1   z0
102  *
103  * CAPITALS = stick, miniscules = touchpad
104  *
105  * ?'s can have different meanings on different models,
106  * such as wheel rotation, extra buttons, stick buttons
107  * on a dualpoint, etc.
108  */
109 
110 static bool alps_is_valid_first_byte(const struct alps_model_info *model,
111                                      unsigned char data)
112 {
113         return (data & model->mask0) == model->byte0;
114 }
115 
116 static void alps_report_buttons(struct psmouse *psmouse,
117                                 struct input_dev *dev1, struct input_dev *dev2,
118                                 int left, int right, int middle)
119 {
120         struct alps_data *priv = psmouse->private;
121         const struct alps_model_info *model = priv->i;
122 
123         if (model->flags & ALPS_PS2_INTERLEAVED) {
124                 struct input_dev *dev;
125 
126                 /*
127                  * If shared button has already been reported on the
128                  * other device (dev2) then this event should be also
129                  * sent through that device.
130                  */
131                 dev = test_bit(BTN_LEFT, dev2->key) ? dev2 : dev1;
132                 input_report_key(dev, BTN_LEFT, left);
133 
134                 dev = test_bit(BTN_RIGHT, dev2->key) ? dev2 : dev1;
135                 input_report_key(dev, BTN_RIGHT, right);
136 
137                 dev = test_bit(BTN_MIDDLE, dev2->key) ? dev2 : dev1;
138                 input_report_key(dev, BTN_MIDDLE, middle);
139 
140                 /*
141                  * Sync the _other_ device now, we'll do the first
142                  * device later once we report the rest of the events.
143                  */
144                 input_sync(dev2);
145         } else {
146                 /*
147                  * For devices with non-interleaved packets we know what
148                  * device buttons belong to so we can simply report them.
149                  */
150                 input_report_key(dev1, BTN_LEFT, left);
151                 input_report_key(dev1, BTN_RIGHT, right);
152                 input_report_key(dev1, BTN_MIDDLE, middle);
153         }
154 }
155 
156 static void alps_process_packet(struct psmouse *psmouse)
157 {
158         struct alps_data *priv = psmouse->private;
159         unsigned char *packet = psmouse->packet;
160         struct input_dev *dev = psmouse->dev;
161         struct input_dev *dev2 = priv->dev2;
162         int x, y, z, ges, fin, left, right, middle;
163         int back = 0, forward = 0;
164 
165         if (priv->i->flags & ALPS_OLDPROTO) {
166                 left = packet[2] & 0x10;
167                 right = packet[2] & 0x08;
168                 middle = 0;
169                 x = packet[1] | ((packet[0] & 0x07) << 7);
170                 y = packet[4] | ((packet[3] & 0x07) << 7);
171                 z = packet[5];
172         } else {
173                 left = packet[3] & 1;
174                 right = packet[3] & 2;
175                 middle = packet[3] & 4;
176                 x = packet[1] | ((packet[2] & 0x78) << (7 - 3));
177                 y = packet[4] | ((packet[3] & 0x70) << (7 - 4));
178                 z = packet[5];
179         }
180 
181         if (priv->i->flags & ALPS_FW_BK_1) {
182                 back = packet[0] & 0x10;
183                 forward = packet[2] & 4;
184         }
185 
186         if (priv->i->flags & ALPS_FW_BK_2) {
187                 back = packet[3] & 4;
188                 forward = packet[2] & 4;
189                 if ((middle = forward && back))
190                         forward = back = 0;
191         }
192 
193         ges = packet[2] & 1;
194         fin = packet[2] & 2;
195 
196         if ((priv->i->flags & ALPS_DUALPOINT) && z == 127) {
197                 input_report_rel(dev2, REL_X,  (x > 383 ? (x - 768) : x));
198                 input_report_rel(dev2, REL_Y, -(y > 255 ? (y - 512) : y));
199 
200                 alps_report_buttons(psmouse, dev2, dev, left, right, middle);
201 
202                 input_sync(dev2);
203                 return;
204         }
205 
206         alps_report_buttons(psmouse, dev, dev2, left, right, middle);
207 
208         /* Convert hardware tap to a reasonable Z value */
209         if (ges && !fin) z = 40;
210 
211         /*
212          * A "tap and drag" operation is reported by the hardware as a transition
213          * from (!fin && ges) to (fin && ges). This should be translated to the
214          * sequence Z>0, Z==0, Z>0, so the Z==0 event has to be generated manually.
215          */
216         if (ges && fin && !priv->prev_fin) {
217                 input_report_abs(dev, ABS_X, x);
218                 input_report_abs(dev, ABS_Y, y);
219                 input_report_abs(dev, ABS_PRESSURE, 0);
220                 input_report_key(dev, BTN_TOOL_FINGER, 0);
221                 input_sync(dev);
222         }
223         priv->prev_fin = fin;
224 
225         if (z > 30) input_report_key(dev, BTN_TOUCH, 1);
226         if (z < 25) input_report_key(dev, BTN_TOUCH, 0);
227 
228         if (z > 0) {
229                 input_report_abs(dev, ABS_X, x);
230                 input_report_abs(dev, ABS_Y, y);
231         }
232 
233         input_report_abs(dev, ABS_PRESSURE, z);
234         input_report_key(dev, BTN_TOOL_FINGER, z > 0);
235 
236         if (priv->i->flags & ALPS_WHEEL)
237                 input_report_rel(dev, REL_WHEEL, ((packet[2] << 1) & 0x08) - ((packet[0] >> 4) & 0x07));
238 
239         if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
240                 input_report_key(dev, BTN_FORWARD, forward);
241                 input_report_key(dev, BTN_BACK, back);
242         }
243 
244         input_sync(dev);
245 }
246 
247 static void alps_report_bare_ps2_packet(struct psmouse *psmouse,
248                                         unsigned char packet[],
249                                         bool report_buttons)
250 {
251         struct alps_data *priv = psmouse->private;
252         struct input_dev *dev2 = priv->dev2;
253 
254         if (report_buttons)
255                 alps_report_buttons(psmouse, dev2, psmouse->dev,
256                                 packet[0] & 1, packet[0] & 2, packet[0] & 4);
257 
258         input_report_rel(dev2, REL_X,
259                 packet[1] ? packet[1] - ((packet[0] << 4) & 0x100) : 0);
260         input_report_rel(dev2, REL_Y,
261                 packet[2] ? ((packet[0] << 3) & 0x100) - packet[2] : 0);
262 
263         input_sync(dev2);
264 }
265 
266 static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse)
267 {
268         struct alps_data *priv = psmouse->private;
269 
270         if (psmouse->pktcnt < 6)
271                 return PSMOUSE_GOOD_DATA;
272 
273         if (psmouse->pktcnt == 6) {
274                 /*
275                  * Start a timer to flush the packet if it ends up last
276                  * 6-byte packet in the stream. Timer needs to fire
277                  * psmouse core times out itself. 20 ms should be enough
278                  * to decide if we are getting more data or not.
279                  */
280                 mod_timer(&priv->timer, jiffies + msecs_to_jiffies(20));
281                 return PSMOUSE_GOOD_DATA;
282         }
283 
284         del_timer(&priv->timer);
285 
286         if (psmouse->packet[6] & 0x80) {
287 
288                 /*
289                  * Highest bit is set - that means we either had
290                  * complete ALPS packet and this is start of the
291                  * next packet or we got garbage.
292                  */
293 
294                 if (((psmouse->packet[3] |
295                       psmouse->packet[4] |
296                       psmouse->packet[5]) & 0x80) ||
297                     (!alps_is_valid_first_byte(priv->i, psmouse->packet[6]))) {
298                         dbg("refusing packet %x %x %x %x "
299                             "(suspected interleaved ps/2)\n",
300                             psmouse->packet[3], psmouse->packet[4],
301                             psmouse->packet[5], psmouse->packet[6]);
302                         return PSMOUSE_BAD_DATA;
303                 }
304 
305                 alps_process_packet(psmouse);
306 
307                 /* Continue with the next packet */
308                 psmouse->packet[0] = psmouse->packet[6];
309                 psmouse->pktcnt = 1;
310 
311         } else {
312 
313                 /*
314                  * High bit is 0 - that means that we indeed got a PS/2
315                  * packet in the middle of ALPS packet.
316                  *
317                  * There is also possibility that we got 6-byte ALPS
318                  * packet followed  by 3-byte packet from trackpoint. We
319                  * can not distinguish between these 2 scenarios but
320                  * becase the latter is unlikely to happen in course of
321                  * normal operation (user would need to press all
322                  * buttons on the pad and start moving trackpoint
323                  * without touching the pad surface) we assume former.
324                  * Even if we are wrong the wost thing that would happen
325                  * the cursor would jump but we should not get protocol
326                  * desynchronization.
327                  */
328 
329                 alps_report_bare_ps2_packet(psmouse, &psmouse->packet[3],
330                                             false);
331 
332                 /*
333                  * Continue with the standard ALPS protocol handling,
334                  * but make sure we won't process it as an interleaved
335                  * packet again, which may happen if all buttons are
336                  * pressed. To avoid this let's reset the 4th bit which
337                  * is normally 1.
338                  */
339                 psmouse->packet[3] = psmouse->packet[6] & 0xf7;
340                 psmouse->pktcnt = 4;
341         }
342 
343         return PSMOUSE_GOOD_DATA;
344 }
345 
346 static void alps_flush_packet(unsigned long data)
347 {
348         struct psmouse *psmouse = (struct psmouse *)data;
349 
350         serio_pause_rx(psmouse->ps2dev.serio);
351 
352         if (psmouse->pktcnt == 6) {
353 
354                 /*
355                  * We did not any more data in reasonable amount of time.
356                  * Validate the last 3 bytes and process as a standard
357                  * ALPS packet.
358                  */
359                 if ((psmouse->packet[3] |
360                      psmouse->packet[4] |
361                      psmouse->packet[5]) & 0x80) {
362                         dbg("refusing packet %x %x %x "
363                             "(suspected interleaved ps/2)\n",
364                             psmouse->packet[3], psmouse->packet[4],
365                             psmouse->packet[5]);
366                 } else {
367                         alps_process_packet(psmouse);
368                 }
369                 psmouse->pktcnt = 0;
370         }
371 
372         serio_continue_rx(psmouse->ps2dev.serio);
373 }
374 
375 static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
376 {
377         struct alps_data *priv = psmouse->private;
378         const struct alps_model_info *model = priv->i;
379 
380         if ((psmouse->packet[0] & 0xc8) == 0x08) { /* PS/2 packet */
381                 if (psmouse->pktcnt == 3) {
382                         alps_report_bare_ps2_packet(psmouse, psmouse->packet,
383                                                     true);
384                         return PSMOUSE_FULL_PACKET;
385                 }
386                 return PSMOUSE_GOOD_DATA;
387         }
388 
389         /* Check for PS/2 packet stuffed in the middle of ALPS packet. */
390 
391         if ((model->flags & ALPS_PS2_INTERLEAVED) &&
392             psmouse->pktcnt >= 4 && (psmouse->packet[3] & 0x0f) == 0x0f) {
393                 return alps_handle_interleaved_ps2(psmouse);
394         }
395 
396         if (!alps_is_valid_first_byte(model, psmouse->packet[0])) {
397                 dbg("refusing packet[0] = %x (mask0 = %x, byte0 = %x)\n",
398                     psmouse->packet[0], model->mask0, model->byte0);
399                 return PSMOUSE_BAD_DATA;
400         }
401 
402         /* Bytes 2 - 6 should have 0 in the highest bit */
403         if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= 6 &&
404             (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) {
405                 dbg("refusing packet[%i] = %x\n",
406                     psmouse->pktcnt - 1, psmouse->packet[psmouse->pktcnt - 1]);
407                 return PSMOUSE_BAD_DATA;
408         }
409 
410         if (psmouse->pktcnt == 6) {
411                 alps_process_packet(psmouse);
412                 return PSMOUSE_FULL_PACKET;
413         }
414 
415         return PSMOUSE_GOOD_DATA;
416 }
417 
418 static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int *version)
419 {
420         struct ps2dev *ps2dev = &psmouse->ps2dev;
421         static const unsigned char rates[] = { 0, 10, 20, 40, 60, 80, 100, 200 };
422         unsigned char param[4];
423         int i;
424 
425         /*
426          * First try "E6 report".
427          * ALPS should return 0,0,10 or 0,0,100
428          */
429         param[0] = 0;
430         if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES) ||
431             ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11) ||
432             ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11) ||
433             ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11))
434                 return NULL;
435 
436         param[0] = param[1] = param[2] = 0xff;
437         if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
438                 return NULL;
439 
440         dbg("E6 report: %2.2x %2.2x %2.2x", param[0], param[1], param[2]);
441 
442         if (param[0] != 0 || param[1] != 0 || (param[2] != 10 && param[2] != 100))
443                 return NULL;
444 
445         /*
446          * Now try "E7 report". Allowed responses are in
447          * alps_model_data[].signature
448          */
449         param[0] = 0;
450         if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES) ||
451             ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE21) ||
452             ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE21) ||
453             ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE21))
454                 return NULL;
455 
456         param[0] = param[1] = param[2] = 0xff;
457         if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
458                 return NULL;
459 
460         dbg("E7 report: %2.2x %2.2x %2.2x", param[0], param[1], param[2]);
461 
462         if (version) {
463                 for (i = 0; i < ARRAY_SIZE(rates) && param[2] != rates[i]; i++)
464                         /* empty */;
465                 *version = (param[0] << 8) | (param[1] << 4) | i;
466         }
467 
468         for (i = 0; i < ARRAY_SIZE(alps_model_data); i++)
469                 if (!memcmp(param, alps_model_data[i].signature,
470                             sizeof(alps_model_data[i].signature)))
471                         return alps_model_data + i;
472 
473         return NULL;
474 }
475 
476 /*
477  * For DualPoint devices select the device that should respond to
478  * subsequent commands. It looks like glidepad is behind stickpointer,
479  * I'd thought it would be other way around...
480  */
481 static int alps_passthrough_mode(struct psmouse *psmouse, int enable)
482 {
483         struct ps2dev *ps2dev = &psmouse->ps2dev;
484         int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11;
485 
486         if (ps2_command(ps2dev, NULL, cmd) ||
487             ps2_command(ps2dev, NULL, cmd) ||
488             ps2_command(ps2dev, NULL, cmd) ||
489             ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE))
490                 return -1;
491 
492         /* we may get 3 more bytes, just ignore them */
493         ps2_drain(ps2dev, 3, 100);
494 
495         return 0;
496 }
497 
498 static int alps_absolute_mode(struct psmouse *psmouse)
499 {
500         struct ps2dev *ps2dev = &psmouse->ps2dev;
501 
502         /* Try ALPS magic knock - 4 disable before enable */
503         if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
504             ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
505             ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
506             ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
507             ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE))
508                 return -1;
509 
510         /*
511          * Switch mouse to poll (remote) mode so motion data will not
512          * get in our way
513          */
514         return ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETPOLL);
515 }
516 
517 static int alps_get_status(struct psmouse *psmouse, char *param)
518 {
519         struct ps2dev *ps2dev = &psmouse->ps2dev;
520 
521         /* Get status: 0xF5 0xF5 0xF5 0xE9 */
522         if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
523             ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
524             ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
525             ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
526                 return -1;
527 
528         dbg("Status: %2.2x %2.2x %2.2x", param[0], param[1], param[2]);
529 
530         return 0;
531 }
532 
533 /*
534  * Turn touchpad tapping on or off. The sequences are:
535  * 0xE9 0xF5 0xF5 0xF3 0x0A to enable,
536  * 0xE9 0xF5 0xF5 0xE8 0x00 to disable.
537  * My guess that 0xE9 (GetInfo) is here as a sync point.
538  * For models that also have stickpointer (DualPoints) its tapping
539  * is controlled separately (0xE6 0xE6 0xE6 0xF3 0x14|0x0A) but
540  * we don't fiddle with it.
541  */
542 static int alps_tap_mode(struct psmouse *psmouse, int enable)
543 {
544         struct ps2dev *ps2dev = &psmouse->ps2dev;
545         int cmd = enable ? PSMOUSE_CMD_SETRATE : PSMOUSE_CMD_SETRES;
546         unsigned char tap_arg = enable ? 0x0A : 0x00;
547         unsigned char param[4];
548 
549         if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO) ||
550             ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
551             ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
552             ps2_command(ps2dev, &tap_arg, cmd))
553                 return -1;
554 
555         if (alps_get_status(psmouse, param))
556                 return -1;
557 
558         return 0;
559 }
560 
561 /*
562  * alps_poll() - poll the touchpad for current motion packet.
563  * Used in resync.
564  */
565 static int alps_poll(struct psmouse *psmouse)
566 {
567         struct alps_data *priv = psmouse->private;
568         unsigned char buf[6];
569         int poll_failed;
570 
571         if (priv->i->flags & ALPS_PASS)
572                 alps_passthrough_mode(psmouse, 1);
573 
574         poll_failed = ps2_command(&psmouse->ps2dev, buf,
575                                   PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)) < 0;
576 
577         if (priv->i->flags & ALPS_PASS)
578                 alps_passthrough_mode(psmouse, 0);
579 
580         if (poll_failed || (buf[0] & priv->i->mask0) != priv->i->byte0)
581                 return -1;
582 
583         if ((psmouse->badbyte & 0xc8) == 0x08) {
584 /*
585  * Poll the track stick ...
586  */
587                 if (ps2_command(&psmouse->ps2dev, buf, PSMOUSE_CMD_POLL | (3 << 8)))
588                         return -1;
589         }
590 
591         memcpy(psmouse->packet, buf, sizeof(buf));
592         return 0;
593 }
594 
595 static int alps_hw_init(struct psmouse *psmouse, int *version)
596 {
597         struct alps_data *priv = psmouse->private;
598 
599         priv->i = alps_get_model(psmouse, version);
600         if (!priv->i)
601                 return -1;
602 
603         if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1))
604                 return -1;
605 
606         if (alps_tap_mode(psmouse, 1)) {
607                 printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n");
608                 return -1;
609         }
610 
611         if (alps_absolute_mode(psmouse)) {
612                 printk(KERN_ERR "alps.c: Failed to enable absolute mode\n");
613                 return -1;
614         }
615 
616         if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 0))
617                 return -1;
618 
619         /* ALPS needs stream mode, otherwise it won't report any data */
620         if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM)) {
621                 printk(KERN_ERR "alps.c: Failed to enable stream mode\n");
622                 return -1;
623         }
624 
625         return 0;
626 }
627 
628 static int alps_reconnect(struct psmouse *psmouse)
629 {
630         psmouse_reset(psmouse);
631 
632         if (alps_hw_init(psmouse, NULL))
633                 return -1;
634 
635         return 0;
636 }
637 
638 static void alps_disconnect(struct psmouse *psmouse)
639 {
640         struct alps_data *priv = psmouse->private;
641 
642         psmouse_reset(psmouse);
643         del_timer_sync(&priv->timer);
644         input_unregister_device(priv->dev2);
645         kfree(priv);
646 }
647 
648 int alps_init(struct psmouse *psmouse)
649 {
650         struct alps_data *priv;
651         struct input_dev *dev1 = psmouse->dev, *dev2;
652         int version;
653 
654         priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL);
655         dev2 = input_allocate_device();
656         if (!priv || !dev2)
657                 goto init_fail;
658 
659         priv->dev2 = dev2;
660         setup_timer(&priv->timer, alps_flush_packet, (unsigned long)psmouse);
661 
662         psmouse->private = priv;
663 
664         if (alps_hw_init(psmouse, &version))
665                 goto init_fail;
666 
667         dev1->evbit[BIT_WORD(EV_KEY)] |= BIT_MASK(EV_KEY);
668         dev1->keybit[BIT_WORD(BTN_TOUCH)] |= BIT_MASK(BTN_TOUCH);
669         dev1->keybit[BIT_WORD(BTN_TOOL_FINGER)] |= BIT_MASK(BTN_TOOL_FINGER);
670         dev1->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) |
671                 BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
672 
673         dev1->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS);
674         input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0);
675         input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0);
676         input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0);
677 
678         if (priv->i->flags & ALPS_WHEEL) {
679                 dev1->evbit[BIT_WORD(EV_REL)] |= BIT_MASK(EV_REL);
680                 dev1->relbit[BIT_WORD(REL_WHEEL)] |= BIT_MASK(REL_WHEEL);
681         }
682 
683         if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
684                 dev1->keybit[BIT_WORD(BTN_FORWARD)] |= BIT_MASK(BTN_FORWARD);
685                 dev1->keybit[BIT_WORD(BTN_BACK)] |= BIT_MASK(BTN_BACK);
686         }
687 
688         snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys);
689         dev2->phys = priv->phys;
690         dev2->name = (priv->i->flags & ALPS_DUALPOINT) ? "DualPoint Stick" : "PS/2 Mouse";
691         dev2->id.bustype = BUS_I8042;
692         dev2->id.vendor  = 0x0002;
693         dev2->id.product = PSMOUSE_ALPS;
694         dev2->id.version = 0x0000;
695         dev2->dev.parent = &psmouse->ps2dev.serio->dev;
696 
697         dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
698         dev2->relbit[BIT_WORD(REL_X)] |= BIT_MASK(REL_X) | BIT_MASK(REL_Y);
699         dev2->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) |
700                 BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
701 
702         if (input_register_device(priv->dev2))
703                 goto init_fail;
704 
705         psmouse->protocol_handler = alps_process_byte;
706         psmouse->poll = alps_poll;
707         psmouse->disconnect = alps_disconnect;
708         psmouse->reconnect = alps_reconnect;
709         psmouse->pktsize = 6;
710 
711         /* We are having trouble resyncing ALPS touchpads so disable it for now */
712         psmouse->resync_time = 0;
713 
714         return 0;
715 
716 init_fail:
717         psmouse_reset(psmouse);
718         input_free_device(dev2);
719         kfree(priv);
720         psmouse->private = NULL;
721         return -1;
722 }
723 
724 int alps_detect(struct psmouse *psmouse, int set_properties)
725 {
726         int version;
727         const struct alps_model_info *model;
728 
729         model = alps_get_model(psmouse, &version);
730         if (!model)
731                 return -1;
732 
733         if (set_properties) {
734                 psmouse->vendor = "ALPS";
735                 psmouse->name = model->flags & ALPS_DUALPOINT ?
736                                 "DualPoint TouchPad" : "GlidePoint";
737                 psmouse->model = version;
738         }
739         return 0;
740 }
741 
742 
  This page was automatically generated by the LXR engine.