xref: /openbmc/linux/drivers/input/mouse/synaptics.c (revision b6dcefde)
1 /*
2  * Synaptics TouchPad PS/2 mouse driver
3  *
4  *   2003 Dmitry Torokhov <dtor@mail.ru>
5  *     Added support for pass-through port. Special thanks to Peter Berg Larsen
6  *     for explaining various Synaptics quirks.
7  *
8  *   2003 Peter Osterlund <petero2@telia.com>
9  *     Ported to 2.5 input device infrastructure.
10  *
11  *   Copyright (C) 2001 Stefan Gmeiner <riddlebox@freesurf.ch>
12  *     start merging tpconfig and gpm code to a xfree-input module
13  *     adding some changes and extensions (ex. 3rd and 4th button)
14  *
15  *   Copyright (c) 1997 C. Scott Ananian <cananian@alumni.priceton.edu>
16  *   Copyright (c) 1998-2000 Bruce Kalk <kall@compass.com>
17  *     code for the special synaptics commands (from the tpconfig-source)
18  *
19  * This program is free software; you can redistribute it and/or modify it
20  * under the terms of the GNU General Public License version 2 as published by
21  * the Free Software Foundation.
22  *
23  * Trademarks are the property of their respective owners.
24  */
25 
26 #include <linux/module.h>
27 #include <linux/dmi.h>
28 #include <linux/input.h>
29 #include <linux/serio.h>
30 #include <linux/libps2.h>
31 #include "psmouse.h"
32 #include "synaptics.h"
33 
34 /*
35  * The x/y limits are taken from the Synaptics TouchPad interfacing Guide,
36  * section 2.3.2, which says that they should be valid regardless of the
37  * actual size of the sensor.
38  */
39 #define XMIN_NOMINAL 1472
40 #define XMAX_NOMINAL 5472
41 #define YMIN_NOMINAL 1408
42 #define YMAX_NOMINAL 4448
43 
44 
45 /*****************************************************************************
46  *	Stuff we need even when we do not want native Synaptics support
47  ****************************************************************************/
48 
49 /*
50  * Set the synaptics touchpad mode byte by special commands
51  */
52 static int synaptics_mode_cmd(struct psmouse *psmouse, unsigned char mode)
53 {
54 	unsigned char param[1];
55 
56 	if (psmouse_sliced_command(psmouse, mode))
57 		return -1;
58 	param[0] = SYN_PS_SET_MODE2;
59 	if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_SETRATE))
60 		return -1;
61 	return 0;
62 }
63 
64 int synaptics_detect(struct psmouse *psmouse, bool set_properties)
65 {
66 	struct ps2dev *ps2dev = &psmouse->ps2dev;
67 	unsigned char param[4];
68 
69 	param[0] = 0;
70 
71 	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
72 	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
73 	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
74 	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
75 	ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO);
76 
77 	if (param[1] != 0x47)
78 		return -ENODEV;
79 
80 	if (set_properties) {
81 		psmouse->vendor = "Synaptics";
82 		psmouse->name = "TouchPad";
83 	}
84 
85 	return 0;
86 }
87 
88 void synaptics_reset(struct psmouse *psmouse)
89 {
90 	/* reset touchpad back to relative mode, gestures enabled */
91 	synaptics_mode_cmd(psmouse, 0);
92 }
93 
94 #ifdef CONFIG_MOUSE_PS2_SYNAPTICS
95 
96 /*****************************************************************************
97  *	Synaptics communications functions
98  ****************************************************************************/
99 
100 /*
101  * Send a command to the synpatics touchpad by special commands
102  */
103 static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, unsigned char *param)
104 {
105 	if (psmouse_sliced_command(psmouse, c))
106 		return -1;
107 	if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO))
108 		return -1;
109 	return 0;
110 }
111 
112 /*
113  * Read the model-id bytes from the touchpad
114  * see also SYN_MODEL_* macros
115  */
116 static int synaptics_model_id(struct psmouse *psmouse)
117 {
118 	struct synaptics_data *priv = psmouse->private;
119 	unsigned char mi[3];
120 
121 	if (synaptics_send_cmd(psmouse, SYN_QUE_MODEL, mi))
122 		return -1;
123 	priv->model_id = (mi[0]<<16) | (mi[1]<<8) | mi[2];
124 	return 0;
125 }
126 
127 /*
128  * Read the capability-bits from the touchpad
129  * see also the SYN_CAP_* macros
130  */
131 static int synaptics_capability(struct psmouse *psmouse)
132 {
133 	struct synaptics_data *priv = psmouse->private;
134 	unsigned char cap[3];
135 
136 	if (synaptics_send_cmd(psmouse, SYN_QUE_CAPABILITIES, cap))
137 		return -1;
138 	priv->capabilities = (cap[0] << 16) | (cap[1] << 8) | cap[2];
139 	priv->ext_cap = 0;
140 	if (!SYN_CAP_VALID(priv->capabilities))
141 		return -1;
142 
143 	/*
144 	 * Unless capExtended is set the rest of the flags should be ignored
145 	 */
146 	if (!SYN_CAP_EXTENDED(priv->capabilities))
147 		priv->capabilities = 0;
148 
149 	if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 1) {
150 		if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB, cap)) {
151 			printk(KERN_ERR "Synaptics claims to have extended capabilities,"
152 			       " but I'm not able to read them.");
153 		} else {
154 			priv->ext_cap = (cap[0] << 16) | (cap[1] << 8) | cap[2];
155 
156 			/*
157 			 * if nExtBtn is greater than 8 it should be considered
158 			 * invalid and treated as 0
159 			 */
160 			if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) > 8)
161 				priv->ext_cap &= 0xff0fff;
162 		}
163 	}
164 	return 0;
165 }
166 
167 /*
168  * Identify Touchpad
169  * See also the SYN_ID_* macros
170  */
171 static int synaptics_identify(struct psmouse *psmouse)
172 {
173 	struct synaptics_data *priv = psmouse->private;
174 	unsigned char id[3];
175 
176 	if (synaptics_send_cmd(psmouse, SYN_QUE_IDENTIFY, id))
177 		return -1;
178 	priv->identity = (id[0]<<16) | (id[1]<<8) | id[2];
179 	if (SYN_ID_IS_SYNAPTICS(priv->identity))
180 		return 0;
181 	return -1;
182 }
183 
184 /*
185  * Read touchpad resolution
186  * Resolution is left zero if touchpad does not support the query
187  */
188 static int synaptics_resolution(struct psmouse *psmouse)
189 {
190 	struct synaptics_data *priv = psmouse->private;
191 	unsigned char res[3];
192 
193 	if (SYN_ID_MAJOR(priv->identity) < 4)
194 		return 0;
195 
196 	if (synaptics_send_cmd(psmouse, SYN_QUE_RESOLUTION, res))
197 		return 0;
198 
199 	if ((res[0] != 0) && (res[1] & 0x80) && (res[2] != 0)) {
200 		priv->x_res = res[0]; /* x resolution in units/mm */
201 		priv->y_res = res[2]; /* y resolution in units/mm */
202 	}
203 
204 	return 0;
205 }
206 
207 static int synaptics_query_hardware(struct psmouse *psmouse)
208 {
209 	if (synaptics_identify(psmouse))
210 		return -1;
211 	if (synaptics_model_id(psmouse))
212 		return -1;
213 	if (synaptics_capability(psmouse))
214 		return -1;
215 	if (synaptics_resolution(psmouse))
216 		return -1;
217 
218 	return 0;
219 }
220 
221 static int synaptics_set_absolute_mode(struct psmouse *psmouse)
222 {
223 	struct synaptics_data *priv = psmouse->private;
224 
225 	priv->mode = SYN_BIT_ABSOLUTE_MODE;
226 	if (SYN_ID_MAJOR(priv->identity) >= 4)
227 		priv->mode |= SYN_BIT_DISABLE_GESTURE;
228 	if (SYN_CAP_EXTENDED(priv->capabilities))
229 		priv->mode |= SYN_BIT_W_MODE;
230 
231 	if (synaptics_mode_cmd(psmouse, priv->mode))
232 		return -1;
233 
234 	return 0;
235 }
236 
237 static void synaptics_set_rate(struct psmouse *psmouse, unsigned int rate)
238 {
239 	struct synaptics_data *priv = psmouse->private;
240 
241 	if (rate >= 80) {
242 		priv->mode |= SYN_BIT_HIGH_RATE;
243 		psmouse->rate = 80;
244 	} else {
245 		priv->mode &= ~SYN_BIT_HIGH_RATE;
246 		psmouse->rate = 40;
247 	}
248 
249 	synaptics_mode_cmd(psmouse, priv->mode);
250 }
251 
252 /*****************************************************************************
253  *	Synaptics pass-through PS/2 port support
254  ****************************************************************************/
255 static int synaptics_pt_write(struct serio *serio, unsigned char c)
256 {
257 	struct psmouse *parent = serio_get_drvdata(serio->parent);
258 	char rate_param = SYN_PS_CLIENT_CMD; /* indicates that we want pass-through port */
259 
260 	if (psmouse_sliced_command(parent, c))
261 		return -1;
262 	if (ps2_command(&parent->ps2dev, &rate_param, PSMOUSE_CMD_SETRATE))
263 		return -1;
264 	return 0;
265 }
266 
267 static inline int synaptics_is_pt_packet(unsigned char *buf)
268 {
269 	return (buf[0] & 0xFC) == 0x84 && (buf[3] & 0xCC) == 0xC4;
270 }
271 
272 static void synaptics_pass_pt_packet(struct serio *ptport, unsigned char *packet)
273 {
274 	struct psmouse *child = serio_get_drvdata(ptport);
275 
276 	if (child && child->state == PSMOUSE_ACTIVATED) {
277 		serio_interrupt(ptport, packet[1], 0);
278 		serio_interrupt(ptport, packet[4], 0);
279 		serio_interrupt(ptport, packet[5], 0);
280 		if (child->pktsize == 4)
281 			serio_interrupt(ptport, packet[2], 0);
282 	} else
283 		serio_interrupt(ptport, packet[1], 0);
284 }
285 
286 static void synaptics_pt_activate(struct psmouse *psmouse)
287 {
288 	struct serio *ptport = psmouse->ps2dev.serio->child;
289 	struct psmouse *child = serio_get_drvdata(ptport);
290 	struct synaptics_data *priv = psmouse->private;
291 
292 	/* adjust the touchpad to child's choice of protocol */
293 	if (child) {
294 		if (child->pktsize == 4)
295 			priv->mode |= SYN_BIT_FOUR_BYTE_CLIENT;
296 		else
297 			priv->mode &= ~SYN_BIT_FOUR_BYTE_CLIENT;
298 
299 		if (synaptics_mode_cmd(psmouse, priv->mode))
300 			printk(KERN_INFO "synaptics: failed to switch guest protocol\n");
301 	}
302 }
303 
304 static void synaptics_pt_create(struct psmouse *psmouse)
305 {
306 	struct serio *serio;
307 
308 	serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
309 	if (!serio) {
310 		printk(KERN_ERR "synaptics: not enough memory to allocate pass-through port\n");
311 		return;
312 	}
313 
314 	serio->id.type = SERIO_PS_PSTHRU;
315 	strlcpy(serio->name, "Synaptics pass-through", sizeof(serio->name));
316 	strlcpy(serio->phys, "synaptics-pt/serio0", sizeof(serio->name));
317 	serio->write = synaptics_pt_write;
318 	serio->parent = psmouse->ps2dev.serio;
319 
320 	psmouse->pt_activate = synaptics_pt_activate;
321 
322 	printk(KERN_INFO "serio: %s port at %s\n", serio->name, psmouse->phys);
323 	serio_register_port(serio);
324 }
325 
326 /*****************************************************************************
327  *	Functions to interpret the absolute mode packets
328  ****************************************************************************/
329 
330 static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data *priv, struct synaptics_hw_state *hw)
331 {
332 	memset(hw, 0, sizeof(struct synaptics_hw_state));
333 
334 	if (SYN_MODEL_NEWABS(priv->model_id)) {
335 		hw->x = (((buf[3] & 0x10) << 8) |
336 			 ((buf[1] & 0x0f) << 8) |
337 			 buf[4]);
338 		hw->y = (((buf[3] & 0x20) << 7) |
339 			 ((buf[1] & 0xf0) << 4) |
340 			 buf[5]);
341 
342 		hw->z = buf[2];
343 		hw->w = (((buf[0] & 0x30) >> 2) |
344 			 ((buf[0] & 0x04) >> 1) |
345 			 ((buf[3] & 0x04) >> 2));
346 
347 		hw->left  = (buf[0] & 0x01) ? 1 : 0;
348 		hw->right = (buf[0] & 0x02) ? 1 : 0;
349 
350 		if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) {
351 			hw->middle = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
352 			if (hw->w == 2)
353 				hw->scroll = (signed char)(buf[1]);
354 		}
355 
356 		if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) {
357 			hw->up   = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
358 			hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0;
359 		}
360 
361 		if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) &&
362 		    ((buf[0] ^ buf[3]) & 0x02)) {
363 			switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) {
364 			default:
365 				/*
366 				 * if nExtBtn is greater than 8 it should be
367 				 * considered invalid and treated as 0
368 				 */
369 				break;
370 			case 8:
371 				hw->ext_buttons |= ((buf[5] & 0x08)) ? 0x80 : 0;
372 				hw->ext_buttons |= ((buf[4] & 0x08)) ? 0x40 : 0;
373 			case 6:
374 				hw->ext_buttons |= ((buf[5] & 0x04)) ? 0x20 : 0;
375 				hw->ext_buttons |= ((buf[4] & 0x04)) ? 0x10 : 0;
376 			case 4:
377 				hw->ext_buttons |= ((buf[5] & 0x02)) ? 0x08 : 0;
378 				hw->ext_buttons |= ((buf[4] & 0x02)) ? 0x04 : 0;
379 			case 2:
380 				hw->ext_buttons |= ((buf[5] & 0x01)) ? 0x02 : 0;
381 				hw->ext_buttons |= ((buf[4] & 0x01)) ? 0x01 : 0;
382 			}
383 		}
384 	} else {
385 		hw->x = (((buf[1] & 0x1f) << 8) | buf[2]);
386 		hw->y = (((buf[4] & 0x1f) << 8) | buf[5]);
387 
388 		hw->z = (((buf[0] & 0x30) << 2) | (buf[3] & 0x3F));
389 		hw->w = (((buf[1] & 0x80) >> 4) | ((buf[0] & 0x04) >> 1));
390 
391 		hw->left  = (buf[0] & 0x01) ? 1 : 0;
392 		hw->right = (buf[0] & 0x02) ? 1 : 0;
393 	}
394 }
395 
396 /*
397  *  called for each full received packet from the touchpad
398  */
399 static void synaptics_process_packet(struct psmouse *psmouse)
400 {
401 	struct input_dev *dev = psmouse->dev;
402 	struct synaptics_data *priv = psmouse->private;
403 	struct synaptics_hw_state hw;
404 	int num_fingers;
405 	int finger_width;
406 	int i;
407 
408 	synaptics_parse_hw_state(psmouse->packet, priv, &hw);
409 
410 	if (hw.scroll) {
411 		priv->scroll += hw.scroll;
412 
413 		while (priv->scroll >= 4) {
414 			input_report_key(dev, BTN_BACK, !hw.down);
415 			input_sync(dev);
416 			input_report_key(dev, BTN_BACK, hw.down);
417 			input_sync(dev);
418 			priv->scroll -= 4;
419 		}
420 		while (priv->scroll <= -4) {
421 			input_report_key(dev, BTN_FORWARD, !hw.up);
422 			input_sync(dev);
423 			input_report_key(dev, BTN_FORWARD, hw.up);
424 			input_sync(dev);
425 			priv->scroll += 4;
426 		}
427 		return;
428 	}
429 
430 	if (hw.z > 0) {
431 		num_fingers = 1;
432 		finger_width = 5;
433 		if (SYN_CAP_EXTENDED(priv->capabilities)) {
434 			switch (hw.w) {
435 			case 0 ... 1:
436 				if (SYN_CAP_MULTIFINGER(priv->capabilities))
437 					num_fingers = hw.w + 2;
438 				break;
439 			case 2:
440 				if (SYN_MODEL_PEN(priv->model_id))
441 					;   /* Nothing, treat a pen as a single finger */
442 				break;
443 			case 4 ... 15:
444 				if (SYN_CAP_PALMDETECT(priv->capabilities))
445 					finger_width = hw.w;
446 				break;
447 			}
448 		}
449 	} else {
450 		num_fingers = 0;
451 		finger_width = 0;
452 	}
453 
454 	/* Post events
455 	 * BTN_TOUCH has to be first as mousedev relies on it when doing
456 	 * absolute -> relative conversion
457 	 */
458 	if (hw.z > 30) input_report_key(dev, BTN_TOUCH, 1);
459 	if (hw.z < 25) input_report_key(dev, BTN_TOUCH, 0);
460 
461 	if (hw.z > 0) {
462 		input_report_abs(dev, ABS_X, hw.x);
463 		input_report_abs(dev, ABS_Y, YMAX_NOMINAL + YMIN_NOMINAL - hw.y);
464 	}
465 	input_report_abs(dev, ABS_PRESSURE, hw.z);
466 
467 	input_report_abs(dev, ABS_TOOL_WIDTH, finger_width);
468 	input_report_key(dev, BTN_TOOL_FINGER, num_fingers == 1);
469 	input_report_key(dev, BTN_LEFT, hw.left);
470 	input_report_key(dev, BTN_RIGHT, hw.right);
471 
472 	if (SYN_CAP_MULTIFINGER(priv->capabilities)) {
473 		input_report_key(dev, BTN_TOOL_DOUBLETAP, num_fingers == 2);
474 		input_report_key(dev, BTN_TOOL_TRIPLETAP, num_fingers == 3);
475 	}
476 
477 	if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
478 		input_report_key(dev, BTN_MIDDLE, hw.middle);
479 
480 	if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) {
481 		input_report_key(dev, BTN_FORWARD, hw.up);
482 		input_report_key(dev, BTN_BACK, hw.down);
483 	}
484 
485 	for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++)
486 		input_report_key(dev, BTN_0 + i, hw.ext_buttons & (1 << i));
487 
488 	input_sync(dev);
489 }
490 
491 static int synaptics_validate_byte(unsigned char packet[], int idx, unsigned char pkt_type)
492 {
493 	static const unsigned char newabs_mask[]	= { 0xC8, 0x00, 0x00, 0xC8, 0x00 };
494 	static const unsigned char newabs_rel_mask[]	= { 0xC0, 0x00, 0x00, 0xC0, 0x00 };
495 	static const unsigned char newabs_rslt[]	= { 0x80, 0x00, 0x00, 0xC0, 0x00 };
496 	static const unsigned char oldabs_mask[]	= { 0xC0, 0x60, 0x00, 0xC0, 0x60 };
497 	static const unsigned char oldabs_rslt[]	= { 0xC0, 0x00, 0x00, 0x80, 0x00 };
498 
499 	if (idx < 0 || idx > 4)
500 		return 0;
501 
502 	switch (pkt_type) {
503 		case SYN_NEWABS:
504 		case SYN_NEWABS_RELAXED:
505 			return (packet[idx] & newabs_rel_mask[idx]) == newabs_rslt[idx];
506 
507 		case SYN_NEWABS_STRICT:
508 			return (packet[idx] & newabs_mask[idx]) == newabs_rslt[idx];
509 
510 		case SYN_OLDABS:
511 			return (packet[idx] & oldabs_mask[idx]) == oldabs_rslt[idx];
512 
513 		default:
514 			printk(KERN_ERR "synaptics: unknown packet type %d\n", pkt_type);
515 			return 0;
516 	}
517 }
518 
519 static unsigned char synaptics_detect_pkt_type(struct psmouse *psmouse)
520 {
521 	int i;
522 
523 	for (i = 0; i < 5; i++)
524 		if (!synaptics_validate_byte(psmouse->packet, i, SYN_NEWABS_STRICT)) {
525 			printk(KERN_INFO "synaptics: using relaxed packet validation\n");
526 			return SYN_NEWABS_RELAXED;
527 		}
528 
529 	return SYN_NEWABS_STRICT;
530 }
531 
532 static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse)
533 {
534 	struct synaptics_data *priv = psmouse->private;
535 
536 	if (psmouse->pktcnt >= 6) { /* Full packet received */
537 		if (unlikely(priv->pkt_type == SYN_NEWABS))
538 			priv->pkt_type = synaptics_detect_pkt_type(psmouse);
539 
540 		if (SYN_CAP_PASS_THROUGH(priv->capabilities) && synaptics_is_pt_packet(psmouse->packet)) {
541 			if (psmouse->ps2dev.serio->child)
542 				synaptics_pass_pt_packet(psmouse->ps2dev.serio->child, psmouse->packet);
543 		} else
544 			synaptics_process_packet(psmouse);
545 
546 		return PSMOUSE_FULL_PACKET;
547 	}
548 
549 	return synaptics_validate_byte(psmouse->packet, psmouse->pktcnt - 1, priv->pkt_type) ?
550 		PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA;
551 }
552 
553 /*****************************************************************************
554  *	Driver initialization/cleanup functions
555  ****************************************************************************/
556 static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
557 {
558 	int i;
559 
560 	__set_bit(EV_ABS, dev->evbit);
561 	input_set_abs_params(dev, ABS_X, XMIN_NOMINAL, XMAX_NOMINAL, 0, 0);
562 	input_set_abs_params(dev, ABS_Y, YMIN_NOMINAL, YMAX_NOMINAL, 0, 0);
563 	input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
564 	__set_bit(ABS_TOOL_WIDTH, dev->absbit);
565 
566 	__set_bit(EV_KEY, dev->evbit);
567 	__set_bit(BTN_TOUCH, dev->keybit);
568 	__set_bit(BTN_TOOL_FINGER, dev->keybit);
569 	__set_bit(BTN_LEFT, dev->keybit);
570 	__set_bit(BTN_RIGHT, dev->keybit);
571 
572 	if (SYN_CAP_MULTIFINGER(priv->capabilities)) {
573 		__set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
574 		__set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
575 	}
576 
577 	if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
578 		__set_bit(BTN_MIDDLE, dev->keybit);
579 
580 	if (SYN_CAP_FOUR_BUTTON(priv->capabilities) ||
581 	    SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) {
582 		__set_bit(BTN_FORWARD, dev->keybit);
583 		__set_bit(BTN_BACK, dev->keybit);
584 	}
585 
586 	for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++)
587 		__set_bit(BTN_0 + i, dev->keybit);
588 
589 	__clear_bit(EV_REL, dev->evbit);
590 	__clear_bit(REL_X, dev->relbit);
591 	__clear_bit(REL_Y, dev->relbit);
592 
593 	dev->absres[ABS_X] = priv->x_res;
594 	dev->absres[ABS_Y] = priv->y_res;
595 }
596 
597 static void synaptics_disconnect(struct psmouse *psmouse)
598 {
599 	synaptics_reset(psmouse);
600 	kfree(psmouse->private);
601 	psmouse->private = NULL;
602 }
603 
604 static int synaptics_reconnect(struct psmouse *psmouse)
605 {
606 	struct synaptics_data *priv = psmouse->private;
607 	struct synaptics_data old_priv = *priv;
608 
609 	psmouse_reset(psmouse);
610 
611 	if (synaptics_detect(psmouse, 0))
612 		return -1;
613 
614 	if (synaptics_query_hardware(psmouse)) {
615 		printk(KERN_ERR "Unable to query Synaptics hardware.\n");
616 		return -1;
617 	}
618 
619 	if (old_priv.identity != priv->identity ||
620 	    old_priv.model_id != priv->model_id ||
621 	    old_priv.capabilities != priv->capabilities ||
622 	    old_priv.ext_cap != priv->ext_cap)
623 		return -1;
624 
625 	if (synaptics_set_absolute_mode(psmouse)) {
626 		printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
627 		return -1;
628 	}
629 
630 	return 0;
631 }
632 
633 static bool impaired_toshiba_kbc;
634 
635 static const struct dmi_system_id __initconst toshiba_dmi_table[] = {
636 #if defined(CONFIG_DMI) && defined(CONFIG_X86)
637 	{
638 		/* Toshiba Satellite */
639 		.matches = {
640 			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
641 			DMI_MATCH(DMI_PRODUCT_NAME, "Satellite"),
642 		},
643 	},
644 	{
645 		/* Toshiba Dynabook */
646 		.matches = {
647 			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
648 			DMI_MATCH(DMI_PRODUCT_NAME, "dynabook"),
649 		},
650 	},
651 	{
652 		/* Toshiba Portege M300 */
653 		.matches = {
654 			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
655 			DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
656 		},
657 
658 	},
659 	{
660 		/* Toshiba Portege M300 */
661 		.matches = {
662 			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
663 			DMI_MATCH(DMI_PRODUCT_NAME, "Portable PC"),
664 			DMI_MATCH(DMI_PRODUCT_VERSION, "Version 1.0"),
665 		},
666 
667 	},
668 	{ }
669 #endif
670 };
671 
672 void __init synaptics_module_init(void)
673 {
674 	impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table);
675 }
676 
677 int synaptics_init(struct psmouse *psmouse)
678 {
679 	struct synaptics_data *priv;
680 
681 	psmouse->private = priv = kzalloc(sizeof(struct synaptics_data), GFP_KERNEL);
682 	if (!priv)
683 		return -1;
684 
685 	psmouse_reset(psmouse);
686 
687 	if (synaptics_query_hardware(psmouse)) {
688 		printk(KERN_ERR "Unable to query Synaptics hardware.\n");
689 		goto init_fail;
690 	}
691 
692 	if (synaptics_set_absolute_mode(psmouse)) {
693 		printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
694 		goto init_fail;
695 	}
696 
697 	priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS;
698 
699 	printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx\n",
700 		SYN_ID_MODEL(priv->identity),
701 		SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity),
702 		priv->model_id, priv->capabilities, priv->ext_cap);
703 
704 	set_input_params(psmouse->dev, priv);
705 
706 	/*
707 	 * Encode touchpad model so that it can be used to set
708 	 * input device->id.version and be visible to userspace.
709 	 * Because version is __u16 we have to drop something.
710 	 * Hardware info bits seem to be good candidates as they
711 	 * are documented to be for Synaptics corp. internal use.
712 	 */
713 	psmouse->model = ((priv->model_id & 0x00ff0000) >> 8) |
714 			  (priv->model_id & 0x000000ff);
715 
716 	psmouse->protocol_handler = synaptics_process_byte;
717 	psmouse->set_rate = synaptics_set_rate;
718 	psmouse->disconnect = synaptics_disconnect;
719 	psmouse->reconnect = synaptics_reconnect;
720 	psmouse->cleanup = synaptics_reset;
721 	psmouse->pktsize = 6;
722 	/* Synaptics can usually stay in sync without extra help */
723 	psmouse->resync_time = 0;
724 
725 	if (SYN_CAP_PASS_THROUGH(priv->capabilities))
726 		synaptics_pt_create(psmouse);
727 
728 	/*
729 	 * Toshiba's KBC seems to have trouble handling data from
730 	 * Synaptics as full rate, switch to lower rate which is roughly
731 	 * thye same as rate of standard PS/2 mouse.
732 	 */
733 	if (psmouse->rate >= 80 && impaired_toshiba_kbc) {
734 		printk(KERN_INFO "synaptics: Toshiba %s detected, limiting rate to 40pps.\n",
735 			dmi_get_system_info(DMI_PRODUCT_NAME));
736 		psmouse->rate = 40;
737 	}
738 
739 	return 0;
740 
741  init_fail:
742 	kfree(priv);
743 	return -1;
744 }
745 
746 bool synaptics_supported(void)
747 {
748 	return true;
749 }
750 
751 #else /* CONFIG_MOUSE_PS2_SYNAPTICS */
752 
753 void __init synaptics_module_init(void)
754 {
755 }
756 
757 int synaptics_init(struct psmouse *psmouse)
758 {
759 	return -ENOSYS;
760 }
761 
762 bool synaptics_supported(void)
763 {
764 	return false;
765 }
766 
767 #endif /* CONFIG_MOUSE_PS2_SYNAPTICS */
768 
769