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/version.h> 24 #include <linux/input.h> 25 #include <linux/ctype.h> 26 #include <linux/libps2.h> 27 #include <linux/serio.h> 28 #include <linux/jiffies.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 printk(KERN_DEBUG "%08dms PS/2 packets: %02x, %02x, %02x, %02x\n", 611 jiffies_msec, packet[0], packet[1], packet[2], packet[3]); 612 613 if (jiffies_msec - ps2_last_second > 1000) { 614 printk(KERN_DEBUG "PS/2 packets/sec = %d\n", ps2_packet_cnt); 615 ps2_packet_cnt = 0; 616 ps2_last_second = jiffies_msec; 617 } 618 } 619 #else 620 static void fsp_packet_debug(unsigned char packet[]) 621 { 622 } 623 #endif 624 625 static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse) 626 { 627 struct input_dev *dev = psmouse->dev; 628 struct fsp_data *ad = psmouse->private; 629 unsigned char *packet = psmouse->packet; 630 unsigned char button_status = 0, lscroll = 0, rscroll = 0; 631 int rel_x, rel_y; 632 633 if (psmouse->pktcnt < 4) 634 return PSMOUSE_GOOD_DATA; 635 636 /* 637 * Full packet accumulated, process it 638 */ 639 640 switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) { 641 case FSP_PKT_TYPE_ABS: 642 dev_warn(&psmouse->ps2dev.serio->dev, 643 "Unexpected absolute mode packet, ignored.\n"); 644 break; 645 646 case FSP_PKT_TYPE_NORMAL_OPC: 647 /* on-pad click, filter it if necessary */ 648 if ((ad->flags & FSPDRV_FLAG_EN_OPC) != FSPDRV_FLAG_EN_OPC) 649 packet[0] &= ~BIT(0); 650 /* fall through */ 651 652 case FSP_PKT_TYPE_NORMAL: 653 /* normal packet */ 654 /* special packet data translation from on-pad packets */ 655 if (packet[3] != 0) { 656 if (packet[3] & BIT(0)) 657 button_status |= 0x01; /* wheel down */ 658 if (packet[3] & BIT(1)) 659 button_status |= 0x0f; /* wheel up */ 660 if (packet[3] & BIT(2)) 661 button_status |= BIT(4);/* horizontal left */ 662 if (packet[3] & BIT(3)) 663 button_status |= BIT(5);/* horizontal right */ 664 /* push back to packet queue */ 665 if (button_status != 0) 666 packet[3] = button_status; 667 rscroll = (packet[3] >> 4) & 1; 668 lscroll = (packet[3] >> 5) & 1; 669 } 670 /* 671 * Processing wheel up/down and extra button events 672 */ 673 input_report_rel(dev, REL_WHEEL, 674 (int)(packet[3] & 8) - (int)(packet[3] & 7)); 675 input_report_rel(dev, REL_HWHEEL, lscroll - rscroll); 676 input_report_key(dev, BTN_BACK, lscroll); 677 input_report_key(dev, BTN_FORWARD, rscroll); 678 679 /* 680 * Standard PS/2 Mouse 681 */ 682 input_report_key(dev, BTN_LEFT, packet[0] & 1); 683 input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1); 684 input_report_key(dev, BTN_RIGHT, (packet[0] >> 1) & 1); 685 686 rel_x = packet[1] ? (int)packet[1] - (int)((packet[0] << 4) & 0x100) : 0; 687 rel_y = packet[2] ? (int)((packet[0] << 3) & 0x100) - (int)packet[2] : 0; 688 689 input_report_rel(dev, REL_X, rel_x); 690 input_report_rel(dev, REL_Y, rel_y); 691 break; 692 } 693 694 input_sync(dev); 695 696 fsp_packet_debug(packet); 697 698 return PSMOUSE_FULL_PACKET; 699 } 700 701 static int fsp_activate_protocol(struct psmouse *psmouse) 702 { 703 struct fsp_data *pad = psmouse->private; 704 struct ps2dev *ps2dev = &psmouse->ps2dev; 705 unsigned char param[2]; 706 int val; 707 708 /* 709 * Standard procedure to enter FSP Intellimouse mode 710 * (scrolling wheel, 4th and 5th buttons) 711 */ 712 param[0] = 200; 713 ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); 714 param[0] = 200; 715 ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); 716 param[0] = 80; 717 ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); 718 719 ps2_command(ps2dev, param, PSMOUSE_CMD_GETID); 720 if (param[0] != 0x04) { 721 dev_err(&psmouse->ps2dev.serio->dev, 722 "Unable to enable 4 bytes packet format.\n"); 723 return -EIO; 724 } 725 726 if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &val)) { 727 dev_err(&psmouse->ps2dev.serio->dev, 728 "Unable to read SYSCTL5 register.\n"); 729 return -EIO; 730 } 731 732 val &= ~(FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8 | FSP_BIT_EN_AUTO_MSID8); 733 /* Ensure we are not in absolute mode */ 734 val &= ~FSP_BIT_EN_PKT_G0; 735 if (pad->buttons == 0x06) { 736 /* Left/Middle/Right & Scroll Up/Down/Right/Left */ 737 val |= FSP_BIT_EN_MSID6; 738 } 739 740 if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, val)) { 741 dev_err(&psmouse->ps2dev.serio->dev, 742 "Unable to set up required mode bits.\n"); 743 return -EIO; 744 } 745 746 /* 747 * Enable OPC tags such that driver can tell the difference between 748 * on-pad and real button click 749 */ 750 if (fsp_opc_tag_enable(psmouse, true)) 751 dev_warn(&psmouse->ps2dev.serio->dev, 752 "Failed to enable OPC tag mode.\n"); 753 754 /* Enable on-pad vertical and horizontal scrolling */ 755 fsp_onpad_vscr(psmouse, true); 756 fsp_onpad_hscr(psmouse, true); 757 758 return 0; 759 } 760 761 int fsp_detect(struct psmouse *psmouse, bool set_properties) 762 { 763 int id; 764 765 if (fsp_reg_read(psmouse, FSP_REG_DEVICE_ID, &id)) 766 return -EIO; 767 768 if (id != 0x01) 769 return -ENODEV; 770 771 if (set_properties) { 772 psmouse->vendor = "Sentelic"; 773 psmouse->name = "FingerSensingPad"; 774 } 775 776 return 0; 777 } 778 779 static void fsp_reset(struct psmouse *psmouse) 780 { 781 fsp_opc_tag_enable(psmouse, false); 782 fsp_onpad_vscr(psmouse, false); 783 fsp_onpad_hscr(psmouse, false); 784 } 785 786 static void fsp_disconnect(struct psmouse *psmouse) 787 { 788 sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj, 789 &fsp_attribute_group); 790 791 fsp_reset(psmouse); 792 kfree(psmouse->private); 793 } 794 795 static int fsp_reconnect(struct psmouse *psmouse) 796 { 797 int version; 798 799 if (fsp_detect(psmouse, 0)) 800 return -ENODEV; 801 802 if (fsp_get_version(psmouse, &version)) 803 return -ENODEV; 804 805 if (fsp_activate_protocol(psmouse)) 806 return -EIO; 807 808 return 0; 809 } 810 811 int fsp_init(struct psmouse *psmouse) 812 { 813 struct fsp_data *priv; 814 int ver, rev, buttons; 815 int error; 816 817 if (fsp_get_version(psmouse, &ver) || 818 fsp_get_revision(psmouse, &rev) || 819 fsp_get_buttons(psmouse, &buttons)) { 820 return -ENODEV; 821 } 822 823 printk(KERN_INFO 824 "Finger Sensing Pad, hw: %d.%d.%d, sw: %s, buttons: %d\n", 825 ver >> 4, ver & 0x0F, rev, fsp_drv_ver, buttons & 7); 826 827 psmouse->private = priv = kzalloc(sizeof(struct fsp_data), GFP_KERNEL); 828 if (!priv) 829 return -ENOMEM; 830 831 priv->ver = ver; 832 priv->rev = rev; 833 priv->buttons = buttons; 834 835 /* enable on-pad click by default */ 836 priv->flags |= FSPDRV_FLAG_EN_OPC; 837 838 /* Set up various supported input event bits */ 839 __set_bit(BTN_MIDDLE, psmouse->dev->keybit); 840 __set_bit(BTN_BACK, psmouse->dev->keybit); 841 __set_bit(BTN_FORWARD, psmouse->dev->keybit); 842 __set_bit(REL_WHEEL, psmouse->dev->relbit); 843 __set_bit(REL_HWHEEL, psmouse->dev->relbit); 844 845 psmouse->protocol_handler = fsp_process_byte; 846 psmouse->disconnect = fsp_disconnect; 847 psmouse->reconnect = fsp_reconnect; 848 psmouse->cleanup = fsp_reset; 849 psmouse->pktsize = 4; 850 851 /* set default packet output based on number of buttons we found */ 852 error = fsp_activate_protocol(psmouse); 853 if (error) 854 goto err_out; 855 856 error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj, 857 &fsp_attribute_group); 858 if (error) { 859 dev_err(&psmouse->ps2dev.serio->dev, 860 "Failed to create sysfs attributes (%d)", error); 861 goto err_out; 862 } 863 864 return 0; 865 866 err_out: 867 kfree(psmouse->private); 868 psmouse->private = NULL; 869 return error; 870 } 871