psmouse-base.c 51.5 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
 * PS/2 mouse driver
 *
 * Copyright (c) 1999-2002 Vojtech Pavlik
 * Copyright (c) 2003-2004 Dmitry Torokhov
 */

/*
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published by
 * the Free Software Foundation.
 */

14 15 16
#define pr_fmt(fmt)		KBUILD_MODNAME ": " fmt
#define psmouse_fmt(fmt)	fmt

17
#include <linux/bitops.h>
Linus Torvalds's avatar
Linus Torvalds committed
18 19 20 21 22 23 24 25
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/serio.h>
#include <linux/init.h>
#include <linux/libps2.h>
26
#include <linux/mutex.h>
27
#include <linux/types.h>
28

Linus Torvalds's avatar
Linus Torvalds committed
29 30 31 32
#include "psmouse.h"
#include "synaptics.h"
#include "logips2pp.h"
#include "alps.h"
33
#include "hgpk.h"
34
#include "lifebook.h"
35
#include "trackpoint.h"
36
#include "touchkit_ps2.h"
37
#include "elantech.h"
38
#include "sentelic.h"
39
#include "cypress_ps2.h"
40
#include "focaltech.h"
Thomas Hellstrom's avatar
Thomas Hellstrom committed
41
#include "vmmouse.h"
42
#include "byd.h"
Linus Torvalds's avatar
Linus Torvalds committed
43 44 45 46 47 48 49

#define DRIVER_DESC	"PS/2 mouse driver"

MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

50
static unsigned int psmouse_max_proto = PSMOUSE_AUTO;
51 52
static int psmouse_set_maxproto(const char *val, const struct kernel_param *);
static int psmouse_get_maxproto(char *buffer, const struct kernel_param *kp);
53
static const struct kernel_param_ops param_ops_proto_abbrev = {
54 55 56
	.set = psmouse_set_maxproto,
	.get = psmouse_get_maxproto,
};
Linus Torvalds's avatar
Linus Torvalds committed
57 58
#define param_check_proto_abbrev(name, p)	__param_check(name, p, unsigned int)
module_param_named(proto, psmouse_max_proto, proto_abbrev, 0644);
59
MODULE_PARM_DESC(proto, "Highest protocol extension to probe (bare, imps, exps, any). Useful for KVM switches.");
Linus Torvalds's avatar
Linus Torvalds committed
60 61 62 63 64 65 66 67 68

static unsigned int psmouse_resolution = 200;
module_param_named(resolution, psmouse_resolution, uint, 0644);
MODULE_PARM_DESC(resolution, "Resolution, in dpi.");

static unsigned int psmouse_rate = 100;
module_param_named(rate, psmouse_rate, uint, 0644);
MODULE_PARM_DESC(rate, "Report rate, in reports per second.");

69
static bool psmouse_smartscroll = true;
Linus Torvalds's avatar
Linus Torvalds committed
70 71 72
module_param_named(smartscroll, psmouse_smartscroll, bool, 0644);
MODULE_PARM_DESC(smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled.");

73 74 75 76
static bool psmouse_a4tech_2wheels;
module_param_named(a4tech_workaround, psmouse_a4tech_2wheels, bool, 0644);
MODULE_PARM_DESC(a4tech_workaround, "A4Tech second scroll wheel workaround, 1 = enabled, 0 = disabled (default).");

77
static unsigned int psmouse_resetafter = 5;
Linus Torvalds's avatar
Linus Torvalds committed
78 79 80
module_param_named(resetafter, psmouse_resetafter, uint, 0644);
MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never).");

81
static unsigned int psmouse_resync_time;
82 83 84
module_param_named(resync_time, psmouse_resync_time, uint, 0644);
MODULE_PARM_DESC(resync_time, "How long can mouse stay idle before forcing resync (in seconds, 0 = never).");

85 86 87 88 89 90 91 92 93 94 95 96
PSMOUSE_DEFINE_ATTR(protocol, S_IWUSR | S_IRUGO,
			NULL,
			psmouse_attr_show_protocol, psmouse_attr_set_protocol);
PSMOUSE_DEFINE_ATTR(rate, S_IWUSR | S_IRUGO,
			(void *) offsetof(struct psmouse, rate),
			psmouse_show_int_attr, psmouse_attr_set_rate);
PSMOUSE_DEFINE_ATTR(resolution, S_IWUSR | S_IRUGO,
			(void *) offsetof(struct psmouse, resolution),
			psmouse_show_int_attr, psmouse_attr_set_resolution);
PSMOUSE_DEFINE_ATTR(resetafter, S_IWUSR | S_IRUGO,
			(void *) offsetof(struct psmouse, resetafter),
			psmouse_show_int_attr, psmouse_set_int_attr);
97 98 99
PSMOUSE_DEFINE_ATTR(resync_time, S_IWUSR | S_IRUGO,
			(void *) offsetof(struct psmouse, resync_time),
			psmouse_show_int_attr, psmouse_set_int_attr);
100 101 102 103 104 105

static struct attribute *psmouse_attributes[] = {
	&psmouse_attr_protocol.dattr.attr,
	&psmouse_attr_rate.dattr.attr,
	&psmouse_attr_resolution.dattr.attr,
	&psmouse_attr_resetafter.dattr.attr,
106
	&psmouse_attr_resync_time.dattr.attr,
107 108 109
	NULL
};

110
static const struct attribute_group psmouse_attribute_group = {
111 112
	.attrs	= psmouse_attributes,
};
Linus Torvalds's avatar
Linus Torvalds committed
113

