Linux Audio

Check our new training course

Embedded Linux training

Mar 31-Apr 8, 2025
Register
Loading...
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*-
   3 * Finger Sensing Pad PS/2 mouse driver.
   4 *
   5 * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd.
   6 * Copyright (C) 2005-2012 Tai-hwa Liang, Sentelic Corporation.
   7 */
   8
   9#include <linux/module.h>
  10#include <linux/input.h>
  11#include <linux/input/mt.h>
  12#include <linux/ctype.h>
  13#include <linux/libps2.h>
  14#include <linux/serio.h>
  15#include <linux/jiffies.h>
  16#include <linux/slab.h>
  17
  18#include "psmouse.h"
  19#include "sentelic.h"
  20
  21/*
  22 * Timeout for FSP PS/2 command only (in milliseconds).
  23 */
  24#define	FSP_CMD_TIMEOUT		200
  25#define	FSP_CMD_TIMEOUT2	30
  26
  27#define	GET_ABS_X(packet)	((packet[1] << 2) | ((packet[3] >> 2) & 0x03))
  28#define	GET_ABS_Y(packet)	((packet[2] << 2) | (packet[3] & 0x03))
  29
  30/** Driver version. */
  31static const char fsp_drv_ver[] = "1.1.0-K";
  32
  33/*
  34 * Make sure that the value being sent to FSP will not conflict with
  35 * possible sample rate values.
  36 */
  37static unsigned char fsp_test_swap_cmd(unsigned char reg_val)
  38{
  39	switch (reg_val) {
  40	case 10: case 20: case 40: case 60: case 80: case 100: case 200:
  41		/*
  42		 * The requested value being sent to FSP matched to possible
  43		 * sample rates, swap the given value such that the hardware
  44		 * wouldn't get confused.
  45		 */
  46		return (reg_val >> 4) | (reg_val << 4);
  47	default:
  48		return reg_val;	/* swap isn't necessary */
  49	}
  50}
  51
  52/*
  53 * Make sure that the value being sent to FSP will not conflict with certain
  54 * commands.
  55 */
  56static unsigned char fsp_test_invert_cmd(unsigned char reg_val)
  57{
  58	switch (reg_val) {
  59	case 0xe9: case 0xee: case 0xf2: case 0xff:
  60		/*
  61		 * The requested value being sent to FSP matched to certain
  62		 * commands, inverse the given value such that the hardware
  63		 * wouldn't get confused.
  64		 */
  65		return ~reg_val;
  66	default:
  67		return reg_val;	/* inversion isn't necessary */
  68	}
  69}
  70
  71static int fsp_reg_read(struct psmouse *psmouse, int reg_addr, int *reg_val)
  72{
  73	struct ps2dev *ps2dev = &psmouse->ps2dev;
  74	unsigned char param[3];
  75	unsigned char addr;
  76	int rc = -1;
  77
  78	/*
  79	 * We need to shut off the device and switch it into command
  80	 * mode so we don't confuse our protocol handler. We don't need
  81	 * to do that for writes because sysfs set helper does this for
  82	 * us.
  83	 */
  84	psmouse_deactivate(psmouse);
  85
  86	ps2_begin_command(ps2dev);
  87
  88	if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
  89		goto out;
  90
  91	/* should return 0xfe(request for resending) */
  92	ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2);
  93	/* should return 0xfc(failed) */
  94	ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
  95
  96	if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
  97		goto out;
  98
  99	if ((addr = fsp_test_invert_cmd(reg_addr)) != reg_addr) {
 100		ps2_sendbyte(ps2dev, 0x68, FSP_CMD_TIMEOUT2);
 101	} else if ((addr = fsp_test_swap_cmd(reg_addr)) != reg_addr) {
 102		/* swapping is required */
 103		ps2_sendbyte(ps2dev, 0xcc, FSP_CMD_TIMEOUT2);
 104		/* expect 0xfe */
 105	} else {
 106		/* swapping isn't necessary */
 107		ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2);
 108		/* expect 0xfe */
 109	}
 110	/* should return 0xfc(failed) */
 111	ps2_sendbyte(ps2dev, addr, FSP_CMD_TIMEOUT);
 112
 113	if (__ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO) < 0)
 114		goto out;
 115
 116	*reg_val = param[2];
 117	rc = 0;
 118
 119 out:
 120	ps2_end_command(ps2dev);
 121	psmouse_activate(psmouse);
 122	psmouse_dbg(psmouse,
 123		    "READ REG: 0x%02x is 0x%02x (rc = %d)\n",
 124		    reg_addr, *reg_val, rc);
 125	return rc;
 126}
 127
 128static int fsp_reg_write(struct psmouse *psmouse, int reg_addr, int reg_val)
 129{
 130	struct ps2dev *ps2dev = &psmouse->ps2dev;
 131	unsigned char v;
 132	int rc = -1;
 133
 134	ps2_begin_command(ps2dev);
 135
 136	if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
 137		goto out;
 138
 139	if ((v = fsp_test_invert_cmd(reg_addr)) != reg_addr) {
 140		/* inversion is required */
 141		ps2_sendbyte(ps2dev, 0x74, FSP_CMD_TIMEOUT2);
 142	} else {
 143		if ((v = fsp_test_swap_cmd(reg_addr)) != reg_addr) {
 144			/* swapping is required */
 145			ps2_sendbyte(ps2dev, 0x77, FSP_CMD_TIMEOUT2);
 146		} else {
 147			/* swapping isn't necessary */
 148			ps2_sendbyte(ps2dev, 0x55, FSP_CMD_TIMEOUT2);
 149		}
 150	}
 151	/* write the register address in correct order */
 152	ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2);
 153
 154	if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
 155		goto out;
 156
 157	if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) {
 158		/* inversion is required */
 159		ps2_sendbyte(ps2dev, 0x47, FSP_CMD_TIMEOUT2);
 160	} else if ((v = fsp_test_swap_cmd(reg_val)) != reg_val) {
 161		/* swapping is required */
 162		ps2_sendbyte(ps2dev, 0x44, FSP_CMD_TIMEOUT2);
 163	} else {
 164		/* swapping isn't necessary */
 165		ps2_sendbyte(ps2dev, 0x33, FSP_CMD_TIMEOUT2);
 166	}
 167
 168	/* write the register value in correct order */
 169	ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2);
 170	rc = 0;
 171
 172 out:
 173	ps2_end_command(ps2dev);
 174	psmouse_dbg(psmouse,
 175		    "WRITE REG: 0x%02x to 0x%02x (rc = %d)\n",
 176		    reg_addr, reg_val, rc);
 177	return rc;
 178}
 179
 180/* Enable register clock gating for writing certain registers */
 181static int fsp_reg_write_enable(struct psmouse *psmouse, bool enable)
 182{
 183	int v, nv;
 184
 185	if (fsp_reg_read(psmouse, FSP_REG_SYSCTL1, &v) == -1)
 186		return -1;
 187
 188	if (enable)
 189		nv = v | FSP_BIT_EN_REG_CLK;
 190	else
 191		nv = v & ~FSP_BIT_EN_REG_CLK;
 192
 193	/* only write if necessary */
 194	if (nv != v)
 195		if (fsp_reg_write(psmouse, FSP_REG_SYSCTL1, nv) == -1)
 196			return -1;
 197
 198	return 0;
 199}
 200
 201static int fsp_page_reg_read(struct psmouse *psmouse, int *reg_val)
 202{
 203	struct ps2dev *ps2dev = &psmouse->ps2dev;
 204	unsigned char param[3];
 205	int rc = -1;
 206
 207	psmouse_deactivate(psmouse);
 208
 209	ps2_begin_command(ps2dev);
 210
 211	if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
 212		goto out;
 213
 214	ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2);
 215	ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
 216
 217	if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
 218		goto out;
 219
 220	ps2_sendbyte(ps2dev, 0x83, FSP_CMD_TIMEOUT2);
 221	ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
 222
 223	/* get the returned result */
 224	if (__ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
 225		goto out;
 226
 227	*reg_val = param[2];
 228	rc = 0;
 229
 230 out:
 231	ps2_end_command(ps2dev);
 232	psmouse_activate(psmouse);
 233	psmouse_dbg(psmouse,
 234		    "READ PAGE REG: 0x%02x (rc = %d)\n",
 235		    *reg_val, rc);
 236	return rc;
 237}
 238
 239static int fsp_page_reg_write(struct psmouse *psmouse, int reg_val)
 240{
 241	struct ps2dev *ps2dev = &psmouse->ps2dev;
 242	unsigned char v;
 243	int rc = -1;
 244
 245	ps2_begin_command(ps2dev);
 246
 247	if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
 248		goto out;
 249
 250	ps2_sendbyte(ps2dev, 0x38, FSP_CMD_TIMEOUT2);
 251	ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
 252
 253	if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
 254		goto out;
 255
 256	if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) {
 257		ps2_sendbyte(ps2dev, 0x47, FSP_CMD_TIMEOUT2);
 258	} else if ((v = fsp_test_swap_cmd(reg_val)) != reg_val) {
 259		/* swapping is required */
 260		ps2_sendbyte(ps2dev, 0x44, FSP_CMD_TIMEOUT2);
 261	} else {
 262		/* swapping isn't necessary */
 263		ps2_sendbyte(ps2dev, 0x33, FSP_CMD_TIMEOUT2);
 264	}
 265
 266	ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2);
 267	rc = 0;
 268
 269 out:
 270	ps2_end_command(ps2dev);
 271	psmouse_dbg(psmouse,
 272		    "WRITE PAGE REG: to 0x%02x (rc = %d)\n",
 273		    reg_val, rc);
 274	return rc;
 275}
 276
 277static int fsp_get_version(struct psmouse *psmouse, int *version)
 278{
 279	if (fsp_reg_read(psmouse, FSP_REG_VERSION, version))
 280		return -EIO;
 281
 282	return 0;
 283}
 284
 285static int fsp_get_revision(struct psmouse *psmouse, int *rev)
 286{
 287	if (fsp_reg_read(psmouse, FSP_REG_REVISION, rev))
 288		return -EIO;
 289
 290	return 0;
 291}
 292
 293static int fsp_get_sn(struct psmouse *psmouse, int *sn)
 294{
 295	int v0, v1, v2;
 296	int rc = -EIO;
 297
 298	/* production number since Cx is available at: 0x0b40 ~ 0x0b42 */
 299	if (fsp_page_reg_write(psmouse, FSP_PAGE_0B))
 300		goto out;
 301	if (fsp_reg_read(psmouse, FSP_REG_SN0, &v0))
 302		goto out;
 303	if (fsp_reg_read(psmouse, FSP_REG_SN1, &v1))
 304		goto out;
 305	if (fsp_reg_read(psmouse, FSP_REG_SN2, &v2))
 306		goto out;
 307	*sn = (v0 << 16) | (v1 << 8) | v2;
 308	rc = 0;
 309out:
 310	fsp_page_reg_write(psmouse, FSP_PAGE_DEFAULT);
 311	return rc;
 312}
 313
 314static int fsp_get_buttons(struct psmouse *psmouse, int *btn)
 315{
 316	static const int buttons[] = {
 317		0x16, /* Left/Middle/Right/Forward/Backward & Scroll Up/Down */
 318		0x06, /* Left/Middle/Right & Scroll Up/Down/Right/Left */
 319		0x04, /* Left/Middle/Right & Scroll Up/Down */
 320		0x02, /* Left/Middle/Right */
 321	};
 322	int val;
 323
 324	if (fsp_reg_read(psmouse, FSP_REG_TMOD_STATUS, &val) == -1)
 325		return -EIO;
 326
 327	*btn = buttons[(val & 0x30) >> 4];
 328	return 0;
 329}
 330
 331/* Enable on-pad command tag output */
 332static int fsp_opc_tag_enable(struct psmouse *psmouse, bool enable)
 333{
 334	int v, nv;
 335	int res = 0;
 336
 337	if (fsp_reg_read(psmouse, FSP_REG_OPC_QDOWN, &v) == -1) {
 338		psmouse_err(psmouse, "Unable get OPC state.\n");
 339		return -EIO;
 340	}
 341
 342	if (enable)
 343		nv = v | FSP_BIT_EN_OPC_TAG;
 344	else
 345		nv = v & ~FSP_BIT_EN_OPC_TAG;
 346
 347	/* only write if necessary */
 348	if (nv != v) {
 349		fsp_reg_write_enable(psmouse, true);
 350		res = fsp_reg_write(psmouse, FSP_REG_OPC_QDOWN, nv);
 351		fsp_reg_write_enable(psmouse, false);
 352	}
 353
 354	if (res != 0) {
 355		psmouse_err(psmouse, "Unable to enable OPC tag.\n");
 356		res = -EIO;
 357	}
 358
 359	return res;
 360}
 361
 362static int fsp_onpad_vscr(struct psmouse *psmouse, bool enable)
 363{
 364	struct fsp_data *pad = psmouse->private;
 365	int val;
 366
 367	if (fsp_reg_read(psmouse, FSP_REG_ONPAD_CTL, &val))
 368		return -EIO;
 369
 370	pad->vscroll = enable;
 371
 372	if (enable)
 373		val |= (FSP_BIT_FIX_VSCR | FSP_BIT_ONPAD_ENABLE);
 374	else
 375		val &= ~FSP_BIT_FIX_VSCR;
 376
 377	if (fsp_reg_write(psmouse, FSP_REG_ONPAD_CTL, val))
 378		return -EIO;
 379
 380	return 0;
 381}
 382
 383static int fsp_onpad_hscr(struct psmouse *psmouse, bool enable)
 384{
 385	struct fsp_data *pad = psmouse->private;
 386	int val, v2;
 387
 388	if (fsp_reg_read(psmouse, FSP_REG_ONPAD_CTL, &val))
 389		return -EIO;
 390
 391	if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &v2))
 392		return -EIO;
 393
 394	pad->hscroll = enable;
 395
 396	if (enable) {
 397		val |= (FSP_BIT_FIX_HSCR | FSP_BIT_ONPAD_ENABLE);
 398		v2 |= FSP_BIT_EN_MSID6;
 399	} else {
 400		val &= ~FSP_BIT_FIX_HSCR;
 401		v2 &= ~(FSP_BIT_EN_MSID6 | FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8);
 402	}
 403
 404	if (fsp_reg_write(psmouse, FSP_REG_ONPAD_CTL, val))
 405		return -EIO;
 406
 407	/* reconfigure horizontal scrolling packet output */
 408	if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, v2))
 409		return -EIO;
 410
 411	return 0;
 412}
 413
 414/*
 415 * Write device specific initial parameters.
 416 *
 417 * ex: 0xab 0xcd - write oxcd into register 0xab
 418 */
 419static ssize_t fsp_attr_set_setreg(struct psmouse *psmouse, void *data,
 420				   const char *buf, size_t count)
 421{
 422	unsigned int reg, val;
 423	char *rest;
 424	ssize_t retval;
 425
 426	reg = simple_strtoul(buf, &rest, 16);
 427	if (rest == buf || *rest != ' ' || reg > 0xff)
 428		return -EINVAL;
 429
 430	retval = kstrtouint(rest + 1, 16, &val);
 431	if (retval)
 432		return retval;
 433
 434	if (val > 0xff)
 435		return -EINVAL;
 436
 437	if (fsp_reg_write_enable(psmouse, true))
 438		return -EIO;
 439
 440	retval = fsp_reg_write(psmouse, reg, val) < 0 ? -EIO : count;
 441
 442	fsp_reg_write_enable(psmouse, false);
 443
 444	return retval;
 445}
 446
 447PSMOUSE_DEFINE_WO_ATTR(setreg, S_IWUSR, NULL, fsp_attr_set_setreg);
 448
 449static ssize_t fsp_attr_show_getreg(struct psmouse *psmouse,
 450					void *data, char *buf)
 451{
 452	struct fsp_data *pad = psmouse->private;
 453
 454	return sprintf(buf, "%02x%02x\n", pad->last_reg, pad->last_val);
 455}
 456
 457/*
 458 * Read a register from device.
 459 *
 460 * ex: 0xab -- read content from register 0xab
 461 */
 462static ssize_t fsp_attr_set_getreg(struct psmouse *psmouse, void *data,
 463					const char *buf, size_t count)
 464{
 465	struct fsp_data *pad = psmouse->private;
 466	unsigned int reg, val;
 467	int err;
 468
 469	err = kstrtouint(buf, 16, &reg);
 470	if (err)
 471		return err;
 472
 473	if (reg > 0xff)
 474		return -EINVAL;
 475
 476	if (fsp_reg_read(psmouse, reg, &val))
 477		return -EIO;
 478
 479	pad->last_reg = reg;
 480	pad->last_val = val;
 481
 482	return count;
 483}
 484
 485PSMOUSE_DEFINE_ATTR(getreg, S_IWUSR | S_IRUGO, NULL,
 486			fsp_attr_show_getreg, fsp_attr_set_getreg);
 487
 488static ssize_t fsp_attr_show_pagereg(struct psmouse *psmouse,
 489					void *data, char *buf)
 490{
 491	int val = 0;
 492
 493	if (fsp_page_reg_read(psmouse, &val))
 494		return -EIO;
 495
 496	return sprintf(buf, "%02x\n", val);
 497}
 498
 499static ssize_t fsp_attr_set_pagereg(struct psmouse *psmouse, void *data,
 500					const char *buf, size_t count)
 501{
 502	unsigned int val;
 503	int err;
 504
 505	err = kstrtouint(buf, 16, &val);
 506	if (err)
 507		return err;
 508
 509	if (val > 0xff)
 510		return -EINVAL;
 511
 512	if (fsp_page_reg_write(psmouse, val))
 513		return -EIO;
 514
 515	return count;
 516}
 517
 518PSMOUSE_DEFINE_ATTR(page, S_IWUSR | S_IRUGO, NULL,
 519			fsp_attr_show_pagereg, fsp_attr_set_pagereg);
 520
 521static ssize_t fsp_attr_show_vscroll(struct psmouse *psmouse,
 522					void *data, char *buf)
 523{
 524	struct fsp_data *pad = psmouse->private;
 525
 526	return sprintf(buf, "%d\n", pad->vscroll);
 527}
 528
 529static ssize_t fsp_attr_set_vscroll(struct psmouse *psmouse, void *data,
 530					const char *buf, size_t count)
 531{
 532	unsigned int val;
 533	int err;
 534
 535	err = kstrtouint(buf, 10, &val);
 536	if (err)
 537		return err;
 538
 539	if (val > 1)
 540		return -EINVAL;
 541
 542	fsp_onpad_vscr(psmouse, val);
 543
 544	return count;
 545}
 546
 547PSMOUSE_DEFINE_ATTR(vscroll, S_IWUSR | S_IRUGO, NULL,
 548			fsp_attr_show_vscroll, fsp_attr_set_vscroll);
 549
 550static ssize_t fsp_attr_show_hscroll(struct psmouse *psmouse,
 551					void *data, char *buf)
 552{
 553	struct fsp_data *pad = psmouse->private;
 554
 555	return sprintf(buf, "%d\n", pad->hscroll);
 556}
 557
 558static ssize_t fsp_attr_set_hscroll(struct psmouse *psmouse, void *data,
 559					const char *buf, size_t count)
 560{
 561	unsigned int val;
 562	int err;
 563
 564	err = kstrtouint(buf, 10, &val);
 565	if (err)
 566		return err;
 567
 568	if (val > 1)
 569		return -EINVAL;
 570
 571	fsp_onpad_hscr(psmouse, val);
 572
 573	return count;
 574}
 575
 576PSMOUSE_DEFINE_ATTR(hscroll, S_IWUSR | S_IRUGO, NULL,
 577			fsp_attr_show_hscroll, fsp_attr_set_hscroll);
 578
 579static ssize_t fsp_attr_show_flags(struct psmouse *psmouse,
 580					void *data, char *buf)
 581{
 582	struct fsp_data *pad = psmouse->private;
 583
 584	return sprintf(buf, "%c\n",
 585			pad->flags & FSPDRV_FLAG_EN_OPC ? 'C' : 'c');
 586}
 587
 588static ssize_t fsp_attr_set_flags(struct psmouse *psmouse, void *data,
 589					const char *buf, size_t count)
 590{
 591	struct fsp_data *pad = psmouse->private;
 592	size_t i;
 593
 594	for (i = 0; i < count; i++) {
 595		switch (buf[i]) {
 596		case 'C':
 597			pad->flags |= FSPDRV_FLAG_EN_OPC;
 598			break;
 599		case 'c':
 600			pad->flags &= ~FSPDRV_FLAG_EN_OPC;
 601			break;
 602		default:
 603			return -EINVAL;
 604		}
 605	}
 606	return count;
 607}
 608
 609PSMOUSE_DEFINE_ATTR(flags, S_IWUSR | S_IRUGO, NULL,
 610			fsp_attr_show_flags, fsp_attr_set_flags);
 611
 612static ssize_t fsp_attr_show_ver(struct psmouse *psmouse,
 613					void *data, char *buf)
 614{
 615	return sprintf(buf, "Sentelic FSP kernel module %s\n", fsp_drv_ver);
 616}
 617
 618PSMOUSE_DEFINE_RO_ATTR(ver, S_IRUGO, NULL, fsp_attr_show_ver);
 619
 620static struct attribute *fsp_attributes[] = {
 621	&psmouse_attr_setreg.dattr.attr,
 622	&psmouse_attr_getreg.dattr.attr,
 623	&psmouse_attr_page.dattr.attr,
 624	&psmouse_attr_vscroll.dattr.attr,
 625	&psmouse_attr_hscroll.dattr.attr,
 626	&psmouse_attr_flags.dattr.attr,
 627	&psmouse_attr_ver.dattr.attr,
 628	NULL
 629};
 630
 631static struct attribute_group fsp_attribute_group = {
 632	.attrs = fsp_attributes,
 633};
 634
 635#ifdef	FSP_DEBUG
 636static void fsp_packet_debug(struct psmouse *psmouse, unsigned char packet[])
 637{
 638	static unsigned int ps2_packet_cnt;
 639	static unsigned int ps2_last_second;
 640	unsigned int jiffies_msec;
 641	const char *packet_type = "UNKNOWN";
 642	unsigned short abs_x = 0, abs_y = 0;
 643
 644	/* Interpret & dump the packet data. */
 645	switch (packet[0] >> FSP_PKT_TYPE_SHIFT) {
 646	case FSP_PKT_TYPE_ABS:
 647		packet_type = "Absolute";
 648		abs_x = GET_ABS_X(packet);
 649		abs_y = GET_ABS_Y(packet);
 650		break;
 651	case FSP_PKT_TYPE_NORMAL:
 652		packet_type = "Normal";
 653		break;
 654	case FSP_PKT_TYPE_NOTIFY:
 655		packet_type = "Notify";
 656		break;
 657	case FSP_PKT_TYPE_NORMAL_OPC:
 658		packet_type = "Normal-OPC";
 659		break;
 660	}
 661
 662	ps2_packet_cnt++;
 663	jiffies_msec = jiffies_to_msecs(jiffies);
 664	psmouse_dbg(psmouse,
 665		    "%08dms %s packets: %02x, %02x, %02x, %02x; "
 666		    "abs_x: %d, abs_y: %d\n",
 667		    jiffies_msec, packet_type,
 668		    packet[0], packet[1], packet[2], packet[3], abs_x, abs_y);
 669
 670	if (jiffies_msec - ps2_last_second > 1000) {
 671		psmouse_dbg(psmouse, "PS/2 packets/sec = %d\n", ps2_packet_cnt);
 672		ps2_packet_cnt = 0;
 673		ps2_last_second = jiffies_msec;
 674	}
 675}
 676#else
 677static void fsp_packet_debug(struct psmouse *psmouse, unsigned char packet[])
 678{
 679}
 680#endif
 681
 682static void fsp_set_slot(struct input_dev *dev, int slot, bool active,
 683			 unsigned int x, unsigned int y)
 684{
 685	input_mt_slot(dev, slot);
 686	input_mt_report_slot_state(dev, MT_TOOL_FINGER, active);
 687	if (active) {
 688		input_report_abs(dev, ABS_MT_POSITION_X, x);
 689		input_report_abs(dev, ABS_MT_POSITION_Y, y);
 690	}
 691}
 692
 693static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse)
 694{
 695	struct input_dev *dev = psmouse->dev;
 696	struct fsp_data *ad = psmouse->private;
 697	unsigned char *packet = psmouse->packet;
 698	unsigned char button_status = 0, lscroll = 0, rscroll = 0;
 699	unsigned short abs_x, abs_y, fgrs = 0;
 700
 701	if (psmouse->pktcnt < 4)
 702		return PSMOUSE_GOOD_DATA;
 703
 704	/*
 705	 * Full packet accumulated, process it
 706	 */
 707
 708	fsp_packet_debug(psmouse, packet);
 709
 710	switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) {
 711	case FSP_PKT_TYPE_ABS:
 712
 713		if ((packet[0] == 0x48 || packet[0] == 0x49) &&
 714		    packet[1] == 0 && packet[2] == 0) {
 715			/*
 716			 * Ignore coordinate noise when finger leaving the
 717			 * surface, otherwise cursor may jump to upper-left
 718			 * corner.
 719			 */
 720			packet[3] &= 0xf0;
 721		}
 722
 723		abs_x = GET_ABS_X(packet);
 724		abs_y = GET_ABS_Y(packet);
 725
 726		if (packet[0] & FSP_PB0_MFMC) {
 727			/*
 728			 * MFMC packet: assume that there are two fingers on
 729			 * pad
 730			 */
 731			fgrs = 2;
 732
 733			/* MFMC packet */
 734			if (packet[0] & FSP_PB0_MFMC_FGR2) {
 735				/* 2nd finger */
 736				if (ad->last_mt_fgr == 2) {
 737					/*
 738					 * workaround for buggy firmware
 739					 * which doesn't clear MFMC bit if
 740					 * the 1st finger is up
 741					 */
 742					fgrs = 1;
 743					fsp_set_slot(dev, 0, false, 0, 0);
 744				}
 745				ad->last_mt_fgr = 2;
 746
 747				fsp_set_slot(dev, 1, fgrs == 2, abs_x, abs_y);
 748			} else {
 749				/* 1st finger */
 750				if (ad->last_mt_fgr == 1) {
 751					/*
 752					 * workaround for buggy firmware
 753					 * which doesn't clear MFMC bit if
 754					 * the 2nd finger is up
 755					 */
 756					fgrs = 1;
 757					fsp_set_slot(dev, 1, false, 0, 0);
 758				}
 759				ad->last_mt_fgr = 1;
 760				fsp_set_slot(dev, 0, fgrs != 0, abs_x, abs_y);
 761			}
 762		} else {
 763			/* SFAC packet */
 764			if ((packet[0] & (FSP_PB0_LBTN|FSP_PB0_PHY_BTN)) ==
 765				FSP_PB0_LBTN) {
 766				/* On-pad click in SFAC mode should be handled
 767				 * by userspace.  On-pad clicks in MFMC mode
 768				 * are real clickpad clicks, and not ignored.
 769				 */
 770				packet[0] &= ~FSP_PB0_LBTN;
 771			}
 772
 773			/* no multi-finger information */
 774			ad->last_mt_fgr = 0;
 775
 776			if (abs_x != 0 && abs_y != 0)
 777				fgrs = 1;
 778
 779			fsp_set_slot(dev, 0, fgrs > 0, abs_x, abs_y);
 780			fsp_set_slot(dev, 1, false, 0, 0);
 781		}
 782		if (fgrs == 1 || (fgrs == 2 && !(packet[0] & FSP_PB0_MFMC_FGR2))) {
 783			input_report_abs(dev, ABS_X, abs_x);
 784			input_report_abs(dev, ABS_Y, abs_y);
 785		}
 786		input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
 787		input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
 788		input_report_key(dev, BTN_TOUCH, fgrs);
 789		input_report_key(dev, BTN_TOOL_FINGER, fgrs == 1);
 790		input_report_key(dev, BTN_TOOL_DOUBLETAP, fgrs == 2);
 791		break;
 792
 793	case FSP_PKT_TYPE_NORMAL_OPC:
 794		/* on-pad click, filter it if necessary */
 795		if ((ad->flags & FSPDRV_FLAG_EN_OPC) != FSPDRV_FLAG_EN_OPC)
 796			packet[0] &= ~FSP_PB0_LBTN;
 797		fallthrough;
 798
 799	case FSP_PKT_TYPE_NORMAL:
 800		/* normal packet */
 801		/* special packet data translation from on-pad packets */
 802		if (packet[3] != 0) {
 803			if (packet[3] & BIT(0))
 804				button_status |= 0x01;	/* wheel down */
 805			if (packet[3] & BIT(1))
 806				button_status |= 0x0f;	/* wheel up */
 807			if (packet[3] & BIT(2))
 808				button_status |= BIT(4);/* horizontal left */
 809			if (packet[3] & BIT(3))
 810				button_status |= BIT(5);/* horizontal right */
 811			/* push back to packet queue */
 812			if (button_status != 0)
 813				packet[3] = button_status;
 814			rscroll = (packet[3] >> 4) & 1;
 815			lscroll = (packet[3] >> 5) & 1;
 816		}
 817		/*
 818		 * Processing wheel up/down and extra button events
 819		 */
 820		input_report_rel(dev, REL_WHEEL,
 821				 (int)(packet[3] & 8) - (int)(packet[3] & 7));
 822		input_report_rel(dev, REL_HWHEEL, lscroll - rscroll);
 823		input_report_key(dev, BTN_BACK, lscroll);
 824		input_report_key(dev, BTN_FORWARD, rscroll);
 825
 826		/*
 827		 * Standard PS/2 Mouse
 828		 */
 829		psmouse_report_standard_packet(dev, packet);
 830		break;
 831	}
 832
 833	input_sync(dev);
 834
 835	return PSMOUSE_FULL_PACKET;
 836}
 837
 838static int fsp_activate_protocol(struct psmouse *psmouse)
 839{
 840	struct fsp_data *pad = psmouse->private;
 841	struct ps2dev *ps2dev = &psmouse->ps2dev;
 842	unsigned char param[2];
 843	int val;
 844
 845	/*
 846	 * Standard procedure to enter FSP Intellimouse mode
 847	 * (scrolling wheel, 4th and 5th buttons)
 848	 */
 849	param[0] = 200;
 850	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
 851	param[0] = 200;
 852	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
 853	param[0] =  80;
 854	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
 855
 856	ps2_command(ps2dev, param, PSMOUSE_CMD_GETID);
 857	if (param[0] != 0x04) {
 858		psmouse_err(psmouse,
 859			    "Unable to enable 4 bytes packet format.\n");
 860		return -EIO;
 861	}
 862
 863	if (pad->ver < FSP_VER_STL3888_C0) {
 864		/* Preparing relative coordinates output for older hardware */
 865		if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &val)) {
 866			psmouse_err(psmouse,
 867				    "Unable to read SYSCTL5 register.\n");
 868			return -EIO;
 869		}
 870
 871		if (fsp_get_buttons(psmouse, &pad->buttons)) {
 872			psmouse_err(psmouse,
 873				    "Unable to retrieve number of buttons.\n");
 874			return -EIO;
 875		}
 876
 877		val &= ~(FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8 | FSP_BIT_EN_AUTO_MSID8);
 878		/* Ensure we are not in absolute mode */
 879		val &= ~FSP_BIT_EN_PKT_G0;
 880		if (pad->buttons == 0x06) {
 881			/* Left/Middle/Right & Scroll Up/Down/Right/Left */
 882			val |= FSP_BIT_EN_MSID6;
 883		}
 884
 885		if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, val)) {
 886			psmouse_err(psmouse,
 887				    "Unable to set up required mode bits.\n");
 888			return -EIO;
 889		}
 890
 891		/*
 892		 * Enable OPC tags such that driver can tell the difference
 893		 * between on-pad and real button click
 894		 */
 895		if (fsp_opc_tag_enable(psmouse, true))
 896			psmouse_warn(psmouse,
 897				     "Failed to enable OPC tag mode.\n");
 898		/* enable on-pad click by default */
 899		pad->flags |= FSPDRV_FLAG_EN_OPC;
 900
 901		/* Enable on-pad vertical and horizontal scrolling */
 902		fsp_onpad_vscr(psmouse, true);
 903		fsp_onpad_hscr(psmouse, true);
 904	} else {
 905		/* Enable absolute coordinates output for Cx/Dx hardware */
 906		if (fsp_reg_write(psmouse, FSP_REG_SWC1,
 907				  FSP_BIT_SWC1_EN_ABS_1F |
 908				  FSP_BIT_SWC1_EN_ABS_2F |
 909				  FSP_BIT_SWC1_EN_FUP_OUT |
 910				  FSP_BIT_SWC1_EN_ABS_CON)) {
 911			psmouse_err(psmouse,
 912				    "Unable to enable absolute coordinates output.\n");
 913			return -EIO;
 914		}
 915	}
 916
 917	return 0;
 918}
 919
 920static int fsp_set_input_params(struct psmouse *psmouse)
 921{
 922	struct input_dev *dev = psmouse->dev;
 923	struct fsp_data *pad = psmouse->private;
 924
 925	if (pad->ver < FSP_VER_STL3888_C0) {
 926		__set_bit(BTN_MIDDLE, dev->keybit);
 927		__set_bit(BTN_BACK, dev->keybit);
 928		__set_bit(BTN_FORWARD, dev->keybit);
 929		__set_bit(REL_WHEEL, dev->relbit);
 930		__set_bit(REL_HWHEEL, dev->relbit);
 931	} else {
 932		/*
 933		 * Hardware prior to Cx performs much better in relative mode;
 934		 * hence, only enable absolute coordinates output as well as
 935		 * multi-touch output for the newer hardware.
 936		 *
 937		 * Maximum coordinates can be computed as:
 938		 *
 939		 *	number of scanlines * 64 - 57
 940		 *
 941		 * where number of X/Y scanline lines are 16/12.
 942		 */
 943		int abs_x = 967, abs_y = 711;
 944
 945		__set_bit(EV_ABS, dev->evbit);
 946		__clear_bit(EV_REL, dev->evbit);
 947		__set_bit(BTN_TOUCH, dev->keybit);
 948		__set_bit(BTN_TOOL_FINGER, dev->keybit);
 949		__set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
 950		__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
 951
 952		input_set_abs_params(dev, ABS_X, 0, abs_x, 0, 0);
 953		input_set_abs_params(dev, ABS_Y, 0, abs_y, 0, 0);
 954		input_mt_init_slots(dev, 2, 0);
 955		input_set_abs_params(dev, ABS_MT_POSITION_X, 0, abs_x, 0, 0);
 956		input_set_abs_params(dev, ABS_MT_POSITION_Y, 0, abs_y, 0, 0);
 957	}
 958
 959	return 0;
 960}
 961
 962int fsp_detect(struct psmouse *psmouse, bool set_properties)
 963{
 964	int id;
 965
 966	if (fsp_reg_read(psmouse, FSP_REG_DEVICE_ID, &id))
 967		return -EIO;
 968
 969	if (id != 0x01)
 970		return -ENODEV;
 971
 972	if (set_properties) {
 973		psmouse->vendor = "Sentelic";
 974		psmouse->name = "FingerSensingPad";
 975	}
 976
 977	return 0;
 978}
 979
 980static void fsp_reset(struct psmouse *psmouse)
 981{
 982	fsp_opc_tag_enable(psmouse, false);
 983	fsp_onpad_vscr(psmouse, false);
 984	fsp_onpad_hscr(psmouse, false);
 985}
 986
 987static void fsp_disconnect(struct psmouse *psmouse)
 988{
 989	sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj,
 990			   &fsp_attribute_group);
 991
 992	fsp_reset(psmouse);
 993	kfree(psmouse->private);
 994}
 995
 996static int fsp_reconnect(struct psmouse *psmouse)
 997{
 998	int version;
 999
1000	if (fsp_detect(psmouse, 0))
1001		return -ENODEV;
1002
1003	if (fsp_get_version(psmouse, &version))
1004		return -ENODEV;
1005
1006	if (fsp_activate_protocol(psmouse))
1007		return -EIO;
1008
1009	return 0;
1010}
1011
1012int fsp_init(struct psmouse *psmouse)
1013{
1014	struct fsp_data *priv;
1015	int ver, rev, sn = 0;
1016	int error;
1017
1018	if (fsp_get_version(psmouse, &ver) ||
1019	    fsp_get_revision(psmouse, &rev)) {
1020		return -ENODEV;
1021	}
1022	if (ver >= FSP_VER_STL3888_C0) {
1023		/* firmware information is only available since C0 */
1024		fsp_get_sn(psmouse, &sn);
1025	}
1026
1027	psmouse_info(psmouse,
1028		     "Finger Sensing Pad, hw: %d.%d.%d, sn: %x, sw: %s\n",
1029		     ver >> 4, ver & 0x0F, rev, sn, fsp_drv_ver);
1030
1031	psmouse->private = priv = kzalloc(sizeof(*priv), GFP_KERNEL);
1032	if (!priv)
1033		return -ENOMEM;
1034
1035	priv->ver = ver;
1036	priv->rev = rev;
1037
1038	psmouse->protocol_handler = fsp_process_byte;
1039	psmouse->disconnect = fsp_disconnect;
1040	psmouse->reconnect = fsp_reconnect;
1041	psmouse->cleanup = fsp_reset;
1042	psmouse->pktsize = 4;
1043
1044	error = fsp_activate_protocol(psmouse);
1045	if (error)
1046		goto err_out;
1047
1048	/* Set up various supported input event bits */
1049	error = fsp_set_input_params(psmouse);
1050	if (error)
1051		goto err_out;
1052
1053	error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj,
1054				   &fsp_attribute_group);
1055	if (error) {
1056		psmouse_err(psmouse,
1057			    "Failed to create sysfs attributes (%d)", error);
1058		goto err_out;
1059	}
1060
1061	return 0;
1062
1063 err_out:
1064	kfree(psmouse->private);
1065	psmouse->private = NULL;
1066	return error;
1067}