Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*-
0003  * Finger Sensing Pad PS/2 mouse driver.
0004  *
0005  * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd.
0006  * Copyright (C) 2005-2012 Tai-hwa Liang, Sentelic Corporation.
0007  */
0008 
0009 #include <linux/module.h>
0010 #include <linux/input.h>
0011 #include <linux/input/mt.h>
0012 #include <linux/ctype.h>
0013 #include <linux/libps2.h>
0014 #include <linux/serio.h>
0015 #include <linux/jiffies.h>
0016 #include <linux/slab.h>
0017 
0018 #include "psmouse.h"
0019 #include "sentelic.h"
0020 
0021 /*
0022  * Timeout for FSP PS/2 command only (in milliseconds).
0023  */
0024 #define FSP_CMD_TIMEOUT     200
0025 #define FSP_CMD_TIMEOUT2    30
0026 
0027 #define GET_ABS_X(packet)   ((packet[1] << 2) | ((packet[3] >> 2) & 0x03))
0028 #define GET_ABS_Y(packet)   ((packet[2] << 2) | (packet[3] & 0x03))
0029 
0030 /** Driver version. */
0031 static const char fsp_drv_ver[] = "1.1.0-K";
0032 
0033 /*
0034  * Make sure that the value being sent to FSP will not conflict with
0035  * possible sample rate values.
0036  */
0037 static unsigned char fsp_test_swap_cmd(unsigned char reg_val)
0038 {
0039     switch (reg_val) {
0040     case 10: case 20: case 40: case 60: case 80: case 100: case 200:
0041         /*
0042          * The requested value being sent to FSP matched to possible
0043          * sample rates, swap the given value such that the hardware
0044          * wouldn't get confused.
0045          */
0046         return (reg_val >> 4) | (reg_val << 4);
0047     default:
0048         return reg_val; /* swap isn't necessary */
0049     }
0050 }
0051 
0052 /*
0053  * Make sure that the value being sent to FSP will not conflict with certain
0054  * commands.
0055  */
0056 static unsigned char fsp_test_invert_cmd(unsigned char reg_val)
0057 {
0058     switch (reg_val) {
0059     case 0xe9: case 0xee: case 0xf2: case 0xff:
0060         /*
0061          * The requested value being sent to FSP matched to certain
0062          * commands, inverse the given value such that the hardware
0063          * wouldn't get confused.
0064          */
0065         return ~reg_val;
0066     default:
0067         return reg_val; /* inversion isn't necessary */
0068     }
0069 }
0070 
0071 static int fsp_reg_read(struct psmouse *psmouse, int reg_addr, int *reg_val)
0072 {
0073     struct ps2dev *ps2dev = &psmouse->ps2dev;
0074     unsigned char param[3];
0075     unsigned char addr;
0076     int rc = -1;
0077 
0078     /*
0079      * We need to shut off the device and switch it into command
0080      * mode so we don't confuse our protocol handler. We don't need
0081      * to do that for writes because sysfs set helper does this for
0082      * us.
0083      */
0084     psmouse_deactivate(psmouse);
0085 
0086     ps2_begin_command(ps2dev);
0087 
0088     if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
0089         goto out;
0090 
0091     /* should return 0xfe(request for resending) */
0092     ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2);
0093     /* should return 0xfc(failed) */
0094     ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
0095 
0096     if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
0097         goto out;
0098 
0099     if ((addr = fsp_test_invert_cmd(reg_addr)) != reg_addr) {
0100         ps2_sendbyte(ps2dev, 0x68, FSP_CMD_TIMEOUT2);
0101     } else if ((addr = fsp_test_swap_cmd(reg_addr)) != reg_addr) {
0102         /* swapping is required */
0103         ps2_sendbyte(ps2dev, 0xcc, FSP_CMD_TIMEOUT2);
0104         /* expect 0xfe */
0105     } else {
0106         /* swapping isn't necessary */
0107         ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2);
0108         /* expect 0xfe */
0109     }
0110     /* should return 0xfc(failed) */
0111     ps2_sendbyte(ps2dev, addr, FSP_CMD_TIMEOUT);
0112 
0113     if (__ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO) < 0)
0114         goto out;
0115 
0116     *reg_val = param[2];
0117     rc = 0;
0118 
0119  out:
0120     ps2_end_command(ps2dev);
0121     psmouse_activate(psmouse);
0122     psmouse_dbg(psmouse,
0123             "READ REG: 0x%02x is 0x%02x (rc = %d)\n",
0124             reg_addr, *reg_val, rc);
0125     return rc;
0126 }
0127 
0128 static int fsp_reg_write(struct psmouse *psmouse, int reg_addr, int reg_val)
0129 {
0130     struct ps2dev *ps2dev = &psmouse->ps2dev;
0131     unsigned char v;
0132     int rc = -1;
0133 
0134     ps2_begin_command(ps2dev);
0135 
0136     if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
0137         goto out;
0138 
0139     if ((v = fsp_test_invert_cmd(reg_addr)) != reg_addr) {
0140         /* inversion is required */
0141         ps2_sendbyte(ps2dev, 0x74, FSP_CMD_TIMEOUT2);
0142     } else {
0143         if ((v = fsp_test_swap_cmd(reg_addr)) != reg_addr) {
0144             /* swapping is required */
0145             ps2_sendbyte(ps2dev, 0x77, FSP_CMD_TIMEOUT2);
0146         } else {
0147             /* swapping isn't necessary */
0148             ps2_sendbyte(ps2dev, 0x55, FSP_CMD_TIMEOUT2);
0149         }
0150     }
0151     /* write the register address in correct order */
0152     ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2);
0153 
0154     if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
0155         goto out;
0156 
0157     if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) {
0158         /* inversion is required */
0159         ps2_sendbyte(ps2dev, 0x47, FSP_CMD_TIMEOUT2);
0160     } else if ((v = fsp_test_swap_cmd(reg_val)) != reg_val) {
0161         /* swapping is required */
0162         ps2_sendbyte(ps2dev, 0x44, FSP_CMD_TIMEOUT2);
0163     } else {
0164         /* swapping isn't necessary */
0165         ps2_sendbyte(ps2dev, 0x33, FSP_CMD_TIMEOUT2);
0166     }
0167 
0168     /* write the register value in correct order */
0169     ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2);
0170     rc = 0;
0171 
0172  out:
0173     ps2_end_command(ps2dev);
0174     psmouse_dbg(psmouse,
0175             "WRITE REG: 0x%02x to 0x%02x (rc = %d)\n",
0176             reg_addr, reg_val, rc);
0177     return rc;
0178 }
0179 
0180 /* Enable register clock gating for writing certain registers */
0181 static int fsp_reg_write_enable(struct psmouse *psmouse, bool enable)
0182 {
0183     int v, nv;
0184 
0185     if (fsp_reg_read(psmouse, FSP_REG_SYSCTL1, &v) == -1)
0186         return -1;
0187 
0188     if (enable)
0189         nv = v | FSP_BIT_EN_REG_CLK;
0190     else
0191         nv = v & ~FSP_BIT_EN_REG_CLK;
0192 
0193     /* only write if necessary */
0194     if (nv != v)
0195         if (fsp_reg_write(psmouse, FSP_REG_SYSCTL1, nv) == -1)
0196             return -1;
0197 
0198     return 0;
0199 }
0200 
0201 static int fsp_page_reg_read(struct psmouse *psmouse, int *reg_val)
0202 {
0203     struct ps2dev *ps2dev = &psmouse->ps2dev;
0204     unsigned char param[3];
0205     int rc = -1;
0206 
0207     psmouse_deactivate(psmouse);
0208 
0209     ps2_begin_command(ps2dev);
0210 
0211     if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
0212         goto out;
0213 
0214     ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2);
0215     ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
0216 
0217     if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
0218         goto out;
0219 
0220     ps2_sendbyte(ps2dev, 0x83, FSP_CMD_TIMEOUT2);
0221     ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
0222 
0223     /* get the returned result */
0224     if (__ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
0225         goto out;
0226 
0227     *reg_val = param[2];
0228     rc = 0;
0229 
0230  out:
0231     ps2_end_command(ps2dev);
0232     psmouse_activate(psmouse);
0233     psmouse_dbg(psmouse,
0234             "READ PAGE REG: 0x%02x (rc = %d)\n",
0235             *reg_val, rc);
0236     return rc;
0237 }
0238 
0239 static int fsp_page_reg_write(struct psmouse *psmouse, int reg_val)
0240 {
0241     struct ps2dev *ps2dev = &psmouse->ps2dev;
0242     unsigned char v;
0243     int rc = -1;
0244 
0245     ps2_begin_command(ps2dev);
0246 
0247     if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
0248         goto out;
0249 
0250     ps2_sendbyte(ps2dev, 0x38, FSP_CMD_TIMEOUT2);
0251     ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
0252 
0253     if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
0254         goto out;
0255 
0256     if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) {
0257         ps2_sendbyte(ps2dev, 0x47, FSP_CMD_TIMEOUT2);
0258     } else if ((v = fsp_test_swap_cmd(reg_val)) != reg_val) {
0259         /* swapping is required */
0260         ps2_sendbyte(ps2dev, 0x44, FSP_CMD_TIMEOUT2);
0261     } else {
0262         /* swapping isn't necessary */
0263         ps2_sendbyte(ps2dev, 0x33, FSP_CMD_TIMEOUT2);
0264     }
0265 
0266     ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2);
0267     rc = 0;
0268 
0269  out:
0270     ps2_end_command(ps2dev);
0271     psmouse_dbg(psmouse,
0272             "WRITE PAGE REG: to 0x%02x (rc = %d)\n",
0273             reg_val, rc);
0274     return rc;
0275 }
0276 
0277 static int fsp_get_version(struct psmouse *psmouse, int *version)
0278 {
0279     if (fsp_reg_read(psmouse, FSP_REG_VERSION, version))
0280         return -EIO;
0281 
0282     return 0;
0283 }
0284 
0285 static int fsp_get_revision(struct psmouse *psmouse, int *rev)
0286 {
0287     if (fsp_reg_read(psmouse, FSP_REG_REVISION, rev))
0288         return -EIO;
0289 
0290     return 0;
0291 }
0292 
0293 static int fsp_get_sn(struct psmouse *psmouse, int *sn)
0294 {
0295     int v0, v1, v2;
0296     int rc = -EIO;
0297 
0298     /* production number since Cx is available at: 0x0b40 ~ 0x0b42 */
0299     if (fsp_page_reg_write(psmouse, FSP_PAGE_0B))
0300         goto out;
0301     if (fsp_reg_read(psmouse, FSP_REG_SN0, &v0))
0302         goto out;
0303     if (fsp_reg_read(psmouse, FSP_REG_SN1, &v1))
0304         goto out;
0305     if (fsp_reg_read(psmouse, FSP_REG_SN2, &v2))
0306         goto out;
0307     *sn = (v0 << 16) | (v1 << 8) | v2;
0308     rc = 0;
0309 out:
0310     fsp_page_reg_write(psmouse, FSP_PAGE_DEFAULT);
0311     return rc;
0312 }
0313 
0314 static int fsp_get_buttons(struct psmouse *psmouse, int *btn)
0315 {
0316     static const int buttons[] = {
0317         0x16, /* Left/Middle/Right/Forward/Backward & Scroll Up/Down */
0318         0x06, /* Left/Middle/Right & Scroll Up/Down/Right/Left */
0319         0x04, /* Left/Middle/Right & Scroll Up/Down */
0320         0x02, /* Left/Middle/Right */
0321     };
0322     int val;
0323 
0324     if (fsp_reg_read(psmouse, FSP_REG_TMOD_STATUS, &val) == -1)
0325         return -EIO;
0326 
0327     *btn = buttons[(val & 0x30) >> 4];
0328     return 0;
0329 }
0330 
0331 /* Enable on-pad command tag output */
0332 static int fsp_opc_tag_enable(struct psmouse *psmouse, bool enable)
0333 {
0334     int v, nv;
0335     int res = 0;
0336 
0337     if (fsp_reg_read(psmouse, FSP_REG_OPC_QDOWN, &v) == -1) {
0338         psmouse_err(psmouse, "Unable get OPC state.\n");
0339         return -EIO;
0340     }
0341 
0342     if (enable)
0343         nv = v | FSP_BIT_EN_OPC_TAG;
0344     else
0345         nv = v & ~FSP_BIT_EN_OPC_TAG;
0346 
0347     /* only write if necessary */
0348     if (nv != v) {
0349         fsp_reg_write_enable(psmouse, true);
0350         res = fsp_reg_write(psmouse, FSP_REG_OPC_QDOWN, nv);
0351         fsp_reg_write_enable(psmouse, false);
0352     }
0353 
0354     if (res != 0) {
0355         psmouse_err(psmouse, "Unable to enable OPC tag.\n");
0356         res = -EIO;
0357     }
0358 
0359     return res;
0360 }
0361 
0362 static int fsp_onpad_vscr(struct psmouse *psmouse, bool enable)
0363 {
0364     struct fsp_data *pad = psmouse->private;
0365     int val;
0366 
0367     if (fsp_reg_read(psmouse, FSP_REG_ONPAD_CTL, &val))
0368         return -EIO;
0369 
0370     pad->vscroll = enable;
0371 
0372     if (enable)
0373         val |= (FSP_BIT_FIX_VSCR | FSP_BIT_ONPAD_ENABLE);
0374     else
0375         val &= ~FSP_BIT_FIX_VSCR;
0376 
0377     if (fsp_reg_write(psmouse, FSP_REG_ONPAD_CTL, val))
0378         return -EIO;
0379 
0380     return 0;
0381 }
0382 
0383 static int fsp_onpad_hscr(struct psmouse *psmouse, bool enable)
0384 {
0385     struct fsp_data *pad = psmouse->private;
0386     int val, v2;
0387 
0388     if (fsp_reg_read(psmouse, FSP_REG_ONPAD_CTL, &val))
0389         return -EIO;
0390 
0391     if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &v2))
0392         return -EIO;
0393 
0394     pad->hscroll = enable;
0395 
0396     if (enable) {
0397         val |= (FSP_BIT_FIX_HSCR | FSP_BIT_ONPAD_ENABLE);
0398         v2 |= FSP_BIT_EN_MSID6;
0399     } else {
0400         val &= ~FSP_BIT_FIX_HSCR;
0401         v2 &= ~(FSP_BIT_EN_MSID6 | FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8);
0402     }
0403 
0404     if (fsp_reg_write(psmouse, FSP_REG_ONPAD_CTL, val))
0405         return -EIO;
0406 
0407     /* reconfigure horizontal scrolling packet output */
0408     if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, v2))
0409         return -EIO;
0410 
0411     return 0;
0412 }
0413 
0414 /*
0415  * Write device specific initial parameters.
0416  *
0417  * ex: 0xab 0xcd - write oxcd into register 0xab
0418  */
0419 static ssize_t fsp_attr_set_setreg(struct psmouse *psmouse, void *data,
0420                    const char *buf, size_t count)
0421 {
0422     unsigned int reg, val;
0423     char *rest;
0424     ssize_t retval;
0425 
0426     reg = simple_strtoul(buf, &rest, 16);
0427     if (rest == buf || *rest != ' ' || reg > 0xff)
0428         return -EINVAL;
0429 
0430     retval = kstrtouint(rest + 1, 16, &val);
0431     if (retval)
0432         return retval;
0433 
0434     if (val > 0xff)
0435         return -EINVAL;
0436 
0437     if (fsp_reg_write_enable(psmouse, true))
0438         return -EIO;
0439 
0440     retval = fsp_reg_write(psmouse, reg, val) < 0 ? -EIO : count;
0441 
0442     fsp_reg_write_enable(psmouse, false);
0443 
0444     return retval;
0445 }
0446 
0447 PSMOUSE_DEFINE_WO_ATTR(setreg, S_IWUSR, NULL, fsp_attr_set_setreg);
0448 
0449 static ssize_t fsp_attr_show_getreg(struct psmouse *psmouse,
0450                     void *data, char *buf)
0451 {
0452     struct fsp_data *pad = psmouse->private;
0453 
0454     return sprintf(buf, "%02x%02x\n", pad->last_reg, pad->last_val);
0455 }
0456 
0457 /*
0458  * Read a register from device.
0459  *
0460  * ex: 0xab -- read content from register 0xab
0461  */
0462 static ssize_t fsp_attr_set_getreg(struct psmouse *psmouse, void *data,
0463                     const char *buf, size_t count)
0464 {
0465     struct fsp_data *pad = psmouse->private;
0466     unsigned int reg, val;
0467     int err;
0468 
0469     err = kstrtouint(buf, 16, &reg);
0470     if (err)
0471         return err;
0472 
0473     if (reg > 0xff)
0474         return -EINVAL;
0475 
0476     if (fsp_reg_read(psmouse, reg, &val))
0477         return -EIO;
0478 
0479     pad->last_reg = reg;
0480     pad->last_val = val;
0481 
0482     return count;
0483 }
0484 
0485 PSMOUSE_DEFINE_ATTR(getreg, S_IWUSR | S_IRUGO, NULL,
0486             fsp_attr_show_getreg, fsp_attr_set_getreg);
0487 
0488 static ssize_t fsp_attr_show_pagereg(struct psmouse *psmouse,
0489                     void *data, char *buf)
0490 {
0491     int val = 0;
0492 
0493     if (fsp_page_reg_read(psmouse, &val))
0494         return -EIO;
0495 
0496     return sprintf(buf, "%02x\n", val);
0497 }
0498 
0499 static ssize_t fsp_attr_set_pagereg(struct psmouse *psmouse, void *data,
0500                     const char *buf, size_t count)
0501 {
0502     unsigned int val;
0503     int err;
0504 
0505     err = kstrtouint(buf, 16, &val);
0506     if (err)
0507         return err;
0508 
0509     if (val > 0xff)
0510         return -EINVAL;
0511 
0512     if (fsp_page_reg_write(psmouse, val))
0513         return -EIO;
0514 
0515     return count;
0516 }
0517 
0518 PSMOUSE_DEFINE_ATTR(page, S_IWUSR | S_IRUGO, NULL,
0519             fsp_attr_show_pagereg, fsp_attr_set_pagereg);
0520 
0521 static ssize_t fsp_attr_show_vscroll(struct psmouse *psmouse,
0522                     void *data, char *buf)
0523 {
0524     struct fsp_data *pad = psmouse->private;
0525 
0526     return sprintf(buf, "%d\n", pad->vscroll);
0527 }
0528 
0529 static ssize_t fsp_attr_set_vscroll(struct psmouse *psmouse, void *data,
0530                     const char *buf, size_t count)
0531 {
0532     unsigned int val;
0533     int err;
0534 
0535     err = kstrtouint(buf, 10, &val);
0536     if (err)
0537         return err;
0538 
0539     if (val > 1)
0540         return -EINVAL;
0541 
0542     fsp_onpad_vscr(psmouse, val);
0543 
0544     return count;
0545 }
0546 
0547 PSMOUSE_DEFINE_ATTR(vscroll, S_IWUSR | S_IRUGO, NULL,
0548             fsp_attr_show_vscroll, fsp_attr_set_vscroll);
0549 
0550 static ssize_t fsp_attr_show_hscroll(struct psmouse *psmouse,
0551                     void *data, char *buf)
0552 {
0553     struct fsp_data *pad = psmouse->private;
0554 
0555     return sprintf(buf, "%d\n", pad->hscroll);
0556 }
0557 
0558 static ssize_t fsp_attr_set_hscroll(struct psmouse *psmouse, void *data,
0559                     const char *buf, size_t count)
0560 {
0561     unsigned int val;
0562     int err;
0563 
0564     err = kstrtouint(buf, 10, &val);
0565     if (err)
0566         return err;
0567 
0568     if (val > 1)
0569         return -EINVAL;
0570 
0571     fsp_onpad_hscr(psmouse, val);
0572 
0573     return count;
0574 }
0575 
0576 PSMOUSE_DEFINE_ATTR(hscroll, S_IWUSR | S_IRUGO, NULL,
0577             fsp_attr_show_hscroll, fsp_attr_set_hscroll);
0578 
0579 static ssize_t fsp_attr_show_flags(struct psmouse *psmouse,
0580                     void *data, char *buf)
0581 {
0582     struct fsp_data *pad = psmouse->private;
0583 
0584     return sprintf(buf, "%c\n",
0585             pad->flags & FSPDRV_FLAG_EN_OPC ? 'C' : 'c');
0586 }
0587 
0588 static ssize_t fsp_attr_set_flags(struct psmouse *psmouse, void *data,
0589                     const char *buf, size_t count)
0590 {
0591     struct fsp_data *pad = psmouse->private;
0592     size_t i;
0593 
0594     for (i = 0; i < count; i++) {
0595         switch (buf[i]) {
0596         case 'C':
0597             pad->flags |= FSPDRV_FLAG_EN_OPC;
0598             break;
0599         case 'c':
0600             pad->flags &= ~FSPDRV_FLAG_EN_OPC;
0601             break;
0602         default:
0603             return -EINVAL;
0604         }
0605     }
0606     return count;
0607 }
0608 
0609 PSMOUSE_DEFINE_ATTR(flags, S_IWUSR | S_IRUGO, NULL,
0610             fsp_attr_show_flags, fsp_attr_set_flags);
0611 
0612 static ssize_t fsp_attr_show_ver(struct psmouse *psmouse,
0613                     void *data, char *buf)
0614 {
0615     return sprintf(buf, "Sentelic FSP kernel module %s\n", fsp_drv_ver);
0616 }
0617 
0618 PSMOUSE_DEFINE_RO_ATTR(ver, S_IRUGO, NULL, fsp_attr_show_ver);
0619 
0620 static struct attribute *fsp_attributes[] = {
0621     &psmouse_attr_setreg.dattr.attr,
0622     &psmouse_attr_getreg.dattr.attr,
0623     &psmouse_attr_page.dattr.attr,
0624     &psmouse_attr_vscroll.dattr.attr,
0625     &psmouse_attr_hscroll.dattr.attr,
0626     &psmouse_attr_flags.dattr.attr,
0627     &psmouse_attr_ver.dattr.attr,
0628     NULL
0629 };
0630 
0631 static struct attribute_group fsp_attribute_group = {
0632     .attrs = fsp_attributes,
0633 };
0634 
0635 #ifdef  FSP_DEBUG
0636 static void fsp_packet_debug(struct psmouse *psmouse, unsigned char packet[])
0637 {
0638     static unsigned int ps2_packet_cnt;
0639     static unsigned int ps2_last_second;
0640     unsigned int jiffies_msec;
0641     const char *packet_type = "UNKNOWN";
0642     unsigned short abs_x = 0, abs_y = 0;
0643 
0644     /* Interpret & dump the packet data. */
0645     switch (packet[0] >> FSP_PKT_TYPE_SHIFT) {
0646     case FSP_PKT_TYPE_ABS:
0647         packet_type = "Absolute";
0648         abs_x = GET_ABS_X(packet);
0649         abs_y = GET_ABS_Y(packet);
0650         break;
0651     case FSP_PKT_TYPE_NORMAL:
0652         packet_type = "Normal";
0653         break;
0654     case FSP_PKT_TYPE_NOTIFY:
0655         packet_type = "Notify";
0656         break;
0657     case FSP_PKT_TYPE_NORMAL_OPC:
0658         packet_type = "Normal-OPC";
0659         break;
0660     }
0661 
0662     ps2_packet_cnt++;
0663     jiffies_msec = jiffies_to_msecs(jiffies);
0664     psmouse_dbg(psmouse,
0665             "%08dms %s packets: %02x, %02x, %02x, %02x; "
0666             "abs_x: %d, abs_y: %d\n",
0667             jiffies_msec, packet_type,
0668             packet[0], packet[1], packet[2], packet[3], abs_x, abs_y);
0669 
0670     if (jiffies_msec - ps2_last_second > 1000) {
0671         psmouse_dbg(psmouse, "PS/2 packets/sec = %d\n", ps2_packet_cnt);
0672         ps2_packet_cnt = 0;
0673         ps2_last_second = jiffies_msec;
0674     }
0675 }
0676 #else
0677 static void fsp_packet_debug(struct psmouse *psmouse, unsigned char packet[])
0678 {
0679 }
0680 #endif
0681 
0682 static void fsp_set_slot(struct input_dev *dev, int slot, bool active,
0683              unsigned int x, unsigned int y)
0684 {
0685     input_mt_slot(dev, slot);
0686     input_mt_report_slot_state(dev, MT_TOOL_FINGER, active);
0687     if (active) {
0688         input_report_abs(dev, ABS_MT_POSITION_X, x);
0689         input_report_abs(dev, ABS_MT_POSITION_Y, y);
0690     }
0691 }
0692 
0693 static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse)
0694 {
0695     struct input_dev *dev = psmouse->dev;
0696     struct fsp_data *ad = psmouse->private;
0697     unsigned char *packet = psmouse->packet;
0698     unsigned char button_status = 0, lscroll = 0, rscroll = 0;
0699     unsigned short abs_x, abs_y, fgrs = 0;
0700 
0701     if (psmouse->pktcnt < 4)
0702         return PSMOUSE_GOOD_DATA;
0703 
0704     /*
0705      * Full packet accumulated, process it
0706      */
0707 
0708     fsp_packet_debug(psmouse, packet);
0709 
0710     switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) {
0711     case FSP_PKT_TYPE_ABS:
0712 
0713         if ((packet[0] == 0x48 || packet[0] == 0x49) &&
0714             packet[1] == 0 && packet[2] == 0) {
0715             /*
0716              * Ignore coordinate noise when finger leaving the
0717              * surface, otherwise cursor may jump to upper-left
0718              * corner.
0719              */
0720             packet[3] &= 0xf0;
0721         }
0722 
0723         abs_x = GET_ABS_X(packet);
0724         abs_y = GET_ABS_Y(packet);
0725 
0726         if (packet[0] & FSP_PB0_MFMC) {
0727             /*
0728              * MFMC packet: assume that there are two fingers on
0729              * pad
0730              */
0731             fgrs = 2;
0732 
0733             /* MFMC packet */
0734             if (packet[0] & FSP_PB0_MFMC_FGR2) {
0735                 /* 2nd finger */
0736                 if (ad->last_mt_fgr == 2) {
0737                     /*
0738                      * workaround for buggy firmware
0739                      * which doesn't clear MFMC bit if
0740                      * the 1st finger is up
0741                      */
0742                     fgrs = 1;
0743                     fsp_set_slot(dev, 0, false, 0, 0);
0744                 }
0745                 ad->last_mt_fgr = 2;
0746 
0747                 fsp_set_slot(dev, 1, fgrs == 2, abs_x, abs_y);
0748             } else {
0749                 /* 1st finger */
0750                 if (ad->last_mt_fgr == 1) {
0751                     /*
0752                      * workaround for buggy firmware
0753                      * which doesn't clear MFMC bit if
0754                      * the 2nd finger is up
0755                      */
0756                     fgrs = 1;
0757                     fsp_set_slot(dev, 1, false, 0, 0);
0758                 }
0759                 ad->last_mt_fgr = 1;
0760                 fsp_set_slot(dev, 0, fgrs != 0, abs_x, abs_y);
0761             }
0762         } else {
0763             /* SFAC packet */
0764             if ((packet[0] & (FSP_PB0_LBTN|FSP_PB0_PHY_BTN)) ==
0765                 FSP_PB0_LBTN) {
0766                 /* On-pad click in SFAC mode should be handled
0767                  * by userspace.  On-pad clicks in MFMC mode
0768                  * are real clickpad clicks, and not ignored.
0769                  */
0770                 packet[0] &= ~FSP_PB0_LBTN;
0771             }
0772 
0773             /* no multi-finger information */
0774             ad->last_mt_fgr = 0;
0775 
0776             if (abs_x != 0 && abs_y != 0)
0777                 fgrs = 1;
0778 
0779             fsp_set_slot(dev, 0, fgrs > 0, abs_x, abs_y);
0780             fsp_set_slot(dev, 1, false, 0, 0);
0781         }
0782         if (fgrs == 1 || (fgrs == 2 && !(packet[0] & FSP_PB0_MFMC_FGR2))) {
0783             input_report_abs(dev, ABS_X, abs_x);
0784             input_report_abs(dev, ABS_Y, abs_y);
0785         }
0786         input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
0787         input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
0788         input_report_key(dev, BTN_TOUCH, fgrs);
0789         input_report_key(dev, BTN_TOOL_FINGER, fgrs == 1);
0790         input_report_key(dev, BTN_TOOL_DOUBLETAP, fgrs == 2);
0791         break;
0792 
0793     case FSP_PKT_TYPE_NORMAL_OPC:
0794         /* on-pad click, filter it if necessary */
0795         if ((ad->flags & FSPDRV_FLAG_EN_OPC) != FSPDRV_FLAG_EN_OPC)
0796             packet[0] &= ~FSP_PB0_LBTN;
0797         fallthrough;
0798 
0799     case FSP_PKT_TYPE_NORMAL:
0800         /* normal packet */
0801         /* special packet data translation from on-pad packets */
0802         if (packet[3] != 0) {
0803             if (packet[3] & BIT(0))
0804                 button_status |= 0x01;  /* wheel down */
0805             if (packet[3] & BIT(1))
0806                 button_status |= 0x0f;  /* wheel up */
0807             if (packet[3] & BIT(2))
0808                 button_status |= BIT(4);/* horizontal left */
0809             if (packet[3] & BIT(3))
0810                 button_status |= BIT(5);/* horizontal right */
0811             /* push back to packet queue */
0812             if (button_status != 0)
0813                 packet[3] = button_status;
0814             rscroll = (packet[3] >> 4) & 1;
0815             lscroll = (packet[3] >> 5) & 1;
0816         }
0817         /*
0818          * Processing wheel up/down and extra button events
0819          */
0820         input_report_rel(dev, REL_WHEEL,
0821                  (int)(packet[3] & 8) - (int)(packet[3] & 7));
0822         input_report_rel(dev, REL_HWHEEL, lscroll - rscroll);
0823         input_report_key(dev, BTN_BACK, lscroll);
0824         input_report_key(dev, BTN_FORWARD, rscroll);
0825 
0826         /*
0827          * Standard PS/2 Mouse
0828          */
0829         psmouse_report_standard_packet(dev, packet);
0830         break;
0831     }
0832 
0833     input_sync(dev);
0834 
0835     return PSMOUSE_FULL_PACKET;
0836 }
0837 
0838 static int fsp_activate_protocol(struct psmouse *psmouse)
0839 {
0840     struct fsp_data *pad = psmouse->private;
0841     struct ps2dev *ps2dev = &psmouse->ps2dev;
0842     unsigned char param[2];
0843     int val;
0844 
0845     /*
0846      * Standard procedure to enter FSP Intellimouse mode
0847      * (scrolling wheel, 4th and 5th buttons)
0848      */
0849     param[0] = 200;
0850     ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
0851     param[0] = 200;
0852     ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
0853     param[0] =  80;
0854     ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
0855 
0856     ps2_command(ps2dev, param, PSMOUSE_CMD_GETID);
0857     if (param[0] != 0x04) {
0858         psmouse_err(psmouse,
0859                 "Unable to enable 4 bytes packet format.\n");
0860         return -EIO;
0861     }
0862 
0863     if (pad->ver < FSP_VER_STL3888_C0) {
0864         /* Preparing relative coordinates output for older hardware */
0865         if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &val)) {
0866             psmouse_err(psmouse,
0867                     "Unable to read SYSCTL5 register.\n");
0868             return -EIO;
0869         }
0870 
0871         if (fsp_get_buttons(psmouse, &pad->buttons)) {
0872             psmouse_err(psmouse,
0873                     "Unable to retrieve number of buttons.\n");
0874             return -EIO;
0875         }
0876 
0877         val &= ~(FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8 | FSP_BIT_EN_AUTO_MSID8);
0878         /* Ensure we are not in absolute mode */
0879         val &= ~FSP_BIT_EN_PKT_G0;
0880         if (pad->buttons == 0x06) {
0881             /* Left/Middle/Right & Scroll Up/Down/Right/Left */
0882             val |= FSP_BIT_EN_MSID6;
0883         }
0884 
0885         if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, val)) {
0886             psmouse_err(psmouse,
0887                     "Unable to set up required mode bits.\n");
0888             return -EIO;
0889         }
0890 
0891         /*
0892          * Enable OPC tags such that driver can tell the difference
0893          * between on-pad and real button click
0894          */
0895         if (fsp_opc_tag_enable(psmouse, true))
0896             psmouse_warn(psmouse,
0897                      "Failed to enable OPC tag mode.\n");
0898         /* enable on-pad click by default */
0899         pad->flags |= FSPDRV_FLAG_EN_OPC;
0900 
0901         /* Enable on-pad vertical and horizontal scrolling */
0902         fsp_onpad_vscr(psmouse, true);
0903         fsp_onpad_hscr(psmouse, true);
0904     } else {
0905         /* Enable absolute coordinates output for Cx/Dx hardware */
0906         if (fsp_reg_write(psmouse, FSP_REG_SWC1,
0907                   FSP_BIT_SWC1_EN_ABS_1F |
0908                   FSP_BIT_SWC1_EN_ABS_2F |
0909                   FSP_BIT_SWC1_EN_FUP_OUT |
0910                   FSP_BIT_SWC1_EN_ABS_CON)) {
0911             psmouse_err(psmouse,
0912                     "Unable to enable absolute coordinates output.\n");
0913             return -EIO;
0914         }
0915     }
0916 
0917     return 0;
0918 }
0919 
0920 static int fsp_set_input_params(struct psmouse *psmouse)
0921 {
0922     struct input_dev *dev = psmouse->dev;
0923     struct fsp_data *pad = psmouse->private;
0924 
0925     if (pad->ver < FSP_VER_STL3888_C0) {
0926         __set_bit(BTN_MIDDLE, dev->keybit);
0927         __set_bit(BTN_BACK, dev->keybit);
0928         __set_bit(BTN_FORWARD, dev->keybit);
0929         __set_bit(REL_WHEEL, dev->relbit);
0930         __set_bit(REL_HWHEEL, dev->relbit);
0931     } else {
0932         /*
0933          * Hardware prior to Cx performs much better in relative mode;
0934          * hence, only enable absolute coordinates output as well as
0935          * multi-touch output for the newer hardware.
0936          *
0937          * Maximum coordinates can be computed as:
0938          *
0939          *  number of scanlines * 64 - 57
0940          *
0941          * where number of X/Y scanline lines are 16/12.
0942          */
0943         int abs_x = 967, abs_y = 711;
0944 
0945         __set_bit(EV_ABS, dev->evbit);
0946         __clear_bit(EV_REL, dev->evbit);
0947         __set_bit(BTN_TOUCH, dev->keybit);
0948         __set_bit(BTN_TOOL_FINGER, dev->keybit);
0949         __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
0950         __set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
0951 
0952         input_set_abs_params(dev, ABS_X, 0, abs_x, 0, 0);
0953         input_set_abs_params(dev, ABS_Y, 0, abs_y, 0, 0);
0954         input_mt_init_slots(dev, 2, 0);
0955         input_set_abs_params(dev, ABS_MT_POSITION_X, 0, abs_x, 0, 0);
0956         input_set_abs_params(dev, ABS_MT_POSITION_Y, 0, abs_y, 0, 0);
0957     }
0958 
0959     return 0;
0960 }
0961 
0962 int fsp_detect(struct psmouse *psmouse, bool set_properties)
0963 {
0964     int id;
0965 
0966     if (fsp_reg_read(psmouse, FSP_REG_DEVICE_ID, &id))
0967         return -EIO;
0968 
0969     if (id != 0x01)
0970         return -ENODEV;
0971 
0972     if (set_properties) {
0973         psmouse->vendor = "Sentelic";
0974         psmouse->name = "FingerSensingPad";
0975     }
0976 
0977     return 0;
0978 }
0979 
0980 static void fsp_reset(struct psmouse *psmouse)
0981 {
0982     fsp_opc_tag_enable(psmouse, false);
0983     fsp_onpad_vscr(psmouse, false);
0984     fsp_onpad_hscr(psmouse, false);
0985 }
0986 
0987 static void fsp_disconnect(struct psmouse *psmouse)
0988 {
0989     sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj,
0990                &fsp_attribute_group);
0991 
0992     fsp_reset(psmouse);
0993     kfree(psmouse->private);
0994 }
0995 
0996 static int fsp_reconnect(struct psmouse *psmouse)
0997 {
0998     int version;
0999 
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 
1012 int 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 }