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

Input: elan_i2c - reduce the resume time for new devices

Newer controllers, such as Voxel, Delbin, Magple, Bobba and others, do not
need to be reset after issuing power-on command, and skipping reset saves
at least 100ms from resume time.

Note that if first attempt of re-initializing device fails we will not be
skipping reset on the subsequent ones.

Signed-off-by: Jingle Wu <jingle.wu@emc.com.tw>
Link: https://lore.kernel.org/r/20210226073537.4926-1-jingle.wu@emc.com.tw
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Jingle Wu and committed by
Dmitry Torokhov
ea16ef96 ad117c55

+53 -10
+5
drivers/input/mouse/elan_i2c.h
··· 55 55 #define ETP_FW_PAGE_SIZE_512 512 56 56 #define ETP_FW_SIGNATURE_SIZE 6 57 57 58 + #define ETP_PRODUCT_ID_DELBIN 0x00C2 59 + #define ETP_PRODUCT_ID_VOXEL 0x00BF 60 + #define ETP_PRODUCT_ID_MAGPIE 0x0120 61 + #define ETP_PRODUCT_ID_BOBBA 0x0121 62 + 58 63 struct i2c_client; 59 64 struct completion; 60 65
+48 -10
drivers/input/mouse/elan_i2c_core.c
··· 46 46 #define ETP_FINGER_WIDTH 15 47 47 #define ETP_RETRY_COUNT 3 48 48 49 + /* quirks to control the device */ 50 + #define ETP_QUIRK_QUICK_WAKEUP BIT(0) 51 + 49 52 /* The main device structure */ 50 53 struct elan_tp_data { 51 54 struct i2c_client *client; ··· 93 90 bool baseline_ready; 94 91 u8 clickpad; 95 92 bool middle_button; 93 + 94 + u32 quirks; /* Various quirks */ 96 95 }; 96 + 97 + static u32 elan_i2c_lookup_quirks(u16 ic_type, u16 product_id) 98 + { 99 + static const struct { 100 + u16 ic_type; 101 + u16 product_id; 102 + u32 quirks; 103 + } elan_i2c_quirks[] = { 104 + { 0x0D, ETP_PRODUCT_ID_DELBIN, ETP_QUIRK_QUICK_WAKEUP }, 105 + { 0x10, ETP_PRODUCT_ID_VOXEL, ETP_QUIRK_QUICK_WAKEUP }, 106 + { 0x14, ETP_PRODUCT_ID_MAGPIE, ETP_QUIRK_QUICK_WAKEUP }, 107 + { 0x14, ETP_PRODUCT_ID_BOBBA, ETP_QUIRK_QUICK_WAKEUP }, 108 + }; 109 + u32 quirks = 0; 110 + int i; 111 + 112 + for (i = 0; i < ARRAY_SIZE(elan_i2c_quirks); i++) { 113 + if (elan_i2c_quirks[i].ic_type == ic_type && 114 + elan_i2c_quirks[i].product_id == product_id) { 115 + quirks = elan_i2c_quirks[i].quirks; 116 + } 117 + } 118 + 119 + if (ic_type >= 0x0D && product_id >= 0x123) 120 + quirks |= ETP_QUIRK_QUICK_WAKEUP; 121 + 122 + return quirks; 123 + } 97 124 98 125 static int elan_get_fwinfo(u16 ic_type, u8 iap_version, u16 *validpage_count, 99 126 u32 *signature_address, u16 *page_size) ··· 291 258 return false; 292 259 } 293 260 294 - static int __elan_initialize(struct elan_tp_data *data) 261 + static int __elan_initialize(struct elan_tp_data *data, bool skip_reset) 295 262 { 296 263 struct i2c_client *client = data->client; 297 264 bool woken_up = false; 298 265 int error; 299 266 300 - error = data->ops->initialize(client); 301 - if (error) { 302 - dev_err(&client->dev, "device initialize failed: %d\n", error); 303 - return error; 267 + if (!skip_reset) { 268 + error = data->ops->initialize(client); 269 + if (error) { 270 + dev_err(&client->dev, "device initialize failed: %d\n", error); 271 + return error; 272 + } 304 273 } 305 274 306 275 error = elan_query_product(data); ··· 346 311 return 0; 347 312 } 348 313 349 - static int elan_initialize(struct elan_tp_data *data) 314 + static int elan_initialize(struct elan_tp_data *data, bool skip_reset) 350 315 { 351 316 int repeat = ETP_RETRY_COUNT; 352 317 int error; 353 318 354 319 do { 355 - error = __elan_initialize(data); 320 + error = __elan_initialize(data, skip_reset); 356 321 if (!error) 357 322 return 0; 358 323 324 + skip_reset = false; 359 325 msleep(30); 360 326 } while (--repeat > 0); 361 327 ··· 392 356 &data->report_len); 393 357 if (error) 394 358 return error; 359 + 360 + data->quirks = elan_i2c_lookup_quirks(data->ic_type, data->product_id); 395 361 396 362 error = elan_get_fwinfo(data->ic_type, data->iap_version, 397 363 &data->fw_validpage_count, ··· 584 546 data->ops->iap_reset(client); 585 547 } else { 586 548 /* Reinitialize TP after fw is updated */ 587 - elan_initialize(data); 549 + elan_initialize(data, false); 588 550 elan_query_device_info(data); 589 551 } 590 552 ··· 1285 1247 } 1286 1248 1287 1249 /* Initialize the touchpad. */ 1288 - error = elan_initialize(data); 1250 + error = elan_initialize(data, false); 1289 1251 if (error) 1290 1252 return error; 1291 1253 ··· 1422 1384 goto err; 1423 1385 } 1424 1386 1425 - error = elan_initialize(data); 1387 + error = elan_initialize(data, data->quirks & ETP_QUIRK_QUICK_WAKEUP); 1426 1388 if (error) 1427 1389 dev_err(dev, "initialize when resuming failed: %d\n", error); 1428 1390