1 /*- 2 * Finger Sensing Pad PS/2 mouse driver. 3 * 4 * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd. 5 * Copyright (C) 2005-2010 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 return -1; 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 return -1; 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_STATUS1, &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 unsigned long 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 if (strict_strtoul(rest + 1, 16, &val) || 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 unsigned long reg; 452 int val; 453 454 if (strict_strtoul(buf, 16, ®) || reg > 0xff) 455 return -EINVAL; 456 457 if (fsp_reg_read(psmouse, reg, &val)) 458 return -EIO; 459 460 pad->last_reg = reg; 461 pad->last_val = val; 462 463 return count; 464 } 465 466 PSMOUSE_DEFINE_ATTR(getreg, S_IWUSR | S_IRUGO, NULL, 467 fsp_attr_show_getreg, fsp_attr_set_getreg); 468 469 static ssize_t fsp_attr_show_pagereg(struct psmouse *psmouse, 470 void *data, char *buf) 471 { 472 int val = 0; 473 474 if (fsp_page_reg_read(psmouse, &val)) 475 return -EIO; 476 477 return sprintf(buf, "%02x\n", val); 478 } 479 480 static ssize_t fsp_attr_set_pagereg(struct psmouse *psmouse, void *data, 481 const char *buf, size_t count) 482 { 483 unsigned long val; 484 485 if (strict_strtoul(buf, 16, &val) || val > 0xff) 486 return -EINVAL; 487 488 if (fsp_page_reg_write(psmouse, val)) 489 return -EIO; 490 491 return count; 492 } 493 494 PSMOUSE_DEFINE_ATTR(page, S_IWUSR | S_IRUGO, NULL, 495 fsp_attr_show_pagereg, fsp_attr_set_pagereg); 496 497 static ssize_t fsp_attr_show_vscroll(struct psmouse *psmouse, 498 void *data, char *buf) 499 { 500 struct fsp_data *pad = psmouse->private; 501 502 return sprintf(buf, "%d\n", pad->vscroll); 503 } 504 505 static ssize_t fsp_attr_set_vscroll(struct psmouse *psmouse, void *data, 506 const char *buf, size_t count) 507 { 508 unsigned long val; 509 510 if (strict_strtoul(buf, 10, &val) || val > 1) 511 return -EINVAL; 512 513 fsp_onpad_vscr(psmouse, val); 514 515 return count; 516 } 517 518 PSMOUSE_DEFINE_ATTR(vscroll, S_IWUSR | S_IRUGO, NULL, 519 fsp_attr_show_vscroll, fsp_attr_set_vscroll); 520 521 static ssize_t fsp_attr_show_hscroll(struct psmouse *psmouse, 522 void *data, char *buf) 523 { 524 struct fsp_data *pad = psmouse->private; 525 526 return sprintf(buf, "%d\n", pad->hscroll); 527 } 528 529 static ssize_t fsp_attr_set_hscroll(struct psmouse *psmouse, void *data, 530 const char *buf, size_t count) 531 { 532 unsigned long val; 533 534 if (strict_strtoul(buf, 10, &val) || val > 1) 535 return -EINVAL; 536 537 fsp_onpad_hscr(psmouse, val); 538 539 return count; 540 } 541 542 PSMOUSE_DEFINE_ATTR(hscroll, S_IWUSR | S_IRUGO, NULL, 543 fsp_attr_show_hscroll, fsp_attr_set_hscroll); 544 545 static ssize_t fsp_attr_show_flags(struct psmouse *psmouse, 546 void *data, char *buf) 547 { 548 struct fsp_data *pad = psmouse->private; 549 550 return sprintf(buf, "%c\n", 551 pad->flags & FSPDRV_FLAG_EN_OPC ? 'C' : 'c'); 552 } 553 554 static ssize_t fsp_attr_set_flags(struct psmouse *psmouse, void *data, 555 const char *buf, size_t count) 556 { 557 struct fsp_data *pad = psmouse->private; 558 size_t i; 559 560 for (i = 0; i < count; i++) { 561 switch (buf[i]) { 562 case 'C': 563 pad->flags |= FSPDRV_FLAG_EN_OPC; 564 break; 565 case 'c': 566 pad->flags &= ~FSPDRV_FLAG_EN_OPC; 567 break; 568 default: 569 return -EINVAL; 570 } 571 } 572 return count; 573 } 574 575 PSMOUSE_DEFINE_ATTR(flags, S_IWUSR | S_IRUGO, NULL, 576 fsp_attr_show_flags, fsp_attr_set_flags); 577 578 static ssize_t fsp_attr_show_ver(struct psmouse *psmouse, 579 void *data, char *buf) 580 { 581 return sprintf(buf, "Sentelic FSP kernel module %s\n", fsp_drv_ver); 582 } 583 584 PSMOUSE_DEFINE_RO_ATTR(ver, S_IRUGO, NULL, fsp_attr_show_ver); 585 586 static struct attribute *fsp_attributes[] = { 587 &psmouse_attr_setreg.dattr.attr, 588 &psmouse_attr_getreg.dattr.attr, 589 &psmouse_attr_page.dattr.attr, 590 &psmouse_attr_vscroll.dattr.attr, 591 &psmouse_attr_hscroll.dattr.attr, 592 &psmouse_attr_flags.dattr.attr, 593 &psmouse_attr_ver.dattr.attr, 594 NULL 595 }; 596 597 static struct attribute_group fsp_attribute_group = { 598 .attrs = fsp_attributes, 599 }; 600 601 #ifdef FSP_DEBUG 602 static void fsp_packet_debug(unsigned char packet[]) 603 { 604 static unsigned int ps2_packet_cnt; 605 static unsigned int ps2_last_second; 606 unsigned int jiffies_msec; 607 608 ps2_packet_cnt++; 609 jiffies_msec = jiffies_to_msecs(jiffies); 610 psmouse_dbg(psmouse, 611 "%08dms PS/2 packets: %02x, %02x, %02x, %02x\n", 612 jiffies_msec, packet[0], packet[1], packet[2], packet[3]); 613 614 if (jiffies_msec - ps2_last_second > 1000) { 615 psmouse_dbg(psmouse, "PS/2 packets/sec = %d\n", ps2_packet_cnt); 616 ps2_packet_cnt = 0; 617 ps2_last_second = jiffies_msec; 618 } 619 } 620 #else 621 static void fsp_packet_debug(unsigned char packet[]) 622 { 623 } 624 #endif 625 626 static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse) 627 { 628 struct input_dev *dev = psmouse->dev; 629 struct fsp_data *ad = psmouse->private; 630 unsigned char *packet = psmouse->packet; 631 unsigned char button_status = 0, lscroll = 0, rscroll = 0; 632 int rel_x, rel_y; 633 634 if (psmouse->pktcnt < 4) 635 return PSMOUSE_GOOD_DATA; 636 637 /* 638 * Full packet accumulated, process it 639 */ 640 641 switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) { 642 case FSP_PKT_TYPE_ABS: 643 dev_warn(&psmouse->ps2dev.serio->dev, 644 "Unexpected absolute mode packet, ignored.\n"); 645 break; 646 647 case FSP_PKT_TYPE_NORMAL_OPC: 648 /* on-pad click, filter it if necessary */ 649 if ((ad->flags & FSPDRV_FLAG_EN_OPC) != FSPDRV_FLAG_EN_OPC) 650 packet[0] &= ~BIT(0); 651 /* fall through */ 652 653 case FSP_PKT_TYPE_NORMAL: 654 /* normal packet */ 655 /* special packet data translation from on-pad packets */ 656 if (packet[3] != 0) { 657 if (packet[3] & BIT(0)) 658 button_status |= 0x01; /* wheel down */ 659 if (packet[3] & BIT(1)) 660 button_status |= 0x0f; /* wheel up */ 661 if (packet[3] & BIT(2)) 662 button_status |= BIT(4);/* horizontal left */ 663 if (packet[3] & BIT(3)) 664 button_status |= BIT(5);/* horizontal right */ 665 /* push back to packet queue */ 666 if (button_status != 0) 667 packet[3] = button_status; 668 rscroll = (packet[3] >> 4) & 1; 669 lscroll = (packet[3] >> 5) & 1; 670 } 671 /* 672 * Processing wheel up/down and extra button events 673 */ 674 input_report_rel(dev, REL_WHEEL, 675 (int)(packet[3] & 8) - (int)(packet[3] & 7)); 676 input_report_rel(dev, REL_HWHEEL, lscroll - rscroll); 677 input_report_key(dev, BTN_BACK, lscroll); 678 input_report_key(dev, BTN_FORWARD, rscroll); 679 680 /* 681 * Standard PS/2 Mouse 682 */ 683 input_report_key(dev, BTN_LEFT, packet[0] & 1); 684 input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1); 685 input_report_key(dev, BTN_RIGHT, (packet[0] >> 1) & 1); 686 687 rel_x = packet[1] ? (int)packet[1] - (int)((packet[0] << 4) & 0x100) : 0; 688 rel_y = packet[2] ? (int)((packet[0] << 3) & 0x100) - (int)packet[2] : 0; 689 690 input_report_rel(dev, REL_X, rel_x); 691 input_report_rel(dev, REL_Y, rel_y); 692 break; 693 } 694 695 input_sync(dev); 696 697 fsp_packet_debug(packet); 698 699 return PSMOUSE_FULL_PACKET; 700 } 701 702 static int fsp_activate_protocol(struct psmouse *psmouse) 703 { 704 struct fsp_data *pad = psmouse->private; 705 struct ps2dev *ps2dev = &psmouse->ps2dev; 706 unsigned char param[2]; 707 int val; 708 709 /* 710 * Standard procedure to enter FSP Intellimouse mode 711 * (scrolling wheel, 4th and 5th buttons) 712 */ 713 param[0] = 200; 714 ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); 715 param[0] = 200; 716 ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); 717 param[0] = 80; 718 ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); 719 720 ps2_command(ps2dev, param, PSMOUSE_CMD_GETID); 721 if (param[0] != 0x04) { 722 dev_err(&psmouse->ps2dev.serio->dev, 723 "Unable to enable 4 bytes packet format.\n"); 724 return -EIO; 725 } 726 727 if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &val)) { 728 dev_err(&psmouse->ps2dev.serio->dev, 729 "Unable to read SYSCTL5 register.\n"); 730 return -EIO; 731 } 732 733 val &= ~(FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8 | FSP_BIT_EN_AUTO_MSID8); 734 /* Ensure we are not in absolute mode */ 735 val &= ~FSP_BIT_EN_PKT_G0; 736 if (pad->buttons == 0x06) { 737 /* Left/Middle/Right & Scroll Up/Down/Right/Left */ 738 val |= FSP_BIT_EN_MSID6; 739 } 740 741 if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, val)) { 742 dev_err(&psmouse->ps2dev.serio->dev, 743 "Unable to set up required mode bits.\n"); 744 return -EIO; 745 } 746 747 /* 748 * Enable OPC tags such that driver can tell the difference between 749 * on-pad and real button click 750 */ 751 if (fsp_opc_tag_enable(psmouse, true)) 752 dev_warn(&psmouse->ps2dev.serio->dev, 753 "Failed to enable OPC tag mode.\n"); 754 755 /* Enable on-pad vertical and horizontal scrolling */ 756 fsp_onpad_vscr(psmouse, true); 757 fsp_onpad_hscr(psmouse, true); 758 759 return 0; 760 } 761 762 int fsp_detect(struct psmouse *psmouse, bool set_properties) 763 { 764 int id; 765 766 if (fsp_reg_read(psmouse, FSP_REG_DEVICE_ID, &id)) 767 return -EIO; 768 769 if (id != 0x01) 770 return -ENODEV; 771 772 if (set_properties) { 773 psmouse->vendor = "Sentelic"; 774 psmouse->name = "FingerSensingPad"; 775 } 776 777 return 0; 778 } 779 780 static void fsp_reset(struct psmouse *psmouse) 781 { 782 fsp_opc_tag_enable(psmouse, false); 783 fsp_onpad_vscr(psmouse, false); 784 fsp_onpad_hscr(psmouse, false); 785 } 786 787 static void fsp_disconnect(struct psmouse *psmouse) 788 { 789 sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj, 790 &fsp_attribute_group); 791 792 fsp_reset(psmouse); 793 kfree(psmouse->private); 794 } 795 796 static int fsp_reconnect(struct psmouse *psmouse) 797 { 798 int version; 799 800 if (fsp_detect(psmouse, 0)) 801 return -ENODEV; 802 803 if (fsp_get_version(psmouse, &version)) 804 return -ENODEV; 805 806 if (fsp_activate_protocol(psmouse)) 807 return -EIO; 808 809 return 0; 810 } 811 812 int fsp_init(struct psmouse *psmouse) 813 { 814 struct fsp_data *priv; 815 int ver, rev, buttons; 816 int error; 817 818 if (fsp_get_version(psmouse, &ver) || 819 fsp_get_revision(psmouse, &rev) || 820 fsp_get_buttons(psmouse, &buttons)) { 821 return -ENODEV; 822 } 823 824 psmouse_info(psmouse, 825 "Finger Sensing Pad, hw: %d.%d.%d, sw: %s, buttons: %d\n", 826 ver >> 4, ver & 0x0F, rev, fsp_drv_ver, buttons & 7); 827 828 psmouse->private = priv = kzalloc(sizeof(struct fsp_data), GFP_KERNEL); 829 if (!priv) 830 return -ENOMEM; 831 832 priv->ver = ver; 833 priv->rev = rev; 834 priv->buttons = buttons; 835 836 /* enable on-pad click by default */ 837 priv->flags |= FSPDRV_FLAG_EN_OPC; 838 839 /* Set up various supported input event bits */ 840 __set_bit(BTN_MIDDLE, psmouse->dev->keybit); 841 __set_bit(BTN_BACK, psmouse->dev->keybit); 842 __set_bit(BTN_FORWARD, psmouse->dev->keybit); 843 __set_bit(REL_WHEEL, psmouse->dev->relbit); 844 __set_bit(REL_HWHEEL, psmouse->dev->relbit); 845 846 psmouse->protocol_handler = fsp_process_byte; 847 psmouse->disconnect = fsp_disconnect; 848 psmouse->reconnect = fsp_reconnect; 849 psmouse->cleanup = fsp_reset; 850 psmouse->pktsize = 4; 851 852 /* set default packet output based on number of buttons we found */ 853 error = fsp_activate_protocol(psmouse); 854 if (error) 855 goto err_out; 856 857 error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj, 858 &fsp_attribute_group); 859 if (error) { 860 dev_err(&psmouse->ps2dev.serio->dev, 861 "Failed to create sysfs attributes (%d)", error); 862 goto err_out; 863 } 864 865 return 0; 866 867 err_out: 868 kfree(psmouse->private); 869 psmouse->private = NULL; 870 return error; 871 } 872