Lines Matching +full:edt +full:- +full:ft5x06

1 // SPDX-License-Identifier: GPL-2.0
5 * Lothar Waßmann <LW@KARO-electronics.de> (DT support)
10 * This is a driver for the EDT "Polytouch" family of touch controllers
11 * based on the FocalTech FT5x06 line of chips.
167 for (i = 0; i < buflen - 1; i++) in edt_ft5x06_ts_check_crc()
170 if (crc != buf[buflen - 1]) { in edt_ft5x06_ts_check_crc()
171 tsdata->crc_errors++; in edt_ft5x06_ts_check_crc()
172 dev_err_ratelimited(&tsdata->client->dev, in edt_ft5x06_ts_check_crc()
174 crc, buf[buflen - 1]); in edt_ft5x06_ts_check_crc()
209 wbuf[0] = M06_REG_CMD(tsdata->factory_mode); in edt_M06_i2c_read()
210 wbuf[1] = M06_REG_ADDR(tsdata->factory_mode, addr); in edt_M06_i2c_read()
211 wbuf[1] |= tsdata->factory_mode ? 0x80 : 0x40; in edt_M06_i2c_read()
214 xfer[0].addr = i2c->addr; in edt_M06_i2c_read()
219 xfer[1].addr = i2c->addr; in edt_M06_i2c_read()
224 ret = i2c_transfer(i2c->adapter, xfer, 2); in edt_M06_i2c_read()
229 return -EIO; in edt_M06_i2c_read()
237 tsdata->header_errors++; in edt_M06_i2c_read()
241 return -EIO; in edt_M06_i2c_read()
245 return -EIO; in edt_M06_i2c_read()
250 return -EIO; in edt_M06_i2c_read()
271 wbuf[0] = M06_REG_CMD(tsdata->factory_mode); in edt_M06_i2c_write()
272 wbuf[1] = M06_REG_ADDR(tsdata->factory_mode, addr); in edt_M06_i2c_write()
276 xfer.addr = i2c->addr; in edt_M06_i2c_write()
281 ret = i2c_transfer(i2c->adapter, &xfer, 1); in edt_M06_i2c_write()
286 return -EIO; in edt_M06_i2c_write()
302 struct device *dev = &tsdata->client->dev; in edt_ft5x06_ts_isr()
308 error = regmap_bulk_read(tsdata->regmap, tsdata->tdata_cmd, rdbuf, in edt_ft5x06_ts_isr()
309 tsdata->tdata_len); in edt_ft5x06_ts_isr()
316 for (i = 0; i < tsdata->max_support_points; i++) { in edt_ft5x06_ts_isr()
317 u8 *buf = &rdbuf[i * tsdata->point_len + tsdata->tdata_offset]; in edt_ft5x06_ts_isr()
325 if (tsdata->version == EDT_M06 && type == TOUCH_EVENT_DOWN) in edt_ft5x06_ts_isr()
331 if (tsdata->version == EV_FT) in edt_ft5x06_ts_isr()
336 input_mt_slot(tsdata->input, id); in edt_ft5x06_ts_isr()
337 if (input_mt_report_slot_state(tsdata->input, MT_TOOL_FINGER, in edt_ft5x06_ts_isr()
339 touchscreen_report_pos(tsdata->input, &tsdata->prop, in edt_ft5x06_ts_isr()
343 input_mt_report_pointer_emulation(tsdata->input, true); in edt_ft5x06_ts_isr()
344 input_sync(tsdata->input); in edt_ft5x06_ts_isr()
382 u8 *field = (u8 *)tsdata + attr->field_offset; in edt_ft5x06_setting_show()
388 mutex_lock(&tsdata->mutex); in edt_ft5x06_setting_show()
390 if (tsdata->factory_mode) { in edt_ft5x06_setting_show()
391 error = -EIO; in edt_ft5x06_setting_show()
395 switch (tsdata->version) { in edt_ft5x06_setting_show()
397 addr = attr->addr_m06; in edt_ft5x06_setting_show()
403 addr = attr->addr_m09; in edt_ft5x06_setting_show()
407 addr = attr->addr_ev; in edt_ft5x06_setting_show()
411 error = -ENODEV; in edt_ft5x06_setting_show()
416 error = regmap_read(tsdata->regmap, addr, &val); in edt_ft5x06_setting_show()
418 dev_err(&tsdata->client->dev, in edt_ft5x06_setting_show()
420 dattr->attr.name, error); in edt_ft5x06_setting_show()
428 dev_warn(&tsdata->client->dev, in edt_ft5x06_setting_show()
430 dattr->attr.name, val, *field); in edt_ft5x06_setting_show()
436 mutex_unlock(&tsdata->mutex); in edt_ft5x06_setting_show()
448 u8 *field = (u8 *)tsdata + attr->field_offset; in edt_ft5x06_setting_store()
453 mutex_lock(&tsdata->mutex); in edt_ft5x06_setting_store()
455 if (tsdata->factory_mode) { in edt_ft5x06_setting_store()
456 error = -EIO; in edt_ft5x06_setting_store()
464 if (val < attr->limit_low || val > attr->limit_high) { in edt_ft5x06_setting_store()
465 error = -ERANGE; in edt_ft5x06_setting_store()
469 switch (tsdata->version) { in edt_ft5x06_setting_store()
471 addr = attr->addr_m06; in edt_ft5x06_setting_store()
477 addr = attr->addr_m09; in edt_ft5x06_setting_store()
481 addr = attr->addr_ev; in edt_ft5x06_setting_store()
485 error = -ENODEV; in edt_ft5x06_setting_store()
490 error = regmap_write(tsdata->regmap, addr, val); in edt_ft5x06_setting_store()
492 dev_err(&tsdata->client->dev, in edt_ft5x06_setting_store()
494 dattr->attr.name, error); in edt_ft5x06_setting_store()
501 mutex_unlock(&tsdata->mutex); in edt_ft5x06_setting_store()
505 /* m06, m09: range 0-31, m12: range 0-5 */
508 /* m06, m09: range 0-31, m12: range 0-16 */
511 /* m06, m09, m12: no supported, ev_ft: range 0-80 */
514 /* m06, m09, m12: no supported, ev_ft: range 0-80 */
530 return sysfs_emit(buf, "%s\n", tsdata->name); in model_show()
541 return sysfs_emit(buf, "%s\n", tsdata->fw_version); in fw_version_show()
553 return sysfs_emit(buf, "%d\n", tsdata->header_errors); in header_errors_show()
565 return sysfs_emit(buf, "%d\n", tsdata->crc_errors); in crc_errors_show()
590 struct edt_reg_addr *reg_addr = &tsdata->reg_addr; in edt_ft5x06_restore_reg_parameters()
591 struct regmap *regmap = tsdata->regmap; in edt_ft5x06_restore_reg_parameters()
593 regmap_write(regmap, reg_addr->reg_threshold, tsdata->threshold); in edt_ft5x06_restore_reg_parameters()
594 regmap_write(regmap, reg_addr->reg_gain, tsdata->gain); in edt_ft5x06_restore_reg_parameters()
595 if (reg_addr->reg_offset != NO_REGISTER) in edt_ft5x06_restore_reg_parameters()
596 regmap_write(regmap, reg_addr->reg_offset, tsdata->offset); in edt_ft5x06_restore_reg_parameters()
597 if (reg_addr->reg_offset_x != NO_REGISTER) in edt_ft5x06_restore_reg_parameters()
598 regmap_write(regmap, reg_addr->reg_offset_x, tsdata->offset_x); in edt_ft5x06_restore_reg_parameters()
599 if (reg_addr->reg_offset_y != NO_REGISTER) in edt_ft5x06_restore_reg_parameters()
600 regmap_write(regmap, reg_addr->reg_offset_y, tsdata->offset_y); in edt_ft5x06_restore_reg_parameters()
601 if (reg_addr->reg_report_rate != NO_REGISTER) in edt_ft5x06_restore_reg_parameters()
602 regmap_write(regmap, reg_addr->reg_report_rate, in edt_ft5x06_restore_reg_parameters()
603 tsdata->report_rate); in edt_ft5x06_restore_reg_parameters()
609 struct i2c_client *client = tsdata->client; in edt_ft5x06_factory_mode()
614 if (tsdata->version != EDT_M06) { in edt_ft5x06_factory_mode()
615 dev_err(&client->dev, in edt_ft5x06_factory_mode()
616 "No factory mode support for non-M06 devices\n"); in edt_ft5x06_factory_mode()
617 return -EINVAL; in edt_ft5x06_factory_mode()
620 disable_irq(client->irq); in edt_ft5x06_factory_mode()
622 if (!tsdata->raw_buffer) { in edt_ft5x06_factory_mode()
623 tsdata->raw_bufsize = tsdata->num_x * tsdata->num_y * in edt_ft5x06_factory_mode()
625 tsdata->raw_buffer = kzalloc(tsdata->raw_bufsize, GFP_KERNEL); in edt_ft5x06_factory_mode()
626 if (!tsdata->raw_buffer) { in edt_ft5x06_factory_mode()
627 error = -ENOMEM; in edt_ft5x06_factory_mode()
633 error = regmap_write(tsdata->regmap, WORK_REGISTER_OPMODE, 0x03); in edt_ft5x06_factory_mode()
635 dev_err(&client->dev, in edt_ft5x06_factory_mode()
640 tsdata->factory_mode = true; in edt_ft5x06_factory_mode()
644 error = regmap_read(tsdata->regmap, FACTORY_REGISTER_OPMODE, in edt_ft5x06_factory_mode()
648 } while (--retries > 0); in edt_ft5x06_factory_mode()
651 dev_err(&client->dev, "not in factory mode after %dms.\n", in edt_ft5x06_factory_mode()
653 error = -EIO; in edt_ft5x06_factory_mode()
660 kfree(tsdata->raw_buffer); in edt_ft5x06_factory_mode()
661 tsdata->raw_buffer = NULL; in edt_ft5x06_factory_mode()
662 tsdata->factory_mode = false; in edt_ft5x06_factory_mode()
663 enable_irq(client->irq); in edt_ft5x06_factory_mode()
670 struct i2c_client *client = tsdata->client; in edt_ft5x06_work_mode()
676 error = regmap_write(tsdata->regmap, FACTORY_REGISTER_OPMODE, 0x1); in edt_ft5x06_work_mode()
678 dev_err(&client->dev, in edt_ft5x06_work_mode()
683 tsdata->factory_mode = false; in edt_ft5x06_work_mode()
688 error = regmap_read(tsdata->regmap, WORK_REGISTER_OPMODE, &val); in edt_ft5x06_work_mode()
691 } while (--retries > 0); in edt_ft5x06_work_mode()
694 dev_err(&client->dev, "not in work mode after %dms.\n", in edt_ft5x06_work_mode()
696 tsdata->factory_mode = true; in edt_ft5x06_work_mode()
697 return -EIO; in edt_ft5x06_work_mode()
700 kfree(tsdata->raw_buffer); in edt_ft5x06_work_mode()
701 tsdata->raw_buffer = NULL; in edt_ft5x06_work_mode()
704 enable_irq(client->irq); in edt_ft5x06_work_mode()
713 *mode = tsdata->factory_mode; in edt_ft5x06_debugfs_mode_get()
724 return -ERANGE; in edt_ft5x06_debugfs_mode_set()
726 mutex_lock(&tsdata->mutex); in edt_ft5x06_debugfs_mode_set()
728 if (mode != tsdata->factory_mode) { in edt_ft5x06_debugfs_mode_set()
733 mutex_unlock(&tsdata->mutex); in edt_ft5x06_debugfs_mode_set()
745 struct edt_ft5x06_ts_data *tsdata = file->private_data; in edt_ft5x06_debugfs_raw_data_read()
746 struct i2c_client *client = tsdata->client; in edt_ft5x06_debugfs_raw_data_read()
754 if (*off < 0 || *off >= tsdata->raw_bufsize) in edt_ft5x06_debugfs_raw_data_read()
757 mutex_lock(&tsdata->mutex); in edt_ft5x06_debugfs_raw_data_read()
759 if (!tsdata->factory_mode || !tsdata->raw_buffer) { in edt_ft5x06_debugfs_raw_data_read()
760 error = -EIO; in edt_ft5x06_debugfs_raw_data_read()
764 error = regmap_write(tsdata->regmap, 0x08, 0x01); in edt_ft5x06_debugfs_raw_data_read()
766 dev_err(&client->dev, in edt_ft5x06_debugfs_raw_data_read()
773 error = regmap_read(tsdata->regmap, 0x08, &val); in edt_ft5x06_debugfs_raw_data_read()
775 dev_err(&client->dev, in edt_ft5x06_debugfs_raw_data_read()
783 } while (--retries > 0); in edt_ft5x06_debugfs_raw_data_read()
786 dev_err(&client->dev, in edt_ft5x06_debugfs_raw_data_read()
788 error = -ETIMEDOUT; in edt_ft5x06_debugfs_raw_data_read()
792 rdbuf = tsdata->raw_buffer; in edt_ft5x06_debugfs_raw_data_read()
793 colbytes = tsdata->num_y * sizeof(u16); in edt_ft5x06_debugfs_raw_data_read()
795 for (i = 0; i < tsdata->num_x; i++) { in edt_ft5x06_debugfs_raw_data_read()
797 error = regmap_bulk_read(tsdata->regmap, 0xf5, rdbuf, colbytes); in edt_ft5x06_debugfs_raw_data_read()
804 read = min_t(size_t, count, tsdata->raw_bufsize - *off); in edt_ft5x06_debugfs_raw_data_read()
805 if (copy_to_user(buf, tsdata->raw_buffer + *off, read)) { in edt_ft5x06_debugfs_raw_data_read()
806 error = -EFAULT; in edt_ft5x06_debugfs_raw_data_read()
812 mutex_unlock(&tsdata->mutex); in edt_ft5x06_debugfs_raw_data_read()
824 tsdata->debug_dir = debugfs_create_dir(debugfs_name, NULL); in edt_ft5x06_ts_prepare_debugfs()
826 debugfs_create_u16("num_x", S_IRUSR, tsdata->debug_dir, &tsdata->num_x); in edt_ft5x06_ts_prepare_debugfs()
827 debugfs_create_u16("num_y", S_IRUSR, tsdata->debug_dir, &tsdata->num_y); in edt_ft5x06_ts_prepare_debugfs()
830 tsdata->debug_dir, tsdata, &debugfs_mode_fops); in edt_ft5x06_ts_prepare_debugfs()
832 tsdata->debug_dir, tsdata, &debugfs_raw_data_fops); in edt_ft5x06_ts_prepare_debugfs()
837 debugfs_remove_recursive(tsdata->debug_dir); in edt_ft5x06_ts_teardown_debugfs()
838 kfree(tsdata->raw_buffer); in edt_ft5x06_ts_teardown_debugfs()
845 return -ENOSYS; in edt_ft5x06_factory_mode()
865 char *model_name = tsdata->name; in edt_ft5x06_ts_identify()
866 char *fw_version = tsdata->fw_version; in edt_ft5x06_ts_identify()
873 error = regmap_bulk_read(tsdata->regmap, 0xBB, rdbuf, EDT_NAME_LEN - 1); in edt_ft5x06_ts_identify()
882 tsdata->version = EDT_M06; in edt_ft5x06_ts_identify()
885 rdbuf[EDT_NAME_LEN - 1] = '\0'; in edt_ft5x06_ts_identify()
886 if (rdbuf[EDT_NAME_LEN - 2] == '$') in edt_ft5x06_ts_identify()
887 rdbuf[EDT_NAME_LEN - 2] = '\0'; in edt_ft5x06_ts_identify()
896 regmap_exit(tsdata->regmap); in edt_ft5x06_ts_identify()
897 tsdata->regmap = regmap_init_i2c(client, in edt_ft5x06_ts_identify()
899 if (IS_ERR(tsdata->regmap)) { in edt_ft5x06_ts_identify()
900 dev_err(&client->dev, "regmap allocation failed\n"); in edt_ft5x06_ts_identify()
901 return PTR_ERR(tsdata->regmap); in edt_ft5x06_ts_identify()
904 tsdata->version = EDT_M12; in edt_ft5x06_ts_identify()
907 rdbuf[EDT_NAME_LEN - 2] = '\0'; in edt_ft5x06_ts_identify()
908 if (rdbuf[EDT_NAME_LEN - 3] == '$') in edt_ft5x06_ts_identify()
909 rdbuf[EDT_NAME_LEN - 3] = '\0'; in edt_ft5x06_ts_identify()
918 /* If it is not an EDT M06/M12 touchscreen, then the model in edt_ft5x06_ts_identify()
919 * detection is a bit hairy. The different ft5x06 in edt_ft5x06_ts_identify()
924 * touches and EDT M09 is that we know how to retrieve in edt_ft5x06_ts_identify()
927 tsdata->version = GENERIC_FT; in edt_ft5x06_ts_identify()
929 error = regmap_bulk_read(tsdata->regmap, 0xA6, rdbuf, 2); in edt_ft5x06_ts_identify()
935 error = regmap_bulk_read(tsdata->regmap, 0xA8, rdbuf, 1); in edt_ft5x06_ts_identify()
940 * not all firmwares for the ft5x06 put useful values in in edt_ft5x06_ts_identify()
944 case 0x11: /* EDT EP0110M09 */ in edt_ft5x06_ts_identify()
945 case 0x35: /* EDT EP0350M09 */ in edt_ft5x06_ts_identify()
946 case 0x43: /* EDT EP0430M09 */ in edt_ft5x06_ts_identify()
947 case 0x50: /* EDT EP0500M09 */ in edt_ft5x06_ts_identify()
948 case 0x57: /* EDT EP0570M09 */ in edt_ft5x06_ts_identify()
949 case 0x70: /* EDT EP0700M09 */ in edt_ft5x06_ts_identify()
950 tsdata->version = EDT_M09; in edt_ft5x06_ts_identify()
954 case 0xa1: /* EDT EP1010ML00 */ in edt_ft5x06_ts_identify()
955 tsdata->version = EDT_M09; in edt_ft5x06_ts_identify()
963 tsdata->version = EV_FT; in edt_ft5x06_ts_identify()
964 error = regmap_bulk_read(tsdata->regmap, 0x53, rdbuf, 1); in edt_ft5x06_ts_identify()
969 "EVERVISION-FT5726NEi"); in edt_ft5x06_ts_identify()
973 "generic ft5x06 (%02x)", in edt_ft5x06_ts_identify()
985 struct edt_reg_addr *reg_addr = &tsdata->reg_addr; in edt_ft5x06_ts_get_defaults()
986 struct regmap *regmap = tsdata->regmap; in edt_ft5x06_ts_get_defaults()
992 regmap_write(regmap, reg_addr->reg_threshold, val); in edt_ft5x06_ts_get_defaults()
993 tsdata->threshold = val; in edt_ft5x06_ts_get_defaults()
998 regmap_write(regmap, reg_addr->reg_gain, val); in edt_ft5x06_ts_get_defaults()
999 tsdata->gain = val; in edt_ft5x06_ts_get_defaults()
1004 if (reg_addr->reg_offset != NO_REGISTER) in edt_ft5x06_ts_get_defaults()
1005 regmap_write(regmap, reg_addr->reg_offset, val); in edt_ft5x06_ts_get_defaults()
1006 tsdata->offset = val; in edt_ft5x06_ts_get_defaults()
1009 error = device_property_read_u32(dev, "offset-x", &val); in edt_ft5x06_ts_get_defaults()
1011 if (reg_addr->reg_offset_x != NO_REGISTER) in edt_ft5x06_ts_get_defaults()
1012 regmap_write(regmap, reg_addr->reg_offset_x, val); in edt_ft5x06_ts_get_defaults()
1013 tsdata->offset_x = val; in edt_ft5x06_ts_get_defaults()
1016 error = device_property_read_u32(dev, "offset-y", &val); in edt_ft5x06_ts_get_defaults()
1018 if (reg_addr->reg_offset_y != NO_REGISTER) in edt_ft5x06_ts_get_defaults()
1019 regmap_write(regmap, reg_addr->reg_offset_y, val); in edt_ft5x06_ts_get_defaults()
1020 tsdata->offset_y = val; in edt_ft5x06_ts_get_defaults()
1026 struct edt_reg_addr *reg_addr = &tsdata->reg_addr; in edt_ft5x06_ts_get_parameters()
1027 struct regmap *regmap = tsdata->regmap; in edt_ft5x06_ts_get_parameters()
1030 regmap_read(regmap, reg_addr->reg_threshold, &tsdata->threshold); in edt_ft5x06_ts_get_parameters()
1031 regmap_read(regmap, reg_addr->reg_gain, &tsdata->gain); in edt_ft5x06_ts_get_parameters()
1032 if (reg_addr->reg_offset != NO_REGISTER) in edt_ft5x06_ts_get_parameters()
1033 regmap_read(regmap, reg_addr->reg_offset, &tsdata->offset); in edt_ft5x06_ts_get_parameters()
1034 if (reg_addr->reg_offset_x != NO_REGISTER) in edt_ft5x06_ts_get_parameters()
1035 regmap_read(regmap, reg_addr->reg_offset_x, &tsdata->offset_x); in edt_ft5x06_ts_get_parameters()
1036 if (reg_addr->reg_offset_y != NO_REGISTER) in edt_ft5x06_ts_get_parameters()
1037 regmap_read(regmap, reg_addr->reg_offset_y, &tsdata->offset_y); in edt_ft5x06_ts_get_parameters()
1038 if (reg_addr->reg_report_rate != NO_REGISTER) in edt_ft5x06_ts_get_parameters()
1039 regmap_read(regmap, reg_addr->reg_report_rate, in edt_ft5x06_ts_get_parameters()
1040 &tsdata->report_rate); in edt_ft5x06_ts_get_parameters()
1041 tsdata->num_x = EDT_DEFAULT_NUM_X; in edt_ft5x06_ts_get_parameters()
1042 if (reg_addr->reg_num_x != NO_REGISTER) { in edt_ft5x06_ts_get_parameters()
1043 if (!regmap_read(regmap, reg_addr->reg_num_x, &val)) in edt_ft5x06_ts_get_parameters()
1044 tsdata->num_x = val; in edt_ft5x06_ts_get_parameters()
1046 tsdata->num_y = EDT_DEFAULT_NUM_Y; in edt_ft5x06_ts_get_parameters()
1047 if (reg_addr->reg_num_y != NO_REGISTER) { in edt_ft5x06_ts_get_parameters()
1048 if (!regmap_read(regmap, reg_addr->reg_num_y, &val)) in edt_ft5x06_ts_get_parameters()
1049 tsdata->num_y = val; in edt_ft5x06_ts_get_parameters()
1057 if (tsdata->version == EDT_M06) { in edt_ft5x06_ts_set_tdata_parameters()
1058 tsdata->tdata_cmd = 0xf9; in edt_ft5x06_ts_set_tdata_parameters()
1059 tsdata->tdata_offset = 5; in edt_ft5x06_ts_set_tdata_parameters()
1060 tsdata->point_len = 4; in edt_ft5x06_ts_set_tdata_parameters()
1063 tsdata->tdata_cmd = 0x0; in edt_ft5x06_ts_set_tdata_parameters()
1064 tsdata->tdata_offset = 3; in edt_ft5x06_ts_set_tdata_parameters()
1065 tsdata->point_len = 6; in edt_ft5x06_ts_set_tdata_parameters()
1069 tsdata->tdata_len = tsdata->point_len * tsdata->max_support_points + in edt_ft5x06_ts_set_tdata_parameters()
1070 tsdata->tdata_offset + crclen; in edt_ft5x06_ts_set_tdata_parameters()
1075 struct edt_reg_addr *reg_addr = &tsdata->reg_addr; in edt_ft5x06_ts_set_regs()
1077 switch (tsdata->version) { in edt_ft5x06_ts_set_regs()
1079 reg_addr->reg_threshold = WORK_REGISTER_THRESHOLD; in edt_ft5x06_ts_set_regs()
1080 reg_addr->reg_report_rate = WORK_REGISTER_REPORT_RATE; in edt_ft5x06_ts_set_regs()
1081 reg_addr->reg_gain = WORK_REGISTER_GAIN; in edt_ft5x06_ts_set_regs()
1082 reg_addr->reg_offset = WORK_REGISTER_OFFSET; in edt_ft5x06_ts_set_regs()
1083 reg_addr->reg_offset_x = NO_REGISTER; in edt_ft5x06_ts_set_regs()
1084 reg_addr->reg_offset_y = NO_REGISTER; in edt_ft5x06_ts_set_regs()
1085 reg_addr->reg_num_x = WORK_REGISTER_NUM_X; in edt_ft5x06_ts_set_regs()
1086 reg_addr->reg_num_y = WORK_REGISTER_NUM_Y; in edt_ft5x06_ts_set_regs()
1091 reg_addr->reg_threshold = M09_REGISTER_THRESHOLD; in edt_ft5x06_ts_set_regs()
1092 reg_addr->reg_report_rate = tsdata->version == EDT_M12 ? in edt_ft5x06_ts_set_regs()
1094 reg_addr->reg_gain = M09_REGISTER_GAIN; in edt_ft5x06_ts_set_regs()
1095 reg_addr->reg_offset = M09_REGISTER_OFFSET; in edt_ft5x06_ts_set_regs()
1096 reg_addr->reg_offset_x = NO_REGISTER; in edt_ft5x06_ts_set_regs()
1097 reg_addr->reg_offset_y = NO_REGISTER; in edt_ft5x06_ts_set_regs()
1098 reg_addr->reg_num_x = M09_REGISTER_NUM_X; in edt_ft5x06_ts_set_regs()
1099 reg_addr->reg_num_y = M09_REGISTER_NUM_Y; in edt_ft5x06_ts_set_regs()
1103 reg_addr->reg_threshold = EV_REGISTER_THRESHOLD; in edt_ft5x06_ts_set_regs()
1104 reg_addr->reg_report_rate = NO_REGISTER; in edt_ft5x06_ts_set_regs()
1105 reg_addr->reg_gain = EV_REGISTER_GAIN; in edt_ft5x06_ts_set_regs()
1106 reg_addr->reg_offset = NO_REGISTER; in edt_ft5x06_ts_set_regs()
1107 reg_addr->reg_offset_x = EV_REGISTER_OFFSET_X; in edt_ft5x06_ts_set_regs()
1108 reg_addr->reg_offset_y = EV_REGISTER_OFFSET_Y; in edt_ft5x06_ts_set_regs()
1109 reg_addr->reg_num_x = NO_REGISTER; in edt_ft5x06_ts_set_regs()
1110 reg_addr->reg_num_y = NO_REGISTER; in edt_ft5x06_ts_set_regs()
1115 reg_addr->reg_threshold = M09_REGISTER_THRESHOLD; in edt_ft5x06_ts_set_regs()
1116 reg_addr->reg_report_rate = NO_REGISTER; in edt_ft5x06_ts_set_regs()
1117 reg_addr->reg_gain = M09_REGISTER_GAIN; in edt_ft5x06_ts_set_regs()
1118 reg_addr->reg_offset = M09_REGISTER_OFFSET; in edt_ft5x06_ts_set_regs()
1119 reg_addr->reg_offset_x = NO_REGISTER; in edt_ft5x06_ts_set_regs()
1120 reg_addr->reg_offset_y = NO_REGISTER; in edt_ft5x06_ts_set_regs()
1121 reg_addr->reg_num_x = NO_REGISTER; in edt_ft5x06_ts_set_regs()
1122 reg_addr->reg_num_y = NO_REGISTER; in edt_ft5x06_ts_set_regs()
1131 if (!IS_ERR_OR_NULL(data->regmap)) in edt_ft5x06_exit_regmap()
1132 regmap_exit(data->regmap); in edt_ft5x06_exit_regmap()
1139 regulator_disable(data->vcc); in edt_ft5x06_disable_regulators()
1140 regulator_disable(data->iovcc); in edt_ft5x06_disable_regulators()
1154 dev_dbg(&client->dev, "probing for EDT FT5x06 I2C\n"); in edt_ft5x06_ts_probe()
1156 tsdata = devm_kzalloc(&client->dev, sizeof(*tsdata), GFP_KERNEL); in edt_ft5x06_ts_probe()
1158 dev_err(&client->dev, "failed to allocate driver data.\n"); in edt_ft5x06_ts_probe()
1159 return -ENOMEM; in edt_ft5x06_ts_probe()
1162 tsdata->regmap = regmap_init_i2c(client, &edt_ft5x06_i2c_regmap_config); in edt_ft5x06_ts_probe()
1163 if (IS_ERR(tsdata->regmap)) { in edt_ft5x06_ts_probe()
1164 dev_err(&client->dev, "regmap allocation failed\n"); in edt_ft5x06_ts_probe()
1165 return PTR_ERR(tsdata->regmap); in edt_ft5x06_ts_probe()
1170 * custom action because we may replace regmap with M06-specific one in edt_ft5x06_ts_probe()
1173 error = devm_add_action_or_reset(&client->dev, edt_ft5x06_exit_regmap, in edt_ft5x06_ts_probe()
1178 chip_data = device_get_match_data(&client->dev); in edt_ft5x06_ts_probe()
1180 chip_data = (const struct edt_i2c_chip_data *)id->driver_data; in edt_ft5x06_ts_probe()
1181 if (!chip_data || !chip_data->max_support_points) { in edt_ft5x06_ts_probe()
1182 dev_err(&client->dev, "invalid or missing chip data\n"); in edt_ft5x06_ts_probe()
1183 return -EINVAL; in edt_ft5x06_ts_probe()
1186 tsdata->max_support_points = chip_data->max_support_points; in edt_ft5x06_ts_probe()
1188 tsdata->vcc = devm_regulator_get(&client->dev, "vcc"); in edt_ft5x06_ts_probe()
1189 if (IS_ERR(tsdata->vcc)) in edt_ft5x06_ts_probe()
1190 return dev_err_probe(&client->dev, PTR_ERR(tsdata->vcc), in edt_ft5x06_ts_probe()
1193 tsdata->iovcc = devm_regulator_get(&client->dev, "iovcc"); in edt_ft5x06_ts_probe()
1194 if (IS_ERR(tsdata->iovcc)) { in edt_ft5x06_ts_probe()
1195 error = PTR_ERR(tsdata->iovcc); in edt_ft5x06_ts_probe()
1196 if (error != -EPROBE_DEFER) in edt_ft5x06_ts_probe()
1197 dev_err(&client->dev, in edt_ft5x06_ts_probe()
1202 error = regulator_enable(tsdata->iovcc); in edt_ft5x06_ts_probe()
1204 dev_err(&client->dev, "failed to enable iovcc: %d\n", error); in edt_ft5x06_ts_probe()
1211 error = regulator_enable(tsdata->vcc); in edt_ft5x06_ts_probe()
1213 dev_err(&client->dev, "failed to enable vcc: %d\n", error); in edt_ft5x06_ts_probe()
1214 regulator_disable(tsdata->iovcc); in edt_ft5x06_ts_probe()
1218 error = devm_add_action_or_reset(&client->dev, in edt_ft5x06_ts_probe()
1224 tsdata->reset_gpio = devm_gpiod_get_optional(&client->dev, in edt_ft5x06_ts_probe()
1226 if (IS_ERR(tsdata->reset_gpio)) { in edt_ft5x06_ts_probe()
1227 error = PTR_ERR(tsdata->reset_gpio); in edt_ft5x06_ts_probe()
1228 dev_err(&client->dev, in edt_ft5x06_ts_probe()
1233 tsdata->wake_gpio = devm_gpiod_get_optional(&client->dev, in edt_ft5x06_ts_probe()
1235 if (IS_ERR(tsdata->wake_gpio)) { in edt_ft5x06_ts_probe()
1236 error = PTR_ERR(tsdata->wake_gpio); in edt_ft5x06_ts_probe()
1237 dev_err(&client->dev, in edt_ft5x06_ts_probe()
1243 * Check which sleep modes we can support. Power-off requieres the in edt_ft5x06_ts_probe()
1244 * reset-pin to ensure correct power-down/power-up behaviour. Start with in edt_ft5x06_ts_probe()
1248 if (tsdata->reset_gpio) in edt_ft5x06_ts_probe()
1249 tsdata->suspend_mode = EDT_PMODE_POWEROFF; in edt_ft5x06_ts_probe()
1250 else if (tsdata->wake_gpio) in edt_ft5x06_ts_probe()
1251 tsdata->suspend_mode = EDT_PMODE_HIBERNATE; in edt_ft5x06_ts_probe()
1253 tsdata->suspend_mode = EDT_PMODE_NOT_SUPPORTED; in edt_ft5x06_ts_probe()
1255 if (tsdata->wake_gpio) { in edt_ft5x06_ts_probe()
1257 gpiod_set_value_cansleep(tsdata->wake_gpio, 1); in edt_ft5x06_ts_probe()
1261 if (tsdata->reset_gpio) { in edt_ft5x06_ts_probe()
1263 gpiod_set_value_cansleep(tsdata->reset_gpio, 0); in edt_ft5x06_ts_probe()
1267 input = devm_input_allocate_device(&client->dev); in edt_ft5x06_ts_probe()
1269 dev_err(&client->dev, "failed to allocate input device.\n"); in edt_ft5x06_ts_probe()
1270 return -ENOMEM; in edt_ft5x06_ts_probe()
1273 mutex_init(&tsdata->mutex); in edt_ft5x06_ts_probe()
1274 tsdata->client = client; in edt_ft5x06_ts_probe()
1275 tsdata->input = input; in edt_ft5x06_ts_probe()
1276 tsdata->factory_mode = false; in edt_ft5x06_ts_probe()
1281 dev_err(&client->dev, "touchscreen probe failed\n"); in edt_ft5x06_ts_probe()
1289 regmap_read(tsdata->regmap, 0x00, &val); in edt_ft5x06_ts_probe()
1293 edt_ft5x06_ts_get_defaults(&client->dev, tsdata); in edt_ft5x06_ts_probe()
1296 if (tsdata->reg_addr.reg_report_rate != NO_REGISTER && in edt_ft5x06_ts_probe()
1297 !device_property_read_u32(&client->dev, in edt_ft5x06_ts_probe()
1298 "report-rate-hz", &report_rate)) { in edt_ft5x06_ts_probe()
1299 if (tsdata->version == EDT_M06) in edt_ft5x06_ts_probe()
1300 tsdata->report_rate = clamp_val(report_rate, 30, 140); in edt_ft5x06_ts_probe()
1302 tsdata->report_rate = clamp_val(report_rate, 1, 255); in edt_ft5x06_ts_probe()
1304 if (report_rate != tsdata->report_rate) in edt_ft5x06_ts_probe()
1305 dev_warn(&client->dev, in edt_ft5x06_ts_probe()
1306 "report-rate %dHz is unsupported, use %dHz\n", in edt_ft5x06_ts_probe()
1307 report_rate, tsdata->report_rate); in edt_ft5x06_ts_probe()
1309 if (tsdata->version == EDT_M06) in edt_ft5x06_ts_probe()
1310 tsdata->report_rate /= 10; in edt_ft5x06_ts_probe()
1312 regmap_write(tsdata->regmap, tsdata->reg_addr.reg_report_rate, in edt_ft5x06_ts_probe()
1313 tsdata->report_rate); in edt_ft5x06_ts_probe()
1316 dev_dbg(&client->dev, in edt_ft5x06_ts_probe()
1318 tsdata->name, tsdata->fw_version, tsdata->num_x, tsdata->num_y); in edt_ft5x06_ts_probe()
1320 input->name = tsdata->name; in edt_ft5x06_ts_probe()
1321 input->id.bustype = BUS_I2C; in edt_ft5x06_ts_probe()
1322 input->dev.parent = &client->dev; in edt_ft5x06_ts_probe()
1325 0, tsdata->num_x * 64 - 1, 0, 0); in edt_ft5x06_ts_probe()
1327 0, tsdata->num_y * 64 - 1, 0, 0); in edt_ft5x06_ts_probe()
1329 touchscreen_parse_properties(input, true, &tsdata->prop); in edt_ft5x06_ts_probe()
1331 error = input_mt_init_slots(input, tsdata->max_support_points, in edt_ft5x06_ts_probe()
1334 dev_err(&client->dev, "Unable to init MT slots.\n"); in edt_ft5x06_ts_probe()
1338 irq_flags = irq_get_trigger_type(client->irq); in edt_ft5x06_ts_probe()
1343 error = devm_request_threaded_irq(&client->dev, client->irq, in edt_ft5x06_ts_probe()
1345 client->name, tsdata); in edt_ft5x06_ts_probe()
1347 dev_err(&client->dev, "Unable to request touchscreen IRQ.\n"); in edt_ft5x06_ts_probe()
1351 error = devm_device_add_group(&client->dev, &edt_ft5x06_attr_group); in edt_ft5x06_ts_probe()
1359 edt_ft5x06_ts_prepare_debugfs(tsdata, dev_driver_string(&client->dev)); in edt_ft5x06_ts_probe()
1361 dev_dbg(&client->dev, in edt_ft5x06_ts_probe()
1362 "EDT FT5x06 initialized: IRQ %d, WAKE pin %d, Reset pin %d.\n", in edt_ft5x06_ts_probe()
1363 client->irq, in edt_ft5x06_ts_probe()
1364 tsdata->wake_gpio ? desc_to_gpio(tsdata->wake_gpio) : -1, in edt_ft5x06_ts_probe()
1365 tsdata->reset_gpio ? desc_to_gpio(tsdata->reset_gpio) : -1); in edt_ft5x06_ts_probe()
1381 struct gpio_desc *reset_gpio = tsdata->reset_gpio; in edt_ft5x06_ts_suspend()
1387 if (tsdata->suspend_mode == EDT_PMODE_NOT_SUPPORTED) in edt_ft5x06_ts_suspend()
1391 ret = regmap_write(tsdata->regmap, PMOD_REGISTER_OPMODE, in edt_ft5x06_ts_suspend()
1396 if (tsdata->suspend_mode == EDT_PMODE_HIBERNATE) in edt_ft5x06_ts_suspend()
1400 * Power-off according the datasheet. Cut the power may leaf the irq in edt_ft5x06_ts_suspend()
1405 disable_irq(tsdata->client->irq); in edt_ft5x06_ts_suspend()
1410 ret = regulator_disable(tsdata->vcc); in edt_ft5x06_ts_suspend()
1413 ret = regulator_disable(tsdata->iovcc); in edt_ft5x06_ts_suspend()
1429 if (tsdata->suspend_mode == EDT_PMODE_NOT_SUPPORTED) in edt_ft5x06_ts_resume()
1432 if (tsdata->suspend_mode == EDT_PMODE_POWEROFF) { in edt_ft5x06_ts_resume()
1433 struct gpio_desc *reset_gpio = tsdata->reset_gpio; in edt_ft5x06_ts_resume()
1446 ret = regulator_enable(tsdata->iovcc); in edt_ft5x06_ts_resume()
1455 ret = regulator_enable(tsdata->vcc); in edt_ft5x06_ts_resume()
1458 regulator_disable(tsdata->iovcc); in edt_ft5x06_ts_resume()
1467 enable_irq(tsdata->client->irq); in edt_ft5x06_ts_resume()
1469 if (tsdata->factory_mode) in edt_ft5x06_ts_resume()
1472 struct gpio_desc *wake_gpio = tsdata->wake_gpio; in edt_ft5x06_ts_resume()
1498 { .name = "edt-ft5x06", .driver_data = (long)&edt_ft5x06_data },
1499 { .name = "edt-ft5506", .driver_data = (long)&edt_ft5506_data },
1500 { .name = "ev-ft5726", .driver_data = (long)&edt_ft5506_data },
1501 /* Note no edt- prefix for compatibility with the ft6236.c driver */
1508 { .compatible = "edt,edt-ft5206", .data = &edt_ft5x06_data },
1509 { .compatible = "edt,edt-ft5306", .data = &edt_ft5x06_data },
1510 { .compatible = "edt,edt-ft5406", .data = &edt_ft5x06_data },
1511 { .compatible = "edt,edt-ft5506", .data = &edt_ft5506_data },
1512 { .compatible = "evervision,ev-ft5726", .data = &edt_ft5506_data },
1534 MODULE_DESCRIPTION("EDT FT5x06 I2C Touchscreen Driver");