114
/*
115
 * psmouse_mutex protects all operations changing state of mouse
116 117 118 119 120
 * (connecting, disconnecting, changing rate or resolution via
 * sysfs). We could use a per-device semaphore but since there
 * rarely more than one PS/2 mouse connected and since semaphore
 * is taken in "slow" paths it is not worth it.
 */
121
static DEFINE_MUTEX(psmouse_mutex);
122

123 124
static struct workqueue_struct *kpsmoused_wq;

125
void psmouse_report_standard_buttons(struct input_dev *dev, u8 buttons)
126 127 128 129 130 131
{
	input_report_key(dev, BTN_LEFT,   buttons & BIT(0));
	input_report_key(dev, BTN_MIDDLE, buttons & BIT(2));
	input_report_key(dev, BTN_RIGHT,  buttons & BIT(1));
}

132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
void psmouse_report_standard_motion(struct input_dev *dev, u8 *packet)
{
	int x, y;

	x = packet[1] ? packet[1] - ((packet[0] << 4) & 0x100) : 0;
	y = packet[2] ? packet[2] - ((packet[0] << 3) & 0x100) : 0;

	input_report_rel(dev, REL_X, x);
	input_report_rel(dev, REL_Y, -y);
}

void psmouse_report_standard_packet(struct input_dev *dev, u8 *packet)
{
	psmouse_report_standard_buttons(dev, packet[0]);
	psmouse_report_standard_motion(dev, packet);
}

Linus Torvalds's avatar
Linus Torvalds committed
149 150 151 152
/*
 * psmouse_process_byte() analyzes the PS/2 data stream and reports
 * relevant events to the input module once full packet has arrived.
 */
153
psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
Linus Torvalds's avatar
Linus Torvalds committed
154
{
155
	struct input_dev *dev = psmouse->dev;
156
	u8 *packet = psmouse->packet;
157
	int wheel;
Linus Torvalds's avatar
Linus Torvalds committed
158 159 160 161

	if (psmouse->pktcnt < psmouse->pktsize)
		return PSMOUSE_GOOD_DATA;

162
	/* Full packet accumulated, process it */
Linus Torvalds's avatar
Linus Torvalds committed
163

164
	switch (psmouse->protocol->type) {
165 166
	case PSMOUSE_IMPS:
		/* IntelliMouse has scroll wheel */
167
		input_report_rel(dev, REL_WHEEL, -(s8) packet[3]);
168
		break;
Linus Torvalds's avatar
Linus Torvalds committed
169

170 171
	case PSMOUSE_IMEX:
		/* Scroll wheel and buttons on IntelliMouse Explorer */
172
		switch (packet[3] & 0xC0) {
173
		case 0x80: /* vertical scroll on IntelliMouse Explorer 4.0 */
174 175
			input_report_rel(dev, REL_WHEEL,
					 -sign_extend32(packet[3], 5));
176 177
			break;
		case 0x40: /* horizontal scroll on IntelliMouse Explorer 4.0 */
178 179
			input_report_rel(dev, REL_HWHEEL,
					 -sign_extend32(packet[3], 5));
180 181 182
			break;
		case 0x00:
		case 0xC0:
183 184 185 186 187 188 189 190 191 192 193 194
			wheel = sign_extend32(packet[3], 3);

			/*
			 * Some A4Tech mice have two scroll wheels, with first
			 * one reporting +/-1 in the lower nibble, and second
			 * one reporting +/-2.
			 */
			if (psmouse_a4tech_2wheels && abs(wheel) > 1)
				input_report_rel(dev, REL_HWHEEL, wheel / 2);
			else
				input_report_rel(dev, REL_WHEEL, -wheel);

195 196
			input_report_key(dev, BTN_SIDE,  packet[3] & BIT(4));
			input_report_key(dev, BTN_EXTRA, packet[3] & BIT(5));
197
			break;
198
		}
199
		break;
Linus Torvalds's avatar
Linus Torvalds committed
200

201 202
	case PSMOUSE_GENPS:
		/* Report scroll buttons on NetMice */
203
		input_report_rel(dev, REL_WHEEL, -(s8) packet[3]);
Linus Torvalds's avatar
Linus Torvalds committed
204

205
		/* Extra buttons on Genius NewNet 3D */
206 207
		input_report_key(dev, BTN_SIDE,  packet[0] & BIT(6));
		input_report_key(dev, BTN_EXTRA, packet[0] & BIT(7));
208
		break;
Linus Torvalds's avatar
Linus Torvalds committed
209

210 211
	case PSMOUSE_THINKPS:
		/* Extra button on ThinkingMouse */
212
		input_report_key(dev, BTN_EXTRA, packet[0] & BIT(3));
213 214 215 216 217

		/*
		 * Without this bit of weirdness moving up gives wildly
		 * high Y changes.
		 */
Linus Torvalds's avatar
Linus Torvalds committed
218
		packet[1] |= (packet[0] & 0x40) << 1;
219
		break;
Linus Torvalds's avatar
Linus Torvalds committed
220

221 222 223 224 225
	case PSMOUSE_CORTRON:
		/*
		 * Cortron PS2 Trackball reports SIDE button in the
		 * 4th bit of the first byte.
		 */
226
		input_report_key(dev, BTN_SIDE, packet[0] & BIT(3));
227
		packet[0] |= BIT(3);
228
		break;
229

230 231 232
	default:
		break;
	}
Linus Torvalds's avatar
Linus Torvalds committed
233

234
	/* Generic PS/2 Mouse */
235 236
	packet[0] |= psmouse->extra_buttons;
	psmouse_report_standard_packet(dev, packet);
Linus Torvalds's avatar
Linus Torvalds committed
237 238 239 240 241 242

	input_sync(dev);

	return PSMOUSE_FULL_PACKET;
}

