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 #include <linux/slab.h> 30 31 #include "psmouse.h" 32 #include "sentelic.h" 33 34 /* 35 * Timeout for FSP PS/2 command only (in milliseconds). 36 */ 37 #define FSP_CMD_TIMEOUT 200 38 #define FSP_CMD_TIMEOUT2 30 39 40 /** Driver version. */ 41 static const char fsp_drv_ver[] = "1.0.0-K"; 42 43 /* 44 * Make sure that the value being sent to FSP will not conflict with 45 * possible sample rate values. 46 */ 47 static unsigned char fsp_test_swap_cmd(unsigned char reg_val) 48 { 49 switch (reg_val) { 50 case 10: case 20: case 40: case 60: case 80: case 100: case 200: 51 /* 52 * The requested value being sent to FSP matched to possible 53 * sample rates, swap the given value such that the hardware 54 * wouldn't get confused. 55 */ 56 return (reg_val >> 4) | (reg_val << 4); 57 default: 58 return reg_val; /* swap isn't necessary */ 59 } 60 } 61 62 /* 63 * Make sure that the value being sent to FSP will not conflict with certain 64 * commands. 65 */ 66 static unsigned char fsp_test_invert_cmd(unsigned char reg_val) 67 { 68 switch (reg_val) { 69 case 0xe9: case 0xee: case 0xf2: case 0xff: 70 /* 71 * The requested value being sent to FSP matched to certain 72 * commands, inverse the given value such that the hardware 73 * wouldn't get confused. 74 */ 75 return ~reg_val; 76 default: 77 return reg_val; /* inversion isn't necessary */ 78 } 79 } 80 81 static int fsp_reg_read(struct psmouse *psmouse, int reg_addr, int *reg_val) 82 { 83 struct ps2dev *ps2dev = &psmouse->ps2dev; 84 unsigned char param[3]; 85 unsigned char addr; 86 int rc = -1; 87 88 /* 89 * We need to shut off the device and switch it into command 90 * mode so we don't confuse our protocol handler. We don't need 91 * to do that for writes because sysfs set helper does this for 92 * us. 93 */ 94 ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE); 95 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); 96 97 ps2_begin_command(ps2dev); 98 99 if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) 100 goto out; 101 102 /* should return 0xfe(request for resending) */ 103 ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2); 104 /* should return 0xfc(failed) */ 105 ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2); 106 107 if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) 108 goto out; 109 110 if ((addr = fsp_test_invert_cmd(reg_addr)) != reg_addr) { 111 ps2_sendbyte(ps2dev, 0x68, FSP_CMD_TIMEOUT2); 112 } else if ((addr = fsp_test_swap_cmd(reg_addr)) != reg_addr) { 113 /* swapping is required */ 114 ps2_sendbyte(ps2dev, 0xcc, FSP_CMD_TIMEOUT2); 115 /* expect 0xfe */ 116 } else { 117 /* swapping isn't necessary */ 118 ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2); 119 /* expect 0xfe */ 120 } 121 /* should return 0xfc(failed) */ 122 ps2_sendbyte(ps2dev, addr, FSP_CMD_TIMEOUT); 123 124 if (__ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO) < 0) 125 goto out; 126 127 *reg_val = param[2]; 128 rc = 0; 129 130 out: 131 ps2_end_command(ps2dev); 132 ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE); 133 psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); 134 dev_dbg(&ps2dev->serio->dev, "READ REG: 0x%02x is 0x%02x (rc = %d)\n", 135 reg_addr, *reg_val, rc); 136 return rc; 137 } 138 139 static int fsp_reg_write(struct psmouse *psmouse, int reg_addr, int reg_val) 140 { 141 struct ps2dev *ps2dev = &psmouse->ps2dev; 142 unsigned char v; 143 int rc = -1; 144 145 ps2_begin_command(ps2dev); 146 147 if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) 148 goto out; 149 150 if ((v = fsp_test_invert_cmd(reg_addr)) != reg_addr) { 151 /* inversion is required */ 152 ps2_sendbyte(ps2dev, 0x74, FSP_CMD_TIMEOUT2); 153 } else { 154 if ((v = fsp_test_swap_cmd(reg_addr)) != reg_addr) { 155 /* swapping is required */ 156 ps2_sendbyte(ps2dev, 0x77, FSP_CMD_TIMEOUT2); 157 } else { 158 /* swapping isn't necessary */ 159 ps2_sendbyte(ps2dev, 0x55, FSP_CMD_TIMEOUT2); 160 } 161 } 162 /* write the register address in correct order */ 163 ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2); 164 165 if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) 166 return -1; 167 168 if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) { 169 /* inversion is required */ 170 ps2_sendbyte(ps2dev, 0x47, FSP_CMD_TIMEOUT2); 171 } else if ((v = fsp_test_swap_cmd(reg_val)) != reg_val) { 172 /* swapping is required */ 173 ps2_sendbyte(ps2dev, 0x44, FSP_CMD_TIMEOUT2); 174 } else { 175 /* swapping isn't necessary */ 176 ps2_sendbyte(ps2dev, 0x33, FSP_CMD_TIMEOUT2); 177 } 178 179 /* write the register value in correct order */ 180 ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2); 181 rc = 0; 182 183 out: 184 ps2_end_command(ps2dev); 185 dev_dbg(&ps2dev->serio->dev, "WRITE REG: 0x%02x to 0x%02x (rc = %d)\n", 186 reg_addr, reg_val, rc); 187 return rc; 188 } 189 190 /* Enable register clock gating for writing certain registers */ 191 static int fsp_reg_write_enable(struct psmouse *psmouse, bool enable) 192 { 193 int v, nv; 194 195 if (fsp_reg_read(psmouse, FSP_REG_SYSCTL1, &v) == -1) 196 return -1; 197 198 if (enable) 199 nv = v | FSP_BIT_EN_REG_CLK; 200 else 201 nv = v & ~FSP_BIT_EN_REG_CLK; 202 203 /* only write if necessary */ 204 if (nv != v) 205 if (fsp_reg_write(psmouse, FSP_REG_SYSCTL1, nv) == -1) 206 return -1; 207 208 return 0; 209 } 210 211 static int fsp_page_reg_read(struct psmouse *psmouse, int *reg_val) 212 { 213 struct ps2dev *ps2dev = &psmouse->ps2dev; 214 unsigned char param[3]; 215 int rc = -1; 216 217 ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE); 218 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); 219 220 ps2_begin_command(ps2dev); 221 222 if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) 223 goto out; 224 225 ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2); 226 ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2); 227 228 if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) 229 goto out; 230 231 ps2_sendbyte(ps2dev, 0x83, FSP_CMD_TIMEOUT2); 232 ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2); 233 234 /* get the returned result */ 235 if (__ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) 236 goto out; 237 238 *reg_val = param[2]; 239 rc = 0; 240 241 out: 242 ps2_end_command(ps2dev); 243 ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE); 244 psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); 245 dev_dbg(&ps2dev->serio->dev, "READ PAGE REG: 0x%02x (rc = %d)\n", 246 *reg_val, rc); 247 return rc; 248 } 249 250 static int fsp_page_reg_write(struct psmouse *psmouse, int reg_val) 251 { 252 struct ps2dev *ps2dev = &psmouse->ps2dev; 253 unsigned char v; 254 int rc = -1; 255 256 ps2_begin_command(ps2dev); 257 258 if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) 259 goto out; 260 261 ps2_sendbyte(ps2dev, 0x38, FSP_CMD_TIMEOUT2); 262 ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2); 263 264 if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) 265 return -1; 266 267 if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) { 268 ps2_sendbyte(ps2dev, 0x47, FSP_CMD_TIMEOUT2); 269 } else if ((v = fsp_test_swap_cmd(reg_val)) != reg_val) { 270 /* swapping is required */ 271 ps2_sendbyte(ps2dev, 0x44, FSP_CMD_TIMEOUT2); 272 } else { 273 /* swapping isn't necessary */ 274 ps2_sendbyte(ps2dev, 0x33, FSP_CMD_TIMEOUT2); 275 } 276 277 ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2); 278 rc = 0; 279 280 out: 281 ps2_end_command(ps2dev); 282 dev_dbg(&ps2dev->serio->dev, "WRITE PAGE REG: to 0x%02x (rc = %d)\n", 283 reg_val, rc); 284 return rc; 285 } 286 287 static int fsp_get_version(struct psmouse *psmouse, int *version) 288 { 289 if (fsp_reg_read(psmouse, FSP_REG_VERSION, version)) 290 return -EIO; 291 292 return 0; 293 } 294 295 static int fsp_get_revision(struct psmouse *psmouse, int *rev) 296 { 297 if (fsp_reg_read(psmouse, FSP_REG_REVISION, rev)) 298 return -EIO; 299 300 return 0; 301 } 302 303 static int fsp_get_buttons(struct psmouse *psmouse, int *btn) 304 { 305 static const int buttons[] = { 306 0x16, /* Left/Middle/Right/Forward/Backward & Scroll Up/Down */ 307 0x06, /* Left/Middle/Right & Scroll Up/Down/Right/Left */ 308 0x04, /* Left/Middle/Right & Scroll Up/Down */ 309 0x02, /* Left/Middle/Right */ 310 }; 311 int val; 312 313 if (fsp_reg_read(psmouse, FSP_REG_TMOD_STATUS1, &val) == -1) 314 return -EIO; 315 316 *btn = buttons[(val & 0x30) >> 4]; 317 return 0; 318 } 319 320 /* Enable on-pad command tag output */ 321 static int fsp_opc_tag_enable(struct psmouse *psmouse, bool enable) 322 { 323 int v, nv; 324 int res = 0; 325 326 if (fsp_reg_read(psmouse, FSP_REG_OPC_QDOWN, &v) == -1) { 327 dev_err(&psmouse->ps2dev.serio->dev, "Unable get OPC state.\n"); 328 return -EIO; 329 } 330 331 if (enable) 332 nv = v | FSP_BIT_EN_OPC_TAG; 333 else 334 nv = v & ~FSP_BIT_EN_OPC_TAG; 335 336 /* only write if necessary */ 337 if (nv != v) { 338 fsp_reg_write_enable(psmouse, true); 339 res = fsp_reg_write(psmouse, FSP_REG_OPC_QDOWN, nv); 340 fsp_reg_write_enable(psmouse, false); 341 } 342 343 if (res != 0) { 344 dev_err(&psmouse->ps2dev.serio->dev, 345 "Unable to enable OPC tag.\n"); 346 res = -EIO; 347 } 348 349 return res; 350 } 351 352 static int fsp_onpad_vscr(struct psmouse *psmouse, bool enable) 353 { 354 struct fsp_data *pad = psmouse->private; 355 int val; 356 357 if (fsp_reg_read(psmouse, FSP_REG_ONPAD_CTL, &val)) 358 return -EIO; 359 360 pad->vscroll = enable; 361 362 if (enable) 363 val |= (FSP_BIT_FIX_VSCR | FSP_BIT_ONPAD_ENABLE); 364 else 365 val &= ~FSP_BIT_FIX_VSCR; 366 367 if (fsp_reg_write(psmouse, FSP_REG_ONPAD_CTL, val)) 368 return -EIO; 369 370 return 0; 371 } 372 373 static int fsp_onpad_hscr(struct psmouse *psmouse, bool enable) 374 { 375 struct fsp_data *pad = psmouse->private; 376 int val, v2; 377 378 if (fsp_reg_read(psmouse, FSP_REG_ONPAD_CTL, &val)) 379 return -EIO; 380 381 if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &v2)) 382 return -EIO; 383 384 pad->hscroll = enable; 385 386 if (enable) { 387 val |= (FSP_BIT_FIX_HSCR | FSP_BIT_ONPAD_ENABLE); 388 v2 |= FSP_BIT_EN_MSID6; 389 } else { 390 val &= ~FSP_BIT_FIX_HSCR; 391 v2 &= ~(FSP_BIT_EN_MSID6 | FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8); 392 } 393 394 if (fsp_reg_write(psmouse, FSP_REG_ONPAD_CTL, val)) 395 return -EIO; 396 397 /* reconfigure horizontal scrolling packet output */ 398 if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, v2)) 399 return -EIO; 400 401 return 0; 402 } 403 404 /* 405 * Write device specific initial parameters. 406 * 407 * ex: 0xab 0xcd - write oxcd into register 0xab 408 */ 409 static ssize_t fsp_attr_set_setreg(struct psmouse *psmouse, void *data, 410 const char *buf, size_t count) 411 { 412 unsigned long reg, val; 413 char *rest; 414 ssize_t retval; 415 416 reg = simple_strtoul(buf, &rest, 16); 417 if (rest == buf || *rest != ' ' || reg > 0xff) 418 return -EINVAL; 419 420 if (strict_strtoul(rest + 1, 16, &val) || val > 0xff) 421 return -EINVAL; 422 423 if (fsp_reg_write_enable(psmouse, true)) 424 return -EIO; 425 426 retval = fsp_reg_write(psmouse, reg, val) < 0 ? -EIO : count; 427 428 fsp_reg_write_enable(psmouse, false); 429 430 return count; 431 } 432 433 PSMOUSE_DEFINE_WO_ATTR(setreg, S_IWUSR, NULL, fsp_attr_set_setreg); 434 435 static ssize_t fsp_attr_show_getreg(struct psmouse *psmouse, 436 void *data, char *buf) 437 { 438 struct fsp_data *pad = psmouse->private; 439 440 return sprintf(buf, "%02x%02x\n", pad->last_reg, pad->last_val); 441 } 442 443 /* 444 * Read a register from device. 445 * 446 * ex: 0xab -- read content from register 0xab 447 */ 448 static ssize_t fsp_attr_set_getreg(struct psmouse *psmouse, void *data, 449 const char *buf, size_t count) 450 { 451 struct fsp_data *pad = psmouse->private; 452 unsigned long reg; 453 int val; 454 455 if (strict_strtoul(buf, 16, ®) || reg > 0xff) 456 return -EINVAL; 457 458 if (fsp_reg_read(psmouse, reg, &val)) 459 return -EIO; 460 461 pad->last_reg = reg; 462 pad->last_val = val; 463 464 return count; 465 } 466 467 PSMOUSE_DEFINE_ATTR(getreg, S_IWUSR | S_IRUGO, NULL, 468 fsp_attr_show_getreg, fsp_attr_set_getreg); 469 470 static ssize_t fsp_attr_show_pagereg(struct psmouse *psmouse, 471 void *data, char *buf) 472 { 473 int val = 0; 474 475 if (fsp_page_reg_read(psmouse, &val)) 476 return -EIO; 477 478 return sprintf(buf, "%02x\n", val); 479 } 480 481 static ssize_t fsp_attr_set_pagereg(struct psmouse *psmouse, void *data, 482 const char *buf, size_t count) 483 { 484 unsigned long val; 485 486 if (strict_strtoul(buf, 16, &val) || val > 0xff) 487 return -EINVAL; 488 489 if (fsp_page_reg_write(psmouse, val)) 490 return -EIO; 491 492 return count; 493 } 494 495 PSMOUSE_DEFINE_ATTR(page, S_IWUSR | S_IRUGO, NULL, 496 fsp_attr_show_pagereg, fsp_attr_set_pagereg); 497 498 static ssize_t fsp_attr_show_vscroll(struct psmouse *psmouse, 499 void *data, char *buf) 500 { 501 struct fsp_data *pad = psmouse->private; 502 503 return sprintf(buf, "%d\n", pad->vscroll); 504 } 505 506 static ssize_t fsp_attr_set_vscroll(struct psmouse *psmouse, void *data, 507 const char *buf, size_t count) 508 { 509 unsigned long val; 510 511 if (strict_strtoul(buf, 10, &val) || val > 1) 512 return -EINVAL; 513 514 fsp_onpad_vscr(psmouse, val); 515 516 return count; 517 } 518 519 PSMOUSE_DEFINE_ATTR(vscroll, S_IWUSR | S_IRUGO, NULL, 520 fsp_attr_show_vscroll, fsp_attr_set_vscroll); 521 522 static ssize_t fsp_attr_show_hscroll(struct psmouse *psmouse, 523 void *data, char *buf) 524 { 525 struct fsp_data *pad = psmouse->private; 526 527 return sprintf(buf, "%d\n", pad->hscroll); 528 } 529 530 static ssize_t fsp_attr_set_hscroll(struct psmouse *psmouse, void *data, 531 const char *buf, size_t count) 532 { 533 unsigned long val; 534 535 if (strict_strtoul(buf, 10, &val) || val > 1) 536 return -EINVAL; 537 538 fsp_onpad_hscr(psmouse, val); 539 540 return count; 541 } 542 543 PSMOUSE_DEFINE_ATTR(hscroll, S_IWUSR | S_IRUGO, NULL, 544 fsp_attr_show_hscroll, fsp_attr_set_hscroll); 545 546 static ssize_t fsp_attr_show_flags(struct psmouse *psmouse, 547 void *data, char *buf) 548 { 549 struct fsp_data *pad = psmouse->private; 550 551 return sprintf(buf, "%c\n", 552 pad->flags & FSPDRV_FLAG_EN_OPC ? 'C' : 'c'); 553 } 554 555 static ssize_t fsp_attr_set_flags(struct psmouse *psmouse, void *data, 556 const char *buf, size_t count) 557 { 558 struct fsp_data *pad = psmouse->private; 559 size_t i; 560 561 for (i = 0; i < count; i++) { 562 switch (buf[i]) { 563 case 'C': 564 pad->flags |= FSPDRV_FLAG_EN_OPC; 565 break; 566 case 'c': 567 pad->flags &= ~FSPDRV_FLAG_EN_OPC; 568 break; 569 default: 570 return -EINVAL; 571 } 572 } 573 return count; 574 } 575 576 PSMOUSE_DEFINE_ATTR(flags, S_IWUSR | S_IRUGO, NULL, 577 fsp_attr_show_flags, fsp_attr_set_flags); 578 579 static ssize_t fsp_attr_show_ver(struct psmouse *psmouse, 580 void *data, char *buf) 581 { 582 return sprintf(buf, "Sentelic FSP kernel module %s\n", fsp_drv_ver); 583 } 584 585 PSMOUSE_DEFINE_RO_ATTR(ver, S_IRUGO, NULL, fsp_attr_show_ver); 586 587 static struct attribute *fsp_attributes[] = { 588 &psmouse_attr_setreg.dattr.attr, 589 &psmouse_attr_getreg.dattr.attr, 590 &psmouse_attr_page.dattr.attr, 591 &psmouse_attr_vscroll.dattr.attr, 592 &psmouse_attr_hscroll.dattr.attr, 593 &psmouse_attr_flags.dattr.attr, 594 &psmouse_attr_ver.dattr.attr, 595 NULL 596 }; 597 598 static struct attribute_group fsp_attribute_group = { 599 .attrs = fsp_attributes, 600 }; 601 602 #ifdef FSP_DEBUG 603 static void fsp_packet_debug(unsigned char packet[]) 604 { 605 static unsigned int ps2_packet_cnt; 606 static unsigned int ps2_last_second; 607 unsigned int jiffies_msec; 608 609 ps2_packet_cnt++; 610 jiffies_msec = jiffies_to_msecs(jiffies); 611 printk(KERN_DEBUG "%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 printk(KERN_DEBUG "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 printk(KERN_INFO 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