Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Input: iqs269a - add support for slider gestures

This patch adds support for slider gestures that can be expressed
by the device. Each gesture (e.g. tap or hold) can be mapped to a
unique keycode for either slider 0 or 1.

With this change, raw slider coordinates are reported only if the
slider has no keycodes defined. This prevents unwanted mouse cur-
sor movement when expressing axial gestures (e.g. swipe) and also
eliminates some unnecessary I2C traffic.

Different revisions of silicon use different tap and swipe timeout
step sizes. Apply an appropriate scaling factor depending on which
revision is found.

To facilitate this change, store the iqs269_ver_info struct in the
driver's private data so that other functions can use it after the
driver has probed.

Last but not least, a former reserved field in iqs269_ver_info now
contains useful information; give it a name (fw_num).

Signed-off-by: Jeff LaBundy <jeff@labundy.com>
Link: https://lore.kernel.org/r/ZZMaT46WQq1/Nrsb@nixie71
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Jeff LaBundy and committed by
Dmitry Torokhov
00521a9b 65cdd3ad

+191 -29
+191 -29
drivers/input/misc/iqs269a.c
··· 9 9 * axial sliders presented by the device. 10 10 */ 11 11 12 + #include <linux/bits.h> 12 13 #include <linux/completion.h> 13 14 #include <linux/delay.h> 14 15 #include <linux/device.h> ··· 27 26 28 27 #define IQS269_VER_INFO 0x00 29 28 #define IQS269_VER_INFO_PROD_NUM 0x4F 29 + #define IQS269_VER_INFO_FW_NUM_2 0x03 30 + #define IQS269_VER_INFO_FW_NUM_3 0x10 30 31 31 32 #define IQS269_SYS_FLAGS 0x02 32 33 #define IQS269_SYS_FLAGS_SHOW_RESET BIT(15) ··· 56 53 #define IQS269_SYS_SETTINGS_ULP_UPDATE_MASK GENMASK(10, 8) 57 54 #define IQS269_SYS_SETTINGS_ULP_UPDATE_SHIFT 8 58 55 #define IQS269_SYS_SETTINGS_ULP_UPDATE_MAX 7 56 + #define IQS269_SYS_SETTINGS_SLIDER_SWIPE BIT(7) 59 57 #define IQS269_SYS_SETTINGS_RESEED_OFFSET BIT(6) 60 58 #define IQS269_SYS_SETTINGS_EVENT_MODE BIT(5) 61 59 #define IQS269_SYS_SETTINGS_EVENT_MODE_LP BIT(4) ··· 73 69 #define IQS269_FILT_STR_MAX 3 74 70 75 71 #define IQS269_EVENT_MASK_SYS BIT(6) 72 + #define IQS269_EVENT_MASK_GESTURE BIT(3) 76 73 #define IQS269_EVENT_MASK_DEEP BIT(2) 77 74 #define IQS269_EVENT_MASK_TOUCH BIT(1) 78 75 #define IQS269_EVENT_MASK_PROX BIT(0) ··· 101 96 #define IQS269_MISC_B_RESEED_UI_SEL_MAX 3 102 97 #define IQS269_MISC_B_TRACKING_UI_ENABLE BIT(4) 103 98 #define IQS269_MISC_B_FILT_STR_SLIDER GENMASK(1, 0) 99 + 100 + #define IQS269_TIMEOUT_TAP_MS_MAX 4080 101 + #define IQS269_TIMEOUT_SWIPE_MS_MAX 4080 102 + #define IQS269_THRESH_SWIPE_MAX 255 104 103 105 104 #define IQS269_CHx_ENG_A_MEAS_CAP_SIZE BIT(15) 106 105 #define IQS269_CHx_ENG_A_RX_GND_INACTIVE BIT(13) ··· 184 175 IQS269_EVENT_DEEP_UP, 185 176 }; 186 177 178 + enum iqs269_slider_id { 179 + IQS269_SLIDER_NONE, 180 + IQS269_SLIDER_KEY, 181 + IQS269_SLIDER_RAW, 182 + }; 183 + 184 + enum iqs269_gesture_id { 185 + IQS269_GESTURE_TAP, 186 + IQS269_GESTURE_HOLD, 187 + IQS269_GESTURE_FLICK_POS, 188 + IQS269_GESTURE_FLICK_NEG, 189 + IQS269_NUM_GESTURES, 190 + }; 191 + 187 192 struct iqs269_switch_desc { 188 193 unsigned int code; 189 194 bool enabled; ··· 257 234 u8 prod_num; 258 235 u8 sw_num; 259 236 u8 hw_num; 260 - u8 padding; 237 + u8 fw_num; 261 238 } __packed; 262 239 263 240 struct iqs269_ch_reg { ··· 308 285 struct regmap *regmap; 309 286 struct mutex lock; 310 287 struct iqs269_switch_desc switches[ARRAY_SIZE(iqs269_events)]; 288 + struct iqs269_ver_info ver_info; 311 289 struct iqs269_sys_reg sys_reg; 312 290 struct completion ati_done; 313 291 struct input_dev *keypad; 314 292 struct input_dev *slider[IQS269_NUM_SL]; 315 293 unsigned int keycode[ARRAY_SIZE(iqs269_events) * IQS269_NUM_CH]; 294 + unsigned int sl_code[IQS269_NUM_SL][IQS269_NUM_GESTURES]; 316 295 unsigned int ch_num; 317 296 bool hall_enable; 318 297 bool ati_current; 319 298 }; 299 + 300 + static enum iqs269_slider_id iqs269_slider_type(struct iqs269_private *iqs269, 301 + int slider_num) 302 + { 303 + int i; 304 + 305 + if (!iqs269->sys_reg.slider_select[slider_num]) 306 + return IQS269_SLIDER_NONE; 307 + 308 + for (i = 0; i < IQS269_NUM_GESTURES; i++) 309 + if (iqs269->sl_code[slider_num][i] != KEY_RESERVED) 310 + return IQS269_SLIDER_KEY; 311 + 312 + return IQS269_SLIDER_RAW; 313 + } 320 314 321 315 static int iqs269_ati_mode_set(struct iqs269_private *iqs269, 322 316 unsigned int ch_num, unsigned int mode) ··· 1044 1004 general |= (val << IQS269_SYS_SETTINGS_ULP_UPDATE_SHIFT); 1045 1005 } 1046 1006 1007 + if (device_property_present(&client->dev, "linux,keycodes")) { 1008 + int scale = 1; 1009 + int count = device_property_count_u32(&client->dev, 1010 + "linux,keycodes"); 1011 + if (count > IQS269_NUM_GESTURES * IQS269_NUM_SL) { 1012 + dev_err(&client->dev, "Too many keycodes present\n"); 1013 + return -EINVAL; 1014 + } else if (count < 0) { 1015 + dev_err(&client->dev, "Failed to count keycodes: %d\n", 1016 + count); 1017 + return count; 1018 + } 1019 + 1020 + error = device_property_read_u32_array(&client->dev, 1021 + "linux,keycodes", 1022 + *iqs269->sl_code, count); 1023 + if (error) { 1024 + dev_err(&client->dev, "Failed to read keycodes: %d\n", 1025 + error); 1026 + return error; 1027 + } 1028 + 1029 + if (device_property_present(&client->dev, 1030 + "azoteq,gesture-swipe")) 1031 + general |= IQS269_SYS_SETTINGS_SLIDER_SWIPE; 1032 + 1033 + /* 1034 + * Early revisions of silicon use a more granular step size for 1035 + * tap and swipe gesture timeouts; scale them appropriately. 1036 + */ 1037 + if (iqs269->ver_info.fw_num < IQS269_VER_INFO_FW_NUM_3) 1038 + scale = 4; 1039 + 1040 + if (!device_property_read_u32(&client->dev, 1041 + "azoteq,timeout-tap-ms", &val)) { 1042 + if (val > IQS269_TIMEOUT_TAP_MS_MAX / scale) { 1043 + dev_err(&client->dev, "Invalid timeout: %u\n", 1044 + val); 1045 + return -EINVAL; 1046 + } 1047 + 1048 + sys_reg->timeout_tap = val / (16 / scale); 1049 + } 1050 + 1051 + if (!device_property_read_u32(&client->dev, 1052 + "azoteq,timeout-swipe-ms", 1053 + &val)) { 1054 + if (val > IQS269_TIMEOUT_SWIPE_MS_MAX / scale) { 1055 + dev_err(&client->dev, "Invalid timeout: %u\n", 1056 + val); 1057 + return -EINVAL; 1058 + } 1059 + 1060 + sys_reg->timeout_swipe = val / (16 / scale); 1061 + } 1062 + 1063 + if (!device_property_read_u32(&client->dev, 1064 + "azoteq,thresh-swipe", &val)) { 1065 + if (val > IQS269_THRESH_SWIPE_MAX) { 1066 + dev_err(&client->dev, "Invalid threshold: %u\n", 1067 + val); 1068 + return -EINVAL; 1069 + } 1070 + 1071 + sys_reg->thresh_swipe = val; 1072 + } 1073 + 1074 + sys_reg->event_mask &= ~IQS269_EVENT_MASK_GESTURE; 1075 + } 1076 + 1047 1077 general &= ~IQS269_SYS_SETTINGS_RESEED_OFFSET; 1048 1078 if (device_property_present(&client->dev, "azoteq,reseed-offset")) 1049 1079 general |= IQS269_SYS_SETTINGS_RESEED_OFFSET; ··· 1122 1012 1123 1013 /* 1124 1014 * As per the datasheet, enable streaming during normal-power mode if 1125 - * either slider is in use. In that case, the device returns to event 1126 - * mode during low-power mode. 1015 + * raw coordinates will be read from either slider. In that case, the 1016 + * device returns to event mode during low-power mode. 1127 1017 */ 1128 - if (sys_reg->slider_select[0] || sys_reg->slider_select[1]) 1018 + if (iqs269_slider_type(iqs269, 0) == IQS269_SLIDER_RAW || 1019 + iqs269_slider_type(iqs269, 1) == IQS269_SLIDER_RAW) 1129 1020 general |= IQS269_SYS_SETTINGS_EVENT_MODE_LP; 1130 1021 1131 1022 general |= IQS269_SYS_SETTINGS_REDO_ATI; ··· 1217 1106 } 1218 1107 1219 1108 for (i = 0; i < IQS269_NUM_SL; i++) { 1220 - if (!iqs269->sys_reg.slider_select[i]) 1109 + if (iqs269_slider_type(iqs269, i) == IQS269_SLIDER_NONE) 1221 1110 continue; 1222 1111 1223 1112 iqs269->slider[i] = devm_input_allocate_device(&client->dev); 1224 1113 if (!iqs269->slider[i]) 1225 1114 return -ENOMEM; 1226 1115 1116 + iqs269->slider[i]->keycodemax = ARRAY_SIZE(iqs269->sl_code[i]); 1117 + iqs269->slider[i]->keycode = iqs269->sl_code[i]; 1118 + iqs269->slider[i]->keycodesize = sizeof(**iqs269->sl_code); 1119 + 1227 1120 iqs269->slider[i]->name = i ? "iqs269a_slider_1" 1228 1121 : "iqs269a_slider_0"; 1229 1122 iqs269->slider[i]->id.bustype = BUS_I2C; 1230 1123 1231 - input_set_capability(iqs269->slider[i], EV_KEY, BTN_TOUCH); 1232 - input_set_abs_params(iqs269->slider[i], ABS_X, 0, 255, 0, 0); 1124 + for (j = 0; j < IQS269_NUM_GESTURES; j++) 1125 + if (iqs269->sl_code[i][j] != KEY_RESERVED) 1126 + input_set_capability(iqs269->slider[i], EV_KEY, 1127 + iqs269->sl_code[i][j]); 1128 + 1129 + /* 1130 + * Present the slider as a narrow trackpad if one or more chan- 1131 + * nels have been selected to participate, but no gestures have 1132 + * been mapped to a keycode. 1133 + */ 1134 + if (iqs269_slider_type(iqs269, i) == IQS269_SLIDER_RAW) { 1135 + input_set_capability(iqs269->slider[i], 1136 + EV_KEY, BTN_TOUCH); 1137 + input_set_abs_params(iqs269->slider[i], 1138 + ABS_X, 0, 255, 0, 0); 1139 + } 1233 1140 1234 1141 error = input_register_device(iqs269->slider[i]); 1235 1142 if (error) { ··· 1296 1167 if (be16_to_cpu(flags.system) & IQS269_SYS_FLAGS_IN_ATI) 1297 1168 return 0; 1298 1169 1299 - error = regmap_raw_read(iqs269->regmap, IQS269_SLIDER_X, slider_x, 1300 - sizeof(slider_x)); 1301 - if (error) { 1302 - dev_err(&client->dev, "Failed to read slider position: %d\n", 1303 - error); 1304 - return error; 1170 + if (iqs269_slider_type(iqs269, 0) == IQS269_SLIDER_RAW || 1171 + iqs269_slider_type(iqs269, 1) == IQS269_SLIDER_RAW) { 1172 + error = regmap_raw_read(iqs269->regmap, IQS269_SLIDER_X, 1173 + slider_x, sizeof(slider_x)); 1174 + if (error) { 1175 + dev_err(&client->dev, 1176 + "Failed to read slider position: %d\n", error); 1177 + return error; 1178 + } 1305 1179 } 1306 1180 1307 1181 for (i = 0; i < IQS269_NUM_SL; i++) { 1308 - if (!iqs269->sys_reg.slider_select[i]) 1182 + flags.gesture >>= (i * IQS269_NUM_GESTURES); 1183 + 1184 + switch (iqs269_slider_type(iqs269, i)) { 1185 + case IQS269_SLIDER_NONE: 1309 1186 continue; 1310 1187 1311 - /* 1312 - * Report BTN_TOUCH if any channel that participates in the 1313 - * slider is in a state of touch. 1314 - */ 1315 - if (flags.states[IQS269_ST_OFFS_TOUCH] & 1316 - iqs269->sys_reg.slider_select[i]) { 1317 - input_report_key(iqs269->slider[i], BTN_TOUCH, 1); 1318 - input_report_abs(iqs269->slider[i], ABS_X, slider_x[i]); 1319 - } else { 1320 - input_report_key(iqs269->slider[i], BTN_TOUCH, 0); 1188 + case IQS269_SLIDER_KEY: 1189 + for (j = 0; j < IQS269_NUM_GESTURES; j++) 1190 + input_report_key(iqs269->slider[i], 1191 + iqs269->sl_code[i][j], 1192 + flags.gesture & BIT(j)); 1193 + 1194 + if (!(flags.gesture & (BIT(IQS269_GESTURE_FLICK_NEG) | 1195 + BIT(IQS269_GESTURE_FLICK_POS) | 1196 + BIT(IQS269_GESTURE_TAP)))) 1197 + break; 1198 + 1199 + input_sync(iqs269->slider[i]); 1200 + 1201 + /* 1202 + * Momentary gestures are followed by a complementary 1203 + * release cycle so as to emulate a full keystroke. 1204 + */ 1205 + for (j = 0; j < IQS269_NUM_GESTURES; j++) 1206 + if (j != IQS269_GESTURE_HOLD) 1207 + input_report_key(iqs269->slider[i], 1208 + iqs269->sl_code[i][j], 1209 + 0); 1210 + break; 1211 + 1212 + case IQS269_SLIDER_RAW: 1213 + /* 1214 + * The slider is considered to be in a state of touch 1215 + * if any selected channels are in a state of touch. 1216 + */ 1217 + state = flags.states[IQS269_ST_OFFS_TOUCH]; 1218 + state &= iqs269->sys_reg.slider_select[i]; 1219 + 1220 + input_report_key(iqs269->slider[i], BTN_TOUCH, state); 1221 + 1222 + if (state) 1223 + input_report_abs(iqs269->slider[i], 1224 + ABS_X, slider_x[i]); 1225 + break; 1321 1226 } 1322 1227 1323 1228 input_sync(iqs269->slider[i]); ··· 1758 1595 1759 1596 static int iqs269_probe(struct i2c_client *client) 1760 1597 { 1761 - struct iqs269_ver_info ver_info; 1762 1598 struct iqs269_private *iqs269; 1763 1599 int error; 1764 1600 ··· 1779 1617 mutex_init(&iqs269->lock); 1780 1618 init_completion(&iqs269->ati_done); 1781 1619 1782 - error = regmap_raw_read(iqs269->regmap, IQS269_VER_INFO, &ver_info, 1783 - sizeof(ver_info)); 1620 + error = regmap_raw_read(iqs269->regmap, IQS269_VER_INFO, 1621 + &iqs269->ver_info, sizeof(iqs269->ver_info)); 1784 1622 if (error) 1785 1623 return error; 1786 1624 1787 - if (ver_info.prod_num != IQS269_VER_INFO_PROD_NUM) { 1625 + if (iqs269->ver_info.prod_num != IQS269_VER_INFO_PROD_NUM) { 1788 1626 dev_err(&client->dev, "Unrecognized product number: 0x%02X\n", 1789 - ver_info.prod_num); 1627 + iqs269->ver_info.prod_num); 1790 1628 return -EINVAL; 1791 1629 } 1792 1630