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