1 /*- 2 * Finger Sensing Pad PS/2 mouse driver. 3 * 4 * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd. 5 * Copyright (C) 2005-2011 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/ctype.h> 25 #include <linux/libps2.h> 26 #include <linux/serio.h> 27 #include <linux/jiffies.h> 28 #include <linux/slab.h> 29 30 #include "psmouse.h" 31 #include "sentelic.h" 32 33 /* 34 * Timeout for FSP PS/2 command only (in milliseconds). 35 */ 36 #define FSP_CMD_TIMEOUT 200 37 #define FSP_CMD_TIMEOUT2 30 38 39 /** Driver version. */ 40 static const char fsp_drv_ver[] = "1.0.0-K"; 41 42 /* 43 * Make sure that the value being sent to FSP will not conflict with 44 * possible sample rate values. 45 */ 46 static unsigned char fsp_test_swap_cmd(unsigned char reg_val) 47 { 48 switch (reg_val) { 49 case 10: case 20: case 40: case 60: case 80: case 100: case 200: 50 /* 51 * The requested value being sent to FSP matched to possible 52 * sample rates, swap the given value such that the hardware 53 * wouldn't get confused. 54 */ 55 return (reg_val >> 4) | (reg_val << 4); 56 default: 57 return reg_val; /* swap isn't necessary */ 58 } 59 } 60 61 /* 62 * Make sure that the value being sent to FSP will not conflict with certain 63 * commands. 64 */ 65 static unsigned char fsp_test_invert_cmd(unsigned char reg_val) 66 { 67 switch (reg_val) { 68 case 0xe9: case 0xee: case 0xf2: case 0xff: 69 /* 70 * The requested value being sent to FSP matched to certain 71 * commands, inverse the given value such that the hardware 72 * wouldn't get confused. 73 */ 74 return ~reg_val; 75 default: 76 return reg_val; /* inversion isn't necessary */ 77 } 78 } 79 80 static int fsp_reg_read(struct psmouse *psmouse, int reg_addr, int *reg_val) 81 { 82 struct ps2dev *ps2dev = &psmouse->ps2dev; 83 unsigned char param[3]; 84 unsigned char addr; 85 int rc = -1; 86 87 /* 88 * We need to shut off the device and switch it into command 89 * mode so we don't confuse our protocol handler. We don't need 90 * to do that for writes because sysfs set helper does this for 91 * us. 92 */ 93 ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE); 94 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); 95 96 ps2_begin_command(ps2dev); 97 98 if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) 99 goto out; 100 101 /* should return 0xfe(request for resending) */ 102 ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2); 103 /* should return 0xfc(failed) */ 104 ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2); 105 106 if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) 107 goto out; 108 109 if ((addr = fsp_test_invert_cmd(reg_addr)) != reg_addr) { 110 ps2_sendbyte(ps2dev, 0x68, FSP_CMD_TIMEOUT2); 111 } else if ((addr = fsp_test_swap_cmd(reg_addr)) != reg_addr) { 112 /* swapping is required */ 113 ps2_sendbyte(ps2dev, 0xcc, FSP_CMD_TIMEOUT2); 114 /* expect 0xfe */ 115 } else { 116 /* swapping isn't necessary */ 117 ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2); 118 /* expect 0xfe */ 119 } 120 /* should return 0xfc(failed) */ 121 ps2_sendbyte(ps2dev, addr, FSP_CMD_TIMEOUT); 122 123 if (__ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO) < 0) 124 goto out; 125 126 *reg_val = param[2]; 127 rc = 0; 128 129 out: 130 ps2_end_command(ps2dev); 131 ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE); 132 psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); 133 dev_dbg(&ps2dev->serio->dev, "READ REG: 0x%02x is 0x%02x (rc = %d)\n", 134 reg_addr, *reg_val, rc); 135 return rc; 136 } 137 138 static int fsp_reg_write(struct psmouse *psmouse, int reg_addr, int reg_val) 139 { 140 struct ps2dev *ps2dev = &psmouse->ps2dev; 141 unsigned char v; 142 int rc = -1; 143 144 ps2_begin_command(ps2dev); 145 146 if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) 147 goto out; 148 149 if ((v = fsp_test_invert_cmd(reg_addr)) != reg_addr) { 150 /* inversion is required */ 151 ps2_sendbyte(ps2dev, 0x74, FSP_CMD_TIMEOUT2); 152 } else { 153 if ((v = fsp_test_swap_cmd(reg_addr)) != reg_addr) { 154 /* swapping is required */ 155 ps2_sendbyte(ps2dev, 0x77, FSP_CMD_TIMEOUT2); 156 } else { 157 /* swapping isn't necessary */ 158 ps2_sendbyte(ps2dev, 0x55, FSP_CMD_TIMEOUT2); 159 } 160 } 161 /* write the register address in correct order */ 162 ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2); 163 164 if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) 165 goto out; 166 167 if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) { 168 /* inversion is required */ 169 ps2_sendbyte(ps2dev, 0x47, FSP_CMD_TIMEOUT2); 170 } else if ((v = fsp_test_swap_cmd(reg_val)) != reg_val) { 171 /* swapping is required */ 172 ps2_sendbyte(ps2dev, 0x44, FSP_CMD_TIMEOUT2); 173 } else { 174 /* swapping isn't necessary */ 175 ps2_sendbyte(ps2dev, 0x33, FSP_CMD_TIMEOUT2); 176 } 177 178 /* write the register value in correct order */ 179 ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2); 180 rc = 0; 181 182 out: 183 ps2_end_command(ps2dev); 184 dev_dbg(&ps2dev->serio->dev, "WRITE REG: 0x%02x to 0x%02x (rc = %d)\n", 185 reg_addr, reg_val, rc); 186 return rc; 187 } 188 189 /* Enable register clock gating for writing certain registers */ 190 static int fsp_reg_write_enable(struct psmouse *psmouse, bool enable) 191 { 192 int v, nv; 193 194 if (fsp_reg_read(psmouse, FSP_REG_SYSCTL1, &v) == -1) 195 return -1; 196 197 if (enable) 198 nv = v | FSP_BIT_EN_REG_CLK; 199 else 200 nv = v & ~FSP_BIT_EN_REG_CLK; 201 202 /* only write if necessary */ 203 if (nv != v) 204 if (fsp_reg_write(psmouse, FSP_REG_SYSCTL1, nv) == -1) 205 return -1; 206 207 return 0; 208 } 209 210 static int fsp_page_reg_read(struct psmouse *psmouse, int *reg_val) 211 { 212 struct ps2dev *ps2dev = &psmouse->ps2dev; 213 unsigned char param[3]; 214 int rc = -1; 215 216 ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE); 217 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); 218 219 ps2_begin_command(ps2dev); 220 221 if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) 222 goto out; 223 224 ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2); 225 ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2); 226 227 if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) 228 goto out; 229 230 ps2_sendbyte(ps2dev, 0x83, FSP_CMD_TIMEOUT2); 231 ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2); 232 233 /* get the returned result */ 234 if (__ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) 235 goto out; 236 237 *reg_val = param[2]; 238 rc = 0; 239 240 out: 241 ps2_end_command(ps2dev); 242 ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE); 243 psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); 244 dev_dbg(&ps2dev->serio->dev, "READ PAGE REG: 0x%02x (rc = %d)\n", 245 *reg_val, rc); 246 return rc; 247 } 248 249 static int fsp_page_reg_write(struct psmouse *psmouse, int reg_val) 250 { 251 struct ps2dev *ps2dev = &psmouse->ps2dev; 252 unsigned char v; 253 int rc = -1; 254 255 ps2_begin_command(ps2dev); 256 257 if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) 258 goto out; 259 260 ps2_sendbyte(ps2dev, 0x38, FSP_CMD_TIMEOUT2); 261 ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2); 262 263 if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) 264 goto out; 265 266 if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) { 267 ps2_sendbyte(ps2dev, 0x47, FSP_CMD_TIMEOUT2); 268 } else if ((v = fsp_test_swap_cmd(reg_val)) != reg_val) { 269 /* swapping is required */ 270 ps2_sendbyte(ps2dev, 0x44, FSP_CMD_TIMEOUT2); 271 } else { 272 /* swapping isn't necessary */ 273 ps2_sendbyte(ps2dev, 0x33, FSP_CMD_TIMEOUT2); 274 } 275 276 ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2); 277 rc = 0; 278 279 out: 280 ps2_end_command(ps2dev); 281 dev_dbg(&ps2dev->serio->dev, "WRITE PAGE REG: to 0x%02x (rc = %d)\n", 282 reg_val, rc); 283 return rc; 284 } 285 286 static int fsp_get_version(struct psmouse *psmouse, int *version) 287 { 288 if (fsp_reg_read(psmouse, FSP_REG_VERSION, version)) 289 return -EIO; 290 291 return 0; 292 } 293 294 static int fsp_get_revision(struct psmouse *psmouse, int *rev) 295 { 296 if (fsp_reg_read(psmouse, FSP_REG_REVISION, rev)) 297 return -EIO; 298 299 return 0; 300 } 301 302 static int fsp_get_buttons(struct psmouse *psmouse, int *btn) 303 { 304 static const int buttons[] = { 305 0x16, /* Left/Middle/Right/Forward/Backward & Scroll Up/Down */ 306 0x06, /* Left/Middle/Right & Scroll Up/Down/Right/Left */ 307 0x04, /* Left/Middle/Right & Scroll Up/Down */ 308 0x02, /* Left/Middle/Right */ 309 }; 310 int val; 311 312 if (fsp_reg_read(psmouse, FSP_REG_TMOD_STATUS, &val) == -1) 313 return -EIO; 314 315 *btn = buttons[(val & 0x30) >> 4]; 316 return 0; 317 } 318 319 /* Enable on-pad command tag output */ 320 static int fsp_opc_tag_enable(struct psmouse *psmouse, bool enable) 321 { 322 int v, nv; 323 int res = 0; 324 325 if (fsp_reg_read(psmouse, FSP_REG_OPC_QDOWN, &v) == -1) { 326 dev_err(&psmouse->ps2dev.serio->dev, "Unable get OPC state.\n"); 327 return -EIO; 328 } 329 330 if (enable) 331 nv = v | FSP_BIT_EN_OPC_TAG; 332 else 333 nv = v & ~FSP_BIT_EN_OPC_TAG; 334 335 /* only write if necessary */ 336 if (nv != v) { 337 fsp_reg_write_enable(psmouse, true); 338 res = fsp_reg_write(psmouse, FSP_REG_OPC_QDOWN, nv); 339 fsp_reg_write_enable(psmouse, false); 340 } 341 342 if (res != 0) { 343 dev_err(&psmouse->ps2dev.serio->dev, 344 "Unable to enable OPC tag.\n"); 345 res = -EIO; 346 } 347 348 return res; 349 } 350 351 static int fsp_onpad_vscr(struct psmouse *psmouse, bool enable) 352 { 353 struct fsp_data *pad = psmouse->private; 354 int val; 355 356 if (fsp_reg_read(psmouse, FSP_REG_ONPAD_CTL, &val)) 357 return -EIO; 358 359 pad->vscroll = enable; 360 361 if (enable) 362 val |= (FSP_BIT_FIX_VSCR | FSP_BIT_ONPAD_ENABLE); 363 else 364 val &= ~FSP_BIT_FIX_VSCR; 365 366 if (fsp_reg_write(psmouse, FSP_REG_ONPAD_CTL, val)) 367 return -EIO; 368 369 return 0; 370 } 371 372 static int fsp_onpad_hscr(struct psmouse *psmouse, bool enable) 373 { 374 struct fsp_data *pad = psmouse->private; 375 int val, v2; 376 377 if (fsp_reg_read(psmouse, FSP_REG_ONPAD_CTL, &val)) 378 return -EIO; 379 380 if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &v2)) 381 return -EIO; 382 383 pad->hscroll = enable; 384 385 if (enable) { 386 val |= (FSP_BIT_FIX_HSCR | FSP_BIT_ONPAD_ENABLE); 387 v2 |= FSP_BIT_EN_MSID6; 388 } else { 389 val &= ~FSP_BIT_FIX_HSCR; 390 v2 &= ~(FSP_BIT_EN_MSID6 | FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8); 391 } 392 393 if (fsp_reg_write(psmouse, FSP_REG_ONPAD_CTL, val)) 394 return -EIO; 395 396 /* reconfigure horizontal scrolling packet output */ 397 if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, v2)) 398 return -EIO; 399 400 return 0; 401 } 402 403 /* 404 * Write device specific initial parameters. 405 * 406 * ex: 0xab 0xcd - write oxcd into register 0xab 407 */ 408 static ssize_t fsp_attr_set_setreg(struct psmouse *psmouse, void *data, 409 const char *buf, size_t count) 410 { 411 int reg, val; 412 char *rest; 413 ssize_t retval; 414 415 reg = simple_strtoul(buf, &rest, 16); 416 if (rest == buf || *rest != ' ' || reg > 0xff) 417 return -EINVAL; 418 419 retval = kstrtoint(rest + 1, 16, &val); 420 if (retval) 421 return retval; 422 423 if (val > 0xff) 424 return -EINVAL; 425 426 if (fsp_reg_write_enable(psmouse, true)) 427 return -EIO; 428 429 retval = fsp_reg_write(psmouse, reg, val) < 0 ? -EIO : count; 430 431 fsp_reg_write_enable(psmouse, false); 432 433 return count; 434 } 435 436 PSMOUSE_DEFINE_WO_ATTR(setreg, S_IWUSR, NULL, fsp_attr_set_setreg); 437 438 static ssize_t fsp_attr_show_getreg(struct psmouse *psmouse, 439 void *data, char *buf) 440 { 441 struct fsp_data *pad = psmouse->private; 442 443 return sprintf(buf, "%02x%02x\n", pad->last_reg, pad->last_val); 444 } 445 446 /* 447 * Read a register from device. 448 * 449 * ex: 0xab -- read content from register 0xab 450 */ 451 static ssize_t fsp_attr_set_getreg(struct psmouse *psmouse, void *data, 452 const char *buf, size_t count) 453 { 454 struct fsp_data *pad = psmouse->private; 455 int reg, val, err; 456 457 err = kstrtoint(buf, 16, ®); 458 if (err) 459 return err; 460 461 if (reg > 0xff) 462 return -EINVAL; 463 464 if (fsp_reg_read(psmouse, reg, &val)) 465 return -EIO; 466 467 pad->last_reg = reg; 468 pad->last_val = val; 469 470 return count; 471 } 472 473 PSMOUSE_DEFINE_ATTR(getreg, S_IWUSR | S_IRUGO, NULL, 474 fsp_attr_show_getreg, fsp_attr_set_getreg); 475 476 static ssize_t fsp_attr_show_pagereg(struct psmouse *psmouse, 477 void *data, char *buf) 478 { 479 int val = 0; 480 481 if (fsp_page_reg_read(psmouse, &val)) 482 return -EIO; 483 484 return sprintf(buf, "%02x\n", val); 485 } 486 487 static ssize_t fsp_attr_set_pagereg(struct psmouse *psmouse, void *data, 488 const char *buf, size_t count) 489 { 490 int val, err; 491 492 err = kstrtoint(buf, 16, &val); 493 if (err) 494 return err; 495 496 if (val > 0xff) 497 return -EINVAL; 498 499 if (fsp_page_reg_write(psmouse, val)) 500 return -EIO; 501 502 return count; 503 } 504 505 PSMOUSE_DEFINE_ATTR(page, S_IWUSR | S_IRUGO, NULL, 506 fsp_attr_show_pagereg, fsp_attr_set_pagereg); 507 508 static ssize_t fsp_attr_show_vscroll(struct psmouse *psmouse, 509 void *data, char *buf) 510 { 511 struct fsp_data *pad = psmouse->private; 512 513 return sprintf(buf, "%d\n", pad->vscroll); 514 } 515 516 static ssize_t fsp_attr_set_vscroll(struct psmouse *psmouse, void *data, 517 const char *buf, size_t count) 518 { 519 unsigned int val; 520 int err; 521 522 err = kstrtouint(buf, 10, &val); 523 if (err) 524 return err; 525 526 if (val > 1) 527 return -EINVAL; 528 529 fsp_onpad_vscr(psmouse, val); 530 531 return count; 532 } 533 534 PSMOUSE_DEFINE_ATTR(vscroll, S_IWUSR | S_IRUGO, NULL, 535 fsp_attr_show_vscroll, fsp_attr_set_vscroll); 536 537 static ssize_t fsp_attr_show_hscroll(struct psmouse *psmouse, 538 void *data, char *buf) 539 { 540 struct fsp_data *pad = psmouse->private; 541 542 return sprintf(buf, "%d\n", pad->hscroll); 543 } 544 545 static ssize_t fsp_attr_set_hscroll(struct psmouse *psmouse, void *data, 546 const char *buf, size_t count) 547 { 548 unsigned int val; 549 int err; 550 551 err = kstrtouint(buf, 10, &val); 552 if (err) 553 return err; 554 555 if (val > 1) 556 return -EINVAL; 557 558 fsp_onpad_hscr(psmouse, val); 559 560 return count; 561 } 562 563 PSMOUSE_DEFINE_ATTR(hscroll, S_IWUSR | S_IRUGO, NULL, 564 fsp_attr_show_hscroll, fsp_attr_set_hscroll); 565 566 static ssize_t fsp_attr_show_flags(struct psmouse *psmouse, 567 void *data, char *buf) 568 { 569 struct fsp_data *pad = psmouse->private; 570 571 return sprintf(buf, "%c\n", 572 pad->flags & FSPDRV_FLAG_EN_OPC ? 'C' : 'c'); 573 } 574 575 static ssize_t fsp_attr_set_flags(struct psmouse *psmouse, void *data, 576 const char *buf, size_t count) 577 { 578 struct fsp_data *pad = psmouse->private; 579 size_t i; 580 581 for (i = 0; i < count; i++) { 582 switch (buf[i]) { 583 case 'C': 584 pad->flags |= FSPDRV_FLAG_EN_OPC; 585 break; 586 case 'c': 587 pad->flags &= ~FSPDRV_FLAG_EN_OPC; 588 break; 589 default: 590 return -EINVAL; 591 } 592 } 593 return count; 594 } 595 596 PSMOUSE_DEFINE_ATTR(flags, S_IWUSR | S_IRUGO, NULL, 597 fsp_attr_show_flags, fsp_attr_set_flags); 598 599 static ssize_t fsp_attr_show_ver(struct psmouse *psmouse, 600 void *data, char *buf) 601 { 602 return sprintf(buf, "Sentelic FSP kernel module %s\n", fsp_drv_ver); 603 } 604 605 PSMOUSE_DEFINE_RO_ATTR(ver, S_IRUGO, NULL, fsp_attr_show_ver); 606 607 static struct attribute *fsp_attributes[] = { 608 &psmouse_attr_setreg.dattr.attr, 609 &psmouse_attr_getreg.dattr.attr, 610 &psmouse_attr_page.dattr.attr, 611 &psmouse_attr_vscroll.dattr.attr, 612 &psmouse_attr_hscroll.dattr.attr, 613 &psmouse_attr_flags.dattr.attr, 614 &psmouse_attr_ver.dattr.attr, 615 NULL 616 }; 617 618 static struct attribute_group fsp_attribute_group = { 619 .attrs = fsp_attributes, 620 }; 621 622 #ifdef FSP_DEBUG 623 static void fsp_packet_debug(unsigned char packet[]) 624 { 625 static unsigned int ps2_packet_cnt; 626 static unsigned int ps2_last_second; 627 unsigned int jiffies_msec; 628 629 ps2_packet_cnt++; 630 jiffies_msec = jiffies_to_msecs(jiffies); 631 psmouse_dbg(psmouse, 632 "%08dms PS/2 packets: %02x, %02x, %02x, %02x\n", 633 jiffies_msec, packet[0], packet[1], packet[2], packet[3]); 634 635 if (jiffies_msec - ps2_last_second > 1000) { 636 psmouse_dbg(psmouse, "PS/2 packets/sec = %d\n", ps2_packet_cnt); 637 ps2_packet_cnt = 0; 638 ps2_last_second = jiffies_msec; 639 } 640 } 641 #else 642 static void fsp_packet_debug(unsigned char packet[]) 643 { 644 } 645 #endif 646 647 static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse) 648 { 649 struct input_dev *dev = psmouse->dev; 650 struct fsp_data *ad = psmouse->private; 651 unsigned char *packet = psmouse->packet; 652 unsigned char button_status = 0, lscroll = 0, rscroll = 0; 653 int rel_x, rel_y; 654 655 if (psmouse->pktcnt < 4) 656 return PSMOUSE_GOOD_DATA; 657 658 /* 659 * Full packet accumulated, process it 660 */ 661 662 switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) { 663 case FSP_PKT_TYPE_ABS: 664 dev_warn(&psmouse->ps2dev.serio->dev, 665 "Unexpected absolute mode packet, ignored.\n"); 666 break; 667 668 case FSP_PKT_TYPE_NORMAL_OPC: 669 /* on-pad click, filter it if necessary */ 670 if ((ad->flags & FSPDRV_FLAG_EN_OPC) != FSPDRV_FLAG_EN_OPC) 671 packet[0] &= ~BIT(0); 672 /* fall through */ 673 674 case FSP_PKT_TYPE_NORMAL: 675 /* normal packet */ 676 /* special packet data translation from on-pad packets */ 677 if (packet[3] != 0) { 678 if (packet[3] & BIT(0)) 679 button_status |= 0x01; /* wheel down */ 680 if (packet[3] & BIT(1)) 681 button_status |= 0x0f; /* wheel up */ 682 if (packet[3] & BIT(2)) 683 button_status |= BIT(4);/* horizontal left */ 684 if (packet[3] & BIT(3)) 685 button_status |= BIT(5);/* horizontal right */ 686 /* push back to packet queue */ 687 if (button_status != 0) 688 packet[3] = button_status; 689 rscroll = (packet[3] >> 4) & 1; 690 lscroll = (packet[3] >> 5) & 1; 691 } 692 /* 693 * Processing wheel up/down and extra button events 694 */ 695 input_report_rel(dev, REL_WHEEL, 696 (int)(packet[3] & 8) - (int)(packet[3] & 7)); 697 input_report_rel(dev, REL_HWHEEL, lscroll - rscroll); 698 input_report_key(dev, BTN_BACK, lscroll); 699 input_report_key(dev, BTN_FORWARD, rscroll); 700 701 /* 702 * Standard PS/2 Mouse 703 */ 704 input_report_key(dev, BTN_LEFT, packet[0] & 1); 705 input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1); 706 input_report_key(dev, BTN_RIGHT, (packet[0] >> 1) & 1); 707 708 rel_x = packet[1] ? (int)packet[1] - (int)((packet[0] << 4) & 0x100) : 0; 709 rel_y = packet[2] ? (int)((packet[0] << 3) & 0x100) - (int)packet[2] : 0; 710 711 input_report_rel(dev, REL_X, rel_x); 712 input_report_rel(dev, REL_Y, rel_y); 713 break; 714 } 715 716 input_sync(dev); 717 718 fsp_packet_debug(packet); 719 720 return PSMOUSE_FULL_PACKET; 721 } 722 723 static int fsp_activate_protocol(struct psmouse *psmouse) 724 { 725 struct fsp_data *pad = psmouse->private; 726 struct ps2dev *ps2dev = &psmouse->ps2dev; 727 unsigned char param[2]; 728 int val; 729 730 /* 731 * Standard procedure to enter FSP Intellimouse mode 732 * (scrolling wheel, 4th and 5th buttons) 733 */ 734 param[0] = 200; 735 ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); 736 param[0] = 200; 737 ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); 738 param[0] = 80; 739 ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); 740 741 ps2_command(ps2dev, param, PSMOUSE_CMD_GETID); 742 if (param[0] != 0x04) { 743 dev_err(&psmouse->ps2dev.serio->dev, 744 "Unable to enable 4 bytes packet format.\n"); 745 return -EIO; 746 } 747 748 if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &val)) { 749 dev_err(&psmouse->ps2dev.serio->dev, 750 "Unable to read SYSCTL5 register.\n"); 751 return -EIO; 752 } 753 754 val &= ~(FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8 | FSP_BIT_EN_AUTO_MSID8); 755 /* Ensure we are not in absolute mode */ 756 val &= ~FSP_BIT_EN_PKT_G0; 757 if (pad->buttons == 0x06) { 758 /* Left/Middle/Right & Scroll Up/Down/Right/Left */ 759 val |= FSP_BIT_EN_MSID6; 760 } 761 762 if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, val)) { 763 dev_err(&psmouse->ps2dev.serio->dev, 764 "Unable to set up required mode bits.\n"); 765 return -EIO; 766 } 767 768 /* 769 * Enable OPC tags such that driver can tell the difference between 770 * on-pad and real button click 771 */ 772 if (fsp_opc_tag_enable(psmouse, true)) 773 dev_warn(&psmouse->ps2dev.serio->dev, 774 "Failed to enable OPC tag mode.\n"); 775 776 /* Enable on-pad vertical and horizontal scrolling */ 777 fsp_onpad_vscr(psmouse, true); 778 fsp_onpad_hscr(psmouse, true); 779 780 return 0; 781 } 782 783 int fsp_detect(struct psmouse *psmouse, bool set_properties) 784 { 785 int id; 786 787 if (fsp_reg_read(psmouse, FSP_REG_DEVICE_ID, &id)) 788 return -EIO; 789 790 if (id != 0x01) 791 return -ENODEV; 792 793 if (set_properties) { 794 psmouse->vendor = "Sentelic"; 795 psmouse->name = "FingerSensingPad"; 796 } 797 798 return 0; 799 } 800 801 static void fsp_reset(struct psmouse *psmouse) 802 { 803 fsp_opc_tag_enable(psmouse, false); 804 fsp_onpad_vscr(psmouse, false); 805 fsp_onpad_hscr(psmouse, false); 806 } 807 808 static void fsp_disconnect(struct psmouse *psmouse) 809 { 810 sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj, 811 &fsp_attribute_group); 812 813 fsp_reset(psmouse); 814 kfree(psmouse->private); 815 } 816 817 static int fsp_reconnect(struct psmouse *psmouse) 818 { 819 int version; 820 821 if (fsp_detect(psmouse, 0)) 822 return -ENODEV; 823 824 if (fsp_get_version(psmouse, &version)) 825 return -ENODEV; 826 827 if (fsp_activate_protocol(psmouse)) 828 return -EIO; 829 830 return 0; 831 } 832 833 int fsp_init(struct psmouse *psmouse) 834 { 835 struct fsp_data *priv; 836 int ver, rev, buttons; 837 int error; 838 839 if (fsp_get_version(psmouse, &ver) || 840 fsp_get_revision(psmouse, &rev) || 841 fsp_get_buttons(psmouse, &buttons)) { 842 return -ENODEV; 843 } 844 845 psmouse_info(psmouse, 846 "Finger Sensing Pad, hw: %d.%d.%d, sw: %s, buttons: %d\n", 847 ver >> 4, ver & 0x0F, rev, fsp_drv_ver, buttons & 7); 848 849 psmouse->private = priv = kzalloc(sizeof(struct fsp_data), GFP_KERNEL); 850 if (!priv) 851 return -ENOMEM; 852 853 priv->ver = ver; 854 priv->rev = rev; 855 priv->buttons = buttons; 856 857 /* enable on-pad click by default */ 858 priv->flags |= FSPDRV_FLAG_EN_OPC; 859 860 /* Set up various supported input event bits */ 861 __set_bit(BTN_MIDDLE, psmouse->dev->keybit); 862 __set_bit(BTN_BACK, psmouse->dev->keybit); 863 __set_bit(BTN_FORWARD, psmouse->dev->keybit); 864 __set_bit(REL_WHEEL, psmouse->dev->relbit); 865 __set_bit(REL_HWHEEL, psmouse->dev->relbit); 866 867 psmouse->protocol_handler = fsp_process_byte; 868 psmouse->disconnect = fsp_disconnect; 869 psmouse->reconnect = fsp_reconnect; 870 psmouse->cleanup = fsp_reset; 871 psmouse->pktsize = 4; 872 873 /* set default packet output based on number of buttons we found */ 874 error = fsp_activate_protocol(psmouse); 875 if (error) 876 goto err_out; 877 878 error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj, 879 &fsp_attribute_group); 880 if (error) { 881 dev_err(&psmouse->ps2dev.serio->dev, 882 "Failed to create sysfs attributes (%d)", error); 883 goto err_out; 884 } 885 886 return 0; 887 888 err_out: 889 kfree(psmouse->private); 890 psmouse->private = NULL; 891 return error; 892 } 893