243 244 245 246 247 248
void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work,
		unsigned long delay)
{
	queue_delayed_work(kpsmoused_wq, work, delay);
}

Linus Torvalds's avatar
Linus Torvalds committed
249
/*
250 251 252 253 254
 * __psmouse_set_state() sets new psmouse state and resets all flags.
 */
static inline void __psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state)
{
	psmouse->state = new_state;
255
	psmouse->pktcnt = psmouse->out_of_sync_cnt = 0;
256 257 258 259 260 261 262 263 264
	psmouse->ps2dev.flags = 0;
	psmouse->last = jiffies;
}

/*
 * psmouse_set_state() sets new psmouse state and resets all flags and
 * counters while holding serio lock so fighting with interrupt handler
 * is not a concern.
 */
265
void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state)
266 267 268 269 270 271 272 273 274 275
{
	serio_pause_rx(psmouse->ps2dev.serio);
	__psmouse_set_state(psmouse, new_state);
	serio_continue_rx(psmouse->ps2dev.serio);
}

/*
 * psmouse_handle_byte() processes one byte of the input data stream
 * by calling corresponding protocol handler.
 */
276
static int psmouse_handle_byte(struct psmouse *psmouse)
277
{
278
	psmouse_ret_t rc = psmouse->protocol_handler(psmouse);
279 280

	switch (rc) {
281 282
	case PSMOUSE_BAD_DATA:
		if (psmouse->state == PSMOUSE_ACTIVATED) {
283 284 285 286
			psmouse_warn(psmouse,
				     "%s at %s lost sync at byte %d\n",
				     psmouse->name, psmouse->phys,
				     psmouse->pktcnt);
287 288
			if (++psmouse->out_of_sync_cnt == psmouse->resetafter) {
				__psmouse_set_state(psmouse, PSMOUSE_IGNORE);
289 290
				psmouse_notice(psmouse,
						"issuing reconnect request\n");
291
				serio_reconnect(psmouse->ps2dev.serio);
292
				return -EIO;
293
			}
294 295 296 297 298 299 300 301
		}
		psmouse->pktcnt = 0;
		break;

	case PSMOUSE_FULL_PACKET:
		psmouse->pktcnt = 0;
		if (psmouse->out_of_sync_cnt) {
			psmouse->out_of_sync_cnt = 0;
302 303 304
			psmouse_notice(psmouse,
					"%s at %s - driver resynced.\n",
					psmouse->name, psmouse->phys);
305 306
		}
		break;
307

308 309
	case PSMOUSE_GOOD_DATA:
		break;
310 311 312 313
	}
	return 0;
}

314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337
static void psmouse_handle_oob_data(struct psmouse *psmouse, u8 data)
{
	switch (psmouse->oob_data_type) {
	case PSMOUSE_OOB_NONE:
		psmouse->oob_data_type = data;
		break;

	case PSMOUSE_OOB_EXTRA_BTNS:
		psmouse_report_standard_buttons(psmouse->dev, data);
		input_sync(psmouse->dev);

		psmouse->extra_buttons = data;
		psmouse->oob_data_type = PSMOUSE_OOB_NONE;
		break;

	default:
		psmouse_warn(psmouse,
			     "unknown OOB_DATA type: 0x%02x\n",
			     psmouse->oob_data_type);
		psmouse->oob_data_type = PSMOUSE_OOB_NONE;
		break;
	}
}

338 339 340
/*
 * psmouse_interrupt() handles incoming characters, either passing them
 * for normal processing or gathering them as command response.
Linus Torvalds's avatar
Linus Torvalds committed
341 342
 */
static irqreturn_t psmouse_interrupt(struct serio *serio,
343
				     u8 data, unsigned int flags)
