aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse/elantech.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/mouse/elantech.c')
-rw-r--r--drivers/input/mouse/elantech.c80
1 files changed, 67 insertions, 13 deletions
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index e2a9867c19d5..d2c0db159b18 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -43,6 +43,24 @@ static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c,
43} 43}
44 44
45/* 45/*
46 * V3 and later support this fast command
47 */
48static int elantech_send_cmd(struct psmouse *psmouse, unsigned char c,
49 unsigned char *param)
50{
51 struct ps2dev *ps2dev = &psmouse->ps2dev;
52
53 if (ps2_command(ps2dev, NULL, ETP_PS2_CUSTOM_COMMAND) ||
54 ps2_command(ps2dev, NULL, c) ||
55 ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) {
56 psmouse_err(psmouse, "%s query 0x%02x failed.\n", __func__, c);
57 return -1;
58 }
59
60 return 0;
61}
62
63/*
46 * A retrying version of ps2_command 64 * A retrying version of ps2_command
47 */ 65 */
48static int elantech_ps2_command(struct psmouse *psmouse, 66static int elantech_ps2_command(struct psmouse *psmouse,
@@ -863,13 +881,13 @@ static int elantech_set_range(struct psmouse *psmouse,
863 i = (etd->fw_version > 0x020800 && 881 i = (etd->fw_version > 0x020800 &&
864 etd->fw_version < 0x020900) ? 1 : 2; 882 etd->fw_version < 0x020900) ? 1 : 2;
865 883
866 if (synaptics_send_cmd(psmouse, ETP_FW_ID_QUERY, param)) 884 if (etd->send_cmd(psmouse, ETP_FW_ID_QUERY, param))
867 return -1; 885 return -1;
868 886
869 fixed_dpi = param[1] & 0x10; 887 fixed_dpi = param[1] & 0x10;
870 888
871 if (((etd->fw_version >> 16) == 0x14) && fixed_dpi) { 889 if (((etd->fw_version >> 16) == 0x14) && fixed_dpi) {
872 if (synaptics_send_cmd(psmouse, ETP_SAMPLE_QUERY, param)) 890 if (etd->send_cmd(psmouse, ETP_SAMPLE_QUERY, param))
873 return -1; 891 return -1;
874 892
875 *x_max = (etd->capabilities[1] - i) * param[1] / 2; 893 *x_max = (etd->capabilities[1] - i) * param[1] / 2;
@@ -888,7 +906,7 @@ static int elantech_set_range(struct psmouse *psmouse,
888 break; 906 break;
889 907
890 case 3: 908 case 3:
891 if (synaptics_send_cmd(psmouse, ETP_FW_ID_QUERY, param)) 909 if (etd->send_cmd(psmouse, ETP_FW_ID_QUERY, param))
892 return -1; 910 return -1;
893 911
894 *x_max = (0x0f & param[0]) << 8 | param[1]; 912 *x_max = (0x0f & param[0]) << 8 | param[1];
@@ -896,7 +914,7 @@ static int elantech_set_range(struct psmouse *psmouse,
896 break; 914 break;
897 915
898 case 4: 916 case 4:
899 if (synaptics_send_cmd(psmouse, ETP_FW_ID_QUERY, param)) 917 if (etd->send_cmd(psmouse, ETP_FW_ID_QUERY, param))
900 return -1; 918 return -1;
901 919
902 *x_max = (0x0f & param[0]) << 8 | param[1]; 920 *x_max = (0x0f & param[0]) << 8 | param[1];
@@ -913,6 +931,30 @@ static int elantech_set_range(struct psmouse *psmouse,
913} 931}
914 932
915/* 933/*
934 * (value from firmware) * 10 + 790 = dpi
935 * we also have to convert dpi to dots/mm (*10/254 to avoid floating point)
936 */
937static unsigned int elantech_convert_res(unsigned int val)
938{
939 return (val * 10 + 790) * 10 / 254;
940}
941
942static int elantech_get_resolution_v4(struct psmouse *psmouse,
943 unsigned int *x_res,
944 unsigned int *y_res)
945{
946 unsigned char param[3];
947
948 if (elantech_send_cmd(psmouse, ETP_RESOLUTION_QUERY, param))
949 return -1;
950
951 *x_res = elantech_convert_res(param[1] & 0x0f);
952 *y_res = elantech_convert_res((param[1] & 0xf0) >> 4);
953
954 return 0;
955}
956
957/*
916 * Set the appropriate event bits for the input subsystem 958 * Set the appropriate event bits for the input subsystem
917 */ 959 */
918static int elantech_set_input_params(struct psmouse *psmouse) 960static int elantech_set_input_params(struct psmouse *psmouse)
@@ -920,6 +962,7 @@ static int elantech_set_input_params(struct psmouse *psmouse)
920 struct input_dev *dev = psmouse->dev; 962 struct input_dev *dev = psmouse->dev;
921 struct elantech_data *etd = psmouse->private; 963 struct elantech_data *etd = psmouse->private;
922 unsigned int x_min = 0, y_min = 0, x_max = 0, y_max = 0, width = 0; 964 unsigned int x_min = 0, y_min = 0, x_max = 0, y_max = 0, width = 0;
965 unsigned int x_res = 0, y_res = 0;
923 966
924 if (elantech_set_range(psmouse, &x_min, &y_min, &x_max, &y_max, &width)) 967 if (elantech_set_range(psmouse, &x_min, &y_min, &x_max, &y_max, &width))
925 return -1; 968 return -1;
@@ -967,10 +1010,20 @@ static int elantech_set_input_params(struct psmouse *psmouse)
967 break; 1010 break;
968 1011
969 case 4: 1012 case 4:
1013 if (elantech_get_resolution_v4(psmouse, &x_res, &y_res)) {
1014 /*
1015 * if query failed, print a warning and leave the values
1016 * zero to resemble synaptics.c behavior.
1017 */
1018 psmouse_warn(psmouse, "couldn't query resolution data.\n");
1019 }
1020
970 __set_bit(BTN_TOOL_QUADTAP, dev->keybit); 1021 __set_bit(BTN_TOOL_QUADTAP, dev->keybit);
971 /* For X to recognize me as touchpad. */ 1022 /* For X to recognize me as touchpad. */
972 input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0); 1023 input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
973 input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0); 1024 input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
1025 input_abs_set_res(dev, ABS_X, x_res);
1026 input_abs_set_res(dev, ABS_Y, y_res);
974 /* 1027 /*
975 * range of pressure and width is the same as v2, 1028 * range of pressure and width is the same as v2,
976 * report ABS_PRESSURE, ABS_TOOL_WIDTH for compatibility. 1029 * report ABS_PRESSURE, ABS_TOOL_WIDTH for compatibility.
@@ -983,6 +1036,8 @@ static int elantech_set_input_params(struct psmouse *psmouse)
983 input_mt_init_slots(dev, ETP_MAX_FINGERS); 1036 input_mt_init_slots(dev, ETP_MAX_FINGERS);
984 input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0); 1037 input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
985 input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0); 1038 input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
1039 input_abs_set_res(dev, ABS_MT_POSITION_X, x_res);
1040 input_abs_set_res(dev, ABS_MT_POSITION_Y, y_res);
986 input_set_abs_params(dev, ABS_MT_PRESSURE, ETP_PMIN_V2, 1041 input_set_abs_params(dev, ABS_MT_PRESSURE, ETP_PMIN_V2,
987 ETP_PMAX_V2, 0, 0); 1042 ETP_PMAX_V2, 0, 0);
988 /* 1043 /*
@@ -1031,16 +1086,13 @@ static ssize_t elantech_set_int_attr(struct psmouse *psmouse,
1031 struct elantech_data *etd = psmouse->private; 1086 struct elantech_data *etd = psmouse->private;
1032 struct elantech_attr_data *attr = data; 1087 struct elantech_attr_data *attr = data;
1033 unsigned char *reg = (unsigned char *) etd + attr->field_offset; 1088 unsigned char *reg = (unsigned char *) etd + attr->field_offset;
1034 unsigned long value; 1089 unsigned char value;
1035 int err; 1090 int err;
1036 1091
1037 err = strict_strtoul(buf, 16, &value); 1092 err = kstrtou8(buf, 16, &value);
1038 if (err) 1093 if (err)
1039 return err; 1094 return err;
1040 1095
1041 if (value > 0xff)
1042 return -EINVAL;
1043
1044 /* Do we need to preserve some bits for version 2 hardware too? */ 1096 /* Do we need to preserve some bits for version 2 hardware too? */
1045 if (etd->hw_version == 1) { 1097 if (etd->hw_version == 1) {
1046 if (attr->reg == 0x10) 1098 if (attr->reg == 0x10)
@@ -1233,9 +1285,11 @@ static int elantech_set_properties(struct elantech_data *etd)
1233 } 1285 }
1234 } 1286 }
1235 1287
1236 /* 1288 /* decide which send_cmd we're gonna use early */
1237 * Turn on packet checking by default. 1289 etd->send_cmd = etd->hw_version >= 3 ? elantech_send_cmd :
1238 */ 1290 synaptics_send_cmd;
1291
1292 /* Turn on packet checking by default */
1239 etd->paritycheck = 1; 1293 etd->paritycheck = 1;
1240 1294
1241 /* 1295 /*
@@ -1291,7 +1345,7 @@ int elantech_init(struct psmouse *psmouse)
1291 "assuming hardware version %d (with firmware version 0x%02x%02x%02x)\n", 1345 "assuming hardware version %d (with firmware version 0x%02x%02x%02x)\n",
1292 etd->hw_version, param[0], param[1], param[2]); 1346 etd->hw_version, param[0], param[1], param[2]);
1293 1347
1294 if (synaptics_send_cmd(psmouse, ETP_CAPABILITIES_QUERY, 1348 if (etd->send_cmd(psmouse, ETP_CAPABILITIES_QUERY,
1295 etd->capabilities)) { 1349 etd->capabilities)) {
1296 psmouse_err(psmouse, "failed to query capabilities.\n"); 1350 psmouse_err(psmouse, "failed to query capabilities.\n");
1297 goto init_fail; 1351 goto init_fail;