static ssize_t cyttsp5_calibrate_store(struct device *dev, struct cyttsp5_attribute *attr, const char *buf, size_t size) { struct cyttsp5_device_access_data *dad = cyttsp5_get_device_access_data(dev); ssize_t length; int rc = 0; mutex_lock(&dad->sysfs_lock); length = cyttsp5_ic_parse_input(dev, buf, size, dad->ic_buf, CY_MAX_PRBUF_SIZE); if (length != 2) { dev_err(dev, "%s: Malformed input\n", __func__); rc = -EINVAL; goto exit_unlock; } dad->calibrate_sensing_mode = dad->ic_buf[0]; dad->calibrate_initialize_baselines = dad->ic_buf[1]; exit_unlock: mutex_unlock(&dad->sysfs_lock); if (rc) return rc; return size; }
static ssize_t cyttsp5_response_show(struct device *dev, struct device_attribute *attr, char *buf) { struct cyttsp5_device_access_data *dad = cyttsp5_get_device_access_data(dev); int i; ssize_t num_read; int index; mutex_lock(&dad->sysfs_lock); index = scnprintf(buf, CY_MAX_PRBUF_SIZE, "Status %d\n", dad->status); if (!dad->status) goto error; num_read = dad->response_length; for (i = 0; i < num_read; i++) index += scnprintf(buf + index, CY_MAX_PRBUF_SIZE - index, "0x%02X\n", dad->response_buf[i]); index += scnprintf(buf + index, CY_MAX_PRBUF_SIZE - index, "(%d bytes)\n", num_read); error: mutex_unlock(&dad->sysfs_lock); return index; }
static ssize_t cyttsp5_baseline_show(struct device *dev, struct cyttsp5_attribute *attr, char *buf) { struct cyttsp5_device_access_data *dad = cyttsp5_get_device_access_data(dev); int status = STATUS_FAIL; int length = 0; int size; int rc; mutex_lock(&dad->sysfs_lock); pm_runtime_get_sync(dev); rc = cmd->request_exclusive(dev, CY_REQUEST_EXCLUSIVE_TIMEOUT); if (rc < 0) { dev_err(dev, "%s: Error on request exclusive r=%d\n", __func__, rc); goto put_pm_runtime; } rc = cyttsp5_suspend_scan_cmd_(dev); if (rc < 0) { dev_err(dev, "%s: Error on suspend scan r=%d\n", __func__, rc); goto release_exclusive; } rc = _cyttsp5_initialize_baselines_cmd(dev, dad->baseline_sensing_mode, &dad->ic_buf[0]); if (rc < 0) { dev_err(dev, "%s: Error on initialize baselines r=%d\n", __func__, rc); goto resume_scan; } length = 1; status = STATUS_SUCCESS; resume_scan: cyttsp5_resume_scan_cmd_(dev); release_exclusive: cmd->release_exclusive(dev); put_pm_runtime: pm_runtime_put(dev); if (status == STATUS_FAIL) length = 0; size = prepare_print_buffer(status, dad->ic_buf, length, buf); mutex_unlock(&dad->sysfs_lock); return size; }
static inline void cyttsp5_remove_file(struct device *dev, const struct cyttsp5_attribute *attr) { struct cyttsp5_device_access_data *dad; if (dev) { dad = cyttsp5_get_device_access_data(dev); sysfs_remove_file(&dad->mfg_test, &attr->attr); } }
static int cyttsp5_setup_sysfs(struct device *dev) { struct cyttsp5_device_access_data *dad = cyttsp5_get_device_access_data(dev); int rc; rc = device_create_file(dev, &dev_attr_command); if (rc) { dev_err(dev, "%s: Error, could not create command\n", __func__); goto exit; } rc = device_create_file(dev, &dev_attr_status); if (rc) { dev_err(dev, "%s: Error, could not create status\n", __func__); goto unregister_command; } rc = device_create_file(dev, &dev_attr_response); if (rc) { dev_err(dev, "%s: Error, could not create response\n", __func__); goto unregister_status; } #ifdef TTHE_TUNER_SUPPORT dad->tthe_get_panel_data_debugfs = debugfs_create_file( CYTTSP5_TTHE_TUNER_GET_PANEL_DATA_FILE_NAME, 0644, NULL, dad, &tthe_get_panel_data_fops); if (IS_ERR_OR_NULL(dad->tthe_get_panel_data_debugfs)) { dev_err(dev, "%s: Error, could not create get_panel_data\n", __func__); dad->tthe_get_panel_data_debugfs = NULL; goto unregister_response; } #endif dad->sysfs_nodes_created = true; return rc; #ifdef TTHE_TUNER_SUPPORT unregister_response: device_remove_file(dev, &dev_attr_response); #endif unregister_status: device_remove_file(dev, &dev_attr_status); unregister_command: device_remove_file(dev, &dev_attr_command); exit: return rc; }
static ssize_t cyttsp5_status_show(struct device *dev, struct device_attribute *attr, char *buf) { struct cyttsp5_device_access_data *dad = cyttsp5_get_device_access_data(dev); u8 val; mutex_lock(&dad->sysfs_lock); val = dad->status; mutex_unlock(&dad->sysfs_lock); return scnprintf(buf, CY_MAX_PRBUF_SIZE, "%d\n", val); }
static inline int cyttsp5_create_file(struct device *dev, const struct cyttsp5_attribute *attr) { struct cyttsp5_device_access_data *dad; int error = 0; if (dev) { dad = cyttsp5_get_device_access_data(dev); error = sysfs_create_file(&dad->mfg_test, &attr->attr); } return error; }
static int cyttsp5_setup_sysfs_attention(struct device *dev) { struct cyttsp5_device_access_data *dad = cyttsp5_get_device_access_data(dev); int rc = 0; dad->si = cmd->request_sysinfo(dev); if (!dad->si) return -EINVAL; rc = cyttsp5_setup_sysfs(dev); cmd->unsubscribe_attention(dev, CY_ATTEN_STARTUP, CY_MODULE_DEVICE_ACCESS, cyttsp5_setup_sysfs_attention, 0); return rc; }
static int cyttsp5_device_access_release(struct device *dev) { struct cyttsp5_device_access_data *dad = cyttsp5_get_device_access_data(dev); if (dad->sysfs_nodes_created) { device_remove_file(dev, &dev_attr_command); device_remove_file(dev, &dev_attr_status); device_remove_file(dev, &dev_attr_response); #ifdef TTHE_TUNER_SUPPORT debugfs_remove(dad->tthe_get_panel_data_debugfs); #endif } else { cmd->unsubscribe_attention(dev, CY_ATTEN_STARTUP, CY_MODULE_DEVICE_ACCESS, cyttsp5_setup_sysfs_attention, 0); } kfree(dad); return 0; }
static ssize_t cyttsp5_command_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct cyttsp5_device_access_data *dad = cyttsp5_get_device_access_data(dev); ssize_t length; int rc; mutex_lock(&dad->sysfs_lock); dad->status = 0; dad->response_length = 0; length = cyttsp5_ic_parse_input(dev, buf, size, dad->ic_buf, CY_MAX_PRBUF_SIZE); if (length <= 0) { dev_err(dev, "%s: %s Group Data store\n", __func__, "Malformed input for"); goto exit; } /* write ic_buf to log */ cyttsp5_pr_buf(dev, dad->pr_buf, dad->ic_buf, length, "ic_buf"); //pm_runtime_get_sync(dev); rc = cmd->cmd->user_cmd(dev, 1, CY_MAX_PRBUF_SIZE, dad->response_buf, length, dad->ic_buf, &dad->response_length); //pm_runtime_put(dev); if (rc) { dad->response_length = 0; dev_err(dev, "%s: Failed to store command\n", __func__); } else { dad->status = 1; } exit: mutex_unlock(&dad->sysfs_lock); dev_vdbg(dev, "%s: return size=%d\n", __func__, size); return size; }
static ssize_t cyttsp5_run_and_get_selftest_result(struct device *dev, char *buf, size_t buf_len, u8 test_id, u16 read_length, bool get_result_on_pass) { struct cyttsp5_device_access_data *dad = cyttsp5_get_device_access_data(dev); int status = STATUS_FAIL; u8 cmd_status = 0; u8 summary_result = 0; u16 act_length = 0; int length = 0; int size; int rc; mutex_lock(&dad->sysfs_lock); pm_runtime_get_sync(dev); rc = cmd->request_exclusive(dev, CY_REQUEST_EXCLUSIVE_TIMEOUT); if (rc < 0) { dev_err(dev, "%s: Error on request exclusive r=%d\n", __func__, rc); goto put_pm_runtime; } rc = cyttsp5_suspend_scan_cmd_(dev); if (rc < 0) { dev_err(dev, "%s: Error on suspend scan r=%d\n", __func__, rc); goto release_exclusive; } rc = cyttsp5_run_selftest_cmd_(dev, test_id, 0, &cmd_status, &summary_result, NULL); if (rc < 0) { dev_err(dev, "%s: Error on run self test for test_id:%d r=%d\n", __func__, test_id, rc); goto resume_scan; } /* Form response buffer */ dad->ic_buf[0] = cmd_status; dad->ic_buf[1] = summary_result; length = 2; /* Get data if command status is success */ if (cmd_status != CY_CMD_STATUS_SUCCESS) goto status_success; /* Get data unless test result is pass */ if (summary_result == CY_ST_RESULT_PASS && !get_result_on_pass) goto status_success; rc = cyttsp5_get_selftest_result_cmd_(dev, 0, read_length, test_id, &cmd_status, &act_length, &dad->ic_buf[6]); if (rc < 0) { dev_err(dev, "%s: Error on get self test result r=%d\n", __func__, rc); goto resume_scan; } dad->ic_buf[2] = cmd_status; dad->ic_buf[3] = test_id; dad->ic_buf[4] = LOW_BYTE(act_length); dad->ic_buf[5] = HI_BYTE(act_length); length = 6 + act_length; status_success: status = STATUS_SUCCESS; resume_scan: cyttsp5_resume_scan_cmd_(dev); release_exclusive: cmd->release_exclusive(dev); put_pm_runtime: pm_runtime_put(dev); if (status == STATUS_FAIL) length = 0; size = prepare_print_buffer(status, dad->ic_buf, length, buf, buf_len); mutex_unlock(&dad->sysfs_lock); return size; }
static int cyttsp5_setup_sysfs(struct device *dev) { struct cyttsp5_device_access_data *dad = cyttsp5_get_device_access_data(dev); int rc; rc = device_create_file(dev, &dev_attr_command); if (rc) { dev_err(dev, "%s: Error, could not create command\n", __func__); goto exit; } rc = device_create_file(dev, &dev_attr_status); if (rc) { dev_err(dev, "%s: Error, could not create status\n", __func__); goto unregister_command; } rc = device_create_file(dev, &dev_attr_response); if (rc) { dev_err(dev, "%s: Error, could not create response\n", __func__); goto unregister_status; } dad->base_dentry = debugfs_create_dir(dev_name(dev), NULL); if (IS_ERR_OR_NULL(dad->base_dentry)) { dev_err(dev, "%s: Error, could not create base directory\n", __func__); goto unregister_response; } dad->mfg_test_dentry = debugfs_create_dir("mfg_test", dad->base_dentry); if (IS_ERR_OR_NULL(dad->mfg_test_dentry)) { dev_err(dev, "%s: Error, could not create mfg_test directory\n", __func__); goto unregister_base_dir; } if (IS_ERR_OR_NULL(debugfs_create_file("panel_scan", 0600, dad->mfg_test_dentry, dad, &panel_scan_debugfs_fops))) { dev_err(dev, "%s: Error, could not create panel_scan\n", __func__); goto unregister_base_dir; } if (IS_ERR_OR_NULL(debugfs_create_file("get_idac", 0600, dad->mfg_test_dentry, dad, &get_idac_debugfs_fops))) { dev_err(dev, "%s: Error, could not create get_idac\n", __func__); goto unregister_base_dir; } if (IS_ERR_OR_NULL(debugfs_create_file("auto_shorts", 0400, dad->mfg_test_dentry, dad, &auto_shorts_debugfs_fops))) { dev_err(dev, "%s: Error, could not create auto_shorts\n", __func__); goto unregister_base_dir; } if (IS_ERR_OR_NULL(debugfs_create_file("opens", 0400, dad->mfg_test_dentry, dad, &opens_debugfs_fops))) { dev_err(dev, "%s: Error, could not create opens\n", __func__); goto unregister_base_dir; } if (IS_ERR_OR_NULL(debugfs_create_file("calibrate", 0600, dad->mfg_test_dentry, dad, &calibrate_debugfs_fops))) { dev_err(dev, "%s: Error, could not create calibrate\n", __func__); goto unregister_base_dir; } if (IS_ERR_OR_NULL(debugfs_create_file("baseline", 0600, dad->mfg_test_dentry, dad, &baseline_debugfs_fops))) { dev_err(dev, "%s: Error, could not create baseline\n", __func__); goto unregister_base_dir; } if (IS_ERR_OR_NULL(debugfs_create_file("cm_panel", 0400, dad->mfg_test_dentry, dad, &cm_panel_debugfs_fops))) { dev_err(dev, "%s: Error, could not create cm_panel\n", __func__); goto unregister_base_dir; } if (IS_ERR_OR_NULL(debugfs_create_file("cp_panel", 0400, dad->mfg_test_dentry, dad, &cp_panel_debugfs_fops))) { dev_err(dev, "%s: Error, could not create cp_panel\n", __func__); goto unregister_base_dir; } if (IS_ERR_OR_NULL(debugfs_create_file("cm_button", 0400, dad->mfg_test_dentry, dad, &cm_button_debugfs_fops))) { dev_err(dev, "%s: Error, could not create cm_button\n", __func__); goto unregister_base_dir; } if (IS_ERR_OR_NULL(debugfs_create_file("cp_button", 0400, dad->mfg_test_dentry, dad, &cp_button_debugfs_fops))) { dev_err(dev, "%s: Error, could not create cp_button\n", __func__); goto unregister_base_dir; } #ifdef TTHE_TUNER_SUPPORT dad->tthe_get_panel_data_debugfs = debugfs_create_file( CYTTSP5_TTHE_TUNER_GET_PANEL_DATA_FILE_NAME, 0644, NULL, dad, &tthe_get_panel_data_fops); if (IS_ERR_OR_NULL(dad->tthe_get_panel_data_debugfs)) { dev_err(dev, "%s: Error, could not create get_panel_data\n", __func__); dad->tthe_get_panel_data_debugfs = NULL; goto unregister_base_dir; } #endif dad->sysfs_nodes_created = true; return rc; unregister_base_dir: debugfs_remove_recursive(dad->base_dentry); unregister_response: device_remove_file(dev, &dev_attr_response); unregister_status: device_remove_file(dev, &dev_attr_status); unregister_command: device_remove_file(dev, &dev_attr_command); exit: return rc; }
static int cyttsp5_setup_sysfs(struct device *dev) { struct cyttsp5_device_access_data *dad = cyttsp5_get_device_access_data(dev); int rc; rc = device_create_file(dev, &dev_attr_command); if (rc) { dev_err(dev, "%s: Error, could not create command\n", __func__); goto exit; } rc = device_create_file(dev, &dev_attr_status); if (rc) { dev_err(dev, "%s: Error, could not create status\n", __func__); goto unregister_command; } rc = device_create_file(dev, &dev_attr_response); if (rc) { dev_err(dev, "%s: Error, could not create response\n", __func__); goto unregister_status; } rc = kobject_init_and_add(&dad->mfg_test, &cyttsp5_ktype, &dev->kobj, "mfg_test"); if (rc) { dev_err(dev, "Unable to create mfg_test kobject\n"); goto unregister_response; } rc = cyttsp5_create_file(dev, &cy_attr_panel_scan); if (rc) { dev_err(dev, "%s: Error, could not create panel_scan\n", __func__); goto put_kobject; } rc = cyttsp5_create_file(dev, &cy_attr_auto_shorts); if (rc) { dev_err(dev, "%s: Error, could not create auto_shorts\n", __func__); goto unregister_panel_scan; } rc = cyttsp5_create_file(dev, &cy_attr_opens); if (rc) { dev_err(dev, "%s: Error, could not create opens\n", __func__); goto unregister_auto_shorts; } rc = cyttsp5_create_file(dev, &cy_attr_get_idac); if (rc) { dev_err(dev, "%s: Error, could not create get_idac\n", __func__); goto unregister_opens; } rc = cyttsp5_create_file(dev, &cy_attr_calibrate); if (rc) { dev_err(dev, "%s: Error, could not create calibrate\n", __func__); goto unregister_get_idac; } rc = cyttsp5_create_file(dev, &cy_attr_baseline); if (rc) { dev_err(dev, "%s: Error, could not create baseline\n", __func__); goto unregister_calibrate; } #ifdef TTHE_TUNER_SUPPORT dad->tthe_get_panel_data_debugfs = debugfs_create_file( CYTTSP5_TTHE_TUNER_GET_PANEL_DATA_FILE_NAME, 0644, NULL, dad, &tthe_get_panel_data_fops); if (IS_ERR_OR_NULL(dad->tthe_get_panel_data_debugfs)) { dev_err(dev, "%s: Error, could not create get_panel_data\n", __func__); dad->tthe_get_panel_data_debugfs = NULL; goto unregister_baseline; } #endif dad->sysfs_nodes_created = true; return rc; #ifdef TTHE_TUNER_SUPPORT unregister_baseline: cyttsp5_remove_file(dev, &cy_attr_baseline); #endif unregister_calibrate: cyttsp5_remove_file(dev, &cy_attr_calibrate); unregister_get_idac: cyttsp5_remove_file(dev, &cy_attr_get_idac); unregister_opens: cyttsp5_remove_file(dev, &cy_attr_opens); unregister_auto_shorts: cyttsp5_remove_file(dev, &cy_attr_auto_shorts); unregister_panel_scan: cyttsp5_remove_file(dev, &cy_attr_panel_scan); put_kobject: kobject_put(&dad->mfg_test); unregister_response: device_remove_file(dev, &dev_attr_response); unregister_status: device_remove_file(dev, &dev_attr_status); unregister_command: device_remove_file(dev, &dev_attr_command); exit: return rc; }
static ssize_t cyttsp5_panel_scan_show(struct device *dev, struct cyttsp5_attribute *attr, char *buf) { struct cyttsp5_device_access_data *dad = cyttsp5_get_device_access_data(dev); int status = STATUS_FAIL; u8 config; u16 actual_read_len; int length = 0; u8 element_size = 0; u8 *buf_offset; int elem_offset = 0; int size; int rc; mutex_lock(&dad->sysfs_lock); pm_runtime_get_sync(dev); rc = cmd->request_exclusive(dev, CY_REQUEST_EXCLUSIVE_TIMEOUT); if (rc < 0) { dev_err(dev, "%s: Error on request exclusive r=%d\n", __func__, rc); goto put_pm_runtime; } rc = cyttsp5_suspend_scan_cmd_(dev); if (rc < 0) { dev_err(dev, "%s: Error on suspend scan r=%d\n", __func__, rc); goto release_exclusive; } rc = cyttsp5_exec_scan_cmd_(dev); if (rc < 0) { dev_err(dev, "%s: Error on execute panel scan r=%d\n", __func__, rc); goto resume_scan; } /* Set length to max to read all */ rc = cyttsp5_ret_scan_data_cmd_(dev, 0, 0xFFFF, dad->panel_scan_data_id, dad->ic_buf, &config, &actual_read_len, NULL); if (rc < 0) { dev_err(dev, "%s: Error on retrieve panel scan r=%d\n", __func__, rc); goto resume_scan; } length = get_unaligned_le16(&dad->ic_buf[0]); buf_offset = dad->ic_buf + length; element_size = config & 0x07; elem_offset = actual_read_len; while (actual_read_len > 0) { rc = cyttsp5_ret_scan_data_cmd_(dev, elem_offset, 0xFFFF, dad->panel_scan_data_id, NULL, &config, &actual_read_len, buf_offset); if (rc < 0) goto resume_scan; length += actual_read_len * element_size; buf_offset = dad->ic_buf + length; elem_offset += actual_read_len; } /* Reconstruct cmd header */ put_unaligned_le16(length, &dad->ic_buf[0]); put_unaligned_le16(elem_offset, &dad->ic_buf[7]); /* Do not print command header */ length -= 5; status = STATUS_SUCCESS; resume_scan: cyttsp5_resume_scan_cmd_(dev); release_exclusive: cmd->release_exclusive(dev); put_pm_runtime: pm_runtime_put(dev); if (status == STATUS_FAIL) length = 0; size = prepare_print_buffer(status, &dad->ic_buf[5], length, buf); mutex_unlock(&dad->sysfs_lock); return size; }
static ssize_t cyttsp5_calibrate_show(struct device *dev, struct cyttsp5_attribute *attr, char *buf) { struct cyttsp5_device_access_data *dad = cyttsp5_get_device_access_data(dev); int status = STATUS_FAIL; int length = 0; int size; int rc; mutex_lock(&dad->sysfs_lock); pm_runtime_get_sync(dev); rc = cmd->request_exclusive(dev, CY_REQUEST_EXCLUSIVE_TIMEOUT); if (rc < 0) { dev_err(dev, "%s: Error on request exclusive r=%d\n", __func__, rc); goto put_pm_runtime; } rc = cyttsp5_suspend_scan_cmd_(dev); if (rc < 0) { dev_err(dev, "%s: Error on suspend scan r=%d\n", __func__, rc); goto release_exclusive; } rc = _cyttsp5_calibrate_idacs_cmd(dev, dad->calibrate_sensing_mode, &dad->ic_buf[0]); if (rc < 0) { dev_err(dev, "%s: Error on calibrate idacs r=%d\n", __func__, rc); goto resume_scan; } length = 1; /* Check if baseline initialization is requested */ if (dad->calibrate_initialize_baselines) { /* Perform baseline initialization for all modes */ rc = _cyttsp5_initialize_baselines_cmd(dev, CY_IB_SM_MUTCAP | CY_IB_SM_SELFCAP | CY_IB_SM_BUTTON, &dad->ic_buf[length]); if (rc < 0) { dev_err(dev, "%s: Error on initialize baselines r=%d\n", __func__, rc); goto resume_scan; } length++; } status = STATUS_SUCCESS; resume_scan: cyttsp5_resume_scan_cmd_(dev); release_exclusive: cmd->release_exclusive(dev); put_pm_runtime: pm_runtime_put(dev); if (status == STATUS_FAIL) length = 0; size = prepare_print_buffer(status, dad->ic_buf, length, buf); mutex_unlock(&dad->sysfs_lock); return size; }
static ssize_t cyttsp5_opens_show(struct device *dev, struct cyttsp5_attribute *attr, char *buf) { struct cyttsp5_device_access_data *dad = cyttsp5_get_device_access_data(dev); int status = STATUS_FAIL; u8 cmd_status = 0; u8 summary_result = 0; u16 act_length = 0; int length = 0; int size; int rc; mutex_lock(&dad->sysfs_lock); pm_runtime_get_sync(dev); rc = cmd->request_exclusive(dev, CY_REQUEST_EXCLUSIVE_TIMEOUT); if (rc < 0) { dev_err(dev, "%s: Error on request exclusive r=%d\n", __func__, rc); goto put_pm_runtime; } rc = cyttsp5_suspend_scan_cmd_(dev); if (rc < 0) { dev_err(dev, "%s: Error on suspend scan r=%d\n", __func__, rc); goto release_exclusive; } rc = cyttsp5_run_selftest_cmd_(dev, CY_ST_ID_OPENS, 0, &cmd_status, &summary_result, NULL); if (rc < 0) { dev_err(dev, "%s: Error on run self test r=%d\n", __func__, rc); goto resume_scan; } /* Form response buffer */ dad->ic_buf[0] = cmd_status; dad->ic_buf[1] = summary_result; length = 2; /* Get data unless test result is success */ if (cmd_status == CY_CMD_STATUS_SUCCESS && summary_result == CY_ST_RESULT_PASS) goto status_success; /* Set length to PIP_CMD_MAX_LENGTH to read all */ rc = cyttsp5_get_selftest_result_cmd_(dev, 0, PIP_CMD_MAX_LENGTH, CY_ST_ID_OPENS, &cmd_status, &act_length, &dad->ic_buf[6]); if (rc < 0) { dev_err(dev, "%s: Error on get self test result r=%d\n", __func__, rc); goto resume_scan; } dad->ic_buf[2] = cmd_status; dad->ic_buf[3] = CY_ST_ID_OPENS; dad->ic_buf[4] = LOW_BYTE(act_length); dad->ic_buf[5] = HI_BYTE(act_length); length = 6 + act_length; status_success: status = STATUS_SUCCESS; resume_scan: cyttsp5_resume_scan_cmd_(dev); release_exclusive: cmd->release_exclusive(dev); put_pm_runtime: pm_runtime_put(dev); if (status == STATUS_FAIL) length = 0; size = prepare_print_buffer(status, dad->ic_buf, length, buf); mutex_unlock(&dad->sysfs_lock); return size; }
static ssize_t cyttsp5_get_idac_show(struct device *dev, struct cyttsp5_attribute *attr, char *buf) { struct cyttsp5_device_access_data *dad = cyttsp5_get_device_access_data(dev); int status = STATUS_FAIL; u8 cmd_status = 0; u8 data_format = 0; u16 act_length = 0; int length = 0; int size; int rc; mutex_lock(&dad->sysfs_lock); pm_runtime_get_sync(dev); rc = cmd->request_exclusive(dev, CY_REQUEST_EXCLUSIVE_TIMEOUT); if (rc < 0) { dev_err(dev, "%s: Error on request exclusive r=%d\n", __func__, rc); goto put_pm_runtime; } rc = cyttsp5_suspend_scan_cmd_(dev); if (rc < 0) { dev_err(dev, "%s: Error on suspend scan r=%d\n", __func__, rc); goto release_exclusive; } rc = cyttsp5_get_data_structure_cmd_(dev, 0, PIP_CMD_MAX_LENGTH, dad->get_idac_data_id, &cmd_status, &data_format, &act_length, &dad->ic_buf[5]); if (rc < 0) { dev_err(dev, "%s: Error on get data structure r=%d\n", __func__, rc); goto resume_scan; } dad->ic_buf[0] = cmd_status; dad->ic_buf[1] = dad->get_idac_data_id; dad->ic_buf[2] = LOW_BYTE(act_length); dad->ic_buf[3] = HI_BYTE(act_length); dad->ic_buf[4] = data_format; length = 5 + act_length; status = STATUS_SUCCESS; resume_scan: cyttsp5_resume_scan_cmd_(dev); release_exclusive: cmd->release_exclusive(dev); put_pm_runtime: pm_runtime_put(dev); if (status == STATUS_FAIL) length = 0; size = prepare_print_buffer(status, dad->ic_buf, length, buf); mutex_unlock(&dad->sysfs_lock); return size; }