Linus Torvalds's avatar
Linus Torvalds committed
344 345 346 347 348 349
{
	struct psmouse *psmouse = serio_get_drvdata(serio);

	if (psmouse->state == PSMOUSE_IGNORE)
		goto out;

350
	if (unlikely((flags & SERIO_TIMEOUT) ||
351 352
		     ((flags & SERIO_PARITY) &&
		      !psmouse->protocol->ignore_parity))) {
353

Linus Torvalds's avatar
Linus Torvalds committed
354
		if (psmouse->state == PSMOUSE_ACTIVATED)
355 356 357 358
			psmouse_warn(psmouse,
				     "bad data from KBC -%s%s\n",
				     flags & SERIO_TIMEOUT ? " timeout" : "",
				     flags & SERIO_PARITY ? " bad parity" : "");
Linus Torvalds's avatar
Linus Torvalds committed
359 360 361 362
		ps2_cmd_aborted(&psmouse->ps2dev);
		goto out;
	}

363 364 365 366 367
	if (flags & SERIO_OOB_DATA) {
		psmouse_handle_oob_data(psmouse, data);
		goto out;
	}

Linus Torvalds's avatar
Linus Torvalds committed
368 369 370 371 372 373 374 375
	if (unlikely(psmouse->ps2dev.flags & PS2_FLAG_ACK))
		if  (ps2_handle_ack(&psmouse->ps2dev, data))
			goto out;

	if (unlikely(psmouse->ps2dev.flags & PS2_FLAG_CMD))
		if  (ps2_handle_response(&psmouse->ps2dev, data))
			goto out;

376
	if (psmouse->state <= PSMOUSE_RESYNCING)
Linus Torvalds's avatar
Linus Torvalds committed
377 378 379 380
		goto out;

	if (psmouse->state == PSMOUSE_ACTIVATED &&
	    psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) {
381 382
		psmouse_info(psmouse, "%s at %s lost synchronization, throwing %d bytes away.\n",
			     psmouse->name, psmouse->phys, psmouse->pktcnt);
383 384
		psmouse->badbyte = psmouse->packet[0];
		__psmouse_set_state(psmouse, PSMOUSE_RESYNCING);
385
		psmouse_queue_work(psmouse, &psmouse->resync_work, 0);
386
		goto out;
Linus Torvalds's avatar
Linus Torvalds committed
387 388 389
	}

	psmouse->packet[psmouse->pktcnt++] = data;
390 391

	/* Check if this is a new device announcement (0xAA 0x00) */
392
	if (unlikely(psmouse->packet[0] == PSMOUSE_RET_BAT && psmouse->pktcnt <= 2)) {
393 394
		if (psmouse->pktcnt == 1) {
			psmouse->last = jiffies;
Linus Torvalds's avatar
Linus Torvalds committed
395
			goto out;
396
		}
Linus Torvalds's avatar
Linus Torvalds committed
397

398
		if (psmouse->packet[1] == PSMOUSE_RET_ID ||
399
		    (psmouse->protocol->type == PSMOUSE_HGPK &&
400
		     psmouse->packet[1] == PSMOUSE_RET_BAT)) {
401 402 403
			__psmouse_set_state(psmouse, PSMOUSE_IGNORE);
			serio_reconnect(serio);
			goto out;
Linus Torvalds's avatar
Linus Torvalds committed
404
		}
405 406

		/* Not a new device, try processing first byte normally */
407
		psmouse->pktcnt = 1;
408
		if (psmouse_handle_byte(psmouse))
409
			goto out;
Linus Torvalds's avatar
Linus Torvalds committed
410

411 412
		psmouse->packet[psmouse->pktcnt++] = data;
	}
Linus Torvalds's avatar
Linus Torvalds committed
413

414 415 416 417
	/*
	 * See if we need to force resync because mouse was idle for
	 * too long.
	 */
418 419 420 421 422
	if (psmouse->state == PSMOUSE_ACTIVATED &&
	    psmouse->pktcnt == 1 && psmouse->resync_time &&
	    time_after(jiffies, psmouse->last + psmouse->resync_time * HZ)) {
		psmouse->badbyte = psmouse->packet[0];
		__psmouse_set_state(psmouse, PSMOUSE_RESYNCING);
423
		psmouse_queue_work(psmouse, &psmouse->resync_work, 0);
424 425
		goto out;
	}
Linus Torvalds's avatar
Linus Torvalds committed
426

427
	psmouse->last = jiffies;
428
	psmouse_handle_byte(psmouse);
Linus Torvalds's avatar
Linus Torvalds committed
429

430
 out:
Linus Torvalds's avatar
Linus Torvalds committed
431 432 433 434 435 436 437 438
	return IRQ_HANDLED;
}

/*
 * psmouse_reset() resets the mouse into power-on state.
 */
int psmouse_reset(struct psmouse *psmouse)
{
439 440
	u8 param[2];
	int error;
Linus Torvalds's avatar
Linus Torvalds committed
441

442 443 444
	error = ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_RESET_BAT);
	if (error)
		return error;
Linus Torvalds's avatar
Linus Torvalds committed
445 446

	if (param[0] != PSMOUSE_RET_BAT && param[1] != PSMOUSE_RET_ID)
447
		return -EIO;
Linus Torvalds's avatar
Linus Torvalds committed
448 449 450 451

	return 0;
}

452 453 454 455 456
/*
 * Here we set the mouse resolution.
 */
void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution)
{
457 458
	static const u8 params[] = { 0, 1, 2, 2, 3 };
	u8 p;
459 460 461 462 463 464 465 466 467 468 469 470 471 472

	if (resolution == 0 || resolution > 200)
		resolution = 200;

	p = params[resolution / 50];
	ps2_command(&psmouse->ps2dev, &p, PSMOUSE_CMD_SETRES);
	psmouse->resolution = 25 << p;
}

/*
 * Here we set the mouse report rate.
 */
static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate)
{
473 474
	static const u8 rates[] = { 200, 100, 80, 60, 40, 20, 10, 0 };
	u8 r;
475 476
	int i = 0;

477 478
	while (rates[i] > rate)
		i++;
479 480 481 482 483
	r = rates[i];
	ps2_command(&psmouse->ps2dev, &r, PSMOUSE_CMD_SETRATE);
	psmouse->rate = r;
}

484 485 486 487 488 489 490 491 492 493
/*
 * Here we set the mouse scaling.
 */
static void psmouse_set_scale(struct psmouse *psmouse, enum psmouse_scale scale)
{
	ps2_command(&psmouse->ps2dev, NULL,
		    scale == PSMOUSE_SCALE21 ? PSMOUSE_CMD_SETSCALE21 :
					       PSMOUSE_CMD_SETSCALE11);
}

494 495 496 497 498 499 500 501 502
/*
 * psmouse_poll() - default poll handler. Everyone except for ALPS uses it.
 */
static int psmouse_poll(struct psmouse *psmouse)
{
	return ps2_command(&psmouse->ps2dev, psmouse->packet,
			   PSMOUSE_CMD_POLL | (psmouse->pktsize << 8));
}

503 504 505 506 507 508 509 510 511 512 513
static bool psmouse_check_pnp_id(const char *id, const char * const ids[])
{
	int i;

	for (i = 0; ids[i]; i++)
		if (!strcasecmp(id, ids[i]))
			return true;

	return false;
}

514 515 516 517 518
/*
 * psmouse_matches_pnp_id - check if psmouse matches one of the passed in ids.
 */
