Lines Matching +full:i2c +full:- +full:crc +full:- +full:enable

1 // SPDX-License-Identifier: GPL-2.0
5 * Lothar Waßmann <LW@KARO-electronics.de> (DT support)
20 #include <linux/i2c.h>
164 u8 crc = 0; in edt_ft5x06_ts_check_crc() local
166 for (i = 0; i < buflen - 1; i++) in edt_ft5x06_ts_check_crc()
167 crc ^= buf[i]; in edt_ft5x06_ts_check_crc()
169 if (crc != buf[buflen - 1]) { in edt_ft5x06_ts_check_crc()
170 tsdata->crc_errors++; in edt_ft5x06_ts_check_crc()
171 dev_err_ratelimited(&tsdata->client->dev, in edt_ft5x06_ts_check_crc()
172 "crc error: 0x%02x expected, got 0x%02x\n", in edt_ft5x06_ts_check_crc()
173 crc, buf[buflen - 1]); in edt_ft5x06_ts_check_crc()
184 struct i2c_client *i2c = to_i2c_client(dev); in edt_M06_i2c_read() local
185 struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(i2c); in edt_M06_i2c_read()
208 wbuf[0] = M06_REG_CMD(tsdata->factory_mode); in edt_M06_i2c_read()
209 wbuf[1] = M06_REG_ADDR(tsdata->factory_mode, addr); in edt_M06_i2c_read()
210 wbuf[1] |= tsdata->factory_mode ? 0x80 : 0x40; in edt_M06_i2c_read()
213 xfer[0].addr = i2c->addr; in edt_M06_i2c_read()
218 xfer[1].addr = i2c->addr; in edt_M06_i2c_read()
223 ret = i2c_transfer(i2c->adapter, xfer, 2); in edt_M06_i2c_read()
228 return -EIO; in edt_M06_i2c_read()
236 tsdata->header_errors++; in edt_M06_i2c_read()
240 return -EIO; in edt_M06_i2c_read()
244 return -EIO; in edt_M06_i2c_read()
249 return -EIO; in edt_M06_i2c_read()
260 struct i2c_client *i2c = to_i2c_client(dev); in edt_M06_i2c_write() local
261 struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(i2c); in edt_M06_i2c_write()
270 wbuf[0] = M06_REG_CMD(tsdata->factory_mode); in edt_M06_i2c_write()
271 wbuf[1] = M06_REG_ADDR(tsdata->factory_mode, addr); in edt_M06_i2c_write()
275 xfer.addr = i2c->addr; in edt_M06_i2c_write()
280 ret = i2c_transfer(i2c->adapter, &xfer, 1); in edt_M06_i2c_write()
285 return -EIO; in edt_M06_i2c_write()
301 struct device *dev = &tsdata->client->dev; in edt_ft5x06_ts_isr()
307 error = regmap_bulk_read(tsdata->regmap, tsdata->tdata_cmd, rdbuf, in edt_ft5x06_ts_isr()
308 tsdata->tdata_len); in edt_ft5x06_ts_isr()
315 for (i = 0; i < tsdata->max_support_points; i++) { in edt_ft5x06_ts_isr()
316 u8 *buf = &rdbuf[i * tsdata->point_len + tsdata->tdata_offset]; in edt_ft5x06_ts_isr()
324 if (tsdata->version == EDT_M06 && type == TOUCH_EVENT_DOWN) in edt_ft5x06_ts_isr()
330 if (tsdata->version == EV_FT) in edt_ft5x06_ts_isr()
335 input_mt_slot(tsdata->input, id); in edt_ft5x06_ts_isr()
336 if (input_mt_report_slot_state(tsdata->input, MT_TOOL_FINGER, in edt_ft5x06_ts_isr()
338 touchscreen_report_pos(tsdata->input, &tsdata->prop, in edt_ft5x06_ts_isr()
342 input_mt_report_pointer_emulation(tsdata->input, true); in edt_ft5x06_ts_isr()
343 input_sync(tsdata->input); in edt_ft5x06_ts_isr()
381 u8 *field = (u8 *)tsdata + attr->field_offset; in edt_ft5x06_setting_show()
387 mutex_lock(&tsdata->mutex); in edt_ft5x06_setting_show()
389 if (tsdata->factory_mode) { in edt_ft5x06_setting_show()
390 error = -EIO; in edt_ft5x06_setting_show()
394 switch (tsdata->version) { in edt_ft5x06_setting_show()
396 addr = attr->addr_m06; in edt_ft5x06_setting_show()
402 addr = attr->addr_m09; in edt_ft5x06_setting_show()
406 addr = attr->addr_ev; in edt_ft5x06_setting_show()
410 error = -ENODEV; in edt_ft5x06_setting_show()
415 error = regmap_read(tsdata->regmap, addr, &val); in edt_ft5x06_setting_show()
417 dev_err(&tsdata->client->dev, in edt_ft5x06_setting_show()
419 dattr->attr.name, error); in edt_ft5x06_setting_show()
427 dev_warn(&tsdata->client->dev, in edt_ft5x06_setting_show()
429 dattr->attr.name, val, *field); in edt_ft5x06_setting_show()
435 mutex_unlock(&tsdata->mutex); in edt_ft5x06_setting_show()
447 u8 *field = (u8 *)tsdata + attr->field_offset; in edt_ft5x06_setting_store()
452 mutex_lock(&tsdata->mutex); in edt_ft5x06_setting_store()
454 if (tsdata->factory_mode) { in edt_ft5x06_setting_store()
455 error = -EIO; in edt_ft5x06_setting_store()
463 if (val < attr->limit_low || val > attr->limit_high) { in edt_ft5x06_setting_store()
464 error = -ERANGE; in edt_ft5x06_setting_store()
468 switch (tsdata->version) { in edt_ft5x06_setting_store()
470 addr = attr->addr_m06; in edt_ft5x06_setting_store()
476 addr = attr->addr_m09; in edt_ft5x06_setting_store()
480 addr = attr->addr_ev; in edt_ft5x06_setting_store()
484 error = -ENODEV; in edt_ft5x06_setting_store()
489 error = regmap_write(tsdata->regmap, addr, val); in edt_ft5x06_setting_store()
491 dev_err(&tsdata->client->dev, in edt_ft5x06_setting_store()
493 dattr->attr.name, error); in edt_ft5x06_setting_store()
500 mutex_unlock(&tsdata->mutex); in edt_ft5x06_setting_store()
504 /* m06, m09: range 0-31, m12: range 0-5 */
507 /* m06, m09: range 0-31, m12: range 0-16 */
510 /* m06, m09, m12: no supported, ev_ft: range 0-80 */
513 /* m06, m09, m12: no supported, ev_ft: range 0-80 */
529 return sysfs_emit(buf, "%s\n", tsdata->name); in model_show()
540 return sysfs_emit(buf, "%s\n", tsdata->fw_version); in fw_version_show()
552 return sysfs_emit(buf, "%d\n", tsdata->header_errors); in header_errors_show()
564 return sysfs_emit(buf, "%d\n", tsdata->crc_errors); in crc_errors_show()
586 struct edt_reg_addr *reg_addr = &tsdata->reg_addr; in edt_ft5x06_restore_reg_parameters()
587 struct regmap *regmap = tsdata->regmap; in edt_ft5x06_restore_reg_parameters()
589 regmap_write(regmap, reg_addr->reg_threshold, tsdata->threshold); in edt_ft5x06_restore_reg_parameters()
590 regmap_write(regmap, reg_addr->reg_gain, tsdata->gain); in edt_ft5x06_restore_reg_parameters()
591 if (reg_addr->reg_offset != NO_REGISTER) in edt_ft5x06_restore_reg_parameters()
592 regmap_write(regmap, reg_addr->reg_offset, tsdata->offset); in edt_ft5x06_restore_reg_parameters()
593 if (reg_addr->reg_offset_x != NO_REGISTER) in edt_ft5x06_restore_reg_parameters()
594 regmap_write(regmap, reg_addr->reg_offset_x, tsdata->offset_x); in edt_ft5x06_restore_reg_parameters()
595 if (reg_addr->reg_offset_y != NO_REGISTER) in edt_ft5x06_restore_reg_parameters()
596 regmap_write(regmap, reg_addr->reg_offset_y, tsdata->offset_y); in edt_ft5x06_restore_reg_parameters()
597 if (reg_addr->reg_report_rate != NO_REGISTER) in edt_ft5x06_restore_reg_parameters()
598 regmap_write(regmap, reg_addr->reg_report_rate, in edt_ft5x06_restore_reg_parameters()
599 tsdata->report_rate); in edt_ft5x06_restore_reg_parameters()
605 struct i2c_client *client = tsdata->client; in edt_ft5x06_factory_mode()
610 if (tsdata->version != EDT_M06) { in edt_ft5x06_factory_mode()
611 dev_err(&client->dev, in edt_ft5x06_factory_mode()
612 "No factory mode support for non-M06 devices\n"); in edt_ft5x06_factory_mode()
613 return -EINVAL; in edt_ft5x06_factory_mode()
616 disable_irq(client->irq); in edt_ft5x06_factory_mode()
618 if (!tsdata->raw_buffer) { in edt_ft5x06_factory_mode()
619 tsdata->raw_bufsize = tsdata->num_x * tsdata->num_y * in edt_ft5x06_factory_mode()
621 tsdata->raw_buffer = kzalloc(tsdata->raw_bufsize, GFP_KERNEL); in edt_ft5x06_factory_mode()
622 if (!tsdata->raw_buffer) { in edt_ft5x06_factory_mode()
623 error = -ENOMEM; in edt_ft5x06_factory_mode()
629 error = regmap_write(tsdata->regmap, WORK_REGISTER_OPMODE, 0x03); in edt_ft5x06_factory_mode()
631 dev_err(&client->dev, in edt_ft5x06_factory_mode()
636 tsdata->factory_mode = true; in edt_ft5x06_factory_mode()
640 error = regmap_read(tsdata->regmap, FACTORY_REGISTER_OPMODE, in edt_ft5x06_factory_mode()
644 } while (--retries > 0); in edt_ft5x06_factory_mode()
647 dev_err(&client->dev, "not in factory mode after %dms.\n", in edt_ft5x06_factory_mode()
649 error = -EIO; in edt_ft5x06_factory_mode()
656 kfree(tsdata->raw_buffer); in edt_ft5x06_factory_mode()
657 tsdata->raw_buffer = NULL; in edt_ft5x06_factory_mode()
658 tsdata->factory_mode = false; in edt_ft5x06_factory_mode()
659 enable_irq(client->irq); in edt_ft5x06_factory_mode()
666 struct i2c_client *client = tsdata->client; in edt_ft5x06_work_mode()
672 error = regmap_write(tsdata->regmap, FACTORY_REGISTER_OPMODE, 0x1); in edt_ft5x06_work_mode()
674 dev_err(&client->dev, in edt_ft5x06_work_mode()
679 tsdata->factory_mode = false; in edt_ft5x06_work_mode()
684 error = regmap_read(tsdata->regmap, WORK_REGISTER_OPMODE, &val); in edt_ft5x06_work_mode()
687 } while (--retries > 0); in edt_ft5x06_work_mode()
690 dev_err(&client->dev, "not in work mode after %dms.\n", in edt_ft5x06_work_mode()
692 tsdata->factory_mode = true; in edt_ft5x06_work_mode()
693 return -EIO; in edt_ft5x06_work_mode()
696 kfree(tsdata->raw_buffer); in edt_ft5x06_work_mode()
697 tsdata->raw_buffer = NULL; in edt_ft5x06_work_mode()
700 enable_irq(client->irq); in edt_ft5x06_work_mode()
709 *mode = tsdata->factory_mode; in edt_ft5x06_debugfs_mode_get()
720 return -ERANGE; in edt_ft5x06_debugfs_mode_set()
722 mutex_lock(&tsdata->mutex); in edt_ft5x06_debugfs_mode_set()
724 if (mode != tsdata->factory_mode) { in edt_ft5x06_debugfs_mode_set()
729 mutex_unlock(&tsdata->mutex); in edt_ft5x06_debugfs_mode_set()
741 struct edt_ft5x06_ts_data *tsdata = file->private_data; in edt_ft5x06_debugfs_raw_data_read()
742 struct i2c_client *client = tsdata->client; in edt_ft5x06_debugfs_raw_data_read()
750 if (*off < 0 || *off >= tsdata->raw_bufsize) in edt_ft5x06_debugfs_raw_data_read()
753 mutex_lock(&tsdata->mutex); in edt_ft5x06_debugfs_raw_data_read()
755 if (!tsdata->factory_mode || !tsdata->raw_buffer) { in edt_ft5x06_debugfs_raw_data_read()
756 error = -EIO; in edt_ft5x06_debugfs_raw_data_read()
760 error = regmap_write(tsdata->regmap, 0x08, 0x01); in edt_ft5x06_debugfs_raw_data_read()
762 dev_err(&client->dev, in edt_ft5x06_debugfs_raw_data_read()
769 error = regmap_read(tsdata->regmap, 0x08, &val); in edt_ft5x06_debugfs_raw_data_read()
771 dev_err(&client->dev, in edt_ft5x06_debugfs_raw_data_read()
779 } while (--retries > 0); in edt_ft5x06_debugfs_raw_data_read()
782 dev_err(&client->dev, in edt_ft5x06_debugfs_raw_data_read()
784 error = -ETIMEDOUT; in edt_ft5x06_debugfs_raw_data_read()
788 rdbuf = tsdata->raw_buffer; in edt_ft5x06_debugfs_raw_data_read()
789 colbytes = tsdata->num_y * sizeof(u16); in edt_ft5x06_debugfs_raw_data_read()
791 for (i = 0; i < tsdata->num_x; i++) { in edt_ft5x06_debugfs_raw_data_read()
793 error = regmap_bulk_read(tsdata->regmap, 0xf5, rdbuf, colbytes); in edt_ft5x06_debugfs_raw_data_read()
800 read = min_t(size_t, count, tsdata->raw_bufsize - *off); in edt_ft5x06_debugfs_raw_data_read()
801 if (copy_to_user(buf, tsdata->raw_buffer + *off, read)) { in edt_ft5x06_debugfs_raw_data_read()
802 error = -EFAULT; in edt_ft5x06_debugfs_raw_data_read()
808 mutex_unlock(&tsdata->mutex); in edt_ft5x06_debugfs_raw_data_read()
819 struct dentry *debug_dir = tsdata->client->debugfs; in edt_ft5x06_ts_prepare_debugfs()
821 debugfs_create_u16("num_x", S_IRUSR, debug_dir, &tsdata->num_x); in edt_ft5x06_ts_prepare_debugfs()
822 debugfs_create_u16("num_y", S_IRUSR, debug_dir, &tsdata->num_y); in edt_ft5x06_ts_prepare_debugfs()
832 kfree(tsdata->raw_buffer); in edt_ft5x06_ts_teardown_debugfs()
839 return -ENOSYS; in edt_ft5x06_factory_mode()
858 char *model_name = tsdata->name; in edt_ft5x06_ts_identify()
859 char *fw_version = tsdata->fw_version; in edt_ft5x06_ts_identify()
866 error = regmap_bulk_read(tsdata->regmap, 0xBB, rdbuf, EDT_NAME_LEN - 1); in edt_ft5x06_ts_identify()
875 tsdata->version = EDT_M06; in edt_ft5x06_ts_identify()
878 rdbuf[EDT_NAME_LEN - 1] = '\0'; in edt_ft5x06_ts_identify()
879 if (rdbuf[EDT_NAME_LEN - 2] == '$') in edt_ft5x06_ts_identify()
880 rdbuf[EDT_NAME_LEN - 2] = '\0'; in edt_ft5x06_ts_identify()
889 regmap_exit(tsdata->regmap); in edt_ft5x06_ts_identify()
890 tsdata->regmap = regmap_init_i2c(client, in edt_ft5x06_ts_identify()
892 if (IS_ERR(tsdata->regmap)) { in edt_ft5x06_ts_identify()
893 dev_err(&client->dev, "regmap allocation failed\n"); in edt_ft5x06_ts_identify()
894 return PTR_ERR(tsdata->regmap); in edt_ft5x06_ts_identify()
897 tsdata->version = EDT_M12; in edt_ft5x06_ts_identify()
900 rdbuf[EDT_NAME_LEN - 2] = '\0'; in edt_ft5x06_ts_identify()
901 if (rdbuf[EDT_NAME_LEN - 3] == '$') in edt_ft5x06_ts_identify()
902 rdbuf[EDT_NAME_LEN - 3] = '\0'; in edt_ft5x06_ts_identify()
920 tsdata->version = GENERIC_FT; in edt_ft5x06_ts_identify()
922 error = regmap_bulk_read(tsdata->regmap, 0xA6, rdbuf, 2); in edt_ft5x06_ts_identify()
928 error = regmap_bulk_read(tsdata->regmap, 0xA8, rdbuf, 1); in edt_ft5x06_ts_identify()
943 tsdata->version = EDT_M09; in edt_ft5x06_ts_identify()
948 tsdata->version = EDT_M09; in edt_ft5x06_ts_identify()
956 tsdata->version = EV_FT; in edt_ft5x06_ts_identify()
957 error = regmap_bulk_read(tsdata->regmap, 0x53, rdbuf, 1); in edt_ft5x06_ts_identify()
962 "EVERVISION-FT5726NEi"); in edt_ft5x06_ts_identify()
978 struct edt_reg_addr *reg_addr = &tsdata->reg_addr; in edt_ft5x06_ts_get_defaults()
979 struct regmap *regmap = tsdata->regmap; in edt_ft5x06_ts_get_defaults()
985 regmap_write(regmap, reg_addr->reg_threshold, val); in edt_ft5x06_ts_get_defaults()
986 tsdata->threshold = val; in edt_ft5x06_ts_get_defaults()
991 regmap_write(regmap, reg_addr->reg_gain, val); in edt_ft5x06_ts_get_defaults()
992 tsdata->gain = val; in edt_ft5x06_ts_get_defaults()
997 if (reg_addr->reg_offset != NO_REGISTER) in edt_ft5x06_ts_get_defaults()
998 regmap_write(regmap, reg_addr->reg_offset, val); in edt_ft5x06_ts_get_defaults()
999 tsdata->offset = val; in edt_ft5x06_ts_get_defaults()
1002 error = device_property_read_u32(dev, "offset-x", &val); in edt_ft5x06_ts_get_defaults()
1004 if (reg_addr->reg_offset_x != NO_REGISTER) in edt_ft5x06_ts_get_defaults()
1005 regmap_write(regmap, reg_addr->reg_offset_x, val); in edt_ft5x06_ts_get_defaults()
1006 tsdata->offset_x = val; in edt_ft5x06_ts_get_defaults()
1009 error = device_property_read_u32(dev, "offset-y", &val); in edt_ft5x06_ts_get_defaults()
1011 if (reg_addr->reg_offset_y != NO_REGISTER) in edt_ft5x06_ts_get_defaults()
1012 regmap_write(regmap, reg_addr->reg_offset_y, val); in edt_ft5x06_ts_get_defaults()
1013 tsdata->offset_y = val; in edt_ft5x06_ts_get_defaults()
1019 struct edt_reg_addr *reg_addr = &tsdata->reg_addr; in edt_ft5x06_ts_get_parameters()
1020 struct regmap *regmap = tsdata->regmap; in edt_ft5x06_ts_get_parameters()
1023 regmap_read(regmap, reg_addr->reg_threshold, &tsdata->threshold); in edt_ft5x06_ts_get_parameters()
1024 regmap_read(regmap, reg_addr->reg_gain, &tsdata->gain); in edt_ft5x06_ts_get_parameters()
1025 if (reg_addr->reg_offset != NO_REGISTER) in edt_ft5x06_ts_get_parameters()
1026 regmap_read(regmap, reg_addr->reg_offset, &tsdata->offset); in edt_ft5x06_ts_get_parameters()
1027 if (reg_addr->reg_offset_x != NO_REGISTER) in edt_ft5x06_ts_get_parameters()
1028 regmap_read(regmap, reg_addr->reg_offset_x, &tsdata->offset_x); in edt_ft5x06_ts_get_parameters()
1029 if (reg_addr->reg_offset_y != NO_REGISTER) in edt_ft5x06_ts_get_parameters()
1030 regmap_read(regmap, reg_addr->reg_offset_y, &tsdata->offset_y); in edt_ft5x06_ts_get_parameters()
1031 if (reg_addr->reg_report_rate != NO_REGISTER) in edt_ft5x06_ts_get_parameters()
1032 regmap_read(regmap, reg_addr->reg_report_rate, in edt_ft5x06_ts_get_parameters()
1033 &tsdata->report_rate); in edt_ft5x06_ts_get_parameters()
1034 tsdata->num_x = EDT_DEFAULT_NUM_X; in edt_ft5x06_ts_get_parameters()
1035 if (reg_addr->reg_num_x != NO_REGISTER) { in edt_ft5x06_ts_get_parameters()
1036 if (!regmap_read(regmap, reg_addr->reg_num_x, &val)) in edt_ft5x06_ts_get_parameters()
1037 tsdata->num_x = val; in edt_ft5x06_ts_get_parameters()
1039 tsdata->num_y = EDT_DEFAULT_NUM_Y; in edt_ft5x06_ts_get_parameters()
1040 if (reg_addr->reg_num_y != NO_REGISTER) { in edt_ft5x06_ts_get_parameters()
1041 if (!regmap_read(regmap, reg_addr->reg_num_y, &val)) in edt_ft5x06_ts_get_parameters()
1042 tsdata->num_y = val; in edt_ft5x06_ts_get_parameters()
1050 if (tsdata->version == EDT_M06) { in edt_ft5x06_ts_set_tdata_parameters()
1051 tsdata->tdata_cmd = 0xf9; in edt_ft5x06_ts_set_tdata_parameters()
1052 tsdata->tdata_offset = 5; in edt_ft5x06_ts_set_tdata_parameters()
1053 tsdata->point_len = 4; in edt_ft5x06_ts_set_tdata_parameters()
1056 tsdata->tdata_cmd = 0x0; in edt_ft5x06_ts_set_tdata_parameters()
1057 tsdata->tdata_offset = 3; in edt_ft5x06_ts_set_tdata_parameters()
1058 tsdata->point_len = 6; in edt_ft5x06_ts_set_tdata_parameters()
1062 tsdata->tdata_len = tsdata->point_len * tsdata->max_support_points + in edt_ft5x06_ts_set_tdata_parameters()
1063 tsdata->tdata_offset + crclen; in edt_ft5x06_ts_set_tdata_parameters()
1068 struct edt_reg_addr *reg_addr = &tsdata->reg_addr; in edt_ft5x06_ts_set_regs()
1070 switch (tsdata->version) { in edt_ft5x06_ts_set_regs()
1072 reg_addr->reg_threshold = WORK_REGISTER_THRESHOLD; in edt_ft5x06_ts_set_regs()
1073 reg_addr->reg_report_rate = WORK_REGISTER_REPORT_RATE; in edt_ft5x06_ts_set_regs()
1074 reg_addr->reg_gain = WORK_REGISTER_GAIN; in edt_ft5x06_ts_set_regs()
1075 reg_addr->reg_offset = WORK_REGISTER_OFFSET; in edt_ft5x06_ts_set_regs()
1076 reg_addr->reg_offset_x = NO_REGISTER; in edt_ft5x06_ts_set_regs()
1077 reg_addr->reg_offset_y = NO_REGISTER; in edt_ft5x06_ts_set_regs()
1078 reg_addr->reg_num_x = WORK_REGISTER_NUM_X; in edt_ft5x06_ts_set_regs()
1079 reg_addr->reg_num_y = WORK_REGISTER_NUM_Y; in edt_ft5x06_ts_set_regs()
1084 reg_addr->reg_threshold = M09_REGISTER_THRESHOLD; in edt_ft5x06_ts_set_regs()
1085 reg_addr->reg_report_rate = tsdata->version == EDT_M12 ? in edt_ft5x06_ts_set_regs()
1087 reg_addr->reg_gain = M09_REGISTER_GAIN; in edt_ft5x06_ts_set_regs()
1088 reg_addr->reg_offset = M09_REGISTER_OFFSET; in edt_ft5x06_ts_set_regs()
1089 reg_addr->reg_offset_x = NO_REGISTER; in edt_ft5x06_ts_set_regs()
1090 reg_addr->reg_offset_y = NO_REGISTER; in edt_ft5x06_ts_set_regs()
1091 reg_addr->reg_num_x = M09_REGISTER_NUM_X; in edt_ft5x06_ts_set_regs()
1092 reg_addr->reg_num_y = M09_REGISTER_NUM_Y; in edt_ft5x06_ts_set_regs()
1096 reg_addr->reg_threshold = EV_REGISTER_THRESHOLD; in edt_ft5x06_ts_set_regs()
1097 reg_addr->reg_report_rate = NO_REGISTER; in edt_ft5x06_ts_set_regs()
1098 reg_addr->reg_gain = EV_REGISTER_GAIN; in edt_ft5x06_ts_set_regs()
1099 reg_addr->reg_offset = NO_REGISTER; in edt_ft5x06_ts_set_regs()
1100 reg_addr->reg_offset_x = EV_REGISTER_OFFSET_X; in edt_ft5x06_ts_set_regs()
1101 reg_addr->reg_offset_y = EV_REGISTER_OFFSET_Y; in edt_ft5x06_ts_set_regs()
1102 reg_addr->reg_num_x = NO_REGISTER; in edt_ft5x06_ts_set_regs()
1103 reg_addr->reg_num_y = NO_REGISTER; in edt_ft5x06_ts_set_regs()
1108 reg_addr->reg_threshold = M09_REGISTER_THRESHOLD; in edt_ft5x06_ts_set_regs()
1109 reg_addr->reg_report_rate = NO_REGISTER; in edt_ft5x06_ts_set_regs()
1110 reg_addr->reg_gain = M09_REGISTER_GAIN; in edt_ft5x06_ts_set_regs()
1111 reg_addr->reg_offset = M09_REGISTER_OFFSET; in edt_ft5x06_ts_set_regs()
1112 reg_addr->reg_offset_x = NO_REGISTER; in edt_ft5x06_ts_set_regs()
1113 reg_addr->reg_offset_y = NO_REGISTER; in edt_ft5x06_ts_set_regs()
1114 reg_addr->reg_num_x = NO_REGISTER; in edt_ft5x06_ts_set_regs()
1115 reg_addr->reg_num_y = NO_REGISTER; in edt_ft5x06_ts_set_regs()
1124 if (!IS_ERR_OR_NULL(data->regmap)) in edt_ft5x06_exit_regmap()
1125 regmap_exit(data->regmap); in edt_ft5x06_exit_regmap()
1132 regulator_disable(data->vcc); in edt_ft5x06_disable_regulators()
1133 regulator_disable(data->iovcc); in edt_ft5x06_disable_regulators()
1147 dev_dbg(&client->dev, "probing for EDT FT5x06 I2C\n"); in edt_ft5x06_ts_probe()
1149 tsdata = devm_kzalloc(&client->dev, sizeof(*tsdata), GFP_KERNEL); in edt_ft5x06_ts_probe()
1151 dev_err(&client->dev, "failed to allocate driver data.\n"); in edt_ft5x06_ts_probe()
1152 return -ENOMEM; in edt_ft5x06_ts_probe()
1155 tsdata->regmap = regmap_init_i2c(client, &edt_ft5x06_i2c_regmap_config); in edt_ft5x06_ts_probe()
1156 if (IS_ERR(tsdata->regmap)) { in edt_ft5x06_ts_probe()
1157 dev_err(&client->dev, "regmap allocation failed\n"); in edt_ft5x06_ts_probe()
1158 return PTR_ERR(tsdata->regmap); in edt_ft5x06_ts_probe()
1163 * custom action because we may replace regmap with M06-specific one in edt_ft5x06_ts_probe()
1166 error = devm_add_action_or_reset(&client->dev, edt_ft5x06_exit_regmap, in edt_ft5x06_ts_probe()
1171 chip_data = device_get_match_data(&client->dev); in edt_ft5x06_ts_probe()
1173 chip_data = (const struct edt_i2c_chip_data *)id->driver_data; in edt_ft5x06_ts_probe()
1174 if (!chip_data || !chip_data->max_support_points) { in edt_ft5x06_ts_probe()
1175 dev_err(&client->dev, "invalid or missing chip data\n"); in edt_ft5x06_ts_probe()
1176 return -EINVAL; in edt_ft5x06_ts_probe()
1179 tsdata->max_support_points = chip_data->max_support_points; in edt_ft5x06_ts_probe()
1181 tsdata->vcc = devm_regulator_get(&client->dev, "vcc"); in edt_ft5x06_ts_probe()
1182 if (IS_ERR(tsdata->vcc)) in edt_ft5x06_ts_probe()
1183 return dev_err_probe(&client->dev, PTR_ERR(tsdata->vcc), in edt_ft5x06_ts_probe()
1186 tsdata->iovcc = devm_regulator_get(&client->dev, "iovcc"); in edt_ft5x06_ts_probe()
1187 if (IS_ERR(tsdata->iovcc)) { in edt_ft5x06_ts_probe()
1188 error = PTR_ERR(tsdata->iovcc); in edt_ft5x06_ts_probe()
1189 if (error != -EPROBE_DEFER) in edt_ft5x06_ts_probe()
1190 dev_err(&client->dev, in edt_ft5x06_ts_probe()
1195 error = regulator_enable(tsdata->iovcc); in edt_ft5x06_ts_probe()
1197 dev_err(&client->dev, "failed to enable iovcc: %d\n", error); in edt_ft5x06_ts_probe()
1204 error = regulator_enable(tsdata->vcc); in edt_ft5x06_ts_probe()
1206 dev_err(&client->dev, "failed to enable vcc: %d\n", error); in edt_ft5x06_ts_probe()
1207 regulator_disable(tsdata->iovcc); in edt_ft5x06_ts_probe()
1211 error = devm_add_action_or_reset(&client->dev, in edt_ft5x06_ts_probe()
1217 tsdata->reset_gpio = devm_gpiod_get_optional(&client->dev, in edt_ft5x06_ts_probe()
1219 if (IS_ERR(tsdata->reset_gpio)) { in edt_ft5x06_ts_probe()
1220 error = PTR_ERR(tsdata->reset_gpio); in edt_ft5x06_ts_probe()
1221 dev_err(&client->dev, in edt_ft5x06_ts_probe()
1226 tsdata->wake_gpio = devm_gpiod_get_optional(&client->dev, in edt_ft5x06_ts_probe()
1228 if (IS_ERR(tsdata->wake_gpio)) { in edt_ft5x06_ts_probe()
1229 error = PTR_ERR(tsdata->wake_gpio); in edt_ft5x06_ts_probe()
1230 dev_err(&client->dev, in edt_ft5x06_ts_probe()
1236 * Check which sleep modes we can support. Power-off requires the in edt_ft5x06_ts_probe()
1237 * reset-pin to ensure correct power-down/power-up behaviour. Start with in edt_ft5x06_ts_probe()
1241 if (tsdata->reset_gpio) in edt_ft5x06_ts_probe()
1242 tsdata->suspend_mode = EDT_PMODE_POWEROFF; in edt_ft5x06_ts_probe()
1243 else if (tsdata->wake_gpio) in edt_ft5x06_ts_probe()
1244 tsdata->suspend_mode = EDT_PMODE_HIBERNATE; in edt_ft5x06_ts_probe()
1246 tsdata->suspend_mode = EDT_PMODE_NOT_SUPPORTED; in edt_ft5x06_ts_probe()
1248 if (tsdata->wake_gpio) { in edt_ft5x06_ts_probe()
1250 gpiod_set_value_cansleep(tsdata->wake_gpio, 1); in edt_ft5x06_ts_probe()
1254 if (tsdata->reset_gpio) { in edt_ft5x06_ts_probe()
1256 gpiod_set_value_cansleep(tsdata->reset_gpio, 0); in edt_ft5x06_ts_probe()
1260 input = devm_input_allocate_device(&client->dev); in edt_ft5x06_ts_probe()
1262 dev_err(&client->dev, "failed to allocate input device.\n"); in edt_ft5x06_ts_probe()
1263 return -ENOMEM; in edt_ft5x06_ts_probe()
1266 mutex_init(&tsdata->mutex); in edt_ft5x06_ts_probe()
1267 tsdata->client = client; in edt_ft5x06_ts_probe()
1268 tsdata->input = input; in edt_ft5x06_ts_probe()
1269 tsdata->factory_mode = false; in edt_ft5x06_ts_probe()
1274 dev_err(&client->dev, "touchscreen probe failed\n"); in edt_ft5x06_ts_probe()
1282 regmap_read(tsdata->regmap, 0x00, &val); in edt_ft5x06_ts_probe()
1286 edt_ft5x06_ts_get_defaults(&client->dev, tsdata); in edt_ft5x06_ts_probe()
1289 if (tsdata->reg_addr.reg_report_rate != NO_REGISTER && in edt_ft5x06_ts_probe()
1290 !device_property_read_u32(&client->dev, in edt_ft5x06_ts_probe()
1291 "report-rate-hz", &report_rate)) { in edt_ft5x06_ts_probe()
1292 if (tsdata->version == EDT_M06) in edt_ft5x06_ts_probe()
1293 tsdata->report_rate = clamp_val(report_rate, 30, 140); in edt_ft5x06_ts_probe()
1295 tsdata->report_rate = clamp_val(report_rate, 1, 255); in edt_ft5x06_ts_probe()
1297 if (report_rate != tsdata->report_rate) in edt_ft5x06_ts_probe()
1298 dev_warn(&client->dev, in edt_ft5x06_ts_probe()
1299 "report-rate %dHz is unsupported, use %dHz\n", in edt_ft5x06_ts_probe()
1300 report_rate, tsdata->report_rate); in edt_ft5x06_ts_probe()
1302 if (tsdata->version == EDT_M06) in edt_ft5x06_ts_probe()
1303 tsdata->report_rate /= 10; in edt_ft5x06_ts_probe()
1305 regmap_write(tsdata->regmap, tsdata->reg_addr.reg_report_rate, in edt_ft5x06_ts_probe()
1306 tsdata->report_rate); in edt_ft5x06_ts_probe()
1309 dev_dbg(&client->dev, in edt_ft5x06_ts_probe()
1311 tsdata->name, tsdata->fw_version, tsdata->num_x, tsdata->num_y); in edt_ft5x06_ts_probe()
1313 input->name = tsdata->name; in edt_ft5x06_ts_probe()
1314 input->id.bustype = BUS_I2C; in edt_ft5x06_ts_probe()
1315 input->dev.parent = &client->dev; in edt_ft5x06_ts_probe()
1318 0, tsdata->num_x * 64 - 1, 0, 0); in edt_ft5x06_ts_probe()
1320 0, tsdata->num_y * 64 - 1, 0, 0); in edt_ft5x06_ts_probe()
1322 touchscreen_parse_properties(input, true, &tsdata->prop); in edt_ft5x06_ts_probe()
1324 error = input_mt_init_slots(input, tsdata->max_support_points, in edt_ft5x06_ts_probe()
1327 dev_err(&client->dev, "Unable to init MT slots.\n"); in edt_ft5x06_ts_probe()
1331 irq_flags = irq_get_trigger_type(client->irq); in edt_ft5x06_ts_probe()
1336 error = devm_request_threaded_irq(&client->dev, client->irq, in edt_ft5x06_ts_probe()
1338 client->name, tsdata); in edt_ft5x06_ts_probe()
1340 dev_err(&client->dev, "Unable to request touchscreen IRQ.\n"); in edt_ft5x06_ts_probe()
1350 dev_dbg(&client->dev, in edt_ft5x06_ts_probe()
1352 client->irq, in edt_ft5x06_ts_probe()
1353 tsdata->wake_gpio ? desc_to_gpio(tsdata->wake_gpio) : -1, in edt_ft5x06_ts_probe()
1354 tsdata->reset_gpio ? desc_to_gpio(tsdata->reset_gpio) : -1); in edt_ft5x06_ts_probe()
1370 struct gpio_desc *reset_gpio = tsdata->reset_gpio; in edt_ft5x06_ts_suspend()
1376 if (tsdata->suspend_mode == EDT_PMODE_NOT_SUPPORTED) in edt_ft5x06_ts_suspend()
1380 ret = regmap_write(tsdata->regmap, PMOD_REGISTER_OPMODE, in edt_ft5x06_ts_suspend()
1385 if (tsdata->suspend_mode == EDT_PMODE_HIBERNATE) in edt_ft5x06_ts_suspend()
1389 * Power-off according the datasheet. Cut the power may leaf the irq in edt_ft5x06_ts_suspend()
1394 disable_irq(tsdata->client->irq); in edt_ft5x06_ts_suspend()
1399 ret = regulator_disable(tsdata->vcc); in edt_ft5x06_ts_suspend()
1402 ret = regulator_disable(tsdata->iovcc); in edt_ft5x06_ts_suspend()
1418 if (tsdata->suspend_mode == EDT_PMODE_NOT_SUPPORTED) in edt_ft5x06_ts_resume()
1421 if (tsdata->suspend_mode == EDT_PMODE_POWEROFF) { in edt_ft5x06_ts_resume()
1422 struct gpio_desc *reset_gpio = tsdata->reset_gpio; in edt_ft5x06_ts_resume()
1435 ret = regulator_enable(tsdata->iovcc); in edt_ft5x06_ts_resume()
1437 dev_err(dev, "Failed to enable iovcc\n"); in edt_ft5x06_ts_resume()
1444 ret = regulator_enable(tsdata->vcc); in edt_ft5x06_ts_resume()
1446 dev_err(dev, "Failed to enable vcc\n"); in edt_ft5x06_ts_resume()
1447 regulator_disable(tsdata->iovcc); in edt_ft5x06_ts_resume()
1456 enable_irq(tsdata->client->irq); in edt_ft5x06_ts_resume()
1458 if (tsdata->factory_mode) in edt_ft5x06_ts_resume()
1461 struct gpio_desc *wake_gpio = tsdata->wake_gpio; in edt_ft5x06_ts_resume()
1503 { .name = "edt-ft5x06", .driver_data = (long)&edt_ft5x06_data },
1504 { .name = "edt-ft5506", .driver_data = (long)&edt_ft5506_data },
1505 { .name = "ev-ft5726", .driver_data = (long)&edt_ft5506_data },
1507 /* Note no edt- prefix for compatibility with the ft6236.c driver */
1514 MODULE_DEVICE_TABLE(i2c, edt_ft5x06_ts_id);
1517 { .compatible = "edt,edt-ft5206", .data = &edt_ft5x06_data },
1518 { .compatible = "edt,edt-ft5306", .data = &edt_ft5x06_data },
1519 { .compatible = "edt,edt-ft5406", .data = &edt_ft5x06_data },
1520 { .compatible = "edt,edt-ft5506", .data = &edt_ft5506_data },
1521 { .compatible = "evervision,ev-ft5726", .data = &edt_ft5506_data },
1549 MODULE_DESCRIPTION("EDT FT5x06 I2C Touchscreen Driver");