1 /* 2 * Copyright (c) 2017 Samsung Electronics Co., Ltd. 3 * Author: Andi Shyti <andi.shyti@samsung.com> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * Samsung S6SY761 Touchscreen device driver 10 */ 11 12 #include <asm/unaligned.h> 13 #include <linux/delay.h> 14 #include <linux/i2c.h> 15 #include <linux/input/mt.h> 16 #include <linux/input/touchscreen.h> 17 #include <linux/interrupt.h> 18 #include <linux/irq.h> 19 #include <linux/module.h> 20 #include <linux/pm_runtime.h> 21 #include <linux/regulator/consumer.h> 22 23 /* commands */ 24 #define S6SY761_SENSE_ON 0x10 25 #define S6SY761_SENSE_OFF 0x11 26 #define S6SY761_TOUCH_FUNCTION 0x30 /* R/W for get/set */ 27 #define S6SY761_FIRMWARE_INTEGRITY 0x21 28 #define S6SY761_PANEL_INFO 0x23 29 #define S6SY761_DEVICE_ID 0x52 30 #define S6SY761_BOOT_STATUS 0x55 31 #define S6SY761_READ_ONE_EVENT 0x60 32 #define S6SY761_READ_ALL_EVENT 0x61 33 #define S6SY761_CLEAR_EVENT_STACK 0x62 34 #define S6SY761_APPLICATION_MODE 0xe4 35 36 /* events */ 37 #define S6SY761_EVENT_INFO 0x02 38 #define S6SY761_EVENT_VENDOR_INFO 0x07 39 40 /* info */ 41 #define S6SY761_INFO_BOOT_COMPLETE 0x00 42 43 /* firmware status */ 44 #define S6SY761_FW_OK 0x80 45 46 /* 47 * the functionalities are put as a reference 48 * as in the device I am using none of them 49 * works therefore not used in this driver yet. 50 */ 51 /* touchscreen functionalities */ 52 #define S6SY761_MASK_TOUCH BIT(0) 53 #define S6SY761_MASK_HOVER BIT(1) 54 #define S6SY761_MASK_COVER BIT(2) 55 #define S6SY761_MASK_GLOVE BIT(3) 56 #define S6SY761_MASK_STYLUS BIT(4) 57 #define S6SY761_MASK_PALM BIT(5) 58 #define S6SY761_MASK_WET BIT(6) 59 #define S6SY761_MASK_PROXIMITY BIT(7) 60 61 /* boot status (BS) */ 62 #define S6SY761_BS_BOOT_LOADER 0x10 63 #define S6SY761_BS_APPLICATION 0x20 64 65 /* event id */ 66 #define S6SY761_EVENT_ID_COORDINATE 0x00 67 #define S6SY761_EVENT_ID_STATUS 0x01 68 69 /* event register masks */ 70 #define S6SY761_MASK_TOUCH_STATE 0xc0 /* byte 0 */ 71 #define S6SY761_MASK_TID 0x3c 72 #define S6SY761_MASK_EID 0x03 73 #define S6SY761_MASK_X 0xf0 /* byte 3 */ 74 #define S6SY761_MASK_Y 0x0f 75 #define S6SY761_MASK_Z 0x3f /* byte 6 */ 76 #define S6SY761_MASK_LEFT_EVENTS 0x3f /* byte 7 */ 77 #define S6SY761_MASK_TOUCH_TYPE 0xc0 /* MSB in byte 6, LSB in byte 7 */ 78 79 /* event touch state values */ 80 #define S6SY761_TS_NONE 0x00 81 #define S6SY761_TS_PRESS 0x01 82 #define S6SY761_TS_MOVE 0x02 83 #define S6SY761_TS_RELEASE 0x03 84 85 /* application modes */ 86 #define S6SY761_APP_NORMAL 0x0 87 #define S6SY761_APP_LOW_POWER 0x1 88 #define S6SY761_APP_TEST 0x2 89 #define S6SY761_APP_FLASH 0x3 90 #define S6SY761_APP_SLEEP 0x4 91 92 #define S6SY761_EVENT_SIZE 8 93 #define S6SY761_EVENT_COUNT 32 94 #define S6SY761_DEVID_SIZE 3 95 #define S6SY761_PANEL_ID_SIZE 11 96 #define S6SY761_TS_STATUS_SIZE 5 97 #define S6SY761_MAX_FINGERS 10 98 99 #define S6SY761_DEV_NAME "s6sy761" 100 101 enum s6sy761_regulators { 102 S6SY761_REGULATOR_VDD, 103 S6SY761_REGULATOR_AVDD, 104 }; 105 106 struct s6sy761_data { 107 struct i2c_client *client; 108 struct regulator_bulk_data regulators[2]; 109 struct input_dev *input; 110 struct touchscreen_properties prop; 111 112 u8 data[S6SY761_EVENT_SIZE * S6SY761_EVENT_COUNT]; 113 114 u16 devid; 115 u8 tx_channel; 116 }; 117 118 /* 119 * We can't simply use i2c_smbus_read_i2c_block_data because we 120 * need to read more than 255 bytes 121 */ 122 static int s6sy761_read_events(struct s6sy761_data *sdata, u16 n_events) 123 { 124 u8 cmd = S6SY761_READ_ALL_EVENT; 125 struct i2c_msg msgs[2] = { 126 { 127 .addr = sdata->client->addr, 128 .len = 1, 129 .buf = &cmd, 130 }, 131 { 132 .addr = sdata->client->addr, 133 .flags = I2C_M_RD, 134 .len = (n_events * S6SY761_EVENT_SIZE), 135 .buf = sdata->data + S6SY761_EVENT_SIZE, 136 }, 137 }; 138 int ret; 139 140 ret = i2c_transfer(sdata->client->adapter, msgs, ARRAY_SIZE(msgs)); 141 if (ret < 0) 142 return ret; 143 144 return ret == ARRAY_SIZE(msgs) ? 0 : -EIO; 145 } 146 147 static void s6sy761_report_coordinates(struct s6sy761_data *sdata, 148 u8 *event, u8 tid) 149 { 150 u8 major = event[4]; 151 u8 minor = event[5]; 152 u8 z = event[6] & S6SY761_MASK_Z; 153 u16 x = (event[1] << 3) | ((event[3] & S6SY761_MASK_X) >> 4); 154 u16 y = (event[2] << 3) | (event[3] & S6SY761_MASK_Y); 155 156 input_mt_slot(sdata->input, tid); 157 158 input_mt_report_slot_state(sdata->input, MT_TOOL_FINGER, true); 159 input_report_abs(sdata->input, ABS_MT_POSITION_X, x); 160 input_report_abs(sdata->input, ABS_MT_POSITION_Y, y); 161 input_report_abs(sdata->input, ABS_MT_TOUCH_MAJOR, major); 162 input_report_abs(sdata->input, ABS_MT_TOUCH_MINOR, minor); 163 input_report_abs(sdata->input, ABS_MT_PRESSURE, z); 164 165 input_sync(sdata->input); 166 } 167 168 static void s6sy761_report_release(struct s6sy761_data *sdata, 169 u8 *event, u8 tid) 170 { 171 input_mt_slot(sdata->input, tid); 172 input_mt_report_slot_state(sdata->input, MT_TOOL_FINGER, false); 173 174 input_sync(sdata->input); 175 } 176 177 static void s6sy761_handle_coordinates(struct s6sy761_data *sdata, u8 *event) 178 { 179 u8 tid; 180 u8 touch_state; 181 182 if (unlikely(!(event[0] & S6SY761_MASK_TID))) 183 return; 184 185 tid = ((event[0] & S6SY761_MASK_TID) >> 2) - 1; 186 touch_state = (event[0] & S6SY761_MASK_TOUCH_STATE) >> 6; 187 188 switch (touch_state) { 189 190 case S6SY761_TS_NONE: 191 break; 192 case S6SY761_TS_RELEASE: 193 s6sy761_report_release(sdata, event, tid); 194 break; 195 case S6SY761_TS_PRESS: 196 case S6SY761_TS_MOVE: 197 s6sy761_report_coordinates(sdata, event, tid); 198 break; 199 } 200 } 201 202 static void s6sy761_handle_events(struct s6sy761_data *sdata, u8 n_events) 203 { 204 int i; 205 206 for (i = 0; i < n_events; i++) { 207 u8 *event = &sdata->data[i * S6SY761_EVENT_SIZE]; 208 u8 event_id = event[0] & S6SY761_MASK_EID; 209 210 if (!event[0]) 211 return; 212 213 switch (event_id) { 214 215 case S6SY761_EVENT_ID_COORDINATE: 216 s6sy761_handle_coordinates(sdata, event); 217 break; 218 219 case S6SY761_EVENT_ID_STATUS: 220 break; 221 222 default: 223 break; 224 } 225 } 226 } 227 228 static irqreturn_t s6sy761_irq_handler(int irq, void *dev) 229 { 230 struct s6sy761_data *sdata = dev; 231 int ret; 232 u8 n_events; 233 234 ret = i2c_smbus_read_i2c_block_data(sdata->client, 235 S6SY761_READ_ONE_EVENT, 236 S6SY761_EVENT_SIZE, 237 sdata->data); 238 if (ret < 0) { 239 dev_err(&sdata->client->dev, "failed to read events\n"); 240 return IRQ_HANDLED; 241 } 242 243 if (!sdata->data[0]) 244 return IRQ_HANDLED; 245 246 n_events = sdata->data[7] & S6SY761_MASK_LEFT_EVENTS; 247 if (unlikely(n_events > S6SY761_EVENT_COUNT - 1)) 248 return IRQ_HANDLED; 249 250 if (n_events) { 251 ret = s6sy761_read_events(sdata, n_events); 252 if (ret < 0) { 253 dev_err(&sdata->client->dev, "failed to read events\n"); 254 return IRQ_HANDLED; 255 } 256 } 257 258 s6sy761_handle_events(sdata, n_events + 1); 259 260 return IRQ_HANDLED; 261 } 262 263 static int s6sy761_input_open(struct input_dev *dev) 264 { 265 struct s6sy761_data *sdata = input_get_drvdata(dev); 266 267 return i2c_smbus_write_byte(sdata->client, S6SY761_SENSE_ON); 268 } 269 270 static void s6sy761_input_close(struct input_dev *dev) 271 { 272 struct s6sy761_data *sdata = input_get_drvdata(dev); 273 int ret; 274 275 ret = i2c_smbus_write_byte(sdata->client, S6SY761_SENSE_OFF); 276 if (ret) 277 dev_err(&sdata->client->dev, "failed to turn off sensing\n"); 278 } 279 280 static ssize_t s6sy761_sysfs_devid(struct device *dev, 281 struct device_attribute *attr, char *buf) 282 { 283 struct s6sy761_data *sdata = dev_get_drvdata(dev); 284 285 return sprintf(buf, "%#x\n", sdata->devid); 286 } 287 288 static DEVICE_ATTR(devid, 0444, s6sy761_sysfs_devid, NULL); 289 290 static struct attribute *s6sy761_sysfs_attrs[] = { 291 &dev_attr_devid.attr, 292 NULL 293 }; 294 295 static struct attribute_group s6sy761_attribute_group = { 296 .attrs = s6sy761_sysfs_attrs 297 }; 298 299 static int s6sy761_power_on(struct s6sy761_data *sdata) 300 { 301 u8 buffer[S6SY761_EVENT_SIZE]; 302 u8 event; 303 int ret; 304 305 ret = regulator_bulk_enable(ARRAY_SIZE(sdata->regulators), 306 sdata->regulators); 307 if (ret) 308 return ret; 309 310 msleep(140); 311 312 /* double check whether the touch is functional */ 313 ret = i2c_smbus_read_i2c_block_data(sdata->client, 314 S6SY761_READ_ONE_EVENT, 315 S6SY761_EVENT_SIZE, 316 buffer); 317 if (ret < 0) 318 return ret; 319 320 event = (buffer[0] >> 2) & 0xf; 321 322 if ((event != S6SY761_EVENT_INFO && 323 event != S6SY761_EVENT_VENDOR_INFO) || 324 buffer[1] != S6SY761_INFO_BOOT_COMPLETE) { 325 return -ENODEV; 326 } 327 328 ret = i2c_smbus_read_byte_data(sdata->client, S6SY761_BOOT_STATUS); 329 if (ret < 0) 330 return ret; 331 332 /* for some reasons the device might be stuck in the bootloader */ 333 if (ret != S6SY761_BS_APPLICATION) 334 return -ENODEV; 335 336 /* enable touch functionality */ 337 ret = i2c_smbus_write_word_data(sdata->client, 338 S6SY761_TOUCH_FUNCTION, 339 S6SY761_MASK_TOUCH); 340 if (ret) 341 return ret; 342 343 return 0; 344 } 345 346 static int s6sy761_hw_init(struct s6sy761_data *sdata, 347 unsigned int *max_x, unsigned int *max_y) 348 { 349 u8 buffer[S6SY761_PANEL_ID_SIZE]; /* larger read size */ 350 int ret; 351 352 ret = s6sy761_power_on(sdata); 353 if (ret) 354 return ret; 355 356 ret = i2c_smbus_read_i2c_block_data(sdata->client, 357 S6SY761_DEVICE_ID, 358 S6SY761_DEVID_SIZE, 359 buffer); 360 if (ret < 0) 361 return ret; 362 363 sdata->devid = get_unaligned_be16(buffer + 1); 364 365 ret = i2c_smbus_read_i2c_block_data(sdata->client, 366 S6SY761_PANEL_INFO, 367 S6SY761_PANEL_ID_SIZE, 368 buffer); 369 if (ret < 0) 370 return ret; 371 372 *max_x = get_unaligned_be16(buffer); 373 *max_y = get_unaligned_be16(buffer + 2); 374 375 /* if no tx channels defined, at least keep one */ 376 sdata->tx_channel = max_t(u8, buffer[8], 1); 377 378 ret = i2c_smbus_read_byte_data(sdata->client, 379 S6SY761_FIRMWARE_INTEGRITY); 380 if (ret < 0) 381 return ret; 382 else if (ret != S6SY761_FW_OK) 383 return -ENODEV; 384 385 return 0; 386 } 387 388 static void s6sy761_power_off(void *data) 389 { 390 struct s6sy761_data *sdata = data; 391 392 disable_irq(sdata->client->irq); 393 regulator_bulk_disable(ARRAY_SIZE(sdata->regulators), 394 sdata->regulators); 395 } 396 397 static int s6sy761_probe(struct i2c_client *client, 398 const struct i2c_device_id *id) 399 { 400 struct s6sy761_data *sdata; 401 unsigned int max_x, max_y; 402 int err; 403 404 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C | 405 I2C_FUNC_SMBUS_BYTE_DATA | 406 I2C_FUNC_SMBUS_I2C_BLOCK)) 407 return -ENODEV; 408 409 sdata = devm_kzalloc(&client->dev, sizeof(*sdata), GFP_KERNEL); 410 if (!sdata) 411 return -ENOMEM; 412 413 i2c_set_clientdata(client, sdata); 414 sdata->client = client; 415 416 sdata->regulators[S6SY761_REGULATOR_VDD].supply = "vdd"; 417 sdata->regulators[S6SY761_REGULATOR_AVDD].supply = "avdd"; 418 err = devm_regulator_bulk_get(&client->dev, 419 ARRAY_SIZE(sdata->regulators), 420 sdata->regulators); 421 if (err) 422 return err; 423 424 err = devm_add_action_or_reset(&client->dev, s6sy761_power_off, sdata); 425 if (err) 426 return err; 427 428 err = s6sy761_hw_init(sdata, &max_x, &max_y); 429 if (err) 430 return err; 431 432 sdata->input = devm_input_allocate_device(&client->dev); 433 if (!sdata->input) 434 return -ENOMEM; 435 436 sdata->input->name = S6SY761_DEV_NAME; 437 sdata->input->id.bustype = BUS_I2C; 438 sdata->input->open = s6sy761_input_open; 439 sdata->input->close = s6sy761_input_close; 440 441 input_set_abs_params(sdata->input, ABS_MT_POSITION_X, 0, max_x, 0, 0); 442 input_set_abs_params(sdata->input, ABS_MT_POSITION_Y, 0, max_y, 0, 0); 443 input_set_abs_params(sdata->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); 444 input_set_abs_params(sdata->input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0); 445 input_set_abs_params(sdata->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); 446 input_set_abs_params(sdata->input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0); 447 input_set_abs_params(sdata->input, ABS_MT_PRESSURE, 0, 255, 0, 0); 448 449 touchscreen_parse_properties(sdata->input, true, &sdata->prop); 450 451 if (!input_abs_get_max(sdata->input, ABS_X) || 452 !input_abs_get_max(sdata->input, ABS_Y)) { 453 dev_warn(&client->dev, "the axis have not been set\n"); 454 } 455 456 err = input_mt_init_slots(sdata->input, sdata->tx_channel, 457 INPUT_MT_DIRECT); 458 if (err) 459 return err; 460 461 input_set_drvdata(sdata->input, sdata); 462 463 err = input_register_device(sdata->input); 464 if (err) 465 return err; 466 467 err = devm_request_threaded_irq(&client->dev, client->irq, NULL, 468 s6sy761_irq_handler, 469 IRQF_TRIGGER_LOW | IRQF_ONESHOT, 470 "s6sy761_irq", sdata); 471 if (err) 472 return err; 473 474 err = devm_device_add_group(&client->dev, &s6sy761_attribute_group); 475 if (err) 476 return err; 477 478 pm_runtime_enable(&client->dev); 479 480 return 0; 481 } 482 483 static int s6sy761_remove(struct i2c_client *client) 484 { 485 pm_runtime_disable(&client->dev); 486 487 return 0; 488 } 489 490 static int __maybe_unused s6sy761_runtime_suspend(struct device *dev) 491 { 492 struct s6sy761_data *sdata = dev_get_drvdata(dev); 493 494 return i2c_smbus_write_byte_data(sdata->client, 495 S6SY761_APPLICATION_MODE, S6SY761_APP_SLEEP); 496 } 497 498 static int __maybe_unused s6sy761_runtime_resume(struct device *dev) 499 { 500 struct s6sy761_data *sdata = dev_get_drvdata(dev); 501 502 return i2c_smbus_write_byte_data(sdata->client, 503 S6SY761_APPLICATION_MODE, S6SY761_APP_NORMAL); 504 } 505 506 static int __maybe_unused s6sy761_suspend(struct device *dev) 507 { 508 struct s6sy761_data *sdata = dev_get_drvdata(dev); 509 510 s6sy761_power_off(sdata); 511 512 return 0; 513 } 514 515 static int __maybe_unused s6sy761_resume(struct device *dev) 516 { 517 struct s6sy761_data *sdata = dev_get_drvdata(dev); 518 519 enable_irq(sdata->client->irq); 520 521 return s6sy761_power_on(sdata); 522 } 523 524 static const struct dev_pm_ops s6sy761_pm_ops = { 525 SET_SYSTEM_SLEEP_PM_OPS(s6sy761_suspend, s6sy761_resume) 526 SET_RUNTIME_PM_OPS(s6sy761_runtime_suspend, 527 s6sy761_runtime_resume, NULL) 528 }; 529 530 #ifdef CONFIG_OF 531 static const struct of_device_id s6sy761_of_match[] = { 532 { .compatible = "samsung,s6sy761", }, 533 { }, 534 }; 535 MODULE_DEVICE_TABLE(of, s6sy761_of_match); 536 #endif 537 538 static const struct i2c_device_id s6sy761_id[] = { 539 { "s6sy761", 0 }, 540 { }, 541 }; 542 MODULE_DEVICE_TABLE(i2c, s6sy761_id); 543 544 static struct i2c_driver s6sy761_driver = { 545 .driver = { 546 .name = S6SY761_DEV_NAME, 547 .of_match_table = of_match_ptr(s6sy761_of_match), 548 .pm = &s6sy761_pm_ops, 549 }, 550 .probe = s6sy761_probe, 551 .remove = s6sy761_remove, 552 .id_table = s6sy761_id, 553 }; 554 555 module_i2c_driver(s6sy761_driver); 556 557 MODULE_AUTHOR("Andi Shyti <andi.shyti@samsung.com>"); 558 MODULE_DESCRIPTION("Samsung S6SY761 Touch Screen"); 559 MODULE_LICENSE("GPL v2"); 560