bool psmouse_matches_pnp_id(struct psmouse *psmouse, const char * const ids[])
{
519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538
	struct serio *serio = psmouse->ps2dev.serio;
	char *p, *fw_id_copy, *save_ptr;
	bool found = false;

	if (strncmp(serio->firmware_id, "PNP: ", 5))
		return false;

	fw_id_copy = kstrndup(&serio->firmware_id[5],
			      sizeof(serio->firmware_id) - 5,
			      GFP_KERNEL);
	if (!fw_id_copy)
		return false;

	save_ptr = fw_id_copy;
	while ((p = strsep(&fw_id_copy, " ")) != NULL) {
		if (psmouse_check_pnp_id(p, ids)) {
			found = true;
			break;
		}
	}
539

540 541
	kfree(save_ptr);
	return found;
542
}
Linus Torvalds's avatar
Linus Torvalds committed
543 544 545 546

/*
 * Genius NetMouse magic init.
 */
547
static int genius_detect(struct psmouse *psmouse, bool set_properties)
Linus Torvalds's avatar
Linus Torvalds committed
548 549
{
	struct ps2dev *ps2dev = &psmouse->ps2dev;
550
	u8 param[4];
Linus Torvalds's avatar
Linus Torvalds committed
551 552 553 554 555 556 557 558 559

	param[0] = 3;
	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
	ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11);
	ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11);
	ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11);
	ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO);

	if (param[0] != 0x00 || param[1] != 0x33 || param[2] != 0x55)
560
		return -ENODEV;
Linus Torvalds's avatar
Linus Torvalds committed
561 562

	if (set_properties) {
563
		__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
564 565 566
		__set_bit(BTN_EXTRA, psmouse->dev->keybit);
		__set_bit(BTN_SIDE, psmouse->dev->keybit);
		__set_bit(REL_WHEEL, psmouse->dev->relbit);
Linus Torvalds's avatar
Linus Torvalds committed
567 568

		psmouse->vendor = "Genius";
569
		psmouse->name = "Mouse";
Linus Torvalds's avatar
Linus Torvalds committed
570 571 572 573 574 575 576 577 578
		psmouse->pktsize = 4;
	}

	return 0;
}

/*
 * IntelliMouse magic init.
 */
579
static int intellimouse_detect(struct psmouse *psmouse, bool set_properties)
Linus Torvalds's avatar
Linus Torvalds committed
580 581
{
	struct ps2dev *ps2dev = &psmouse->ps2dev;
582
	u8 param[2];
Linus Torvalds's avatar
Linus Torvalds committed
583 584 585 586 587 588 589 590 591 592

	param[0] = 200;
	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
	param[0] = 100;
	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
	param[0] =  80;
	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
	ps2_command(ps2dev, param, PSMOUSE_CMD_GETID);

	if (param[0] != 3)
593
		return -ENODEV;
Linus Torvalds's avatar
Linus Torvalds committed
594 595

	if (set_properties) {
596 597
		__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
		__set_bit(REL_WHEEL, psmouse->dev->relbit);
Linus Torvalds's avatar
Linus Torvalds committed
598

599 600 601 602
		if (!psmouse->vendor)
			psmouse->vendor = "Generic";
		if (!psmouse->name)
			psmouse->name = "Wheel Mouse";
Linus Torvalds's avatar
Linus Torvalds committed
603 604 605 606 607 608 609 610 611
		psmouse->pktsize = 4;
	}

	return 0;
}

/*
 * Try IntelliMouse/Explorer magic init.
 */
612
static int im_explorer_detect(struct psmouse *psmouse, bool set_properties)
Linus Torvalds's avatar
Linus Torvalds committed
613 614
{
	struct ps2dev *ps2dev = &psmouse->ps2dev;
615
	u8 param[2];
Linus Torvalds's avatar
Linus Torvalds committed
616 617 618 619 620 621 622 623 624 625 626 627

	intellimouse_detect(psmouse, 0);

	param[0] = 200;
	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
	param[0] = 200;
	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
	param[0] =  80;
	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
	ps2_command(ps2dev, param, PSMOUSE_CMD_GETID);

	if (param[0] != 4)
628
		return -ENODEV;
Linus Torvalds's avatar
Linus Torvalds committed
629

630
	/* Magic to enable horizontal scrolling on IntelliMouse 4.0 */
631 632 633 634 635 636 637
	param[0] = 200;
	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
	param[0] =  80;
	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
	param[0] =  40;
	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);

Linus Torvalds's avatar
Linus Torvalds committed
638
	if (set_properties) {
639 640 641 642 643
		__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
		__set_bit(REL_WHEEL, psmouse->dev->relbit);
		__set_bit(REL_HWHEEL, psmouse->dev->relbit);
		__set_bit(BTN_SIDE, psmouse->dev->keybit);
		__set_bit(BTN_EXTRA, psmouse->dev->keybit);
Linus Torvalds's avatar
Linus Torvalds committed
644

645 646 647 648
		if (!psmouse->vendor)
			psmouse->vendor = "Generic";
		if (!psmouse->name)
			psmouse->name = "Explorer Mouse";
Linus Torvalds's avatar
Linus Torvalds committed
649 650 651 652 653 654 655 656 657
		psmouse->pktsize = 4;
	}

	return 0;
}

/*
 * Kensington ThinkingMouse / ExpertMouse magic init.
 */
