]> Pileus Git - ~andy/linux/blobdiff - drivers/input/mouse/sentelic.c
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/bwh/sfc...
[~andy/linux] / drivers / input / mouse / sentelic.c
index 661a0ca3b3d6939df7b11efd2576f4eb8dcc55f5..a261d857691957a98e732124f6370c6f8280451a 100644 (file)
@@ -41,7 +41,7 @@
 #define        GET_ABS_Y(packet)       ((packet[2] << 2) | (packet[3] & 0x03))
 
 /** Driver version. */
-static const char fsp_drv_ver[] = "1.0.0-K";
+static const char fsp_drv_ver[] = "1.1.0-K";
 
 /*
  * Make sure that the value being sent to FSP will not conflict with
@@ -303,6 +303,27 @@ static int fsp_get_revision(struct psmouse *psmouse, int *rev)
        return 0;
 }
 
+static int fsp_get_sn(struct psmouse *psmouse, int *sn)
+{
+       int v0, v1, v2;
+       int rc = -EIO;
+
+       /* production number since Cx is available at: 0x0b40 ~ 0x0b42 */
+       if (fsp_page_reg_write(psmouse, FSP_PAGE_0B))
+               goto out;
+       if (fsp_reg_read(psmouse, FSP_REG_SN0, &v0))
+               goto out;
+       if (fsp_reg_read(psmouse, FSP_REG_SN1, &v1))
+               goto out;
+       if (fsp_reg_read(psmouse, FSP_REG_SN2, &v2))
+               goto out;
+       *sn = (v0 << 16) | (v1 << 8) | v2;
+       rc = 0;
+out:
+       fsp_page_reg_write(psmouse, FSP_PAGE_DEFAULT);
+       return rc;
+}
+
 static int fsp_get_buttons(struct psmouse *psmouse, int *btn)
 {
        static const int buttons[] = {
@@ -700,6 +721,17 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse)
 
        switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) {
        case FSP_PKT_TYPE_ABS:
+
+               if ((packet[0] == 0x48 || packet[0] == 0x49) &&
+                   packet[1] == 0 && packet[2] == 0) {
+                       /*
+                        * Ignore coordinate noise when finger leaving the
+                        * surface, otherwise cursor may jump to upper-left
+                        * corner.
+                        */
+                       packet[3] &= 0xf0;
+               }
+
                abs_x = GET_ABS_X(packet);
                abs_y = GET_ABS_Y(packet);
 
@@ -1000,16 +1032,21 @@ static int fsp_reconnect(struct psmouse *psmouse)
 int fsp_init(struct psmouse *psmouse)
 {
        struct fsp_data *priv;
-       int ver, rev;
+       int ver, rev, sn = 0;
        int error;
 
        if (fsp_get_version(psmouse, &ver) ||
            fsp_get_revision(psmouse, &rev)) {
                return -ENODEV;
        }
+       if (ver >= FSP_VER_STL3888_C0) {
+               /* firmware information is only available since C0 */
+               fsp_get_sn(psmouse, &sn);
+       }
 
-       psmouse_info(psmouse, "Finger Sensing Pad, hw: %d.%d.%d, sw: %s\n",
-                    ver >> 4, ver & 0x0F, rev, fsp_drv_ver);
+       psmouse_info(psmouse,
+                    "Finger Sensing Pad, hw: %d.%d.%d, sn: %x, sw: %s\n",
+                    ver >> 4, ver & 0x0F, rev, sn, fsp_drv_ver);
 
        psmouse->private = priv = kzalloc(sizeof(struct fsp_data), GFP_KERNEL);
        if (!priv)