sentelic.c (25451B)
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, ®); 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(struct fsp_data), 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}