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