1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Driver for MStar msg2638 touchscreens 4 * 5 * Copyright (c) 2021 Vincent Knecht <vincent.knecht@mailoo.org> 6 * 7 * Checksum and IRQ handler based on mstar_drv_common.c and 8 * mstar_drv_mutual_fw_control.c 9 * Copyright (c) 2006-2012 MStar Semiconductor, Inc. 10 * 11 * Driver structure based on zinitix.c by Michael Srba <Michael.Srba@seznam.cz> 12 */ 13 14 #include <linux/delay.h> 15 #include <linux/gpio/consumer.h> 16 #include <linux/i2c.h> 17 #include <linux/input.h> 18 #include <linux/input/mt.h> 19 #include <linux/input/touchscreen.h> 20 #include <linux/interrupt.h> 21 #include <linux/kernel.h> 22 #include <linux/module.h> 23 #include <linux/property.h> 24 #include <linux/regulator/consumer.h> 25 #include <linux/slab.h> 26 27 #define MODE_DATA_RAW 0x5A 28 29 #define MSG2138_MAX_FINGERS 2 30 #define MSG2638_MAX_FINGERS 5 31 32 #define MAX_BUTTONS 4 33 34 #define CHIP_ON_DELAY_MS 15 35 #define FIRMWARE_ON_DELAY_MS 50 36 #define RESET_DELAY_MIN_US 10000 37 #define RESET_DELAY_MAX_US 11000 38 39 struct msg_chip_data { 40 irq_handler_t irq_handler; 41 unsigned int max_fingers; 42 }; 43 44 struct msg2138_packet { 45 u8 xy_hi; /* higher bits of x and y coordinates */ 46 u8 x_low; 47 u8 y_low; 48 }; 49 50 struct msg2138_touch_event { 51 u8 magic; 52 struct msg2138_packet pkt[MSG2138_MAX_FINGERS]; 53 u8 checksum; 54 }; 55 56 struct msg2638_packet { 57 u8 xy_hi; /* higher bits of x and y coordinates */ 58 u8 x_low; 59 u8 y_low; 60 u8 pressure; 61 }; 62 63 struct msg2638_touch_event { 64 u8 mode; 65 struct msg2638_packet pkt[MSG2638_MAX_FINGERS]; 66 u8 proximity; 67 u8 checksum; 68 }; 69 70 struct msg2638_ts_data { 71 struct i2c_client *client; 72 struct input_dev *input_dev; 73 struct touchscreen_properties prop; 74 struct regulator_bulk_data supplies[2]; 75 struct gpio_desc *reset_gpiod; 76 int max_fingers; 77 u32 keycodes[MAX_BUTTONS]; 78 int num_keycodes; 79 }; 80 81 static u8 msg2638_checksum(u8 *data, u32 length) 82 { 83 s32 sum = 0; 84 u32 i; 85 86 for (i = 0; i < length; i++) 87 sum += data[i]; 88 89 return (u8)((-sum) & 0xFF); 90 } 91 92 static void msg2138_report_keys(struct msg2638_ts_data *msg2638, u8 keys) 93 { 94 int i; 95 96 /* keys can be 0x00 or 0xff when all keys have been released */ 97 if (keys == 0xff) 98 keys = 0; 99 100 for (i = 0; i < msg2638->num_keycodes; ++i) 101 input_report_key(msg2638->input_dev, msg2638->keycodes[i], 102 keys & BIT(i)); 103 } 104 105 static irqreturn_t msg2138_ts_irq_handler(int irq, void *msg2638_handler) 106 { 107 struct msg2638_ts_data *msg2638 = msg2638_handler; 108 struct i2c_client *client = msg2638->client; 109 struct input_dev *input = msg2638->input_dev; 110 struct msg2138_touch_event touch_event; 111 u32 len = sizeof(touch_event); 112 struct i2c_msg msg[] = { 113 { 114 .addr = client->addr, 115 .flags = I2C_M_RD, 116 .len = sizeof(touch_event), 117 .buf = (u8 *)&touch_event, 118 }, 119 }; 120 struct msg2138_packet *p0, *p1; 121 u16 x, y, delta_x, delta_y; 122 int ret; 123 124 ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); 125 if (ret != ARRAY_SIZE(msg)) { 126 dev_err(&client->dev, 127 "Failed I2C transfer in irq handler: %d\n", 128 ret < 0 ? ret : -EIO); 129 goto out; 130 } 131 132 if (msg2638_checksum((u8 *)&touch_event, len - 1) != 133 touch_event.checksum) { 134 dev_err(&client->dev, "Failed checksum!\n"); 135 goto out; 136 } 137 138 p0 = &touch_event.pkt[0]; 139 p1 = &touch_event.pkt[1]; 140 141 /* Ignore non-pressed finger data, but check for key code */ 142 if (p0->xy_hi == 0xFF && p0->x_low == 0xFF && p0->y_low == 0xFF) { 143 if (p1->xy_hi == 0xFF && p1->y_low == 0xFF) 144 msg2138_report_keys(msg2638, p1->x_low); 145 goto report; 146 } 147 148 x = ((p0->xy_hi & 0xF0) << 4) | p0->x_low; 149 y = ((p0->xy_hi & 0x0F) << 8) | p0->y_low; 150 151 input_mt_slot(input, 0); 152 input_mt_report_slot_state(input, MT_TOOL_FINGER, true); 153 touchscreen_report_pos(input, &msg2638->prop, x, y, true); 154 155 /* Ignore non-pressed finger data */ 156 if (p1->xy_hi == 0xFF && p1->x_low == 0xFF && p1->y_low == 0xFF) 157 goto report; 158 159 /* Second finger is reported as a delta position */ 160 delta_x = ((p1->xy_hi & 0xF0) << 4) | p1->x_low; 161 delta_y = ((p1->xy_hi & 0x0F) << 8) | p1->y_low; 162 163 /* Ignore second finger if both deltas equal 0 */ 164 if (delta_x == 0 && delta_y == 0) 165 goto report; 166 167 x += delta_x; 168 y += delta_y; 169 170 input_mt_slot(input, 1); 171 input_mt_report_slot_state(input, MT_TOOL_FINGER, true); 172 touchscreen_report_pos(input, &msg2638->prop, x, y, true); 173 174 report: 175 input_mt_sync_frame(msg2638->input_dev); 176 input_sync(msg2638->input_dev); 177 178 out: 179 return IRQ_HANDLED; 180 } 181 182 static irqreturn_t msg2638_ts_irq_handler(int irq, void *msg2638_handler) 183 { 184 struct msg2638_ts_data *msg2638 = msg2638_handler; 185 struct i2c_client *client = msg2638->client; 186 struct input_dev *input = msg2638->input_dev; 187 struct msg2638_touch_event touch_event; 188 u32 len = sizeof(touch_event); 189 struct i2c_msg msg[] = { 190 { 191 .addr = client->addr, 192 .flags = I2C_M_RD, 193 .len = sizeof(touch_event), 194 .buf = (u8 *)&touch_event, 195 }, 196 }; 197 struct msg2638_packet *p; 198 u16 x, y; 199 int ret; 200 int i; 201 202 ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); 203 if (ret != ARRAY_SIZE(msg)) { 204 dev_err(&client->dev, 205 "Failed I2C transfer in irq handler: %d\n", 206 ret < 0 ? ret : -EIO); 207 goto out; 208 } 209 210 if (touch_event.mode != MODE_DATA_RAW) 211 goto out; 212 213 if (msg2638_checksum((u8 *)&touch_event, len - 1) != 214 touch_event.checksum) { 215 dev_err(&client->dev, "Failed checksum!\n"); 216 goto out; 217 } 218 219 for (i = 0; i < msg2638->max_fingers; i++) { 220 p = &touch_event.pkt[i]; 221 222 /* Ignore non-pressed finger data */ 223 if (p->xy_hi == 0xFF && p->x_low == 0xFF && p->y_low == 0xFF) 224 continue; 225 226 x = (((p->xy_hi & 0xF0) << 4) | p->x_low); 227 y = (((p->xy_hi & 0x0F) << 8) | p->y_low); 228 229 input_mt_slot(input, i); 230 input_mt_report_slot_state(input, MT_TOOL_FINGER, true); 231 touchscreen_report_pos(input, &msg2638->prop, x, y, true); 232 } 233 234 input_mt_sync_frame(msg2638->input_dev); 235 input_sync(msg2638->input_dev); 236 237 out: 238 return IRQ_HANDLED; 239 } 240 241 static void msg2638_reset(struct msg2638_ts_data *msg2638) 242 { 243 gpiod_set_value_cansleep(msg2638->reset_gpiod, 1); 244 usleep_range(RESET_DELAY_MIN_US, RESET_DELAY_MAX_US); 245 gpiod_set_value_cansleep(msg2638->reset_gpiod, 0); 246 msleep(FIRMWARE_ON_DELAY_MS); 247 } 248 249 static int msg2638_start(struct msg2638_ts_data *msg2638) 250 { 251 int error; 252 253 error = regulator_bulk_enable(ARRAY_SIZE(msg2638->supplies), 254 msg2638->supplies); 255 if (error) { 256 dev_err(&msg2638->client->dev, 257 "Failed to enable regulators: %d\n", error); 258 return error; 259 } 260 261 msleep(CHIP_ON_DELAY_MS); 262 263 msg2638_reset(msg2638); 264 265 enable_irq(msg2638->client->irq); 266 267 return 0; 268 } 269 270 static int msg2638_stop(struct msg2638_ts_data *msg2638) 271 { 272 int error; 273 274 disable_irq(msg2638->client->irq); 275 276 error = regulator_bulk_disable(ARRAY_SIZE(msg2638->supplies), 277 msg2638->supplies); 278 if (error) { 279 dev_err(&msg2638->client->dev, 280 "Failed to disable regulators: %d\n", error); 281 return error; 282 } 283 284 return 0; 285 } 286 287 static int msg2638_input_open(struct input_dev *dev) 288 { 289 struct msg2638_ts_data *msg2638 = input_get_drvdata(dev); 290 291 return msg2638_start(msg2638); 292 } 293 294 static void msg2638_input_close(struct input_dev *dev) 295 { 296 struct msg2638_ts_data *msg2638 = input_get_drvdata(dev); 297 298 msg2638_stop(msg2638); 299 } 300 301 static int msg2638_init_input_dev(struct msg2638_ts_data *msg2638) 302 { 303 struct device *dev = &msg2638->client->dev; 304 struct input_dev *input_dev; 305 int error; 306 int i; 307 308 input_dev = devm_input_allocate_device(dev); 309 if (!input_dev) { 310 dev_err(dev, "Failed to allocate input device.\n"); 311 return -ENOMEM; 312 } 313 314 input_set_drvdata(input_dev, msg2638); 315 msg2638->input_dev = input_dev; 316 317 input_dev->name = "MStar TouchScreen"; 318 input_dev->phys = "input/ts"; 319 input_dev->id.bustype = BUS_I2C; 320 input_dev->open = msg2638_input_open; 321 input_dev->close = msg2638_input_close; 322 323 if (msg2638->num_keycodes) { 324 input_dev->keycode = msg2638->keycodes; 325 input_dev->keycodemax = msg2638->num_keycodes; 326 input_dev->keycodesize = sizeof(msg2638->keycodes[0]); 327 for (i = 0; i < msg2638->num_keycodes; i++) 328 input_set_capability(input_dev, 329 EV_KEY, msg2638->keycodes[i]); 330 } 331 332 input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_X); 333 input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_Y); 334 335 touchscreen_parse_properties(input_dev, true, &msg2638->prop); 336 if (!msg2638->prop.max_x || !msg2638->prop.max_y) { 337 dev_err(dev, "touchscreen-size-x and/or touchscreen-size-y not set in properties\n"); 338 return -EINVAL; 339 } 340 341 error = input_mt_init_slots(input_dev, msg2638->max_fingers, 342 INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); 343 if (error) { 344 dev_err(dev, "Failed to initialize MT slots: %d\n", error); 345 return error; 346 } 347 348 error = input_register_device(input_dev); 349 if (error) { 350 dev_err(dev, "Failed to register input device: %d\n", error); 351 return error; 352 } 353 354 return 0; 355 } 356 357 static int msg2638_ts_probe(struct i2c_client *client) 358 { 359 const struct msg_chip_data *chip_data; 360 struct device *dev = &client->dev; 361 struct msg2638_ts_data *msg2638; 362 int error; 363 364 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 365 dev_err(dev, "Failed to assert adapter's support for plain I2C.\n"); 366 return -ENXIO; 367 } 368 369 msg2638 = devm_kzalloc(dev, sizeof(*msg2638), GFP_KERNEL); 370 if (!msg2638) 371 return -ENOMEM; 372 373 msg2638->client = client; 374 i2c_set_clientdata(client, msg2638); 375 376 chip_data = device_get_match_data(&client->dev); 377 if (!chip_data || !chip_data->max_fingers) { 378 dev_err(dev, "Invalid or missing chip data\n"); 379 return -EINVAL; 380 } 381 382 msg2638->max_fingers = chip_data->max_fingers; 383 384 msg2638->supplies[0].supply = "vdd"; 385 msg2638->supplies[1].supply = "vddio"; 386 error = devm_regulator_bulk_get(dev, ARRAY_SIZE(msg2638->supplies), 387 msg2638->supplies); 388 if (error) { 389 dev_err(dev, "Failed to get regulators: %d\n", error); 390 return error; 391 } 392 393 msg2638->reset_gpiod = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); 394 if (IS_ERR(msg2638->reset_gpiod)) { 395 error = PTR_ERR(msg2638->reset_gpiod); 396 dev_err(dev, "Failed to request reset GPIO: %d\n", error); 397 return error; 398 } 399 400 msg2638->num_keycodes = device_property_count_u32(dev, 401 "linux,keycodes"); 402 if (msg2638->num_keycodes == -EINVAL) { 403 msg2638->num_keycodes = 0; 404 } else if (msg2638->num_keycodes < 0) { 405 dev_err(dev, "Unable to parse linux,keycodes property: %d\n", 406 msg2638->num_keycodes); 407 return msg2638->num_keycodes; 408 } else if (msg2638->num_keycodes > ARRAY_SIZE(msg2638->keycodes)) { 409 dev_warn(dev, "Found %d linux,keycodes but max is %zd, ignoring the rest\n", 410 msg2638->num_keycodes, ARRAY_SIZE(msg2638->keycodes)); 411 msg2638->num_keycodes = ARRAY_SIZE(msg2638->keycodes); 412 } 413 414 if (msg2638->num_keycodes > 0) { 415 error = device_property_read_u32_array(dev, "linux,keycodes", 416 msg2638->keycodes, 417 msg2638->num_keycodes); 418 if (error) { 419 dev_err(dev, "Unable to read linux,keycodes values: %d\n", 420 error); 421 return error; 422 } 423 } 424 425 error = devm_request_threaded_irq(dev, client->irq, 426 NULL, chip_data->irq_handler, 427 IRQF_ONESHOT | IRQF_NO_AUTOEN, 428 client->name, msg2638); 429 if (error) { 430 dev_err(dev, "Failed to request IRQ: %d\n", error); 431 return error; 432 } 433 434 error = msg2638_init_input_dev(msg2638); 435 if (error) { 436 dev_err(dev, "Failed to initialize input device: %d\n", error); 437 return error; 438 } 439 440 return 0; 441 } 442 443 static int msg2638_suspend(struct device *dev) 444 { 445 struct i2c_client *client = to_i2c_client(dev); 446 struct msg2638_ts_data *msg2638 = i2c_get_clientdata(client); 447 448 guard(mutex)(&msg2638->input_dev->mutex); 449 450 if (input_device_enabled(msg2638->input_dev)) 451 msg2638_stop(msg2638); 452 453 return 0; 454 } 455 456 static int msg2638_resume(struct device *dev) 457 { 458 struct i2c_client *client = to_i2c_client(dev); 459 struct msg2638_ts_data *msg2638 = i2c_get_clientdata(client); 460 int error; 461 462 guard(mutex)(&msg2638->input_dev->mutex); 463 464 if (input_device_enabled(msg2638->input_dev)) { 465 error = msg2638_start(msg2638); 466 if (error) 467 return error; 468 } 469 470 return 0; 471 } 472 473 static DEFINE_SIMPLE_DEV_PM_OPS(msg2638_pm_ops, msg2638_suspend, msg2638_resume); 474 475 static const struct msg_chip_data msg2138_data = { 476 .irq_handler = msg2138_ts_irq_handler, 477 .max_fingers = MSG2138_MAX_FINGERS, 478 }; 479 480 static const struct msg_chip_data msg2638_data = { 481 .irq_handler = msg2638_ts_irq_handler, 482 .max_fingers = MSG2638_MAX_FINGERS, 483 }; 484 485 static const struct of_device_id msg2638_of_match[] = { 486 { .compatible = "mstar,msg2138", .data = &msg2138_data }, 487 { .compatible = "mstar,msg2638", .data = &msg2638_data }, 488 { } 489 }; 490 MODULE_DEVICE_TABLE(of, msg2638_of_match); 491 492 static struct i2c_driver msg2638_ts_driver = { 493 .probe = msg2638_ts_probe, 494 .driver = { 495 .name = "MStar-TS", 496 .pm = pm_sleep_ptr(&msg2638_pm_ops), 497 .of_match_table = msg2638_of_match, 498 }, 499 }; 500 module_i2c_driver(msg2638_ts_driver); 501 502 MODULE_AUTHOR("Vincent Knecht <vincent.knecht@mailoo.org>"); 503 MODULE_DESCRIPTION("MStar MSG2638 touchscreen driver"); 504 MODULE_LICENSE("GPL v2"); 505