Input: elantech - query the min/max information beforehand too
authorBenjamin Tissoires <benjamin.tissoires@redhat.com>
Tue, 28 May 2019 01:24:28 +0000 (18:24 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Tue, 28 May 2019 01:50:39 +0000 (18:50 -0700)
For the latest generation of Elantech touchpads, we need to forward
the min/max information from PS/2 to SMBus. Prepare this work
by fetching the information before creating the SMBus companion
device.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
drivers/input/mouse/elantech.c
drivers/input/mouse/elantech.h

index 530142b..b551a65 100644 (file)
@@ -994,88 +994,6 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse)
        return rc;
 }
 
-static int elantech_set_range(struct psmouse *psmouse,
-                             unsigned int *x_min, unsigned int *y_min,
-                             unsigned int *x_max, unsigned int *y_max,
-                             unsigned int *width)
-{
-       struct elantech_data *etd = psmouse->private;
-       struct elantech_device_info *info = &etd->info;
-       unsigned char param[3];
-       unsigned char traces;
-
-       switch (info->hw_version) {
-       case 1:
-               *x_min = ETP_XMIN_V1;
-               *y_min = ETP_YMIN_V1;
-               *x_max = ETP_XMAX_V1;
-               *y_max = ETP_YMAX_V1;
-               break;
-
-       case 2:
-               if (info->fw_version == 0x020800 ||
-                   info->fw_version == 0x020b00 ||
-                   info->fw_version == 0x020030) {
-                       *x_min = ETP_XMIN_V2;
-                       *y_min = ETP_YMIN_V2;
-                       *x_max = ETP_XMAX_V2;
-                       *y_max = ETP_YMAX_V2;
-               } else {
-                       int i;
-                       int fixed_dpi;
-
-                       i = (info->fw_version > 0x020800 &&
-                            info->fw_version < 0x020900) ? 1 : 2;
-
-                       if (info->send_cmd(psmouse, ETP_FW_ID_QUERY, param))
-                               return -1;
-
-                       fixed_dpi = param[1] & 0x10;
-
-                       if (((info->fw_version >> 16) == 0x14) && fixed_dpi) {
-                               if (info->send_cmd(psmouse, ETP_SAMPLE_QUERY, param))
-                                       return -1;
-
-                               *x_max = (info->capabilities[1] - i) * param[1] / 2;
-                               *y_max = (info->capabilities[2] - i) * param[2] / 2;
-                       } else if (info->fw_version == 0x040216) {
-                               *x_max = 819;
-                               *y_max = 405;
-                       } else if (info->fw_version == 0x040219 || info->fw_version == 0x040215) {
-                               *x_max = 900;
-                               *y_max = 500;
-                       } else {
-                               *x_max = (info->capabilities[1] - i) * 64;
-                               *y_max = (info->capabilities[2] - i) * 64;
-                       }
-               }
-               break;
-
-       case 3:
-               if (info->send_cmd(psmouse, ETP_FW_ID_QUERY, param))
-                       return -1;
-
-               *x_max = (0x0f & param[0]) << 8 | param[1];
-               *y_max = (0xf0 & param[0]) << 4 | param[2];
-               break;
-
-       case 4:
-               if (info->send_cmd(psmouse, ETP_FW_ID_QUERY, param))
-                       return -1;
-
-               *x_max = (0x0f & param[0]) << 8 | param[1];
-               *y_max = (0xf0 & param[0]) << 4 | param[2];
-               traces = info->capabilities[1];
-               if ((traces < 2) || (traces > *x_max))
-                       return -1;
-
-               *width = *x_max / (traces - 1);
-               break;
-       }
-
-       return 0;
-}
-
 /*
  * (value from firmware) * 10 + 790 = dpi
  * we also have to convert dpi to dots/mm (*10/254 to avoid floating point)
@@ -1202,10 +1120,9 @@ static int elantech_set_input_params(struct psmouse *psmouse)
        struct input_dev *dev = psmouse->dev;
        struct elantech_data *etd = psmouse->private;
        struct elantech_device_info *info = &etd->info;
-       unsigned int x_min = 0, y_min = 0, x_max = 0, y_max = 0, width = 0;
-
-       if (elantech_set_range(psmouse, &x_min, &y_min, &x_max, &y_max, &width))
-               return -1;
+       unsigned int x_min = info->x_min, y_min = info->y_min,
+                    x_max = info->x_max, y_max = info->y_max,
+                    width = info->width;
 
        __set_bit(INPUT_PROP_POINTER, dev->propbit);
        __set_bit(EV_KEY, dev->evbit);
@@ -1689,6 +1606,7 @@ static int elantech_query_info(struct psmouse *psmouse,
                               struct elantech_device_info *info)
 {
        unsigned char param[3];
+       unsigned char traces;
 
        memset(info, 0, sizeof(*info));
 
@@ -1757,6 +1675,76 @@ static int elantech_query_info(struct psmouse *psmouse,
                }
        }
 
+       /* query range information */
+       switch (info->hw_version) {
+       case 1:
+               info->x_min = ETP_XMIN_V1;
+               info->y_min = ETP_YMIN_V1;
+               info->x_max = ETP_XMAX_V1;
+               info->y_max = ETP_YMAX_V1;
+               break;
+
+       case 2:
+               if (info->fw_version == 0x020800 ||
+                   info->fw_version == 0x020b00 ||
+                   info->fw_version == 0x020030) {
+                       info->x_min = ETP_XMIN_V2;
+                       info->y_min = ETP_YMIN_V2;
+                       info->x_max = ETP_XMAX_V2;
+                       info->y_max = ETP_YMAX_V2;
+               } else {
+                       int i;
+                       int fixed_dpi;
+
+                       i = (info->fw_version > 0x020800 &&
+                            info->fw_version < 0x020900) ? 1 : 2;
+
+                       if (info->send_cmd(psmouse, ETP_FW_ID_QUERY, param))
+                               return -EINVAL;
+
+                       fixed_dpi = param[1] & 0x10;
+
+                       if (((info->fw_version >> 16) == 0x14) && fixed_dpi) {
+                               if (info->send_cmd(psmouse, ETP_SAMPLE_QUERY, param))
+                                       return -EINVAL;
+
+                               info->x_max = (info->capabilities[1] - i) * param[1] / 2;
+                               info->y_max = (info->capabilities[2] - i) * param[2] / 2;
+                       } else if (info->fw_version == 0x040216) {
+                               info->x_max = 819;
+                               info->y_max = 405;
+                       } else if (info->fw_version == 0x040219 || info->fw_version == 0x040215) {
+                               info->x_max = 900;
+                               info->y_max = 500;
+                       } else {
+                               info->x_max = (info->capabilities[1] - i) * 64;
+                               info->y_max = (info->capabilities[2] - i) * 64;
+                       }
+               }
+               break;
+
+       case 3:
+               if (info->send_cmd(psmouse, ETP_FW_ID_QUERY, param))
+                       return -EINVAL;
+
+               info->x_max = (0x0f & param[0]) << 8 | param[1];
+               info->y_max = (0xf0 & param[0]) << 4 | param[2];
+               break;
+
+       case 4:
+               if (info->send_cmd(psmouse, ETP_FW_ID_QUERY, param))
+                       return -EINVAL;
+
+               info->x_max = (0x0f & param[0]) << 8 | param[1];
+               info->y_max = (0xf0 & param[0]) << 4 | param[2];
+               traces = info->capabilities[1];
+               if ((traces < 2) || (traces > info->x_max))
+                       return -EINVAL;
+
+               info->width = info->x_max / (traces - 1);
+               break;
+       }
+
        return 0;
 }
 
index 1197270..194503e 100644 (file)
@@ -144,8 +144,13 @@ struct elantech_device_info {
        unsigned char debug;
        unsigned char hw_version;
        unsigned int fw_version;
+       unsigned int x_min;
+       unsigned int y_min;
+       unsigned int x_max;
+       unsigned int y_max;
        unsigned int x_res;
        unsigned int y_res;
+       unsigned int width;
        unsigned int bus;
        bool paritycheck;
        bool jumpy_cursor;