linux/drivers/input/mouse/sentelic.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*-
   3 * Finger Sensing Pad PS/2 mouse driver.
   4 *
   5 * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd.
   6 * Copyright (C) 2005-2012 Tai-hwa Liang, Sentelic Corporation.
   7 */
   8
   9#include <linux/module.h>
  10#include <linux/input.h>
  11#include <linux/input/mt.h>
  12#include <linux/ctype.h>
  13#include <linux/libps2.h>
  14#include <linux/serio.h>
  15#include <linux/jiffies.h>
  16#include <linux/slab.h>
  17
  18#include "psmouse.h"
  19#include "sentelic.h"
  20
  21/*
  22 * Timeout for FSP PS/2 command only (in milliseconds).
  23 */
  24#define FSP_CMD_TIMEOUT         200
  25#define FSP_CMD_TIMEOUT2        30
  26
  27#define GET_ABS_X(packet)       ((packet[1] << 2) | ((packet[3] >> 2) & 0x03))
  28#define GET_ABS_Y(packet)       ((packet[2] << 2) | (packet[3] & 0x03))
  29
  30/** Driver version. */
  31static const char fsp_drv_ver[] = "1.1.0-K";
  32
  33/*
  34 * Make sure that the value being sent to FSP will not conflict with
  35 * possible sample rate values.
  36 */
  37static unsigned char fsp_test_swap_cmd(unsigned char reg_val)
  38{
  39        switch (reg_val) {
  40        case 10: case 20: case 40: case 60: case 80: case 100: case 200:
  41                /*
  42                 * The requested value being sent to FSP matched to possible
  43                 * sample rates, swap the given value such that the hardware
  44                 * wouldn't get confused.
  45                 */
  46                return (reg_val >> 4) | (reg_val << 4);
  47        default:
  48                return reg_val; /* swap isn't necessary */
  49        }
  50}
  51
  52/*
  53 * Make sure that the value being sent to FSP will not conflict with certain
  54 * commands.
  55 */
  56static unsigned char fsp_test_invert_cmd(unsigned char reg_val)
  57{
  58        switch (reg_val) {
  59        case 0xe9: case 0xee: case 0xf2: case 0xff:
  60                /*
  61                 * The requested value being sent to FSP matched to certain
  62                 * commands, inverse the given value such that the hardware
  63                 * wouldn't get confused.
  64                 */
  65                return ~reg_val;
  66        default:
  67                return reg_val; /* inversion isn't necessary */
  68        }
  69}
  70
  71static int fsp_reg_read(struct psmouse *psmouse, int reg_addr, int *reg_val)
  72{
  73        struct ps2dev *ps2dev = &psmouse->ps2dev;
  74        unsigned char param[3];
  75        unsigned char addr;
  76        int rc = -1;
  77
  78        /*
  79         * We need to shut off the device and switch it into command
  80         * mode so we don't confuse our protocol handler. We don't need
  81         * to do that for writes because sysfs set helper does this for
  82         * us.
  83         */
  84        psmouse_deactivate(psmouse);
  85
  86        ps2_begin_command(ps2dev);
  87
  88        if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
  89                goto out;
  90
  91        /* should return 0xfe(request for resending) */
  92        ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2);
  93        /* should return 0xfc(failed) */
  94        ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
  95
  96        if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
  97                goto out;
  98
  99        if ((addr = fsp_test_invert_cmd(reg_addr)) != reg_addr) {
 100                ps2_sendbyte(ps2dev, 0x68, FSP_CMD_TIMEOUT2);
 101        } else if ((addr = fsp_test_swap_cmd(reg_addr)) != reg_addr) {
 102                /* swapping is required */
 103                ps2_sendbyte(ps2dev, 0xcc, FSP_CMD_TIMEOUT2);
 104                /* expect 0xfe */
 105        } else {
 106                /* swapping isn't necessary */
 107                ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2);
 108                /* expect 0xfe */
 109        }
 110        /* should return 0xfc(failed) */
 111        ps2_sendbyte(ps2dev, addr, FSP_CMD_TIMEOUT);
 112
 113        if (__ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO) < 0)
 114                goto out;
 115
 116        *reg_val = param[2];
 117        rc = 0;
 118
 119 out:
 120        ps2_end_command(ps2dev);
 121        psmouse_activate(psmouse);
 122        psmouse_dbg(psmouse,
 123                    "READ REG: 0x%02x is 0x%02x (rc = %d)\n",
 124                    reg_addr, *reg_val, rc);
 125        return rc;
 126}
 127
 128static int fsp_reg_write(struct psmouse *psmouse, int reg_addr, int reg_val)
 129{
 130        struct ps2dev *ps2dev = &psmouse->ps2dev;
 131        unsigned char v;
 132        int rc = -1;
 133
 134        ps2_begin_command(ps2dev);
 135
 136        if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
 137                goto out;
 138
 139        if ((v = fsp_test_invert_cmd(reg_addr)) != reg_addr) {
 140                /* inversion is required */
 141                ps2_sendbyte(ps2dev, 0x74, FSP_CMD_TIMEOUT2);
 142        } else {
 143                if ((v = fsp_test_swap_cmd(reg_addr)) != reg_addr) {
 144                        /* swapping is required */
 145                        ps2_sendbyte(ps2dev, 0x77, FSP_CMD_TIMEOUT2);
 146                } else {
 147                        /* swapping isn't necessary */
 148                        ps2_sendbyte(ps2dev, 0x55, FSP_CMD_TIMEOUT2);
 149                }
 150        }
 151        /* write the register address in correct order */
 152        ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2);
 153
 154        if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
 155                goto out;
 156
 157        if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) {
 158                /* inversion is required */
 159                ps2_sendbyte(ps2dev, 0x47, FSP_CMD_TIMEOUT2);
 160        } else if ((v = fsp_test_swap_cmd(reg_val)) != reg_val) {
 161                /* swapping is required */
 162                ps2_sendbyte(ps2dev, 0x44, FSP_CMD_TIMEOUT2);
 163        } else {
 164                /* swapping isn't necessary */
 165                ps2_sendbyte(ps2dev, 0x33, FSP_CMD_TIMEOUT2);
 166        }
 167
 168        /* write the register value in correct order */
 169        ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2);
 170        rc = 0;
 171
 172 out:
 173        ps2_end_command(ps2dev);
 174        psmouse_dbg(psmouse,
 175                    "WRITE REG: 0x%02x to 0x%02x (rc = %d)\n",
 176                    reg_addr, reg_val, rc);
 177        return rc;
 178}
 179
 180/* Enable register clock gating for writing certain registers */
 181static int fsp_reg_write_enable(struct psmouse *psmouse, bool enable)
 182{
 183        int v, nv;
 184
 185        if (fsp_reg_read(psmouse, FSP_REG_SYSCTL1, &v) == -1)
 186                return -1;
 187
 188        if (enable)
 189                nv = v | FSP_BIT_EN_REG_CLK;
 190        else
 191                nv = v & ~FSP_BIT_EN_REG_CLK;
 192
 193        /* only write if necessary */
 194        if (nv != v)
 195                if (fsp_reg_write(psmouse, FSP_REG_SYSCTL1, nv) == -1)
 196                        return -1;
 197
 198        return 0;
 199}
 200
 201static int fsp_page_reg_read(struct psmouse *psmouse, int *reg_val)
 202{
 203        struct ps2dev *ps2dev = &psmouse->ps2dev;
 204        unsigned char param[3];
 205        int rc = -1;
 206
 207        psmouse_deactivate(psmouse);
 208
 209        ps2_begin_command(ps2dev);
 210
 211        if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
 212                goto out;
 213
 214        ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2);
 215        ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
 216
 217        if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
 218                goto out;
 219
 220        ps2_sendbyte(ps2dev, 0x83, FSP_CMD_TIMEOUT2);
 221        ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
 222
 223        /* get the returned result */
 224        if (__ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
 225                goto out;
 226
 227        *reg_val = param[2];
 228        rc = 0;
 229
 230 out:
 231        ps2_end_command(ps2dev);
 232        psmouse_activate(psmouse);
 233        psmouse_dbg(psmouse,
 234                    "READ PAGE REG: 0x%02x (rc = %d)\n",
 235                    *reg_val, rc);
 236        return rc;
 237}
 238
 239static int fsp_page_reg_write(struct psmouse *psmouse, int reg_val)
 240{
 241        struct ps2dev *ps2dev = &psmouse->ps2dev;
 242        unsigned char v;
 243        int rc = -1;
 244
 245        ps2_begin_command(ps2dev);
 246
 247        if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
 248                goto out;
 249
 250        ps2_sendbyte(ps2dev, 0x38, FSP_CMD_TIMEOUT2);
 251        ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
 252
 253        if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
 254                goto out;
 255
 256        if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) {
 257                ps2_sendbyte(ps2dev, 0x47, FSP_CMD_TIMEOUT2);
 258        } else if ((v = fsp_test_swap_cmd(reg_val)) != reg_val) {
 259                /* swapping is required */
 260                ps2_sendbyte(ps2dev, 0x44, FSP_CMD_TIMEOUT2);
 261        } else {
 262                /* swapping isn't necessary */
 263                ps2_sendbyte(ps2dev, 0x33, FSP_CMD_TIMEOUT2);
 264        }
 265
 266        ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2);
 267        rc = 0;
 268
 269 out:
 270        ps2_end_command(ps2dev);
 271        psmouse_dbg(psmouse,
 272                    "WRITE PAGE REG: to 0x%02x (rc = %d)\n",
 273                    reg_val, rc);
 274        return rc;
 275}
 276
 277static int fsp_get_version(struct psmouse *psmouse, int *version)
 278{
 279        if (fsp_reg_read(psmouse, FSP_REG_VERSION, version))
 280                return -EIO;
 281
 282        return 0;
 283}
 284
 285static int fsp_get_revision(struct psmouse *psmouse, int *rev)
 286{
 287        if (fsp_reg_read(psmouse, FSP_REG_REVISION, rev))
 288                return -EIO;
 289
 290        return 0;
 291}
 292
 293static int fsp_get_sn(struct psmouse *psmouse, int *sn)
 294{
 295        int v0, v1, v2;
 296        int rc = -EIO;
 297
 298        /* production number since Cx is available at: 0x0b40 ~ 0x0b42 */
 299        if (fsp_page_reg_write(psmouse, FSP_PAGE_0B))
 300                goto out;
 301        if (fsp_reg_read(psmouse, FSP_REG_SN0, &v0))
 302                goto out;
 303        if (fsp_reg_read(psmouse, FSP_REG_SN1, &v1))
 304                goto out;
 305        if (fsp_reg_read(psmouse, FSP_REG_SN2, &v2))
 306                goto out;
 307        *sn = (v0 << 16) | (v1 << 8) | v2;
 308        rc = 0;
 309out:
 310        fsp_page_reg_write(psmouse, FSP_PAGE_DEFAULT);
 311        return rc;
 312}
 313
 314static int fsp_get_buttons(struct psmouse *psmouse, int *btn)
 315{
 316        static const int buttons[] = {
 317                0x16, /* Left/Middle/Right/Forward/Backward & Scroll Up/Down */
 318                0x06, /* Left/Middle/Right & Scroll Up/Down/Right/Left */
 319                0x04, /* Left/Middle/Right & Scroll Up/Down */
 320                0x02, /* Left/Middle/Right */
 321        };
 322        int val;
 323
 324        if (fsp_reg_read(psmouse, FSP_REG_TMOD_STATUS, &val) == -1)
 325                return -EIO;
 326
 327        *btn = buttons[(val & 0x30) >> 4];
 328        return 0;
 329}
 330
 331/* Enable on-pad command tag output */
 332static int fsp_opc_tag_enable(struct psmouse *psmouse, bool enable)
 333{
 334        int v, nv;
 335        int res = 0;
 336
 337        if (fsp_reg_read(psmouse, FSP_REG_OPC_QDOWN, &v) == -1) {
 338                psmouse_err(psmouse, "Unable get OPC state.\n");
 339                return -EIO;
 340        }
 341
 342        if (enable)
 343                nv = v | FSP_BIT_EN_OPC_TAG;
 344        else
 345                nv = v & ~FSP_BIT_EN_OPC_TAG;
 346
 347        /* only write if necessary */
 348        if (nv != v) {
 349                fsp_reg_write_enable(psmouse, true);
 350                res = fsp_reg_write(psmouse, FSP_REG_OPC_QDOWN, nv);
 351                fsp_reg_write_enable(psmouse, false);
 352        }
 353
 354        if (res != 0) {
 355                psmouse_err(psmouse, "Unable to enable OPC tag.\n");
 356                res = -EIO;
 357        }
 358
 359        return res;
 360}
 361
 362static int fsp_onpad_vscr(struct psmouse *psmouse, bool enable)
 363{
 364        struct fsp_data *pad = psmouse->private;
 365        int val;
 366
 367        if (fsp_reg_read(psmouse, FSP_REG_ONPAD_CTL, &val))
 368                return -EIO;
 369
 370        pad->vscroll = enable;
 371
 372        if (enable)
 373                val |= (FSP_BIT_FIX_VSCR | FSP_BIT_ONPAD_ENABLE);
 374        else
 375                val &= ~FSP_BIT_FIX_VSCR;
 376
 377        if (fsp_reg_write(psmouse, FSP_REG_ONPAD_CTL, val))
 378                return -EIO;
 379
 380        return 0;
 381}
 382
 383static int fsp_onpad_hscr(struct psmouse *psmouse, bool enable)
 384{
 385        struct fsp_data *pad = psmouse->private;
 386        int val, v2;
 387
 388        if (fsp_reg_read(psmouse, FSP_REG_ONPAD_CTL, &val))
 389                return -EIO;
 390
 391        if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &v2))
 392                return -EIO;
 393
 394        pad->hscroll = enable;
 395
 396        if (enable) {
 397                val |= (FSP_BIT_FIX_HSCR | FSP_BIT_ONPAD_ENABLE);
 398                v2 |= FSP_BIT_EN_MSID6;
 399        } else {
 400                val &= ~FSP_BIT_FIX_HSCR;
 401                v2 &= ~(FSP_BIT_EN_MSID6 | FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8);
 402        }
 403
 404        if (fsp_reg_write(psmouse, FSP_REG_ONPAD_CTL, val))
 405                return -EIO;
 406
 407        /* reconfigure horizontal scrolling packet output */
 408        if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, v2))
 409                return -EIO;
 410
 411        return 0;
 412}
 413
 414/*
 415 * Write device specific initial parameters.
 416 *
 417 * ex: 0xab 0xcd - write oxcd into register 0xab
 418 */
 419static ssize_t fsp_attr_set_setreg(struct psmouse *psmouse, void *data,
 420                                   const char *buf, size_t count)
 421{
 422        unsigned int reg, val;
 423        char *rest;
 424        ssize_t retval;
 425
 426        reg = simple_strtoul(buf, &rest, 16);
 427        if (rest == buf || *rest != ' ' || reg > 0xff)
 428                return -EINVAL;
 429
 430        retval = kstrtouint(rest + 1, 16, &val);
 431        if (retval)
 432                return retval;
 433
 434        if (val > 0xff)
 435                return -EINVAL;
 436
 437        if (fsp_reg_write_enable(psmouse, true))
 438                return -EIO;
 439
 440        retval = fsp_reg_write(psmouse, reg, val) < 0 ? -EIO : count;
 441
 442        fsp_reg_write_enable(psmouse, false);
 443
 444        return count;
 445}
 446
 447PSMOUSE_DEFINE_WO_ATTR(setreg, S_IWUSR, NULL, fsp_attr_set_setreg);
 448
 449static ssize_t fsp_attr_show_getreg(struct psmouse *psmouse,
 450                                        void *data, char *buf)
 451{
 452        struct fsp_data *pad = psmouse->private;
 453
 454        return sprintf(buf, "%02x%02x\n", pad->last_reg, pad->last_val);
 455}
 456
 457/*
 458 * Read a register from device.
 459 *
 460 * ex: 0xab -- read content from register 0xab
 461 */
 462static ssize_t fsp_attr_set_getreg(struct psmouse *psmouse, void *data,
 463                                        const char *buf, size_t count)
 464{
 465        struct fsp_data *pad = psmouse->private;
 466        unsigned int reg, val;
 467        int err;
 468
 469        err = kstrtouint(buf, 16, &reg);
 470        if (err)
 471                return err;
 472
 473        if (reg > 0xff)
 474                return -EINVAL;
 475
 476        if (fsp_reg_read(psmouse, reg, &val))
 477                return -EIO;
 478
 479        pad->last_reg = reg;
 480        pad->last_val = val;
 481
 482        return count;
 483}
 484
 485PSMOUSE_DEFINE_ATTR(getreg, S_IWUSR | S_IRUGO, NULL,
 486                        fsp_attr_show_getreg, fsp_attr_set_getreg);
 487
 488static ssize_t fsp_attr_show_pagereg(struct psmouse *psmouse,
 489                                        void *data, char *buf)
 490{
 491        int val = 0;
 492
 493        if (fsp_page_reg_read(psmouse, &val))
 494                return -EIO;
 495
 496        return sprintf(buf, "%02x\n", val);
 497}
 498
 499static ssize_t fsp_attr_set_pagereg(struct psmouse *psmouse, void *data,
 500                                        const char *buf, size_t count)
 501{
 502        unsigned int val;
 503        int err;
 504
 505        err = kstrtouint(buf, 16, &val);
 506        if (err)
 507                return err;
 508
 509        if (val > 0xff)
 510                return -EINVAL;
 511
 512        if (fsp_page_reg_write(psmouse, val))
 513                return -EIO;
 514
 515        return count;
 516}
 517
 518PSMOUSE_DEFINE_ATTR(page, S_IWUSR | S_IRUGO, NULL,
 519                        fsp_attr_show_pagereg, fsp_attr_set_pagereg);
 520
 521static ssize_t fsp_attr_show_vscroll(struct psmouse *psmouse,
 522                                        void *data, char *buf)
 523{
 524        struct fsp_data *pad = psmouse->private;
 525
 526        return sprintf(buf, "%d\n", pad->vscroll);
 527}
 528
 529static ssize_t fsp_attr_set_vscroll(struct psmouse *psmouse, void *data,
 530                                        const char *buf, size_t count)
 531{
 532        unsigned int val;
 533        int err;
 534
 535        err = kstrtouint(buf, 10, &val);
 536        if (err)
 537                return err;
 538
 539        if (val > 1)
 540                return -EINVAL;
 541
 542        fsp_onpad_vscr(psmouse, val);
 543
 544        return count;
 545}
 546
 547PSMOUSE_DEFINE_ATTR(vscroll, S_IWUSR | S_IRUGO, NULL,
 548                        fsp_attr_show_vscroll, fsp_attr_set_vscroll);
 549
 550static ssize_t fsp_attr_show_hscroll(struct psmouse *psmouse,
 551                                        void *data, char *buf)
 552{
 553        struct fsp_data *pad = psmouse->private;
 554
 555        return sprintf(buf, "%d\n", pad->hscroll);
 556}
 557
 558static ssize_t fsp_attr_set_hscroll(struct psmouse *psmouse, void *data,
 559                                        const char *buf, size_t count)
 560{
 561        unsigned int val;
 562        int err;
 563
 564        err = kstrtouint(buf, 10, &val);
 565        if (err)
 566                return err;
 567
 568        if (val > 1)
 569                return -EINVAL;
 570
 571        fsp_onpad_hscr(psmouse, val);
 572
 573        return count;
 574}
 575
 576PSMOUSE_DEFINE_ATTR(hscroll, S_IWUSR | S_IRUGO, NULL,
 577                        fsp_attr_show_hscroll, fsp_attr_set_hscroll);
 578
 579static ssize_t fsp_attr_show_flags(struct psmouse *psmouse,
 580                                        void *data, char *buf)
 581{
 582        struct fsp_data *pad = psmouse->private;
 583
 584        return sprintf(buf, "%c\n",
 585                        pad->flags & FSPDRV_FLAG_EN_OPC ? 'C' : 'c');
 586}
 587
 588static ssize_t fsp_attr_set_flags(struct psmouse *psmouse, void *data,
 589                                        const char *buf, size_t count)
 590{
 591        struct fsp_data *pad = psmouse->private;
 592        size_t i;
 593
 594        for (i = 0; i < count; i++) {
 595                switch (buf[i]) {
 596                case 'C':
 597                        pad->flags |= FSPDRV_FLAG_EN_OPC;
 598                        break;
 599                case 'c':
 600                        pad->flags &= ~FSPDRV_FLAG_EN_OPC;
 601                        break;
 602                default:
 603                        return -EINVAL;
 604                }
 605        }
 606        return count;
 607}
 608
 609PSMOUSE_DEFINE_ATTR(flags, S_IWUSR | S_IRUGO, NULL,
 610                        fsp_attr_show_flags, fsp_attr_set_flags);
 611
 612static ssize_t fsp_attr_show_ver(struct psmouse *psmouse,
 613                                        void *data, char *buf)
 614{
 615        return sprintf(buf, "Sentelic FSP kernel module %s\n", fsp_drv_ver);
 616}
 617
 618PSMOUSE_DEFINE_RO_ATTR(ver, S_IRUGO, NULL, fsp_attr_show_ver);
 619
 620static struct attribute *fsp_attributes[] = {
 621        &psmouse_attr_setreg.dattr.attr,
 622        &psmouse_attr_getreg.dattr.attr,
 623        &psmouse_attr_page.dattr.attr,
 624        &psmouse_attr_vscroll.dattr.attr,
 625        &psmouse_attr_hscroll.dattr.attr,
 626        &psmouse_attr_flags.dattr.attr,
 627        &psmouse_attr_ver.dattr.attr,
 628        NULL
 629};
 630
 631static struct attribute_group fsp_attribute_group = {
 632        .attrs = fsp_attributes,
 633};
 634
 635#ifdef  FSP_DEBUG
 636static void fsp_packet_debug(struct psmouse *psmouse, unsigned char packet[])
 637{
 638        static unsigned int ps2_packet_cnt;
 639        static unsigned int ps2_last_second;
 640        unsigned int jiffies_msec;
 641        const char *packet_type = "UNKNOWN";
 642        unsigned short abs_x = 0, abs_y = 0;
 643
 644        /* Interpret & dump the packet data. */
 645        switch (packet[0] >> FSP_PKT_TYPE_SHIFT) {
 646        case FSP_PKT_TYPE_ABS:
 647                packet_type = "Absolute";
 648                abs_x = GET_ABS_X(packet);
 649                abs_y = GET_ABS_Y(packet);
 650                break;
 651        case FSP_PKT_TYPE_NORMAL:
 652                packet_type = "Normal";
 653                break;
 654        case FSP_PKT_TYPE_NOTIFY:
 655                packet_type = "Notify";
 656                break;
 657        case FSP_PKT_TYPE_NORMAL_OPC:
 658                packet_type = "Normal-OPC";
 659                break;
 660        }
 661
 662        ps2_packet_cnt++;
 663        jiffies_msec = jiffies_to_msecs(jiffies);
 664        psmouse_dbg(psmouse,
 665                    "%08dms %s packets: %02x, %02x, %02x, %02x; "
 666                    "abs_x: %d, abs_y: %d\n",
 667                    jiffies_msec, packet_type,
 668                    packet[0], packet[1], packet[2], packet[3], abs_x, abs_y);
 669
 670        if (jiffies_msec - ps2_last_second > 1000) {
 671                psmouse_dbg(psmouse, "PS/2 packets/sec = %d\n", ps2_packet_cnt);
 672                ps2_packet_cnt = 0;
 673                ps2_last_second = jiffies_msec;
 674        }
 675}
 676#else
 677static void fsp_packet_debug(struct psmouse *psmouse, unsigned char packet[])
 678{
 679}
 680#endif
 681
 682static void fsp_set_slot(struct input_dev *dev, int slot, bool active,
 683                         unsigned int x, unsigned int y)
 684{
 685        input_mt_slot(dev, slot);
 686        input_mt_report_slot_state(dev, MT_TOOL_FINGER, active);
 687        if (active) {
 688                input_report_abs(dev, ABS_MT_POSITION_X, x);
 689                input_report_abs(dev, ABS_MT_POSITION_Y, y);
 690        }
 691}
 692
 693static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse)
 694{
 695        struct input_dev *dev = psmouse->dev;
 696        struct fsp_data *ad = psmouse->private;
 697        unsigned char *packet = psmouse->packet;
 698        unsigned char button_status = 0, lscroll = 0, rscroll = 0;
 699        unsigned short abs_x, abs_y, fgrs = 0;
 700
 701        if (psmouse->pktcnt < 4)
 702                return PSMOUSE_GOOD_DATA;
 703
 704        /*
 705         * Full packet accumulated, process it
 706         */
 707
 708        fsp_packet_debug(psmouse, packet);
 709
 710        switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) {
 711        case FSP_PKT_TYPE_ABS:
 712
 713                if ((packet[0] == 0x48 || packet[0] == 0x49) &&
 714                    packet[1] == 0 && packet[2] == 0) {
 715                        /*
 716                         * Ignore coordinate noise when finger leaving the
 717                         * surface, otherwise cursor may jump to upper-left
 718                         * corner.
 719                         */
 720                        packet[3] &= 0xf0;
 721                }
 722
 723                abs_x = GET_ABS_X(packet);
 724                abs_y = GET_ABS_Y(packet);
 725
 726                if (packet[0] & FSP_PB0_MFMC) {
 727                        /*
 728                         * MFMC packet: assume that there are two fingers on
 729                         * pad
 730                         */
 731                        fgrs = 2;
 732
 733                        /* MFMC packet */
 734                        if (packet[0] & FSP_PB0_MFMC_FGR2) {
 735                                /* 2nd finger */
 736                                if (ad->last_mt_fgr == 2) {
 737                                        /*
 738                                         * workaround for buggy firmware
 739                                         * which doesn't clear MFMC bit if
 740                                         * the 1st finger is up
 741                                         */
 742                                        fgrs = 1;
 743                                        fsp_set_slot(dev, 0, false, 0, 0);
 744                                }
 745                                ad->last_mt_fgr = 2;
 746
 747                                fsp_set_slot(dev, 1, fgrs == 2, abs_x, abs_y);
 748                        } else {
 749                                /* 1st finger */
 750                                if (ad->last_mt_fgr == 1) {
 751                                        /*
 752                                         * workaround for buggy firmware
 753                                         * which doesn't clear MFMC bit if
 754                                         * the 2nd finger is up
 755                                         */
 756                                        fgrs = 1;
 757                                        fsp_set_slot(dev, 1, false, 0, 0);
 758                                }
 759                                ad->last_mt_fgr = 1;
 760                                fsp_set_slot(dev, 0, fgrs != 0, abs_x, abs_y);
 761                        }
 762                } else {
 763                        /* SFAC packet */
 764                        if ((packet[0] & (FSP_PB0_LBTN|FSP_PB0_PHY_BTN)) ==
 765                                FSP_PB0_LBTN) {
 766                                /* On-pad click in SFAC mode should be handled
 767                                 * by userspace.  On-pad clicks in MFMC mode
 768                                 * are real clickpad clicks, and not ignored.
 769                                 */
 770                                packet[0] &= ~FSP_PB0_LBTN;
 771                        }
 772
 773                        /* no multi-finger information */
 774                        ad->last_mt_fgr = 0;
 775
 776                        if (abs_x != 0 && abs_y != 0)
 777                                fgrs = 1;
 778
 779                        fsp_set_slot(dev, 0, fgrs > 0, abs_x, abs_y);
 780                        fsp_set_slot(dev, 1, false, 0, 0);
 781                }
 782                if (fgrs == 1 || (fgrs == 2 && !(packet[0] & FSP_PB0_MFMC_FGR2))) {
 783                        input_report_abs(dev, ABS_X, abs_x);
 784                        input_report_abs(dev, ABS_Y, abs_y);
 785                }
 786                input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
 787                input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
 788                input_report_key(dev, BTN_TOUCH, fgrs);
 789                input_report_key(dev, BTN_TOOL_FINGER, fgrs == 1);
 790                input_report_key(dev, BTN_TOOL_DOUBLETAP, fgrs == 2);
 791                break;
 792
 793        case FSP_PKT_TYPE_NORMAL_OPC:
 794                /* on-pad click, filter it if necessary */
 795                if ((ad->flags & FSPDRV_FLAG_EN_OPC) != FSPDRV_FLAG_EN_OPC)
 796                        packet[0] &= ~FSP_PB0_LBTN;
 797                /* fall through */
 798
 799        case FSP_PKT_TYPE_NORMAL:
 800                /* normal packet */
 801                /* special packet data translation from on-pad packets */
 802                if (packet[3] != 0) {
 803                        if (packet[3] & BIT(0))
 804                                button_status |= 0x01;  /* wheel down */
 805                        if (packet[3] & BIT(1))
 806                                button_status |= 0x0f;  /* wheel up */
 807                        if (packet[3] & BIT(2))
 808                                button_status |= BIT(4);/* horizontal left */
 809                        if (packet[3] & BIT(3))
 810                                button_status |= BIT(5);/* horizontal right */
 811                        /* push back to packet queue */
 812                        if (button_status != 0)
 813                                packet[3] = button_status;
 814                        rscroll = (packet[3] >> 4) & 1;
 815                        lscroll = (packet[3] >> 5) & 1;
 816                }
 817                /*
 818                 * Processing wheel up/down and extra button events
 819                 */
 820                input_report_rel(dev, REL_WHEEL,
 821                                 (int)(packet[3] & 8) - (int)(packet[3] & 7));
 822                input_report_rel(dev, REL_HWHEEL, lscroll - rscroll);
 823                input_report_key(dev, BTN_BACK, lscroll);
 824                input_report_key(dev, BTN_FORWARD, rscroll);
 825
 826                /*
 827                 * Standard PS/2 Mouse
 828                 */
 829                psmouse_report_standard_packet(dev, packet);
 830                break;
 831        }
 832
 833        input_sync(dev);
 834
 835        return PSMOUSE_FULL_PACKET;
 836}
 837
 838static int fsp_activate_protocol(struct psmouse *psmouse)
 839{
 840        struct fsp_data *pad = psmouse->private;
 841        struct ps2dev *ps2dev = &psmouse->ps2dev;
 842        unsigned char param[2];
 843        int val;
 844
 845        /*
 846         * Standard procedure to enter FSP Intellimouse mode
 847         * (scrolling wheel, 4th and 5th buttons)
 848         */
 849        param[0] = 200;
 850        ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
 851        param[0] = 200;
 852        ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
 853        param[0] =  80;
 854        ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
 855
 856        ps2_command(ps2dev, param, PSMOUSE_CMD_GETID);
 857        if (param[0] != 0x04) {
 858                psmouse_err(psmouse,
 859                            "Unable to enable 4 bytes packet format.\n");
 860                return -EIO;
 861        }
 862
 863        if (pad->ver < FSP_VER_STL3888_C0) {
 864                /* Preparing relative coordinates output for older hardware */
 865                if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &val)) {
 866                        psmouse_err(psmouse,
 867                                    "Unable to read SYSCTL5 register.\n");
 868                        return -EIO;
 869                }
 870
 871                if (fsp_get_buttons(psmouse, &pad->buttons)) {
 872                        psmouse_err(psmouse,
 873                                    "Unable to retrieve number of buttons.\n");
 874                        return -EIO;
 875                }
 876
 877                val &= ~(FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8 | FSP_BIT_EN_AUTO_MSID8);
 878                /* Ensure we are not in absolute mode */
 879                val &= ~FSP_BIT_EN_PKT_G0;
 880                if (pad->buttons == 0x06) {
 881                        /* Left/Middle/Right & Scroll Up/Down/Right/Left */
 882                        val |= FSP_BIT_EN_MSID6;
 883                }
 884
 885                if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, val)) {
 886                        psmouse_err(psmouse,
 887                                    "Unable to set up required mode bits.\n");
 888                        return -EIO;
 889                }
 890
 891                /*
 892                 * Enable OPC tags such that driver can tell the difference
 893                 * between on-pad and real button click
 894                 */
 895                if (fsp_opc_tag_enable(psmouse, true))
 896                        psmouse_warn(psmouse,
 897                                     "Failed to enable OPC tag mode.\n");
 898                /* enable on-pad click by default */
 899                pad->flags |= FSPDRV_FLAG_EN_OPC;
 900
 901                /* Enable on-pad vertical and horizontal scrolling */
 902                fsp_onpad_vscr(psmouse, true);
 903                fsp_onpad_hscr(psmouse, true);
 904        } else {
 905                /* Enable absolute coordinates output for Cx/Dx hardware */
 906                if (fsp_reg_write(psmouse, FSP_REG_SWC1,
 907                                  FSP_BIT_SWC1_EN_ABS_1F |
 908                                  FSP_BIT_SWC1_EN_ABS_2F |
 909                                  FSP_BIT_SWC1_EN_FUP_OUT |
 910                                  FSP_BIT_SWC1_EN_ABS_CON)) {
 911                        psmouse_err(psmouse,
 912                                    "Unable to enable absolute coordinates output.\n");
 913                        return -EIO;
 914                }
 915        }
 916
 917        return 0;
 918}
 919
 920static int fsp_set_input_params(struct psmouse *psmouse)
 921{
 922        struct input_dev *dev = psmouse->dev;
 923        struct fsp_data *pad = psmouse->private;
 924
 925        if (pad->ver < FSP_VER_STL3888_C0) {
 926                __set_bit(BTN_MIDDLE, dev->keybit);
 927                __set_bit(BTN_BACK, dev->keybit);
 928                __set_bit(BTN_FORWARD, dev->keybit);
 929                __set_bit(REL_WHEEL, dev->relbit);
 930                __set_bit(REL_HWHEEL, dev->relbit);
 931        } else {
 932                /*
 933                 * Hardware prior to Cx performs much better in relative mode;
 934                 * hence, only enable absolute coordinates output as well as
 935                 * multi-touch output for the newer hardware.
 936                 *
 937                 * Maximum coordinates can be computed as:
 938                 *
 939                 *      number of scanlines * 64 - 57
 940                 *
 941                 * where number of X/Y scanline lines are 16/12.
 942                 */
 943                int abs_x = 967, abs_y = 711;
 944
 945                __set_bit(EV_ABS, dev->evbit);
 946                __clear_bit(EV_REL, dev->evbit);
 947                __set_bit(BTN_TOUCH, dev->keybit);
 948                __set_bit(BTN_TOOL_FINGER, dev->keybit);
 949                __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
 950                __set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
 951
 952                input_set_abs_params(dev, ABS_X, 0, abs_x, 0, 0);
 953                input_set_abs_params(dev, ABS_Y, 0, abs_y, 0, 0);
 954                input_mt_init_slots(dev, 2, 0);
 955                input_set_abs_params(dev, ABS_MT_POSITION_X, 0, abs_x, 0, 0);
 956                input_set_abs_params(dev, ABS_MT_POSITION_Y, 0, abs_y, 0, 0);
 957        }
 958
 959        return 0;
 960}
 961
 962int fsp_detect(struct psmouse *psmouse, bool set_properties)
 963{
 964        int id;
 965
 966        if (fsp_reg_read(psmouse, FSP_REG_DEVICE_ID, &id))
 967                return -EIO;
 968
 969        if (id != 0x01)
 970                return -ENODEV;
 971
 972        if (set_properties) {
 973                psmouse->vendor = "Sentelic";
 974                psmouse->name = "FingerSensingPad";
 975        }
 976
 977        return 0;
 978}
 979
 980static void fsp_reset(struct psmouse *psmouse)
 981{
 982        fsp_opc_tag_enable(psmouse, false);
 983        fsp_onpad_vscr(psmouse, false);
 984        fsp_onpad_hscr(psmouse, false);
 985}
 986
 987static void fsp_disconnect(struct psmouse *psmouse)
 988{
 989        sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj,
 990                           &fsp_attribute_group);
 991
 992        fsp_reset(psmouse);
 993        kfree(psmouse->private);
 994}
 995
 996static int fsp_reconnect(struct psmouse *psmouse)
 997{
 998        int version;
 999
1000        if (fsp_detect(psmouse, 0))
1001                return -ENODEV;
1002
1003        if (fsp_get_version(psmouse, &version))
1004                return -ENODEV;
1005
1006        if (fsp_activate_protocol(psmouse))
1007                return -EIO;
1008
1009        return 0;
1010}
1011
1012int fsp_init(struct psmouse *psmouse)
1013{
1014        struct fsp_data *priv;
1015        int ver, rev, sn = 0;
1016        int error;
1017
1018        if (fsp_get_version(psmouse, &ver) ||
1019            fsp_get_revision(psmouse, &rev)) {
1020                return -ENODEV;
1021        }
1022        if (ver >= FSP_VER_STL3888_C0) {
1023                /* firmware information is only available since C0 */
1024                fsp_get_sn(psmouse, &sn);
1025        }
1026
1027        psmouse_info(psmouse,
1028                     "Finger Sensing Pad, hw: %d.%d.%d, sn: %x, sw: %s\n",
1029                     ver >> 4, ver & 0x0F, rev, sn, fsp_drv_ver);
1030
1031        psmouse->private = priv = kzalloc(sizeof(struct fsp_data), GFP_KERNEL);
1032        if (!priv)
1033                return -ENOMEM;
1034
1035        priv->ver = ver;
1036        priv->rev = rev;
1037
1038        psmouse->protocol_handler = fsp_process_byte;
1039        psmouse->disconnect = fsp_disconnect;
1040        psmouse->reconnect = fsp_reconnect;
1041        psmouse->cleanup = fsp_reset;
1042        psmouse->pktsize = 4;
1043
1044        error = fsp_activate_protocol(psmouse);
1045        if (error)
1046                goto err_out;
1047
1048        /* Set up various supported input event bits */
1049        error = fsp_set_input_params(psmouse);
1050        if (error)
1051                goto err_out;
1052
1053        error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj,
1054                                   &fsp_attribute_group);
1055        if (error) {
1056                psmouse_err(psmouse,
1057                            "Failed to create sysfs attributes (%d)", error);
1058                goto err_out;
1059        }
1060
1061        return 0;
1062
1063 err_out:
1064        kfree(psmouse->private);
1065        psmouse->private = NULL;
1066        return error;
1067}
1068