658
static int thinking_detect(struct psmouse *psmouse, bool set_properties)
Linus Torvalds's avatar
Linus Torvalds committed
659 660
{
	struct ps2dev *ps2dev = &psmouse->ps2dev;
661 662
	u8 param[2];
	static const u8 seq[] = { 20, 60, 40, 20, 20, 60, 40, 20, 20 };
Linus Torvalds's avatar
Linus Torvalds committed
663 664 665 666 667 668
	int i;

	param[0] = 10;
	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
	param[0] = 0;
	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
Helge Deller's avatar
Helge Deller committed
669 670 671 672
	for (i = 0; i < ARRAY_SIZE(seq); i++) {
		param[0] = seq[i];
		ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
	}
Linus Torvalds's avatar
Linus Torvalds committed
673 674 675
	ps2_command(ps2dev, param, PSMOUSE_CMD_GETID);

	if (param[0] != 2)
676
		return -ENODEV;
Linus Torvalds's avatar
Linus Torvalds committed
677 678

	if (set_properties) {
679
		__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
680
		__set_bit(BTN_EXTRA, psmouse->dev->keybit);
Linus Torvalds's avatar
Linus Torvalds committed
681 682 683 684 685 686 687 688 689 690 691

		psmouse->vendor = "Kensington";
		psmouse->name = "ThinkingMouse";
	}

	return 0;
}

/*
 * Bare PS/2 protocol "detection". Always succeeds.
 */
692
static int ps2bare_detect(struct psmouse *psmouse, bool set_properties)
Linus Torvalds's avatar
Linus Torvalds committed
693
{
694
	if (set_properties) {
695 696 697 698 699
		if (!psmouse->vendor)
			psmouse->vendor = "Generic";
		if (!psmouse->name)
			psmouse->name = "Mouse";

700 701 702 703
		/*
		 * We have no way of figuring true number of buttons so let's
		 * assume that the device has 3.
		 */
704
		input_set_capability(psmouse->dev, EV_KEY, BTN_MIDDLE);
705
	}
Linus Torvalds's avatar
Linus Torvalds committed
706 707 708 709

	return 0;
}

710 711 712 713
/*
 * Cortron PS/2 protocol detection. There's no special way to detect it, so it
 * must be forced by sysfs protocol writing.
 */
714
static int cortron_detect(struct psmouse *psmouse, bool set_properties)
715 716 717 718
{
	if (set_properties) {
		psmouse->vendor = "Cortron";
		psmouse->name = "PS/2 Trackball";
719 720

		__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
721
		__set_bit(BTN_SIDE, psmouse->dev->keybit);
722 723 724 725
	}

	return 0;
}
726

