1 // SPDX-License-Identifier: GPL-2.0-only 2 #include <linux/delay.h> 3 #include <linux/gpio/consumer.h> 4 #include <linux/i2c.h> 5 #include <linux/input.h> 6 #include <linux/input/mt.h> 7 #include <linux/input/touchscreen.h> 8 #include <linux/interrupt.h> 9 #include <linux/module.h> 10 #include <linux/of_device.h> 11 #include <linux/sizes.h> 12 #include <linux/slab.h> 13 #include <asm/unaligned.h> 14 15 #define ILI2XXX_POLL_PERIOD 20 16 17 #define ILI210X_DATA_SIZE 64 18 #define ILI211X_DATA_SIZE 43 19 #define ILI251X_DATA_SIZE1 31 20 #define ILI251X_DATA_SIZE2 20 21 22 /* Touchscreen commands */ 23 #define REG_TOUCHDATA 0x10 24 #define REG_PANEL_INFO 0x20 25 #define REG_CALIBRATE 0xcc 26 27 struct ili2xxx_chip { 28 int (*read_reg)(struct i2c_client *client, u8 reg, 29 void *buf, size_t len); 30 int (*get_touch_data)(struct i2c_client *client, u8 *data); 31 bool (*parse_touch_data)(const u8 *data, unsigned int finger, 32 unsigned int *x, unsigned int *y); 33 bool (*continue_polling)(const u8 *data, bool touch); 34 unsigned int max_touches; 35 unsigned int resolution; 36 bool has_calibrate_reg; 37 }; 38 39 struct ili210x { 40 struct i2c_client *client; 41 struct input_dev *input; 42 struct gpio_desc *reset_gpio; 43 struct touchscreen_properties prop; 44 const struct ili2xxx_chip *chip; 45 bool stop; 46 }; 47 48 static int ili210x_read_reg(struct i2c_client *client, 49 u8 reg, void *buf, size_t len) 50 { 51 struct i2c_msg msg[] = { 52 { 53 .addr = client->addr, 54 .flags = 0, 55 .len = 1, 56 .buf = ®, 57 }, 58 { 59 .addr = client->addr, 60 .flags = I2C_M_RD, 61 .len = len, 62 .buf = buf, 63 } 64 }; 65 int error, ret; 66 67 ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); 68 if (ret != ARRAY_SIZE(msg)) { 69 error = ret < 0 ? ret : -EIO; 70 dev_err(&client->dev, "%s failed: %d\n", __func__, error); 71 return error; 72 } 73 74 return 0; 75 } 76 77 static int ili210x_read_touch_data(struct i2c_client *client, u8 *data) 78 { 79 return ili210x_read_reg(client, REG_TOUCHDATA, 80 data, ILI210X_DATA_SIZE); 81 } 82 83 static bool ili210x_touchdata_to_coords(const u8 *touchdata, 84 unsigned int finger, 85 unsigned int *x, unsigned int *y) 86 { 87 if (touchdata[0] & BIT(finger)) 88 return false; 89 90 *x = get_unaligned_be16(touchdata + 1 + (finger * 4) + 0); 91 *y = get_unaligned_be16(touchdata + 1 + (finger * 4) + 2); 92 93 return true; 94 } 95 96 static bool ili210x_check_continue_polling(const u8 *data, bool touch) 97 { 98 return data[0] & 0xf3; 99 } 100 101 static const struct ili2xxx_chip ili210x_chip = { 102 .read_reg = ili210x_read_reg, 103 .get_touch_data = ili210x_read_touch_data, 104 .parse_touch_data = ili210x_touchdata_to_coords, 105 .continue_polling = ili210x_check_continue_polling, 106 .max_touches = 2, 107 .has_calibrate_reg = true, 108 }; 109 110 static int ili211x_read_touch_data(struct i2c_client *client, u8 *data) 111 { 112 s16 sum = 0; 113 int error; 114 int ret; 115 int i; 116 117 ret = i2c_master_recv(client, data, ILI211X_DATA_SIZE); 118 if (ret != ILI211X_DATA_SIZE) { 119 error = ret < 0 ? ret : -EIO; 120 dev_err(&client->dev, "%s failed: %d\n", __func__, error); 121 return error; 122 } 123 124 /* This chip uses custom checksum at the end of data */ 125 for (i = 0; i < ILI211X_DATA_SIZE - 1; i++) 126 sum = (sum + data[i]) & 0xff; 127 128 if ((-sum & 0xff) != data[ILI211X_DATA_SIZE - 1]) { 129 dev_err(&client->dev, 130 "CRC error (crc=0x%02x expected=0x%02x)\n", 131 sum, data[ILI211X_DATA_SIZE - 1]); 132 return -EIO; 133 } 134 135 return 0; 136 } 137 138 static bool ili211x_touchdata_to_coords(const u8 *touchdata, 139 unsigned int finger, 140 unsigned int *x, unsigned int *y) 141 { 142 u32 data; 143 144 data = get_unaligned_be32(touchdata + 1 + (finger * 4) + 0); 145 if (data == 0xffffffff) /* Finger up */ 146 return false; 147 148 *x = ((touchdata[1 + (finger * 4) + 0] & 0xf0) << 4) | 149 touchdata[1 + (finger * 4) + 1]; 150 *y = ((touchdata[1 + (finger * 4) + 0] & 0x0f) << 8) | 151 touchdata[1 + (finger * 4) + 2]; 152 153 return true; 154 } 155 156 static bool ili211x_decline_polling(const u8 *data, bool touch) 157 { 158 return false; 159 } 160 161 static const struct ili2xxx_chip ili211x_chip = { 162 .read_reg = ili210x_read_reg, 163 .get_touch_data = ili211x_read_touch_data, 164 .parse_touch_data = ili211x_touchdata_to_coords, 165 .continue_polling = ili211x_decline_polling, 166 .max_touches = 10, 167 .resolution = 2048, 168 }; 169 170 static int ili251x_read_reg(struct i2c_client *client, 171 u8 reg, void *buf, size_t len) 172 { 173 int error; 174 int ret; 175 176 ret = i2c_master_send(client, ®, 1); 177 if (ret == 1) { 178 usleep_range(5000, 5500); 179 180 ret = i2c_master_recv(client, buf, len); 181 if (ret == len) 182 return 0; 183 } 184 185 error = ret < 0 ? ret : -EIO; 186 dev_err(&client->dev, "%s failed: %d\n", __func__, error); 187 return ret; 188 } 189 190 static int ili251x_read_touch_data(struct i2c_client *client, u8 *data) 191 { 192 int error; 193 194 error = ili251x_read_reg(client, REG_TOUCHDATA, 195 data, ILI251X_DATA_SIZE1); 196 if (!error && data[0] == 2) { 197 error = i2c_master_recv(client, data + ILI251X_DATA_SIZE1, 198 ILI251X_DATA_SIZE2); 199 if (error >= 0 && error != ILI251X_DATA_SIZE2) 200 error = -EIO; 201 } 202 203 return error; 204 } 205 206 static bool ili251x_touchdata_to_coords(const u8 *touchdata, 207 unsigned int finger, 208 unsigned int *x, unsigned int *y) 209 { 210 u16 val; 211 212 val = get_unaligned_be16(touchdata + 1 + (finger * 5) + 0); 213 if (!(val & BIT(15))) /* Touch indication */ 214 return false; 215 216 *x = val & 0x3fff; 217 *y = get_unaligned_be16(touchdata + 1 + (finger * 5) + 2); 218 219 return true; 220 } 221 222 static bool ili251x_check_continue_polling(const u8 *data, bool touch) 223 { 224 return touch; 225 } 226 227 static const struct ili2xxx_chip ili251x_chip = { 228 .read_reg = ili251x_read_reg, 229 .get_touch_data = ili251x_read_touch_data, 230 .parse_touch_data = ili251x_touchdata_to_coords, 231 .continue_polling = ili251x_check_continue_polling, 232 .max_touches = 10, 233 .has_calibrate_reg = true, 234 }; 235 236 static bool ili210x_report_events(struct ili210x *priv, u8 *touchdata) 237 { 238 struct input_dev *input = priv->input; 239 int i; 240 bool contact = false, touch; 241 unsigned int x = 0, y = 0; 242 243 for (i = 0; i < priv->chip->max_touches; i++) { 244 touch = priv->chip->parse_touch_data(touchdata, i, &x, &y); 245 246 input_mt_slot(input, i); 247 if (input_mt_report_slot_state(input, MT_TOOL_FINGER, touch)) { 248 touchscreen_report_pos(input, &priv->prop, x, y, true); 249 contact = true; 250 } 251 } 252 253 input_mt_report_pointer_emulation(input, false); 254 input_sync(input); 255 256 return contact; 257 } 258 259 static irqreturn_t ili210x_irq(int irq, void *irq_data) 260 { 261 struct ili210x *priv = irq_data; 262 struct i2c_client *client = priv->client; 263 const struct ili2xxx_chip *chip = priv->chip; 264 u8 touchdata[ILI210X_DATA_SIZE] = { 0 }; 265 bool keep_polling; 266 bool touch; 267 int error; 268 269 do { 270 error = chip->get_touch_data(client, touchdata); 271 if (error) { 272 dev_err(&client->dev, 273 "Unable to get touch data: %d\n", error); 274 break; 275 } 276 277 touch = ili210x_report_events(priv, touchdata); 278 keep_polling = chip->continue_polling(touchdata, touch); 279 if (keep_polling) 280 msleep(ILI2XXX_POLL_PERIOD); 281 } while (!priv->stop && keep_polling); 282 283 return IRQ_HANDLED; 284 } 285 286 static ssize_t ili210x_calibrate(struct device *dev, 287 struct device_attribute *attr, 288 const char *buf, size_t count) 289 { 290 struct i2c_client *client = to_i2c_client(dev); 291 struct ili210x *priv = i2c_get_clientdata(client); 292 unsigned long calibrate; 293 int rc; 294 u8 cmd = REG_CALIBRATE; 295 296 if (kstrtoul(buf, 10, &calibrate)) 297 return -EINVAL; 298 299 if (calibrate > 1) 300 return -EINVAL; 301 302 if (calibrate) { 303 rc = i2c_master_send(priv->client, &cmd, sizeof(cmd)); 304 if (rc != sizeof(cmd)) 305 return -EIO; 306 } 307 308 return count; 309 } 310 static DEVICE_ATTR(calibrate, S_IWUSR, NULL, ili210x_calibrate); 311 312 static struct attribute *ili210x_attributes[] = { 313 &dev_attr_calibrate.attr, 314 NULL, 315 }; 316 317 static umode_t ili210x_calibrate_visible(struct kobject *kobj, 318 struct attribute *attr, int index) 319 { 320 struct device *dev = kobj_to_dev(kobj); 321 struct i2c_client *client = to_i2c_client(dev); 322 struct ili210x *priv = i2c_get_clientdata(client); 323 324 return priv->chip->has_calibrate_reg; 325 } 326 327 static const struct attribute_group ili210x_attr_group = { 328 .attrs = ili210x_attributes, 329 .is_visible = ili210x_calibrate_visible, 330 }; 331 332 static void ili210x_power_down(void *data) 333 { 334 struct gpio_desc *reset_gpio = data; 335 336 gpiod_set_value_cansleep(reset_gpio, 1); 337 } 338 339 static void ili210x_stop(void *data) 340 { 341 struct ili210x *priv = data; 342 343 /* Tell ISR to quit even if there is a contact. */ 344 priv->stop = true; 345 } 346 347 static int ili210x_i2c_probe(struct i2c_client *client, 348 const struct i2c_device_id *id) 349 { 350 struct device *dev = &client->dev; 351 const struct ili2xxx_chip *chip; 352 struct ili210x *priv; 353 struct gpio_desc *reset_gpio; 354 struct input_dev *input; 355 int error; 356 unsigned int max_xy; 357 358 dev_dbg(dev, "Probing for ILI210X I2C Touschreen driver"); 359 360 chip = device_get_match_data(dev); 361 if (!chip && id) 362 chip = (const struct ili2xxx_chip *)id->driver_data; 363 if (!chip) { 364 dev_err(&client->dev, "unknown device model\n"); 365 return -ENODEV; 366 } 367 368 if (client->irq <= 0) { 369 dev_err(dev, "No IRQ!\n"); 370 return -EINVAL; 371 } 372 373 reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); 374 if (IS_ERR(reset_gpio)) 375 return PTR_ERR(reset_gpio); 376 377 if (reset_gpio) { 378 error = devm_add_action_or_reset(dev, ili210x_power_down, 379 reset_gpio); 380 if (error) 381 return error; 382 383 usleep_range(50, 100); 384 gpiod_set_value_cansleep(reset_gpio, 0); 385 msleep(100); 386 } 387 388 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 389 if (!priv) 390 return -ENOMEM; 391 392 input = devm_input_allocate_device(dev); 393 if (!input) 394 return -ENOMEM; 395 396 priv->client = client; 397 priv->input = input; 398 priv->reset_gpio = reset_gpio; 399 priv->chip = chip; 400 i2c_set_clientdata(client, priv); 401 402 /* Setup input device */ 403 input->name = "ILI210x Touchscreen"; 404 input->id.bustype = BUS_I2C; 405 406 /* Multi touch */ 407 max_xy = (chip->resolution ?: SZ_64K) - 1; 408 input_set_abs_params(input, ABS_MT_POSITION_X, 0, max_xy, 0, 0); 409 input_set_abs_params(input, ABS_MT_POSITION_Y, 0, max_xy, 0, 0); 410 touchscreen_parse_properties(input, true, &priv->prop); 411 412 error = input_mt_init_slots(input, priv->chip->max_touches, 413 INPUT_MT_DIRECT); 414 if (error) { 415 dev_err(dev, "Unable to set up slots, err: %d\n", error); 416 return error; 417 } 418 419 error = devm_request_threaded_irq(dev, client->irq, NULL, ili210x_irq, 420 IRQF_ONESHOT, client->name, priv); 421 if (error) { 422 dev_err(dev, "Unable to request touchscreen IRQ, err: %d\n", 423 error); 424 return error; 425 } 426 427 error = devm_add_action_or_reset(dev, ili210x_stop, priv); 428 if (error) 429 return error; 430 431 error = devm_device_add_group(dev, &ili210x_attr_group); 432 if (error) { 433 dev_err(dev, "Unable to create sysfs attributes, err: %d\n", 434 error); 435 return error; 436 } 437 438 error = input_register_device(priv->input); 439 if (error) { 440 dev_err(dev, "Cannot register input device, err: %d\n", error); 441 return error; 442 } 443 444 return 0; 445 } 446 447 static const struct i2c_device_id ili210x_i2c_id[] = { 448 { "ili210x", (long)&ili210x_chip }, 449 { "ili2117", (long)&ili211x_chip }, 450 { "ili251x", (long)&ili251x_chip }, 451 { } 452 }; 453 MODULE_DEVICE_TABLE(i2c, ili210x_i2c_id); 454 455 static const struct of_device_id ili210x_dt_ids[] = { 456 { .compatible = "ilitek,ili210x", .data = &ili210x_chip }, 457 { .compatible = "ilitek,ili2117", .data = &ili211x_chip }, 458 { .compatible = "ilitek,ili251x", .data = &ili251x_chip }, 459 { } 460 }; 461 MODULE_DEVICE_TABLE(of, ili210x_dt_ids); 462 463 static struct i2c_driver ili210x_ts_driver = { 464 .driver = { 465 .name = "ili210x_i2c", 466 .of_match_table = ili210x_dt_ids, 467 }, 468 .id_table = ili210x_i2c_id, 469 .probe = ili210x_i2c_probe, 470 }; 471 472 module_i2c_driver(ili210x_ts_driver); 473 474 MODULE_AUTHOR("Olivier Sobrie <olivier@sobrie.be>"); 475 MODULE_DESCRIPTION("ILI210X I2C Touchscreen Driver"); 476 MODULE_LICENSE("GPL"); 477