Lines Matching +full:i2c +full:- +full:retry +full:- +full:count

2  * Weida HiTech WDT87xx TouchScreen I2C driver
4 * Copyright (c) 2015 Weida Hi-Tech Co., Ltd.
12 #include <linux/i2c.h>
193 .addr = client->addr, in wdt87xx_i2c_xfer()
199 .addr = client->addr, in wdt87xx_i2c_xfer()
208 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); in wdt87xx_i2c_xfer()
210 error = ret < 0 ? ret : -EIO; in wdt87xx_i2c_xfer()
211 dev_err(&client->dev, "%s: i2c transfer failed: %d\n", in wdt87xx_i2c_xfer()
230 dev_err(&client->dev, "get desc failed: %d\n", error); in wdt87xx_get_desc()
235 dev_err(&client->dev, "unexpected response to get desc: %d\n", in wdt87xx_get_desc()
237 return -EINVAL; in wdt87xx_get_desc()
254 return -EINVAL; in wdt87xx_get_string()
259 dev_err(&client->dev, "get string failed: %d\n", error); in wdt87xx_get_string()
264 dev_err(&client->dev, "unexpected response to get string: %d\n", in wdt87xx_get_string()
266 return -EINVAL; in wdt87xx_get_string()
287 return -EINVAL; in wdt87xx_get_feature()
305 dev_err(&client->dev, "get feature failed: %d\n", error); in wdt87xx_get_feature()
341 return -EINVAL; in wdt87xx_set_feature()
348 dev_err(&client->dev, "set feature failed: %d\n", error); in wdt87xx_set_feature()
390 dev_err(&client->dev, "Invalid command: %d\n", cmd); in wdt87xx_send_command()
391 return -EINVAL; in wdt87xx_send_command()
401 dev_dbg(&client->dev, "resetting device now\n"); in wdt87xx_sw_reset()
405 dev_err(&client->dev, "reset failed\n"); in wdt87xx_sw_reset()
420 while (pos < fw->size) { in wdt87xx_get_fw_chunk()
421 chunk_id = get_unaligned_le32(fw->data + in wdt87xx_get_fw_chunk()
424 return fw->data + pos; in wdt87xx_get_fw_chunk()
426 chunk_size = get_unaligned_le32(fw->data + in wdt87xx_get_fw_chunk()
442 dev_err(&client->dev, "failed to get device desc\n"); in wdt87xx_get_sysparam()
446 param->vendor_id = get_unaligned_le16(buf + DEV_DESC_OFFSET_VID); in wdt87xx_get_sysparam()
447 param->product_id = get_unaligned_le16(buf + DEV_DESC_OFFSET_PID); in wdt87xx_get_sysparam()
451 dev_err(&client->dev, "failed to get parameters\n"); in wdt87xx_get_sysparam()
455 param->xmls_id1 = get_unaligned_le16(buf + CTL_PARAM_OFFSET_XMLS_ID1); in wdt87xx_get_sysparam()
456 param->xmls_id2 = get_unaligned_le16(buf + CTL_PARAM_OFFSET_XMLS_ID2); in wdt87xx_get_sysparam()
457 param->phy_ch_x = get_unaligned_le16(buf + CTL_PARAM_OFFSET_PHY_CH_X); in wdt87xx_get_sysparam()
458 param->phy_ch_y = get_unaligned_le16(buf + CTL_PARAM_OFFSET_PHY_CH_Y); in wdt87xx_get_sysparam()
459 param->phy_w = get_unaligned_le16(buf + CTL_PARAM_OFFSET_PHY_W) / 10; in wdt87xx_get_sysparam()
460 param->phy_h = get_unaligned_le16(buf + CTL_PARAM_OFFSET_PHY_H) / 10; in wdt87xx_get_sysparam()
463 param->scaling_factor = in wdt87xx_get_sysparam()
466 param->max_x = MAX_UNIT_AXIS; in wdt87xx_get_sysparam()
467 param->max_y = DIV_ROUND_CLOSEST(MAX_UNIT_AXIS * param->phy_h, in wdt87xx_get_sysparam()
468 param->phy_w); in wdt87xx_get_sysparam()
472 dev_err(&client->dev, "failed to get platform id\n"); in wdt87xx_get_sysparam()
476 param->plat_id = buf[1]; in wdt87xx_get_sysparam()
481 dev_err(&client->dev, "failed to get firmware id\n"); in wdt87xx_get_sysparam()
486 dev_err(&client->dev, "wrong id of fw response: 0x%x\n", in wdt87xx_get_sysparam()
488 return -EINVAL; in wdt87xx_get_sysparam()
491 param->fw_id = get_unaligned_le16(&buf[1]); in wdt87xx_get_sysparam()
493 dev_info(&client->dev, in wdt87xx_get_sysparam()
495 param->fw_id, param->plat_id, in wdt87xx_get_sysparam()
496 param->xmls_id1, param->xmls_id2); in wdt87xx_get_sysparam()
510 data1 = get_unaligned_le32(fw->data + FW_FOURCC1_OFFSET); in wdt87xx_validate_firmware()
511 data2 = get_unaligned_le32(fw->data + FW_FOURCC2_OFFSET); in wdt87xx_validate_firmware()
513 dev_err(&wdt->client->dev, "check fw tag failed\n"); in wdt87xx_validate_firmware()
514 return -EINVAL; in wdt87xx_validate_firmware()
517 size = get_unaligned_le32(fw->data + FW_SIZE_OFFSET); in wdt87xx_validate_firmware()
518 if (size != fw->size) { in wdt87xx_validate_firmware()
519 dev_err(&wdt->client->dev, in wdt87xx_validate_firmware()
521 size, fw->size); in wdt87xx_validate_firmware()
522 return -EINVAL; in wdt87xx_validate_firmware()
531 dev_err(&wdt->client->dev, in wdt87xx_validate_firmware()
533 return -EINVAL; in wdt87xx_validate_firmware()
538 chip_id = (wdt->param.fw_id >> 12) & 0xF; in wdt87xx_validate_firmware()
541 dev_err(&wdt->client->dev, in wdt87xx_validate_firmware()
544 return -ENODEV; in wdt87xx_validate_firmware()
557 return -EINVAL; in wdt87xx_validate_fw_chunk()
567 int count = 0; in wdt87xx_write_data() local
573 dev_err(&client->dev, in wdt87xx_write_data()
576 return -EINVAL; in wdt87xx_write_data()
592 length -= packet_size; in wdt87xx_write_data()
599 if ((++count % 32) == 0) { in wdt87xx_write_data()
651 dev_err(&client->dev, "failed to set checksum length\n"); in wdt87xx_get_checksum()
657 dev_err(&client->dev, "failed to set checksum address\n"); in wdt87xx_get_checksum()
670 dev_err(&client->dev, "failed to request checksum\n"); in wdt87xx_get_checksum()
678 dev_err(&client->dev, "failed to read checksum\n"); in wdt87xx_get_checksum()
694 int retry = 0; in wdt87xx_write_firmware() local
697 dev_dbg(&client->dev, "start 4k page program\n"); in wdt87xx_write_firmware()
701 dev_err(&client->dev, "stop report mode failed\n"); in wdt87xx_write_firmware()
707 dev_err(&client->dev, "unlock failed\n"); in wdt87xx_write_firmware()
714 dev_dbg(&client->dev, "%s: %x, %x\n", __func__, in wdt87xx_write_firmware()
718 size -= page_size; in wdt87xx_write_firmware()
720 for (retry = 0; retry < MAX_RETRIES; retry++) { in wdt87xx_write_firmware()
724 dev_err(&client->dev, in wdt87xx_write_firmware()
734 dev_err(&client->dev, in wdt87xx_write_firmware()
743 dev_err(&client->dev, in wdt87xx_write_firmware()
755 dev_err(&client->dev, in wdt87xx_write_firmware()
756 "checksum fail: %d vs %d, retry %d\n", in wdt87xx_write_firmware()
757 device_checksum, firmware_checksum, retry); in wdt87xx_write_firmware()
760 if (retry == MAX_RETRIES) { in wdt87xx_write_firmware()
761 dev_err(&client->dev, "page write failed\n"); in wdt87xx_write_firmware()
762 error = -EIO; in wdt87xx_write_firmware()
773 dev_err(&client->dev, "lock failed\n"); in wdt87xx_write_firmware()
780 dev_err(&client->dev, "start to report failed\n"); in wdt87xx_write_firmware()
793 dev_err(&client->dev, "unable to locate chunk (type %d)\n", in wdt87xx_load_chunk()
795 return -EINVAL; in wdt87xx_load_chunk()
800 dev_err(&client->dev, "invalid chunk (type %d): %d\n", in wdt87xx_load_chunk()
807 dev_err(&client->dev, in wdt87xx_load_chunk()
827 error = mutex_lock_interruptible(&wdt->fw_mutex); in wdt87xx_do_update_firmware()
831 disable_irq(client->irq); in wdt87xx_do_update_firmware()
835 dev_err(&client->dev, in wdt87xx_do_update_firmware()
843 dev_err(&client->dev, "soft reset failed: %d\n", error); in wdt87xx_do_update_firmware()
848 error = wdt87xx_get_sysparam(client, &wdt->param); in wdt87xx_do_update_firmware()
850 dev_err(&client->dev, in wdt87xx_do_update_firmware()
853 enable_irq(client->irq); in wdt87xx_do_update_firmware()
854 mutex_unlock(&wdt->fw_mutex); in wdt87xx_do_update_firmware()
868 dev_err(&client->dev, "unable to retrieve firmware %s: %d\n", in wdt87xx_update_firmware()
887 cfg_csum = wdt->param.xmls_id1; in config_csum_show()
888 cfg_csum = (cfg_csum << 16) | wdt->param.xmls_id2; in config_csum_show()
899 return scnprintf(buf, PAGE_SIZE, "%x\n", wdt->param.fw_id); in fw_version_show()
908 return scnprintf(buf, PAGE_SIZE, "%x\n", wdt->param.plat_id); in plat_id_show()
913 const char *buf, size_t count) in update_config_store() argument
919 return error ? error : count; in update_config_store()
924 const char *buf, size_t count) in update_fw_store() argument
930 return error ? error : count; in update_fw_store()
960 finger_id = (buf[FINGER_EV_V1_OFFSET_ID] >> 3) - 1; in wdt87xx_report_contact()
969 w *= param->scaling_factor; in wdt87xx_report_contact()
976 y = DIV_ROUND_CLOSEST(y * param->phy_h, param->phy_w); in wdt87xx_report_contact()
979 if (x > param->max_x || y > param->max_y) in wdt87xx_report_contact()
982 dev_dbg(input->dev.parent, "tip on (%d), x(%d), y(%d)\n", in wdt87xx_report_contact()
996 struct i2c_client *client = wdt->client; in wdt87xx_ts_interrupt()
1003 dev_err(&client->dev, "read v1 raw data failed: %d\n", error); in wdt87xx_ts_interrupt()
1012 wdt87xx_report_contact(wdt->input, in wdt87xx_ts_interrupt()
1013 &wdt->param, in wdt87xx_ts_interrupt()
1017 input_mt_sync_frame(wdt->input); in wdt87xx_ts_interrupt()
1018 input_sync(wdt->input); in wdt87xx_ts_interrupt()
1026 struct device *dev = &wdt->client->dev; in wdt87xx_ts_create_input_device()
1028 unsigned int res = DIV_ROUND_CLOSEST(MAX_UNIT_AXIS, wdt->param.phy_w); in wdt87xx_ts_create_input_device()
1034 return -ENOMEM; in wdt87xx_ts_create_input_device()
1036 wdt->input = input; in wdt87xx_ts_create_input_device()
1038 input->name = "WDT87xx Touchscreen"; in wdt87xx_ts_create_input_device()
1039 input->id.bustype = BUS_I2C; in wdt87xx_ts_create_input_device()
1040 input->id.vendor = wdt->param.vendor_id; in wdt87xx_ts_create_input_device()
1041 input->id.product = wdt->param.product_id; in wdt87xx_ts_create_input_device()
1042 input->phys = wdt->phys; in wdt87xx_ts_create_input_device()
1045 wdt->param.max_x, 0, 0); in wdt87xx_ts_create_input_device()
1047 wdt->param.max_y, 0, 0); in wdt87xx_ts_create_input_device()
1052 0, wdt->param.max_x, 0, 0); in wdt87xx_ts_create_input_device()
1073 dev_dbg(&client->dev, "adapter=%d, client irq: %d\n", in wdt87xx_ts_probe()
1074 client->adapter->nr, client->irq); in wdt87xx_ts_probe()
1076 /* Check if the I2C function is ok in this adaptor */ in wdt87xx_ts_probe()
1077 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) in wdt87xx_ts_probe()
1078 return -ENXIO; in wdt87xx_ts_probe()
1080 wdt = devm_kzalloc(&client->dev, sizeof(*wdt), GFP_KERNEL); in wdt87xx_ts_probe()
1082 return -ENOMEM; in wdt87xx_ts_probe()
1084 wdt->client = client; in wdt87xx_ts_probe()
1085 mutex_init(&wdt->fw_mutex); in wdt87xx_ts_probe()
1088 snprintf(wdt->phys, sizeof(wdt->phys), "i2c-%u-%04x/input0", in wdt87xx_ts_probe()
1089 client->adapter->nr, client->addr); in wdt87xx_ts_probe()
1091 error = wdt87xx_get_sysparam(client, &wdt->param); in wdt87xx_ts_probe()
1099 error = devm_request_threaded_irq(&client->dev, client->irq, in wdt87xx_ts_probe()
1102 client->name, wdt); in wdt87xx_ts_probe()
1104 dev_err(&client->dev, "request irq failed: %d\n", error); in wdt87xx_ts_probe()
1108 error = devm_device_add_group(&client->dev, &wdt87xx_attr_group); in wdt87xx_ts_probe()
1110 dev_err(&client->dev, "create sysfs failed: %d\n", error); in wdt87xx_ts_probe()
1122 disable_irq(client->irq); in wdt87xx_suspend()
1126 enable_irq(client->irq); in wdt87xx_suspend()
1127 dev_err(&client->dev, in wdt87xx_suspend()
1149 dev_err(&client->dev, in wdt87xx_resume()
1153 enable_irq(client->irq); in wdt87xx_resume()
1164 MODULE_DEVICE_TABLE(i2c, wdt87xx_dev_id);