727 728 729 730 731 732 733 734
static const struct psmouse_protocol psmouse_protocols[] = {
	{
		.type		= PSMOUSE_PS2,
		.name		= "PS/2",
		.alias		= "bare",
		.maxproto	= true,
		.ignore_parity	= true,
		.detect		= ps2bare_detect,
735
		.try_passthru	= true,
736 737 738 739 740 741
	},
#ifdef CONFIG_MOUSE_PS2_LOGIPS2PP
	{
		.type		= PSMOUSE_PS2PP,
		.name		= "PS2++",
		.alias		= "logitech",
742
		.detect		= ps2pp_detect,
743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772
	},
#endif
	{
		.type		= PSMOUSE_THINKPS,
		.name		= "ThinkPS/2",
		.alias		= "thinkps",
		.detect		= thinking_detect,
	},
#ifdef CONFIG_MOUSE_PS2_CYPRESS
	{
		.type		= PSMOUSE_CYPRESS,
		.name		= "CyPS/2",
		.alias		= "cypress",
		.detect		= cypress_detect,
		.init		= cypress_init,
	},
#endif
	{
		.type		= PSMOUSE_GENPS,
		.name		= "GenPS/2",
		.alias		= "genius",
		.detect		= genius_detect,
	},
	{
		.type		= PSMOUSE_IMPS,
		.name		= "ImPS/2",
		.alias		= "imps",
		.maxproto	= true,
		.ignore_parity	= true,
		.detect		= intellimouse_detect,
773
		.try_passthru	= true,
774 775 776 777 778 779 780 781
	},
	{
		.type		= PSMOUSE_IMEX,
		.name		= "ImExPS/2",
		.alias		= "exps",
		.maxproto	= true,
		.ignore_parity	= true,
		.detect		= im_explorer_detect,
782
		.try_passthru	= true,
783 784 785 786 787 788 789
	},
#ifdef CONFIG_MOUSE_PS2_SYNAPTICS
	{
		.type		= PSMOUSE_SYNAPTICS,
		.name		= "SynPS/2",
		.alias		= "synaptics",
		.detect		= synaptics_detect,
790
		.init		= synaptics_init_absolute,
791 792 793 794 795 796 797 798 799
	},
	{
		.type		= PSMOUSE_SYNAPTICS_RELATIVE,
		.name		= "SynRelPS/2",
		.alias		= "synaptics-relative",
		.detect		= synaptics_detect,
		.init		= synaptics_init_relative,
	},
#endif
800 801 802 803 804 805 806 807 808 809
#ifdef CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS
	{
		.type		= PSMOUSE_SYNAPTICS_SMBUS,
		.name		= "SynSMBus",
		.alias		= "synaptics-smbus",
		.detect		= synaptics_detect,
		.init		= synaptics_init_smbus,
		.smbus_companion = true,
	},
#endif
810 811 812 813 814 815 816 817 818 819 820 821 822 823
#ifdef CONFIG_MOUSE_PS2_ALPS
	{
		.type		= PSMOUSE_ALPS,
		.name		= "AlpsPS/2",
		.alias		= "alps",
		.detect		= alps_detect,
		.init		= alps_init,
	},
#endif
#ifdef CONFIG_MOUSE_PS2_LIFEBOOK
	{
		.type		= PSMOUSE_LIFEBOOK,
		.name		= "LBPS/2",
		.alias		= "lifebook",
824
		.detect		= lifebook_detect,
825 826 827 828 829 830 831 832 833
		.init		= lifebook_init,
	},
#endif
#ifdef CONFIG_MOUSE_PS2_TRACKPOINT
	{
		.type		= PSMOUSE_TRACKPOINT,
		.name		= "TPPS/2",
		.alias		= "trackpoint",
		.detect		= trackpoint_detect,
834
		.try_passthru	= true,
835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858
	},
#endif
#ifdef CONFIG_MOUSE_PS2_TOUCHKIT
	{
		.type		= PSMOUSE_TOUCHKIT_PS2,
		.name		= "touchkitPS/2",
		.alias		= "touchkit",
		.detect		= touchkit_ps2_detect,
	},
#endif
#ifdef CONFIG_MOUSE_PS2_OLPC
	{
		.type		= PSMOUSE_HGPK,
		.name		= "OLPC HGPK",
		.alias		= "hgpk",
		.detect		= hgpk_detect,
	},
#endif
#ifdef CONFIG_MOUSE_PS2_ELANTECH
	{
		.type		= PSMOUSE_ELANTECH,
		.name		= "ETPS/2",
		.alias		= "elantech",
		.detect		= elantech_detect,
859 860 861 862 863 864 865 866 867 868 869
		.init		= elantech_init_ps2,
	},
#endif
#ifdef CONFIG_MOUSE_PS2_ELANTECH_SMBUS
	{
		.type		= PSMOUSE_ELANTECH_SMBUS,
		.name		= "ETSMBus",
		.alias		= "elantech-smbus",
		.detect		= elantech_detect,
		.init		= elantech_init_smbus,
		.smbus_companion = true,
870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903
	},
#endif
#ifdef CONFIG_MOUSE_PS2_SENTELIC
	{
		.type		= PSMOUSE_FSP,
		.name		= "FSPPS/2",
		.alias		= "fsp",
		.detect		= fsp_detect,
		.init		= fsp_init,
	},
#endif
	{
		.type		= PSMOUSE_CORTRON,
		.name		= "CortronPS/2",
		.alias		= "cortps",
		.detect		= cortron_detect,
	},
#ifdef CONFIG_MOUSE_PS2_FOCALTECH
	{
		.type		= PSMOUSE_FOCALTECH,
		.name		= "FocalTechPS/2",
		.alias		= "focaltech",
		.detect		= focaltech_detect,
		.init		= focaltech_init,
	},
#endif
#ifdef CONFIG_MOUSE_PS2_VMMOUSE
	{
		.type		= PSMOUSE_VMMOUSE,
		.name		= VMMOUSE_PSNAME,
		.alias		= "vmmouse",
		.detect		= vmmouse_detect,
		.init		= vmmouse_init,
	},
904 905 906 907
#endif
#ifdef CONFIG_MOUSE_PS2_BYD
	{
		.type		= PSMOUSE_BYD,
908
		.name		= "BYDPS/2",
909 910 911 912
		.alias		= "byd",
		.detect		= byd_detect,
		.init		= byd_init,
	},
913 914 915 916 917 918 919 920 921
#endif
	{
		.type		= PSMOUSE_AUTO,
		.name		= "auto",
		.alias		= "any",
		.maxproto	= true,
	},
};

922
static const struct psmouse_protocol *__psmouse_protocol_by_type(enum psmouse_type type)
923 924 925 926 927 928 929
{
	int i;

	for (i = 0; i < ARRAY_SIZE(psmouse_protocols); i++)
		if (psmouse_protocols[i].type == type)
			return &psmouse_protocols[i];

930 931 932 933 934 935 936 937 938 939 940
	return NULL;
}

static const struct psmouse_protocol *psmouse_protocol_by_type(enum psmouse_type type)
{
	const struct psmouse_protocol *proto;

	proto = __psmouse_protocol_by_type(type);
	if (proto)
		return proto;

941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960
	WARN_ON(1);
	return &psmouse_protocols[0];
}

static const struct psmouse_protocol *psmouse_protocol_by_name(const char *name, size_t len)
{
	const struct psmouse_protocol *p;
	int i;

	for (i = 0; i < ARRAY_SIZE(psmouse_protocols); i++) {
		p = &psmouse_protocols[i];

		if ((strlen(p->name) == len && !strncmp(p->name, name, len)) ||
		    (strlen(p->alias) == len && !strncmp(p->alias, name, len)))
			return &psmouse_protocols[i];
	}

	return NULL;
}

961 962 963 964 965 966 967 968
/*
 * Apply default settings to the psmouse structure. Most of them will
 * be overridden by individual protocol initialization routines.
 */
static void psmouse_apply_defaults(struct psmouse *psmouse)
{
	struct input_dev *input_dev = psmouse->dev;

969 970 971 972 973
	bitmap_zero(input_dev->evbit, EV_CNT);
	bitmap_zero(input_dev->keybit, KEY_CNT);
	bitmap_zero(input_dev->relbit, REL_CNT);
	bitmap_zero(input_dev->absbit, ABS_CNT);
	bitmap_zero(input_dev->mscbit, MSC_CNT);
974

975 976
	input_set_capability(input_dev, EV_KEY, BTN_LEFT);
	input_set_capability(input_dev, EV_KEY, BTN_RIGHT);
977

978 979
	input_set_capability(input_dev, EV_REL, REL_X);
	input_set_capability(input_dev, EV_REL, REL_Y);
980

981 982
	__set_bit(INPUT_PROP_POINTER, input_dev->propbit);

983 984
	psmouse->protocol = &psmouse_protocols[0];

985 986
	psmouse->set_rate = psmouse_set_rate;
	psmouse->set_resolution = psmouse_set_resolution;
987
	psmouse->set_scale = psmouse_set_scale;
988 989 990 991
	psmouse->poll = psmouse_poll;
	psmouse->protocol_handler = psmouse_process_byte;
	psmouse->pktsize = 3;
	psmouse->reconnect = NULL;
992
	psmouse->fast_reconnect = NULL;
993 994 995 996 997 998
	psmouse->disconnect = NULL;
	psmouse->cleanup = NULL;
	psmouse->pt_activate = NULL;
	psmouse->pt_deactivate = NULL;
}

