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/touchscreen: imagis: Add support for Imagis IST3038B

Imagis IST3038B is another variant of Imagis IST3038 IC, which has
a different register interface from IST3038C (possibly firmware defined).
This should also work for IST3044B (though untested), however other
variants using this interface/protocol(IST3026, IST3032, IST3026B,
IST3032B) have a different format for coordinates, and they'd need
additional effort to be supported by this driver.

Signed-off-by: Markuss Broks <markuss.broks@gmail.com>
Signed-off-by: Karel Balej <balejk@matfyz.cz>
Link: https://lore.kernel.org/r/20240301164659.13240-4-karelb@gimli.ms.mff.cuni.cz
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Markuss Broks and committed by
Dmitry Torokhov
10ad7d7a c53d309a

+47 -11
+47 -11
drivers/input/touchscreen/imagis.c
··· 11 11 #include <linux/property.h> 12 12 #include <linux/regulator/consumer.h> 13 13 14 + #define IST3038B_REG_STATUS 0x20 15 + #define IST3038B_REG_CHIPID 0x30 16 + #define IST3038B_WHOAMI 0x30380b 17 + 14 18 #define IST3038C_HIB_ACCESS (0x800B << 16) 15 19 #define IST3038C_DIRECT_ACCESS BIT(31) 16 - #define IST3038C_REG_CHIPID 0x40001000 20 + #define IST3038C_REG_CHIPID (0x40001000 | IST3038C_DIRECT_ACCESS) 17 21 #define IST3038C_REG_HIB_BASE 0x30000100 18 22 #define IST3038C_REG_TOUCH_STATUS (IST3038C_REG_HIB_BASE | IST3038C_HIB_ACCESS) 19 23 #define IST3038C_REG_TOUCH_COORD (IST3038C_REG_HIB_BASE | IST3038C_HIB_ACCESS | 0x8) ··· 35 31 #define IST3038C_FINGER_COUNT_SHIFT 12 36 32 #define IST3038C_FINGER_STATUS_MASK GENMASK(9, 0) 37 33 34 + struct imagis_properties { 35 + unsigned int interrupt_msg_cmd; 36 + unsigned int touch_coord_cmd; 37 + unsigned int whoami_cmd; 38 + unsigned int whoami_val; 39 + bool protocol_b; 40 + }; 41 + 38 42 struct imagis_ts { 39 43 struct i2c_client *client; 44 + const struct imagis_properties *tdata; 40 45 struct input_dev *input_dev; 41 46 struct touchscreen_properties prop; 42 47 struct regulator_bulk_data supplies[2]; ··· 97 84 int i; 98 85 int error; 99 86 100 - error = imagis_i2c_read_reg(ts, IST3038C_REG_INTR_MESSAGE, 101 - &intr_message); 87 + error = imagis_i2c_read_reg(ts, ts->tdata->interrupt_msg_cmd, &intr_message); 102 88 if (error) { 103 89 dev_err(&ts->client->dev, 104 90 "failed to read the interrupt message: %d\n", error); ··· 116 104 finger_pressed = intr_message & IST3038C_FINGER_STATUS_MASK; 117 105 118 106 for (i = 0; i < finger_count; i++) { 119 - error = imagis_i2c_read_reg(ts, 120 - IST3038C_REG_TOUCH_COORD + (i * 4), 121 - &finger_status); 107 + if (ts->tdata->protocol_b) 108 + error = imagis_i2c_read_reg(ts, 109 + ts->tdata->touch_coord_cmd, &finger_status); 110 + else 111 + error = imagis_i2c_read_reg(ts, 112 + ts->tdata->touch_coord_cmd + (i * 4), 113 + &finger_status); 122 114 if (error) { 123 115 dev_err(&ts->client->dev, 124 116 "failed to read coordinates for finger %d: %d\n", ··· 277 261 278 262 ts->client = i2c; 279 263 264 + ts->tdata = device_get_match_data(dev); 265 + if (!ts->tdata) { 266 + dev_err(dev, "missing chip data\n"); 267 + return -EINVAL; 268 + } 269 + 280 270 error = imagis_init_regulators(ts); 281 271 if (error) { 282 272 dev_err(dev, "regulator init error: %d\n", error); ··· 301 279 return error; 302 280 } 303 281 304 - error = imagis_i2c_read_reg(ts, 305 - IST3038C_REG_CHIPID | IST3038C_DIRECT_ACCESS, 306 - &chip_id); 282 + error = imagis_i2c_read_reg(ts, ts->tdata->whoami_cmd, &chip_id); 307 283 if (error) { 308 284 dev_err(dev, "chip ID read failure: %d\n", error); 309 285 return error; 310 286 } 311 287 312 - if (chip_id != IST3038C_WHOAMI) { 288 + if (chip_id != ts->tdata->whoami_val) { 313 289 dev_err(dev, "unknown chip ID: 0x%x\n", chip_id); 314 290 return -EINVAL; 315 291 } ··· 363 343 364 344 static DEFINE_SIMPLE_DEV_PM_OPS(imagis_pm_ops, imagis_suspend, imagis_resume); 365 345 346 + static const struct imagis_properties imagis_3038b_data = { 347 + .interrupt_msg_cmd = IST3038B_REG_STATUS, 348 + .touch_coord_cmd = IST3038B_REG_STATUS, 349 + .whoami_cmd = IST3038B_REG_CHIPID, 350 + .whoami_val = IST3038B_WHOAMI, 351 + .protocol_b = true, 352 + }; 353 + 354 + static const struct imagis_properties imagis_3038c_data = { 355 + .interrupt_msg_cmd = IST3038C_REG_INTR_MESSAGE, 356 + .touch_coord_cmd = IST3038C_REG_TOUCH_COORD, 357 + .whoami_cmd = IST3038C_REG_CHIPID, 358 + .whoami_val = IST3038C_WHOAMI, 359 + }; 360 + 366 361 #ifdef CONFIG_OF 367 362 static const struct of_device_id imagis_of_match[] = { 368 - { .compatible = "imagis,ist3038c", }, 363 + { .compatible = "imagis,ist3038b", .data = &imagis_3038b_data }, 364 + { .compatible = "imagis,ist3038c", .data = &imagis_3038c_data }, 369 365 { }, 370 366 }; 371 367 MODULE_DEVICE_TABLE(of, imagis_of_match);