999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013
static bool psmouse_do_detect(int (*detect)(struct psmouse *, bool),
			      struct psmouse *psmouse, bool allow_passthrough,
			      bool set_properties)
{
	if (psmouse->ps2dev.serio->id.type == SERIO_PS_PSTHRU &&
	    !allow_passthrough) {
		return false;
	}

	if (set_properties)
		psmouse_apply_defaults(psmouse);

	return detect(psmouse, set_properties) == 0;
}

1014 1015 1016 1017
static bool psmouse_try_protocol(struct psmouse *psmouse,
				 enum psmouse_type type,
				 unsigned int *max_proto,
				 bool set_properties, bool init_allowed)
1018
{
1019 1020 1021 1022 1023 1024
	const struct psmouse_protocol *proto;

	proto = __psmouse_protocol_by_type(type);
	if (!proto)
		return false;

1025 1026
	if (!psmouse_do_detect(proto->detect, psmouse, proto->try_passthru,
			       set_properties))
1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042
		return false;

	if (set_properties && proto->init && init_allowed) {
		if (proto->init(psmouse) != 0) {
			/*
			 * We detected device, but init failed. Adjust
			 * max_proto so we only try standard protocols.
			 */
			if (*max_proto > PSMOUSE_IMEX)
				*max_proto = PSMOUSE_IMEX;

			return false;
		}
	}

	return true;
1043 1044
}

Linus Torvalds's avatar
Linus Torvalds committed
1045 1046 1047 1048 1049
/*
 * psmouse_extensions() probes for any extensions to the basic PS/2 protocol
 * the mouse may have.
 */
static int psmouse_extensions(struct psmouse *psmouse,
1050
			      unsigned int max_proto, bool set_properties)
Linus Torvalds's avatar
Linus Torvalds committed
1051
{
1052
	bool synaptics_hardware = false;
1053
	int ret;
Linus Torvalds's avatar
Linus Torvalds committed
1054

1055 1056 1057 1058
	/*
	 * Always check for focaltech, this is safe as it uses pnp-id
	 * matching.
	 */
1059 1060
	if (psmouse_do_detect(focaltech_detect,
			      psmouse, false, set_properties)) {
1061 1062 1063 1064
		if (max_proto > PSMOUSE_IMEX &&
		    IS_ENABLED(CONFIG_MOUSE_PS2_FOCALTECH) &&
		    (!set_properties || focaltech_init(psmouse) == 0)) {
			return PSMOUSE_FOCALTECH;
1065
		}
1066 1067 1068 1069 1070 1071 1072 1073 1074
		/*
		 * Restrict psmouse_max_proto so that psmouse_initialize()
		 * does not try to reset rate and resolution, because even
		 * that upsets the device.
		 * This also causes us to basically fall through to basic
		 * protocol detection, where we fully reset the mouse,
		 * and set it up as bare PS/2 protocol device.
		 */
		psmouse_max_proto = max_proto = PSMOUSE_PS2;
1075 1076
	}

1077 1078 1079 1080
	/*
	 * We always check for LifeBook because it does not disturb mouse
	 * (it only checks DMI information).
	 */
1081 1082 1083
	if (psmouse_try_protocol(psmouse, PSMOUSE_LIFEBOOK, &max_proto,
				 set_properties, max_proto > PSMOUSE_IMEX))
		return PSMOUSE_LIFEBOOK;
1084

1085 1086 1087
	if (psmouse_try_protocol(psmouse, PSMOUSE_VMMOUSE, &max_proto,
				 set_properties, max_proto > PSMOUSE_IMEX))
		return PSMOUSE_VMMOUSE;
Thomas Hellstrom's avatar
Thomas Hellstrom committed
1088

1089 1090 1091 1092
	/*
	 * Try Kensington ThinkingMouse (we try first, because Synaptics
	 * probe upsets the ThinkingMouse).
	 */
1093
	if (max_proto > PSMOUSE_IMEX &&
1094 1095
	    psmouse_try_protocol(psmouse, PSMOUSE_THINKPS, &max_proto,
				 set_properties, true)) {
Linus Torvalds's avatar
Linus Torvalds committed
1096
		return PSMOUSE_THINKPS;
1097
	}
Linus Torvalds's avatar
Linus Torvalds committed
1098

1099 1100 1101 1102 1103 1104
	/*
	 * Try Synaptics TouchPad. Note that probing is done even if
	 * Synaptics protocol support is disabled in config - we need to
	 * know if it is Synaptics so we can reset it properly after
	 * probing for IntelliMouse.
	 */
1105
	if (max_proto > PSMOUSE_PS2 &&
1106 1107
	    psmouse_do_detect(synaptics_detect,
			      psmouse, false, set_properties)) {
1108
		synaptics_hardware = true;
Linus Torvalds's avatar
Linus Torvalds committed
1109 1110

		if (max_proto > PSMOUSE_IMEX) {