diff --git a/pt/Makefile b/pt/Makefile index f495e2dbcd..da836e6f10 100644 --- a/pt/Makefile +++ b/pt/Makefile @@ -4,13 +4,11 @@ # # Each configuration option enables a list of files. - obj-$(CONFIG_TOUCHSCREEN_PARADE) += pt.o pt-y := pt_core.o pt_mt_common.o pt-$(CONFIG_TOUCHSCREEN_PARADE_MT_A) += pt_mta.o pt-$(CONFIG_TOUCHSCREEN_PARADE_MT_B) += pt_mtb.o pt-$(CONFIG_TOUCHSCREEN_PARADE_BUTTON) += pt_btn.o -pt-$(CONFIG_TOUCHSCREEN_PARADE_PEN) += pt_pen.o pt-$(CONFIG_TOUCHSCREEN_PARADE_PROXIMITY) += pt_proximity.o obj-$(CONFIG_TOUCHSCREEN_PARADE_DEVICETREE_SUPPORT) += pt_devtree.o ifdef CONFIG_TOUCHSCREEN_PARADE @@ -30,7 +28,6 @@ CFLAGS_pt_mta.o += -DDEBUG CFLAGS_pt_mtb.o += -DDEBUG CFLAGS_pt_mt_common.o += -DDEBUG CFLAGS_pt_btn.o += -DDEBUG -CFLAGS_pt_pen.o += -DDEBUG CFLAGS_pt_proximity.o += -DDEBUG CFLAGS_pt_device_access.o += -DDEBUG CFLAGS_pt_loader.o += -DDEBUG @@ -47,7 +44,6 @@ CFLAGS_pt_mta.o += -DVERBOSE_DEBUG CFLAGS_pt_mtb.o += -DVERBOSE_DEBUG CFLAGS_pt_mt_common.o += -DVERBOSE_DEBUG CFLAGS_pt_btn.o += -DVERBOSE_DEBUG -CFLAGS_pt_pen.o += -DVERBOSE_DEBUG CFLAGS_pt_proximity.o += -DVERBOSE_DEBUG CFLAGS_pt_device_access.o += -DVERBOSE_DEBUG CFLAGS_pt_loader.o += -DVERBOSE_DEBUG diff --git a/pt/pt_btn.c b/pt/pt_btn.c index 28d1df077c..17d2a93b13 100644 --- a/pt/pt_btn.c +++ b/pt/pt_btn.c @@ -1,4 +1,3 @@ -#ifndef TTDL_KERNEL_SUBMISSION /* * pt_btn.c * Parade TrueTouch(TM) Standard Product CapSense Reports Module. @@ -382,7 +381,7 @@ static int pt_setup_input_attention(struct device *dev) bd->si = _pt_request_sysinfo(dev); if (!bd->si) - return -1; + return -EPERM; rc = pt_setup_input_device(dev); @@ -521,4 +520,3 @@ int pt_btn_release(struct device *dev) return 0; } -#endif /*!TTDL_KERNEL_SUBMISSION */ diff --git a/pt/pt_core.c b/pt/pt_core.c index 0ecbe1b537..44a43453fb 100644 --- a/pt/pt_core.c +++ b/pt/pt_core.c @@ -27,17 +27,28 @@ * Contact Parade Technologies at www.paradetech.com */ -#include "pt_regs.h" -#include #include #include +#include +#include "pt_regs.h" -#ifdef PT_PTSBC_SUPPORT -#define PT_CORE_PROBE_STARTUP_DELAY_MS 500 -#endif /* PT_PTSBC_SUPPORT */ +#define PINCTRL_STATE_ACTIVE "pmx_ts_active" +#define PINCTRL_STATE_SUSPEND "pmx_ts_suspend" +#define PINCTRL_STATE_RELEASE "pmx_ts_release" + +#define FT_VTG_MIN_UV 2800000 +#define FT_VTG_MAX_UV 2800000 +#define FT_I2C_VTG_MIN_UV 1800000 +#define FT_I2C_VTG_MAX_UV 1800000 #define PT_CORE_STARTUP_RETRY_COUNT 3 +#define PT_STATUS_STR_LEN (50) + +#if defined(CONFIG_DRM) +static struct drm_panel *active_panel; +#endif + MODULE_FIRMWARE(PT_FW_FILE_NAME); static const char *pt_driver_core_name = PT_CORE_NAME; @@ -69,7 +80,6 @@ struct pt_hid_report { int header_size; int record_size; u32 usage_page; - int log_collection_num; }; struct atten_node { @@ -95,7 +105,6 @@ struct module_node { }; struct pt_hid_cmd { - __le16 descriptor; u8 opcode; u8 report_type; union { @@ -104,7 +113,6 @@ struct pt_hid_cmd { }; u8 has_data_register; size_t write_length; - size_t read_length; u8 *write_buf; u8 *read_buf; u8 wait_interrupt; @@ -155,7 +163,7 @@ void pt_pr_buf(struct device *dev, u8 debug_level, u8 *buf, { struct pt_core_data *cd = dev_get_drvdata(dev); int i; - int pr_buf_index = 0; + ssize_t pr_buf_index = 0; int max_size; /* only proceed if valid debug level and there is data to print */ @@ -166,12 +174,15 @@ void pt_pr_buf(struct device *dev, u8 debug_level, u8 *buf, return; /* - * With spaces each printed char takes 3 bytes, subtract - * the length of the data_name and length prefix and divide 3 + * With a space each printed char takes 3 bytes, subtract + * the length of the data_name prefix as well as 11 bytes + * for the " [0..xxx]: " printed before the data. */ + max_size = (PT_MAX_PR_BUF_SIZE - sizeof(data_name) - 11) / 3; + + /* Ensure pr_buf_index stays within the 1018 size */ pr_buf_index += scnprintf(pr_buf, PT_MAX_PR_BUF_SIZE, "%s [0..%d]: ", - data_name, buf_len); - max_size = (PT_MAX_PR_BUF_SIZE - pr_buf_index) / 3; + data_name); for (i = 0; i < buf_len && i < max_size; i++) pr_buf_index += scnprintf(pr_buf + pr_buf_index, PT_MAX_PR_BUF_SIZE, "%02X ", buf[i]); @@ -325,6 +336,7 @@ static int pt_add_parameter(struct pt_core_data *cd, /* Check if parameter already exists in the list */ spin_lock(&cd->spinlock); + list_for_each_entry(param, &cd->param_list, node) { if (param->id == param_id) { /* Update parameter */ @@ -357,7 +369,6 @@ exit_unlock: return 0; } -#ifndef TTDL_KERNEL_SUBMISSION #ifdef TTDL_DIAGNOSTICS /******************************************************************************* * FUNCTION: pt_erase_parameter_list @@ -415,7 +426,6 @@ static int pt_count_parameter_list(struct pt_core_data *cd) return entries; } #endif /* TTDL_DIAGNOSTICS */ -#endif /* !TTDL_KERNEL_SUBMISSION */ /******************************************************************************* * FUNCTION: request_exclusive @@ -523,7 +533,7 @@ int release_exclusive(struct pt_core_data *cd, void *ownptr) } /******************************************************************************* - * FUNCTION: pt_hid_create_cmd_and_send_ + * FUNCTION: pt_hid_exec_cmd_ * * SUMMARY: Send the HID command to the DUT * @@ -535,7 +545,7 @@ int release_exclusive(struct pt_core_data *cd, void *ownptr) * *cd - pointer to core data * *hid_cmd - pointer to the HID command to send ******************************************************************************/ -static int pt_hid_create_cmd_and_send_(struct pt_core_data *cd, +static int pt_hid_exec_cmd_(struct pt_core_data *cd, struct pt_hid_cmd *hid_cmd) { int rc = 0; @@ -543,27 +553,16 @@ static int pt_hid_create_cmd_and_send_(struct pt_core_data *cd, u16 cmd_length; u8 cmd_offset = 0; - if (hid_cmd->descriptor) { - cmd_length = 2; /* hid or report register */ - } else { - cmd_length = - 2 /* command register */ - + 2 /* command */ - + (hid_cmd->report_id >= 0XF ? 1 : 0) /* Report ID */ - + (hid_cmd->has_data_register ? 2 : 0) /* Data register */ - + hid_cmd->write_length; /* Data length */ - } + cmd_length = 2 /* command register */ + + 2 /* command */ + + (hid_cmd->report_id >= 0XF ? 1 : 0) /* Report ID */ + + (hid_cmd->has_data_register ? 2 : 0) /* Data register */ + + hid_cmd->write_length; /* Data length */ cmd = kzalloc(cmd_length, GFP_KERNEL); if (!cmd) return -ENOMEM; - /* hid & report descriptor doesn't require other field */ - if (hid_cmd->descriptor) { - memcpy(&cmd[cmd_offset], &hid_cmd->descriptor, cmd_length); - goto skip_other_field; - } - /* Set Command register */ memcpy(&cmd[cmd_offset], &cd->hid_desc.command_register, sizeof(cd->hid_desc.command_register)); @@ -604,14 +603,12 @@ static int pt_hid_create_cmd_and_send_(struct pt_core_data *cd, ">>> %s: Write Buffer Size[%d] Cmd[0x%02X]\n", __func__, cmd_length, hid_cmd->report_id); -skip_other_field: pt_pr_buf(cd->dev, DL_DEBUG, cmd, cmd_length, ">>> CMD"); - - rc = pt_adap_write_read_specific(cd, cmd_length, cmd, hid_cmd->read_buf, - hid_cmd->read_length); + rc = pt_adap_write_read_specific(cd, cmd_length, cmd, + hid_cmd->read_buf); if (rc) pt_debug(cd->dev, DL_ERROR, - "%s: Fail pt_adap_transfer\n", __func__); + "%s: Fail pt_adap_transfer\n", __func__); kfree(cmd); return rc; @@ -685,13 +682,22 @@ static int pt_hid_exec_cmd_and_wait_(struct pt_core_data *cd, else cmd_state = &cd->hid_cmd_state; - mutex_lock(&cd->system_lock); - *cmd_state = 1; - mutex_unlock(&cd->system_lock); + if (hid_cmd->wait_interrupt) { + mutex_lock(&cd->system_lock); + *cmd_state = 1; + mutex_unlock(&cd->system_lock); + } - rc = pt_hid_create_cmd_and_send_(cd, hid_cmd); - if (rc) - goto error; + rc = pt_hid_exec_cmd_(cd, hid_cmd); + if (rc) { + if (hid_cmd->wait_interrupt) + goto error; + + goto exit; + } + + if (!hid_cmd->wait_interrupt) + goto exit; if (hid_cmd->timeout_ms) timeout_ms = hid_cmd->timeout_ms; @@ -723,60 +729,6 @@ exit: return rc; } -/******************************************************************************* - * FUNCTION: pt_hid_exec_cmd_no_wait_ - * - * SUMMARY: The function works to send HID command and can read response - * directly instead of waiting it to be received in interrupt function. It - * assgins the read buffer to receive response in following condition: - * 1) descriptor is assigned to get hid descriptor or report descripter - * 2) output register is assigned for vendor-defined commands (TBD) - * - * NOTE: If no read buffer is assigned, it only perform send action. - * - * RETURN: - * 0 = success - * !0 = failure - * - * PARAMETERS: - * *cd - pointer to core data - * *hid_cmd - pointer to the HID command to send - ******************************************************************************/ -static int pt_hid_exec_cmd_no_wait_(struct pt_core_data *cd, - struct pt_hid_cmd *hid_cmd) -{ - int rc = 0; - - if (hid_cmd->descriptor) - hid_cmd->read_buf = cd->response_buf; - - rc = pt_hid_create_cmd_and_send_(cd, hid_cmd); - return rc; -} - -/******************************************************************************* - * FUNCTION: pt_hid_send_command - * - * SUMMARY: Wrapper function to call pt_hid_exec_cmd_no_wait_() for HID protocol - * and pt_hid_exec_cmd_and_wait_() for PIP protocol. - * - * RETURN: - * 0 = success - * !0 = failure - * - * PARAMETERS: - * *cd - pointer to core data - * *hid_cmd - pointer to the HID command to send - ******************************************************************************/ -static int pt_hid_send_command(struct pt_core_data *cd, - struct pt_hid_cmd *hid_cmd) -{ - if (cd->dut_status.protocol_mode == PT_PROTOCOL_MODE_HID) - return pt_hid_exec_cmd_no_wait_(cd, hid_cmd); - else - return pt_hid_exec_cmd_and_wait_(cd, hid_cmd); -} - /******************************************************************************* * FUNCTION: pt_hid_cmd_reset_ * @@ -793,11 +745,12 @@ static int pt_hid_cmd_reset_(struct pt_core_data *cd) { struct pt_hid_cmd hid_cmd = { .opcode = HID_CMD_RESET, + .wait_interrupt = 1, .reset_cmd = 1, .timeout_ms = PT_HID_CMD_DEFAULT_TIMEOUT, }; - return pt_hid_send_command(cd, &hid_cmd); + return pt_hid_exec_cmd_and_wait_(cd, &hid_cmd); } /******************************************************************************* @@ -854,13 +807,14 @@ static int pt_hid_cmd_set_power_(struct pt_core_data *cd, int rc = 0; struct pt_hid_cmd hid_cmd = { .opcode = HID_CMD_SET_POWER, + .wait_interrupt = 1, .timeout_ms = PT_HID_CMD_DEFAULT_TIMEOUT, }; hid_cmd.power_state = power_state; /* The chip won't give response if goes to Deep Standby */ if (power_state == HID_POWER_STANDBY) { - rc = pt_hid_exec_cmd_no_wait_(cd, &hid_cmd); + rc = pt_hid_exec_cmd_(cd, &hid_cmd); if (rc) pt_debug(cd->dev, DL_ERROR, "%s: Failed to set power to state:%d\n", @@ -871,7 +825,7 @@ static int pt_hid_cmd_set_power_(struct pt_core_data *cd, } cd->fw_sys_mode_in_standby_state = false; - rc = pt_hid_send_command(cd, &hid_cmd); + rc = pt_hid_exec_cmd_and_wait_(cd, &hid_cmd); if (rc) { pt_debug(cd->dev, DL_ERROR, "%s: Failed to set power to state:%d\n", @@ -879,10 +833,6 @@ static int pt_hid_cmd_set_power_(struct pt_core_data *cd, return rc; } - /* HID COMMAND doesn't have a response */ - if (cd->dut_status.protocol_mode == PT_PROTOCOL_MODE_HID) - return rc; - /* validate */ if ((cd->response_buf[2] != HID_RESPONSE_REPORT_ID) || ((cd->response_buf[3] & 0x3) != power_state) @@ -892,7 +842,6 @@ static int pt_hid_cmd_set_power_(struct pt_core_data *cd, return rc; } -#ifndef TTDL_KERNEL_SUBMISSION /******************************************************************************* * FUNCTION: pt_hid_cmd_set_power * @@ -928,7 +877,6 @@ static int pt_hid_cmd_set_power(struct pt_core_data *cd, return rc; } -#endif /* !TTDL_KERNEL_SUBMISSION */ static const u16 crc_table[16] = { 0x0000, 0x1021, 0x2042, 0x3063, @@ -1229,7 +1177,7 @@ static int pt_pip2_get_cmd_response_len(u8 id) if (p->id != PIP2_CMD_ID_END) return p->response_len; else - return -1; + return -EPERM; } /******************************************************************************* @@ -1627,11 +1575,12 @@ static int pt_hid_send_output_user_(struct pt_core_data *cd, pt_debug(cd->dev, DL_INFO, ">>> %s: Write Buffer Size[%d] Cmd[0x%02X]\n", __func__, hid_output->length, cmd); + pt_pr_buf(cd->dev, DL_DEBUG, hid_output->write_buf, hid_output->length, ">>> User CMD"); rc = pt_adap_write_read_specific(cd, hid_output->length, - hid_output->write_buf, NULL, 0); + hid_output->write_buf, NULL); if (rc) pt_debug(cd->dev, DL_ERROR, "%s: Fail pt_adap_transfer\n", __func__); @@ -1679,9 +1628,7 @@ static int pt_hid_send_output_user_and_wait_(struct pt_core_data *cd, rc = -ETIME; goto error; } - pt_check_command(cd, hid_output, true); - goto exit; error: @@ -1764,15 +1711,7 @@ static ssize_t pt_flush_bus(struct pt_core_data *cd, int rc = 0; if (flush_type == PT_FLUSH_BUS_BASED_ON_LEN) { -#ifdef TTDL_PTVIRTDUT_SUPPORT - if (cd->route_bus_virt_dut) - rc = pt_adap_read_default(cd, buf, - PT_MAX_PIP2_MSG_SIZE); - else - rc = pt_adap_read_default(cd, buf, 2); -#else rc = pt_adap_read_default(cd, buf, 2); -#endif /* TTDL_PTVIRTDUT_SUPPORT */ if (rc) { bytes_read = 0; goto exit; @@ -1807,15 +1746,7 @@ static ssize_t pt_flush_bus(struct pt_core_data *cd, "%s: Flush read of %d bytes...\n", __func__, pip_len); -#ifdef TTDL_PTVIRTDUT_SUPPORT - rc = 0; - if (cd->route_bus_virt_dut) - bytes_read = pip_len; - else - rc = pt_adap_read_default(cd, buf, pip_len); -#else rc = pt_adap_read_default(cd, buf, pip_len); -#endif /* TTDL_PTVIRTDUT_SUPPORT */ if (!rc) bytes_read = pip_len; else @@ -1903,15 +1834,6 @@ static int pt_hid_send_output_(struct pt_core_data *cd, u8 cmd_offset = 0; u8 cmd_allocated = 0; -#ifdef FUTURE - /* - * *** TODO - Determine side effects of adding this safety net *** - * If IRQ is already asserted due to a pending report, it must be - * cleared before sending command. - */ - pt_flush_bus_if_irq_asserted(cd, PT_FLUSH_BUS_BASED_ON_LEN); -#endif - switch (hid_output->cmd_type) { case PIP1_CMD_TYPE_FW: report_id = PT_PIP_NON_HID_COMMAND_ID; @@ -1971,8 +1893,9 @@ static int pt_hid_send_output_(struct pt_core_data *cd, pt_debug(cd->dev, DL_INFO, ">>> %s: Write Buffer Size[%d] Cmd[0x%02X]\n", __func__, length + 2, hid_output->command_code); + pt_pr_buf(cd->dev, DL_DEBUG, cmd, length + 2, ">>> CMD"); - rc = pt_adap_write_read_specific(cd, length + 2, cmd, NULL, 0); + rc = pt_adap_write_read_specific(cd, length + 2, cmd, NULL); if (rc) pt_debug(cd->dev, DL_ERROR, @@ -2072,7 +1995,6 @@ static int pt_hid_output_user_cmd_(struct pt_core_data *cd, .length = write_len, .write_buf = write_buf, }; - #ifdef TTHE_TUNER_SUPPORT if (!cd->pip2_send_user_cmd) { int command_code = 0; @@ -2092,7 +2014,6 @@ static int pt_hid_output_user_cmd_(struct pt_core_data *cd, tthe_print(cd, write_buf, len, "CMD="); } #endif - rc = pt_hid_send_output_user_and_wait_(cd, &hid_output); if (rc) return rc; @@ -2198,7 +2119,6 @@ static int _pt_request_pip2_send_cmd(struct device *dev, u8 extra_bytes; memset(&pip2_cmd, 0, sizeof(pip2_cmd)); - /* Hard coded register for PIP2.x */ pip2_cmd.reg[0] = 0x01; pip2_cmd.reg[1] = 0x01; @@ -2225,6 +2145,7 @@ static int _pt_request_pip2_send_cmd(struct device *dev, pip2_cmd.id = id & PIP2_CMD_COMMAND_ID_MASK; pip2_cmd.seq = pt_pip2_get_next_cmd_seq(cd); pip2_cmd.data = data; + pt_pip2_cmd_calculate_crc(&pip2_cmd, extra_bytes); /* Add the command length to the extra bytes based on PIP version */ @@ -2234,6 +2155,7 @@ static int _pt_request_pip2_send_cmd(struct device *dev, __func__, pip2_cmd.len, write_len); write_buf = kzalloc(write_len, GFP_KERNEL); + if (write_buf == NULL) { rc = -ENOMEM; goto exit; @@ -2254,6 +2176,7 @@ static int _pt_request_pip2_send_cmd(struct device *dev, read_len = pt_pip2_get_cmd_response_len(pip2_cmd.id); if (read_len < 0) read_len = 255; + pt_debug(dev, DL_INFO, "%s cmd_id[0x%02X] expected response length:%d ", __func__, pip2_cmd.id, read_len); @@ -2271,19 +2194,18 @@ static int _pt_request_pip2_send_cmd(struct device *dev, if (protect == PT_CORE_CMD_PROTECTED) rc = pt_hid_output_user_cmd(cd, read_len, read_buf, write_len, write_buf, actual_read_len); - else + else { rc = pt_hid_output_user_cmd_(cd, read_len, read_buf, write_len, write_buf, actual_read_len); + } if (rc) { pt_debug(dev, DL_ERROR, "%s: nonhid_cmd->user_cmd() Error = %d\n", __func__, rc); goto exit; } - rc = pt_pip2_validate_response(cd, &pip2_cmd, read_buf, *actual_read_len); - exit: mutex_lock(&cd->system_lock); cd->pip2_prot_active = false; @@ -2400,7 +2322,7 @@ static int _pt_pip2_send_cmd_no_int(struct device *dev, pt_pr_buf(cd->dev, DL_DEBUG, write_buf, write_len, ">>> NO_INT CMD"); - rc = pt_adap_write_read_specific(cd, write_len, write_buf, NULL, 0); + rc = pt_adap_write_read_specific(cd, write_len, write_buf, NULL); if (rc) { pt_debug(dev, DL_ERROR, "%s: SPI write Error = %d\n", @@ -2533,11 +2455,9 @@ static int pt_pip_null_(struct pt_core_data *cd) struct pt_hid_output hid_output = { CREATE_PIP1_FW_CMD(PIP1_CMD_ID_NULL), }; - return pt_pip1_send_output_and_wait_(cd, &hid_output); } -#ifndef TTDL_KERNEL_SUBMISSION /******************************************************************************* * FUNCTION: pt_pip_null * @@ -2570,13 +2490,12 @@ static int pt_pip_null(struct pt_core_data *cd) return rc; } -#endif /*!TTDL_KERNEL_SUBMISSION */ static void pt_stop_wd_timer(struct pt_core_data *cd); /******************************************************************************* * FUNCTION: pt_pip_start_bootloader_ * - * SUMMARY: Sends the PIP command start_bootloader [PIP cmd 0x01] to the DUT + * SUMMARY: Sends the HID command start_bootloader [PIP cmd 0x01] to the DUT * * NOTE: The WD MUST be stopped/restarted by the calling Function. Having * the WD active could cause this function to fail! @@ -2597,7 +2516,6 @@ static int pt_pip_start_bootloader_(struct pt_core_data *cd) .timeout_ms = PT_PIP1_START_BOOTLOADER_TIMEOUT, .reset_expected = 1, }; - if (cd->watchdog_enabled) { pt_debug(cd->dev, DL_WARN, "%s: watchdog isn't stopped before enter bl\n", @@ -2820,7 +2738,6 @@ static void pt_si_get_sensing_conf_data(struct pt_core_data *cd) scd->tx_num = scd->electrodes_y; scd->rx_num = scd->electrodes_x; } - /* * When the Panel ID is coming from an XY pin and not a dedicated * GPIO, store the PID in pid_for_loader. This cannot be done for all @@ -3120,7 +3037,6 @@ static int pt_hid_output_get_sysinfo_(struct pt_core_data *cd) return rc; } -#ifndef TTDL_KERNEL_SUBMISSION /******************************************************************************* * FUNCTION: pt_hid_output_get_sysinfo * @@ -3153,7 +3069,6 @@ static int pt_hid_output_get_sysinfo(struct pt_core_data *cd) return rc; } -#endif /*!TTDL_KERNEL_SUBMISSION */ /******************************************************************************* * FUNCTION: pt_pip_suspend_scanning_ @@ -3466,7 +3381,6 @@ static int pt_pip_set_param_(struct pt_core_data *cd, CREATE_PIP1_FW_CMD(PIP1_CMD_ID_SET_PARAM), .write_buf = write_buf, }; - write_buf[0] = param_id; write_buf[1] = size; for (i = 0; i < size; i++) { @@ -3576,7 +3490,6 @@ static int pt_hid_output_enter_easywake_state_( .write_length = write_length, .write_buf = param, }; - rc = pt_pip1_send_output_and_wait_(cd, &hid_output); if (rc) return rc; @@ -3614,7 +3527,6 @@ static int pt_pip_verify_config_block_crc_( .write_length = write_length, .write_buf = param, }; - rc = pt_pip1_send_output_and_wait_(cd, &hid_output); if (rc) return rc; @@ -4978,7 +4890,6 @@ static int pt_pip_calibrate_idacs_(struct pt_core_data *cd, .write_buf = write_buf, .timeout_ms = PT_PIP1_CMD_CALIBRATE_IDAC_TIMEOUT, }; - write_buf[cmd_offset++] = mode; rc = pt_pip1_send_output_and_wait_(cd, &hid_output); if (rc) @@ -5083,7 +4994,6 @@ static int pt_hid_output_initialize_baselines_( .write_length = write_length, .write_buf = write_buf, }; - write_buf[cmd_offset++] = test_id; rc = pt_pip1_send_output_and_wait_(cd, &hid_output); @@ -5619,7 +5529,7 @@ static int _pt_request_pip_bl_get_information(struct device *dev, /******************************************************************************* * FUNCTION: pt_hid_output_bl_initiate_bl_ * - * SUMMARY: Sends the PIP "Initiate Bootload" (0x48) command to the + * SUMMARY: Sends the PIP "Get Bootloader Information" (0x48) command to the * DUT to erases the entire TrueTouch application, Configuration Data block, * and Design Data block in flash and enables the host to execute the Program * and Verify Row command to bootload the application image and data. @@ -5742,7 +5652,7 @@ static int _pt_request_pip_bl_initiate_bl(struct device *dev, /******************************************************************************* * FUNCTION: pt_hid_output_bl_program_and_verify_ * - * SUMMARY: Sends the PIP "Program and Verify" (0x39) command to upload + * SUMMARY: Sends the PIP "Get Bootloader Information" (0x39) command to upload * and program a 128-byte row into the flash, and then verifies written data. * * RETURN: @@ -5836,7 +5746,7 @@ static int _pt_request_pip_bl_program_and_verify( /******************************************************************************* * FUNCTION: pt_hid_output_bl_verify_app_integrity_ * - * SUMMARY: Sends the PIP "Verify Application Integrity" (0x31) command to + * SUMMARY: Sends the PIP "Get Bootloader Information" (0x31) command to * perform a full verification of the application integrity by calculating the * CRC of the image in flash and compare it to the expected CRC stored in the * Metadata row. @@ -6112,55 +6022,6 @@ static int _pt_request_pip_bl_get_panel_id( return pt_hid_output_bl_get_panel_id_(cd, panel_id); } -/******************************************************************************* - * FUNCTION: pt_pip2_get_status_ - * - * SUMMARY: Sends a PIP2 STATUS command to the DUT and stores the data in - * cd status_data. - * - * RETURN: - * 0 = success - * !0 = failure - * - * PARAMETERS: - * *cd - pointer to core data structure - ******************************************************************************/ -static int pt_pip2_get_status_(struct pt_core_data *cd) -{ - u16 actual_read_len; - u8 read_buf[12]; - u8 status, boot; - int rc = 0; - - rc = _pt_request_pip2_send_cmd(cd->dev, PT_CORE_CMD_UNPROTECTED, - PIP2_CMD_ID_STATUS, NULL, 0, read_buf, &actual_read_len); - if (rc) { - pt_debug(cd->dev, DL_ERROR, "%s: PIP2 STATUS command rc = %d\n", - __func__, rc); - return rc; - } - - pt_pr_buf(cd->dev, DL_DEBUG, read_buf, actual_read_len, - "PIP2 STATUS"); - - status = read_buf[PIP2_RESP_STATUS_OFFSET]; - boot = read_buf[PIP2_RESP_BODY_OFFSET] & 0x01; - - cd->dut_status.fw_system_mode = - read_buf[PIP2_RESP_BODY_OFFSET + 1]; - - if (status == PIP2_RSP_ERR_NONE && boot == 0x00) - cd->dut_status.mode = PT_MODE_BOOTLOADER; - else if (status == PIP2_RSP_ERR_NONE && boot == 0x01) { - cd->dut_status.mode = PT_MODE_OPERATIONAL; - cd->dut_status.protocol_mode = - read_buf[PIP2_RESP_BODY_OFFSET + 2]; - } else - cd->dut_status.mode = PT_MODE_UNKNOWN; - - return rc; -} - /******************************************************************************* * FUNCTION: pt_pip2_get_mode_sysmode_ * @@ -6179,14 +6040,39 @@ static int pt_pip2_get_status_(struct pt_core_data *cd) static int pt_pip2_get_mode_sysmode_(struct pt_core_data *cd, u8 *mode, u8 *sys_mode) { + u16 actual_read_len; + u8 read_buf[12]; + u8 status, boot; int rc = 0; - rc = pt_pip2_get_status_(cd); + rc = _pt_request_pip2_send_cmd(cd->dev, PT_CORE_CMD_UNPROTECTED, + PIP2_CMD_ID_STATUS, NULL, 0, read_buf, &actual_read_len); + + pt_debug(cd->dev, DL_INFO, "%s: PIP2 STATUS command rc = %d\n", + __func__, rc); + if (!rc) { - if (sys_mode) - *sys_mode = cd->dut_status.fw_system_mode; - if (mode) - *mode = cd->dut_status.mode; + pt_pr_buf(cd->dev, DL_DEBUG, read_buf, actual_read_len, + "PIP2 STATUS"); + status = read_buf[PIP2_RESP_STATUS_OFFSET]; + boot = read_buf[PIP2_RESP_BODY_OFFSET] & 0x01; + if (sys_mode) { + if (status == PIP2_RSP_ERR_NONE && + boot == PIP2_STATUS_APP_EXEC) + *sys_mode = read_buf[PIP2_RESP_BODY_OFFSET + 1]; + else + *sys_mode = FW_SYS_MODE_UNDEFINED; + } + if (mode) { + if (status == PIP2_RSP_ERR_NONE && + boot == PIP2_STATUS_BOOT_EXEC) + *mode = PT_MODE_BOOTLOADER; + else if (status == PIP2_RSP_ERR_NONE && + boot == PIP2_STATUS_APP_EXEC) + *mode = PT_MODE_OPERATIONAL; + else + *mode = PT_MODE_UNKNOWN; + } } else { if (mode) *mode = PT_MODE_UNKNOWN; @@ -6581,12 +6467,9 @@ static int pt_get_hid_descriptor_(struct pt_core_data *cd, struct pt_hid_desc *desc) { struct device *dev = cd->dev; - struct pt_hid_cmd hid_cmd = { - .descriptor = cd->hid_core.hid_desc_register, - .read_length = 0, - }; int rc = 0; - u16 hid_len; + int t; + u8 cmd[2]; /* * During startup the HID descriptor is required for all future @@ -6595,68 +6478,63 @@ static int pt_get_hid_descriptor_(struct pt_core_data *cd, */ pt_flush_bus_if_irq_asserted(cd, PT_FLUSH_BUS_BASED_ON_LEN); - rc = pt_hid_send_command(cd, &hid_cmd); + /* Read HID descriptor length and version */ + mutex_lock(&cd->system_lock); + cd->hid_cmd_state = 1; + mutex_unlock(&cd->system_lock); + + /* Set HID descriptor register */ + memcpy(cmd, &cd->hid_core.hid_desc_register, + sizeof(cd->hid_core.hid_desc_register)); + + pt_debug(cd->dev, DL_INFO, ">>> %s: Write Buffer [%zu]", + __func__, sizeof(cmd)); + pt_pr_buf(cd->dev, DL_DEBUG, cmd, sizeof(cmd), ">>> Get HID Desc"); + rc = pt_adap_write_read_specific(cd, 2, cmd, NULL); if (rc) { pt_debug(dev, DL_ERROR, "%s: failed to get HID descriptor, rc=%d\n", __func__, rc); - goto exit; + goto error; } - hid_len = get_unaligned_le16(&cd->response_buf[0]); - pt_pr_buf(cd->dev, DL_DEBUG, cd->response_buf, hid_len, "<<< HIDDesc"); + t = wait_event_timeout(cd->wait_q, (cd->hid_cmd_state == 0), + msecs_to_jiffies(PT_GET_HID_DESCRIPTOR_TIMEOUT)); - /* - * HID doesn't have packet_id and reserve_byte in struct struct - * pt_hid_desc and assign fixed value to packet_id. - */ - if (cd->dut_status.protocol_mode == PT_PROTOCOL_MODE_HID) { - if ((hid_len + 2) != sizeof(*desc)) { - pt_debug(dev, DL_ERROR, "%s: Unsupported HID length: %X\n", - __func__, hid_len); - rc = -ENODEV; - goto exit; - } - /* Copy length filed */ - memcpy((u8 *)desc, &cd->response_buf[0], 2); - /* Assign fixed value to packet_id */ - desc->packet_id = HID_APP_REPORT_ID; - /* Skip 2 bytes in desc and Copy to left fields */ - memcpy((u8 *)desc + 4, &cd->response_buf[2], hid_len - 2); + if (IS_TMO(t)) { +#ifdef TTDL_DIAGNOSTICS + cd->bus_transmit_error_count++; + pt_toggle_err_gpio(cd, PT_ERR_GPIO_I2C_TRANS); +#endif /* TTDL_DIAGNOSTICS */ + pt_debug(cd->dev, DL_ERROR, + "%s: HID get descriptor timed out\n", __func__); + rc = -ETIME; + goto error; } else { - if (hid_len != sizeof(*desc)) { - pt_debug(dev, DL_ERROR, "%s: Unsupported HID length: %X\n", - __func__, hid_len); - rc = -ENODEV; - goto exit; - } - - /* Load the HID descriptor including all registers */ - memcpy((u8 *)desc, cd->response_buf, hid_len); + cd->hw_detected = true; } + /* Load the HID descriptor including all registers */ + memcpy((u8 *)desc, cd->response_buf, sizeof(struct pt_hid_desc)); + /* Check HID descriptor length and version */ pt_debug(dev, DL_INFO, "%s: HID len:%X HID ver:%X\n", __func__, le16_to_cpu(desc->hid_desc_len), le16_to_cpu(desc->bcd_version)); - cd->hid_core.hid_report_desc_len = - le16_to_cpu(desc->report_desc_len); - - pt_debug(dev, DL_INFO, "%s: report descriptor len:%d\n", __func__, - cd->hid_core.hid_report_desc_len); - - if (le16_to_cpu(desc->bcd_version) != HID_VERSION) { + if (le16_to_cpu(desc->hid_desc_len) != sizeof(*desc) || + le16_to_cpu(desc->bcd_version) != HID_VERSION) { pt_debug(dev, DL_ERROR, "%s: Unsupported HID version\n", __func__); - rc = -ENODEV; - goto exit; + return -ENODEV; } -#ifdef TTHE_TUNER_SUPPORT - tthe_print(cd, cd->response_buf, hid_len, "HIDDesc="); -#endif + goto exit; +error: + mutex_lock(&cd->system_lock); + cd->hid_cmd_state = 0; + mutex_unlock(&cd->system_lock); exit: return rc; } @@ -6888,15 +6766,9 @@ static int _pt_detect_dut_generation(struct device *dev, struct pt_core_data *cd = dev_get_drvdata(dev); struct pt_hid_desc hid_desc; - /* protocol_mode must be known before dut gen */ - rc = pt_pip2_get_status_(cd); - if (rc) { - /* PIP prot assumed if error */ - cd->dut_status.protocol_mode = PT_PROTOCOL_MODE_PIP; - } - memset(&hid_desc, 0, sizeof(hid_desc)); rc = pt_get_hid_descriptor_(cd, &hid_desc); + while (rc && attempt < 3) { attempt++; usleep_range(2000, 5000); @@ -7460,8 +7332,6 @@ static void pt_init_pip_report_fields(struct pt_core_data *cd) si->desc.tch_record_size = TOUCH_REPORT_SIZE; si->desc.tch_header_size = TOUCH_INPUT_HEADER_SIZE; si->desc.btn_report_id = PT_PIP_CAPSENSE_BTN_REPORT_ID; - si->desc.pen_report_id = PT_HID_PEN_REPORT_ID; - si->desc.max_touch_num = MAX_TOUCH_NUM; cd->features.easywake = 1; cd->features.noise_metric = 1; @@ -7469,989 +7339,6 @@ static void pt_init_pip_report_fields(struct pt_core_data *cd) cd->features.sensor_data = 1; } -/******************************************************************************* - * FUNCTION: pt_get_hid_report_ - * - * SUMMARY: Get or create report. Must be called with cd->hid_report_lock - * acquired. - * - * RETURN: - * 0 = success - * !0 = failure - * - * PARAMETERS: - * *cd - pointer to core data structure - * *index - pointer to report index - * report_type - type of hid report - * report_id - id of hid report - * create - true: will create a new report - * false: will not create a new report - ******************************************************************************/ -static int pt_get_hid_report_(struct pt_core_data *cd, u8 *index, - u8 report_type, u8 report_id, bool create) -{ - struct pt_hid_report *report = NULL; - int i; - int rc = 0; - - /* Look for created reports */ - for (i = 0; i < cd->num_hid_reports; i++) { - if (cd->hid_reports[i]->type == report_type && - cd->hid_reports[i]->id == report_id) { - *index = i; - goto exit; - } - } - - if (create && cd->num_hid_reports >= PT_HID_MAX_REPORTS) { - pt_debug(cd->dev, DL_WARN, - "%s: num_hid_reports=%d max=%d\n", __func__, - cd->num_hid_reports, PT_HID_MAX_REPORTS); - rc = -EINVAL; - } else if (create && cd->num_hid_reports < PT_HID_MAX_REPORTS) { - /* Create a new report */ - report = kzalloc(sizeof(struct pt_hid_report), - GFP_KERNEL); - if (!report) - rc = -ENOMEM; - else { - report->type = report_type; - report->id = report_id; - *index = cd->num_hid_reports; - cd->hid_reports[cd->num_hid_reports++] = report; - } - } - -exit: - return rc; -} - -/******************************************************************************* - * FUNCTION: pt_free_hid_reports_ - * - * SUMMARY: Free HID report. Must be called with cd->hid_report_lock acquired. - * - * PARAMETERS: - * *cd - pointer to core data structure - ******************************************************************************/ -static void pt_free_hid_reports_(struct pt_core_data *cd) -{ - struct pt_hid_report *report; - int i, j; - - for (i = 0; i < cd->num_hid_reports; i++) { - report = cd->hid_reports[i]; - for (j = 0; j < report->num_fields; j++) - kfree(report->fields[j]); - kfree(report); - cd->hid_reports[i] = NULL; - } - - cd->num_hid_reports = 0; -} - -/******************************************************************************* - * FUNCTION: pt_free_hid_reports - * - * SUMMARY: Protected call to pt_free_hid_reports_() by a mutex lock. - * - * PARAMETERS: - * *cd - pointer to core data structure - ******************************************************************************/ -static void pt_free_hid_reports(struct pt_core_data *cd) -{ - mutex_lock(&cd->hid_report_lock); - pt_free_hid_reports_(cd); - mutex_unlock(&cd->hid_report_lock); -} - -/******************************************************************************* - * FUNCTION: pt_create_hid_field_ - * - * SUMMARY: Create field for HID report.Must be called with cd->hid_report_lock - * acquired. - * - * RETURN: - * pointer to hid field structure - * - * PARAMETERS: - * *report - pointer to hid report structure - ******************************************************************************/ -static struct pt_hid_field *pt_create_hid_field_( - struct pt_hid_report *report) -{ - struct pt_hid_field *field; - - if (!report) - return NULL; - - if (report->num_fields == PT_HID_MAX_FIELDS) - return NULL; - - field = kzalloc(sizeof(struct pt_hid_field), GFP_KERNEL); - if (!field) - return NULL; - - field->report = report; - - report->fields[report->num_fields++] = field; - - return field; -} - -/******************************************************************************* - * FUNCTION: get_hid_item_data - * - * SUMMARY: Get hid item data according to the item size. - * - * RETURN: - * 0 = no data - * !0 = data - * - * PARAMETERS: - * *data - pointer to item data - * item_size - the size of the item - ******************************************************************************/ -static inline int get_hid_item_data(u8 *data, int item_size) -{ - if (item_size == 1) - return (int)*data; - else if (item_size == 2) - return (int)get_unaligned_le16(data); - else if (item_size == 4) - return (int)get_unaligned_le32(data); - return 0; -} - -/******************************************************************************* - * FUNCTION: parse_report_descriptor - * - * SUMMARY: Parse report descriptor. - * - * RETURN: - * 0 = success - * !0 = failure - * - * PARAMETERS: - * *cd - pointer to core data structure - * *report_desc - pointer to report descriptor structure - * len - length of the data buffer to be parsed - ******************************************************************************/ -static int parse_report_descriptor(struct pt_core_data *cd, - u8 *report_desc, size_t len) -{ - struct pt_hid_report *report; - struct pt_hid_field *field; - u8 *buf = report_desc; - u8 *end = buf + len; - int rc = 0; - int offset = 0; - int i, j; - u8 report_type; - u32 up_usage; - /* Global items */ - u8 report_id = 0; - u16 usage_page = 0; - int report_count = 0; - int report_size = 0; - int logical_min = 0; - int logical_max = 0; - /* Local items */ - u16 usage = 0; - /* Main items - Collection stack */ - u32 collection_usages[PT_HID_MAX_NESTED_COLLECTIONS] = {0}; - u8 collection_types[PT_HID_MAX_NESTED_COLLECTIONS] = {0}; - u32 usages_pen[PT_HID_MAX_CONTINUOUS_USAGES] = {0}; - /* First collection for header, second for report */ - int logical_collection_count = 0; - int app_collection_count = 0; - int collection_nest = 0; - int usage_cnt = 0; - u8 report_index = 0; - - pt_debug(cd->dev, DL_DEBUG, "%s: Report descriptor length: %u\n", - __func__, (u32)len); - - mutex_lock(&cd->hid_report_lock); - pt_free_hid_reports_(cd); - - while (buf < end) { - int item_type; - int item_size; - int item_tag; - u8 *data; - - /* Get Item */ - item_size = HID_GET_ITEM_SIZE(buf[0]); - if (item_size == 3) - item_size = 4; - item_type = HID_GET_ITEM_TYPE(buf[0]); - item_tag = HID_GET_ITEM_TAG(buf[0]); - - data = ++buf; - buf += item_size; - - /* Process current item */ - switch (item_type) { - case HID_ITEM_TYPE_GLOBAL: /* 1 */ - switch (item_tag) { - case HID_GLOBAL_ITEM_TAG_USAGE_PAGE: /* 0 */ - if (item_size == 0 || item_size == 4) { - rc = -EINVAL; - goto exit; - } - usage_page = (u16)get_hid_item_data(data, - item_size); - break; - case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM: /* 1 */ - if (item_size == 0) { - rc = -EINVAL; - goto exit; - } - logical_min = get_hid_item_data(data, - item_size); - break; - case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM: /* 2 */ - if (item_size == 0) { - rc = -EINVAL; - goto exit; - } - logical_max = get_hid_item_data(data, - item_size); - break; - case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM: /* 3 */ - pt_debug(cd->dev, DL_INFO, - "%s: TAG Ignored - Physical Min\n", - __func__); - break; - case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM: /* 4 */ - pt_debug(cd->dev, DL_INFO, - "%s: TAG Ignored - Physical Max\n", - __func__); - break; - case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT: /* 5 */ - pt_debug(cd->dev, DL_INFO, - "%s: TAG Ignored - Unit Exponent\n", - __func__); - break; - case HID_GLOBAL_ITEM_TAG_UNIT: /* 6 */ - pt_debug(cd->dev, DL_INFO, - "%s: TAG Ignored - Unit\n", - __func__); - break; - case HID_GLOBAL_ITEM_TAG_REPORT_SIZE: /* 7 */ - if (item_size == 0) { - rc = -EINVAL; - goto exit; - } - report_size = get_hid_item_data(data, - item_size); - break; - case HID_GLOBAL_ITEM_TAG_REPORT_ID: /* 8 */ - if (item_size != 1) { - rc = -EINVAL; - goto exit; - } - report_id = get_hid_item_data(data, item_size); - offset = 0; - logical_collection_count = 0; - break; - case HID_GLOBAL_ITEM_TAG_REPORT_COUNT: /* 9 */ - if (item_size == 0) { - rc = -EINVAL; - goto exit; - } - report_count = get_hid_item_data(data, - item_size); - break; - case HID_GLOBAL_ITEM_TAG_PUSH: /* A */ - pt_debug(cd->dev, DL_INFO, - "%s: TAG Ignored - Push\n", - __func__); - break; - case HID_GLOBAL_ITEM_TAG_POP: /* B */ - pt_debug(cd->dev, DL_INFO, - "%s: TAG Ignored - Pop\n", - __func__); - break; - default: - pt_debug(cd->dev, DL_INFO, - "%s: Unrecognized Global tag 0x%X\n", - __func__, item_tag); - } - break; - case HID_ITEM_TYPE_LOCAL: /* 2 */ - switch (item_tag) { - case HID_LOCAL_ITEM_TAG_USAGE: - if (item_size == 0 || item_size == 4) { - rc = -EINVAL; - goto exit; - } - usage = (u16)get_hid_item_data(data, - item_size); - if (report_id == PT_HID_PEN_REPORT_ID) { - usages_pen[usage_cnt++] = - usage_page << 16 | usage; - } - break; - case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM: - if (item_size == 0) { - rc = -EINVAL; - goto exit; - } - /* usage_min = */ - get_hid_item_data(data, item_size); - break; - case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM: - if (item_size == 0) { - rc = -EINVAL; - goto exit; - } - /* usage_max = */ - get_hid_item_data(data, item_size); - break; - default: - pt_debug(cd->dev, DL_INFO, - "%s: Unrecognized Local tag %d\n", - __func__, item_tag); - } - break; - case HID_ITEM_TYPE_MAIN: /* 0 */ - switch (item_tag) { - case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION: - usage_cnt = 0; - - if (item_size != 1) { - rc = -EINVAL; - goto exit; - } - if (PT_HID_MAX_NESTED_COLLECTIONS == - collection_nest) { - rc = -EINVAL; - goto exit; - } - - up_usage = usage_page << 16 | usage; - - /* Update collection stack */ - collection_usages[collection_nest] = up_usage; - collection_types[collection_nest] = - get_hid_item_data(data, item_size); - - if (collection_types[collection_nest] == - HID_COLLECTION_LOGICAL) { - logical_collection_count++; - app_collection_count = 0; - } - if (collection_types[collection_nest] == - HID_COLLECTION_APPLICATION) - app_collection_count++; - - collection_nest++; - break; - case HID_MAIN_ITEM_TAG_END_COLLECTION: - if (item_size != 0) { - rc = -EINVAL; - goto exit; - } - if (--collection_nest < 0) { - rc = -EINVAL; - goto exit; - } - break; - case HID_MAIN_ITEM_TAG_INPUT: - report_type = HID_INPUT_REPORT; - goto continue_main_item; - case HID_MAIN_ITEM_TAG_OUTPUT: - report_type = HID_OUTPUT_REPORT; - goto continue_main_item; - case HID_MAIN_ITEM_TAG_FEATURE: - report_type = HID_FEATURE_REPORT; -continue_main_item: - if (item_size != 1) { - pt_debug(cd->dev, DL_WARN, - "%s: %s=%d\n", - __func__, - "item_size", item_size); - rc = -EINVAL; - goto exit; - } - - up_usage = usage_page << 16 | usage; - - /* Get or create report */ - rc = pt_get_hid_report_(cd, &report_index, - report_type, report_id, true); - if (rc) { - pt_debug(cd->dev, DL_WARN, - "%s: %s rc=%d\n", - __func__, - "get_hid_report failed", rc); - goto exit; - } else - report = cd->hid_reports[report_index]; - - if (!report->usage_page && collection_nest > 0) - report->usage_page = - collection_usages - [collection_nest - 1]; - - if (report->id == PT_HID_PEN_REPORT_ID - && report_count > 1) - goto continue_pen_usages; - - /* Create field */ - field = pt_create_hid_field_(report); - if (!field) { - pt_debug(cd->dev, DL_WARN, - "%s: %s\n", - __func__, - "create field failed"); - rc = -ENOMEM; - goto exit; - } - - field->report_count = report_count; - field->report_size = report_size; - field->size = report_count - * report_size; - field->offset = offset; - field->data_type = - get_hid_item_data(data, - item_size); - field->logical_min = logical_min; - field->logical_max = logical_max; - field->usage_page = up_usage; - usages_pen[0] = 0; - for (j = 0; j < collection_nest; j++) { - field->collection_usage_pages - [collection_types[j]] = - collection_usages[j]; - } - - goto exit_main_item; -continue_pen_usages: - for (i = 0; i < report_count; i++) { - /* Create field */ - field = pt_create_hid_field_( - report); - if (!field) { - pt_debug(cd->dev, DL_WARN, - "%s: Pen - %s\n", - __func__, - "create field failed"); - rc = -ENOMEM; - goto exit; - } - - field->report_size = report_size; - field->size = report_count * - report_size; - field->report_count = 1; - field->offset = offset + i*report_size; - field->data_type = - get_hid_item_data(data, - item_size); - field->logical_min = logical_min; - field->logical_max = logical_max; - field->usage_page = usages_pen[i]; - usages_pen[i] = 0; - for (j = 0; j < collection_nest; j++) { - field->collection_usage_pages - [collection_types[j]] = - collection_usages[j]; - } - } - -exit_main_item: - /* Update report's header or record size */ - if (app_collection_count == 1) { - report->header_size += field->size; - } else if (logical_collection_count == 1) { - field->record_field = true; - field->offset -= report->header_size; - /* Set record field index */ - if (report->record_field_index == 0) - report->record_field_index = - report->num_fields - 1; - report->record_size += field->size; - } - - report->size += field->size; - report->log_collection_num = - logical_collection_count; - - offset += field->size; - - usage_cnt = 0; - break; - default: - pt_debug(cd->dev, DL_INFO, - "%s: Unrecognized Main tag %d\n", - __func__, item_tag); - } - - /* Reset all local items */ - usage = 0; - break; - } - } - - if (buf != end) { - pt_debug(cd->dev, DL_ERROR, - "%s: Report descriptor length invalid\n", - __func__); - rc = -EINVAL; - goto exit; - } - - if (collection_nest) { - pt_debug(cd->dev, DL_ERROR, - "%s: Unbalanced collection items (%d)\n", - __func__, collection_nest); - rc = -EINVAL; - goto exit; - } - -exit: - if (rc) - pt_free_hid_reports_(cd); - mutex_unlock(&cd->hid_report_lock); - return rc; -} - -/******************************************************************************* - * FUNCTION: find_report_desc_field - * - * SUMMARY: Find the corresponding field from report according to the usage page - * and collection usage page. - * - * RETURN: - * pointer to hid field structure - * - * PARAMETERS: - * *cd - pointer to core data structure - * usage_page - hid usage page - * collection_usage_page - hid collection usage page - * collection_type - hid collection type - ******************************************************************************/ -static struct pt_hid_field *find_report_desc_field( - struct pt_core_data *cd, u32 usage_page, - u32 collection_usage_page, u8 collection_type) -{ - struct pt_hid_report *report = NULL; - struct pt_hid_field *field = NULL; - int i; - int j; - u32 field_cup; - u32 field_up; - - for (i = 0; i < cd->num_hid_reports; i++) { - report = cd->hid_reports[i]; - for (j = 0; j < report->num_fields; j++) { - field = report->fields[j]; - field_cup = field->collection_usage_pages - [collection_type]; - field_up = field->usage_page; - if (field_cup == collection_usage_page - && field_up == usage_page) { - return field; - } - } - } - - return NULL; -} - -/******************************************************************************* - * FUNCTION: fill_tch_abs - * - * SUMMARY: Fill touch abs with hid field. - * - * PARAMETERS: - * *cd - pointer to core data structure - * *field - pointer to hid field structure - ******************************************************************************/ -static void fill_tch_abs(struct pt_tch_abs_params *tch_abs, - struct pt_hid_field *field) -{ - tch_abs->ofs = field->offset / 8; - tch_abs->size = field->report_size / 8; - if (field->report_size % 8) - tch_abs->size += 1; - tch_abs->min = 0; - tch_abs->max = 1 << field->report_size; - tch_abs->bofs = field->offset - (tch_abs->ofs << 3); - tch_abs->logical_max = field->logical_max; -} - -/******************************************************************************* - * FUNCTION: find_report_desc - * - * SUMMARY: Find out the corresponding report based on the usage page. - * - * RETURN: - * pointer to hid report structure - * - * PARAMETERS: - * *cd - pointer to core data structure - * id - report id - * usage_page - hid usage page - ******************************************************************************/ -static struct pt_hid_report *find_report_desc(struct pt_core_data *cd, - u8 id, u32 usage_page) -{ - struct pt_hid_report *report = NULL; - int i; - - for (i = 0; i < cd->num_hid_reports; i++) { - if (cd->hid_reports[i]->usage_page == usage_page && - cd->hid_reports[i]->id == id) { - report = cd->hid_reports[i]; - break; - } - } - - return report; -} - -/******************************************************************************* - * FUNCTION: setup_pen_report_from_report_desc - * - * SUMMARY: Setup values for pen report according to report descriptor. - * - * PARAMETERS: - * *cd - pointer to core data structure - ******************************************************************************/ -static void setup_pen_report_from_report_desc( - struct pt_core_data *cd) -{ - struct pt_sysinfo *si = &cd->sysinfo; - struct pt_hid_report *report; - struct pt_hid_field *field; - int i; - u32 pen_collection_usage_page = HID_PT_PEN_COL_USAGE_PG; - u8 id = PT_HID_PEN_REPORT_ID; - - /* - * Search each pen abs field. If found, fill the values into the - * pen struct.If not, mark this pen field as invalid (report = 0). - */ - for (i = PT_PEN_X; i < PT_PEN_NUM_ABS; i++) { - field = find_report_desc_field(cd, - pt_pen_abs_field_map[i], - pen_collection_usage_page, - HID_COLLECTION_PHYSICAL); - if (field) { - pt_debug(cd->dev, DL_DEBUG, - " Field %p: rep_cnt:%d rep_sz:%d off:%d data:%02X min:%d max:%d usage_page:%08X\n", - field, field->report_count, field->report_size, - field->offset, field->data_type, - field->logical_min, field->logical_max, - field->usage_page); - fill_tch_abs(&si->pen_abs[i], field); - si->pen_abs[i].report = 2; - pt_debug(cd->dev, DL_DEBUG, "%s: ofs:%u size:%u min:%u max:%u bofs:%u report:%d", - pt_pen_abs_string[i], - (u32)si->pen_abs[i].ofs, - (u32)si->pen_abs[i].size, - (u32)si->pen_abs[i].min, - (u32)si->pen_abs[i].max, - (u32)si->pen_abs[i].bofs, - si->pen_abs[i].report); - - } else { - si->pen_abs[i].report = 0; - pt_debug(cd->dev, DL_DEBUG, "%s: report:%d\n", - pt_pen_abs_string[i], si->pen_abs[i].report); - } - } - - report = find_report_desc(cd, id, pen_collection_usage_page); - if (report) - si->desc.pen_report_id = report->id; - else - si->desc.pen_report_id = PT_HID_PEN_REPORT_ID; -} - -/******************************************************************************* - * FUNCTION: setup_finger_report_from_report_desc - * - * SUMMARY: Setup values for finger report according to report descriptor. - * - * PARAMETERS: - * *cd - pointer to core data structure - ******************************************************************************/ -static void setup_finger_report_from_report_desc( - struct pt_core_data *cd) -{ - struct pt_sysinfo *si = &cd->sysinfo; - struct pt_hid_report *report; - struct pt_hid_field *field; - u32 tch_collection_usage_page = HID_PT_TCH_COL_USAGE_PG; - u8 id = PT_HID_FINGER_REPORT_ID; - int i; - - /* - * Search each touch abs field. If found, fill the values into the - * abs struct. If not, mark this abs field as invalid (report = 0). - */ - for (i = PT_TCH_X; i < PT_TCH_NUM_ABS; i++) { - field = find_report_desc_field(cd, - pt_tch_abs_field_map[i], - tch_collection_usage_page, - HID_COLLECTION_APPLICATION); - if (field) { - pt_debug(cd->dev, DL_DEBUG, - " Field %p: rep_cnt:%d rep_sz:%d off:%d data:%02X min:%d max:%d usage_page:%08X\n", - field, field->report_count, field->report_size, - field->offset, field->data_type, - field->logical_min, field->logical_max, - field->usage_page); - fill_tch_abs(&si->tch_abs[i], field); - si->tch_abs[i].report = 1; - pt_debug(cd->dev, DL_DEBUG, "%s: ofs:%u size:%u min:%u max:%u bofs:%u report:%d", - pt_tch_abs_string[i], - (u32)si->tch_abs[i].ofs, - (u32)si->tch_abs[i].size, - (u32)si->tch_abs[i].min, - (u32)si->tch_abs[i].max, - (u32)si->tch_abs[i].bofs, - si->tch_abs[i].report); - } else { - si->tch_abs[i].report = 0; - } - } - - /* - * Search each touch header field. If found, fill the values into - * the header struct. If not, mark this header field as invalid - * (report = 0). - */ - for (i = PT_TCH_TIME; i < PT_TCH_NUM_HDR; i++) { - field = find_report_desc_field(cd, - pt_tch_hdr_field_map[i], - tch_collection_usage_page, - HID_COLLECTION_APPLICATION); - if (field) { - pt_debug(cd->dev, DL_DEBUG, - " Field %p: rep_cnt:%d rep_sz:%d off:%d data:%02X min:%d max:%d usage_page:%08X\n", - field, field->report_count, field->report_size, - field->offset, field->data_type, - field->logical_min, field->logical_max, - field->usage_page); - fill_tch_abs(&si->tch_hdr[i], field); - si->tch_hdr[i].report = 1; - pt_debug(cd->dev, DL_DEBUG, "%s: ofs:%u size:%u min:%u max:%u bofs:%u report:%d", - pt_tch_hdr_string[i], - (u32)si->tch_hdr[i].ofs, - (u32)si->tch_hdr[i].size, - (u32)si->tch_hdr[i].min, - (u32)si->tch_hdr[i].max, - (u32)si->tch_hdr[i].bofs, - si->tch_hdr[i].report); - } else { - si->tch_hdr[i].report = 0; - } - } - - si->desc.max_touch_num = si->tch_hdr[PT_TCH_NUM].max; - - report = find_report_desc(cd, id, tch_collection_usage_page); - if (report) { - si->desc.tch_report_id = report->id; - /* First, report->record_size and report->header_size are based - * on 'BIT', they need to be divided by 8 to get tch_record_size - * and tch_header_size, which are based on 'BYTE'. - * Second, tch_header_size needs to add 3 bytes: 2 bytes length, - * 1 byte report id. - */ - si->desc.tch_record_size = report->record_size / 8; - si->desc.tch_header_size = (report->header_size / 8) + 3; - si->desc.max_tch_per_packet = report->log_collection_num; - } else { - si->desc.tch_report_id = PT_HID_FINGER_REPORT_ID; - si->desc.tch_record_size = TOUCH_REPORT_SIZE; - si->desc.tch_header_size = TOUCH_INPUT_HEADER_SIZE; - si->desc.max_tch_per_packet = MAX_TOUCH_NUM; - } - - pt_debug(cd->dev, DL_DEBUG, - "%s: tch_record_size:%d, tch_header_size:%d, max_touch_num:%d\n", - __func__, - si->desc.tch_record_size, - si->desc.tch_header_size, - si->desc.max_touch_num); -} - -/******************************************************************************* - * FUNCTION: publish_report_desc - * - * SUMMARY: If TTHE_TUNER_SUPPORT is defined print the report descriptor data - * into the tthe_tuner sysfs node under the label "HIDRptDesc". - * - * PARAMETERS: - * *cd - pointer to core data - * len - Report descriptor length - ******************************************************************************/ -static void publish_report_desc(struct pt_core_data *cd, u16 len) -{ - int max_bytes = 300; - int pr_bytes = 0; - int size = len; - -#ifdef TTHE_TUNER_SUPPORT - tthe_print(cd, cd->response_buf, size, - "HIDRptDesc="); -#endif - - while (size > max_bytes) { - pt_pr_buf(cd->dev, DL_DEBUG, - cd->response_buf + pr_bytes, - max_bytes, "<<< HIDRptDesc"); - pr_bytes += max_bytes; - size -= max_bytes; - } - if (size > 0) - pt_pr_buf(cd->dev, DL_DEBUG, - cd->response_buf + pr_bytes, - size, "<<< HIDRptDesc"); -} - -/******************************************************************************* - * FUNCTION: pt_get_report_descriptor_ - * - * SUMMARY: Get and parse report descriptor. - * - * RETURN: - * 0 = success - * !0 = failure - * - * PARAMETERS: - * *cd - pointer to core data - ******************************************************************************/ -static int pt_get_report_descriptor_(struct pt_core_data *cd) -{ - struct device *dev = cd->dev; - struct pt_hid_cmd hid_cmd = { - .descriptor = cd->hid_desc.report_desc_register, - .read_length = cd->hid_core.hid_report_desc_len, - }; - int rc; - int t; - u8 *desc; - u16 desc_len; - - rc = pt_hid_send_command(cd, &hid_cmd); - if (rc) { - pt_debug(dev, DL_ERROR, - "%s: failed to get HID report descriptor length, rc=%d\n", - __func__, rc); - goto exit; - } - - desc = cd->response_buf; - desc_len = cd->hid_core.hid_report_desc_len; - - /* Remove length field and report id to prepare parse work */ - if (cd->dut_status.protocol_mode != PT_PROTOCOL_MODE_HID) { - desc = cd->response_buf + 3; - desc_len -= 3; - } - - publish_report_desc(cd, cd->hid_core.hid_report_desc_len); - - rc = parse_report_descriptor(cd, desc, desc_len); - if (rc) { - pt_debug(cd->dev, DL_ERROR, - "%s: Error parsing report descriptor rc=%d\n", - __func__, rc); - } - - pt_debug(cd->dev, DL_INFO, "%s: %d reports found in descriptor\n", - __func__, cd->num_hid_reports); - - for (t = 0; t < cd->num_hid_reports; t++) { - struct pt_hid_report *report = cd->hid_reports[t]; - int j; - - pt_debug(cd->dev, DL_DEBUG, - "Report %d: type:%d id:%02X size:%d fields:%d rec_fld_index:%d hdr_sz:%d rec_sz:%d usage_page:%08X\n", - t, report->type, report->id, - report->size, report->num_fields, - report->record_field_index, report->header_size, - report->record_size, report->usage_page); - - if (report->id == PT_HID_FINGER_REPORT_ID) - pt_debug(cd->dev, DL_INFO, "%s: logical collection number: %d\n", - __func__, report->log_collection_num); - - for (j = 0; j < report->num_fields; j++) { - struct pt_hid_field *field = report->fields[j]; - - pt_debug(cd->dev, DL_DEBUG, - " Field %d: rep_cnt:%d rep_sz:%d off:%d data:%02X min:%d max:%d usage_page:%08X\n", - j, field->report_count, field->report_size, - field->offset, field->data_type, - field->logical_min, field->logical_max, - field->usage_page); - - pt_debug(cd->dev, DL_DEBUG, " Collections Phys:%08X App:%08X Log:%08X\n", - field->collection_usage_pages - [HID_COLLECTION_PHYSICAL], - field->collection_usage_pages - [HID_COLLECTION_APPLICATION], - field->collection_usage_pages - [HID_COLLECTION_LOGICAL]); - } - } - - setup_pen_report_from_report_desc(cd); - setup_finger_report_from_report_desc(cd); - - /* Free it for now */ - pt_free_hid_reports_(cd); - - pt_debug(cd->dev, DL_INFO, "%s: %d reports found in descriptor\n", - __func__, cd->num_hid_reports); - -exit: - return rc; -} - -/******************************************************************************* - * FUNCTION: pt_get_report_descriptor - * - * SUMMARY: Protected call to pt_get_report_descriptor_() - * - * RETURN: - * 0 = success - * !0 = failure - * - * PARAMETERS: - * *cd - pointer to core data - ******************************************************************************/ -static int pt_get_report_descriptor(struct pt_core_data *cd) -{ - int rc; - - rc = request_exclusive(cd, cd->dev, PT_REQUEST_EXCLUSIVE_TIMEOUT); - if (rc < 0) { - pt_debug(cd->dev, DL_ERROR, - "%s: fail get exclusive ex=%p own=%p\n", - __func__, cd->exclusive_dev, cd->dev); - return rc; - } - - rc = pt_get_report_descriptor_(cd); - - if (release_exclusive(cd, cd->dev) < 0) - pt_debug(cd->dev, DL_ERROR, - "%s: fail to release exclusive\n", __func__); - - return rc; -} - /******************************************************************************* * FUNCTION: pt_get_mode * @@ -8498,6 +7385,7 @@ static int _pt_request_get_mode(struct device *dev, int protect, u8 *mode) int rc = 0; memset(&hid_desc, 0, sizeof(hid_desc)); + if (protect) rc = pt_get_hid_descriptor(cd, &hid_desc); else @@ -8764,15 +7652,13 @@ static int pt_core_sleep_(struct pt_core_data *cd) { int rc = 0; - /* - * Do nothing if system already sleeping or in progress of - * entering sleep. Proceed if awake or waking. - */ - if (cd->sleep_state == SS_SLEEP_ON || cd->sleep_state == SS_SLEEPING) - goto exit; - mutex_lock(&cd->system_lock); - cd->sleep_state = SS_SLEEPING; + if (cd->sleep_state == SS_SLEEP_OFF) { + cd->sleep_state = SS_SLEEPING; + } else { + mutex_unlock(&cd->system_lock); + return 1; + } mutex_unlock(&cd->system_lock); /* Ensure watchdog and startup works stopped */ @@ -8780,7 +7666,7 @@ static int pt_core_sleep_(struct pt_core_data *cd) cancel_work_sync(&cd->enum_work); pt_stop_wd_timer(cd); - if (IS_EASY_WAKE_CONFIGURED(cd->easy_wakeup_gesture)) + if (IS_EASY_WAKE_CONFIGURED(cd->easy_wakeup_gesture) && cd->runtime) rc = pt_put_device_into_easy_wakeup_(cd); else if (cd->cpdata->flags & PT_CORE_FLAG_POWEROFF_ON_SLEEP) rc = pt_core_poweroff_device_(cd); @@ -8790,15 +7676,9 @@ static int pt_core_sleep_(struct pt_core_data *cd) rc = pt_put_device_into_deep_sleep_(cd); mutex_lock(&cd->system_lock); - if (rc == 0) { - cd->sleep_state = SS_SLEEP_ON; - } else { - cd->sleep_state = SS_SLEEP_OFF; - pt_start_wd_timer(cd); - } + cd->sleep_state = SS_SLEEP_ON; mutex_unlock(&cd->system_lock); -exit: return rc; } @@ -8911,43 +7791,30 @@ exit: } /******************************************************************************* - * FUNCTION: pt_get_touch_field + * FUNCTION: pt_get_touch_axis * - * SUMMARY: Function to calculate touch fields. The field refers to each element - * in the input report, such as "Number of Records", "X-axis". This function - * can calculate the value of element based on the bit offset, size and the - * max value of the element. + * SUMMARY: Function to calculate touch axis * * PARAMETERS: - * *dev - pointer to device structure - * *field - pointer to field calculation result + * *cd - pointer to core data structure + * *axis - pointer to axis calculation result * size - size in bytes * max - max value of result - * *data - pointer to input data to be parsed + * *xy_data - pointer to input data to be parsed * bofs - bit offset ******************************************************************************/ -void pt_get_touch_field(struct device *dev, - int *field, int size, int max, u8 *data, int bofs) +static void pt_get_touch_axis(struct pt_core_data *cd, + int *axis, int size, int max, u8 *data, int bofs) { int nbyte; int next; - for (nbyte = 0, *field = 0, next = 0; nbyte < size; nbyte++) { - pt_debug(dev, DL_DEBUG, - "%s: *field=%02X(%d) size=%d max=%08X data=%p data[%d]=%02X(%d) bofs=%d\n", - __func__, *field, *field, size, max, data, next, - data[next], data[next], bofs); - *field = *field + ((data[next] >> bofs) << (nbyte * 8)); + for (nbyte = 0, *axis = 0, next = 0; nbyte < size; nbyte++) { + *axis = *axis + ((data[next] >> bofs) << (nbyte * 8)); next++; } - if (max > 0) - *field &= max - 1; - - pt_debug(dev, DL_DEBUG, - "%s: *field=%02X(%d) size=%d max=%08X data=%p data[%d]=%02X(%d)\n", - __func__, *field, *field, size, max, data, next, - data[next], data[next]); + *axis &= max - 1; } /******************************************************************************* @@ -9045,7 +7912,7 @@ static int move_button_data(struct pt_core_data *cd, } /******************************************************************************* - * FUNCTION: move_touch_data_pip + * FUNCTION: move_touch_data * * SUMMARY: Move the valid touch data from the input buffer into the system * information structure, xy_mode and xy_data. @@ -9060,17 +7927,16 @@ static int move_button_data(struct pt_core_data *cd, * *cd - pointer to core data * *si - pointer to the system information structure ******************************************************************************/ -static int move_touch_data_pip(struct pt_core_data *cd, struct pt_sysinfo *si) +static int move_touch_data(struct pt_core_data *cd, struct pt_sysinfo *si) { int max_tch = si->sensing_conf_data.max_tch; - int num_cur_tch = 0; + int num_cur_tch; int length; - int actual_tch_num; struct pt_tch_abs_params *tch = &si->tch_hdr[PT_TCH_NUM]; - - int size = get_unaligned_le16(&cd->input_buf[0]); #ifdef TTHE_TUNER_SUPPORT - if (size > 0) + int size = get_unaligned_le16(&cd->input_buf[0]); + + if (size) tthe_print(cd, cd->input_buf, size, "OpModeData="); #endif @@ -9078,21 +7944,11 @@ static int move_touch_data_pip(struct pt_core_data *cd, struct pt_sysinfo *si) pt_pr_buf(cd->dev, DL_INFO, (u8 *)si->xy_mode, si->desc.tch_header_size, "xy_mode"); - pt_get_touch_field(cd->dev, &num_cur_tch, tch->size, + pt_get_touch_axis(cd, &num_cur_tch, tch->size, tch->max, si->xy_mode + 3 + tch->ofs, tch->bofs); if (unlikely(num_cur_tch > max_tch)) num_cur_tch = max_tch; - actual_tch_num = (size - si->desc.tch_header_size) - / si->desc.tch_record_size; - - if (actual_tch_num < num_cur_tch) { - pt_debug(cd->dev, DL_ERROR, - "%s: ATM - Malformed touch packet. actual_tch_num=%d, num_cur_tch=%d\n", - __func__, actual_tch_num, num_cur_tch); - num_cur_tch = actual_tch_num; - } - length = num_cur_tch * si->desc.tch_record_size; memcpy(si->xy_data, &cd->input_buf[si->desc.tch_header_size], length); @@ -9100,150 +7956,6 @@ static int move_touch_data_pip(struct pt_core_data *cd, struct pt_sysinfo *si) return 0; } -/******************************************************************************* - * FUNCTION: move_touch_data_hid - * - * SUMMARY: Move the valid touch data from the input buffer into the system - * information structure, xy_mode and xy_data. - * - If TTHE_TUNER_SUPPORT is defined print the raw touch data into - * the tthe_tuner sysfs node under the label "HID-USB", "HID-I2C" or - * "OpModeData" - * - * RETURN: - * 0 = success - * !0 = failure - * - * PARAMETERS: - * *cd - pointer to core data - * *si - pointer to the system information structure - ******************************************************************************/ -static int move_touch_data_hid(struct pt_core_data *cd, - struct pt_sysinfo *si) -{ - int max_tch = si->sensing_conf_data.max_tch; - int num_cur_tch = 0; - u16 hdr_sz; - u16 rec_sz; - int max_tch_per_packet; - static u8 remain_tch; - static u8 packet_no; - static u8 input_sz; - int length; - int rc = 0; - struct pt_tch_abs_params *tch = &si->tch_hdr[PT_TCH_NUM]; - int size = get_unaligned_le16(&cd->input_buf[0]); - - hdr_sz = si->desc.tch_header_size; - rec_sz = si->desc.tch_record_size; - max_tch_per_packet = si->desc.max_tch_per_packet; - -#ifdef TTHE_TUNER_SUPPORT - length = hdr_sz + rec_sz * max_tch_per_packet; - pt_debug(cd->dev, DL_DEBUG, - "%s: touch report size=%d, len=%d, record=%d, max_tch=%d\n", - __func__, size, length, rec_sz, max_tch_per_packet); - /* - * HID over USB does not require the two byte length field, so - * this should print from input_buf[2] but to keep both finger - * and pen reports the same the length is included - */ - if (cd->tthe_hid_usb_format == PT_TTHE_TUNER_FORMAT_HID_USB) - tthe_print(cd, &(cd->input_buf[2]), length - 2, - "HID-USB="); - else if (cd->tthe_hid_usb_format == - PT_TTHE_TUNER_FORMAT_HID_I2C) - tthe_print(cd, &(cd->input_buf[0]), length, - "HID-I2C="); -#endif - - memcpy(si->xy_mode, cd->input_buf, hdr_sz); - pt_pr_buf(cd->dev, DL_INFO, (u8 *)si->xy_mode, - hdr_sz, "xy_mode"); - - /* - * The fifth parameter points to the location of "Number of Records": - * Pointer "xy_mode" points to start address of touch report header. - * The byte offset of "Number of Records" is 2 (tch->ofs, retrieved - * from report descriptor). Then the pointer "xy_mode + 3 (skip the - * two bytes length and 1 byte report ID) + tch->ofs" points to the - * location of "Number of Records". - */ - pt_get_touch_field(cd->dev, &num_cur_tch, tch->size, - tch->max, si->xy_mode + 3 + tch->ofs, tch->bofs); - - if (unlikely(num_cur_tch > max_tch)) - num_cur_tch = max_tch; - - /* According to Hybrid Mode touch report defined by Microsoft, - * if the touch number exceeds the max touch per packet (defined - * in report descriptor), the touch packet will be broken up into - * to multiple reports. Timestamp will be consistent across all - * touches in a single frame. The "Number of records" will have the - * total in the first report and be 0 in all subsequent reports that - * belong to the same frame. - */ - pt_debug(cd->dev, DL_INFO, "%s: max_tch=%d, packet_no=%d, num_cur_tch=%d\n", - __func__, max_tch, packet_no, num_cur_tch); - - if (packet_no == 0) { - input_sz = hdr_sz + num_cur_tch * rec_sz; - memset(cd->touch_buf, 0, sizeof(cd->touch_buf)); - memcpy(cd->touch_buf, cd->input_buf, input_sz); - if (num_cur_tch > max_tch_per_packet) { - remain_tch = num_cur_tch - max_tch_per_packet; - packet_no++; - rc = -EINVAL; - goto exit; - } - } else { - if (remain_tch <= max_tch_per_packet) { - memcpy(&cd->touch_buf[hdr_sz + - max_tch_per_packet * packet_no * rec_sz], - &(cd->input_buf[hdr_sz]), - rec_sz * remain_tch); - remain_tch = 0; - packet_no = 0; - rc = 0; - } else { - memcpy(&cd->touch_buf[hdr_sz + - max_tch_per_packet * packet_no * rec_sz], - &(cd->input_buf[hdr_sz]), - rec_sz * max_tch_per_packet); - remain_tch -= max_tch_per_packet; - packet_no++; - rc = -EINVAL; - goto exit; - } - } - -#ifdef TTHE_TUNER_SUPPORT - /* Update pip packet length */ - cd->touch_buf[0] = input_sz & 0xff; - cd->touch_buf[1] = (input_sz & 0xff00) >> 8; - - /* - * For PT_TTHE_TUNER_FORMAT_HID_FINGER_TO_PIP and - * PT_TTHE_TUNER_FORMAT_HID_FINGER_AND_PEN_TO_PIP mode, all touches - * should be combined into a single row for the tthe_tuner node. - */ - if (cd->tthe_hid_usb_format == - PT_TTHE_TUNER_FORMAT_HID_FINGER_TO_PIP || - cd->tthe_hid_usb_format == - PT_TTHE_TUNER_FORMAT_HID_FINGER_AND_PEN_TO_PIP) - tthe_print(cd, cd->touch_buf, input_sz, - "OpModeData="); -#endif - - memcpy(si->xy_data, &cd->touch_buf[hdr_sz], input_sz - hdr_sz); - pt_pr_buf(cd->dev, DL_INFO, - (u8 *)si->xy_data, input_sz - hdr_sz, "xy_data"); - - input_sz = 0; - -exit: - return rc; -} - /******************************************************************************* * FUNCTION: move_hid_pen_data * @@ -9263,17 +7975,8 @@ exit: ******************************************************************************/ static int move_hid_pen_data(struct pt_core_data *cd, struct pt_sysinfo *si) { - int size = get_unaligned_le16(&cd->input_buf[0]); - #ifdef TTHE_TUNER_SUPPORT - enum pt_pen_abs abs; - struct pt_pen pen; - int packet_len = 17; - int report_id = 1; - static int report_counter; - int event_id = 2; - int touch_id = 0; - int i = 0; + int size = get_unaligned_le16(&cd->input_buf[0]); if (size) { /* @@ -9281,77 +7984,14 @@ static int move_hid_pen_data(struct pt_core_data *cd, struct pt_sysinfo *si) * this should print from input_buf[2] but to keep both finger * and pen reports the same the length is included */ - if (cd->tthe_hid_usb_format == PT_TTHE_TUNER_FORMAT_HID_USB) + if (cd->tthe_hid_usb_format == PT_FEATURE_ENABLE) tthe_print(cd, &(cd->input_buf[2]), size - 2, "HID-USB="); - else if (cd->tthe_hid_usb_format == - PT_TTHE_TUNER_FORMAT_HID_I2C || - cd->tthe_hid_usb_format == - PT_TTHE_TUNER_FORMAT_HID_FINGER_TO_PIP) + else tthe_print(cd, &(cd->input_buf[0]), size, "HID-I2C="); - else if (cd->tthe_hid_usb_format == - PT_TTHE_TUNER_FORMAT_HID_FINGER_AND_PEN_TO_PIP) { - memset(cd->touch_buf, 0, sizeof(cd->touch_buf)); - - for (abs = PT_PEN_X; abs < PT_PEN_NUM_ABS; abs++) { - if (!si->pen_abs[abs].report) - continue; - pt_get_touch_field(cd->dev, &pen.abs[abs], - si->pen_abs[abs].size, - si->pen_abs[abs].max, - cd->input_buf + 3 + - si->pen_abs[abs].ofs, - si->pen_abs[abs].bofs); - pt_debug(cd->dev, DL_DEBUG, "%s: get %s=%04X(%d)\n", - __func__, pt_pen_abs_string[abs], - pen.abs[abs], pen.abs[abs]); - } - /* pip packet length: 17 */ - cd->touch_buf[i++] = packet_len & 0xff; - cd->touch_buf[i++] = (packet_len & 0xff00) >> 8; - /* pip finger report id: 1*/ - cd->touch_buf[i++] = report_id; - /* Timestamp: 0 */ - cd->touch_buf[i++] = 0; - cd->touch_buf[i++] = 0; - /* LO: 0; Number of Records: 1*/ - cd->touch_buf[i++] = 1; - /* Report Counter:[0-3]; Noise Effects:0 */ - cd->touch_buf[i++] = (report_counter & 0x03) << 6; - /* Touch Type: Stylus (2)*/ - cd->touch_buf[i++] = PT_OBJ_STYLUS; - /* Tip: pen tip switch; Event ID: 2; Touch ID: 0 */ - cd->touch_buf[i++] = - ((pen.abs[PT_PEN_TS] & 0x01) << 7) | - ((event_id & 0x03) << 5) | - (touch_id & 0x1f); - /* X: Pen X */ - cd->touch_buf[i++] = pen.abs[PT_PEN_X] & 0xff; - cd->touch_buf[i++] = (pen.abs[PT_PEN_X] & 0xff00) >> 8; - /* Y: Pen Y */ - cd->touch_buf[i++] = pen.abs[PT_PEN_Y] & 0xff; - cd->touch_buf[i++] = (pen.abs[PT_PEN_Y] & 0xff00) >> 8; - /* Pressure: Pen pressure drop the least 4 bits */ - cd->touch_buf[i++] = (pen.abs[PT_PEN_P] & 0xff0) >> 4; - /* Major: Pen Tilt_X*/ - cd->touch_buf[i++] = pen.abs[PT_PEN_X_TILT] & 0xff; - /* Minor: Pen Tilt_Y*/ - cd->touch_buf[i++] = pen.abs[PT_PEN_Y_TILT] & 0xff; - /* Orientation: Btn2, Btn1*/ - cd->touch_buf[i++] = - (pen.abs[PT_PEN_BS] & 0x01) | - ((pen.abs[PT_PEN_2ND_BS] & 0x01) << 1); - - if (++report_counter > 3) - report_counter = 0; - - tthe_print(cd, cd->touch_buf, packet_len, - "OpModeData="); - } } #endif - memcpy(si->xy_data, cd->input_buf, size); pt_pr_buf(cd->dev, DL_INFO, (u8 *)&(cd->input_buf[0]), size, "HID Pen"); return 0; } @@ -9388,22 +8028,9 @@ static int parse_touch_input(struct pt_core_data *cd, int size) if (!si->xy_mode || !si->xy_data) return rc; - if (report_id == PT_PIP_TOUCH_REPORT_ID || - report_id == PT_HID_VS_FINGER_REPORT_ID) { - if (cd->dut_status.protocol_mode == PT_PROTOCOL_MODE_PIP) - rc = move_touch_data_pip(cd, si); - else { - rc = move_touch_data_hid(cd, si); - if (rc) { - pt_debug(cd->dev, DL_INFO, - "%s: Skip report for the first touch packet\n", - __func__); - return 0; - } - } - } else if ((report_id == PT_HID_PEN_REPORT_ID || - report_id == PT_HID_VS_PEN_REPORT_ID) && - cd->dut_status.protocol_mode == PT_PROTOCOL_MODE_HID) + if (report_id == PT_PIP_TOUCH_REPORT_ID) + rc = move_touch_data(cd, si); + else if (report_id == PT_HID_PEN_REPORT_ID) rc = move_hid_pen_data(cd, si); else if (report_id == PT_PIP_CAPSENSE_BTN_REPORT_ID) rc = move_button_data(cd, si); @@ -9515,8 +8142,6 @@ static bool pt_is_touch_report(int id) { if (id == PT_PIP_TOUCH_REPORT_ID || id == PT_HID_PEN_REPORT_ID || - id == PT_HID_VS_FINGER_REPORT_ID || - id == PT_HID_VS_PEN_REPORT_ID || id == PT_PIP_CAPSENSE_BTN_REPORT_ID || id == PT_PIP_SENSOR_DATA_REPORT_ID || id == PT_PIP_TRACKING_HEATMAP_REPORT_ID) @@ -9549,7 +8174,7 @@ static bool pt_is_touch_report(int id) ******************************************************************************/ static int pt_parse_input(struct pt_core_data *cd) { - int report_id = 0; + int report_id; int cmd_id; int is_command = 0; int size; @@ -9566,7 +8191,6 @@ static int pt_parse_input(struct pt_core_data *cd) if (print_size <= PT_MAX_INPUT) pt_pr_buf(cd->dev, DL_DEBUG, cd->input_buf, print_size, "<<< Read buf"); - if (size == 0 || (size == 11 && (cd->input_buf[PIP2_RESP_SEQUENCE_OFFSET] & @@ -9604,7 +8228,6 @@ static int pt_parse_input(struct pt_core_data *cd) STARTUP_STATUS_START; } cd->fw_system_mode = FW_SYS_MODE_UNDEFINED; - pt_debug(cd->dev, DL_INFO, "%s: ATM Gen5/6 %s sentinel received\n", __func__, @@ -9622,7 +8245,6 @@ static int pt_parse_input(struct pt_core_data *cd) __func__); } mutex_unlock(&cd->system_lock); - if (pt_allow_enumeration(cd)) { if (cd->active_dut_generation == DUT_UNKNOWN) { pt_debug(cd->dev, DL_INFO, @@ -9698,11 +8320,9 @@ static int pt_parse_input(struct pt_core_data *cd) /* PIP2 does not have a report id, hard code it */ report_id = 0x00; cmd_id = cd->input_buf[PIP2_RESP_COMMAND_ID_OFFSET]; - calc_crc = crc_ccitt_calculate(cd->input_buf, size - 2); resp_crc = cd->input_buf[size - 2] << 8; resp_crc |= cd->input_buf[size - 1]; - if ((cd->pip2_cmd_tag_seq != (cd->input_buf[PIP2_RESP_SEQUENCE_OFFSET] & 0x0F)) && (resp_crc != calc_crc) && @@ -9710,17 +8330,16 @@ static int pt_parse_input(struct pt_core_data *cd) == PT_PIP_TOUCH_REPORT_ID) || (cd->input_buf[PIP1_RESP_REPORT_ID_OFFSET] == PT_PIP_CAPSENSE_BTN_REPORT_ID))) { - report_id = cd->input_buf[PIP1_RESP_REPORT_ID_OFFSET]; - cmd_id = cd->input_buf[PIP1_RESP_COMMAND_ID_OFFSET]; - pt_debug(cd->dev, DL_INFO, - "%s: %s %d %s\n", __func__, - "Received PIP1 report id =", - report_id, - "when expecting a PIP2 report"); - } else { - is_command = 1; - touch_report = false; + pt_debug(cd->dev, DL_WARN, + "%s: %s %d %s\n", + __func__, + "Received PIP1 report id =", + cd->input_buf[PIP1_RESP_REPORT_ID_OFFSET], + "when expecting a PIP2 report - IGNORE report"); + return 0; } + is_command = 1; + touch_report = false; } else { report_id = cd->input_buf[PIP1_RESP_REPORT_ID_OFFSET]; cmd_id = cd->input_buf[PIP1_RESP_COMMAND_ID_OFFSET]; @@ -9740,7 +8359,6 @@ static int pt_parse_input(struct pt_core_data *cd) #endif return 0; } - mod_timer_pending(&cd->watchdog_timer, jiffies + msecs_to_jiffies(cd->watchdog_interval)); @@ -9752,12 +8370,10 @@ static int pt_parse_input(struct pt_core_data *cd) is_command = 1; touch_report = false; } - if (unlikely(is_command)) { parse_command_input(cd, size); return 0; } - if (touch_report) parse_touch_input(cd, size); @@ -9788,7 +8404,8 @@ static int pt_read_input(struct pt_core_data *cd) * Interrupt for easywake, wait for bus controller to wake */ mutex_lock(&cd->system_lock); - if (IS_EASY_WAKE_CONFIGURED(cd->easy_wakeup_gesture)) { + + if (IS_EASY_WAKE_CONFIGURED(cd->easy_wakeup_gesture) && cd->runtime) { if (cd->sleep_state == SS_SLEEP_ON) { mutex_unlock(&cd->system_lock); if (!dev->power.is_suspended) @@ -9815,7 +8432,6 @@ static int pt_read_input(struct pt_core_data *cd) mutex_unlock(&cd->system_lock); read: - memset(cd->input_buf, 0, sizeof(cd->input_buf)); /* Try reading up to 'retry' times */ while (retry-- != 0) { rc = pt_adap_read_default_nosize(cd, cd->input_buf, @@ -9851,15 +8467,8 @@ irqreturn_t pt_irq(int irq, void *handle) struct pt_core_data *cd = handle; int rc = 0; -#ifdef TTDL_PTVIRTDUT_SUPPORT - if (!cd->route_bus_virt_dut) { - if (!pt_check_irq_asserted(cd)) - return IRQ_HANDLED; - } -#else if (!pt_check_irq_asserted(cd)) return IRQ_HANDLED; -#endif /* TTDL_PTVIRTDUT_SUPPORT */ rc = pt_read_input(cd); #ifdef TTDL_DIAGNOSTICS @@ -9886,36 +8495,6 @@ irqreturn_t pt_irq(int irq, void *handle) return IRQ_HANDLED; } -#ifdef PT_AUX_BRIDGE_ENABLED -/******************************************************************************* - * FUNCTION: pt_trigger_ttdl_irq - * - * SUMMARY: API for other kernel drivers to artificially trigger a TTDL IRQ - * - * IMPROVE - dpmux should likely call pt_get_core_data once and make a - * copy of cd so that the function only needs to be called once. - * RETURN: - * 0 = success - * !0 = failure - * - * PARAMETERS: none - * - ******************************************************************************/ -int pt_trigger_ttdl_irq(void) -{ - struct pt_core_data *cd; - char *core_name = PT_DEFAULT_CORE_ID; - - cd = pt_get_core_data(core_name); - if (!cd) { - pr_err("%s: No Device\n", __func__); - return -ENODEV; - } - pt_irq(cd->irq, (void *)cd); - return 0; -} -EXPORT_SYMBOL_GPL(pt_trigger_ttdl_irq); -#endif /******************************************************************************* * FUNCTION: _pt_subscribe_attention @@ -10002,11 +8581,11 @@ int _pt_unsubscribe_attention(struct device *dev, if (atten->id == id && atten->mode == mode) { list_del(&atten->node); spin_unlock(&cd->spinlock); - kfree(atten); pt_debug(cd->dev, DL_DEBUG, "%s: %s=%p %s=%d\n", __func__, "unsub for atten->dev", atten->dev, "atten->mode", atten->mode); + kfree(atten); return 0; } } @@ -10520,8 +9099,7 @@ int pt_pip2_exit_bl_(struct pt_core_data *cd, u8 *status_str, int buf_size) rc = _pt_request_wait_for_enum_state(cd->dev, 4000, STARTUP_STATUS_FW_RESET_SENTINEL); if (rc && load_status_str) { - strlcpy(status_str, - "No FW sentinel after BL", + strlcpy(status_str, "No FW sentinel after BL", sizeof(*status_str)*PT_STATUS_STR_LEN); goto exit; } @@ -10550,9 +9128,8 @@ int pt_pip2_exit_bl_(struct pt_core_data *cd, u8 *status_str, int buf_size) cd->startup_status); if (load_status_str && !(cd->startup_status & STARTUP_STATUS_FW_OUT_OF_BOOT)) { - strlcpy(status_str, - "FW Stuck in Boot mode", - sizeof(*status_str)*PT_STATUS_STR_LEN); + strlcpy(status_str, "FW Stuck in Boot mode", + sizeof(*status_str)*PT_STATUS_STR_LEN); goto exit; } } @@ -10569,15 +9146,13 @@ int pt_pip2_exit_bl_(struct pt_core_data *cd, u8 *status_str, int buf_size) } if (load_status_str) { if (rc == PIP2_RSP_ERR_INVALID_IMAGE) - strlcpy(status_str, - "Failed - Invalid image in FLASH", + strlcpy(status_str, "Failed - Invalid image in FLASH", sizeof(*status_str)*PT_STATUS_STR_LEN); else if (!rc) - strlcpy(status_str, - "Entered APP from BL mode", sizeof(*status_str)*PT_STATUS_STR_LEN); + strlcpy(status_str, "Entered APP from BL mode", + sizeof(*status_str)*PT_STATUS_STR_LEN); else - strlcpy(status_str, - "Failed to enter APP from BL mode", + strlcpy(status_str, "Failed to enter APP from BL mode", sizeof(*status_str)*PT_STATUS_STR_LEN); } } else if (mode == PT_MODE_OPERATIONAL) { @@ -10587,12 +9162,10 @@ int pt_pip2_exit_bl_(struct pt_core_data *cd, u8 *status_str, int buf_size) rc = pt_poll_for_fw_exit_boot_mode(cd, 1500, &wait_time); if (load_status_str) { if (!rc) - strlcpy(status_str, - "Already in APP mode", + strlcpy(status_str, "Already in APP mode", sizeof(*status_str)*PT_STATUS_STR_LEN); else - strlcpy(status_str, - "Already in APP mode - FW stuck in Boot mode", + strlcpy(status_str, "Already in APP mode - FW stuck in Boot mode", sizeof(*status_str)*PT_STATUS_STR_LEN); } } else if (rc || mode == PT_MODE_UNKNOWN) { @@ -10600,7 +9173,7 @@ int pt_pip2_exit_bl_(struct pt_core_data *cd, u8 *status_str, int buf_size) cd->mode = mode; mutex_unlock(&cd->system_lock); if (load_status_str) - strlcpy(status_str, "Failed to determine active mode", + strlcpy(status_str, "Failed to determine active mode", sizeof(*status_str)*PT_STATUS_STR_LEN); } @@ -10668,7 +9241,6 @@ static int _fast_startup(struct pt_core_data *cd) int wait_time = 0; memset(&hid_desc, 0, sizeof(hid_desc)); - reset: if (retry != PT_CORE_STARTUP_RETRY_COUNT) pt_debug(cd->dev, DL_INFO, "%s: Retry %d\n", __func__, @@ -10910,22 +9482,26 @@ static int pt_core_wake_(struct pt_core_data *cd) { int rc = 0; - /* - * Do nothing if system already awake or in progress of waking. - * Proceed if sleeping or entering sleep state. - */ - if (cd->sleep_state == SS_SLEEP_OFF || cd->sleep_state == SS_WAKING) - goto exit; - mutex_lock(&cd->system_lock); - cd->sleep_state = SS_WAKING; + if (cd->sleep_state == SS_SLEEP_ON) { + cd->sleep_state = SS_WAKING; + } else { + mutex_unlock(&cd->system_lock); + return 1; + } mutex_unlock(&cd->system_lock); if (!(cd->cpdata->flags & PT_CORE_FLAG_SKIP_RESUME)) { - if (IS_EASY_WAKE_CONFIGURED(cd->easy_wakeup_gesture)) + if (IS_EASY_WAKE_CONFIGURED(cd->easy_wakeup_gesture) && cd->runtime) rc = pt_core_wake_device_from_easy_wake_(cd); - else if (cd->cpdata->flags & PT_CORE_FLAG_POWEROFF_ON_SLEEP) + else if (cd->cpdata->flags & PT_CORE_FLAG_POWEROFF_ON_SLEEP) { + pt_debug(cd->dev, DL_INFO, + "%s: Entering into poweron mode:\n", __func__); rc = pt_core_poweron_device_(cd); + if (rc < 0) + pr_err("%s: Poweron error detected: rc=%d\n", + __func__, rc); + } else if (cd->cpdata->flags & PT_CORE_FLAG_DEEP_STANDBY) rc = pt_core_wake_device_from_deep_standby_(cd); else /* Default action to exit DeepSleep */ @@ -10933,20 +9509,15 @@ static int pt_core_wake_(struct pt_core_data *cd) } mutex_lock(&cd->system_lock); - if (rc == 0) - cd->sleep_state = SS_SLEEP_OFF; - else - cd->sleep_state = SS_SLEEP_ON; + cd->sleep_state = SS_SLEEP_OFF; mutex_unlock(&cd->system_lock); pt_start_wd_timer(cd); - -exit: return rc; } /******************************************************************************* - * FUNCTION: pt_core_wake + * FUNCTION: pt_core_wake_ * * SUMMARY: Protected call to pt_core_wake_ by exclusive access to the DUT. * @@ -11153,7 +9724,6 @@ static int pt_enum_with_dut_(struct pt_core_data *cd, bool reset, bool detected = false; u8 return_data[8]; u8 mode = PT_MODE_UNKNOWN; - u8 protocol_mode = PT_PROTOCOL_MODE_PIP; u8 pid = PANEL_ID_NOT_ENABLED; u8 sys_mode = FW_SYS_MODE_UNDEFINED; struct pt_hid_desc hid_desc; @@ -11165,13 +9735,11 @@ static int pt_enum_with_dut_(struct pt_core_data *cd, bool reset, pt_debug(cd->dev, DL_INFO, "%s: Start enum... 0x%04X, reset=%d\n", __func__, cd->startup_status, reset); pt_stop_wd_timer(cd); - reset: if (try > 1) pt_debug(cd->dev, DL_WARN, "%s: DUT Enum Attempt %d\n", __func__, try); pt_flush_bus_if_irq_asserted(cd, PT_FLUSH_BUS_BASED_ON_LEN); - if (cd->active_dut_generation == DUT_PIP1_ONLY) { pt_debug(cd->dev, DL_INFO, "%s: PIP1 Enumeration start\n", __func__); @@ -11196,7 +9764,6 @@ reset: /* sleep to allow FW to be launched if available */ msleep(120); } - rc = pt_get_hid_descriptor_(cd, &hid_desc); if (rc < 0) { pt_debug(cd->dev, DL_ERROR, @@ -11209,7 +9776,6 @@ reset: } detected = true; cd->mode = pt_get_mode(cd, &hid_desc); - /* * Most systems do not use an XY pin as the panel_id and so * the BL is used to retrieve the panel_id, however for @@ -11230,10 +9796,9 @@ reset: goto exit; } cd->mode = PT_MODE_BOOTLOADER; - pt_debug(cd->dev, DL_INFO, - "%s: Bootloader mode\n", __func__); + pt_debug(cd->dev, DL_INFO, "%s: Bootloader mode\n", + __func__); } - rc = pt_hid_output_bl_get_information_(cd, return_data); if (!rc) { cd->bl_info.ready = true; @@ -11246,13 +9811,11 @@ reset: "%s: failed to get chip ID, r=%d\n", __func__, rc); } - rc = pt_hid_output_bl_get_panel_id_(cd, &pid); mutex_lock(&cd->system_lock); if (!rc) { cd->pid_for_loader = pid; - pt_debug(cd->dev, DL_INFO, - "%s: Panel ID: 0x%02X\n", + pt_debug(cd->dev, DL_INFO, "%s: Panel ID: 0x%02X\n", __func__, cd->pid_for_loader); } else { cd->pid_for_loader = PANEL_ID_NOT_ENABLED; @@ -11263,7 +9826,6 @@ reset: mutex_unlock(&cd->system_lock); } - /* Exit BL due to XY_PIN case or any other cause to be in BL */ if (cd->mode == PT_MODE_BOOTLOADER) { rc = pt_hid_output_bl_launch_app_(cd); @@ -11291,6 +9853,7 @@ reset: rc = -EIO; goto exit; } + cd->mode = pt_get_mode(cd, &hid_desc); if (cd->mode == PT_MODE_BOOTLOADER) { pt_debug(cd->dev, DL_WARN, @@ -11310,24 +9873,21 @@ reset: /* Generation is PIP2 Capable */ pt_debug(cd->dev, DL_INFO, "%s: PIP2 Enumeration start\n", __func__); - rc = pt_pip2_get_status_(cd); + + rc = pt_pip2_get_mode_sysmode_(cd, &mode, NULL); if (rc) { pt_debug(cd->dev, DL_ERROR, "%s: Get mode failed, mode unknown\n", __func__); mode = PT_MODE_UNKNOWN; - } else { - mode = cd->dut_status.mode; + } else detected = true; - } cd->mode = mode; - switch (cd->mode) { case PT_MODE_OPERATIONAL: pt_debug(cd->dev, DL_INFO, "%s: Operational mode\n", __func__); - protocol_mode = cd->dut_status.protocol_mode; if (cd->app_pip_ver_ready == false) { rc = pt_pip2_get_version_(cd); if (!rc) @@ -11405,20 +9965,19 @@ reset: */ msleep(60); /* Check and update the mode */ - rc = pt_pip2_get_status_(cd); + rc = pt_pip2_get_mode_sysmode_(cd, &mode, NULL); if (rc) { pt_debug(cd->dev, DL_ERROR, "%s: Get mode failed, mode unknown\n", __func__); mode = PT_MODE_UNKNOWN; - } else - mode = cd->dut_status.mode; + } + cd->mode = mode; if (cd->mode == PT_MODE_OPERATIONAL) { pt_debug(cd->dev, DL_INFO, "%s: Launched to Operational mode\n", __func__); - protocol_mode = cd->dut_status.protocol_mode; } else if (cd->mode == PT_MODE_BOOTLOADER) { pt_debug(cd->dev, DL_ERROR, "%s: Launch failed, Bootloader mode\n", @@ -11432,7 +9991,6 @@ reset: goto reset; goto exit; } - if (cd->app_pip_ver_ready == false) { rc = pt_pip2_get_version_(cd); if (!rc) @@ -11451,30 +10009,11 @@ reset: goto reset; goto exit; } - if (cd->dut_status.protocol_mode == PT_PROTOCOL_MODE_HID) { - rc = pt_get_hid_descriptor_(cd, &hid_desc); - if (!rc) - *enum_status |= STARTUP_STATUS_GET_DESC; - } else { - *enum_status |= STARTUP_STATUS_GET_DESC; - } + *enum_status |= STARTUP_STATUS_GET_DESC; } pt_init_pip_report_fields(cd); - if (protocol_mode == PT_PROTOCOL_MODE_HID) { - rc = pt_get_report_descriptor_(cd); - if (rc < 0) { - pt_debug(cd->dev, DL_ERROR, - "%s: Error on getting report descriptor r=%d\n", - __func__, rc); - if (try++ < PT_CORE_STARTUP_RETRY_COUNT) - goto reset; - goto exit; - } - } - *enum_status |= STARTUP_STATUS_GET_RPT_DESC; - if (!cd->features.easywake) cd->easy_wakeup_gesture = PT_CORE_EWG_NONE; @@ -11488,7 +10027,6 @@ reset: goto exit; } *enum_status |= STARTUP_STATUS_GET_SYS_INFO; - /* FW cannot handle most PIP cmds when it is still in BOOT mode */ rc = _pt_poll_for_fw_exit_boot_mode(cd, 10000, &wait_time); if (!rc) { @@ -11507,7 +10045,6 @@ reset: __func__, cd->sysinfo.ttdata.pip_ver_major, cd->sysinfo.ttdata.pip_ver_minor); - rc = pt_get_ic_crc_(cd, PT_TCH_PARM_EBID); if (rc) { pt_debug(cd->dev, DL_ERROR, @@ -11526,7 +10063,6 @@ reset: } else *enum_status |= STARTUP_STATUS_GET_CFG_CRC; } - rc = pt_restore_parameters_(cd); if (rc) { pt_debug(cd->dev, DL_ERROR, @@ -11534,7 +10070,6 @@ reset: __func__, rc); } else *enum_status |= STARTUP_STATUS_RESTORE_PARM; - call_atten_cb(cd, PT_ATTEN_STARTUP, 0); cd->watchdog_interval = PT_WATCHDOG_TIMEOUT; cd->startup_retry_count = 0; @@ -11600,7 +10135,6 @@ static int pt_enum_with_dut(struct pt_core_data *cd, bool reset, u32 *status) else pt_debug(cd->dev, DL_DEBUG, "%s: pass release exclusive\n", __func__); - exit: mutex_lock(&cd->system_lock); /* Clear startup state for any tasks waiting for startup completion */ @@ -11616,11 +10150,9 @@ exit: return rc; } -#ifndef TTDL_KERNEL_SUBMISSION static int add_sysfs_interfaces(struct device *dev); static void remove_sysfs_interfaces(struct device *dev); static void remove_sysfs_and_modules(struct device *dev); -#endif /*!TTDL_KERNEL_SUBMISSION */ static void pt_release_modules(struct pt_core_data *cd); static void pt_probe_modules(struct pt_core_data *cd); /******************************************************************************* @@ -11646,7 +10178,6 @@ static int _pt_ttdl_restart(struct device *dev) struct i2c_client *client = (struct i2c_client *)container_of(dev, struct i2c_client, dev); #endif - /* * Make sure the device is awake, pt_mt_release function will * cause pm sleep function and lead to deadlock. @@ -11769,6 +10300,119 @@ static void pt_enum_work_function(struct work_struct *work) __func__, rc); } +static int pt_get_regulator(struct pt_core_data *cd, bool get) +{ + int rc; + + if (!get) { + rc = 0; + goto regulator_put; + } + + cd->vdd = regulator_get(cd->dev, "vdd"); + if (IS_ERR(cd->vdd)) { + rc = PTR_ERR(cd->vdd); + dev_err(cd->dev, + "Regulator get failed vdd rc=%d\n", rc); + goto regulator_put; + } + + cd->vcc_i2c = regulator_get(cd->dev, "vcc_i2c"); + if (IS_ERR(cd->vcc_i2c)) { + rc = PTR_ERR(cd->vcc_i2c); + dev_err(cd->dev, + "Regulator get failed vcc_i2c rc=%d\n", rc); + goto regulator_put; + } + + return 0; + +regulator_put: + if (cd->vdd) { + regulator_put(cd->vdd); + cd->vdd = NULL; + } + + if (cd->vcc_i2c) { + regulator_put(cd->vcc_i2c); + cd->vcc_i2c = NULL; + } + + return rc; +} + +static int pt_enable_regulator(struct pt_core_data *cd, bool en) +{ + int rc; + + if (!en) { + rc = 0; + goto disable_vcc_i2c_reg; + } + + if (cd->vdd) { + if (regulator_count_voltages(cd->vdd) > 0) { + rc = regulator_set_voltage(cd->vdd, FT_VTG_MIN_UV, + FT_VTG_MAX_UV); + if (rc) { + dev_err(cd->dev, + "Regulator set_vtg failed vdd rc=%d\n", rc); + goto exit; + } + } + + rc = regulator_enable(cd->vdd); + if (rc) { + dev_err(cd->dev, + "Regulator vdd enable failed rc=%d\n", rc); + goto exit; + } + } + + if (cd->vcc_i2c) { + if (regulator_count_voltages(cd->vcc_i2c) > 0) { + rc = regulator_set_voltage(cd->vcc_i2c, FT_I2C_VTG_MIN_UV, + FT_I2C_VTG_MAX_UV); + if (rc) { + dev_err(cd->dev, + "Regulator set_vtg failed vcc_i2c rc=%d\n", rc); + goto disable_vdd_reg; + } + } + + rc = regulator_enable(cd->vcc_i2c); + if (rc) { + dev_err(cd->dev, + "Regulator vcc_i2c enable failed rc=%d\n", rc); + goto disable_vdd_reg; + } + } + + return 0; + +disable_vcc_i2c_reg: + if (cd->vcc_i2c) { + if (regulator_count_voltages(cd->vcc_i2c) > 0) + regulator_set_voltage(cd->vcc_i2c, FT_I2C_VTG_MIN_UV, + FT_I2C_VTG_MAX_UV); + + regulator_disable(cd->vcc_i2c); + } + +disable_vdd_reg: + if (cd->vdd) { + if (regulator_count_voltages(cd->vdd) > 0) + regulator_set_voltage(cd->vdd, FT_VTG_MIN_UV, + FT_VTG_MAX_UV); + + regulator_disable(cd->vdd); + } + +exit: + return rc; +} + + #if (KERNEL_VERSION(3, 19, 0) <= LINUX_VERSION_CODE) #define KERNEL_VER_GT_3_19 #endif @@ -11793,14 +10437,20 @@ static int pt_core_rt_suspend(struct device *dev) struct pt_core_data *cd = dev_get_drvdata(dev); int rc = 0; + dev_info(dev, "%s: Entering into runtime suspend mode:\n", + __func__); if (cd->cpdata->flags & PT_CORE_FLAG_SKIP_RUNTIME) return 0; + if (cd->sleep_state == SS_SLEEP_OFF) + cd->runtime = 1; + rc = pt_core_sleep(cd); if (rc < 0) { pt_debug(dev, DL_ERROR, "%s: Error on sleep\n", __func__); return -EAGAIN; } + return 0; } @@ -11821,6 +10471,8 @@ static int pt_core_rt_resume(struct device *dev) struct pt_core_data *cd = dev_get_drvdata(dev); int rc = 0; + dev_info(dev, "%s: Entering into runtime resume mode:\n", + __func__); if (cd->cpdata->flags & PT_CORE_FLAG_SKIP_RUNTIME) return 0; @@ -11830,6 +10482,9 @@ static int pt_core_rt_resume(struct device *dev) return -EAGAIN; } + if (cd->sleep_state == SS_SLEEP_OFF) + cd->runtime = 0; + return 0; } #endif /* CONFIG_PM_SLEEP */ @@ -11851,11 +10506,26 @@ static int pt_core_rt_resume(struct device *dev) ******************************************************************************/ static int pt_core_suspend_(struct device *dev) { + int rc; struct pt_core_data *cd = dev_get_drvdata(dev); - pt_core_sleep(cd); + pt_debug(dev, DL_INFO, "%s: Entering into suspend mode:\n", + __func__); + rc = pt_core_sleep(cd); + if (rc < 0) { + pt_debug(dev, DL_ERROR, "%s: Error on sleep\n", __func__); + return -EAGAIN; + } - if (!IS_EASY_WAKE_CONFIGURED(cd->easy_wakeup_gesture)) + rc = pt_enable_regulator(cd, false); + if (rc) { + dev_err(dev, "%s: Failed to disable regulators: rc=%d\n", + __func__, rc); + } + dev_info(dev, "%s: Sayantan1: Voltage regulators disabled: rc=%d\n", + __func__, rc); + + if (!IS_EASY_WAKE_CONFIGURED(cd->easy_wakeup_gesture) && !cd->runtime) return 0; /* Required to prevent interrupts before bus awake */ @@ -11872,7 +10542,7 @@ static int pt_core_suspend_(struct device *dev) __func__); } - return 0; + return rc; } /******************************************************************************* @@ -11892,7 +10562,6 @@ static int pt_core_suspend_(struct device *dev) static int pt_core_suspend(struct device *dev) { struct pt_core_data *cd = dev_get_drvdata(dev); - if (cd->cpdata->flags & PT_CORE_FLAG_SKIP_SYS_SLEEP) return 0; @@ -11914,9 +10583,20 @@ static int pt_core_suspend(struct device *dev) ******************************************************************************/ static int pt_core_resume_(struct device *dev) { + int rc = 0; struct pt_core_data *cd = dev_get_drvdata(dev); - if (!IS_EASY_WAKE_CONFIGURED(cd->easy_wakeup_gesture)) + dev_info(dev, "%s: Entering into resume mode:\n", + __func__); + rc = pt_enable_regulator(cd, true); + if (rc < 0) { + dev_err(dev, "%s: Failed to enable regulators: rc=%d\n", + __func__, rc); + } + dev_info(dev, "%s: Voltage regulator enabled: rc=%d\n", + __func__, rc); + + if (!IS_EASY_WAKE_CONFIGURED(cd->easy_wakeup_gesture) && !cd->runtime) goto exit; /* @@ -11963,7 +10643,6 @@ exit: static int pt_core_resume(struct device *dev) { struct pt_core_data *cd = dev_get_drvdata(dev); - if (cd->cpdata->flags & PT_CORE_FLAG_SKIP_SYS_SLEEP) return 0; @@ -11992,7 +10671,6 @@ static int pt_pm_notifier(struct notifier_block *nb, { struct pt_core_data *cd = container_of(nb, struct pt_core_data, pm_notifier); - if (action == PM_SUSPEND_PREPARE) { pt_debug(cd->dev, DL_INFO, "%s: Suspend prepare\n", __func__); @@ -12176,12 +10854,13 @@ _retry: pt_debug(cd->dev, DL_INFO, ">>> %s: Write Buffer Size[%d] Stay in BL\n", __func__, (int)sizeof(host_mode_cmd)); + pt_pr_buf(cd->dev, DL_DEBUG, host_mode_cmd, (int)sizeof(host_mode_cmd), ">>> User CMD"); rc = 1; while (rc && time < 34) { rc = pt_adap_write_read_specific(cd, 4, - host_mode_cmd, NULL, 0); + host_mode_cmd, NULL); usleep_range(1800, 2000); time += 2; } @@ -12274,7 +10953,7 @@ exit: } } - pt_debug(dev, DL_INFO, "%s: Flashless Auto_BL - %s\n", __func__, + pt_debug(dev, DL_INFO, "%s Flashless Auto_BL - %s\n", __func__, saved_flashless_auto_bl_mode == PT_ALLOW_AUTO_BL ? "ALLOW" : "SUPPRESS"); cd->flashless_auto_bl = saved_flashless_auto_bl_mode; @@ -12300,47 +10979,34 @@ exit: ******************************************************************************/ int _pt_pip2_file_open(struct device *dev, u8 file_no) { - int rc = 0; + int ret = 0; u16 status; u16 actual_read_len; u8 file_handle; u8 data[2]; u8 read_buf[10]; - u8 expected_len = pt_pip2_get_cmd_response_len(PIP2_CMD_ID_FILE_OPEN); pt_debug(dev, DL_DEBUG, "%s: OPEN file %d\n", __func__, file_no); data[0] = file_no; - rc = _pt_request_pip2_send_cmd(dev, + ret = _pt_request_pip2_send_cmd(dev, PT_CORE_CMD_UNPROTECTED, PIP2_CMD_ID_FILE_OPEN, data, 1, read_buf, &actual_read_len); - if (rc) { + if (ret) { pt_debug(dev, DL_ERROR, - "%s: FILE_OPEN timeout for file=%d\n", + "%s ROM BL FILE_OPEN timeout for file = %d\n", __func__, file_no); return -PIP2_RSP_ERR_NOT_OPEN; } status = read_buf[PIP2_RESP_STATUS_OFFSET]; - if (rc || ((status != PIP2_RSP_ERR_NONE) && - (status != PIP2_RSP_ERR_ALREADY_OPEN))) { + file_handle = read_buf[PIP2_RESP_BODY_OFFSET]; + if (ret || ((status != 0x00) && (status != 0x03)) || + (file_handle != file_no)) { pt_debug(dev, DL_ERROR, - "%s: %s 0x%02X for file=%d\n", - __func__, "FILE_OPEN failure:", status, file_no); - return -status; - } else if (actual_read_len == expected_len) { - /* File_open returned a file handle */ - file_handle = read_buf[PIP2_RESP_BODY_OFFSET]; - if (file_handle != file_no) { - pt_debug(dev, DL_ERROR, - "%s: %s 0x%02X file=%d returned handle=%d\n", - __func__, "FILE_OPEN failure:", - status, file_no, file_handle); - return -status; - } - } else { + "%s ROM BL FILE_OPEN failure: 0x%02X for file = %d\n", + __func__, status, file_handle); return -status; } - return file_handle; } @@ -12390,25 +11056,24 @@ int _pt_pip2_file_close(struct device *dev, u8 file_handle) } /******************************************************************************* - * FUNCTION: _pt_pip2_file_erase_by_file_no + * FUNCTION: _pt_pip2_file_erase * - * SUMMARY: Using the BL PIP2 commands erase a file by file number only. + * SUMMARY: Using the BL PIP2 commands erase a file * - * NOTE: The DUT must be in BL mode for this command to work - * NOTE: Some FLASH parts can time out while erasing one or more sectors, - * one retry is attempted for each sector in a file. + * NOTE: The DUT must be in BL mode for this command to work + * NOTE: Some FLASH parts can time out while erasing one or more sectors, + * one retry is attempted for each sector in a file. * * RETURNS: - * <0 = Error - * >0 = file handle closed + * <0 = Error + * >0 = file handle closed * * PARAMETERS: - * *dev - pointer to device structure - * file_handle - handle to the file to be erased - * *status - PIP2 erase status code + * *dev - pointer to device structure + * file_handle - handle to the file to be erased + * *status - PIP2 erase status code ******************************************************************************/ -int _pt_pip2_file_erase_by_file_no(struct device *dev, u8 file_handle, - int *status) +static int _pt_pip2_file_erase(struct device *dev, u8 file_handle, int *status) { int ret = 0; int max_retry = PT_PIP2_MAX_FILE_SIZE/PT_PIP2_FILE_SECTOR_SIZE; @@ -12463,129 +11128,6 @@ int _pt_pip2_file_erase_by_file_no(struct device *dev, u8 file_handle, return file_handle; } -/******************************************************************************* - * FUNCTION: _pt_pip2_file_erase_by_file_sector - * - * SUMMARY: Using the BL PIP2 commands erase a file sector by sector. - * - * NOTE: The DUT must be in BL mode for this command to work - * NOTE: Some FLASH parts can time out while erasing one or more sectors, - * one retry is attempted for each sector in a file. - * - * RETURNS: - * <0 = Error - * >0 = file handle closed - * - * PARAMETERS: - * *dev - pointer to device structure - * file_handle - handle to the file to be erased - * file_sector - Number of sectors to erase - * *status - PIP2 erase status code - ******************************************************************************/ -int _pt_pip2_file_erase_by_file_sector(struct device *dev, u8 file_handle, - u16 file_sector, int *status) -{ - int ret = 0, index = 0; - int max_retry = 3; - int retry = 0; - int tmp_status = PIP2_RSP_ERR_NONE; - u16 sector_to_erase = 1; - u16 actual_read_len; - u8 data[6]; - u8 read_buf[10]; - struct pt_core_data *cd = dev_get_drvdata(dev); - - pt_debug(dev, DL_DEBUG, "%s: ERASE file=%d, sector=%d\n", __func__, - file_handle, file_sector); - data[0] = file_handle; - data[1] = PIP2_FILE_IOCTL_CODE_ERASE_FILE; - /* Set how many sectors to erase*/ - data[4] = LOW_BYTE(sector_to_erase); - data[5] = HI_BYTE(sector_to_erase); - - /* Increase waiting time for large file erase */ - mutex_lock(&cd->system_lock); - cd->pip_cmd_timeout = PT_PIP2_CMD_FILE_SECTOR_ERASE_TIMEOUT; - mutex_unlock(&cd->system_lock); - for (retry = 0; retry < max_retry; retry++) { - for (index = 0; index < file_sector; index++) { - /* Initialize status code */ - tmp_status = PIP2_RSP_ERR_NONE; - /* Set which sector starts to erase */ - data[2] = LOW_BYTE(index); - data[3] = HI_BYTE(index); - ret = _pt_request_pip2_send_cmd(dev, - PT_CORE_CMD_UNPROTECTED, PIP2_CMD_ID_FILE_IOCTL, - data, 6, read_buf, &actual_read_len); - - tmp_status = read_buf[PIP2_RESP_STATUS_OFFSET]; - if (ret || tmp_status != PIP2_RSP_ERR_NONE) - break; - } - /* - * Only retry if response doesn't arrive or the status code is - * PIP2_RSP_ERR_TIMEOUT. - */ - if ((ret != -ETIME) || (tmp_status != PIP2_RSP_ERR_TIMEOUT)) - break; - else { -#ifdef TTDL_DIAGNOSTICS - cd->file_erase_timeout_count++; -#endif - pt_debug(dev, DL_WARN, - "%s: ERASE timeout %d for file=%d, sector=%d\n", - __func__, retry, file_handle, index); - } - } - - mutex_lock(&cd->system_lock); - *status = tmp_status; - cd->pip_cmd_timeout = cd->pip_cmd_timeout_default; - mutex_unlock(&cd->system_lock); - if (ret) { - pt_debug(dev, DL_ERROR, - "%s ROM FILE_ERASE cmd failure: %d for file=%d, sector=%d\n", - __func__, ret, file_handle, index); - return -EIO; - } - - if (*status != 0x00) { - pt_debug(dev, DL_ERROR, - "%s ROM FILE_ERASE failure: 0x%02X for file=%d, sector=%d\n", - __func__, *status, file_handle, index); - return -EIO; - } - return file_handle; -} - -/******************************************************************************* - * FUNCTION: _pt_pip2_file_erase - * - * SUMMARY: Wrapper function to call _pt_pip2_file_erase_by_file_sector() and - * _pt_pip2_file_erase_by_file_no() by checking file_sector. - * - * NOTE: If the file_sector is 0, it will erase the entire file. - * - * RETURNS: - * <0 = Error - * >0 = file handle closed - * - * PARAMETERS: - * *dev - pointer to device structure - * file_handle - handle to the file to be erased - * file_sector - Number of sectors to erase - * *status - PIP2 erase status code - ******************************************************************************/ -int _pt_pip2_file_erase(struct device *dev, u8 file_handle, u16 file_sector, - int *status) -{ - if (file_sector) - return _pt_pip2_file_erase_by_file_sector(dev, file_handle, - file_sector, status); - else - return _pt_pip2_file_erase_by_file_no(dev, file_handle, status); -} - /******************************************************************************* * FUNCTION: _pt_pip2_file_read * @@ -12613,6 +11155,7 @@ int _pt_pip2_file_read(struct device *dev, u8 file_handle, u16 num_bytes, data[0] = file_handle; data[1] = (num_bytes & 0x00FF); data[2] = (num_bytes & 0xFF00) >> 8; + ret = _pt_request_pip2_send_cmd(dev, PT_CORE_CMD_UNPROTECTED, PIP2_CMD_ID_FILE_READ, data, 3, read_buf, &actual_read_len); @@ -12621,7 +11164,7 @@ int _pt_pip2_file_read(struct device *dev, u8 file_handle, u16 num_bytes, pt_debug(dev, DL_ERROR, "%s File open failure with error code = %d\n", __func__, status); - return -1; + return -EPERM; } ret = num_bytes; @@ -12657,14 +11200,13 @@ int _pt_read_us_file(struct device *dev, u8 *file_path, u8 *buf, int *size) pt_debug(dev, DL_ERROR, "%s: path || buf is NULL.\n", __func__); return -EINVAL; } - pt_debug(dev, DL_WARN, "%s: path = %s\n", __func__, file_path); oldfs = get_fs(); set_fs(KERNEL_DS); filp = filp_open(file_path, O_RDONLY, 0400); if (IS_ERR(filp)) { - pt_debug(dev, DL_WARN, "%s: Failed to open %s\n", __func__, + pt_debug(dev, DL_ERROR, "%s: Failed to open %s\n", __func__, file_path); rc = -ENOENT; goto err; @@ -12703,12 +11245,7 @@ int _pt_read_us_file(struct device *dev, u8 *file_path, u8 *buf, int *size) goto exit; } filp->private_data = inode->i_private; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)) - if (kernel_read(filp, buf, read_len, &(filp->f_pos)) != read_len) { -#else if (vfs_read(filp, buf, read_len, &(filp->f_pos)) != read_len) { -#endif pt_debug(dev, DL_ERROR, "%s: file read error.\n", __func__); rc = -EINVAL; goto exit; @@ -12755,7 +11292,7 @@ int _pt_request_pip2_bin_hdr(struct device *dev, struct pt_bin_file_hdr *hdr) read_buf, &read_size); if (rc) { ret = rc; - pt_debug(dev, DL_WARN, + pt_debug(dev, DL_ERROR, "%s Failed to read fw image from US, rc=%d\n", __func__, rc); goto exit; @@ -13098,7 +11635,6 @@ ping_test_exit: return rc; } -#ifndef TTDL_KERNEL_SUBMISSION /******************************************************************************* * FUNCTION: _pt_ic_parse_input_hex * @@ -13301,7 +11837,6 @@ static int _pt_ic_parse_input(struct device *dev, error: return ret; } -#endif /* !TTDL_KERNEL_SUBMISSION */ #ifdef TTHE_TUNER_SUPPORT /******************************************************************************* @@ -13327,7 +11862,6 @@ static int tthe_debugfs_open(struct inode *inode, struct file *filp) u32 buf_size = PT_MAX_PRBUF_SIZE; filp->private_data = inode->i_private; - if (cd->tthe_buf) return -EBUSY; @@ -13363,91 +11897,12 @@ static int tthe_debugfs_close(struct inode *inode, struct file *filp) struct pt_core_data *cd = filp->private_data; filp->private_data = NULL; - kfree(cd->tthe_buf); cd->tthe_buf = NULL; return 0; } -/******************************************************************************* - * FUNCTION: tthe_debugfs_store - * - * SUMMARY: Write method for tthe_tuner debugfs node. This function allows - * user configuration of some output values via a bitmask. - * 0x01 = HID USB vs I2C output - * 0xFE = Reserved - * - * RETURN: Size of debugfs data write - * - * PARAMETERS: - * *filp - file pointer to debugfs file - * *buf - the user space buffer to read to - * count - the maximum number of bytes to read - * *ppos - the current position in the buffer - ******************************************************************************/ -static ssize_t tthe_debugfs_store(struct file *filp, const char __user *buf, - size_t count, loff_t *ppos) -{ - struct pt_core_data *cd = filp->private_data; - ssize_t length; - u32 input_data[2]; - u8 tmp_buf[4]; /* large enough for 1 32bit value */ - int rc = 0; - - mutex_lock(&cd->tthe_lock); - - /* copy data from user space */ - rc = simple_write_to_buffer(tmp_buf, sizeof(tmp_buf), - ppos, buf, count); - if (rc < 0) - goto exit; - - length = _pt_ic_parse_input(cd->dev, tmp_buf, count, - input_data, ARRAY_SIZE(input_data)); - - if (length == 1) { - mutex_lock(&(cd->system_lock)); - cd->tthe_hid_usb_format = input_data[0]; - if (input_data[0] == PT_TTHE_TUNER_FORMAT_HID_USB) - pt_debug(cd->dev, DL_INFO, - "%s: Enable tthe_tuner HID-USB format\n", - __func__); - else if (input_data[0] == PT_TTHE_TUNER_FORMAT_HID_I2C) - pt_debug(cd->dev, DL_INFO, - "%s: Enable tthe_tuner HID-I2C format\n", - __func__); - else if (input_data[0] == - PT_TTHE_TUNER_FORMAT_HID_FINGER_TO_PIP) - pt_debug(cd->dev, DL_INFO, - "%s: Enable tthe_tuner HID-FINGER-TO-PIP format\n", - __func__); - else if (input_data[0] == - PT_TTHE_TUNER_FORMAT_HID_FINGER_AND_PEN_TO_PIP) - pt_debug(cd->dev, DL_INFO, - "%s: Enable tthe_tuner HID_FINGER_AND_PEN_TO_PIP format\n", - __func__); - else { - rc = -EINVAL; - pt_debug(cd->dev, DL_ERROR, - "%s: Invalid parameter: %d\n", - __func__, input_data[0]); - } - mutex_unlock(&(cd->system_lock)); - } else { - rc = -EINVAL; - pt_debug(cd->dev, DL_ERROR, - "%s: Invalid number of parameters\n", __func__); - } - -exit: - mutex_unlock(&cd->tthe_lock); - if (rc) - return rc; - else - return count; -} - /******************************************************************************* * FUNCTION: tthe_debugfs_read * @@ -13492,18 +11947,11 @@ static ssize_t tthe_debugfs_read(struct file *filp, char __user *buf, } else { ret = copy_to_user(buf, cd->tthe_buf, size); } - - /* - * When size >= tthe_buf_len setting partial_read will cause NULL - * characters to be printed in the output. - */ - if (size == count && size < cd->tthe_buf_len) + if (size == count) partial_read = count; - if (ret == size) { - mutex_unlock(&cd->tthe_lock); + if (ret == size) return -EFAULT; - } size -= ret; cd->tthe_buf_len -= size; mutex_unlock(&cd->tthe_lock); @@ -13515,7 +11963,6 @@ static const struct file_operations tthe_debugfs_fops = { .open = tthe_debugfs_open, .release = tthe_debugfs_close, .read = tthe_debugfs_read, - .write = tthe_debugfs_store, }; #endif @@ -13580,9 +12027,7 @@ static struct pt_core_commands _pt_core_commands = { .request_pip2_bin_hdr = _pt_request_pip2_bin_hdr, .request_dut_generation = _pt_request_dut_generation, .request_hw_version = _pt_request_hw_version, -#ifndef TTDL_KERNEL_SUBMISSION .parse_sysfs_input = _pt_ic_parse_input, -#endif #ifdef TTHE_TUNER_SUPPORT .request_tthe_print = _pt_request_tthe_print, #endif @@ -13692,7 +12137,7 @@ static void pt_probe_modules(struct pt_core_data *cd) mutex_lock(&module_list_lock); list_for_each_entry(m, &module_list, node) { - pt_debug(cd->dev, DL_WARN, "%s: Probe module %s\n", + pt_debug(cd->dev, DL_ERROR, "%s: Probe module %s\n", __func__, m->name); rc = pt_probe_module(cd, m); if (rc) @@ -13918,12 +12363,11 @@ static void pt_early_suspend(struct early_suspend *h) call_atten_cb(cd, PT_ATTEN_SUSPEND, 0); } - /******************************************************************************* * FUNCTION: pt_late_resume * * SUMMARY: Android PM architecture function that will call "PT_ATTEN_RESUME" - * attention list. + * attention list. * * PARAMETERS: * *h - pointer to early_suspend structure @@ -13952,6 +12396,112 @@ static void pt_setup_early_suspend(struct pt_core_data *cd) register_early_suspend(&cd->es); } +#elif defined(CONFIG_DRM) + +/******************************************************************************* + * FUNCTION: drm_notifier_callback + * + * SUMMARY: Call back function for DRM notifier to allow to call + * resume/suspend attention list. + * + * RETURN: + * 0 = success + * + * PARAMETERS: + * *self - pointer to notifier_block structure + * event - event type of fb notifier + * *data - pointer to fb_event structure + ******************************************************************************/ +static int drm_notifier_callback(struct notifier_block *self, + unsigned long event, void *data) +{ + struct pt_core_data *cd = + container_of(self, struct pt_core_data, fb_notifier); + struct drm_panel_notifier *evdata = data; + int *blank; + + pt_debug(cd->dev, DL_INFO, "%s: DRM notifier called!\n", __func__); + + if (!evdata) + goto exit; + + if (!(event == DRM_PANEL_EARLY_EVENT_BLANK || + event == DRM_PANEL_EVENT_BLANK)) { + pt_debug(cd->dev, DL_INFO, "%s: Event(%lu) do not need process\n", + __func__, event); + goto exit; + } + + blank = evdata->data; + pt_debug(cd->dev, DL_INFO, "%s: DRM event:%lu,blank:%d", __func__, event, *blank); + if (*blank == DRM_PANEL_BLANK_UNBLANK) { + pt_debug(cd->dev, DL_INFO, "%s: UNBLANK!\n", __func__); + if (event == DRM_PANEL_EARLY_EVENT_BLANK) { + pt_debug(cd->dev, DL_INFO, "%s: resume: event = %lu, not care\n", + __func__, event); + } else if (event == DRM_PANEL_EVENT_BLANK) { + if (cd->fb_state != FB_ON) { + call_atten_cb(cd, PT_ATTEN_RESUME, 0); +#if defined(CONFIG_PM_SLEEP) + pt_debug(cd->dev, DL_INFO, "%s: Resume notifier called!\n", + __func__); + if (cd->cpdata->flags & PT_CORE_FLAG_SKIP_RUNTIME) + pt_core_resume_(cd->dev); +#endif + cd->fb_state = FB_ON; + pt_debug(cd->dev, DL_INFO, "%s: Resume notified!\n", __func__); + } + } + } else if (*blank == DRM_PANEL_BLANK_LP) { + pt_debug(cd->dev, DL_INFO, "%s: LOWPOWER!\n", __func__); + if (event == DRM_PANEL_EARLY_EVENT_BLANK) { + if (cd->fb_state != FB_OFF) { +#if defined(CONFIG_PM_SLEEP) + pt_debug(cd->dev, DL_INFO, "%s: Suspend notifier called!\n", + __func__); + if (cd->cpdata->flags & PT_CORE_FLAG_SKIP_RUNTIME) + pt_core_suspend_(cd->dev); +#endif + call_atten_cb(cd, PT_ATTEN_SUSPEND, 0); + cd->fb_state = FB_OFF; + pt_debug(cd->dev, DL_INFO, "%s: Suspend notified!\n", __func__); + } + } else if (event == DRM_PANEL_EVENT_BLANK) { + pt_debug(cd->dev, DL_INFO, "%s: suspend: event = %lu, not care\n", + __func__, event); + } + } else { + pt_debug(cd->dev, DL_INFO, "%s: DRM BLANK(%d) do not need process\n", + __func__, *blank); + } +exit: + return 0; +} + +/******************************************************************************* + * FUNCTION: pt_setup_drm_notifier + * + * SUMMARY: Set up call back function into drm notifier. + * + * PARAMETERS: + * *cd - pointer to core data + ******************************************************************************/ +static void pt_setup_drm_notifier(struct pt_core_data *cd) +{ + cd->fb_state = FB_ON; + cd->fb_notifier.notifier_call = drm_notifier_callback; + pt_debug(cd->dev, DL_INFO, "%s: Setting up drm notifier\n", __func__); + + if (!active_panel) + pt_debug(cd->dev, DL_ERROR, + "%s: Active panel not registered!\n", __func__); + + if (active_panel && + drm_panel_notifier_register(active_panel, + &cd->fb_notifier) < 0) + pt_debug(cd->dev, DL_ERROR, + "%s: Register notifier failed!\n", __func__); +} #elif defined(CONFIG_FB) /******************************************************************************* * FUNCTION: fb_notifier_callback @@ -14018,7 +12568,6 @@ static void pt_setup_fb_notifier(struct pt_core_data *cd) int rc = 0; cd->fb_state = FB_ON; - cd->fb_notifier.notifier_call = fb_notifier_callback; rc = fb_register_client(&cd->fb_notifier); @@ -14054,7 +12603,6 @@ static void pt_watchdog_work(struct work_struct *work) int rc = 0; struct pt_core_data *cd = container_of(work, struct pt_core_data, watchdog_work); - /* * if found the current sleep_state is SS_SLEEPING * then no need to request_exclusive, directly return @@ -14081,7 +12629,7 @@ static void pt_watchdog_work(struct work_struct *work) cd->watchdog_irq_stuck_count++; pt_toggle_err_gpio(cd, PT_ERR_GPIO_IRQ_STUCK); #endif /* TTDL_DIAGNOSTICS */ - pt_debug(cd->dev, DL_WARN, + pt_debug(cd->dev, DL_ERROR, "%s: TTDL WD found IRQ asserted, attempt to clear\n", __func__); pt_flush_bus(cd, PT_FLUSH_BUS_BASED_ON_LEN, NULL); @@ -14145,7 +12693,7 @@ queue_startup: } #ifdef TTDL_DIAGNOSTICS cd->wd_xres_count++; - pt_debug(cd->dev, DL_WARN, + pt_debug(cd->dev, DL_ERROR, "%s: Comm Failed - DUT reset [#%d]\n", __func__, cd->wd_xres_count); #endif /* TTDL_DIAGNOSTICS */ @@ -14154,7 +12702,7 @@ queue_startup: * After trying PT_WATCHDOG_RETRY_COUNT times to * reset the part to regain communications, try to BL */ - pt_debug(cd->dev, DL_WARN, + pt_debug(cd->dev, DL_ERROR, "%s: WD DUT access failure, Start FW Upgrade\n", __func__); #ifdef TTDL_DIAGNOSTICS @@ -14181,7 +12729,7 @@ queue_startup: mutex_unlock(&cd->system_lock); if (cd->active_dut_generation == DUT_UNKNOWN) { - pt_debug(cd->dev, DL_WARN, + pt_debug(cd->dev, DL_ERROR, "%s: Queue Restart\n", __func__); pt_queue_restart(cd); } else @@ -14191,7 +12739,7 @@ queue_startup: cd->hw_detected = true; if (cd->startup_status <= (STARTUP_STATUS_FW_RESET_SENTINEL | STARTUP_STATUS_BL_RESET_SENTINEL)) { - pt_debug(cd->dev, DL_WARN, + pt_debug(cd->dev, DL_ERROR, "%s: HW detected but not enumerated\n", __func__); pt_queue_enum(cd); @@ -14217,7 +12765,6 @@ exit: static void pt_watchdog_timer(unsigned long handle) { struct pt_core_data *cd = (struct pt_core_data *)handle; - if (!cd) return; @@ -14242,7 +12789,6 @@ static void pt_watchdog_timer(unsigned long handle) static void pt_watchdog_timer(struct timer_list *t) { struct pt_core_data *cd = from_timer(cd, t, watchdog_timer); - if (!cd) return; @@ -14254,65 +12800,6 @@ static void pt_watchdog_timer(struct timer_list *t) } #endif -#ifdef PT_PTSBC_SUPPORT -/* Required to support the Parade Techologies Development Platform */ -static int pt_probe_complete(struct pt_core_data *cd); - -/******************************************************************************* - * FUNCTION: pt_probe_work - * - * SUMMARY: For the PtSBC the probe functionality is split into two functions; - * pt_probe() and pt_probe_complete() which is called from here. - * This function is scheduled as a "work" task in order to launch after - * I2C/SPI is up. - * - * RETURN: Void - * - * PARAMETERS: - * *work - pointer to work structure - ******************************************************************************/ -static void pt_probe_work(struct work_struct *work) -{ - struct pt_core_data *cd = - container_of(work, struct pt_core_data, - probe_work); - int rc; - - rc = pt_probe_complete(cd); - - if (rc < 0) - pr_err("%s: Probe_complete returns rc=%d\n", __func__, rc); - else - pt_debug(cd->dev, DL_INFO, - "%s: Probe_complete returns rc=%d\n", __func__, rc); -} - -/******************************************************************************* - * FUNCTION: pt_probe_timer - * - * SUMMARY: For the PtSBC the probe functionality is split into two functions; - * pt_probe() and pt_probe_complete(). This timer shedules the - * probe_work function. - * - * RETURN: Void - * - * PARAMETERS: - * handle - pointer to the core data - ******************************************************************************/ -static void pt_probe_timer(unsigned long handle) -{ - struct pt_core_data *cd = (struct pt_core_data *)handle; - - if (!cd) - return; - - pt_debug(cd->dev, DL_INFO, "%s: Watchdog timer triggered\n", - __func__); - - if (!work_pending(&cd->probe_work)) - schedule_work(&cd->probe_work); -} -#endif /* --- End PT_PTSBC_SUPPORT --- */ @@ -14337,9 +12824,8 @@ static ssize_t pt_hw_version_show(struct device *dev, struct device_attribute *attr, char *buf) { struct pt_core_data *cd = dev_get_drvdata(dev); - _pt_request_hw_version(dev, cd->hw_version); - return snprintf(buf, PT_MAX_PRBUF_SIZE, "%s\n", cd->hw_version); + return scnprintf(buf, PT_MAX_PRBUF_SIZE, "%s\n", cd->hw_version); } static DEVICE_ATTR(hw_version, 0444, pt_hw_version_show, NULL); @@ -14359,7 +12845,7 @@ static DEVICE_ATTR(hw_version, 0444, pt_hw_version_show, NULL); static ssize_t pt_drv_version_show(struct device *dev, struct device_attribute *attr, char *buf) { - return snprintf(buf, PT_MAX_PRBUF_SIZE, + return scnprintf(buf, PT_MAX_PRBUF_SIZE, "Driver: %s\nVersion: %s\nDate: %s\n", pt_driver_core_name, pt_driver_core_version, pt_driver_core_date); @@ -14537,7 +13023,6 @@ static ssize_t pt_sysinfo_show(struct device *dev, } static DEVICE_ATTR(sysinfo, 0444, pt_sysinfo_show, NULL); -#ifndef TTDL_KERNEL_SUBMISSION /******************************************************************************* * FUNCTION: pt_hw_reset_show * @@ -14590,7 +13075,7 @@ static ssize_t pt_hw_reset_show(struct device *dev, t = wait_event_timeout(cd->wait_q, (cd->fw_updating == true), msecs_to_jiffies(200)); if (IS_TMO(t)) { - pt_debug(dev, DL_WARN, + pt_debug(dev, DL_ERROR, "%s: Timeout waiting for FW update", __func__); rc = -ETIME; @@ -14611,7 +13096,7 @@ static ssize_t pt_hw_reset_show(struct device *dev, } } else { /* Wait for any sentinel */ - rc = _pt_request_wait_for_enum_state(dev, 250, + rc = _pt_request_wait_for_enum_state(dev, 150, STARTUP_STATUS_BL_RESET_SENTINEL | STARTUP_STATUS_FW_RESET_SENTINEL); if (rc) { @@ -14726,7 +13211,7 @@ static ssize_t pt_pip2_cmd_rsp_store(struct device *dev, length = _pt_ic_parse_input_hex(dev, buf, size, input_data, PT_MAX_PIP2_MSG_SIZE); if (length <= 0 || length > PT_MAX_PIP2_MSG_SIZE) { - pt_debug(dev, DL_WARN, "%s: Invalid number of arguments\n", + pt_debug(dev, DL_ERROR, "%s: Invalid number of arguments\n", __func__); rc = -EINVAL; goto exit; @@ -14749,7 +13234,7 @@ static ssize_t pt_pip2_cmd_rsp_store(struct device *dev, } else { cd->cmd_rsp_buf_len = actual_read_len; memcpy(cd->cmd_rsp_buf, read_buf, actual_read_len); - pt_debug(dev, DL_WARN, + pt_debug(dev, DL_ERROR, "%s: PIP2 actual_read_len = %d\n", __func__, actual_read_len); } @@ -14834,9 +13319,6 @@ static ssize_t pt_command_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct pt_core_data *cd = dev_get_drvdata(dev); -#ifdef TTDL_PTVIRTDUT_SUPPORT - struct pt_hid_output hid_output; -#endif unsigned short crc; u16 actual_read_len; u8 input_data[PT_MAX_PIP2_MSG_SIZE + 1]; @@ -14852,45 +13334,12 @@ static ssize_t pt_command_store(struct device *dev, length = _pt_ic_parse_input_hex(dev, buf, size, input_data, PT_MAX_PIP2_MSG_SIZE); if (length <= 0 || length > PT_MAX_PIP2_MSG_SIZE) { - pt_debug(dev, DL_WARN, "%s: Invalid number of arguments\n", + pt_debug(dev, DL_ERROR, "%s: Invalid number of arguments\n", __func__); rc = -EINVAL; goto pt_command_store_exit; } - /* Get HID Desc */ - if (length == 2 && input_data[0] == 0x01 && input_data[1] == 0x00) { - pm_runtime_get_sync(dev); - rc = pt_get_hid_descriptor(cd, &cd->hid_desc); - mutex_lock(&cd->sysfs_lock); - if (!rc) { - cd->cmd_rsp_buf_len = - get_unaligned_le16(&cd->response_buf[0]); - memcpy(cd->cmd_rsp_buf, cd->response_buf, - cd->cmd_rsp_buf_len); - } - cd->raw_cmd_status = rc; - mutex_unlock(&cd->sysfs_lock); - pm_runtime_put(dev); - goto pt_command_store_exit; - } - - /* Get Report Desc */ - if (length == 2 && input_data[0] == 0x02 && input_data[1] == 0x00) { - pm_runtime_get_sync(dev); - rc = pt_get_report_descriptor(cd); - mutex_lock(&cd->sysfs_lock); - if (!rc) { - cd->cmd_rsp_buf_len = cd->hid_core.hid_report_desc_len; - memcpy(cd->cmd_rsp_buf, cd->response_buf, - cd->cmd_rsp_buf_len); - } - cd->raw_cmd_status = rc; - mutex_unlock(&cd->sysfs_lock); - pm_runtime_put(dev); - goto pt_command_store_exit; - } - /* PIP2 messages begin with 01 01 */ if (length >= 2 && input_data[0] == 0x01 && input_data[1] == 0x01) { cd->pip2_prot_active = 1; @@ -14901,7 +13350,7 @@ static ssize_t pt_command_store(struct device *dev, if (len_field == length && length <= 254) { crc = crc_ccitt_calculate(&input_data[2], length - 2); - pt_debug(dev, DL_WARN, "%s: len=%d crc=0x%02X\n", + pt_debug(dev, DL_ERROR, "%s: len=%d crc=0x%02X\n", __func__, length, crc); input_data[length] = (crc & 0xFF00) >> 8; input_data[length + 1] = crc & 0x00FF; @@ -14914,19 +13363,6 @@ static ssize_t pt_command_store(struct device *dev, pm_runtime_get_sync(dev); -#ifdef TTDL_PTVIRTDUT_SUPPORT - /* Special case for handling Virtual DUT exit */ - if (length >= 3 && - input_data[0] == 0xFF && - input_data[1] == 0xFF && - input_data[2] == 0x00) { - hid_output.length = length, - hid_output.write_buf = input_data, - rc = pt_hid_send_output_user_(cd, &hid_output); - pm_runtime_put(dev); - goto pt_command_store_exit; - } -#endif rc = pt_hid_output_user_cmd(cd, PT_MAX_INPUT, cd->cmd_rsp_buf, length, input_data, &actual_read_len); pm_runtime_put(dev); @@ -14958,105 +13394,38 @@ static DEVICE_ATTR(command, 0220, NULL, pt_command_store); * available to be read here. * * PARAMETERS: - * *filp - pointer to file structure - * *kobj - pointer to kobject structure - * *bin_attr - pointer to bin_attribute structure - * buf - pointer to cmd input buffer - * offset - offset index to store input buffer - * count - size of data in buffer + * *dev - pointer to Device structure + * *attr - pointer to the device attribute structure + * *buf - pointer to buffer to print ******************************************************************************/ -static ssize_t pt_response_show(struct file *filp, - struct kobject *kobj, struct bin_attribute *bin_attr, - char *buf, loff_t offset, size_t count) +static ssize_t pt_response_show(struct device *dev, + struct device_attribute *attr, char *buf) { - struct device *dev = container_of(kobj, struct device, kobj); struct pt_core_data *cd = dev_get_drvdata(dev); - static int pr_left; - static int pr_index; - static u8 *pr_buf; - int i = 0; - int index = 0; - int rc = 0; - int print_len = 0; + int i; + ssize_t num_read; + int index; - if (pr_left) { - if (count < pr_left) { - index = count; - memcpy(buf, pr_buf + pr_index, index); - pr_left -= count; - pr_index += count; - } else { - index = pr_left; - memcpy(buf, pr_buf + pr_index, index); - pr_left = 0; - pr_index = 0; - kfree(pr_buf); - } - return index; - } + mutex_lock(&cd->sysfs_lock); + index = scnprintf(buf, PT_MAX_PRBUF_SIZE, + "Status: %d\n", cd->raw_cmd_status); + if (cd->raw_cmd_status) + goto error; - if (offset == 0) { - mutex_lock(&cd->sysfs_lock); - if (cd->raw_cmd_status) { - index = scnprintf(buf, PT_MAX_PRBUF_SIZE, - "Status: %d\n", cd->raw_cmd_status); - mutex_unlock(&cd->sysfs_lock); - return index; - } + num_read = cd->cmd_rsp_buf_len; + for (i = 0; i < num_read; i++) + index += scnprintf(buf + index, PT_MAX_PRBUF_SIZE - index, + "0x%02X\n", cd->cmd_rsp_buf[i]); - /* - * Allocate memory according to the cost, each byte need 5 - * character, and extra 100 bytes for the header and tail. - */ - if (cd->cmd_rsp_buf_len > PT_MAX_INPUT) { - rc = -EINVAL; - goto exit; - } - print_len = cd->cmd_rsp_buf_len * 5 + 100; - pr_buf = kzalloc(print_len, GFP_KERNEL); - if (!pr_buf) { - rc = -ENOMEM; - goto exit; - } + index += scnprintf(buf + index, PT_MAX_PRBUF_SIZE - index, + "(%zd bytes)\n", num_read); - /* Format all data to pr_buf */ - index = scnprintf(pr_buf, print_len - index, "Status: %d\n", - cd->raw_cmd_status); - for (i = 0; i < cd->cmd_rsp_buf_len; i++) - index += scnprintf(pr_buf + index, - print_len - index, "0x%02X\n", - cd->cmd_rsp_buf[i]); - index += scnprintf(pr_buf + index, print_len - index, - "(%zd bytes)\n", cd->cmd_rsp_buf_len); - - mutex_unlock(&cd->sysfs_lock); - - if (count < index) { - memcpy(buf, pr_buf, count); - pr_left = index - count; - pr_index = count; - index = count; - } else { - memcpy(buf, pr_buf, index); - pr_left = 0; - pr_index = 0; - kfree(pr_buf); - } - return index; - } - -exit: +error: mutex_unlock(&cd->sysfs_lock); - return rc; + return index; } +static DEVICE_ATTR(response, 0444, pt_response_show, NULL); -static struct bin_attribute bin_attr_pt_response = { - .attr = { - .name = "response", - .mode = (0444), - }, - .read = pt_response_show, -}; /******************************************************************************* * FUNCTION: pt_dut_debug_show * @@ -15097,7 +13466,6 @@ static ssize_t pt_dut_debug_show(struct device *dev, "%d %s \t- %s\n" "%d %s \t- %s\n" "%d %s \t- %s\n" - "%d %s \t- %s\n" , PIP1_BL_CMD_ID_VERIFY_APP_INTEGRITY, "", "BL Verify APP", PT_DUT_DBG_HID_RESET, "", "HID Reset", @@ -15115,8 +13483,7 @@ static ssize_t pt_dut_debug_show(struct device *dev, PT_DUT_DBG_HID_SYSINFO, "", "HID system info", PT_DUT_DBG_PIP_SUSPEND_SCAN, "", "Suspend Scan", PT_DUT_DBG_PIP_RESUME_SCAN, "", "Resume Scan", - PT_DUT_DBG_HID_DESC, "", "Get HID Desc", - PT_DUT_DBG_REPORT_DESC, "", "Get HID Report Desc" + PT_DUT_DBG_HID_DESC, "", "Get HID Desc" ); return ret; @@ -15171,6 +13538,7 @@ static ssize_t pt_drv_debug_show(struct device *dev, "%d %s \t- %s\n" "%d %s \t- %s\n" "%d %s \t- %s\n" + "%d %s \t- %s\n" #endif /* TTDL_DIAGNOSTICS */ , PT_DRV_DBG_SUSPEND, " ", "Suspend TTDL responding to INT", @@ -15198,8 +13566,10 @@ static ssize_t pt_drv_debug_show(struct device *dev, PT_DRV_DBG_SET_FORCE_SEQ, "[8-15]", "Force PIP2 Sequence #", PT_DRV_DBG_BL_WITH_NO_INT, "[0|1]", "BL with no INT", PT_DRV_DBG_CAL_CACHE_IN_HOST, "[0|1]", "CAL Cache in host", - PT_DRV_DBG_NUM_DEVICES, "[1-255]", "Number of Devices", - PT_DRV_DBG_PIP_TIMEOUT, "[100-7000]", "PIP Resp Timeout (ms)" + PT_DRV_DBG_MULTI_CHIP, "[0|1]", "Multi Chip Support", + PT_DRV_DBG_PIP_TIMEOUT, "[100-7000]", "PIP Resp Timeout (ms)", + PT_DRV_DBG_TTHE_HID_USB_FORMAT, "[0|1]", + "TTHE_TUNER HID USB Format" #endif /* TTDL_DIAGNOSTICS */ ); @@ -15243,7 +13613,6 @@ static ssize_t pt_drv_debug_store(struct device *dev, unsigned short crc = 0; u16 cal_size; #endif - input_data[0] = 0; input_data[1] = 0; @@ -15251,7 +13620,7 @@ static ssize_t pt_drv_debug_store(struct device *dev, length = _pt_ic_parse_input(dev, buf, size, input_data, ARRAY_SIZE(input_data)); if (length < 1 || length > 2) { - pt_debug(dev, DL_WARN, "%s: Invalid number of arguments\n", + pt_debug(dev, DL_ERROR, "%s: Invalid number of arguments\n", __func__); rc = -EINVAL; goto pt_drv_debug_store_exit; @@ -15432,14 +13801,7 @@ static ssize_t pt_drv_debug_store(struct device *dev, "%s: CAL Cleared, Chip ID=0x%04X size=%d\n", __func__, crc, size); break; - case PT_DUT_DBG_REPORT_DESC: /* 113 */ - rc = pt_get_report_descriptor(cd); - if (rc != 0) { - pt_debug(cd->dev, DL_ERROR, - "%s: Error on getting report descriptor r=%d\n", - __func__, rc); - } - break; + case PT_DRV_DBG_REPORT_LEVEL: /* 200 */ mutex_lock(&cd->system_lock); if (input_data[1] >= 0 && input_data[1] < DL_MAX) { @@ -15510,11 +13872,11 @@ static ssize_t pt_drv_debug_store(struct device *dev, case PT_DRV_DBG_GET_PUT_SYNC: /* 206 */ if (input_data[1] == 0) { pm_runtime_put(dev); - pt_debug(dev, DL_WARN, + pt_debug(dev, DL_ERROR, "%s: Force call pm_runtime_put()\n", __func__); } else if (input_data[1] == 1) { pm_runtime_get_sync(dev); - pt_debug(dev, DL_WARN, + pt_debug(dev, DL_ERROR, "%s: Force call pm_runtime_get_sync()\n", __func__); } else { @@ -15676,25 +14038,18 @@ static ssize_t pt_drv_debug_store(struct device *dev, } mutex_unlock(&(cd->system_lock)); break; - case PT_DRV_DBG_NUM_DEVICES: /* 217 */ + case PT_DRV_DBG_MULTI_CHIP: /* 217 */ mutex_lock(&cd->system_lock); if (input_data[1] == 0) { - /* 0 is not supported */ - rc = -EINVAL; - pt_debug(dev, DL_ERROR, "%s: Invalid parameter: %d\n", - __func__, input_data[1]); - } else if (input_data[1] == 1) { - cd->num_devices = input_data[1]; + cd->multi_chip = PT_FEATURE_DISABLE; cd->ttdl_bist_select = 0x07; pt_debug(dev, DL_INFO, - "%s: Multi-chip support Disabled\n", __func__); - } else if (input_data[1] > 1 && - input_data[1] <= PT_MAX_DEVICES) { - cd->num_devices = input_data[1]; + "%s: Disable Multi-chip support\n", __func__); + } else if (input_data[1] == 1) { + cd->multi_chip = PT_FEATURE_ENABLE; cd->ttdl_bist_select = 0x3F; pt_debug(dev, DL_INFO, - "%s: Multi-chip support Enabled with %d DUTs\n", - __func__, cd->num_devices); + "%s: Enable Multi-chip support\n", __func__); } else { rc = -EINVAL; pt_debug(dev, DL_ERROR, "%s: Invalid parameter: %d\n", @@ -15707,12 +14062,11 @@ static ssize_t pt_drv_debug_store(struct device *dev, if (input_data[1] <= 0x07) { cd->panel_id_support = input_data[1]; pt_debug(dev, DL_INFO, - "%s: ATM - Set panel_id_support to %d\n", + "%s: Set panel_id_support to %d\n", __func__, cd->panel_id_support); } else { rc = -EINVAL; - pt_debug(dev, DL_ERROR, - "%s: ATM - Invalid parameter: %d\n", + pt_debug(dev, DL_ERROR, "%s: Invalid parameter: %d\n", __func__, input_data[1]); } mutex_unlock(&(cd->system_lock)); @@ -15728,73 +14082,34 @@ static ssize_t pt_drv_debug_store(struct device *dev, cd->pip_cmd_timeout_default = input_data[1]; cd->pip_cmd_timeout = input_data[1]; pt_debug(dev, DL_INFO, - "%s: ATM - PIP Timeout = %d\n", __func__, + "%s: PIP Timeout = %d\n", __func__, cd->pip_cmd_timeout_default); } else { rc = -EINVAL; - pt_debug(dev, DL_ERROR, - "%s: ATM - Invalid parameter: %d\n", + pt_debug(dev, DL_ERROR, "%s: Invalid parameter: %d\n", __func__, input_data[1]); } mutex_unlock(&(cd->system_lock)); break; - case PT_DRV_DBG_CORE_PLATFORM_FLAG: /* 220 */ + case PT_DRV_DBG_TTHE_HID_USB_FORMAT: /* 220 */ mutex_lock(&cd->system_lock); - if (cd->cpdata) { - cd->cpdata->flags = input_data[1]; - pt_debug(dev, DL_INFO, - "%s: ATM - Set core platform flag to 0x%02X\n", - __func__, input_data[1]); - } else { - rc = -EINVAL; - pt_debug(dev, DL_ERROR, "%s: No platform data\n", - __func__); - } - mutex_unlock(&cd->system_lock); - break; -#ifdef TTDL_PTVIRTDUT_SUPPORT - case PT_DRV_DBG_SET_HW_DETECT: /* 298 */ - mutex_lock(&cd->system_lock); - if (input_data[1]) - cd->hw_detect_enabled = true; - else - cd->hw_detect_enabled = false; - pt_debug(dev, DL_INFO, - "%s: Set hw_detect_enabled to %d\n", - __func__, cd->hw_detect_enabled); - mutex_unlock(&(cd->system_lock)); - break; - case PT_DRV_DBG_VIRTUAL_I2C_DUT: /* 299 */ if (input_data[1] == 0) { - /* Cancel all work threads when disabling */ - pt_debug(dev, DL_WARN, "%s: Canceling Work", __func__); -#ifdef PT_PTSBC_SUPPORT - cancel_work_sync(&cd->irq_work); - cancel_work_sync(&cd->probe_work); -#endif - cancel_work_sync(&cd->ttdl_restart_work); - cancel_work_sync(&cd->enum_work); - pt_stop_wd_timer(cd); - call_atten_cb(cd, PT_ATTEN_CANCEL_LOADER, 0); - - mutex_lock(&cd->system_lock); - cd->route_bus_virt_dut = 0; - mutex_unlock(&(cd->system_lock)); - pt_debug(dev, DL_WARN, "%s: Enable Virtual DUT mode\n", + cd->tthe_hid_usb_format = PT_FEATURE_DISABLE; + pt_debug(dev, DL_INFO, + "%s: Disable tthe_tuner HID-USB format\n", __func__); } else if (input_data[1] == 1) { - mutex_lock(&cd->system_lock); - cd->route_bus_virt_dut = 1; - mutex_unlock(&(cd->system_lock)); - pt_debug(dev, DL_WARN, "%s: Enable Virtual DUT mode\n", + cd->tthe_hid_usb_format = PT_FEATURE_ENABLE; + pt_debug(dev, DL_INFO, + "%s: Enable tthe_tuner HID-USB format\n", __func__); } else { rc = -EINVAL; pt_debug(dev, DL_ERROR, "%s: Invalid parameter: %d\n", __func__, input_data[1]); } + mutex_unlock(&(cd->system_lock)); break; -#endif /* TTDL_PTVIRTDUT_SUPPORT */ #endif /* TTDL_DIAGNOSTICS */ default: rc = -EINVAL; @@ -15836,9 +14151,9 @@ static ssize_t pt_sleep_status_show(struct device *dev, mutex_lock(&cd->system_lock); if (cd->sleep_state == SS_SLEEP_ON) - ret = snprintf(buf, PT_MAX_PRBUF_SIZE, "off\n"); + ret = scnprintf(buf, PT_MAX_PRBUF_SIZE, "off\n"); else - ret = snprintf(buf, PT_MAX_PRBUF_SIZE, "on\n"); + ret = scnprintf(buf, PT_MAX_PRBUF_SIZE, "on\n"); mutex_unlock(&cd->system_lock); return ret; @@ -15882,7 +14197,7 @@ static ssize_t pt_panel_id_show(struct device *dev, if (cd->panel_id_support & PT_PANEL_ID_BY_BL) { rc = pt_hid_output_bl_get_panel_id_(cd, &pid); if (rc) { - pt_debug(dev, DL_WARN, "%s: %s %s\n", + pt_debug(dev, DL_ERROR, "%s: %s %s\n", "Failed to retrieve Panel ID. ", "Using cached value\n", __func__); @@ -15896,12 +14211,12 @@ static ssize_t pt_panel_id_show(struct device *dev, if (!rc) pid = cd->sysinfo.sensing_conf_data.panel_id; - pt_debug(dev, DL_WARN, + pt_debug(dev, DL_ERROR, "%s: Gen6 FW mode rc=%d PID=0x%02X\n", __func__, rc, pid); } } else { - pt_debug(dev, DL_WARN, "%s: Active mode unknown\n", + pt_debug(dev, DL_ERROR, "%s: Active mode unknown\n", __func__); rc = -EPERM; } @@ -15922,22 +14237,22 @@ static ssize_t pt_panel_id_show(struct device *dev, if (!rc) pid = cd->sysinfo.sensing_conf_data.panel_id; - pt_debug(dev, DL_WARN, + pt_debug(dev, DL_ERROR, "%s: TT/TC FW mode rc=%d PID=0x%02X\n", __func__, rc, pid); } } else { - pt_debug(dev, DL_WARN, "%s: Active mode unknown\n", + pt_debug(dev, DL_ERROR, "%s: Active mode unknown\n", __func__); rc = -EPERM; } } else { - pt_debug(dev, DL_WARN, "%s: Dut generation is unknown\n", + pt_debug(dev, DL_ERROR, "%s: Dut generation is unknown\n", __func__); rc = -EPERM; } - ret = snprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n0x%02X\n", + ret = scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n0x%02X\n", rc, pid); return ret; } @@ -15970,7 +14285,7 @@ static ssize_t pt_get_param_store(struct device *dev, length = _pt_ic_parse_input(dev, buf, size, input_data, ARRAY_SIZE(input_data)); if (length != 1) { - pt_debug(dev, DL_WARN, "%s: Invalid number of arguments\n", + pt_debug(dev, DL_ERROR, "%s: Invalid number of arguments\n", __func__); rc = -EINVAL; goto exit; @@ -16019,6 +14334,7 @@ static ssize_t pt_get_param_show(struct device *dev, u32 value = 0; status = pt_pip_get_param(cd, cd->get_param_id, &value); + if (status) { pt_debug(dev, DL_ERROR, "%s: %s Failed, status = %d\n", __func__, "pt_get_param", status); @@ -16059,7 +14375,6 @@ static ssize_t pt_ttdl_restart_show(struct device *dev, mutex_lock(&cd->system_lock); cd->startup_state = STARTUP_NONE; mutex_unlock(&(cd->system_lock)); - /* ensure no left over exclusive access is still locked */ release_exclusive(cd, cd->dev); @@ -16109,17 +14424,17 @@ static ssize_t pt_pip2_gpio_read_show(struct device *dev, if (!rc) { if (status == 0) - return snprintf(buf, PT_MAX_PRBUF_SIZE, + return scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n" "DUT GPIO Reg: 0x%08X\n", rc, gpio_value); else - return snprintf(buf, PT_MAX_PRBUF_SIZE, + return scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n" "DUT GPIO Reg: n/a\n", status); } else - return snprintf(buf, PT_MAX_PRBUF_SIZE, + return scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n" "DUT GPIO Reg: n/a\n", rc); @@ -16147,7 +14462,7 @@ static ssize_t pt_pip2_version_show(struct device *dev, rc = pt_pip2_get_version(cd); if (!rc) { - return snprintf(buf, PT_MAX_PRBUF_SIZE, + return scnprintf(buf, PT_MAX_PRBUF_SIZE, "PIP VERSION : %02X.%02X\n" "BL VERSION : %02X.%02X\n" "FW VERSION : %02X.%02X\n" @@ -16167,7 +14482,7 @@ static ssize_t pt_pip2_version_show(struct device *dev, pt_debug(dev, DL_ERROR, "%s: Failed to retriev PIP2 VERSION data\n", __func__); - return snprintf(buf, PT_MAX_PRBUF_SIZE, + return scnprintf(buf, PT_MAX_PRBUF_SIZE, "PIP VERSION : -\n" "BL VERSION : -\n" "FW VERSION : -\n" @@ -16212,17 +14527,14 @@ static ssize_t pt_ttdl_status_show(struct device *dev, "%s: 0x%04X\n" "%s: %d\n" "%s: %s\n" + "%s: %s %s\n" + "%s: %s\n" "%s: 0x%02X\n" "%s: %s\n" "%s: %s\n" + "%s: %s\n" + "%s: %s\n" "%s: %d\n" - "%s: %s %s\n" - "%s: %s\n" - "%s: %s\n" - "%s: %s\n" - "%s: %s\n" - "%s: %s\n" - "%s: %s\n" "%s: %d\n" "%s: %s\n" "%s: %s\n" @@ -16238,22 +14550,19 @@ static ssize_t pt_ttdl_status_show(struct device *dev, "%s: %d\n" "%s: %d\n" "%s: %d\n" - "%s: %d\n" + "%s: %s\n" + "%s: %s\n" "%s: %s\n" "%s: %d\n" "%s: 0x%04X\n" + "%s: %s\n" #endif /* TTDL_DIAGNOSTICS */ , "Startup Status ", cd->startup_status, "TTDL Debug Level ", cd->debug_level, - "Active Bus Module ", - cd->bus_ops->bustype == BUS_I2C ? "I2C" : "SPI", - "I2C Address ", - cd->bus_ops->bustype == BUS_I2C ? client->addr : 0, - "Exclusive Access Lock ", cd->exclusive_dev ? "Set":"Free", - "HW Detected ", - cd->hw_detected ? "True" : "False", - "Number of Devices ", cd->num_devices, + "Mode ", + cd->mode ? (cd->mode == PT_MODE_OPERATIONAL ? + "Operational" : "BL") : "Unknown", "DUT Generation ", cd->active_dut_generation ? (cd->active_dut_generation == DUT_PIP2_CAPABLE ? @@ -16261,17 +14570,14 @@ static ssize_t pt_ttdl_status_show(struct device *dev, cd->active_dut_generation ? (cd->set_dut_generation == true ? "(Set)" : "(Detected)") : "", - "Protocol Mode ", - cd->dut_status.protocol_mode == PT_PROTOCOL_MODE_HID ? - "Hybrid HID" : "PIP", - "Mode ", - cd->mode ? (cd->mode == PT_MODE_OPERATIONAL ? - "Operational" : "BL") : "Unknown", + "HW Detected ", + cd->hw_detected ? "True" : "False", + "I2C Address ", + cd->bus_ops->bustype == BUS_I2C ? client->addr : 0, + "Active Bus Module ", + cd->bus_ops->bustype == BUS_I2C ? "I2C" : "SPI", "Flashless Mode ", cd->flashless_dut == 1 ? "Yes" : "No", - "Suppress No-Flash Auto BL ", - cd->flashless_auto_bl == PT_SUPPRESS_AUTO_BL ? - "Yes" : "No", "GPIO state - IRQ ", cd->cpdata->irq_stat ? (cd->cpdata->irq_stat(cd->cpdata, dev) ? @@ -16280,30 +14586,35 @@ static ssize_t pt_ttdl_status_show(struct device *dev, pdata->core_pdata->rst_gpio ? (gpio_get_value(pdata->core_pdata->rst_gpio) ? "High" : "Low") : "not defined", - "Error GPIO trigger type ", cd->err_gpio_type, + "RAM Parm restore list ", pt_count_parameter_list(cd), + "Startup Retry Count ", cd->startup_retry_count, "WD - Manual Force Stop ", cd->watchdog_force_stop ? "True" : "False", "WD - Enabled ", cd->watchdog_enabled ? "True" : "False", "WD - Interval (ms) ", cd->watchdog_interval #ifdef TTDL_DIAGNOSTICS - , - "WD - Triggered Count ", cd->watchdog_count, + , "WD - Triggered Count ", cd->watchdog_count, "WD - IRQ Stuck low count ", cd->watchdog_irq_stuck_count, "WD - Device Access Errors ", cd->watchdog_failed_access_count, "WD - XRES Count ", cd->wd_xres_count, - "Startup Retry Count ", cd->startup_retry_count, "IRQ Triggered Count ", cd->irq_count, "BL Packet Retry Count ", cd->bl_retry_packet_count, "PIP2 CRC Error Count ", cd->pip2_crc_error_count, "Bus Transmit Error Count ", cd->bus_transmit_error_count, "File Erase Timeout Count ", cd->file_erase_timeout_count, - "RAM Parm Restore Count ", pt_count_parameter_list(cd), + "Error GPIO trigger type ", cd->err_gpio_type, + "Exclusive Access Lock ", cd->exclusive_dev ? "Set":"Free", + "Suppress No-Flash Auto BL ", + cd->flashless_auto_bl == PT_SUPPRESS_AUTO_BL ? + "Yes" : "No", "Calibration Cache on host ", cd->cal_cache_in_host == PT_FEATURE_ENABLE ? "Yes" : "No", "Calibration Cache size ", cal_size, - "Calibration Cache chip ID ", crc + "Calibration Cache chip ID ", crc, + "Multi-Chip Support ", + cd->multi_chip == PT_FEATURE_ENABLE ? "Yes" : "No" #endif /* TTDL_DIAGNOSTICS */ ); @@ -16346,7 +14657,6 @@ static ssize_t pt_pip2_enter_bl_show(struct device *dev, int result = 0; u8 mode = PT_MODE_UNKNOWN; struct pt_core_data *cd = dev_get_drvdata(dev); - bool current_bridge_mode = cd->bridge_mode; /* Turn off the TTDL WD before enter bootloader */ pt_stop_wd_timer(cd); @@ -16361,45 +14671,42 @@ static ssize_t pt_pip2_enter_bl_show(struct device *dev, rc = _pt_request_pip2_enter_bl(dev, &mode, &result); switch (result) { case PT_ENTER_BL_PASS: - ret = snprintf(buf, PT_MAX_PRBUF_SIZE, + ret = scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\nEntered BL\n", PT_ENTER_BL_PASS); break; case PT_ENTER_BL_ERROR: - ret = snprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n%s\n", + ret = scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n%s\n", rc, " Unknown Error"); break; case PT_ENTER_BL_RESET_FAIL: - ret = snprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n%s\n", + ret = scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n%s\n", rc, " Soft Reset Failed"); break; case PT_ENTER_BL_HID_START_BL_FAIL: - ret = snprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n%s\n", + ret = scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n%s\n", rc, " PIP Start BL Cmd Failed"); break; case PT_ENTER_BL_CONFIRM_FAIL: - ret = snprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n%s\n", + ret = scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n%s\n", rc, " Error confirming DUT entered BL"); break; default: - ret = snprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n%s\n", + ret = scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n%s\n", rc, " Unknown Error"); break; }; - /* Restore state of allowing enumeration work to be queued again */ - mutex_lock(&cd->system_lock); - cd->bridge_mode = current_bridge_mode; - mutex_unlock(&cd->system_lock); + /* Allow enumeration work to be queued again */ + cd->bridge_mode = false; return ret; } static DEVICE_ATTR(pip2_enter_bl, 0444, pt_pip2_enter_bl_show, NULL); -#define PT_STATUS_STR_LEN (50) /******************************************************************************* * FUNCTION: pt_pip2_exit_bl_show * @@ -16465,7 +14772,7 @@ static ssize_t pt_easy_wakeup_gesture_show(struct device *dev, ssize_t ret; mutex_lock(&cd->system_lock); - ret = snprintf(buf, PT_MAX_PRBUF_SIZE, "0x%02X\n", + ret = scnprintf(buf, PT_MAX_PRBUF_SIZE, "0x%02X\n", cd->easy_wakeup_gesture); mutex_unlock(&cd->system_lock); return ret; @@ -16497,7 +14804,7 @@ static ssize_t pt_easy_wakeup_gesture_store(struct device *dev, length = _pt_ic_parse_input(dev, buf, size, input_data, ARRAY_SIZE(input_data)); if (length != 1) { - pt_debug(dev, DL_WARN, "%s: Invalid number of arguments\n", + pt_debug(dev, DL_ERROR, "%s: Invalid number of arguments\n", __func__); rc = -EINVAL; goto exit; @@ -16554,7 +14861,7 @@ static ssize_t pt_easy_wakeup_gesture_id_show(struct device *dev, ssize_t ret; mutex_lock(&cd->system_lock); - ret = snprintf(buf, PT_MAX_PRBUF_SIZE, "Status: 0\n0x%02X\n", + ret = scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: 0\n0x%02X\n", cd->gesture_id); mutex_unlock(&cd->system_lock); return ret; @@ -16584,13 +14891,12 @@ static ssize_t pt_easy_wakeup_gesture_data_show(struct device *dev, int i; mutex_lock(&cd->system_lock); - - ret += snprintf(buf + ret, PT_MAX_PRBUF_SIZE - ret, "Status: %d\n", 0); + ret += scnprintf(buf + ret, PT_MAX_PRBUF_SIZE - ret, "Status: %d\n", 0); for (i = 0; i < cd->gesture_data_length; i++) - ret += snprintf(buf + ret, PT_MAX_PRBUF_SIZE - ret, + ret += scnprintf(buf + ret, PT_MAX_PRBUF_SIZE - ret, "0x%02X\n", cd->gesture_data[i]); - ret += snprintf(buf + ret, PT_MAX_PRBUF_SIZE - ret, + ret += scnprintf(buf + ret, PT_MAX_PRBUF_SIZE - ret, "(%d bytes)\n", cd->gesture_data_length); mutex_unlock(&cd->system_lock); @@ -16655,12 +14961,11 @@ static ssize_t pt_err_gpio_store(struct device *dev, input_data[0] = 0; input_data[1] = 0; - /* Maximmum input is two elements */ length = _pt_ic_parse_input(dev, buf, size, input_data, ARRAY_SIZE(input_data)); if (length < 1 || length > 2) { - pt_debug(dev, DL_WARN, "%s: Invalid number of arguments\n", + pt_debug(dev, DL_ERROR, "%s: Invalid number of arguments\n", __func__); rc = -EINVAL; goto exit; @@ -16716,12 +15021,12 @@ static ssize_t pt_drv_irq_show(struct device *dev, ssize_t ret = 0; mutex_lock(&cd->system_lock); - ret += snprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n", 0); + ret += scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n", 0); if (cd->irq_enabled) - ret += snprintf(buf + ret, PT_MAX_PRBUF_SIZE - ret, + ret += scnprintf(buf + ret, PT_MAX_PRBUF_SIZE - ret, "Driver interrupt: ENABLED\n"); else - ret += snprintf(buf + ret, PT_MAX_PRBUF_SIZE - ret, + ret += scnprintf(buf + ret, PT_MAX_PRBUF_SIZE - ret, "Driver interrupt: DISABLED\n"); mutex_unlock(&cd->system_lock); @@ -16754,7 +15059,7 @@ static ssize_t pt_drv_irq_store(struct device *dev, length = _pt_ic_parse_input(dev, buf, size, input_data, ARRAY_SIZE(input_data)); if (length != 1) { - pt_debug(dev, DL_WARN, "%s: Invalid number of arguments\n", + pt_debug(dev, DL_ERROR, "%s: Invalid number of arguments\n", __func__); rc = -EINVAL; goto exit; @@ -17014,9 +15319,10 @@ static int pt_bist_bus_test(struct device *dev, u8 *net_toggled, u8 *err_str) pt_debug(cd->dev, DL_INFO, ">>> %s: Write Buffer Size[%d] VERSION\n", __func__, (int)sizeof(ver_cmd)); + pt_pr_buf(cd->dev, DL_DEBUG, ver_cmd, (int)sizeof(ver_cmd), ">>> User CMD"); - rc = pt_adap_write_read_specific(cd, sizeof(ver_cmd), ver_cmd, NULL, 0); + rc = pt_adap_write_read_specific(cd, sizeof(ver_cmd), ver_cmd, NULL); if (rc) { pt_debug(dev, DL_ERROR, "%s: BUS Test - Failed to send VER cmd\n", __func__); @@ -17099,9 +15405,6 @@ exit: static int pt_bist_irq_test(struct device *dev, u8 *bus_toggled, u8 *irq_toggled, u8 *xres_toggled, u8 *err_str) { -#ifdef TTDL_PTVIRTDUT_SUPPORT - u8 release_irq[3] = {0xFF, 0xFF, 0x03}; -#endif /* TTDL_PTVIRTDUT_SUPPORT */ struct pt_core_data *cd = dev_get_drvdata(dev); u8 *read_buf = NULL; u8 mode = PT_MODE_UNKNOWN; @@ -17127,14 +15430,6 @@ static int pt_bist_irq_test(struct device *dev, count++; bytes_read += pt_flush_bus(cd, PT_FLUSH_BUS_BASED_ON_LEN, NULL); } -#ifdef TTDL_PTVIRTDUT_SUPPORT - if (pt_check_irq_asserted(cd) && cd->route_bus_virt_dut) { - /* Force virtual DUT to release IRQ */ - pt_pr_buf(cd->dev, DL_DEBUG, release_irq, - (int)sizeof(release_irq), ">>> User CMD"); - pt_adap_write_read_specific(cd, 3, release_irq, NULL, 0); - } -#endif /* TTDL_PTVIRTDUT_SUPPORT */ if (count > 1 && count < 5 && bytes_read > 0) { /* @@ -17291,9 +15586,6 @@ static int pt_bist_xres_test(struct device *dev, { struct pt_core_data *cd = dev_get_drvdata(dev); struct pt_platform_data *pdata = dev_get_platdata(dev); -#ifdef TTDL_PTVIRTDUT_SUPPORT - u8 release_irq[3] = {0xFF, 0xFF, 0x03}; -#endif /* TTDL_PTVIRTDUT_SUPPORT */ u8 *read_buf = NULL; u8 mode = PT_MODE_UNKNOWN; int rc = 0; @@ -17319,14 +15611,6 @@ static int pt_bist_xres_test(struct device *dev, /* Ensure we have nothing pending on active bus */ pt_flush_bus_if_irq_asserted(cd, PT_FLUSH_BUS_BASED_ON_LEN); -#ifdef TTDL_PTVIRTDUT_SUPPORT - if (pt_check_irq_asserted(cd) && cd->route_bus_virt_dut) { - /* Force virtual DUT to release IRQ */ - pt_pr_buf(cd->dev, DL_DEBUG, release_irq, - (int)sizeof(release_irq), ">>> User CMD"); - pt_adap_write_read_specific(cd, 3, release_irq, NULL, 0); - } -#endif /* TTDL_PTVIRTDUT_SUPPORT */ /* Perform a hard XRES toggle and wait for reset sentinel */ mutex_lock(&cd->system_lock); @@ -17465,11 +15749,16 @@ exit: * !0 = Failure * * PARAMETERS: - * *dev - pointer to device structure - * *slave - pointer to one entry in the slave info array + * *dev - pointer to device structure + * *slave_irq_toggled - pointer to where to store if slave IRQ toggled + * *slave_bus_toggled - pointer to where to store if slave Bus toggled + * *err_str - pointer to error string buffer + * *slave_detect - pointer to slave detect buffer + * *boot_err - pointer to boot_err buffer ******************************************************************************/ static int pt_bist_slave_irq_test(struct device *dev, - struct pt_bist_data *slave) + u8 *slave_irq_toggled, u8 *slave_bus_toggled, u8 *err_str, + u8 *slave_detect, u8 *boot_err) { struct pt_core_data *cd = dev_get_drvdata(dev); u8 mode = PT_MODE_UNKNOWN; @@ -17489,11 +15778,9 @@ static int pt_bist_slave_irq_test(struct device *dev, */ rc = _pt_request_pip2_enter_bl(dev, &mode, &result); if (rc) { - pt_debug(cd->dev, DL_WARN, "%s: Error entering BL rc=%d\n", + pt_debug(cd->dev, DL_ERROR, "%s: Error entering BL rc=%d\n", __func__, rc); - if (slave->irq_err_str) - strlcpy(slave->irq_err_str, - "- State could not be determined.", PT_ERR_STR_SIZE); + strlcpy(err_str, "- State could not be determined.", PT_ERR_STR_SIZE); goto exit; } @@ -17505,7 +15792,7 @@ static int pt_bist_slave_irq_test(struct device *dev, pt_pr_buf(cd->dev, DL_INFO, read_buf, actual_read_len, "PIP2 STATUS"); status = read_buf[PIP2_RESP_STATUS_OFFSET]; - boot = read_buf[PIP2_RESP_BODY_OFFSET] & slave->mask; + boot = read_buf[PIP2_RESP_BODY_OFFSET] & 0x01; /* Slave detect is only valid if status ok and in boot exec */ if (status == PIP2_RSP_ERR_NONE && @@ -17513,17 +15800,13 @@ static int pt_bist_slave_irq_test(struct device *dev, detected = read_buf[PIP2_RESP_BODY_OFFSET + 2] & SLAVE_DETECT_MASK; } else { - if (slave->irq_err_str) - strlcpy(slave->irq_err_str, - "- State could not be determined", PT_ERR_STR_SIZE); + strlcpy(err_str, "- State could not be determined", PT_ERR_STR_SIZE); rc = -EPERM; } } else { - pt_debug(cd->dev, DL_WARN, "%s: STATUS cmd failure\n", + pt_debug(cd->dev, DL_ERROR, "%s: STATUS cmd failure\n", __func__); - if (slave->irq_err_str) - strlcpy(slave->irq_err_str, - "- State could not be determined.", PT_ERR_STR_SIZE); + strlcpy(err_str, "- State could not be determined.", PT_ERR_STR_SIZE); goto exit; } @@ -17540,68 +15823,52 @@ static int pt_bist_slave_irq_test(struct device *dev, status = read_buf[PIP2_RESP_STATUS_OFFSET]; last_err = read_buf[PIP2_RESP_BODY_OFFSET]; if (last_err) { - pt_debug(cd->dev, DL_WARN, + pt_debug(cd->dev, DL_ERROR, "%s: Master Boot Last Err = 0x%02X\n", __func__, last_err); } } else { - pt_debug(cd->dev, DL_WARN, + pt_debug(cd->dev, DL_ERROR, "%s: GET_LAST_ERRNO cmd failure\n", __func__); - if (slave->irq_err_str) - strlcpy(slave->irq_err_str, - "- stuck, likely shorted to GND.", PT_ERR_STR_SIZE); + strlcpy(err_str, "- stuck, likely shorted to GND.", PT_ERR_STR_SIZE); } exit: pt_debug(cd->dev, DL_INFO, "%s: rc=%d detected=0x%02X boot_err=0x%02X\n", __func__, rc, detected, last_err); - - /* - * Clear any possible false positives: - * - An invalid image error as BIST doesn't need valid FW - * - A Flash file too small as BIST doesn't need FLASH - * - FLASH access errors when in no-flash mode - */ - if ((last_err == PIP2_RSP_ERR_INVALID_IMAGE) || - (last_err == PIP2_RSP_ERR_BUF_TOO_SMALL) || - (last_err == PIP2_RSP_ERR_BAD_ADDRESS && cd->flashless_dut) || - (last_err == PIP2_RSP_ERR_BAD_FRAME && cd->flashless_dut)) { - pt_debug(cd->dev, DL_INFO, "%s: Cleared boot error: 0x%02X\n", - __func__, last_err); - last_err = PIP2_RSP_ERR_NONE; - } - - /* Attempt to add a hint based on boot error and detection */ - if (slave->irq_err_str) { - if (last_err && detected) - scnprintf(slave->irq_err_str,PT_ERR_STR_SIZE, "%s 0x%02X", + if (err_str && last_err) { + if (detected) + scnprintf(err_str, PT_ERR_STR_SIZE, "%s 0x%02X", "- Likely stuck low. Boot Error:", last_err); - else if (last_err && !detected) - scnprintf(slave->irq_err_str, PT_ERR_STR_SIZE, "%s 0x%02X", + else + scnprintf(err_str, PT_ERR_STR_SIZE, "%s 0x%02X", "- Likely stuck high. Boot Error:", last_err); - else if (detected) - strlcpy(slave->irq_err_str, - "- Likely stuck low. No Critical Boot Error", PT_ERR_STR_SIZE); - else if (!detected) - strlcpy(slave->irq_err_str, - "- Likely stuck high. No Critical Boot Error.", PT_ERR_STR_SIZE); } - slave->irq_toggled = (detected && !last_err) ? true : false; - /* Leave as UNTEST if slave not detected */ - if (detected) - slave->bus_toggled = !last_err ? true : false; - slave->detected = detected; - slave->boot_err = last_err; + /* Ignore an invalid image error as BIST doesn't need valid FW */ + if (last_err == PIP2_RSP_ERR_INVALID_IMAGE) + last_err = PIP2_RSP_ERR_NONE; + + if (slave_irq_toggled) + *slave_irq_toggled = (detected && !last_err) ? true : false; + if (slave_bus_toggled) { + /* Leave as UNTEST if slave not detected */ + if (detected) + *slave_bus_toggled = !last_err ? true : false; + } + if (slave_detect) + *slave_detect = detected; + if (boot_err) + *boot_err = last_err; pt_debug(cd->dev, DL_INFO, "%s: %s=0x%02X, %s=0x%02X, %s=0x%02X\n", __func__, "Detected", detected, - "slave_irq_toggled", slave->irq_toggled, - "slave_bus_toggled", slave->bus_toggled); + "slave_irq_toggled", *slave_irq_toggled, + "slave_bus_toggled", *slave_bus_toggled); return rc; } @@ -17621,13 +15888,19 @@ exit: * !0 = Failure * * PARAMETERS: - * *dev - pointer to device structure - * *slave - pointer to one entry in the slave info array + * *dev - pointer to device structure + * *slave_irq_toggled - pointer to where to store if slave IRQ toggled + * *slave_bus_toggled - pointer to where to store if slave Bus toggled + * *slave_xres_toggled - pointer to where to store if slave XRES toggled + * *err_str - pointer to error string buffer ******************************************************************************/ static int pt_bist_slave_xres_test(struct device *dev, - struct pt_bist_data *slave) + u8 *slave_irq_toggled, u8 *slave_bus_toggled, u8 *slave_xres_toggled, + u8 *err_str) { struct pt_core_data *cd = dev_get_drvdata(dev); + u8 slave_detect = 0; + u8 boot_err = 0; int rc = 0; /* Force a reset to force the 'slave detect' bits to be re-acquired */ @@ -17638,39 +15911,31 @@ static int pt_bist_slave_xres_test(struct device *dev, pt_hw_hard_reset(cd); msleep(100); - rc = pt_bist_slave_irq_test(dev, slave); + rc = pt_bist_slave_irq_test(dev, slave_irq_toggled, + slave_bus_toggled, err_str, &slave_detect, &boot_err); pt_debug(dev, DL_INFO, "%s: IRQ test rc = %d\n", __func__, rc); - if (!rc && slave->irq_toggled == false) { + if (!rc && *slave_irq_toggled == false) { /* * If the slave IRQ did not toggle, either the slave_detect * bit was not set or we had a boot error. If the slave * detect was not set the slave did not reset causing a boot * error. */ - if (slave->xres_err_str && !slave->detected) { - strlcpy(slave->xres_err_str, slave->irq_err_str, PT_ERR_STR_SIZE); - pt_debug(dev, DL_INFO, - "%s: detected=0 irq_err_str = %s\n", - __func__, slave->irq_err_str); - } else if (slave->xres_err_str && slave->boot_err > 0) { - scnprintf(slave->xres_err_str, PT_ERR_STR_SIZE, "%s 0x%02X", + if (!slave_detect) + strlcpy(err_str, "- likely open.", PT_ERR_STR_SIZE); + else + scnprintf(err_str, PT_ERR_STR_SIZE, "%s 0x%02X", "- likely open or an IRQ issue. Boot Error:", - slave->boot_err); - pt_debug(dev, DL_INFO, - "%s: boot_err=%d xres_err_str = %s\n", - __func__, - slave->boot_err, slave->xres_err_str); - } else { - pt_debug(dev, DL_WARN, "%s: No xres_err_str buffer\n", - __func__); - } + boot_err); } + if (slave_xres_toggled) { + if (!rc) + *slave_xres_toggled = *slave_irq_toggled ? true : false; + else + *slave_xres_toggled = false; - if (!rc) - slave->xres_toggled = slave->irq_toggled ? true : false; - else - slave->xres_toggled = false; + } return rc; } @@ -17691,11 +15956,13 @@ static int pt_bist_slave_xres_test(struct device *dev, * !0 = Failure * * PARAMETERS: - * *dev - pointer to device structure - * *slave - pointer to one entry in the slave info array + * *dev - pointer to device structure + * *slave_irq_toggled - pointer to where to store if slave IRQ toggled + * *slave_bus_toggled - pointer to where to store if slave Bus toggled + * *err_str - pointer to error string buffer ******************************************************************************/ static int pt_bist_slave_bus_test(struct device *dev, - struct pt_bist_data *slave) + u8 *slave_irq_toggled, u8 *slave_bus_toggled, u8 *err_str) { struct pt_core_data *cd = dev_get_drvdata(dev); u8 mode = PT_MODE_UNKNOWN; @@ -17706,11 +15973,9 @@ static int pt_bist_slave_bus_test(struct device *dev, rc = _pt_request_pip2_enter_bl(dev, &mode, &result); if (rc) { - pt_debug(cd->dev, DL_WARN, "%s: Error entering BL rc=%d\n", + pt_debug(cd->dev, DL_ERROR, "%s: Error entering BL rc=%d\n", __func__, rc); - if (slave->bus_err_str) - strlcpy(slave->bus_err_str, - "- State could not be determined.", PT_ERR_STR_SIZE); + strlcpy(err_str, "- State could not be determined.", PT_ERR_STR_SIZE); goto exit; } @@ -17719,16 +15984,14 @@ static int pt_bist_slave_bus_test(struct device *dev, if (file_handle != PIP2_RAM_FILE) { rc = -ENOENT; bus_toggled = false; - pt_debug(dev, DL_WARN, + pt_debug(dev, DL_ERROR, "%s Failed to open bin file\n", __func__); - if (slave->bus_err_str) - strlcpy(slave->bus_err_str, - "- Bus open, shorted or DUT in reset", PT_ERR_STR_SIZE); + strlcpy(err_str, "- Bus open, shorted or DUT in reset", PT_ERR_STR_SIZE); goto exit; } else { bus_toggled = true; if (file_handle != _pt_pip2_file_close(dev, file_handle)) { - pt_debug(dev, DL_WARN, + pt_debug(dev, DL_ERROR, "%s: File Close failed, file_handle=%d\n", __func__, file_handle); } @@ -17736,315 +15999,10 @@ static int pt_bist_slave_bus_test(struct device *dev, exit: /* If the master was able to send/recv a PIP msg, the IRQ must be ok */ - slave->irq_toggled = bus_toggled; - slave->bus_toggled = bus_toggled; - - return rc; -} - -/******************************************************************************* - * FUNCTION: pt_bist_slave_test - * - * SUMMARY: Tests XRES, SPI BUS and IRQ for the slave DUT - * - * RETURN: - * 0 = Success - * !0 = Failure - * - * PARAMETERS: - * *dev - pointer to device structure - * *slave - pointer to one entry in the bist info array - * slave_id - id of the slave chip - ******************************************************************************/ -static int pt_bist_slave_test(struct device *dev, - struct pt_bist_data *slave, int slave_id) -{ - struct pt_core_data *cd = dev_get_drvdata(dev); - char *pr_buf; - int rc = 0; - - slave->mask = 0x01 << slave_id; - slave->bus_toggled = 0x0F; /* untested */ - slave->irq_toggled = 0x0F; /* untested */ - slave->xres_toggled = 0x0F; /* untested */ - - pr_buf = slave->print_buf; - if (!pr_buf) { - rc = -ENOMEM; - goto print_results; - } - - slave->bus_err_str = kzalloc(PT_ERR_STR_SIZE, - GFP_KERNEL); - slave->irq_err_str = kzalloc(PT_ERR_STR_SIZE, - GFP_KERNEL); - slave->xres_err_str = kzalloc(PT_ERR_STR_SIZE, - GFP_KERNEL); - - /* ensure no malloc failure */ - if (!slave->bus_err_str || - !slave->irq_err_str || - !slave->xres_err_str) - goto print_results; - - memset(slave->bus_err_str, 0, PT_ERR_STR_SIZE); - memset(slave->irq_err_str, 0, PT_ERR_STR_SIZE); - memset(slave->xres_err_str, 0, PT_ERR_STR_SIZE); - - /* --------------- SLAVE XRES BIST TEST --------------- */ - if ((cd->ttdl_bist_select & PT_BIST_SLAVE_XRES_TEST) != 0) { - pt_debug(dev, DL_INFO, - "%s: ----- Start Slave %d XRES BIST -----", - __func__, slave_id); - slave->xres_toggled = 0xFF; - rc = pt_bist_slave_xres_test(dev, slave); - if (slave->bus_toggled == 1 && - slave->irq_toggled == 1 && - slave->xres_toggled == 1) - goto print_results; - } - - /* --------------- SLAVE IRQ BIST TEST --------------- */ - if ((cd->ttdl_bist_select & PT_BIST_SLAVE_IRQ_TEST) != 0) { - pt_debug(dev, DL_INFO, - "%s: ----- Start Slave %d IRQ BIST -----", - __func__, slave_id); - slave->irq_toggled = 0xFF; - rc = pt_bist_slave_irq_test(dev, slave); - pt_debug(dev, DL_INFO, - "%s: slave_irq_toggled = 0x%02X\n", - __func__, slave->irq_toggled); - if (slave->irq_toggled == 1) { - slave->bus_toggled = 1; - goto print_results; - } - } - - /* --------------- SLAVE BUS BIST TEST --------------- */ - if ((cd->ttdl_bist_select & PT_BIST_SLAVE_BUS_TEST) != 0) { - pt_debug(dev, DL_INFO, - "%s: ----- Start Slave %d BUS BIST -----", - __func__, slave_id); - slave->bus_toggled = 0xFF; - rc = pt_bist_slave_bus_test(dev, slave); - } - -print_results: - /* --------------- PRINT OUT BIST RESULTS ---------------*/ - pt_debug(dev, DL_INFO, "%s: ----- BIST Print Results ----", __func__); - if (!slave->bus_err_str || - !slave->irq_err_str || - !slave->xres_err_str) { - slave->pr_index = scnprintf(pr_buf, PT_MAX_PR_BUF_SIZE, - "M/S%d SPI (MISO,MOSI,CS,CLK): [UNTEST]\n" - "M/S%d IRQ connection: [UNTEST]\n" - "M/S%d TP_XRES connection: [UNTEST]\n", - slave_id, slave_id, slave_id); - } else { - if (slave->irq_toggled == 1) - memset(slave->irq_err_str, 0, PT_ERR_STR_SIZE); - if (slave->xres_toggled == 1) - memset(slave->xres_err_str, 0, PT_ERR_STR_SIZE); - if (slave->bus_toggled == 1) - memset(slave->bus_err_str, 0, PT_ERR_STR_SIZE); - - slave->status = 0; - if (cd->ttdl_bist_select & PT_BIST_SLAVE_BUS_TEST) - slave->status += slave->bus_toggled; - if (cd->ttdl_bist_select & PT_BIST_SLAVE_IRQ_TEST) - slave->status += slave->irq_toggled; - if (cd->ttdl_bist_select & PT_BIST_SLAVE_XRES_TEST) - slave->status += slave->xres_toggled; - pt_debug(dev, DL_WARN, - "%s: status = %d (Slave %d: %d,%d,%d)\n", - __func__, slave->status, slave_id, - slave->bus_toggled, - slave->irq_toggled, - slave->xres_toggled); - - slave->pr_index = scnprintf(pr_buf, PT_MAX_PR_BUF_SIZE, - "M/S%d SPI (MISO,MOSI,CS,CLK): %s %s\n" - "M/S%d IRQ connection: %s %s\n" - "M/S%d TP_XRES connection: %s %s\n", - slave_id, - slave->bus_toggled == 0x0F ? - "[UNTEST]" : - slave->bus_toggled == 1 ? - "[ OK ]" : - "[FAILED]", - slave->bus_err_str, - slave_id, - slave->irq_toggled == 0x0F ? - "[UNTEST]" : - slave->irq_toggled == 1 ? - "[ OK ]" : - "[FAILED]", - slave->irq_err_str, - slave_id, - slave->xres_toggled == 0x0F ? - "[UNTEST]" : - slave->xres_toggled == 1 ? - "[ OK ]" : - "[FAILED]", - slave->xres_err_str); - } - - kfree(slave->bus_err_str); - kfree(slave->irq_err_str); - kfree(slave->xres_err_str); - - return rc; -} - -/******************************************************************************* - * FUNCTION: pt_bist_host_test - * - * SUMMARY: Tests XRES, SPI BUS and IRQ for the host DUT - * - * RETURN: - * 0 = Success - * !0 = Failure - * - * PARAMETERS: - * *dev - pointer to device structure - * *host - pointer to the entry in the bist info array - ******************************************************************************/ -static int pt_bist_host_test(struct device *dev, - struct pt_bist_data *host) -{ - struct pt_core_data *cd = dev_get_drvdata(dev); - char *pr_buf; - int rc = 0; - - u8 bus_toggled = 0x0F; /* default to untested */ - u8 i2c_toggled = 0x0F; /* default to untested */ - u8 spi_toggled = 0x0F; /* default to untested */ - u8 irq_toggled = 0x0F; /* default to untested */ - u8 xres_toggled = 0x0F; /* default to untested */ - - pr_buf = host->print_buf; - if (!pr_buf) { - rc = -ENOMEM; - goto print_results; - } - - host->bus_err_str = kzalloc(PT_ERR_STR_SIZE, GFP_KERNEL); - host->irq_err_str = kzalloc(PT_ERR_STR_SIZE, GFP_KERNEL); - host->xres_err_str = kzalloc(PT_ERR_STR_SIZE, GFP_KERNEL); - if (!host->bus_err_str || - !host->irq_err_str || - !host->xres_err_str) - goto print_results; - - memset(host->xres_err_str, 0, PT_ERR_STR_SIZE); - memset(host->irq_err_str, 0, PT_ERR_STR_SIZE); - memset(host->bus_err_str, 0, PT_ERR_STR_SIZE); - - /* --------------- TP_XRES BIST TEST --------------- */ - if ((cd->ttdl_bist_select & PT_BIST_TP_XRES_TEST) != 0) { - pt_debug(dev, DL_INFO, - "%s: ----- Start TP_XRES BIST -----", __func__); - rc = pt_bist_xres_test(dev, &bus_toggled, &irq_toggled, - &xres_toggled, host->xres_err_str); - /* Done if the rest of all nets toggled */ - if (bus_toggled == 1 && irq_toggled == 1 && xres_toggled == 1) - goto print_results; - } - - /* Flush bus in case a PIP response is waiting from previous test */ - pt_flush_bus(cd, PT_FLUSH_BUS_BASED_ON_LEN, NULL); - - /* --------------- IRQ BIST TEST --------------- */ - if ((cd->ttdl_bist_select & PT_BIST_IRQ_TEST) != 0) { - pt_debug(dev, DL_INFO, - "%s: ----- Start IRQ BIST -----", __func__); - bus_toggled = 0xFF; - irq_toggled = 0xFF; - rc = pt_bist_irq_test(dev, &bus_toggled, &irq_toggled, - &xres_toggled, host->irq_err_str); - /* If this net failed clear results from previous net */ - if (irq_toggled != 1) { - xres_toggled = 0x0F; - memset(host->xres_err_str, 0, PT_ERR_STR_SIZE); - } - if (bus_toggled == 1 && irq_toggled == 1) - goto print_results; - } - - /* Flush bus in case a PIP response is waiting from previous test */ - pt_flush_bus(cd, PT_FLUSH_BUS_BASED_ON_LEN, NULL); - - /* --------------- BUS BIST TEST --------------- */ - if ((cd->ttdl_bist_select & PT_BIST_BUS_TEST) != 0) { - pt_debug(dev, DL_INFO, - "%s: ----- Start BUS BIST -----", __func__); - bus_toggled = 0xFF; - rc = pt_bist_bus_test(dev, &bus_toggled, host->bus_err_str); - /* If this net failed clear results from previous net */ - if (bus_toggled == 0) { - irq_toggled = 0x0F; - memset(host->irq_err_str, 0, PT_ERR_STR_SIZE); - } - } - -print_results: - /* --------------- PRINT OUT BIST RESULTS ---------------*/ - pt_debug(dev, DL_INFO, "%s: ----- BIST Print Results ----", __func__); - - /* Cannot print if any memory allocation issues */ - if (!host->bus_err_str || !host->irq_err_str || !host->xres_err_str) { - host->pr_index = scnprintf(pr_buf, PT_MAX_PR_BUF_SIZE, - "Status: %d\n" - "I2C (SDA,SCL): [UNTEST]\n" - "SPI (MISO,MOSI,CS,CLK): [UNTEST]\n" - "IRQ connection: [UNTEST]\n" - "TP_XRES connection: [UNTEST]\n", -ENOMEM); - } else { - host->status = 0; - if (bus_toggled == 1) - memset(host->bus_err_str, 0, PT_ERR_STR_SIZE); - if (irq_toggled == 1) - memset(host->irq_err_str, 0, PT_ERR_STR_SIZE); - if (xres_toggled == 1) - memset(host->xres_err_str, 0, PT_ERR_STR_SIZE); - - if (cd->ttdl_bist_select & PT_BIST_BUS_TEST) - host->status += bus_toggled; - if (cd->ttdl_bist_select & PT_BIST_IRQ_TEST) - host->status += irq_toggled; - if (cd->ttdl_bist_select & PT_BIST_TP_XRES_TEST) - host->status += xres_toggled; - pt_debug(dev, DL_WARN, "%s: status = %d (%d,%d,%d)\n", - __func__, host->status, bus_toggled, irq_toggled, - xres_toggled); - - if (cd->bus_ops->bustype == BUS_I2C) - i2c_toggled = bus_toggled; - else - spi_toggled = bus_toggled; - - host->pr_index = scnprintf(pr_buf, PT_MAX_PR_BUF_SIZE, - "I2C (SDA,SCL): %s %s\n" - "SPI (MISO,MOSI,CS,CLK): %s %s\n" - "IRQ connection: %s %s\n" - "TP_XRES connection: %s %s\n", - i2c_toggled == 0x0F ? "[UNTEST]" : - i2c_toggled == 1 ? "[ OK ]" : "[FAILED]", - i2c_toggled == 0x0F ? "" : host->bus_err_str, - spi_toggled == 0x0F ? "[UNTEST]" : - spi_toggled == 1 ? "[ OK ]" : "[FAILED]", - spi_toggled == 0x0F ? "" : host->bus_err_str, - irq_toggled == 0x0F ? "[UNTEST]" : - irq_toggled == 1 ? "[ OK ]" : "[FAILED]", - host->irq_err_str, - xres_toggled == 0x0F ? "[UNTEST]" : - xres_toggled == 1 ? "[ OK ]" : "[FAILED]", - host->xres_err_str); - } - - kfree(host->bus_err_str); - kfree(host->irq_err_str); - kfree(host->xres_err_str); + if (slave_irq_toggled) + *slave_irq_toggled = bus_toggled; + if (slave_bus_toggled) + *slave_bus_toggled = bus_toggled; return rc; } @@ -18075,28 +16033,49 @@ static ssize_t pt_ttdl_bist_show(struct device *dev, struct device_attribute *attr, char *buf) { struct pt_core_data *cd = dev_get_drvdata(dev); - ssize_t ret = 0; + ssize_t ret; + char *bus_err_str = NULL; + char *irq_err_str = NULL; + char *xres_err_str = NULL; + char *slave_bus_err_str = NULL; + char *slave_irq_err_str = NULL; + char *slave_xres_err_str = NULL; u8 tests; - int slave_id = 0; - int num_slaves = 0; int rc = 0; int num_tests = 0; int status = 1; /* 0 = Pass, !0 = fail */ - struct pt_bist_data host; - struct pt_bist_data slaves[PT_MAX_DEVICES]; - int idx_status = 0; + u8 bus_toggled = 0x0F; /* default to untested */ + u8 i2c_toggled = 0x0F; /* default to untested */ + u8 spi_toggled = 0x0F; /* default to untested */ + u8 irq_toggled = 0x0F; /* default to untested */ + u8 xres_toggled = 0x0F; /* default to untested */ + u8 slave_bus_toggled = 0x0F; /* default to untested */ + u8 slave_irq_toggled = 0x0F; /* default to untested */ + u8 slave_xres_toggled = 0x0F; /* default to untested */ - host.print_buf = kzalloc(PT_MAX_PR_BUF_SIZE, GFP_KERNEL); - if (!host.print_buf) { - ret = scnprintf(buf, strlen(buf), - "Status: 1\n" - "Failed to alloc memory"); - return ret; + bus_err_str = kzalloc(PT_ERR_STR_SIZE, GFP_KERNEL); + irq_err_str = kzalloc(PT_ERR_STR_SIZE, GFP_KERNEL); + xres_err_str = kzalloc(PT_ERR_STR_SIZE, GFP_KERNEL); + if (!bus_err_str || !irq_err_str || !xres_err_str) + goto print_results; + + memset(xres_err_str, 0, PT_ERR_STR_SIZE); + memset(irq_err_str, 0, PT_ERR_STR_SIZE); + memset(bus_err_str, 0, PT_ERR_STR_SIZE); + + if (cd->multi_chip) { + slave_bus_err_str = kzalloc(PT_ERR_STR_SIZE, GFP_KERNEL); + slave_irq_err_str = kzalloc(PT_ERR_STR_SIZE, GFP_KERNEL); + slave_xres_err_str = kzalloc(PT_ERR_STR_SIZE, GFP_KERNEL); + if (!slave_bus_err_str || + !slave_irq_err_str || + !slave_xres_err_str) + goto print_results; + memset(slave_bus_err_str, 0, PT_ERR_STR_SIZE); + memset(slave_irq_err_str, 0, PT_ERR_STR_SIZE); + memset(slave_xres_err_str, 0, PT_ERR_STR_SIZE); } - /* Load up slave info array when slaves present */ - num_slaves = cd->num_devices - 1; - /* Turn off the TTDL WD during the test */ pt_stop_wd_timer(cd); @@ -18109,7 +16088,7 @@ static ssize_t pt_ttdl_bist_show(struct device *dev, num_tests += tests & 1; tests >>= 1; } - pt_debug(dev, DL_WARN, "%s: BIST select = 0x%02X, run %d tests\n", + pt_debug(dev, DL_ERROR, "%s: BIST select = 0x%02X, run %d tests\n", __func__, cd->ttdl_bist_select, num_tests); /* Suppress auto BL to avoid loader thread sending PIP during xres */ @@ -18121,43 +16100,95 @@ static ssize_t pt_ttdl_bist_show(struct device *dev, mutex_unlock(&cd->system_lock); } - /* --------------- TP HOST BIST TEST --------------- */ - host.status = 0; - host.pr_index = 0; - rc = pt_bist_host_test(dev, &host); - pt_debug(dev, DL_INFO, "%s print_idx = %d\n", - __func__, host.pr_index); + /* --------------- TP_XRES BIST TEST --------------- */ + if ((cd->ttdl_bist_select & PT_TTDL_BIST_TP_XRES_TEST) != 0) { + pt_debug(dev, DL_INFO, + "%s: ----- Start TP_XRES BIST -----", __func__); + rc = pt_bist_xres_test(dev, &bus_toggled, &irq_toggled, + &xres_toggled, xres_err_str); + /* Done if the rest of all nets toggled */ + if (bus_toggled == 1 && irq_toggled == 1 && xres_toggled == 1) + goto host_nets_complete; + } - status = host.status; + /* Flush bus in case a PIP response is waiting from previous test */ + pt_flush_bus(cd, PT_FLUSH_BUS_BASED_ON_LEN, NULL); - /* --------------- TP SLAVE BIST TEST --------------- */ - for (slave_id = 0; slave_id < num_slaves; slave_id++) { - slaves[slave_id].print_buf = kzalloc(PT_MAX_PR_BUF_SIZE, - GFP_KERNEL); - if (!slaves[slave_id].print_buf) { - ret = scnprintf(buf, strlen(buf), - "Status: 1\n" - "Failed to alloc memory"); - goto exit; + /* --------------- IRQ BIST TEST --------------- */ + if ((cd->ttdl_bist_select & PT_TTDL_BIST_IRQ_TEST) != 0) { + pt_debug(dev, DL_INFO, + "%s: ----- Start IRQ BIST -----", __func__); + bus_toggled = 0xFF; + irq_toggled = 0xFF; + rc = pt_bist_irq_test(dev, &bus_toggled, &irq_toggled, + &xres_toggled, irq_err_str); + /* If this net failed clear results from previous net */ + if (irq_toggled != 1) { + xres_toggled = 0x0F; + memset(xres_err_str, 0, PT_ERR_STR_SIZE); } - slaves[slave_id].status = 0; - slaves[slave_id].pr_index = 0; - pt_bist_slave_test(dev, &slaves[slave_id], slave_id); - status += slaves[slave_id].status; + if (bus_toggled == 1 && irq_toggled == 1) + goto host_nets_complete; } - idx_status = scnprintf(buf, strlen(buf), "Status: %d\n", - status == num_tests ? 0 : 1); - memcpy(buf + idx_status, host.print_buf, host.pr_index); - ret = idx_status + host.pr_index; + /* Flush bus in case a PIP response is waiting from previous test */ + pt_flush_bus(cd, PT_FLUSH_BUS_BASED_ON_LEN, NULL); - for (slave_id = 0; slave_id < num_slaves; slave_id++) { - memcpy(buf + ret, slaves[slave_id].print_buf, - slaves[slave_id].pr_index); - ret += slaves[slave_id].pr_index; + /* --------------- BUS BIST TEST --------------- */ + if ((cd->ttdl_bist_select & PT_TTDL_BIST_BUS_TEST) != 0) { + pt_debug(dev, DL_INFO, + "%s: ----- Start BUS BIST -----", __func__); + bus_toggled = 0xFF; + rc = pt_bist_bus_test(dev, &bus_toggled, bus_err_str); + /* If this net failed clear results from previous net */ + if (bus_toggled == 0) { + irq_toggled = 0x0F; + memset(irq_err_str, 0, PT_ERR_STR_SIZE); + } } -exit: +host_nets_complete: + /* --------------- SLAVE XRES BIST TEST --------------- */ + if (cd->multi_chip && + (cd->ttdl_bist_select & PT_TTDL_BIST_SLAVE_XRES_TEST) != 0) { + pt_debug(dev, DL_INFO, + "%s: ----- Start Slave XRES BIST -----", __func__); + slave_xres_toggled = 0xFF; + rc = pt_bist_slave_xres_test(dev, &slave_irq_toggled, + &slave_bus_toggled, &slave_xres_toggled, + slave_xres_err_str); + if ((slave_bus_toggled == 1 && slave_irq_toggled == 1 && + slave_xres_toggled == 1) || slave_xres_toggled == 0) + goto print_results; + } + + /* --------------- SLAVE IRQ BIST TEST --------------- */ + if (cd->multi_chip && + (cd->ttdl_bist_select & PT_TTDL_BIST_SLAVE_IRQ_TEST) != 0) { + pt_debug(dev, DL_INFO, + "%s: ----- Start Slave IRQ BIST -----", __func__); + slave_irq_toggled = 0xFF; + rc = pt_bist_slave_irq_test(dev, &slave_irq_toggled, + &slave_bus_toggled, slave_irq_err_str, NULL, NULL); + pt_debug(dev, DL_INFO, "%s: slave_irq_toggled = 0x%02X\n", + __func__, slave_irq_toggled); + if (slave_irq_toggled == 1) { + slave_bus_toggled = 1; + goto print_results; + } + } + + /* --------------- SLAVE BUS BIST TEST --------------- */ + if (cd->multi_chip && + (cd->ttdl_bist_select & PT_TTDL_BIST_SLAVE_BUS_TEST) != 0) { + pt_debug(dev, DL_INFO, + "%s: ----- Start Slave BUS BIST -----", __func__); + slave_bus_toggled = 0xFF; + rc = pt_bist_slave_bus_test(dev, &slave_irq_toggled, + &slave_bus_toggled, slave_bus_err_str); + } + +print_results: /* Restore PIP command timeout */ cd->pip_cmd_timeout = cd->pip_cmd_timeout_default; @@ -18222,14 +16253,112 @@ exit: } msleep(20); + /* --------------- PRINT OUT BIST RESULTS ---------------*/ + pt_debug(dev, DL_INFO, "%s: ----- BIST Print Results ----", __func__); + pt_start_wd_timer(cd); + + /* Canned print if any memory allocation issues */ + if (!bus_err_str || !irq_err_str || !xres_err_str) { + ret = scnprintf(buf, strlen(buf), + "Status: %d\n" + "I2C (SDA,SCL): [UNTEST]\n" + "SPI (MISO,MOSI,CS,CLK): [UNTEST]\n" + "IRQ connection: [UNTEST]\n" + "TP_XRES connection: [UNTEST]\n", -ENOMEM); + if (cd->multi_chip) { + ret += scnprintf(buf + ret, strlen(buf), + "I/P SPI (MISO,MOSI,CS,CLK): [UNTEST]\n" + "I/P IRQ connection: [UNTEST]\n" + "I/P TP_XRES connection: [UNTEST]\n"); + } + } else { + status = 0; + if (bus_toggled == 1) + memset(bus_err_str, 0, PT_ERR_STR_SIZE); + if (irq_toggled == 1) + memset(irq_err_str, 0, PT_ERR_STR_SIZE); + if (xres_toggled == 1) + memset(xres_err_str, 0, PT_ERR_STR_SIZE); + + if (cd->ttdl_bist_select & PT_TTDL_BIST_BUS_TEST) + status += bus_toggled; + if (cd->ttdl_bist_select & PT_TTDL_BIST_IRQ_TEST) + status += irq_toggled; + if (cd->ttdl_bist_select & PT_TTDL_BIST_TP_XRES_TEST) + status += xres_toggled; + pt_debug(dev, DL_ERROR, "%s: status = %d (%d,%d,%d)\n", + __func__, status, bus_toggled, irq_toggled, + xres_toggled); + + if (cd->multi_chip) { + if (slave_irq_toggled == 1) + memset(slave_irq_err_str, 0, PT_ERR_STR_SIZE); + if (slave_xres_toggled == 1) + memset(slave_xres_err_str, 0, PT_ERR_STR_SIZE); + if (slave_bus_toggled == 1) + memset(slave_bus_err_str, 0, PT_ERR_STR_SIZE); + + if (cd->ttdl_bist_select & PT_TTDL_BIST_SLAVE_BUS_TEST) + status += slave_bus_toggled; + if (cd->ttdl_bist_select & PT_TTDL_BIST_SLAVE_IRQ_TEST) + status += slave_irq_toggled; + if (cd->ttdl_bist_select & PT_TTDL_BIST_SLAVE_XRES_TEST) + status += slave_xres_toggled; + pt_debug(dev, DL_ERROR, + "%s: status = %d (%d,%d,%d,%d,%d,%d)\n", + __func__, status, bus_toggled, irq_toggled, + xres_toggled, slave_bus_toggled, + slave_irq_toggled, slave_xres_toggled); + } + + if (cd->bus_ops->bustype == BUS_I2C) + i2c_toggled = bus_toggled; + else + spi_toggled = bus_toggled; + + ret = scnprintf(buf, strlen(buf), + "Status: %d\n" + "I2C (SDA,SCL): %s %s\n" + "SPI (MISO,MOSI,CS,CLK): %s %s\n" + "IRQ connection: %s %s\n" + "TP_XRES connection: %s %s\n", + status == num_tests ? 0 : 1, + i2c_toggled == 0x0F ? "[UNTEST]" : + i2c_toggled == 1 ? "[ OK ]" : "[FAILED]", + i2c_toggled == 0x0F ? "" : bus_err_str, + spi_toggled == 0x0F ? "[UNTEST]" : + spi_toggled == 1 ? "[ OK ]" : "[FAILED]", + spi_toggled == 0x0F ? "" : bus_err_str, + irq_toggled == 0x0F ? "[UNTEST]" : + irq_toggled == 1 ? "[ OK ]" : "[FAILED]", + irq_err_str, + xres_toggled == 0x0F ? "[UNTEST]" : + xres_toggled == 1 ? "[ OK ]" : "[FAILED]", + xres_err_str); + + if (cd->multi_chip) { + ret += scnprintf(buf + ret, strlen(buf), + "I/P SPI (MISO,MOSI,CS,CLK): %s %s\n" + "I/P IRQ connection: %s %s\n" + "I/P TP_XRES connection: %s %s\n", + slave_bus_toggled == 0x0F ? "[UNTEST]" : + slave_bus_toggled == 1 ? "[ OK ]" : + "[FAILED]", slave_bus_err_str, + slave_irq_toggled == 0x0F ? "[UNTEST]" : + slave_irq_toggled == 1 ? "[ OK ]" : + "[FAILED]", slave_irq_err_str, + slave_xres_toggled == 0x0F ? "[UNTEST]" : + slave_xres_toggled == 1 ? "[ OK ]" : + "[FAILED]", slave_xres_err_str); + } + } + /* Put TTDL back into a known state, issue a ttdl enum if needed */ pt_debug(dev, DL_INFO, "%s: Startup_status = 0x%04X\n", __func__, cd->startup_status); - - kfree(host.print_buf); - for (slave_id = 0; slave_id < num_slaves; slave_id++) - kfree(slaves[slave_id].print_buf); - + kfree(bus_err_str); + kfree(irq_err_str); + kfree(xres_err_str); return ret; } @@ -18258,7 +16387,7 @@ static ssize_t pt_ttdl_bist_store(struct device *dev, length = _pt_ic_parse_input(dev, buf, size, input_data, ARRAY_SIZE(input_data)); if (length != 1) { - pt_debug(dev, DL_WARN, "%s: Invalid number of arguments\n", + pt_debug(dev, DL_ERROR, "%s: Invalid number of arguments\n", __func__); rc = -EINVAL; goto exit; @@ -18301,7 +16430,7 @@ static ssize_t pt_flush_bus_store(struct device *dev, length = _pt_ic_parse_input(dev, buf, size, input_data, ARRAY_SIZE(input_data)); if (length != 1) { - pt_debug(dev, DL_WARN, "%s: Invalid number of arguments\n", + pt_debug(dev, DL_ERROR, "%s: Invalid number of arguments\n", __func__); rc = -EINVAL; goto exit; @@ -18387,7 +16516,7 @@ static ssize_t pt_pip2_ping_test_store(struct device *dev, length = _pt_ic_parse_input(dev, buf, size, input_data, ARRAY_SIZE(input_data)); if (length != 1) { - pt_debug(dev, DL_WARN, "%s: Invalid number of arguments\n", + pt_debug(dev, DL_ERROR, "%s: Invalid number of arguments\n", __func__); rc = -EINVAL; goto exit; @@ -18474,7 +16603,7 @@ static ssize_t pt_t_refresh_store(struct device *dev, length = _pt_ic_parse_input(dev, buf, size, input_data, ARRAY_SIZE(input_data)); if (length != 1) { - pt_debug(dev, DL_WARN, "%s: Invalid number of arguments\n", + pt_debug(dev, DL_ERROR, "%s: Invalid number of arguments\n", __func__); rc = -EINVAL; goto exit; @@ -18488,13 +16617,13 @@ static ssize_t pt_t_refresh_store(struct device *dev, cd->t_refresh_count = 0; cd->t_refresh_active = 1; } else { - pt_debug(dev, DL_WARN, "%s: Invalid value\n", __func__); + pt_debug(dev, DL_ERROR, "%s: Invalid value\n", __func__); rc = -EINVAL; } mutex_unlock(&cd->system_lock); exit: - pt_debug(dev, DL_WARN, "%s: rc = %d\n", __func__, rc); + pt_debug(dev, DL_ERROR, "%s: rc = %d\n", __func__, rc); if (rc) return rc; return size; @@ -18593,7 +16722,7 @@ static ssize_t pt_dut_status_show(struct device *dev, /* Retrieve mode and FW system mode which can only be 0-4 */ rc = pt_get_fw_sys_mode(cd, &sys_mode, &mode); if (rc || mode == PT_MODE_UNKNOWN) { - ret = snprintf(buf, PT_MAX_PRBUF_SIZE, + ret = scnprintf(buf, PT_MAX_PRBUF_SIZE, "%s: %d\n" "%s: n/a\n" "%s: n/a\n" @@ -18618,7 +16747,7 @@ static ssize_t pt_dut_status_show(struct device *dev, if (rc) goto print_limited_results; - ret = snprintf(buf, PT_MAX_PRBUF_SIZE, + ret = scnprintf(buf, PT_MAX_PRBUF_SIZE, "%s: %d\n" "%s: %s\n" "%s: %s\n" @@ -18637,7 +16766,7 @@ static ssize_t pt_dut_status_show(struct device *dev, } print_limited_results: - ret = snprintf(buf, PT_MAX_PRBUF_SIZE, + ret = scnprintf(buf, PT_MAX_PRBUF_SIZE, "%s: %d\n" "%s: %s\n" "%s: %s\n" @@ -18664,11 +16793,11 @@ static struct attribute *early_attrs[] = { &dev_attr_drv_ver.attr, &dev_attr_fw_version.attr, &dev_attr_sysinfo.attr, -#ifndef TTDL_KERNEL_SUBMISSION &dev_attr_pip2_cmd_rsp.attr, &dev_attr_command.attr, &dev_attr_drv_debug.attr, &dev_attr_hw_reset.attr, + &dev_attr_response.attr, &dev_attr_ttdl_restart.attr, #ifdef TTDL_DIAGNOSTICS &dev_attr_ttdl_status.attr, @@ -18678,7 +16807,6 @@ static struct attribute *early_attrs[] = { &dev_attr_flush_bus.attr, &dev_attr_ttdl_bist.attr, #endif /* TTDL_DIAGNOSTICS */ -#endif /* !TTDL_KERNEL_SUBMISSION */ NULL, }; @@ -18802,8 +16930,60 @@ static void remove_sysfs_and_modules(struct device *dev) pt_mt_release(dev); remove_sysfs_interfaces(dev); } -#endif /* !TTDL_KERNEL_SUBMISSION */ +static int pt_ts_pinctrl_init(struct pt_core_data *cd) +{ + int retval; + + /* Get pinctrl if target uses pinctrl */ + cd->ts_pinctrl = devm_pinctrl_get(cd->dev); + if (IS_ERR_OR_NULL(cd->ts_pinctrl)) { + retval = PTR_ERR(cd->ts_pinctrl); + dev_dbg(cd->dev, + "Target does not use pinctrl %d\n", retval); + goto err_pinctrl_get; + } + + cd->pinctrl_state_active + = pinctrl_lookup_state(cd->ts_pinctrl, + PINCTRL_STATE_ACTIVE); + if (IS_ERR_OR_NULL(cd->pinctrl_state_active)) { + retval = PTR_ERR(cd->pinctrl_state_active); + dev_err(cd->dev, + "Can not lookup %s pinstate %d\n", + PINCTRL_STATE_ACTIVE, retval); + goto err_pinctrl_lookup; + } + + cd->pinctrl_state_suspend + = pinctrl_lookup_state(cd->ts_pinctrl, + PINCTRL_STATE_SUSPEND); + if (IS_ERR_OR_NULL(cd->pinctrl_state_suspend)) { + retval = PTR_ERR(cd->pinctrl_state_suspend); + dev_err(cd->dev, + "Can not lookup %s pinstate %d\n", + PINCTRL_STATE_SUSPEND, retval); + goto err_pinctrl_lookup; + } + + cd->pinctrl_state_release + = pinctrl_lookup_state(cd->ts_pinctrl, + PINCTRL_STATE_RELEASE); + if (IS_ERR_OR_NULL(cd->pinctrl_state_release)) { + retval = PTR_ERR(cd->pinctrl_state_release); + dev_dbg(cd->dev, + "Can not lookup %s pinstate %d\n", + PINCTRL_STATE_RELEASE, retval); + } + + return 0; + +err_pinctrl_lookup: + devm_pinctrl_put(cd->ts_pinctrl); +err_pinctrl_get: + cd->ts_pinctrl = NULL; + return retval; +} /******************************************************************************* ******************************************************************************* @@ -18833,15 +17013,11 @@ int pt_probe(const struct pt_bus_ops *ops, struct device *dev, struct pt_core_data *cd; struct pt_platform_data *pdata = dev_get_platdata(dev); enum pt_atten_type type; + struct i2c_client *client = to_i2c_client(dev); int rc = 0; -#ifndef PT_PTSBC_SUPPORT u8 pip_ver_major; u8 pip_ver_minor; u32 status = STARTUP_STATUS_START; -#endif -#ifdef TTDL_PTVIRTDUT_SUPPORT - int retry = 3; -#endif if (!pdata || !pdata->core_pdata || !pdata->mt_pdata) { pt_debug(dev, DL_ERROR, "%s: Missing platform data\n", @@ -18859,14 +17035,12 @@ int pt_probe(const struct pt_bus_ops *ops, struct device *dev, goto error_no_pdata; } } - /* get context and debug print buffers */ cd = kzalloc(sizeof(*cd), GFP_KERNEL); if (!cd) { rc = -ENOMEM; - goto error_alloc_data; + goto error_no_pdata; } - /* Initialize device info */ cd->dev = dev; cd->pdata = pdata; @@ -18885,6 +17059,7 @@ int pt_probe(const struct pt_bus_ops *ops, struct device *dev, cd->watchdog_enabled = 0; cd->startup_retry_count = 0; cd->core_probe_complete = 0; + cd->runtime = 0; cd->fw_system_mode = FW_SYS_MODE_BOOT; cd->pip_cmd_timeout = PT_PIP_CMD_DEFAULT_TIMEOUT; cd->pip_cmd_timeout_default = PT_PIP_CMD_DEFAULT_TIMEOUT; @@ -18892,8 +17067,8 @@ int pt_probe(const struct pt_bus_ops *ops, struct device *dev, cd->flashless_auto_bl = PT_SUPPRESS_AUTO_BL; cd->bl_with_no_int = 0; cd->cal_cache_in_host = PT_FEATURE_DISABLE; - cd->num_devices = 1; - cd->tthe_hid_usb_format = PT_TTHE_TUNER_FORMAT_HID_I2C; + cd->multi_chip = PT_FEATURE_DISABLE; + cd->tthe_hid_usb_format = PT_FEATURE_DISABLE; if (cd->cpdata->config_dut_generation == CONFIG_DUT_PIP2_CAPABLE) { cd->set_dut_generation = true; @@ -18905,17 +17080,12 @@ int pt_probe(const struct pt_bus_ops *ops, struct device *dev, cd->set_dut_generation = false; cd->active_dut_generation = DUT_UNKNOWN; } - /* Initialize with platform data */ cd->watchdog_force_stop = cd->cpdata->watchdog_force_stop; -#ifdef PT_PTSBC_SUPPORT - /* Extend first WD to allow DDI to complete configuration */ - cd->watchdog_interval = PT_PTSBC_INIT_WATCHDOG_TIMEOUT; -#else cd->watchdog_interval = PT_WATCHDOG_TIMEOUT; -#endif cd->hid_cmd_state = 1; cd->fw_updating = false; + cd->multi_chip = 0; #ifdef TTDL_DIAGNOSTICS cd->t_refresh_active = 0; @@ -18932,20 +17102,9 @@ int pt_probe(const struct pt_bus_ops *ops, struct device *dev, cd->force_pip2_seq = 0; #endif /* TTDL_DIAGNOSTICS */ -#ifdef TTDL_PTVIRTDUT_SUPPORT - /* - * This variable is only used for BATS test. The - * default value "true" has no effect on whether - * the PT_DETECT_HW build flag is enabled or not. - */ - cd->hw_detect_enabled = true; - cd->route_bus_virt_dut = 0; -#endif /* TTDL_PTVIRTDUT_SUPPORT */ - memset(cd->pip2_us_file_path, 0, PT_MAX_PATH_SIZE); memcpy(cd->pip2_us_file_path, PT_PIP2_BIN_FILE_PATH, sizeof(PT_PIP2_BIN_FILE_PATH)); - pt_init_hid_descriptor(&cd->hid_desc); /* Read and store the descriptor lengths */ cd->hid_core.hid_report_desc_len = @@ -18954,14 +17113,12 @@ int pt_probe(const struct pt_bus_ops *ops, struct device *dev, le16_to_cpu(cd->hid_desc.max_input_len); cd->hid_core.hid_max_output_len = le16_to_cpu(cd->hid_desc.max_output_len); - /* Initialize mutexes and spinlocks */ mutex_init(&cd->module_list_lock); mutex_init(&cd->system_lock); mutex_init(&cd->sysfs_lock); mutex_init(&cd->ttdl_restart_lock); mutex_init(&cd->firmware_class_lock); - mutex_init(&cd->hid_report_lock); spin_lock_init(&cd->spinlock); /* Initialize module list */ @@ -18976,6 +17133,29 @@ int pt_probe(const struct pt_bus_ops *ops, struct device *dev, /* Initialize wait queue */ init_waitqueue_head(&cd->wait_q); + rc = pt_ts_pinctrl_init(cd); + if (!rc && cd->ts_pinctrl) { + /* + * Pinctrl handle is optional. If pinctrl handle is found + * let pins to be configured in active state. If not + * found continue further without error. + */ + rc = pinctrl_select_state(cd->ts_pinctrl, + cd->pinctrl_state_active); + if (rc < 0) + dev_err(&client->dev, "failed to select pin to active state\n"); + } + rc = pt_get_regulator(cd, true); + if (rc) { + dev_err(&client->dev, "Failed to get voltage regulators\n"); + goto error_alloc_data; + } + + rc = pt_enable_regulator(cd, true); + if (rc) { + dev_err(dev, "Failed to enable regulators: rc=%d\n", rc); + goto error_get_regulator; + } /* Initialize works */ INIT_WORK(&cd->enum_work, pt_enum_work_function); @@ -18993,6 +17173,11 @@ int pt_probe(const struct pt_bus_ops *ops, struct device *dev, /* Set platform easywake value */ cd->easy_wakeup_gesture = cd->cpdata->easy_wakeup_gesture; +#ifdef CONFIG_DRM + /* Setup active dsi panel */ + active_panel = cd->cpdata->active_panel; +#endif + /* Set platform panel_id value */ cd->panel_id_support = cd->cpdata->panel_id_support; @@ -19006,24 +17191,15 @@ int pt_probe(const struct pt_bus_ops *ops, struct device *dev, snprintf(cd->hw_version, HW_VERSION_LEN_MAX, "FFFF.FFFF.FF"); dev_set_drvdata(dev, cd); -#ifndef PT_PTSBC_SUPPORT /* PtSBC builds will call this function in pt_probe_complete() */ pt_add_core(dev); -#endif rc = sysfs_create_group(&dev->kobj, &early_attr_group); - if (rc) - pt_debug(cd->dev, DL_WARN, "%s:create early attrs failed\n", - __func__); -#ifndef TTDL_KERNEL_SUBMISSION - rc = device_create_bin_file(dev, &bin_attr_pt_response); if (rc) { - pt_debug(dev, DL_ERROR, - "%s: Error, could not create node response\n", + pt_debug(cd->dev, DL_ERROR, "%s:create early attrs failed\n", __func__); + goto error_enable_regulator; } -#endif /* !TTDL_KERNEL_SUBMISSION */ - /* * Save the pointer to a global value, which will be used * in ttdl_restart function @@ -19037,74 +17213,15 @@ int pt_probe(const struct pt_bus_ops *ops, struct device *dev, */ if (!cd->cpdata->irq_stat) { cd->irq = irq; - pt_debug(cd->dev, DL_WARN, "%s:No irq_stat, Set cd->irq = %d\n", + pt_debug(cd->dev, DL_ERROR, "%s:No irq_stat, Set cd->irq = %d\n", __func__, cd->irq); } - -#ifdef PT_PTSBC_SUPPORT - /* - * For the PtSBC, on the first bring up, I2C/SPI will not be ready - * in time so complete probe with pt_probe_complete() after work - * probe timer expires. - */ - INIT_WORK(&cd->probe_work, pt_probe_work); -#if (KERNEL_VERSION(4, 14, 0) > LINUX_VERSION_CODE) - setup_timer(&cd->probe_timer, pt_probe_timer, (unsigned long)cd); -#else - timer_setup(&cd->probe_timer, pt_probe_timer, 0); -#endif - - /* Some host i2c/spi busses start late and then run too slow */ - pt_debug(cd->dev, DL_INFO, "%s:start wait for probe timer\n", - __func__); - mod_timer(&cd->probe_timer, jiffies + - msecs_to_jiffies(PT_CORE_PROBE_STARTUP_DELAY_MS)); - return rc; - -error_alloc_data: -error_no_pdata: - pt_debug(dev, DL_ERROR, "%s failed.\n", __func__); - return rc; -} - -/******************************************************************************* - * FUNCTION: pt_probe_complete - * - * SUMMARY: This function is only needed when PT_PTSBC_SUPPORT is enabled. - * For the PtSBC, the probe functionality is split into two functions; - * pt_probe() and pt_probe_complete(). The initial setup is done - * in pt_probe() and the rest is done here after I2C/SPI is up. This - * function also configures all voltage regulators for the PtSBC. - * - * RETURN: - * 0 = success - * !0 = failure - * - * PARAMETERS: - * *cd - pointer to the core data structure - ******************************************************************************/ -static int pt_probe_complete(struct pt_core_data *cd) -{ - int rc = -1; - u32 status = STARTUP_STATUS_START; - struct device *dev = cd->dev; - u8 pip_ver_major; - u8 pip_ver_minor; -#ifdef TTDL_PTVIRTDUT_SUPPORT - int retry = 3; -#endif - - pt_debug(cd->dev, DL_DEBUG, - "%s: PARADE Entering Probe complete function\n", __func__); - pt_add_core(cd->dev); -#endif /* --- End PT_PTSBC_SUPPORT --- */ - /* Call platform init function before setting up the GPIO's */ if (cd->cpdata->init) { pt_debug(cd->dev, DL_INFO, "%s: Init HW\n", __func__); rc = cd->cpdata->init(cd->cpdata, PT_MT_POWER_ON, cd->dev); } else { - pt_debug(cd->dev, DL_WARN, "%s: No HW INIT function\n", + pt_debug(cd->dev, DL_ERROR, "%s: No HW INIT function\n", __func__); rc = 0; } @@ -19112,14 +17229,13 @@ static int pt_probe_complete(struct pt_core_data *cd) pt_debug(cd->dev, DL_ERROR, "%s: HW Init fail r=%d\n", __func__, rc); } - /* Power on any needed regulator(s) */ if (cd->cpdata->setup_power) { pt_debug(cd->dev, DL_INFO, "%s: Device power on!\n", __func__); rc = cd->cpdata->setup_power(cd->cpdata, PT_MT_POWER_ON, cd->dev); } else { - pt_debug(cd->dev, DL_WARN, "%s: No setup power function\n", + pt_debug(cd->dev, DL_ERROR, "%s: No setup power function\n", __func__); rc = 0; } @@ -19131,18 +17247,6 @@ static int pt_probe_complete(struct pt_core_data *cd) cd->watchdog_irq_stuck_count = 0; cd->bus_transmit_error_count = 0; #endif /* TTDL_DIAGNOSTICS */ - -#ifdef TTDL_PTVIRTDUT_SUPPORT - /* - * In the case that the variable hw_detect_enabled needs to be set to - * false as the default value, it needs to be set to true through - * drv_debug sysfs node when testing HW detect function. But the probe() - * function runs fast, and drv_debug may not set this variable to - * true in time. This "retry" is to avoid this issue. - */ -retry_hw_detect: - if (cd->hw_detect_enabled) { -#endif if (cd->cpdata->detect) { pt_debug(cd->dev, DL_INFO, "%s: Detect HW\n", __func__); rc = cd->cpdata->detect(cd->cpdata, cd->dev, @@ -19159,7 +17263,7 @@ retry_hw_detect: goto error_detect; } } else { - pt_debug(dev, DL_WARN, + pt_debug(dev, DL_ERROR, "%s: PARADE No HW detect function pointer\n", __func__); /* @@ -19173,14 +17277,6 @@ retry_hw_detect: "%s: FAILED to execute HARD reset\n", __func__); } -#ifdef TTDL_PTVIRTDUT_SUPPORT - } else { - if (retry--) { - msleep(50); - goto retry_hw_detect; - } - } -#endif if (cd->cpdata->setup_irq) { pt_debug(cd->dev, DL_INFO, "%s: setup IRQ\n", __func__); @@ -19204,7 +17300,6 @@ retry_hw_detect: timer_setup(&cd->watchdog_timer, pt_watchdog_timer, 0); #endif pt_stop_wd_timer(cd); - #ifdef TTHE_TUNER_SUPPORT mutex_init(&cd->tthe_lock); cd->tthe_debugfs = debugfs_create_file(PT_TTHE_TUNER_FILE_NAME, @@ -19218,7 +17313,6 @@ retry_hw_detect: pm_runtime_get_noresume(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); - /* If IRQ asserted, read out all from buffer to release INT pin */ if (cd->cpdata->irq_stat) { pt_flush_bus_if_irq_asserted(cd, PT_FLUSH_BUS_BASED_ON_LEN); @@ -19228,10 +17322,8 @@ retry_hw_detect: if (!rc) pt_parse_input(cd); } - /* Without sleep DUT is not ready and will NAK the first write */ msleep(150); - /* Attempt to set the DUT generation if not yet set */ if (cd->active_dut_generation == DUT_UNKNOWN) { if (cd->bl_pip_ver_ready || @@ -19252,18 +17344,17 @@ retry_hw_detect: } } } - _pt_request_active_pip_protocol(cd->dev, PT_CORE_CMD_PROTECTED, &pip_ver_major, &pip_ver_minor); if (pip_ver_major == 2) { cd->bl_pip_ver_ready = true; - pt_debug(dev, DL_WARN, + pt_debug(dev, DL_ERROR, " === PIP2.%d Detected, Attempt to launch APP ===\n", pip_ver_minor); cd->hw_detected = true; } else if (pip_ver_major == 1) { cd->app_pip_ver_ready = true; - pt_debug(dev, DL_WARN, + pt_debug(dev, DL_ERROR, " === PIP1.%d Detected ===\n", pip_ver_minor); cd->hw_detected = true; } else { @@ -19277,23 +17368,18 @@ retry_hw_detect: if (cd->active_dut_generation != DUT_PIP1_ONLY) goto skip_enum; } - rc = pt_enum_with_dut(cd, false, &status); - pt_debug(dev, DL_WARN, "%s: cd->startup_status=0x%04X status=0x%04X\n", + pt_debug(dev, DL_ERROR, "%s: cd->startup_status=0x%04X status=0x%04X\n", __func__, cd->startup_status, status); if (rc == -ENODEV) { pt_debug(cd->dev, DL_ERROR, "%s: Enumeration Failed r=%d\n", __func__, rc); -#ifndef PT_PTSBC_SUPPORT /* For PtSBC don't error out, allow TTDL to stay up */ goto error_after_startup; -#endif } - /* Suspend scanning until probe is complete to avoid asyc touches */ pt_pip_suspend_scanning_(cd); -#ifndef TTDL_KERNEL_SUBMISSION if (cd->hw_detected) { pt_debug(dev, DL_INFO, "%s: Add sysfs interfaces\n", __func__); @@ -19304,12 +17390,10 @@ retry_hw_detect: goto error_after_startup; } } else { - pt_debug(dev, DL_WARN, + pt_debug(dev, DL_ERROR, "%s: No HW detected, sysfs interfaces not added\n", __func__); } -#endif /* !TTDL_KERNEL_SUBMISSION */ - skip_enum: pm_runtime_put_sync(dev); @@ -19320,18 +17404,19 @@ skip_enum: __func__); goto error_after_sysfs_create; } - rc = pt_btn_probe(dev); if (rc < 0) { pt_debug(dev, DL_ERROR, "%s: Error, fail btn probe\n", __func__); goto error_after_startup_mt; } - pt_probe_modules(cd); #ifdef CONFIG_HAS_EARLYSUSPEND pt_setup_early_suspend(cd); +#elif defined(CONFIG_DRM) + pt_debug(dev, DL_ERROR, "%s: Probe: Setup drm notifier\n", __func__); + pt_setup_drm_notifier(cd); #elif defined(CONFIG_FB) pt_setup_fb_notifier(cd); #endif @@ -19341,13 +17426,12 @@ skip_enum: register_pm_notifier(&cd->pm_notifier); #endif pt_pip_resume_scanning_(cd); - mutex_lock(&cd->system_lock); cd->startup_status |= status; cd->core_probe_complete = 1; mutex_unlock(&cd->system_lock); - pt_debug(dev, DL_WARN, "%s: TTDL Core Probe Completed Successfully\n", + pt_debug(dev, DL_ERROR, "%s: TTDL Core Probe Completed Successfully\n", __func__); return 0; @@ -19365,9 +17449,7 @@ error_after_sysfs_create: cancel_work_sync(&cd->enum_work); pt_stop_wd_timer(cd); pt_free_si_ptrs(cd); -#ifndef TTDL_KERNEL_SUBMISSION remove_sysfs_interfaces(dev); -#endif /* !TTDL_KERNEL_SUBMISSION */ error_after_startup: pr_err("%s PARADE error_after_startup\n", __func__); @@ -19376,21 +17458,20 @@ error_after_startup: cd->cpdata->setup_irq(cd->cpdata, PT_MT_IRQ_FREE, dev); error_setup_irq: error_detect: -#ifdef PT_PTSBC_SUPPORT - del_timer(&cd->probe_timer); -#endif if (cd->cpdata->init) cd->cpdata->init(cd->cpdata, PT_MT_POWER_OFF, dev); if (cd->cpdata->setup_power) cd->cpdata->setup_power(cd->cpdata, PT_MT_POWER_OFF, dev); sysfs_remove_group(&dev->kobj, &early_attr_group); +error_enable_regulator: pt_del_core(dev); dev_set_drvdata(dev, NULL); - kfree(cd); -#ifndef PT_PTSBC_SUPPORT + pt_enable_regulator(cd, false); +error_get_regulator: + pt_get_regulator(cd, false); error_alloc_data: + kfree(cd); error_no_pdata: -#endif pr_err("%s failed.\n", __func__); return rc; } @@ -19434,16 +17515,10 @@ int pt_release(struct pt_core_data *cd) * all I2C/SPI communication. */ pt_stop_wd_timer(cd); -#ifdef PT_PTSBC_SUPPORT - cancel_work_sync(&cd->probe_work); -#endif call_atten_cb(cd, PT_ATTEN_CANCEL_LOADER, 0); cancel_work_sync(&cd->ttdl_restart_work); cancel_work_sync(&cd->enum_work); pt_stop_wd_timer(cd); -#ifdef PT_PTSBC_SUPPORT - cancel_work_sync(&cd->irq_work); -#endif pt_release_modules(cd); pt_proximity_release(dev); @@ -19452,6 +17527,9 @@ int pt_release(struct pt_core_data *cd) #ifdef CONFIG_HAS_EARLYSUSPEND unregister_early_suspend(&cd->es); +#elif defined(CONFIG_DRM) + if (active_panel) + drm_panel_notifier_unregister(active_panel, &cd->fb_notifier); #elif defined(CONFIG_FB) fb_unregister_client(&cd->fb_notifier); #endif @@ -19475,9 +17553,7 @@ int pt_release(struct pt_core_data *cd) sysfs_remove_group(&dev->kobj, &early_attr_group); -#ifndef TTDL_KERNEL_SUBMISSION remove_sysfs_interfaces(dev); -#endif /* !TTDL_KERNEL_SUBMISSION */ disable_irq_nosync(cd->irq); if (cd->cpdata->setup_irq) @@ -19488,8 +17564,9 @@ int pt_release(struct pt_core_data *cd) cd->cpdata->setup_power(cd->cpdata, PT_MT_POWER_OFF, dev); dev_set_drvdata(dev, NULL); pt_del_core(dev); + pt_enable_regulator(cd, false); + pt_get_regulator(cd, false); pt_free_si_ptrs(cd); - pt_free_hid_reports(cd); kfree(cd); return 0; } diff --git a/pt/pt_device_access.c b/pt/pt_device_access.c index af9e62b56a..80da0c98d8 100644 --- a/pt/pt_device_access.c +++ b/pt/pt_device_access.c @@ -1,4 +1,3 @@ -#ifndef TTDL_KERNEL_SUBMISSION /* * pt_device_access.c * Parade TrueTouch(TM) Standard Product Device Access Module. @@ -40,7 +39,7 @@ #define CMCP_THRESHOLD_FILE_NAME "ttdl_cmcp_thresholdfile.csv" /* Max test case number */ -#define MAX_CASE_NUM (23) +#define MAX_CASE_NUM (22) /* ASCII */ #define ASCII_LF (0x0A) @@ -52,9 +51,6 @@ /* Max characters of test case name */ #define NAME_SIZE_MAX (50) -/* Max characters of project information */ -#define NAME_PROJECT_INFO_MAX (128) - /* Max sensor and button number */ #define MAX_BUTTONS (PIP1_SYSINFO_MAX_BTN) #define MAX_SENSORS (5120) @@ -85,8 +81,6 @@ enum print_buffer_format { /* cmcp csv file information */ struct configuration { - /* One more space in the arrary below is left for null character */ - char proj_info[NAME_PROJECT_INFO_MAX + 1]; u32 cm_range_limit_row; u32 cm_range_limit_col; u32 cm_min_limit_cal; @@ -146,12 +140,10 @@ enum test_case_type { TEST_CASE_TYPE_ONE, TEST_CASE_TYPE_MUL, TEST_CASE_TYPE_MUL_LINES, - TEST_CASE_TYPE_STRING, }; /* Test case order in test_case_field_array */ enum case_order { - PROJ_VERSION, CM_TEST_INPUTS, CM_EXCLUDING_COL_EDGE, CM_EXCLUDING_ROW_EDGE, @@ -245,7 +237,7 @@ struct pt_device_access_data { struct dentry *cmcp_results_debugfs; struct dentry *base_dentry; struct dentry *mfg_test_dentry; - u8 ic_buf[10 * PT_MAX_PRBUF_SIZE]; + u8 ic_buf[PT_MAX_PRBUF_SIZE]; u8 response_buf[PT_MAX_PRBUF_SIZE]; struct mutex cmcp_threshold_lock; u8 *cmcp_threshold_data; @@ -353,7 +345,7 @@ static struct pt_module device_access_module; static ssize_t pt_run_and_get_selftest_result(struct device *dev, int protect, char *buf, size_t buf_len, u8 test_id, - u16 read_length, u8 get_result_on_pass, + u16 read_length, bool get_result_on_pass, bool print_results, u8 print_format); static int _pt_calibrate_idacs_cmd(struct device *dev, @@ -1820,36 +1812,36 @@ start_testing: if (result->test_summary) { pt_debug(dev, DL_INFO, "%s: Finish Cm/Cp test! All Test Passed\n", __func__); - index = snprintf(buf, PT_MAX_PRBUF_SIZE, "Status: 1\n"); + index = scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: 1\n"); } else { pt_debug(dev, DL_INFO, "%s: Finish Cm/Cp test! Range Check Failure\n", __func__); - index = snprintf(buf, PT_MAX_PRBUF_SIZE, "Status: 6\n"); + index = scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: 6\n"); } goto cmcp_ready; mismatch: - index = snprintf(buf, PT_MAX_PRBUF_SIZE, + index = scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: 2\nInput cmcp threshold file mismatches with FW\n"); goto cmcp_ready; invalid_item_btn: - index = snprintf(buf, PT_MAX_PRBUF_SIZE, + index = scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: 3\nFW doesn't support button!\n"); goto cmcp_ready; invalid_item: - index = snprintf(buf, PT_MAX_PRBUF_SIZE, + index = scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: 4\nWrong test item or range check input!\nOnly support below items:\n0 - Cm/Cp Panel & Button with Gradient (Typical)\n1 - Cm Panel with Gradient\n2 - Cp Panel\n3 - Cm Button\n4 - Cp Button\nOnly support below range check:\n0 - Full Range Checking (default)\n1 - Basic Range Checking(TSG5 style)\n"); goto cmcp_ready; self_test_failed: - index = snprintf(buf, PT_MAX_PRBUF_SIZE, + index = scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: 5\nget self test ID not supported!\n"); goto cmcp_ready; cmcp_not_ready: - index = snprintf(buf, PT_MAX_PRBUF_SIZE, "Status: 0\n"); + index = scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: 0\n"); goto cmcp_ready; no_builtin: - index = snprintf(buf, PT_MAX_PRBUF_SIZE, + index = scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: 7\nNo cmcp threshold file!\n"); cmcp_ready: mutex_lock(&dad->sysfs_lock); @@ -2030,17 +2022,16 @@ int prepare_print_data(char *out_buf, int32_t *in_buf, int index, int data_num) * index - index in output buffer for appending content * *result - pointer to result structure ******************************************************************************/ -int save_header(char *out_buf, int index, struct configuration *config, - struct result *result) +static int save_header(char *out_buf, int index, struct result *result) { struct rtc_time tm; char time_buf[100] = {0}; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)) - struct timespec64 ts; + struct timespec ts; - ktime_get_real_ts64(&ts); - rtc_time64_to_tm(ts.tv_sec, &tm); + getnstimeofday(&ts); + rtc_time_to_tm(ts.tv_sec, &tm); #else struct timex txc; @@ -2058,12 +2049,6 @@ int save_header(char *out_buf, int index, struct configuration *config, index = prepare_print_string(out_buf, ",SW_VERSION,", index); index = prepare_print_string(out_buf, PT_DRIVER_VERSION, index); index = prepare_print_string(out_buf, ",\n", index); - if (config) { - index = prepare_print_string(out_buf, ",PROJ_VERSION,", index); - index = prepare_print_string(out_buf, config->proj_info, index); - index = prepare_print_string(out_buf, ",\n", index); - } - index = prepare_print_string(out_buf, ",.end,\n", index); index = prepare_print_string(out_buf, ",.engineering data,\n", index); @@ -2972,7 +2957,7 @@ int result_save(struct device *dev, char *buf, if (cmcp_info == NULL) pt_debug(dev, DL_WARN, "cmcp_info is NULL"); - index = save_header(out_buf, index, configuration, result); + index = save_header(out_buf, index, result); index = save_engineering_data(dev, out_buf, index, cmcp_info, configuration, result, test_item, no_builtin_file); @@ -3318,65 +3303,6 @@ exit: return value; } -/******************************************************************************* - * FUNCTION: cmcp_get_one_string - * - * SUMMARY: Parses csv file at a given row and offset and find out one string - * which must start with a comma and should end with a comma. The character - * LF/CR will also be taken as the symbol to end the search. - * - * NOTE: There is a static value to calculate line count inside this function. - * - * RETURN: - * 0 = success - * !0 = failure - * - * PARAMETERS: - * *dev - pointer to devices structure - * *input_buf - pointer to input buffer - * *offset - offset index of input buffer - * *out_buf - pointer to store string - * out_buf_len - size of out_buf - * pFileEnd - pointer to the end of threshold file - ******************************************************************************/ -static int cmcp_get_one_string(struct device *dev, const char *input_buf, - u32 *offset, char *out_buf, u32 out_buf_len, - const char *pFileEnd) -{ - u8 token = ASCII_COMMA; - u32 i; - u32 temp_offset = *offset + 1; /* skip first comma */ - u32 pre_index; /* to store the start index of string */ - u32 next_index; /* to store the index of comma after string */ - u32 total_len = pFileEnd - input_buf; /* valid range of index */ - - memset(out_buf, 0, out_buf_len); - - pre_index = next_index = temp_offset; - for (i = temp_offset; i < total_len; i++) { - if (input_buf[i] == token || input_buf[i] == ASCII_LF || - input_buf[i] == ASCII_CR) { - next_index = i; - /* - * next_index could be equal to pre_index if string is - * null. The max size of string is restricted by macro - * NAME_PROJECT_INFO_MAX. - */ - if (pre_index < next_index) - memcpy(out_buf, input_buf + pre_index, - MIN(next_index - pre_index, - NAME_PROJECT_INFO_MAX)); - *offset = next_index; - return 0; - } - - if (input_buf[i] == ASCII_LF || input_buf[i] == ASCII_CR) - break; - } - - return -ENODATA; -} - /******************************************************************************* * FUNCTION: cmcp_get_configuration_info * @@ -3444,16 +3370,6 @@ void cmcp_get_configuration_info(struct device *dev, field_array[count].data_num = 1; field_array[count].line_num = 1; break; - case TEST_CASE_TYPE_STRING: - value_offset = search_array[sub_count].offset - + search_array[sub_count].name_size; - cmcp_get_one_string( - dev, buf, &value_offset, - (char *)field_array[count].bufptr, - NAME_PROJECT_INFO_MAX, pFileEnd); - field_array[count].data_num = 1; - field_array[count].line_num = 1; - break; case TEST_CASE_TYPE_MUL: case TEST_CASE_TYPE_MUL_LINES: line_num = 1; @@ -3658,8 +3574,6 @@ void cmcp_test_case_field_init(struct test_case_field *test_field_array, struct configuration *configs) { struct test_case_field test_case_field_array[MAX_CASE_NUM] = { - {"PROJ_VERSION", 12, TEST_CASE_TYPE_STRING, - (void *)&configs->proj_info, 0, 0, 0}, {"CM TEST INPUTS", 14, TEST_CASE_TYPE_NO, NULL, 0, 0, 0}, {"CM_EXCLUDING_COL_EDGE", 21, TEST_CASE_TYPE_ONE, @@ -4350,7 +4264,7 @@ exit: ******************************************************************************/ static ssize_t pt_run_and_get_selftest_result(struct device *dev, int protect, char *buf, size_t buf_len, u8 test_id, - u16 read_length, u8 get_result_on_pass, bool print_results, + u16 read_length, bool get_result_on_pass, bool print_results, u8 print_format) { struct pt_device_access_data *dad = pt_get_device_access_data(dev); @@ -4442,23 +4356,13 @@ static ssize_t pt_run_and_get_selftest_result(struct device *dev, length = 2; - /* - * For "auto_shorts" sysfs node, detailed data is - * retrieved only when the summary result is fail. - */ - if (get_result_on_pass == PT_ST_GET_RESULTS_BASED_ON_DATA && - test_id == PT_ST_ID_AUTOSHORTS && - summary_result == PT_ST_RESULT_PASS) - goto resume_scan; - /* * Get data if requested and the cmd status indicates that the test * completed with either a pass or a fail. All other status codes * indicate the test itself was not run so there is no data to retrieve */ if ((cmd_status == PT_ST_RESULT_PASS || - cmd_status == PT_ST_RESULT_FAIL) && - get_result_on_pass != PT_ST_DONT_GET_RESULTS) { + cmd_status == PT_ST_RESULT_FAIL) && get_result_on_pass) { rc = pt_get_selftest_result_cmd_(dev, 0, read_length, test_id, &cmd_status, &act_length, &dad->ic_buf[6]); if (rc) { @@ -5538,7 +5442,7 @@ static ssize_t auto_shorts_debugfs_read(struct file *filp, char __user *buf, data->dad->dev, PT_CORE_CMD_PROTECTED, data->pr_buf, sizeof(data->pr_buf), PT_ST_ID_AUTOSHORTS, PIP_CMD_MAX_LENGTH, - PT_ST_GET_RESULTS_BASED_ON_DATA, PT_ST_PRINT_RESULTS, + PT_ST_DONT_GET_RESULTS, PT_ST_PRINT_RESULTS, PT_PR_FORMAT_DEFAULT); return simple_read_from_buffer(buf, count, ppos, data->pr_buf, @@ -5832,7 +5736,7 @@ exit: /******************************************************************************* * FUNCTION: fw_self_test_debugfs_write * - * SUMMARY: Store the self test ID and output format, the read method will + * SUMMARY: Store the self test ID and ouptut format, the read method will * perform. * * RETURN: Size of debugfs data write @@ -5968,7 +5872,7 @@ static ssize_t tthe_get_panel_data_debugfs_read(struct file *filp, rc = pt_ret_scan_data_cmd_(dev, elem_offset, PT_MAX_ELEN, dad->heatmap.data_type, dad->ic_buf, &config, &actual_read_len, NULL); - } else{ + } else { rc = pt_ret_scan_data_cmd_(dev, elem_offset, elem, dad->heatmap.data_type, dad->ic_buf, &config, &actual_read_len, NULL); @@ -5994,7 +5898,7 @@ static ssize_t tthe_get_panel_data_debugfs_read(struct file *filp, rc = pt_ret_scan_data_cmd_(dev, elem_offset, PT_MAX_ELEN, dad->heatmap.data_type, NULL, &config, &actual_read_len, buf_offset); - } else{ + } else { rc = pt_ret_scan_data_cmd_(dev, elem_offset, elem, dad->heatmap.data_type, NULL, &config, &actual_read_len, buf_offset); @@ -6355,7 +6259,7 @@ static int pt_setup_sysfs(struct device *dev) rc = device_create_file(dev, &dev_attr_cmcp_threshold_loading); if (rc) { pt_debug(dev, DL_ERROR, - "%s: Error, could not create cmcp_thresold_loading\n", + "%s: Error, could not create cmcp_threshold_loading\n", __func__); goto unregister_cmcp_test; } @@ -6363,7 +6267,7 @@ static int pt_setup_sysfs(struct device *dev) rc = device_create_bin_file(dev, &bin_attr_cmcp_threshold_data); if (rc) { pt_debug(dev, DL_ERROR, - "%s: Error, could not create cmcp_thresold_data\n", + "%s: Error, could not create cmcp_threshold_data\n", __func__); goto unregister_cmcp_thresold_loading; } @@ -6827,4 +6731,3 @@ module_exit(pt_device_access_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Parade TrueTouch(R) Standard Product Device Access Driver"); MODULE_AUTHOR("Parade Technologies "); -#endif /* !TTDL_KERNEL_SUBMISSION */ diff --git a/pt/pt_devtree.c b/pt/pt_devtree.c index b147a7d0d5..9b6261a0cf 100644 --- a/pt/pt_devtree.c +++ b/pt/pt_devtree.c @@ -31,8 +31,8 @@ #include #include #include -#include "pt_regs.h" #include +#include "pt_regs.h" #define MAX_NAME_LENGTH 64 @@ -41,7 +41,6 @@ static bool is_create_and_get_pdata; enum pt_device_type { DEVICE_MT, DEVICE_BTN, - DEVICE_PEN, DEVICE_PROXIMITY, DEVICE_TYPE_MAX, }; @@ -485,58 +484,6 @@ static void free_btn_pdata(void *pdata) kfree(btn_pdata); } -/******************************************************************************* - * FUNCTION: create_and_get_pen_pdata - * - * SUMMARY: Create and get pen platform data from dts. - * - * RETURN: - * success: the pointer of the platform data - * fail : error code with type of error pointer - * - * PARAMETERS: - * *dev_node - pointer to device_node structure - ******************************************************************************/ -static void *create_and_get_pen_pdata(struct device_node *dev_node) -{ - struct pt_pen_platform_data *pdata; - int rc; - - pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); - if (!pdata) { - rc = -ENOMEM; - goto fail; - } - - rc = get_inp_dev_name(dev_node, &pdata->inp_dev_name); - if (rc) - goto fail_free_pdata; - - return pdata; - -fail_free_pdata: - kfree(pdata); -fail: - return ERR_PTR(rc); -} - -/******************************************************************************* - * FUNCTION: free_pen_pdata - * - * SUMMARY: Free all pointers for pen platform data. - * - * PARAMETERS: - * *pdata - pointer to virtual key structure - ******************************************************************************/ -static void free_pen_pdata(void *pdata) -{ - struct pt_pen_platform_data *pen_pdata = - (struct pt_pen_platform_data *)pdata; - - kfree(pen_pdata); -} - - /******************************************************************************* * FUNCTION: create_and_get_proximity_pdata * @@ -608,10 +555,6 @@ static struct pt_device_pdata_func device_pdata_funcs[DEVICE_TYPE_MAX] = { .create_and_get_pdata = create_and_get_btn_pdata, .free_pdata = free_btn_pdata, }, - [DEVICE_PEN] = { - .create_and_get_pdata = create_and_get_pen_pdata, - .free_pdata = free_pen_pdata, - }, [DEVICE_PROXIMITY] = { .create_and_get_pdata = create_and_get_proximity_pdata, .free_pdata = free_proximity_pdata, @@ -623,7 +566,6 @@ static struct pt_pdata_ptr pdata_ptr[DEVICE_TYPE_MAX]; static const char *device_names[DEVICE_TYPE_MAX] = { [DEVICE_MT] = "parade,mt", [DEVICE_BTN] = "parade,btn", - [DEVICE_PEN] = "parade,pen", [DEVICE_PROXIMITY] = "parade,proximity", }; @@ -639,7 +581,6 @@ static void set_pdata_ptr(struct pt_platform_data *pdata) { pdata_ptr[DEVICE_MT].pdata = (void **)&pdata->mt_pdata; pdata_ptr[DEVICE_BTN].pdata = (void **)&pdata->btn_pdata; - pdata_ptr[DEVICE_PEN].pdata = (void **)&pdata->pen_pdata; pdata_ptr[DEVICE_PROXIMITY].pdata = (void **)&pdata->prox_pdata; } @@ -805,6 +746,49 @@ static char *touch_setting_names[PT_IC_GRPNUM_NUM] = { NULL, /* PT_IC_GRPNUM_TTHE_REGS */ }; +/******************************************************************************* + * FUNCTION: pt_check_dsi_panel_dt + * + * SUMMARY: Get the DSI active panel information from dtsi + * + * RETURN: + * 0 = success + * !0 = fail + * + * PARAMETERS: + * np - pointer to device_node structure + * active_panel - name of active DSI panel + ******************************************************************************/ + + +static int pt_check_dsi_panel_dt(struct device_node *np, struct drm_panel **active_panel) +{ + int i; + int count; + struct device_node *node; + struct drm_panel *panel; + + count = of_count_phandle_with_args(np, "panel", NULL); + pr_info("%s: Active panel count: %d\n", __func__, count); + if (count <= 0) + return 0; + + for (i = 0; i < count; i++) { + node = of_parse_phandle(np, "panel", i); + if (node != NULL) + pr_info("%s: Node handle successfully parsed !\n", __func__); + panel = of_drm_find_panel(node); + of_node_put(node); + if (!IS_ERR(panel)) { + pr_info("%s: Active panel selected !\n", __func__); + *active_panel = panel; + return 0; + } + } + pr_err("%s: Active panel NOT selected !\n", __func__); + return PTR_ERR(panel); +} + /******************************************************************************* * FUNCTION: create_and_get_core_pdata * @@ -832,9 +816,7 @@ static struct pt_core_platform_data *create_and_get_core_pdata( } /* Required fields */ - rc = of_property_read_u32(core_node, "parade,irq_gpio", &value); - if (rc) - goto fail_free; + value = of_get_named_gpio_flags(core_node, "parade,irq_gpio", 0, &pdata->irq_gpio_flags); pdata->irq_gpio = value; rc = of_property_read_u32(core_node, "parade,hid_desc_register", @@ -847,9 +829,8 @@ static struct pt_core_platform_data *create_and_get_core_pdata( /* rst_gpio is optional since a platform may use * power cycling instead of using the XRES pin */ - rc = of_property_read_u32(core_node, "parade,rst_gpio", &value); - if (!rc) - pdata->rst_gpio = value; + value = of_get_named_gpio_flags(core_node, "parade,rst_gpio", 0, &pdata->rst_gpio_flags); + pdata->rst_gpio = value; rc = of_property_read_u32(core_node, "parade,ddi_rst_gpio", &value); if (!rc) @@ -1006,10 +987,13 @@ int pt_devtree_create_and_get_pdata(struct device *adap_dev) { struct pt_platform_data *pdata; struct device_node *core_node, *dev_node, *dev_node_fail; + struct drm_panel *active_panel = NULL; enum pt_device_type type; int count = 0; int rc = 0; + pr_info("%s: Start of fetch dtsi..\n", __func__); + if (is_create_and_get_pdata == true) return 0; @@ -1031,12 +1015,28 @@ int pt_devtree_create_and_get_pdata(struct device *adap_dev) if (!rc) pr_debug("%s: name:%s\n", __func__, name); + rc = pt_check_dsi_panel_dt(core_node, &active_panel); + if (rc) { + pr_err("%s: Panel not selected, rc=%d\n", __func__, rc); + if (rc == -EPROBE_DEFER) { + pr_err("%s: Probe defer selected, rc=%d\n", __func__, rc); + kfree(pdata); + return rc; + } + } + pdata->core_pdata = create_and_get_core_pdata(core_node); if (IS_ERR(pdata->core_pdata)) { + pr_err("%s: Error in fetch dtsi..\n", __func__); rc = PTR_ERR(pdata->core_pdata); break; } + pr_info("%s: End of fetch dtsi..\n", __func__); + pdata->core_pdata->active_panel = active_panel; + pr_info("%s: Successful insert of active panel in core data\n", + __func__); + /* Increment reference count */ of_node_get(core_node); diff --git a/pt/pt_i2c.c b/pt/pt_i2c.c index 111834d92d..5ce74720d9 100644 --- a/pt/pt_i2c.c +++ b/pt/pt_i2c.c @@ -33,188 +33,7 @@ #include #define PT_I2C_DATA_SIZE (2 * 256) - -#ifdef TTDL_PTVIRTDUT_SUPPORT -#define VIRT_DUT_BUF_SIZE 2048 -static unsigned char pt_dut_cmd_buf[VIRT_DUT_BUF_SIZE]; -static unsigned char pt_dut_out_buf[VIRT_DUT_BUF_SIZE]; -static int pt_dut_cmd_len; -static int pt_dut_out_len; -DEFINE_MUTEX(virt_i2c_lock); - -/******************************************************************************* - * FUNCTION: virt_i2c_transfer - * - * SUMMARY: Copies the current i2c output message to the temporary buffer - * used by the dut_cmd sysfs node - * - * RETURN VALUE: - * Number of messages transferred which in this function will be 1 - * - * PARAMETERS: - * *buf - pointer to i2c command - * len - length of command in the buffer - ******************************************************************************/ -static int virt_i2c_transfer(u8 *buf, int len) -{ - int rc = 0; - - mutex_lock(&virt_i2c_lock); - if (len <= sizeof(pt_dut_cmd_buf)) { - memcpy(pt_dut_cmd_buf, buf, len); - pt_dut_cmd_len = len; - rc = 1; - } else - rc = 0; - mutex_unlock(&virt_i2c_lock); - - return rc; -} - -/******************************************************************************* - * FUNCTION: virt_i2c_master_recv - * - * SUMMARY: Copies the i2c input message from the dut_out sysfs node into a - * temporary buffer. - * - * RETURN VALUE: - * Length of data transferred - * - * PARAMETERS: - * *dev - pointer to device struct - * *buf - pointer to i2c incoming report - * size - size to be read - ******************************************************************************/ -static int virt_i2c_master_recv(struct device *dev, u8 *buf, int size) -{ -#ifndef PT_POLL_RESP_BY_BUS - struct pt_core_data *cd = dev_get_drvdata(dev); - int i = 0; -#endif - - mutex_lock(&virt_i2c_lock); - memcpy(buf, pt_dut_out_buf, size); - - /* Set "empty buffer" */ - pt_dut_out_buf[1] = 0xFF; - pt_dut_out_len = 0; - mutex_unlock(&virt_i2c_lock); - -#ifndef PT_POLL_RESP_BY_BUS - if (cd->bl_with_no_int) { - /* - * Wait for IRQ gpio to be released, make read operation - * synchronize with PtVirtDut tool. - * Safety net: Exit after 500ms (50us * 10000 loops = 500ms) - */ - while (i < VIRT_MAX_IRQ_RELEASE_TIME_US && - !gpio_get_value(cd->cpdata->irq_gpio)) { - pt_debug(dev, DL_INFO, "%s: %d IRQ still Enabled\n", - __func__, i); - usleep_range(50, 60); - i += 50; - } - } -#endif - - pt_debug(dev, DL_INFO, - "%s: Copy msg from dut_out to i2c buffer, size=%d\n", - __func__, size); - - return size; -} - -/******************************************************************************* - * FUNCTION: pt_dut_cmd_show - * - * SUMMARY: The show function for the dut_cmd sysfs node. Provides read access - * to the pt_dut_cmd_buf and clears it after it has been read. - * - * RETURN VALUE: - * Number of bytes transferred - * - * PARAMETERS: - * *dev - pointer to device structure - * *attr - pointer to device attributes - * *buf - pointer to output buffer - ******************************************************************************/ -static ssize_t pt_dut_cmd_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int i; - int index = 0; - - /* Only print to sysfs if the buffer has data */ - mutex_lock(&virt_i2c_lock); - if (pt_dut_cmd_len > 0) { - for (i = 0; i < pt_dut_cmd_len; i++) - index += scnprintf(buf + index, strlen(buf), "%02X", - pt_dut_cmd_buf[i]); - index += scnprintf(buf + index, strlen(buf), "\n"); - } - pt_dut_cmd_len = 0; - mutex_unlock(&virt_i2c_lock); - return index; -} -static DEVICE_ATTR(dut_cmd, 0444, pt_dut_cmd_show, NULL); - -/******************************************************************************* - * FUNCTION: pt_dut_out_store - * - * SUMMARY: The store function for the dut_out sysfs node. Provides write - * access to the pt_dut_out_buf. The smallest valid PIP response is 2 - * bytes so don't update buffer if only 1 byte passed in. - * - * RETURN VALUE: - * Number of bytes read from virtual DUT - * - * PARAMETERS: - * *dev - pointer to device structure - * *attr - pointer to device attributes - * *buf - pointer to buffer that hold the command parameters - * size - size of buf - ******************************************************************************/ -static ssize_t pt_dut_out_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - int loop_max = ARRAY_SIZE(pt_dut_out_buf); - int hex_str_len = strlen(buf)/2; - int i; - const char *pos = buf; - struct pt_core_data *cd = dev_get_drvdata(dev); - - /* Clear out the last message */ - mutex_lock(&virt_i2c_lock); - memset(pt_dut_out_buf, 0, VIRT_DUT_BUF_SIZE); - pt_dut_out_len = 0; - - /* Only update the dut_out buffer if at least 2 byte payload */ - if (size >= 2 && hex_str_len <= loop_max) { - /* Convert string of hex values to byte array */ - for (i = 0; i < hex_str_len; i++) { - pt_dut_out_buf[i] = ((HEXOF(*pos)) << 4) + - HEXOF(*(pos + 1)); - pos += 2; - } - /* - * In HID we send the full string, non HID we send based - * on the 2 byte length. - */ - if (cd->dut_status.protocol_mode == PT_PROTOCOL_MODE_HID) - pt_dut_out_len = hex_str_len; - else - pt_dut_out_len = get_unaligned_le16(&pt_dut_out_buf[0]); - } else if (size >= PT_PIP_1P7_EMPTY_BUF) { - /* Message too large, set to 'empty buffer' message */ - pt_dut_out_buf[1] = 0xFF; - pt_dut_out_len = 0; - } - mutex_unlock(&virt_i2c_lock); - - return size; -} -static DEVICE_ATTR(dut_out, 0200, NULL, pt_dut_out_store); -#endif /* TTDL_PTVIRTDUT_SUPPORT */ +#define PT_I2C_NAME "pt_i2c_adapter" /******************************************************************************* * FUNCTION: pt_i2c_read_default @@ -228,24 +47,14 @@ static DEVICE_ATTR(dut_out, 0200, NULL, pt_dut_out_store); ******************************************************************************/ static int pt_i2c_read_default(struct device *dev, void *buf, int size) { -#ifdef TTDL_PTVIRTDUT_SUPPORT - struct pt_core_data *cd = dev_get_drvdata(dev); -#endif /* TTDL_PTVIRTDUT_SUPPORT */ struct i2c_client *client = to_i2c_client(dev); int rc; int read_size = size; - if (!buf || !size || size > VIRT_DUT_BUF_SIZE) + if (!buf || !size || size > PT_I2C_DATA_SIZE) return -EINVAL; -#ifdef TTDL_PTVIRTDUT_SUPPORT - if (cd->route_bus_virt_dut) - rc = virt_i2c_master_recv(dev, buf, read_size); - else - rc = i2c_master_recv(client, buf, read_size); -#else rc = i2c_master_recv(client, buf, read_size); -#endif /* TTDL_PTVIRTDUT_SUPPORT */ return (rc < 0) ? rc : rc != read_size ? -EIO : 0; } @@ -270,22 +79,6 @@ static int pt_i2c_read_default_nosize(struct device *dev, u8 *buf, u32 max) u8 msg_count = 1; int rc; u32 size; -#ifdef TTDL_PTVIRTDUT_SUPPORT - struct pt_core_data *cd = dev_get_drvdata(dev); - - if (cd->route_bus_virt_dut) { - mutex_lock(&virt_i2c_lock); - size = pt_dut_out_len; - mutex_unlock(&virt_i2c_lock); - pt_debug(dev, DL_INFO, "%s: pt_dut_out_len=%d\n", - __func__, pt_dut_out_len); - /* Only copy 2 bytes for "empty buffer" or "FW sentinel" */ - if (!size || size == 2 || size >= PT_PIP_1P7_EMPTY_BUF) - size = 2; - goto skip_read_len; - } - -#endif /* TTDL_PTVIRTDUT_SUPPORT */ if (!buf) return -EINVAL; @@ -309,17 +102,7 @@ static int pt_i2c_read_default_nosize(struct device *dev, u8 *buf, u32 max) if (size > max) return -EINVAL; -#ifdef TTDL_PTVIRTDUT_SUPPORT -skip_read_len: - if (cd->route_bus_virt_dut) - rc = virt_i2c_master_recv(dev, buf, size); - else - rc = i2c_master_recv(client, buf, size); - - pt_debug(dev, DL_INFO, "%s: rc = %d\n", __func__, rc); -#else rc = i2c_master_recv(client, buf, size); -#endif /* TTDL_PTVIRTDUT_SUPPORT */ return (rc < 0) ? rc : rc != (int)size ? -EIO : 0; } @@ -327,22 +110,18 @@ skip_read_len: * FUNCTION: pt_i2c_write_read_specific * * SUMMARY: Write the contents of write_buf to the I2C device and then read - * the response using pt_i2c_read_default_nosize() + * the response using pt_i2c_read_default_nosize() * * PARAMETERS: - * *dev - pointer to Device structure - * write_len - length of data buffer write_buf - * *write_buf - pointer to buffer to write - * *read_buf - pointer to buffer to read response into - * read_len - length to read, 0 to use pt_i2c_read_default_nosize + * *dev - pointer to Device structure + * write_len - length of data buffer write_buf + * *write_buf - pointer to buffer to write + * *read_buf - pointer to buffer to read response into ******************************************************************************/ static int pt_i2c_write_read_specific(struct device *dev, u16 write_len, - u8 *write_buf, u8 *read_buf, u16 read_len) + u8 *write_buf, u8 *read_buf) { struct i2c_client *client = to_i2c_client(dev); -#ifdef TTDL_PTVIRTDUT_SUPPORT - struct pt_core_data *cd = dev_get_drvdata(dev); -#endif /* TTDL_PTVIRTDUT_SUPPORT */ struct i2c_msg msgs[2]; u8 msg_count = 1; int rc; @@ -365,16 +144,7 @@ static int pt_i2c_write_read_specific(struct device *dev, u16 write_len, msgs[0].flags = client->flags & I2C_M_TEN; msgs[0].len = write_len; msgs[0].buf = write_buf; -#ifdef TTDL_PTVIRTDUT_SUPPORT - if (cd->route_bus_virt_dut) { - rc = virt_i2c_transfer(msgs[0].buf, msgs[0].len); - pt_debug(dev, DL_DEBUG, "%s: Virt transfer size = %d", - __func__, msgs[0].len); - } else - rc = i2c_transfer(client->adapter, msgs, msg_count); -#else rc = i2c_transfer(client->adapter, msgs, msg_count); -#endif /* TTDL_PTVIRTDUT_SUPPORT */ if (rc < 0 || rc != msg_count) return (rc < 0) ? rc : -EIO; @@ -382,17 +152,7 @@ static int pt_i2c_write_read_specific(struct device *dev, u16 write_len, rc = 0; if (read_buf) { -#ifdef TTDL_PTVIRTDUT_SUPPORT - if (cd->route_bus_virt_dut && - cd->dut_status.protocol_mode == PT_PROTOCOL_MODE_HID) { - /* Simulate clock stretch */ - usleep_range(3000, 4000); - } -#endif /* TTDL_PTVIRTDUT_SUPPORT */ - if (read_len > 0) - rc = pt_i2c_read_default(dev, read_buf, read_len); - else - rc = pt_i2c_read_default_nosize(dev, read_buf, + rc = pt_i2c_read_default_nosize(dev, read_buf, PT_I2C_DATA_SIZE); } @@ -432,12 +192,10 @@ static int pt_i2c_probe(struct i2c_client *client, const struct of_device_id *match; #endif int rc; - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { pt_debug(dev, DL_ERROR, "I2C functionality not Supported\n"); return -EIO; } - #ifdef CONFIG_TOUCHSCREEN_PARADE_DEVICETREE_SUPPORT match = of_match_device(of_match_ptr(pt_i2c_of_match), dev); if (match) { @@ -447,17 +205,6 @@ static int pt_i2c_probe(struct i2c_client *client, } #endif -#ifdef TTDL_PTVIRTDUT_SUPPORT - /* - * When using the virtual DUT these files must be created before - * pt_probe is called. - */ - mutex_lock(&virt_i2c_lock); - device_create_file(dev, &dev_attr_dut_cmd); - device_create_file(dev, &dev_attr_dut_out); - mutex_unlock(&virt_i2c_lock); -#endif /* TTDL_PTVIRTDUT_SUPPORT */ - rc = pt_probe(&pt_i2c_bus_ops, &client->dev, client->irq, PT_I2C_DATA_SIZE); @@ -465,15 +212,6 @@ static int pt_i2c_probe(struct i2c_client *client, if (rc && match) pt_devtree_clean_pdata(dev); #endif -#ifdef TTDL_PTVIRTDUT_SUPPORT - if (rc) { - mutex_lock(&virt_i2c_lock); - device_remove_file(dev, &dev_attr_dut_cmd); - device_remove_file(dev, &dev_attr_dut_out); - mutex_unlock(&virt_i2c_lock); - } -#endif /* TTDL_PTVIRTDUT_SUPPORT */ - return rc; } @@ -494,12 +232,6 @@ static int pt_i2c_remove(struct i2c_client *client) struct pt_core_data *cd = i2c_get_clientdata(client); pt_release(cd); -#ifdef TTDL_PTVIRTDUT_SUPPORT - mutex_lock(&virt_i2c_lock); - device_remove_file(dev, &dev_attr_dut_cmd); - device_remove_file(dev, &dev_attr_dut_out); - mutex_unlock(&virt_i2c_lock); -#endif /* TTDL_PTVIRTDUT_SUPPORT */ #ifdef CONFIG_TOUCHSCREEN_PARADE_DEVICETREE_SUPPORT match = of_match_device(of_match_ptr(pt_i2c_of_match), dev); diff --git a/pt/pt_loader.c b/pt/pt_loader.c index c57657e346..ca53aa904b 100644 --- a/pt/pt_loader.c +++ b/pt/pt_loader.c @@ -32,13 +32,6 @@ #define PT_LOADER_NAME "pt_loader" -#ifdef UPGRADE_FW_AND_CONFIG_IN_PROBE -/* Enable UPGRADE_FW_AND_CONFIG_IN_PROBE definition - * to perform FW and config upgrade during probe - * instead of scheduling a work for it - */ -/* #define UPGRADE_FW_AND_CONFIG_IN_PROBE */ -#endif #define PT_AUTO_LOAD_FOR_CORRUPTED_FW 1 #define PT_LOADER_FW_UPGRADE_RETRY_COUNT 3 @@ -133,16 +126,13 @@ struct pt_loader_data { #endif }; -static u8 write_file_status; -#ifndef TTDL_KERNEL_SUBMISSION +static u8 update_fw_status; static int pip2_erase_status; static int pip2_erase_rc; -#endif /* !TTDL_KERNEL_SUBMISSION */ /* PIP2 update fw status codes. 1-99% are "active" */ enum UPDATE_FW_STATUS { UPDATE_FW_IDLE = 0, - UPDATE_FW_REQUEST_EXCLUSIVE = 1, UPDATE_FW_ACTIVE_10 = 10, UPDATE_FW_ACTIVE_90 = 90, UPDATE_FW_ACTIVE_99 = 99, @@ -162,7 +152,6 @@ enum UPDATE_FW_STATUS { UPDATE_FW_EXCLUSIVE_ACCESS_ERROR = 212, UPDATE_FW_NO_FW_PROVIDED = 213, UPDATE_FW_INVALID_FW_IMAGE = 214, - UPDATE_FW_FILE_SEEK_ERROR = 215, UPDATE_FW_MISALIGN_FW_IMAGE = 230, UPDATE_FW_SYSTEM_NOMEM = 231, UPDATE_FW_INIT_BL_ERROR = 232, @@ -171,12 +160,7 @@ enum UPDATE_FW_STATUS { UPDATE_FW_EXIT_BL_ERROR = 235, UPDATE_FW_CHECK_SUM_ERROR = 236, UPDATE_FW_NO_PLATFORM_DATA = 237, - UPDATE_FW_NOT_SUPPORTED_FILE_NO = 238, UPDATE_FW_UNDEFINED_ERROR = 255, - UPDATE_FW_INCREMENT = 300, - UPDATE_FW_INCREMENT_BY_1 = 301, - UPDATE_FW_INCREMENT_BY_5 = 305, - UPDATE_FW_UNDEFINED_INC = 400, }; enum PIP2_FILE_ERASE_STATUS { @@ -380,7 +364,7 @@ static int pt_check_firmware_version(struct device *dev, if (fw_ver_new < fw_ver_img) { pt_debug(dev, DL_WARN, "%s: Image is older, will NOT upgrade\n", __func__); - return -1; + return -EPERM; } fw_revctrl_img = ld->si->ttdata.revctrl; @@ -398,7 +382,7 @@ static int pt_check_firmware_version(struct device *dev, if (fw_revctrl_new < fw_revctrl_img) { pt_debug(dev, DL_WARN, "%s: Image is older, will NOT upgrade\n", __func__); - return -1; + return -EPERM; } return 0; @@ -642,6 +626,7 @@ static int pt_ldr_exit_(struct device *dev) return cmd->nonhid_cmd->launch_app(dev, 0); } +#define PT_NO_INC 0 /******************************************************************************* * FUNCTION: _pt_pip2_update_bl_status * @@ -650,53 +635,43 @@ static int pt_ldr_exit_(struct device *dev) * * PARAMETERS: * *dev - pointer to device structure - * value - Value to force. + * value - Value to force, if 0 then ignore. + * inc - Value to increment, if 0 then ignore. ******************************************************************************/ -static u8 _pt_update_write_file_status(struct device *dev, u16 value) +static u8 _pt_pip2_update_bl_status(struct device *dev, u8 value, u8 inc) { - u8 inc = 0; - pt_debug(dev, DL_DEBUG, - "%s: fw_status = %d, request val=%d\n", - __func__, write_file_status, value); + "%s: fw_status = %d, request val=%d, request inc=%d\n", + __func__, update_fw_status, value, inc); - /* Reset status if value is 0 */ - if (value == UPDATE_FW_IDLE) { - write_file_status = value; + /* Reset status if both value and inc are 0 */ + if (value == UPDATE_FW_IDLE && inc == 0) { + update_fw_status = value; pt_debug(dev, DL_WARN, "%s: ATM - Reset BL Status to %d\n", __func__, value); - return write_file_status; + return update_fw_status; } /* Set to value if valid */ if (value > UPDATE_FW_IDLE && value < UPDATE_FW_UNDEFINED_ERROR) { - if (value <= UPDATE_FW_COMPLETE && value > write_file_status) { - write_file_status = value; - pt_debug(dev, DL_DEBUG, "%s: Set BL Status to %d\n", - __func__, value); + if (value <= UPDATE_FW_COMPLETE && value > update_fw_status) { + update_fw_status = value; } else if (value >= UPDATE_FW_GENERAL_ERROR) { - write_file_status = value; + update_fw_status = value; pt_debug(dev, DL_WARN, "%s: BL Status set to error code %d\n", __func__, value); } - return write_file_status; + return update_fw_status; } - if (value > UPDATE_FW_INCREMENT && value < UPDATE_FW_UNDEFINED_INC) { - inc = value - UPDATE_FW_INCREMENT; - if (write_file_status + inc <= UPDATE_FW_COMPLETE) - write_file_status += inc; - else - pt_debug(dev, DL_ERROR, - "%s: Inc Request out of bounds: status=%d inc=%d\n", - __func__, write_file_status, inc); - } else + if (inc > 0 && update_fw_status + inc <= UPDATE_FW_COMPLETE) + update_fw_status += inc; + else pt_debug(dev, DL_ERROR, - "%s: Value Request out of bounds: status=%d value=%d\n", - __func__, write_file_status, value); - - return write_file_status; + "%s: Inc Request out of bounds: status=%d inc=%d\n", + __func__, update_fw_status, inc); + return update_fw_status; } /******************************************************************************* @@ -936,7 +911,7 @@ static int pt_upgrade_firmware(struct device *dev, const u8 *fw_img, int rc; int t; - _pt_update_write_file_status(dev, UPDATE_FW_IDLE); + _pt_pip2_update_bl_status(dev, UPDATE_FW_IDLE, PT_NO_INC); if (update_status == NULL) { rc = -EINVAL; @@ -1180,7 +1155,8 @@ static int upgrade_firmware_from_platform(struct device *dev, retry_bl: if (!ld->loader_pdata) { - _pt_update_write_file_status(dev, UPDATE_FW_NO_PLATFORM_DATA); + _pt_pip2_update_bl_status(dev, UPDATE_FW_NO_PLATFORM_DATA, + PT_NO_INC); pt_debug(dev, DL_ERROR, "%s: No loader platform data\n", __func__); return rc; @@ -1188,14 +1164,16 @@ retry_bl: fw = pt_get_platform_firmware(dev); if (!fw || !fw->img || !fw->size) { - _pt_update_write_file_status(dev, UPDATE_FW_NO_FW_PROVIDED); + _pt_pip2_update_bl_status(dev, UPDATE_FW_NO_FW_PROVIDED, + PT_NO_INC); pt_debug(dev, DL_ERROR, "%s: No platform firmware\n", __func__); return rc; } if (!fw->ver || !fw->vsize) { - _pt_update_write_file_status(dev, UPDATE_FW_INVALID_FW_IMAGE); + _pt_pip2_update_bl_status(dev, UPDATE_FW_INVALID_FW_IMAGE, + PT_NO_INC); pt_debug(dev, DL_ERROR, "%s: No platform firmware version\n", __func__); return rc; @@ -1208,7 +1186,7 @@ retry_bl: if (upgrade) { rc = pt_upgrade_firmware(dev, - fw->img, fw->size, &write_file_status); + fw->img, fw->size, &update_fw_status); /* An extra BL may be needed if default PID was wrong choice */ if ((cd->panel_id_support & PT_PANEL_ID_BY_SYS_INFO) && @@ -1244,11 +1222,12 @@ static int _pt_pip1_bl_from_file(struct device *dev) u8 *fw_img = NULL; u8 header_size = 0; - _pt_update_write_file_status(dev, UPDATE_FW_IDLE); + _pt_pip2_update_bl_status(dev, UPDATE_FW_IDLE, PT_NO_INC); fw_img = kzalloc(PT_PIP2_MAX_FILE_SIZE, GFP_KERNEL); if (!fw_img) { - _pt_update_write_file_status(dev, UPDATE_FW_SYSTEM_NOMEM); + _pt_pip2_update_bl_status(dev, UPDATE_FW_SYSTEM_NOMEM, + PT_NO_INC); rc = -ENOMEM; goto exit; } @@ -1258,14 +1237,16 @@ static int _pt_pip1_bl_from_file(struct device *dev) if (rc) { pt_debug(dev, DL_ERROR, "%s: No firmware provided to load\n", __func__); - _pt_update_write_file_status(dev, UPDATE_FW_NO_FW_PROVIDED); + _pt_pip2_update_bl_status(dev, UPDATE_FW_NO_FW_PROVIDED, + PT_NO_INC); goto exit; } if (!fw_img || !fw_size) { pt_debug(dev, DL_ERROR, "%s: No firmware received\n", __func__); - _pt_update_write_file_status(dev, UPDATE_FW_INVALID_FW_IMAGE); + _pt_pip2_update_bl_status(dev, UPDATE_FW_INVALID_FW_IMAGE, + PT_NO_INC); goto exit; } @@ -1273,12 +1254,13 @@ static int _pt_pip1_bl_from_file(struct device *dev) if (header_size >= (fw_size + 1)) { pt_debug(dev, DL_ERROR, "%s: Firmware format is invalid\n", __func__); - _pt_update_write_file_status(dev, UPDATE_FW_INVALID_FW_IMAGE); + _pt_pip2_update_bl_status(dev, UPDATE_FW_INVALID_FW_IMAGE, + PT_NO_INC); goto exit; } pt_upgrade_firmware(dev, &(fw_img[header_size + 1]), - fw_size - (header_size + 1), &write_file_status); + fw_size - (header_size + 1), &update_fw_status); exit: kfree(fw_img); return rc; @@ -1300,17 +1282,19 @@ static void _pt_firmware_cont(const struct firmware *fw, void *context) struct pt_loader_data *ld = pt_get_loader_data(dev); u8 header_size = 0; - _pt_update_write_file_status(dev, UPDATE_FW_IDLE); + _pt_pip2_update_bl_status(dev, UPDATE_FW_IDLE, PT_NO_INC); if (!fw) { pt_debug(dev, DL_ERROR, "%s: No firmware\n", __func__); - _pt_update_write_file_status(dev, UPDATE_FW_NO_FW_PROVIDED); + _pt_pip2_update_bl_status(dev, UPDATE_FW_NO_FW_PROVIDED, + PT_NO_INC); goto pt_firmware_cont_exit; } if (!fw->data || !fw->size) { pt_debug(dev, DL_ERROR, "%s: No firmware received\n", __func__); - _pt_update_write_file_status(dev, UPDATE_FW_INVALID_FW_IMAGE); + _pt_pip2_update_bl_status(dev, UPDATE_FW_INVALID_FW_IMAGE, + PT_NO_INC); goto pt_firmware_cont_release_exit; } @@ -1318,12 +1302,13 @@ static void _pt_firmware_cont(const struct firmware *fw, void *context) if (header_size >= (fw->size + 1)) { pt_debug(dev, DL_ERROR, "%s: Firmware format is invalid\n", __func__); - _pt_update_write_file_status(dev, UPDATE_FW_INVALID_FW_IMAGE); + _pt_pip2_update_bl_status(dev, UPDATE_FW_INVALID_FW_IMAGE, + PT_NO_INC); goto pt_firmware_cont_release_exit; } pt_upgrade_firmware(dev, &(fw->data[header_size + 1]), - fw->size - (header_size + 1), &write_file_status); + fw->size - (header_size + 1), &update_fw_status); pt_firmware_cont_release_exit: if (fw) @@ -1374,7 +1359,7 @@ static int pt_check_firmware_config_version(struct device *dev, return 0; } - return -1; + return -EPERM; } /******************************************************************************* @@ -1689,7 +1674,6 @@ retry_bl: } #endif /* CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE */ -#ifndef TTDL_KERNEL_SUBMISSION #if PT_TTCONFIG_UPGRADE /******************************************************************************* * FUNCTION: pt_write_config_row_ @@ -2378,7 +2362,6 @@ exit_free: static DEVICE_ATTR(config_loading, 0200, NULL, pt_config_loading_store); #endif /* CONFIG_TOUCHSCREEN_PARADE_MANUAL_TTCONFIG_UPGRADE */ -#endif /* !TTDL_KERNEL_SUBMISSION */ #ifdef CONFIG_TOUCHSCREEN_PARADE_PLATFORM_FW_UPGRADE /******************************************************************************* @@ -2449,7 +2432,7 @@ static ssize_t pt_manual_upgrade_store(struct device *dev, goto exit; } - _pt_update_write_file_status(dev, UPDATE_FW_IDLE); + _pt_pip2_update_bl_status(dev, UPDATE_FW_IDLE, PT_NO_INC); if (ld->is_manual_upgrade_enabled) { rc = -EBUSY; goto exit; @@ -2467,9 +2450,7 @@ exit: return size; } -#ifndef TTDL_KERNEL_SUBMISSION static DEVICE_ATTR(manual_upgrade, 0200, NULL, pt_manual_upgrade_store); -#endif /* !TTDL_KERNEL_SUBMISSION */ #endif /* CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE */ /******************************************************************************* @@ -2551,7 +2532,8 @@ static void pt_fw_and_config_upgrade( * *dev - pointer to device structure * *read_buf - pointer to the read buffer array to store the response ******************************************************************************/ -static void _pt_pip2_get_flash_info(struct device *dev, u8 *read_buf) +static void _pt_pip2_get_flash_info(struct device *dev, + u8 *read_buf) { u16 actual_read_len; int ret; @@ -2601,85 +2583,6 @@ static void _pt_pip2_get_flash_info(struct device *dev, u8 *read_buf) } #endif /* TTDL_DIAGNOSTICS */ -/******************************************************************************* - * FUNCTION: _pt_pip2_file_write_packet - * - * SUMMARY: Using the BL PIP2 commands to write a file. - * - * NOTE#1: This function support No Interrupt Solution and switch - * "pip2_send_cmd" function according to the global variable "bl_with_no_int". - * NOTE#2: The maximum write len is limited to 256 as well as the total buffer - * size is limited as PT_MAX_PIP2_MSG_SIZE. - * - * RETURNS: - * 0 = success - * !0 = failure - * - * PARAMETERS: - * *dev - pointer to device structure - * file_hd - file handle for file operation - * *write_buf - pointer of buffer to write - * write_len - length to write - * *status - pointer to store the STATUS in response - ******************************************************************************/ -static int _pt_pip2_file_write_packet(struct device *dev, u8 file_hd, - u8 *write_buf, u16 write_len, u8 *status) -{ - struct pt_core_data *cd = dev_get_drvdata(dev); - PIP2_SEND_CMD pip2_send_cmd; - int ret = 0; - u16 actual_read_len = 0; - u8 read_buf[PT_MAX_PIP2_MSG_SIZE]; - u8 buf[PT_MAX_PIP2_MSG_SIZE]; - - if (write_len > PIP2_FILE_WRITE_MAX_LEN_PER_PACKET) { - pt_debug(dev, DL_ERROR, "%s write_len (%d) is over size\n", - __func__, write_len); - return -EINVAL; - } - if (cd->bl_with_no_int) - pip2_send_cmd = cmd->nonhid_cmd->pip2_send_cmd_no_int; - else - pip2_send_cmd = cmd->nonhid_cmd->pip2_send_cmd; - - buf[0] = file_hd; - memcpy(&buf[1], write_buf, write_len); - ret = pip2_send_cmd(dev, PT_CORE_CMD_UNPROTECTED, - PIP2_CMD_ID_FILE_WRITE, buf, write_len + 1, - read_buf, &actual_read_len); - if (status) - *status = read_buf[PIP2_RESP_STATUS_OFFSET]; - return ret; -} - -/******************************************************************************* - * FUNCTION: _pt_pip2_execute_app - * - * SUMMARY: Using the BL PIP2 commands to executes an image downloaded into the - * SRAM. - * - * RETURNS: - * 0 = success - * !0 = failure - * - * PARAMETERS: - * *dev - pointer to device structure - * *status - pointer to store the STATUS in response - ******************************************************************************/ -static int _pt_pip2_execute_app(struct device *dev, u8 *status) -{ - int ret = 0; - u16 actual_read_len = 0; - u8 read_buf[PT_MAX_PIP2_MSG_SIZE]; - - ret = cmd->nonhid_cmd->pip2_send_cmd(dev, PT_CORE_CMD_UNPROTECTED, - PIP2_CMD_ID_EXECUTE, NULL, 0, - read_buf, &actual_read_len); - if (status) - *status = read_buf[PIP2_RESP_STATUS_OFFSET]; - return ret; -} - /******************************************************************************* * FUNCTION: _pt_pip2_log_last_error * @@ -2698,7 +2601,8 @@ static int _pt_pip2_execute_app(struct device *dev, u8 *status) * *dev - pointer to device structure * *read_buf - pointer to the read buffer array to store the response ******************************************************************************/ -static int _pt_pip2_log_last_error(struct device *dev, u8 *read_buf) +static int _pt_pip2_log_last_error(struct device *dev, + u8 *read_buf) { u16 actual_read_len; u8 loop = 5; @@ -2757,82 +2661,6 @@ static int _pt_pip2_log_last_error(struct device *dev, u8 *read_buf) return ret; } -/******************************************************************************* - * FUNCTION: _pt_pip2_file_write_packet_and_log_err - * - * SUMMARY: Wrapper function for File Write. If meet failure, it will call - * function _pt_pip2_log_last_error() and do a retry within 3x. - * - * NOTE: This function support No Interrupt Solution and switch "pip2_send_cmd" - * function according to the global variable "bl_with_no_int". - * - * RETURN: - * 0 = success - * !0 = failure - * - * PARAMETERS: - * *dev - pointer to device structure - * file_hd - file handle for file operation - * *write_buf - pointer of buffer to write - * write_len - length to write - * last_write - flag for last_write (1: is last write) - ******************************************************************************/ -#define PIP2_FILE_WRITE_RETRY_MAX (3) -static int _pt_pip2_file_write_packet_and_log_err(struct device *dev, - u8 file_hd, u8 *write_buf, u16 write_len, u8 last_write) -{ - struct pt_core_data *cd = dev_get_drvdata(dev); - int ret = 0; - int retry_packet = 0; - u8 read_buf[PT_MAX_PIP2_MSG_SIZE]; - u8 status = 0; - - do { - ret = _pt_pip2_file_write_packet(dev, file_hd, write_buf, - write_len, &status); - /* Write cmd successful with a fail status */ - if (ret) { - pt_debug(dev, DL_ERROR, "%s %d - Packet cmd error\n", - __func__, ret); - } else if (status) { - /* - * The last time through the loop when remain_bytes = - * write_len, no partial payload will remain, the last - * successful write (when writing to RAM) will respond - * with EOF status, writing to FLASH will respond with a - * standard success status of 0x00 - */ - if (last_write && (file_hd == PIP2_RAM_FILE) && - (status == PIP2_RSP_ERR_END_OF_FILE)) { - pt_debug(dev, DL_WARN, - "%s Last write, ret = 0x%02x\n", - __func__, status); - status = 0; - break; - } - - pt_debug(dev, DL_ERROR, "%s %d - Packet status error\n", - __func__, status); - /* Manually assign ret to negative value */ - ret = -EINVAL; - } else { - /* No issue is seen, and break the loop */ - break; - } - -#ifdef TTDL_DIAGNOSTICS - cd->bl_retry_packet_count++; - cmd->request_toggle_err_gpio(dev, PT_ERR_GPIO_BL_RETRY_PACKET); - pt_debug(dev, DL_WARN, "%s: === Retry Packet #%d ===\n", - __func__, retry_packet); -#endif - /* Get and log the last error(s) */ - _pt_pip2_log_last_error(dev, read_buf); - } while (retry_packet++ < PIP2_FILE_WRITE_RETRY_MAX); - - return ret; -} - /******************************************************************************* * FUNCTION: _pt_pip2_check_fw_ver * @@ -2877,7 +2705,7 @@ static int _pt_pip2_check_fw_ver(struct device *dev, (256 * hdr->fw_major + hdr->fw_minor)) { pt_debug(dev, DL_WARN, "ATM - bin file version < FW, will NOT upgrade FW"); - return -1; + return -EPERM; } if (img_app_rev_ctrl > hdr->fw_rev_ctrl) { @@ -2889,7 +2717,7 @@ static int _pt_pip2_check_fw_ver(struct device *dev, if (img_app_rev_ctrl < hdr->fw_rev_ctrl) { pt_debug(dev, DL_WARN, "bin file rev ctrl > FW, will NOT upgrade FW"); - return -1; + return -EPERM; } return 0; @@ -2932,7 +2760,7 @@ static int _pt_pip2_check_config_ver(struct device *dev, return 1; } else pt_debug(dev, DL_WARN, - "ATM - bin file Config version <= FW, will NOT upgrade FW"); + "ATM - bin file Config version <= FW, will NOT upgrade FW"); return 0; } @@ -3061,386 +2889,136 @@ static int _pt_calibrate_flashless_dut(struct device *dev) } /******************************************************************************* - * FUNCTION: _search_fw_from_builtin + * FUNCTION: _pt_pip2_firmware_cont * - * SUMMARY: Check the existence of builtin FW by filename and set the pointer - * to FW image + * SUMMARY: Bootload the DUT with a FW image using the PIP2 protocol. This + * includes getting the DUT into BL mode, writing the file to either SRAM + * or FLASH, and launching the application directly in SRAM or by resetting + * the DUT without the hostmode pin asserted. * - * RETURN: - * 0 = success - * !0 = failure + * NOTE: Special care must be taken to support a DUT communicating in + * PIP2.0 where the length field is defined differently. + * NOTE: The write packet len is set so that the overall packet size is + * less than 255. The overhead is 9 bytes: 2 byte address (0101), + * 4 byte header, 1 byte file no. 2 byte CRC * * PARAMETERS: - * *dev - pointer to device structure - * *filename - pointer of file name - * **fw - pointer to store the pointer of FW image to load + * *fw - pointer to the new FW image to load + * *context - pointer to the device ******************************************************************************/ -static int _search_fw_from_builtin(struct device *dev, char *filename, - const struct firmware **fw) +static void _pt_pip2_firmware_cont(const struct firmware *fw, + void *context) { - int ret = 0; -#if (KERNEL_VERSION(3, 13, 0) > LINUX_VERSION_CODE) - ret = request_firmware(fw, filename, dev); -#else - ret = request_firmware_direct(fw, filename, dev); -#endif - if (ret) { - pt_debug(dev, DL_WARN, "%s: ATM - Fail request FW %s load\n", - __func__, filename); - } else { - pt_debug(dev, DL_INFO, "%s: FW %s class file loading\n", - __func__, filename); - } - - return ret; -} - -/******************************************************************************* - * FUNCTION: _search_fw_from_us - * - * SUMMARY: Check the existence of FW from user space by file name defined in - * "pip2_us_file_path". - * - * RETURN: - * 0 = success - * !0 = failure - * - * PARAMETERS: - * *dev - pointer to device structure - ******************************************************************************/ -static int _search_fw_from_us(struct device *dev) -{ - struct pt_core_data *cd = dev_get_drvdata(dev); - int read_size = 16; - int ret = 0; - u8 image[16]; - - if (cd->pip2_us_file_path[0] == '\0') { - pt_debug(dev, DL_WARN, - "%s: US Path not defined, BL from built-in\n", - __func__); - ret = -EINVAL; - } else { - /* Read a few bytes to see if file exists */ - ret = cmd->nonhid_cmd->read_us_file(dev, cd->pip2_us_file_path, - image, &read_size); - if (!ret) { - pt_debug(dev, DL_WARN, "%s: %s Found, BL from US\n", - __func__, cd->pip2_us_file_path); - } else { - pt_debug(dev, DL_WARN, - "%s: ATM - %s NOT Found, BL from built-in\n", - __func__, cd->pip2_us_file_path); - } - } - return ret; -} - -/******************************************************************************* - * FUNCTION: pt_pip2_write_file - * - * SUMMARY: Compelete steps to wite a FILE in external SPI flash over PIP2 BL - * commands. It includes: Open->Erase->Write->Close. - * - * NOTE: "write_file_status" is updated from x to 99 in this scope, and higher - * level function is allowed to reset to 0 or report an error status. - * - * RETURN: - * 0 = success - * !0 = failure - * - * PARAMETERS: - * *dev - pointer to device structure - * *fw - pointer to FW image to load - * file_no - Identifies the files to write - ******************************************************************************/ -static int pt_pip2_write_file(struct device *dev, const struct firmware *fw, - u8 file_no) -{ - struct pt_core_data *cd = dev_get_drvdata(dev); - struct pt_loader_data *ld = pt_get_loader_data(dev); - int ret = 0; - int erase_status = 0; - u32 percent_cmplt; - u32 remain_bytes = 0; - u32 fw_size = 0; - u32 offset = 0; - u32 max_file_size = 0; - u16 packet_size = 0; - u16 sector_num = 0; - u8 *fw_img = NULL; - u8 file_handle = 0; u8 read_buf[PT_MAX_PIP2_MSG_SIZE]; + u8 buf[PT_MAX_PIP2_MSG_SIZE]; + u8 *fw_img = NULL; + u16 write_len; + u8 mode = PT_MODE_UNKNOWN; + u8 retry_packet = 0; + u8 us_fw_used = 0; + u16 actual_read_len; + u16 status = 0; + u16 packet_size; + int fw_size = 0; + int remain_bytes; + int ret = 0; + int percent_cmplt; + int t; + int erase_status; + u32 max_file_size; + bool wait_for_calibration_complete = false; + PIP2_SEND_CMD pip2_send_cmd; + struct device *dev = context; + struct pt_loader_data *ld = pt_get_loader_data(dev); + struct pip2_loader_data *pip2_data = ld->pip2_data; + struct pt_core_data *cd = dev_get_drvdata(dev); - if (!fw || !fw->data || !fw->size) { - pt_debug(dev, DL_ERROR, "%s The FW is invalid\n", __func__); - return -EINVAL; - } - fw_img = (u8 *)&(fw->data[0]); - fw_size = fw->size; + pt_debug(dev, DL_WARN, "%s: ATM - Begin BL\n", __func__); + _pt_pip2_update_bl_status(dev, UPDATE_FW_IDLE, PT_NO_INC); if (cd->bus_ops->bustype == BUS_I2C) packet_size = PIP2_BL_I2C_FILE_WRITE_LEN_PER_PACKET; else packet_size = PIP2_BL_SPI_FILE_WRITE_LEN_PER_PACKET; - /* 1. Open file before any file operation */ - pt_debug(dev, DL_INFO, "%s OPEN File %d for write\n", - __func__, file_no); - ret = cmd->nonhid_cmd->pip2_file_open(dev, file_no); - if (ret < 0) { - pt_debug(dev, DL_ERROR, "%s Open file %d failed\n", - __func__, file_no); - _pt_update_write_file_status(dev, UPDATE_FW_FILE_OPEN_ERROR); - goto exit; - } - file_handle = ret; - - /* Write File Status: inc to 11 */ - _pt_update_write_file_status(dev, UPDATE_FW_INCREMENT_BY_1); - - /* - * 2. Erase file - * 2.1 Obtain the size of FILE - * 2.2 Confirm content to be written is not too large - * 2.3 Check whether Sector Erase is valid - * 2.4 Log flash information - * 2.5 Do Sector Erase or File Erase - * 2.6 Reset FILE pointer - * NOTE: Regarding to TC3315, the size of RAM_FILE is less than fw - * image, so will not do step 2.2 for PIP2_RAM_FILE. - */ - if (file_no != PIP2_RAM_FILE) { - ret = cmd->nonhid_cmd->pip2_file_get_stats( - dev, file_handle, NULL, &max_file_size); - if (ret) { - pt_debug(dev, DL_ERROR, - "%s: Failed to get_file_state ret=%d\n", - __func__, ret); - goto exit_close_file; - } - if (fw_size > max_file_size) { - pt_debug(dev, DL_ERROR, - "%s: Firmware image(%d) is over size(%d)\n", - __func__, fw_size, max_file_size); - _pt_update_write_file_status(dev, - UPDATE_FW_INVALID_FW_IMAGE); - goto exit_close_file; - } - - /* calculate number of sector */ - sector_num = max_file_size / PT_PIP2_FILE_SECTOR_SIZE; - if (max_file_size % PT_PIP2_FILE_SECTOR_SIZE) { - pt_debug(dev, DL_WARN, - "%s: file size %d misalign, don't use sector erase\n", - __func__, max_file_size); - /* - * TODO: Not sure whether can have this case, and this - * is a workaround to ensure the safety in logic. - * Force sector number to 0 will use the default method - * to do file erase by FILE instead of SECTOR. - */ - sector_num = 0; - } - -#ifdef TTDL_DIAGNOSTICS - /* Log the Flash part info */ - if (cd->debug_level >= DL_DEBUG) - _pt_pip2_get_flash_info(dev, read_buf); -#endif - /* Erase file before loading */ - ret = cmd->nonhid_cmd->pip2_file_erase(dev, - ld->pip2_load_file_no, sector_num, &erase_status); - if (ret < 0) { - pt_debug(dev, DL_ERROR, - "%s: File erase failed rc=%d status=%d\n", - __func__, ret, erase_status); - _pt_update_write_file_status(dev, - UPDATE_FW_ERASE_ERROR); - goto exit_close_file; - } - - /* Write File Status: inc to 12 */ - _pt_update_write_file_status(dev, UPDATE_FW_INCREMENT_BY_1); - - /* Reset file pointer as sector erase moved it */ - ret = cmd->nonhid_cmd->pip2_file_seek_offset(dev, - ld->pip2_load_file_no, 0, 0); - if (ret) { - pt_debug(dev, DL_ERROR, - "%s: Failed to seek file offset rc=%d\n", - __func__, ret); - _pt_update_write_file_status(dev, - UPDATE_FW_FILE_SEEK_ERROR); - goto exit_close_file; - } - /* Write File Status: inc to 17 */ - _pt_update_write_file_status(dev, UPDATE_FW_INCREMENT_BY_5); - } - - /* - * 3. Write file - * 3.1* Disable IRQ when using polling method to save BL time - * 3.2 Looping to write file, and the last packet need extra check. - * 3.3* Enable IRQ - */ - pt_debug(dev, DL_WARN, - "%s: ATM - Writing %d bytes of firmware data now\n", - __func__, fw_size); - - /* - * No IRQ function is used to BL to reduce BL time due to any IRQ - * latency. - */ - if (cd->bl_with_no_int) - disable_irq_nosync(cd->irq); - - while (offset < fw_size) { - remain_bytes = fw_size - offset; - /* Don't update BL status on every pass */ - if (remain_bytes % 2000 < packet_size) { - /* Calculate % complete for write_file_status sysfs */ - percent_cmplt = - (fw_size - remain_bytes) * 100 / fw_size + 1; - if (percent_cmplt > UPDATE_FW_ACTIVE_90) - percent_cmplt = UPDATE_FW_ACTIVE_90; - /* - * Write File Status: set from 1 to 90 when - * fw_size is big enough (such as 82033). But the - * function doesn't update "write_file_status" if the - * input value is less than current stored value. - */ - _pt_update_write_file_status(dev, percent_cmplt); -#ifdef TTDL_DIAGNOSTICS - pt_debug(dev, DL_INFO, - "Wrote %d bytes with %d bytes remaining\n", - offset, remain_bytes); -#endif - } - if (remain_bytes > packet_size) { - /* The last para passes in with last_packet=0 (false) */ - ret = _pt_pip2_file_write_packet_and_log_err( - dev, file_handle, &fw_img[offset], packet_size, 0); - offset += packet_size; - if (ret) - break; - } else { - pt_debug(dev, DL_INFO, - "Write last %d bytes to File = 0x%02x\n", - remain_bytes, ld->pip2_load_file_no); - /* The last para passes in with last_packet=1 (true) */ - ret = _pt_pip2_file_write_packet_and_log_err( - dev, file_handle, &fw_img[offset], remain_bytes, 1); - offset += remain_bytes; - break; - } - } - - if (cd->bl_with_no_int) - enable_irq(cd->irq); - - if (!ret) { - /* Write File Status: set to 99 */ - _pt_update_write_file_status(dev, UPDATE_FW_ACTIVE_99); - pt_debug(dev, DL_INFO, - "%s: BIN file write finished successfully\n", __func__); - } else - _pt_update_write_file_status(dev, UPDATE_FW_WRITE_ERROR); - -exit_close_file: - /* 4. Close file */ - ret = cmd->nonhid_cmd->pip2_file_close(dev, file_handle); - if (ret != ld->pip2_load_file_no) { - pt_debug(dev, DL_ERROR, - "%s file close failure\n", __func__); - _pt_update_write_file_status(dev, UPDATE_FW_FILE_CLOSE_ERROR); - ret = -EBADF; - } else - ret = 0; - -exit: - return ret; -} - -/******************************************************************************* - * FUNCTION: _pt_pip2_update_fw - * - * SUMMARY: Compelete steps to update FW. It includes following steps: - * 1) Enter bootloader - * 2) Compare IMG version with FW version - * 3) Write IMG to target FILE - * 4) Exit bootloader - * 5) Trigger Enum and check the sentinel - * Also includes exclusive protection, PM function, Watchdog function, and - * complete progress for "update_bl_status". - * - * NOTE: "write_file_status" is updated from 0 to 100 in this scope, and higher - * level function is allowed to reset status to 0 or report an error status. - * - * RETURN: - * 0 = success - * !0 = failure - * - * PARAMETERS: - * *dev - pointer to device structure - * *fw - pointer to FW image to load - * file_no - Identifies the files to write - ******************************************************************************/ -static int _pt_pip2_update_fw(struct device *dev, const struct firmware *fw, - u8 file_no) -{ - struct pt_core_data *cd = dev_get_drvdata(dev); - struct pt_loader_data *ld = pt_get_loader_data(dev); - int ret = 0; - int t = 0; - bool wait_for_calibration_complete = false; - u8 mode = PT_MODE_UNKNOWN; - u8 status = 0; - u8 read_buf[PT_MAX_PIP2_MSG_SIZE]; - - pt_debug(dev, DL_WARN, "%s: ATM - Begin BL\n", __func__); - /* Write File Status: reset to 0 */ - _pt_update_write_file_status(dev, UPDATE_FW_IDLE); - - if (file_no > PIP2_FW_FILE) { - pt_debug(dev, DL_ERROR, - "%s: Invalid File_no = %d\n", __func__, file_no); - _pt_update_write_file_status(dev, - UPDATE_FW_NOT_SUPPORTED_FILE_NO); - goto exit; - } - - /* Write File Status: set to 0 */ ret = cmd->request_exclusive(dev, PT_LDR_REQUEST_EXCLUSIVE_TIMEOUT); - if (ret) { + if (ret < 0) { pt_debug(dev, DL_ERROR, "%s: Failed to aquire exclusive access\n", __func__); - _pt_update_write_file_status(dev, - UPDATE_FW_EXCLUSIVE_ACCESS_ERROR); + update_fw_status = UPDATE_FW_EXCLUSIVE_ACCESS_ERROR; goto exit; } - /* Write File Status: set to 1 */ - _pt_update_write_file_status(dev, UPDATE_FW_REQUEST_EXCLUSIVE); + _pt_pip2_update_bl_status(dev, 0, 1); + + if (!fw) { + if (ld->pip2_load_builtin) { + pt_debug(dev, DL_ERROR, + "%s: No builtin firmware\n", __func__); + ld->builtin_bin_fw_status = -EINVAL; + pt_debug(dev, DL_ERROR, "%s: Exit BL\n", __func__); + _pt_pip2_update_bl_status(dev, + UPDATE_FW_NO_FW_PROVIDED, PT_NO_INC); + goto exit; + } else { + fw_img = kzalloc(PT_PIP2_MAX_FILE_SIZE, GFP_KERNEL); + us_fw_used = 1; + ret = cmd->nonhid_cmd->read_us_file(dev, + cd->pip2_us_file_path, fw_img, &fw_size); + if (ret) { + pt_debug(dev, DL_ERROR, + "%s: No firmware provided to load\n", + __func__); + pt_debug(dev, DL_ERROR, "%s: Exit BL\n", + __func__); + _pt_pip2_update_bl_status(dev, + UPDATE_FW_NO_FW_PROVIDED, PT_NO_INC); + goto exit; + } + } + } else { + fw_img = (u8 *)&(fw->data[0]); + fw_size = fw->size; + } + + if (!fw_img || !fw_size) { + pt_debug(dev, DL_ERROR, + "%s: Invalid fw or file size=%d\n", __func__, + (int)fw_size); + _pt_pip2_update_bl_status(dev, UPDATE_FW_INVALID_FW_IMAGE, + PT_NO_INC); + goto exit; + } + if (ld->pip2_load_file_no == PIP2_FW_FILE) { + if (fw_img[0] >= (fw_size + 1)) { + pt_debug(dev, DL_ERROR, + "%s: Firmware format is invalid\n", __func__); + _pt_pip2_update_bl_status(dev, + UPDATE_FW_INVALID_FW_IMAGE, PT_NO_INC); + goto exit; + } + } cd->fw_updating = true; wake_up(&cd->wait_q); - /* Write File Status: inc to 2 */ - _pt_update_write_file_status(dev, UPDATE_FW_INCREMENT_BY_1); - + _pt_pip2_update_bl_status(dev, 0, 1); pt_debug(dev, DL_INFO, - "%s: Found file of size: %d bytes\n", __func__, (int)fw->size); - + "%s: Found file of size: %d bytes\n", __func__, (int)fw_size); pm_runtime_get_sync(dev); - /* Write File Status: inc to 3 */ - _pt_update_write_file_status(dev, UPDATE_FW_INCREMENT_BY_1); + _pt_pip2_update_bl_status(dev, 0, 1); + + /* Wait for completion of FW upgrade thread before continuing */ + if (!ld->pip2_load_builtin) + init_completion(&pip2_data->pip2_fw_upgrade_complete); + + _pt_pip2_update_bl_status(dev, 0, 1); cmd->request_stop_wd(dev); - /* Write File Status: inc to 4 */ - _pt_update_write_file_status(dev, UPDATE_FW_INCREMENT_BY_1); - cd->bl_pip_ver_ready = false; - cd->app_pip_ver_ready = false; + if (cd->flashless_dut) { + cd->bl_pip_ver_ready = false; + cd->app_pip_ver_ready = false; + } /* * 'mode' is used below, if DUT was already in BL before attempting to @@ -3451,54 +3029,278 @@ static int _pt_pip2_update_fw(struct device *dev, const struct firmware *fw, if (ret) { pt_debug(dev, DL_ERROR, "%s: Failed to enter BL\n", __func__); - _pt_update_write_file_status(dev, UPDATE_FW_ENTER_BL_ERROR); + _pt_pip2_update_bl_status(dev, UPDATE_FW_ENTER_BL_ERROR, + PT_NO_INC); goto exit; } - /* Write File Status: inc to 5 */ - _pt_update_write_file_status(dev, UPDATE_FW_INCREMENT_BY_1); + _pt_pip2_update_bl_status(dev, 0, 1); + /* Only compare FW ver or previous mode when doing a built-in upgrade */ if (ld->pip2_load_builtin) { if (_pt_pip2_need_upgrade_due_to_fw_ver(dev, fw) || mode == PT_MODE_BOOTLOADER) { - /* Write File Status: inc to 6 */ - _pt_update_write_file_status(dev, - UPDATE_FW_INCREMENT_BY_1); + _pt_pip2_update_bl_status(dev, 0, 1); } else { - _pt_update_write_file_status(dev, - UPDATE_FW_VERSION_ERROR); + _pt_pip2_update_bl_status(dev, + UPDATE_FW_VERSION_ERROR, PT_NO_INC); goto exit; } } + pt_debug(dev, DL_INFO, "%s OPEN File %d for write\n", + __func__, ld->pip2_load_file_no); + ret = cmd->nonhid_cmd->pip2_file_open(dev, ld->pip2_load_file_no); + if (ret < 0) { + pt_debug(dev, DL_ERROR, "%s Open file %d failed\n", + __func__, ld->pip2_load_file_no); + _pt_pip2_update_bl_status(dev, UPDATE_FW_FILE_OPEN_ERROR, + PT_NO_INC); + goto exit; + } + pip2_data->pip2_file_handle = ret; + _pt_pip2_update_bl_status(dev, 0, 1); + + /* Regarding to TC3315, the size of RAM_FILE is less than fw image */ + if (ld->pip2_load_file_no != PIP2_RAM_FILE) { + ret = cmd->nonhid_cmd->pip2_file_get_stats(dev, + ld->pip2_load_file_no, NULL, &max_file_size); + if (ret) { + pt_debug(dev, DL_ERROR, + "%s: Failed to get_file_state ret=%d\n", + __func__, ret); + goto exit_close_file; + } + if (fw_size > max_file_size) { + pt_debug(dev, DL_ERROR, + "%s: Firmware image(%d) is over size(%d)\n", + __func__, fw_size, max_file_size); + _pt_pip2_update_bl_status(dev, + UPDATE_FW_INVALID_FW_IMAGE, PT_NO_INC); + goto exit_close_file; + } +#ifdef TTDL_DIAGNOSTICS + /* Log the Flash part info */ + if (cd->debug_level >= DL_DEBUG) + _pt_pip2_get_flash_info(dev, read_buf); +#endif + /* Erase file before loading */ + ret = cmd->nonhid_cmd->pip2_file_erase(dev, + ld->pip2_load_file_no, &erase_status); + if (ret < 0) { + pt_debug(dev, DL_ERROR, + "%s: File erase failed rc=%d status=%d\n", + __func__, ret, erase_status); + _pt_pip2_update_bl_status(dev, + UPDATE_FW_ERASE_ERROR, PT_NO_INC); + goto exit_close_file; + } + _pt_pip2_update_bl_status(dev, 0, 5); + } + + remain_bytes = fw_size; + buf[0] = pip2_data->pip2_file_handle; + pt_debug(dev, DL_WARN, + "%s: ATM - Writing %d bytes of firmware data now\n", + __func__, fw_size); + /* - * Write File Status: set to 10 before pt_pip2_write_file() is called to - * align with _pt_pip2_write_file_cont(). + * No IRQ function is used to BL to reduce BL time due to any IRQ + * latency. */ - _pt_update_write_file_status(dev, UPDATE_FW_ACTIVE_10); - /* Write File Status: inc from 10, the max is not bigger than 99 */ - ret = pt_pip2_write_file(dev, fw, file_no); - if (ret) { - pt_debug(dev, DL_ERROR, "%s: Failed to write FILE_%d\n", - __func__, file_no); + if (cd->bl_with_no_int) { + pip2_send_cmd = cmd->nonhid_cmd->pip2_send_cmd_no_int; + disable_irq_nosync(cd->irq); + } else + pip2_send_cmd = cmd->nonhid_cmd->pip2_send_cmd; + + /* Continue writing while data remains */ + while (remain_bytes > packet_size) { + write_len = packet_size; + + /* Don't update BL status on every pass */ + if (remain_bytes % 2000 < packet_size) { + /* Calculate % complete for update_fw_status sysfs */ + percent_cmplt = (fw_size - remain_bytes) * + 100 / fw_size; + if (percent_cmplt > 0 && + percent_cmplt > UPDATE_FW_ACTIVE_90) + percent_cmplt = UPDATE_FW_ACTIVE_90; + _pt_pip2_update_bl_status(dev, percent_cmplt, + PT_NO_INC); + +#ifdef TTDL_DIAGNOSTICS + pt_debug(dev, DL_INFO, + "Wrote %d bytes with %d bytes remaining\n", + fw_size - remain_bytes - write_len, + remain_bytes); +#endif + } + if (retry_packet > 0) { +#ifdef TTDL_DIAGNOSTICS + cd->bl_retry_packet_count++; + cmd->request_toggle_err_gpio(dev, + PT_ERR_GPIO_BL_RETRY_PACKET); + pt_debug(dev, DL_WARN, + "%s: === Retry Packet #%d ===\n", + __func__, retry_packet); +#endif + /* Get and log the last error(s) */ + _pt_pip2_log_last_error(dev, read_buf); + } + + memcpy(&buf[1], fw_img, write_len); + ret = pip2_send_cmd(dev, + PT_CORE_CMD_UNPROTECTED, PIP2_CMD_ID_FILE_WRITE, + buf, write_len + 1, read_buf, &actual_read_len); + status = read_buf[PIP2_RESP_STATUS_OFFSET]; + + /* Write cmd successful with a fail status */ + if (!ret && status) { + /* + * The last time through the loop when remain_bytes = + * write_len, no partial payload will remain, the last + * successful write (when writing to RAM) will respond + * with EOF status, writing to FLASH will respond with a + * standard success status of 0x00 + */ + if ((ld->pip2_load_file_no == PIP2_RAM_FILE) && + (status == PIP2_RSP_ERR_END_OF_FILE) && + (remain_bytes == write_len)) { + pt_debug(dev, DL_WARN, + "%s Last write, ret = 0x%02x\n", + __func__, status); + /* Drop out of the while loop */ + break; + } + _pt_pip2_update_bl_status(dev, + UPDATE_FW_WRITE_ERROR, PT_NO_INC); + pt_debug(dev, DL_ERROR, + "%s file write failure, status = 0x%02x\n", + __func__, status); + if (retry_packet >= 3) { + /* Tripple retry error - break */ + remain_bytes = 0; + pt_debug(dev, DL_ERROR, + "%s %d - Packet status error - Break\n", + __func__, status); + } else { + retry_packet++; + } + } else if (ret) { + /* Packet write failed - retry 3x */ + if (retry_packet >= 3) { + remain_bytes = 0; + pt_debug(dev, DL_ERROR, + "%s %d - Packet cmd error - Break\n", + __func__, ret); + } + retry_packet++; + } else { + /* Cmd success and status success */ + retry_packet = 0; + } + + if (retry_packet == 0) { + fw_img += write_len; + remain_bytes -= write_len; + } + } + /* Write the remaining bytes if any remain */ + if (remain_bytes > 0 && retry_packet == 0) { + pt_debug(dev, DL_INFO, + "Write last %d bytes to File = 0x%02x\n", + remain_bytes, pip2_data->pip2_file_handle); + memcpy(&buf[1], fw_img, remain_bytes); + while (remain_bytes > 0 && retry_packet <= 3) { + ret = pip2_send_cmd(dev, PT_CORE_CMD_UNPROTECTED, + PIP2_CMD_ID_FILE_WRITE, buf, remain_bytes + 1, + read_buf, &actual_read_len); + status = read_buf[PIP2_RESP_STATUS_OFFSET]; + if (ret || status) { + /* + * Any non zero status when writing to FLASH is + * an error. Only when writing to RAM, the last + * packet must respond with an EOF status + */ + if ((ld->pip2_load_file_no >= PIP2_FW_FILE) || + (ld->pip2_load_file_no == PIP2_RAM_FILE && + status != PIP2_RSP_ERR_END_OF_FILE)) { + _pt_pip2_update_bl_status(dev, + UPDATE_FW_WRITE_ERROR, + PT_NO_INC); + pt_debug(dev, DL_ERROR, + "%s Write Fail-status=0x%02x\n", + __func__, status); + retry_packet++; + } else if (ld->pip2_load_file_no == + PIP2_RAM_FILE && + status == PIP2_RSP_ERR_END_OF_FILE) { + /* Special case EOF writing to SRAM */ + remain_bytes = 0; + status = 0; + } + } else { + remain_bytes = 0; + } + } + } + + if (cd->bl_with_no_int) + enable_irq(cd->irq); + + if (remain_bytes == 0 && retry_packet == 0) + _pt_pip2_update_bl_status(dev, UPDATE_FW_ACTIVE_99, PT_NO_INC); + + if (retry_packet >= 3) { + /* A packet write failure occurred 3x */ + pt_debug(dev, DL_ERROR, + "%s: BL terminated due to consecutive write errors\n", + __func__); + _pt_pip2_update_bl_status(dev, UPDATE_FW_WRITE_ERROR, + PT_NO_INC); + } else if (status) { + ret = status; + pt_debug(dev, DL_ERROR, + "%s: File write failed with status=%d\n", + __func__, status); + _pt_pip2_update_bl_status(dev, UPDATE_FW_WRITE_ERROR, + PT_NO_INC); + } else + pt_debug(dev, DL_INFO, + "%s: BIN file write finished successfully\n", __func__); + + ret = cmd->nonhid_cmd->pip2_file_close(dev, ld->pip2_load_file_no); + if (ret != ld->pip2_load_file_no) { + pt_debug(dev, DL_ERROR, + "%s file close failure\n", __func__); + _pt_pip2_update_bl_status(dev, UPDATE_FW_FILE_CLOSE_ERROR, + PT_NO_INC); goto exit; } - if ((file_no == PIP2_RAM_FILE) && - (write_file_status < UPDATE_FW_COMPLETE)) { + /* When updating non FW files, stay in BL */ + if (ld->pip2_load_file_no >= PIP2_CONFIG_FILE) + goto exit; + + if ((ld->pip2_load_file_no == PIP2_RAM_FILE) && + (update_fw_status < UPDATE_FW_COMPLETE)) { /* When writing to RAM don't reset, just launch application */ pt_debug(dev, DL_INFO, "%s Sending execute command now...\n", __func__); cd->startup_status = STARTUP_STATUS_START; - ret = _pt_pip2_execute_app(dev, &status); + ret = cmd->nonhid_cmd->pip2_send_cmd(dev, + PT_CORE_CMD_UNPROTECTED, PIP2_CMD_ID_EXECUTE, + NULL, 0, read_buf, &actual_read_len); + status = read_buf[PIP2_RESP_STATUS_OFFSET]; if (ret || status) { pt_debug(dev, DL_ERROR, "%s Execute command failure\n", __func__); - _pt_update_write_file_status(dev, - UPDATE_FW_EXECUTE_ERROR); + _pt_pip2_update_bl_status(dev, + UPDATE_FW_EXECUTE_ERROR, PT_NO_INC); goto exit; } - } else if (file_no == PIP2_FW_FILE && - write_file_status < UPDATE_FW_COMPLETE) { + } else if (ld->pip2_load_file_no == PIP2_FW_FILE && + update_fw_status < UPDATE_FW_COMPLETE) { pt_debug(dev, DL_INFO, "%s Toggle TP_XRES now...\n", __func__); cmd->request_reset(dev, PT_CORE_CMD_UNPROTECTED); @@ -3506,8 +3308,8 @@ static int _pt_pip2_update_fw(struct device *dev, const struct firmware *fw, pt_debug(dev, DL_INFO, "%s: APP launched\n", __func__); /* If any error occurred simply close the file and exit */ - if (write_file_status > UPDATE_FW_COMPLETE) - goto exit; + if (update_fw_status > UPDATE_FW_COMPLETE) + goto exit_close_file; /* Wait for FW reset sentinel from reset or execute for up to 500ms */ t = wait_event_timeout(cd->wait_q, @@ -3529,14 +3331,16 @@ static int _pt_pip2_update_fw(struct device *dev, const struct firmware *fw, pt_debug(dev, DL_ERROR, "%s ERROR: Not in App mode as expected\n", __func__); - _pt_update_write_file_status(dev, UPDATE_FW_MODE_ERROR); + _pt_pip2_update_bl_status(dev, UPDATE_FW_MODE_ERROR, + PT_NO_INC); goto exit; } } else { pt_debug(dev, DL_ERROR, "%s: FW sentinel not seen 0x%04X\n", __func__, cd->startup_status); _pt_pip2_log_last_error(dev, read_buf); - _pt_update_write_file_status(dev, UPDATE_FW_SENTINEL_NOT_SEEN); + _pt_pip2_update_bl_status(dev, UPDATE_FW_SENTINEL_NOT_SEEN, + PT_NO_INC); goto exit; } @@ -3570,41 +3374,58 @@ static int _pt_pip2_update_fw(struct device *dev, const struct firmware *fw, pt_debug(dev, DL_INFO, "%s: == PIP2 FW upgrade finished ==\n", __func__); + goto exit; + +exit_close_file: + ret = cmd->nonhid_cmd->pip2_file_close(dev, ld->pip2_load_file_no); + if (ret < 0) { + pt_debug(dev, DL_ERROR, + "%s file close failure\n", __func__); + _pt_pip2_update_bl_status(dev, UPDATE_FW_FILE_CLOSE_ERROR, + PT_NO_INC); + } exit: cd->fw_updating = false; + if (us_fw_used) + kfree(fw_img); + if (ld->pip2_load_file_no > PIP2_FW_FILE) + goto exit_staying_in_bl; + + cmd->release_exclusive(dev); + + pm_runtime_put_sync(dev); + if (fw) + release_firmware(fw); + /* * For built-in FW update, it should not warn builtin_bin_fw_status - * for each bootup since write_file_status would be + * for each bootup since update_fw_status would be * UPDATE_FW_VERSION_ERROR in most situations because firmware * should have been up to date. */ if (ld->pip2_load_builtin) { - if ((write_file_status == UPDATE_FW_ACTIVE_99) || - (write_file_status == UPDATE_FW_VERSION_ERROR)) + if ((update_fw_status == UPDATE_FW_ACTIVE_99) || + (update_fw_status == UPDATE_FW_VERSION_ERROR)) ld->builtin_bin_fw_status = 0; else ld->builtin_bin_fw_status = -EINVAL; } - cmd->release_exclusive(dev); - pm_runtime_put_sync(dev); - - if ((write_file_status == UPDATE_FW_ACTIVE_99) || - (write_file_status == UPDATE_FW_VERSION_ERROR)) { + if ((update_fw_status == UPDATE_FW_ACTIVE_99) || + (update_fw_status == UPDATE_FW_VERSION_ERROR)) { pt_debug(dev, DL_WARN, "%s: Queue ENUM\n", __func__); cmd->request_enum(dev, true); } - - /* Write File Status: set to 100 */ - if (write_file_status < UPDATE_FW_COMPLETE) - _pt_update_write_file_status(dev, UPDATE_FW_COMPLETE); + if (update_fw_status < UPDATE_FW_COMPLETE) + _pt_pip2_update_bl_status(dev, UPDATE_FW_COMPLETE, PT_NO_INC); if (wait_for_calibration_complete) wait_for_completion(&ld->calibration_complete); pt_debug(dev, DL_INFO, "%s: Starting watchdog\n", __func__); - cmd->request_start_wd(dev); + ret = cmd->request_start_wd(dev); + /* * When in No-Flash mode allow auto BL after any BL. * There is an issue where setting flashless mode via drv_debug @@ -3615,184 +3436,48 @@ exit: if (cd->flashless_dut) cd->flashless_auto_bl = PT_ALLOW_AUTO_BL; - /* - * ret is not always updated, while builtin_bin_fw_status can reflect - * the result. - */ - return ld->builtin_bin_fw_status; -} - -/******************************************************************************* - * FUNCTION: _pt_pip2_write_file_cont - * - * SUMMARY: Write the file to either SRAM or FLASH - * - * NOTE: The DUT must stay in bootloader. This function doesn't try to - * enter/exit bootloader. - * - * PARAMETERS: - * *fw - pointer to the new FW image to load - * *context - pointer to the device - ******************************************************************************/ -static void _pt_pip2_write_file_cont(const struct firmware *fw, void *context) -{ - struct device *dev = context; - struct pt_core_data *cd = dev_get_drvdata(dev); - struct pt_loader_data *ld = pt_get_loader_data(dev); - int ret = 0; - - if (!fw) { - pt_debug(dev, DL_ERROR, "%s: No FW is provided\n", __func__); - _pt_update_write_file_status(dev, UPDATE_FW_NO_FW_PROVIDED); - goto exit; - } - - if (!fw->size) { - pt_debug(dev, DL_ERROR, "%s: Invalid fw or file size=%d\n", - __func__, (int)fw->size); - _pt_update_write_file_status(dev, UPDATE_FW_INVALID_FW_IMAGE); - goto exit_release; - } - - if (ld->pip2_load_file_no == PIP2_FW_FILE) { - if (fw->data[0] >= (fw->size + 1)) { - pt_debug(dev, DL_ERROR, - "%s: Firmware format is invalid\n", __func__); - _pt_update_write_file_status(dev, - UPDATE_FW_INVALID_FW_IMAGE); - goto exit_release; - } - } - - ret = cmd->request_exclusive(dev, PT_LDR_REQUEST_EXCLUSIVE_TIMEOUT); - if (ret < 0) { - pt_debug(dev, DL_ERROR, - "%s: Failed to aquire exclusive access\n", __func__); - goto exit_release; - } - - /* Write File Status: set to 1 */ - _pt_update_write_file_status(dev, UPDATE_FW_REQUEST_EXCLUSIVE); - - cd->fw_updating = true; - /* Write File Status: inc to 2 */ - _pt_update_write_file_status(dev, UPDATE_FW_INCREMENT_BY_1); - - /* - * Write File Status: set to 10 before pt_pip2_write_file() is called to - * align with _pt_pip2_firmware_cont(). - */ - _pt_update_write_file_status(dev, UPDATE_FW_ACTIVE_10); - /* Write File Status: inc from 10, the max is not bigger than 99 */ - ret = pt_pip2_write_file(dev, fw, ld->pip2_load_file_no); - if (ret) { - pt_debug(dev, DL_ERROR, "%s: Failed to write FILE_%d\n", - __func__, ld->pip2_load_file_no); - } - - cd->fw_updating = false; - - /* Write File Status: set to 100 */ - if (write_file_status < UPDATE_FW_COMPLETE) - _pt_update_write_file_status(dev, UPDATE_FW_COMPLETE); + return; +exit_staying_in_bl: + /* When updating a non FW file, a restart is not wanted. Stay in BL */ + _pt_pip2_update_bl_status(dev, UPDATE_FW_COMPLETE, PT_NO_INC); cmd->release_exclusive(dev); - -exit_release: + pm_runtime_put_sync(dev); if (fw) release_firmware(fw); -exit: - ld->is_manual_upgrade_enabled = 0; } - +#define PIP2_MAX_FILE_NAMES 3 /******************************************************************************* - * FUNCTION: _pt_pip2_firmware_cont - * - * SUMMARY: Bootload the DUT with a FW image using the PIP2 protocol. This - * includes getting the DUT into BL mode, writing the file to either SRAM - * or FLASH, and launching the application directly in SRAM or by resetting - * the DUT without the hostmode pin asserted. - * - * NOTE: Special care must be taken to support a DUT communicating in - * PIP2.0 where the length field is defined differently. - * NOTE: The write packet len is set so that the overall packet size is - * less than 255. The overhead is 9 bytes: 2 byte address (0101), - * 4 byte header, 1 byte file no. 2 byte CRC - * - * PARAMETERS: - * *fw - pointer to the new FW image to load - * *context - pointer to the device - ******************************************************************************/ -static void _pt_pip2_firmware_cont(const struct firmware *fw, - void *context) -{ - struct device *dev = context; - struct pt_loader_data *ld = pt_get_loader_data(dev); - - if (!fw) { - pt_debug(dev, DL_ERROR, "%s: No FW is provided\n", __func__); - _pt_update_write_file_status(dev, UPDATE_FW_NO_FW_PROVIDED); - goto pt_firmware_cont_exit; - } - - if (!fw->data || !fw->size) { - pt_debug(dev, DL_ERROR, "%s: Invalid fw or file size=%d\n", - __func__, (int)fw->size); - _pt_update_write_file_status(dev, UPDATE_FW_INVALID_FW_IMAGE); - goto pt_firmware_cont_release_exit; - } - - if (ld->pip2_load_file_no == PIP2_FW_FILE) { - if (fw->data[0] >= (fw->size + 1)) { - pt_debug(dev, DL_ERROR, - "%s: Firmware format is invalid\n", __func__); - _pt_update_write_file_status( - dev, UPDATE_FW_INVALID_FW_IMAGE); - goto pt_firmware_cont_release_exit; - } - } - - _pt_pip2_update_fw(dev, fw, ld->pip2_load_file_no); - -pt_firmware_cont_release_exit: - if (fw) - release_firmware(fw); - -pt_firmware_cont_exit: - ld->is_manual_upgrade_enabled = 0; -} - -/******************************************************************************* - * FUNCTION: _pt_pip2_update_fw_from_builtin + * FUNCTION: pt_pip2_upgrade_firmware_from_builtin * * SUMMARY: Bootload the DUT with a built in firmware binary image. - * - * RETURN: - * 0 = success - * !0 = failure + * Load either a SRAM image "ttdl_fw_RAM.bin" or a FLASH image + * "ttdl_fw.bin" with the priority being the SRAM image. * * PARAMETERS: * *dev - pointer to the device structure ******************************************************************************/ -#define PIP2_MAX_FILE_NAMES 3 -static int _pt_pip2_update_fw_from_builtin(struct device *dev) +static int pt_pip2_upgrade_firmware_from_builtin(struct device *dev) { - struct pt_core_data *cd = dev_get_drvdata(dev); struct pt_loader_data *ld = pt_get_loader_data(dev); - const struct firmware *fw = NULL; - int ret = 0; + struct pt_core_data *cd = dev_get_drvdata(dev); + const struct firmware *fw_entry = NULL; + int retval; + int rc = 0; + int read_size = 16; + u8 image[16]; int index = 0; int file_count = 0; char *filename[PIP2_MAX_FILE_NAMES]; /* - * 1. Generate FW Name for builtin kernel * Load the supported filenames in the correct search order * 0 - "tt_fw<_PIDX>.bin" * 1 - "XXXX_tt_fw<_PIDX>.bin" where XXXX = Silicon ID * 2 - "tt_fw.bin", default FW name */ + filename[file_count++] = generate_firmware_filename(dev); filename[file_count++] = generate_silicon_id_firmware_filename(dev); if (pt_get_panel_id(dev) != PANEL_ID_NOT_ENABLED) { @@ -3806,175 +3491,77 @@ static int _pt_pip2_update_fw_from_builtin(struct device *dev) if (!filename[index]) return -ENOMEM; } - /* 2. Look for any FW file name match */ - mutex_lock(&cd->firmware_class_lock); - index = 0; - while (index < file_count) { - pt_debug(dev, DL_INFO, "%s: Request FW class file: %s\n", - __func__, filename[index]); - if (_search_fw_from_builtin(dev, filename[index], &fw)) - index++; - else - break; - } - /* No matching file names found */ - if (index == file_count) { - pt_debug(dev, DL_WARN, "%s: No FW is found\n", __func__); - _pt_update_write_file_status(dev, UPDATE_FW_NO_FW_PROVIDED); - ret = -EINVAL; - goto exit; - } - - /* 3. Validate the FW */ - if (!fw) { - pt_debug(dev, DL_ERROR, "%s: No FW is provided\n", __func__); - _pt_update_write_file_status(dev, UPDATE_FW_NO_FW_PROVIDED); - ret = -EINVAL; - goto exit_release_fw; - } - - if (!fw->size) { - pt_debug(dev, DL_ERROR, "%s: Invalid fw or file size=%d\n", - __func__, (int)fw->size); - _pt_update_write_file_status(dev, UPDATE_FW_INVALID_FW_IMAGE); - ret = -EINVAL; - goto exit_release_fw; - } - - if (ld->pip2_load_file_no == PIP2_FW_FILE) { - if (fw->data[0] >= (fw->size + 1)) { - pt_debug(dev, DL_ERROR, - "%s: Firmware format is invalid\n", __func__); - _pt_update_write_file_status(dev, - UPDATE_FW_INVALID_FW_IMAGE); - ret = -EINVAL; - goto exit_release_fw; - } - } - - /* 4. update the FW */ - ret = _pt_pip2_update_fw(dev, fw, ld->pip2_load_file_no); - -exit_release_fw: - /* 5. Recycle */ - if (fw) - release_firmware(fw); -exit: - index = 0; - while (index < file_count) - kfree(filename[index++]); - - mutex_unlock(&cd->firmware_class_lock); - return ret; -} - -/******************************************************************************* - * FUNCTION: _pt_pip2_update_fw_from_us - * - * SUMMARY: Bootload the DUT with firmware binary image in user space. - * - * RETURN: - * 0 = success - * !0 = failure - * - * PARAMETERS: - * *dev - pointer to the device structure - ******************************************************************************/ -static int _pt_pip2_update_fw_from_us(struct device *dev) -{ - struct pt_core_data *cd = dev_get_drvdata(dev); - struct pt_loader_data *ld = pt_get_loader_data(dev); - struct firmware fw_us; - int ret = 0; - u32 fw_size = 0; - u8 *fw_img = NULL; - - fw_img = kzalloc(PT_PIP2_MAX_FILE_SIZE, GFP_KERNEL); - if (!fw_img) { - _pt_update_write_file_status(dev, UPDATE_FW_NO_FW_PROVIDED); - return -ENOMEM; - } - - ret = cmd->nonhid_cmd->read_us_file(dev, cd->pip2_us_file_path, - fw_img, &fw_size); - if (ret) { - pt_debug(dev, DL_ERROR, "%s: No firmware provided to load\n", - __func__); - pt_debug(dev, DL_ERROR, "%s: Exit BL\n", __func__); - _pt_update_write_file_status(dev, UPDATE_FW_NO_FW_PROVIDED); - goto exit; - } - - if (!fw_size) { - pt_debug(dev, DL_ERROR, "%s: Invalid fw file size=%d\n", - __func__, (int)fw_size); - _pt_update_write_file_status(dev, UPDATE_FW_INVALID_FW_IMAGE); - goto exit; - } - - if (ld->pip2_load_file_no == PIP2_FW_FILE) { - if (fw_img[0] >= (fw_size + 1)) { - pt_debug(dev, DL_ERROR, - "%s: Firmware format is invalid\n", __func__); - _pt_update_write_file_status(dev, - UPDATE_FW_INVALID_FW_IMAGE); - goto exit; - } - } - - memset(&fw_us, 0, sizeof(fw_us)); - fw_us.data = fw_img; - fw_us.size = fw_size; - ret = _pt_pip2_update_fw(dev, &fw_us, ld->pip2_load_file_no); - -exit: - kfree(fw_img); - return ret; -} - -/******************************************************************************* - * FUNCTION: pt_pip2_upgrade_firmware_from_builtin - * - * SUMMARY: Bootload the DUT with a built in firmware binary image. - * Load either a SRAM image "ttdl_fw_RAM.bin" or a FLASH image - * "ttdl_fw.bin" with the priority being the SRAM image. - * - * PARAMETERS: - * *dev - pointer to the device structure - ******************************************************************************/ -static int pt_pip2_upgrade_firmware_from_builtin(struct device *dev) -{ - struct pt_core_data *cd = dev_get_drvdata(dev); - struct pt_loader_data *ld = pt_get_loader_data(dev); - int ret = 0; - - /* 1. Look for FW from us at first */ if (cd->flashless_dut) { - pt_debug(dev, DL_INFO, "%s: Proceed to BL flashless DUT\n", - __func__); + pt_debug(dev, DL_INFO, + "%s: Proceed to BL flashless DUT\n", __func__); ld->pip2_load_file_no = PIP2_RAM_FILE; - ret = _search_fw_from_us(dev); - if (!ret) { - ld->pip2_load_builtin = false; - /* 2. Do update with fw from user space */ - ret = _pt_pip2_update_fw_from_us(dev); - return ret; - } else { + if (cd->pip2_us_file_path[0] == '\0') { ld->pip2_load_builtin = true; + pt_debug(dev, DL_WARN, + "%s: US Path not defined, BL from built-in\n", + __func__); + } else { + /* Read a few bytes to see if file exists */ + rc = cmd->nonhid_cmd->read_us_file(dev, + cd->pip2_us_file_path, image, &read_size); + if (!rc) { + ld->pip2_load_builtin = false; + pt_debug(dev, DL_WARN, + "%s: %s Found, BL from US\n", + __func__, cd->pip2_us_file_path); + goto ready; + } else { + ld->pip2_load_builtin = true; + pt_debug(dev, DL_WARN, + "%s: ATM - %s NOT Found, BL from built-in\n", + __func__, cd->pip2_us_file_path); + } } } else { ld->pip2_load_file_no = PIP2_FW_FILE; ld->pip2_load_builtin = true; } - /* 2. Do update with fw from builtin */ - ret = _pt_pip2_update_fw_from_builtin(dev); - return ret; + /* Look for any FW file name match and request the FW */ + mutex_lock(&cd->firmware_class_lock); + index = 0; + while (index < file_count) { + pt_debug(dev, DL_INFO, "%s: Request FW class file: %s\n", + __func__, filename[index]); + retval = request_firmware_direct(&fw_entry, + filename[index], dev); + if (retval < 0) { + pt_debug(dev, DL_WARN, "%s: ATM - Fail request FW %s load\n", + __func__, filename[index]); + } else { + pt_debug(dev, DL_INFO, "%s: FW %s class file loading\n", + __func__, filename[index]); + break; + } + index++; + } + + /* No matching file names found */ + if (index == file_count) { + pt_debug(dev, DL_WARN, "%s: No FW is found\n", __func__); + goto exit; + } + +ready: + _pt_pip2_firmware_cont(fw_entry, dev); + retval = ld->builtin_bin_fw_status; +exit: + mutex_unlock(&cd->firmware_class_lock); + index = 0; + while (index < file_count) + kfree(filename[index++]); + + return retval; } /******************************************************************************* - * FUNCTION: _pt_pip2_update_fw_from_class + * FUNCTION: pt_pip2_create_fw_class * * SUMMARY: Create the firmware class but don't actually laod any FW to the * DUT. This creates all the sysfs nodes needed for a user to bootload @@ -3983,10 +3570,12 @@ static int pt_pip2_upgrade_firmware_from_builtin(struct device *dev) * PARAMETERS: * *pip2_data - pointer to the PIP2 loader data structure ******************************************************************************/ -static int _pt_pip2_update_fw_from_class(struct device *dev) +static int pt_pip2_create_fw_class(struct pip2_loader_data *pip2_data) { - struct pt_loader_data *ld = pt_get_loader_data(dev); + int ret = 0; + struct device *dev = pip2_data->dev; + struct pt_loader_data *ld = pt_get_loader_data(dev); /* * The file name dev_name(dev) is tied with bus name and usually @@ -4010,44 +3599,6 @@ static int _pt_pip2_update_fw_from_class(struct device *dev) return ret; } -/******************************************************************************* - * FUNCTION: _pt_pip2_write_file_from_class - * - * SUMMARY: Similar function of _pt_pip2_update_fw_from_class() but to call - * function _pt_pip2_write_file_cont() which doesn't perform enter/exit - * bootloader action. - * - * PARAMETERS: - * *pip2_data - pointer to the PIP2 loader data structure - ******************************************************************************/ -static int _pt_pip2_write_file_from_class(struct device *dev) -{ - - int ret = 0; - struct pt_loader_data *ld = pt_get_loader_data(dev); - - /* - * The file name dev_name(dev) is tied with bus name and usually - * it is "x-0024". This name is wanted to keep consistency - * (e.g. /sys/class/firmware/x-0024/) for the path of fw class - * nodes with different kernel release. Also it is an invalid bin - * file name used intentionally because request_firmware_nowait - * will not find the file which is what we want and then simply - * create the fw class nodes. - */ - ld->pip2_load_builtin = false; - pt_debug(dev, DL_INFO, "%s: Request FW Class", __func__); - ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG, - dev_name(dev), dev, GFP_KERNEL, dev, - _pt_pip2_write_file_cont); - if (ret) { - pt_debug(dev, DL_ERROR, - "%s: ERROR requesting firmware class\n", __func__); - } - - return ret; -} - /******************************************************************************* * FUNCTION: pt_pip2_bl_from_file_work * @@ -4061,8 +3612,9 @@ static void pt_pip2_bl_from_file_work(struct work_struct *pip2_bl_from_file) struct pt_loader_data *ld = container_of(pip2_bl_from_file, struct pt_loader_data, pip2_bl_from_file); struct device *dev = ld->dev; + const struct firmware *fw_entry = NULL; - _pt_pip2_update_fw_from_us(dev); + _pt_pip2_firmware_cont(fw_entry, dev); } /******************************************************************************* @@ -4079,10 +3631,11 @@ static void pt_bl_from_file_work(struct work_struct *bl_from_file) struct pt_loader_data *ld = container_of(bl_from_file, struct pt_loader_data, bl_from_file); struct device *dev = ld->dev; + const struct firmware *fw_entry = NULL; u8 dut_gen = cmd->request_dut_generation(dev); if (dut_gen == DUT_PIP2_CAPABLE) - _pt_pip2_update_fw_from_us(dev); + _pt_pip2_firmware_cont(fw_entry, dev); else if (dut_gen == DUT_PIP1_ONLY) _pt_pip1_bl_from_file(dev); } @@ -4110,9 +3663,6 @@ static ssize_t pt_pip2_bl_from_file_show(struct device *dev, int read_size = 2; u8 image[2]; - /* Write File Status: reset to 0 */ - _pt_update_write_file_status(dev, UPDATE_FW_IDLE); - mutex_lock(&cd->firmware_class_lock); ld->pip2_load_builtin = false; mutex_unlock(&cd->firmware_class_lock); @@ -4124,13 +3674,12 @@ static ssize_t pt_pip2_bl_from_file_show(struct device *dev, if (!rc) { schedule_work(&ld->pip2_bl_from_file); - return snprintf(buf, PT_MAX_PRBUF_SIZE, + return scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n" "BL File: %s\n", rc, cd->pip2_us_file_path); } else { - _pt_update_write_file_status(dev, UPDATE_FW_NO_FW_PROVIDED); - return snprintf(buf, PT_MAX_PRBUF_SIZE, + return scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n" "BL File: '%s' - Does not exist\n", rc, cd->pip2_us_file_path); @@ -4162,9 +3711,6 @@ static ssize_t pt_bl_from_file_show(struct device *dev, u8 dut_gen = cmd->request_dut_generation(dev); u8 image[2]; - /* Write File Status: reset to 0 */ - _pt_update_write_file_status(dev, UPDATE_FW_IDLE); - mutex_lock(&cd->firmware_class_lock); ld->pip2_load_builtin = false; mutex_unlock(&cd->firmware_class_lock); @@ -4174,22 +3720,20 @@ static ssize_t pt_bl_from_file_show(struct device *dev, cd->pip2_us_file_path, image, &read_size); if (dut_gen == DUT_UNKNOWN) { - _pt_update_write_file_status(dev, UPDATE_FW_MODE_ERROR); rc = -EINVAL; - return snprintf(buf, PT_MAX_PRBUF_SIZE, + return scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n" "BL File: '%s' - Failed, DUT Generation could not be determined\n", rc, cd->pip2_us_file_path); } else if (!rc) { schedule_work(&ld->bl_from_file); - return snprintf(buf, PT_MAX_PRBUF_SIZE, + return scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n" "BL File: %s\n", rc, cd->pip2_us_file_path); } else { - _pt_update_write_file_status(dev, UPDATE_FW_NO_FW_PROVIDED); - return snprintf(buf, PT_MAX_PRBUF_SIZE, + return scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n" "BL File: '%s' - Does not exist\n", rc, cd->pip2_us_file_path); @@ -4252,7 +3796,8 @@ static ssize_t pt_pip2_bl_from_file_store(struct device *dev, pt_debug(dev, DL_WARN, "%s:Path=%s, File_no=%s(%d)\n", __func__, ptr_left, ptr_right, file_no); - if ((file_no_set) && (file_no > PIP2_FW_FILE)) { + if ((file_no_set) && + ((file_no < PIP2_RAM_FILE) || (file_no > PIP2_FILE_MAX))) { pt_debug(dev, DL_WARN, "%s:Invalid File_no = %d\n", __func__, file_no); return -EINVAL; @@ -4314,20 +3859,19 @@ static ssize_t pt_pip2_manual_upgrade_store(struct device *dev, goto exit; } + _pt_pip2_update_bl_status(dev, UPDATE_FW_IDLE, PT_NO_INC); if (ld->is_manual_upgrade_enabled) { pt_debug(dev, DL_ERROR, "%s: ERROR - Manual upgrade busy\n", __func__); rc = -EBUSY; goto exit; } - /* Write File Status: reset to 0 */ - _pt_update_write_file_status(dev, UPDATE_FW_IDLE); ld->pip2_load_file_no = PIP2_FW_FILE; pt_debug(dev, DL_DEBUG, "%s: ATM - File number is %d\n", __func__, ld->pip2_load_file_no); ld->is_manual_upgrade_enabled = 1; - rc = _pt_pip2_update_fw_from_class(dev); + rc = pt_pip2_create_fw_class(ld->pip2_data); ld->is_manual_upgrade_enabled = 0; if (rc < 0) pt_debug(dev, DL_ERROR, @@ -4338,7 +3882,6 @@ exit: return rc; return size; } -#ifndef TTDL_KERNEL_SUBMISSION static DEVICE_ATTR(pip2_manual_upgrade, 0200, NULL, pt_pip2_manual_upgrade_store); @@ -4378,6 +3921,7 @@ static ssize_t pt_pip2_manual_ram_upgrade_store(struct device *dev, goto exit; } + _pt_pip2_update_bl_status(dev, UPDATE_FW_IDLE, PT_NO_INC); if (ld->is_manual_upgrade_enabled) { pt_debug(dev, DL_ERROR, "%s: ERROR - Manual upgrade busy\n", __func__); @@ -4385,14 +3929,12 @@ static ssize_t pt_pip2_manual_ram_upgrade_store(struct device *dev, goto exit; } - /* Write File Status: reset to 0 */ - _pt_update_write_file_status(dev, UPDATE_FW_IDLE); ld->pip2_load_file_no = PIP2_RAM_FILE; pt_debug(dev, DL_DEBUG, "%s: ATM - File number is %d\n", __func__, ld->pip2_load_file_no); ld->is_manual_upgrade_enabled = 1; - rc = _pt_pip2_update_fw_from_class(dev); + rc = pt_pip2_create_fw_class(ld->pip2_data); ld->is_manual_upgrade_enabled = 0; if (rc < 0) pt_debug(dev, DL_ERROR, @@ -4421,7 +3963,6 @@ static DEVICE_ATTR(pip2_manual_ram_upgrade, 0200, static ssize_t pt_pip2_file_write_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { - struct pt_core_data *cd = dev_get_drvdata(dev); struct pt_loader_data *ld = pt_get_loader_data(dev); int rc; u32 input_data[3]; @@ -4451,22 +3992,12 @@ static ssize_t pt_pip2_file_write_store(struct device *dev, goto exit; } - /* This functionality is only available in the BL */ - if (cd->mode != PT_MODE_BOOTLOADER) { - rc = -EPERM; - pt_debug(dev, DL_ERROR, "%s: Invalid DUT mode = %d\n", - __func__, cd->mode); - goto exit; - } - - /* Write File Status: reset to 0 */ - _pt_update_write_file_status(dev, UPDATE_FW_IDLE); ld->pip2_load_file_no = input_data[0]; if (length == 2) ld->pip2_file_data.file_offset = input_data[1]; ld->is_manual_upgrade_enabled = 1; - rc = _pt_pip2_write_file_from_class(dev); + rc = pt_pip2_create_fw_class(ld->pip2_data); ld->is_manual_upgrade_enabled = 0; if (rc < 0) pt_debug(dev, DL_ERROR, @@ -4477,7 +4008,6 @@ exit: return size; } static DEVICE_ATTR(pip2_file_write, 0200, NULL, pt_pip2_file_write_store); -#endif /* !TTDL_KERNEL_SUBMISSION */ /******************************************************************************* * FUNCTION: pt_update_fw_store @@ -4509,7 +4039,6 @@ static ssize_t pt_update_fw_store(struct device *dev, static DEVICE_ATTR(update_fw, 0200, NULL, pt_update_fw_store); #endif /* CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE */ -#ifndef TTDL_KERNEL_SUBMISSION #ifdef TTDL_DIAGNOSTICS /******************************************************************************* * FUNCTION: pt_pip2_file_read_show @@ -4818,7 +4347,7 @@ static ssize_t pt_pip2_file_read_store(struct file *filp, goto error; } - if (ic_buffer[0] < PIP2_FW_FILE || ic_buffer[0] > PIP2_FILE_MAX) { + if (ic_buffer[0] < PIP2_FW_FILE || ic_buffer[0] > PIP2_FILE_7) { pt_debug(dev, DL_ERROR, "%s: Invalid file handle!\n", __func__); ld->pip2_file_data.para_num = 0; @@ -4911,7 +4440,7 @@ static ssize_t pt_pip2_file_crc_show(struct device *dev, pt_debug(dev, DL_ERROR, "%s: Invalid parameters!\n", __func__); - print_idx = snprintf(buf, PT_MAX_PRBUF_SIZE, + print_idx = scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n" "Invalid parameters!\n", -EINVAL); return print_idx; @@ -4924,7 +4453,7 @@ static ssize_t pt_pip2_file_crc_show(struct device *dev, /* This functionality is only available in the BL */ if (cd->mode != PT_MODE_BOOTLOADER) { rc = -EPERM; - print_idx = snprintf(buf, PT_MAX_PRBUF_SIZE, + print_idx = scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n", rc); goto exit; } @@ -4934,7 +4463,7 @@ static ssize_t pt_pip2_file_crc_show(struct device *dev, pt_debug(dev, DL_ERROR, "%s: Failed to request exclusive rc=%d\n", __func__, rc); - print_idx = snprintf(buf, PT_MAX_PRBUF_SIZE, + print_idx = scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n", rc); goto exit; } @@ -4944,7 +4473,7 @@ static ssize_t pt_pip2_file_crc_show(struct device *dev, pt_debug(dev, DL_ERROR, "%s: Failed to file_open rc=%d\n", __func__, rc); - print_idx = snprintf(buf, PT_MAX_PRBUF_SIZE, + print_idx = scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n", rc); goto exit_release; } @@ -4955,7 +4484,7 @@ static ssize_t pt_pip2_file_crc_show(struct device *dev, pt_debug(dev, DL_ERROR, "%s: Failed to get_file_state rc=%d\n", __func__, rc); - print_idx = snprintf(buf, PT_MAX_PRBUF_SIZE, + print_idx = scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n", rc); goto exit_file_close; } @@ -4969,7 +4498,7 @@ static ssize_t pt_pip2_file_crc_show(struct device *dev, pt_debug(dev, DL_ERROR, "%s: Invalid parameters!\n", __func__); - print_idx = snprintf(buf, PT_MAX_PRBUF_SIZE, + print_idx = scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n", rc); goto exit_file_close; } @@ -4980,18 +4509,18 @@ static ssize_t pt_pip2_file_crc_show(struct device *dev, pt_debug(dev, DL_ERROR, "%s: Failed to get file crc, rc=%d\n", __func__, rc); - print_idx = snprintf(buf, PT_MAX_PRBUF_SIZE, + print_idx = scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n", rc); } else { status = read_buf[PIP2_RESP_STATUS_OFFSET]; if (status == PIP2_RSP_ERR_NONE) { file_crc = get_unaligned_le16(&read_buf[5]); - print_idx = snprintf(buf, PT_MAX_PRBUF_SIZE, + print_idx = scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n" "FILE CRC: %04X\n", status, file_crc); } else - print_idx = snprintf(buf, PT_MAX_PRBUF_SIZE, + print_idx = scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n" "FILE CRC: n/a\n", status); @@ -5094,8 +4623,6 @@ static ssize_t pt_pip2_file_erase_show(struct device *dev, struct pt_core_data *cd = dev_get_drvdata(dev); u8 file_handle; u8 file = ld->pip2_file_erase_file_no; - u16 sector_num = 0; - u32 max_file_size = 0; int rc; pip2_erase_status = -1; @@ -5126,31 +4653,8 @@ static ssize_t pt_pip2_file_erase_show(struct device *dev, goto exit_release; } - rc = cmd->nonhid_cmd->pip2_file_get_stats(dev, - file, NULL, &max_file_size); - if (rc) { - pt_debug(dev, DL_ERROR, - "%s: Failed to get_file_state ret=%d\n", - __func__, rc); - goto exit_release; - } - - sector_num = max_file_size / PT_PIP2_FILE_SECTOR_SIZE; - if (max_file_size % PT_PIP2_FILE_SECTOR_SIZE) { - pt_debug(dev, DL_WARN, - "%s: file size %d misalign, don't use sector erase\n", - __func__, max_file_size); - /* - * TODO: Not sure whether can have this case, and this - * is a workaround to ensure the safety in logic. - * Force sector number to 0 will use the default method - * to do file erase by FILE instead of SECTOR. - */ - sector_num = 0; - } - file_handle = cmd->nonhid_cmd->pip2_file_erase(dev, file, - sector_num, &pip2_erase_status); + &pip2_erase_status); if (file_handle < 0) { rc = file_handle; pt_debug(dev, DL_INFO, "%s: File erase error rc = %d\n", @@ -5171,12 +4675,12 @@ exit_release: exit: pip2_erase_rc = rc; if (pip2_erase_status == -1) { - return snprintf(buf, PT_MAX_PRBUF_SIZE, + return scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n" "Erase Status: n/a\n", pip2_erase_rc); } - return snprintf(buf, PT_MAX_PRBUF_SIZE, + return scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n" "Erase Status: 0x%02X\n", pip2_erase_rc, pip2_erase_status); @@ -5235,7 +4739,7 @@ static DEVICE_ATTR(pip2_file_erase, 0644, pt_pip2_file_erase_show, pt_pip2_file_erase_store); /******************************************************************************* - * FUNCTION: pt_write_file_status_show + * FUNCTION: pt_pip2_bl_status_show * * SUMMARY: The show method for the pip2_bl_status sysfs node. * Shows the percent completion of the current BL or an error message. @@ -5245,16 +4749,16 @@ static DEVICE_ATTR(pip2_file_erase, 0644, * *attr - pointer to device attributes structure * *buf - pointer to print output buffer ******************************************************************************/ -static ssize_t pt_write_file_status_show(struct device *dev, +static ssize_t pt_pip2_bl_status_show(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t ret; - u8 status = write_file_status; + u8 status = update_fw_status; - if (write_file_status <= UPDATE_FW_COMPLETE) { + if (update_fw_status <= UPDATE_FW_COMPLETE) { pt_debug(dev, DL_DEBUG, - "%s BL_STATUS = %d\n", __func__, write_file_status); - return scnprintf(buf, strlen(buf), "%d\n", write_file_status); + "%s BL_STATUS = %d\n", __func__, update_fw_status); + return scnprintf(buf, strlen(buf), "%d\n", update_fw_status); } switch (status) { @@ -5325,9 +4829,6 @@ static ssize_t pt_write_file_status_show(struct device *dev, case UPDATE_FW_INVALID_FW_IMAGE: ret = scnprintf(buf, strlen(buf), "ERROR: %d - Invalid FW image\n", status); break; - case UPDATE_FW_FILE_SEEK_ERROR: - ret = scnprintf(buf, strlen(buf), "ERROR: %d - File seek failure\n", status); - break; case UPDATE_FW_MISALIGN_FW_IMAGE: ret = scnprintf(buf, strlen(buf), "ERROR: %d - FW image is misaligned\n", status); @@ -5361,10 +4862,6 @@ static ssize_t pt_write_file_status_show(struct device *dev, ret = scnprintf(buf, strlen(buf), "ERROR: %d - No platform data\n", status); break; - case UPDATE_FW_NOT_SUPPORTED_FILE_NO: - ret = scnprintf(buf, strlen(buf), - "ERROR: %d - Not supported file number\n", status); - break; case UPDATE_FW_UNDEFINED_ERROR: default: ret = scnprintf(buf, strlen(buf), "ERROR: %d - Unknown error\n", status); @@ -5372,9 +4869,9 @@ static ssize_t pt_write_file_status_show(struct device *dev, } return ret; } -static DEVICE_ATTR(pip2_bl_status, 0444, pt_write_file_status_show, NULL); +static DEVICE_ATTR(pip2_bl_status, 0444, pt_pip2_bl_status_show, NULL); #if PT_FW_UPGRADE -static DEVICE_ATTR(update_fw_status, 0444, pt_write_file_status_show, NULL); +static DEVICE_ATTR(update_fw_status, 0444, pt_pip2_bl_status_show, NULL); #endif /******************************************************************************* * FUNCTION: pt_pip2_get_last_error_show @@ -5418,16 +4915,16 @@ exit_release: cmd->release_exclusive(dev); exit: if (rc) - return snprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n", rc); + return scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n", rc); if (read_buf[PIP2_RESP_STATUS_OFFSET] == PIP2_RSP_ERR_NONE) { - return snprintf(buf, PT_MAX_PRBUF_SIZE, + return scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n" "Last Error No: 0x%02X\n", PIP2_RSP_ERR_NONE, read_buf[PIP2_RESP_BODY_OFFSET]); } else { - return snprintf(buf, PT_MAX_PRBUF_SIZE, + return scnprintf(buf, PT_MAX_PRBUF_SIZE, "Status: %d\n" "Last Error No: n/a\n", read_buf[PIP2_RESP_STATUS_OFFSET]); @@ -5435,7 +4932,6 @@ exit: } static DEVICE_ATTR(pip2_get_last_error, 0444, pt_pip2_get_last_error_show, NULL); -#endif /* !TTDL_KERNEL_SUBMISSION */ #if PT_FW_UPGRADE /******************************************************************************* @@ -5552,8 +5048,8 @@ static int pt_loader_probe(struct device *dev, void **data) #if PT_FW_UPGRADE /* Initialize boot loader status */ - if (write_file_status != UPDATE_FW_COMPLETE) - _pt_update_write_file_status(dev, UPDATE_FW_IDLE); + if (update_fw_status != UPDATE_FW_COMPLETE) + _pt_pip2_update_bl_status(dev, UPDATE_FW_IDLE, PT_NO_INC); #endif if (dut_gen == DUT_PIP2_CAPABLE) { @@ -5592,7 +5088,6 @@ static int pt_loader_probe(struct device *dev, void **data) } #endif /* CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE */ -#ifndef TTDL_KERNEL_SUBMISSION #ifdef CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE rc = device_create_file(dev, &dev_attr_pip2_manual_upgrade); if (rc) { @@ -5662,7 +5157,6 @@ static int pt_loader_probe(struct device *dev, void **data) goto remove_files; } #endif -#endif /* !TTDL_KERNEL_SUBMISSION */ } else { #if PT_FW_UPGRADE rc = device_create_file(dev, &dev_attr_update_fw_status); @@ -5690,7 +5184,6 @@ static int pt_loader_probe(struct device *dev, void **data) goto remove_files; } #endif /* CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE */ -#ifndef TTDL_KERNEL_SUBMISSION #ifdef CONFIG_TOUCHSCREEN_PARADE_PLATFORM_FW_UPGRADE rc = device_create_file(dev, &dev_attr_forced_upgrade); if (rc) { @@ -5726,7 +5219,6 @@ static int pt_loader_probe(struct device *dev, void **data) goto remove_files; } #endif /* CONFIG_TOUCHSCREEN_PARADE_MANUAL_TTCONFIG_UPGRADE */ -#endif /* !TTDL_KERNEL_SUBMISSION */ } if (!pdata || !pdata->loader_pdata) { @@ -5772,14 +5264,9 @@ static int pt_loader_probe(struct device *dev, void **data) mutex_init(&ld->config_lock); #endif -#ifdef UPGRADE_FW_AND_CONFIG_IN_PROBE - /* Call FW and config upgrade directly in probe */ - pt_fw_and_config_upgrade(&ld->fw_and_config_upgrade); -#else pt_debug(dev, DL_INFO, "%s: Schedule FW upgrade work\n", __func__); INIT_WORK(&ld->fw_and_config_upgrade, pt_fw_and_config_upgrade); schedule_work(&ld->fw_and_config_upgrade); -#endif pt_debug(dev, DL_INFO, "%s: Successful probe %s\n", __func__, dev_name(dev)); @@ -5787,7 +5274,6 @@ static int pt_loader_probe(struct device *dev, void **data) remove_files: -#ifndef TTDL_KERNEL_SUBMISSION #ifdef CONFIG_TOUCHSCREEN_PARADE_MANUAL_TTCONFIG_UPGRADE device_remove_file(dev, &dev_attr_config_loading); #endif @@ -5813,7 +5299,6 @@ remove_files: device_remove_file(dev, &dev_attr_update_fw); device_remove_file(dev, &dev_attr_update_fw_status); #endif /* CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE */ -#endif /* !TTDL_KERNEL_SUBMISSION */ kfree(ld->pip2_data); kfree(ld); @@ -5857,7 +5342,6 @@ static void pt_loader_release(struct device *dev, void *data) #ifdef CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE device_remove_file(dev, &dev_attr_update_fw); #endif /* CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE */ -#ifndef TTDL_KERNEL_SUBMISSION #ifdef TTDL_DIAGNOSTICS device_remove_bin_file(dev, &bin_attr_pip2_file_read); device_remove_file(dev, &dev_attr_pip2_file_crc); @@ -5872,13 +5356,11 @@ static void pt_loader_release(struct device *dev, void *data) device_remove_file(dev, &dev_attr_pip2_manual_ram_upgrade); device_remove_file(dev, &dev_attr_pip2_manual_upgrade); #endif /* CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE */ -#endif /* !TTDL_KERNEL_SUBMISSION */ kfree(ld->pip2_data); } else { #ifdef CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE device_remove_file(dev, &dev_attr_update_fw); #endif /* CONFIG_TOUCHSCREEN_PARADE_BINARY_FW_UPGRADE */ -#ifndef TTDL_KERNEL_SUBMISSION #ifdef CONFIG_TOUCHSCREEN_PARADE_MANUAL_TTCONFIG_UPGRADE device_remove_bin_file(dev, &bin_attr_config_data); device_remove_file(dev, &dev_attr_config_loading); @@ -5892,7 +5374,6 @@ static void pt_loader_release(struct device *dev, void *data) #ifdef CONFIG_TOUCHSCREEN_PARADE_PLATFORM_FW_UPGRADE device_remove_file(dev, &dev_attr_forced_upgrade); #endif /* CONFIG_TOUCHSCREEN_PARADE_PLATFORM_FW_UPGRADE */ -#endif /* !TTDL_KERNEL_SUBMISSION */ } kfree(ld); } diff --git a/pt/pt_mt_common.c b/pt/pt_mt_common.c index 008db5c972..d1a9ade148 100644 --- a/pt/pt_mt_common.c +++ b/pt/pt_mt_common.c @@ -55,6 +55,42 @@ static void pt_mt_lift_all(struct pt_mt_data *md) } } +/******************************************************************************* + * FUNCTION: pt_get_touch_axis + * + * SUMMARY: Calculates touch axis + * + * PARAMETERS: + * *md - pointer to touch data structure + * *axis - pointer to axis calculation result + * size - size in byte + * max - max value of result + * *xy_data - pointer to input data to be parsed + * bofs - bit offset + ******************************************************************************/ +static void pt_get_touch_axis(struct pt_mt_data *md, + int *axis, int size, int max, u8 *xy_data, int bofs) +{ + int nbyte; + int next; + + for (nbyte = 0, *axis = 0, next = 0; nbyte < size; nbyte++) { + pt_debug(md->dev, DL_DEBUG, + "%s: *axis=%02X(%d) size=%d max=%08X xy_data=%p xy_data[%d]=%02X(%d) bofs=%d\n", + __func__, *axis, *axis, size, max, xy_data, next, + xy_data[next], xy_data[next], bofs); + *axis = *axis + ((xy_data[next] >> bofs) << (nbyte * 8)); + next++; + } + + *axis &= max - 1; + + pt_debug(md->dev, DL_DEBUG, + "%s: *axis=%02X(%d) size=%d max=%08X xy_data=%p xy_data[%d]=%02X(%d)\n", + __func__, *axis, *axis, size, max, xy_data, next, + xy_data[next], xy_data[next]); +} + /******************************************************************************* * FUNCTION: pt_get_touch_hdr * @@ -75,7 +111,7 @@ static void pt_get_touch_hdr(struct pt_mt_data *md, for (hdr = PT_TCH_TIME; hdr < PT_TCH_NUM_HDR; hdr++) { if (!si->tch_hdr[hdr].report) continue; - pt_get_touch_field(dev, &touch->hdr[hdr], + pt_get_touch_axis(md, &touch->hdr[hdr], si->tch_hdr[hdr].size, si->tch_hdr[hdr].max, xy_mode + si->tch_hdr[hdr].ofs, @@ -115,7 +151,7 @@ static void pt_get_touch_record(struct pt_mt_data *md, for (abs = PT_TCH_X; abs < PT_TCH_NUM_ABS; abs++) { if (!si->tch_abs[abs].report) continue; - pt_get_touch_field(dev, &touch->abs[abs], + pt_get_touch_axis(md, &touch->abs[abs], si->tch_abs[abs].size, si->tch_abs[abs].max, xy_data + si->tch_abs[abs].ofs, @@ -249,9 +285,8 @@ static void pt_get_mt_touches(struct pt_mt_data *md, if (PT_TOUCH_ID_MAX < si->tch_abs[PT_TCH_T].max) { pt_debug(dev, DL_ERROR, - "%s: Touch ID %d is allocated less than needed %d\n", - __func__, PT_TOUCH_ID_MAX, - (int)si->tch_abs[PT_TCH_T].max); + "%s: Touch ID num %d is allocated less than needed %d\n", + __func__, PT_TOUCH_ID_MAX, si->tch_abs[PT_TCH_T].max); return; } diff --git a/pt/pt_platform.c b/pt/pt_platform.c index f623f76c82..3b2c8e88fe 100644 --- a/pt/pt_platform.c +++ b/pt/pt_platform.c @@ -29,10 +29,6 @@ #include "pt_regs.h" #include -#include -#ifdef PT_PTSBC_SUPPORT -#include -#endif #ifdef CONFIG_TOUCHSCREEN_PARADE_PLATFORM_FW_UPGRADE /* FW for Panel ID = 0x00 */ @@ -368,193 +364,6 @@ static int pt_pinctrl_select_release(struct pt_core_platform_data *pdata, } #endif /* PT_PINCTRL_EN */ -#ifdef PT_REGULATOR_EN -#define PT_VCC_MIN_UV (2800000) -#define PT_VCC_MAX_UV (3300000) -#define PT_VDDI_MIN_UV (1800000) -#define PT_VDDI_MAX_UV (1900000) -/******************************************************************************* - * FUNCTION: pt_regulator_init - * - * SUMMARY: With regulator framework to get regulator handle and setup voltage - * level. - * - * NOTE: The function only contains setup for VCC and VDDI since AVDD AVEE is - * usually used by TDDI products while the power is setup on other driver. - * - * RETURN: - * 0 = success - * !0 = fail - * - * PARAMETERS: - * *pdata - pointer to the platform data structure - * *dev - pointer to Device structure - ******************************************************************************/ -static int pt_regulator_init(struct pt_core_platform_data *pdata, - struct device *dev) -{ - int rc = 0; - - pdata->vcc = devm_regulator_get(dev, "vcc"); - if (IS_ERR(pdata->vcc)) { - rc = PTR_ERR(pdata->vcc); - pt_debug(dev, DL_ERROR, "get vcc regulator failed,rc=%d", rc); - return rc; - } - - if (regulator_count_voltages(pdata->vcc) > 0) { - rc = regulator_set_voltage(pdata->vcc, PT_VCC_MIN_UV, - PT_VCC_MAX_UV); - if (rc) { - pt_debug(dev, DL_ERROR, - "set vcc regulator failed rc=%d", rc); - goto error_set_vcc; - } - } - - pdata->vddi = devm_regulator_get(dev, "vddi"); - if (IS_ERR(pdata->vddi)) { - rc = PTR_ERR(pdata->vddi); - pt_debug(dev, DL_ERROR, "get vddi regulator failed,rc=%d", rc); - goto error_get_vcc; - } - - if (regulator_count_voltages(pdata->vddi) > 0) { - rc = regulator_set_voltage(pdata->vddi, PT_VDDI_MIN_UV, - PT_VDDI_MAX_UV); - if (rc) { - pt_debug(dev, DL_ERROR, - "set vddi regulator failed rc=%d", rc); - goto error_set_vddi; - } - } - - return 0; - -error_set_vddi: - devm_regulator_put(pdata->vddi); -error_get_vcc: - /* - * regulator_set_voltage always select minimum legal voltage between - * min_uV and max_uV. To set the minuV to 0 means to restore the default - * value of regulator. Since regulator_set_voltage is the part to - * release regulator source, it's not necessary to check the returned - * value of it. - */ - if (regulator_count_voltages(pdata->vcc) > 0) - regulator_set_voltage(pdata->vcc, 0, PT_VCC_MAX_UV); -error_set_vcc: - devm_regulator_put(pdata->vcc); - - return rc; -} - -/******************************************************************************* - * FUNCTION: pt_setup_power_by_regulator - * - * SUMMARY: With regulator framework to set power on/off. - * - * NOTE: The function only contains setup for VCC and VDDI since AVDD AVEE is - * usually used by TDDI products while the power is setup on other driver. - * - * NOTE: The timing sequence is the EXAMPLE ONLY for TT7XXX: - * power up order : VDDI, VCC - * power down order : VCC, VDDI - * - * RETURN: - * 0 = success - * !0 = fail - * - * PARAMETERS: - * *pdata - pointer to the platform data structure - * on - flag to decide power state,PT_MT_POWER_ON/PT_MT_POWER_OFF - * *dev - pointer to Device structure - ******************************************************************************/ -static int pt_setup_power_by_regulator(struct pt_core_platform_data *pdata, - int on, struct device *dev) -{ - int rc = 0; - - if (IS_ERR(pdata->vddi) || IS_ERR(pdata->vcc)) { - pt_debug(dev, DL_ERROR, "vddi or vcc is not valid\n"); - return -EINVAL; - } - - if (on == PT_MT_POWER_ON) { - rc = regulator_enable(pdata->vddi); - if (rc) { - pt_debug(dev, DL_ERROR, - "enable vddi regulator failed,rc=%d", rc); - } - /* Ensure the power goes stable */ - usleep_range(3000, 4000); - - rc = regulator_enable(pdata->vcc); - if (rc) { - pt_debug(dev, DL_ERROR, - "enable vcc regulator failed,rc=%d", rc); - } - /* Ensure the power goes stable */ - usleep_range(3000, 4000); - } else { - rc = regulator_disable(pdata->vcc); - if (rc) { - pt_debug(dev, DL_ERROR, - "disable vcc regulator failed,rc=%d", rc); - } - rc = regulator_disable(pdata->vddi); - if (rc) { - pt_debug(dev, DL_ERROR, - "disable vddi regulator failed,rc=%d", rc); - } - /* Ensure the power ramp down completely */ - usleep_range(10000, 12000); - } - - return rc; -} - -/******************************************************************************* - * FUNCTION: pt_regulator_release - * - * SUMMARY: With regulator framework to release regulator resource - * - * NOTE: The regulator MUST be disabled before this call. - * NOTE: The function only contains setup for VCC and VDDI since AVDD AVEE is - * usually used by TDDI products while the power is setup on other driver. - * - * RETURN: - * 0 = success - * !0 = fail - * - * PARAMETERS: - * *pdata - pointer to the platform data structure - * *dev - pointer to Device structure - ******************************************************************************/ -static int pt_regulator_release(struct pt_core_platform_data *pdata, - struct device *dev) -{ - if (IS_ERR(pdata->vddi) || IS_ERR(pdata->vcc)) - return -EINVAL; - - /* - * regulator_set_voltage always select minimum legal voltage between - * min_uV and max_uV. To set the minuV to 0 means to restore the default - * value of regulator. Since regulator_set_voltage is the part to - * release regulator source, it's not necessary to check the returned - * value of it. - */ - if (regulator_count_voltages(pdata->vddi) > 0) - regulator_set_voltage(pdata->vddi, 0, PT_VDDI_MAX_UV); - devm_regulator_put(pdata->vddi); - - if (regulator_count_voltages(pdata->vcc) > 0) - regulator_set_voltage(pdata->vcc, 0, PT_VCC_MAX_UV); - devm_regulator_put(pdata->vcc); - - return 0; -} -#endif /* PT_REGULATOR_EN */ /******************************************************************************* * FUNCTION: pt_init * @@ -577,8 +386,8 @@ int pt_init(struct pt_core_platform_data *pdata, int ddi_rst_gpio = pdata->ddi_rst_gpio; int rc = 0; - if (on) { #ifdef PT_PINCTRL_EN + if (on) { rc = pt_pinctrl_init(pdata, dev); if (!rc) { pt_pinctrl_select_normal(pdata, dev); @@ -586,17 +395,8 @@ int pt_init(struct pt_core_platform_data *pdata, pt_debug(dev, DL_ERROR, "%s: Failed to request pinctrl\n", __func__); } -#endif -#ifdef PT_REGULATOR_EN - rc = pt_regulator_init(pdata, dev); - if (rc) { - pt_debug(dev, DL_ERROR, - "%s: Failed requesting regulator rc=%d", - __func__, rc); - } -#endif } - +#endif if (on && rst_gpio) { /* Configure RST GPIO */ pt_debug(dev, DL_WARN, "%s: Request RST GPIO %d", @@ -687,9 +487,6 @@ int pt_init(struct pt_core_platform_data *pdata, gpio_free(irq_gpio); if (rst_gpio) gpio_free(rst_gpio); -#ifdef PT_REGULATOR_EN - pt_regulator_release(pdata, dev); -#endif #ifdef PT_PINCTRL_EN pt_pinctrl_select_release(pdata, dev); #endif @@ -721,6 +518,199 @@ success: return rc; } +/******************************************************************************* + * FUNCTION: pt_wakeup + * + * SUMMARY: Resume power for "power on/off" sleep strategy which against to + * "deepsleep" strategy. + * + * RETURN: + * 0 = success + * !0 = fail + * + * PARAMETERS: + * *pdata - pointer to the platform data structure + * *dev - pointer to Device structure + * *ignore_irq - pointer to atomic structure to allow the host ignoring false + * IRQ during power up + ******************************************************************************/ +static int pt_wakeup(struct pt_core_platform_data *pdata, + struct device *dev, atomic_t *ignore_irq) +{ + /* Example for TT7XXX */ + int rc = 0; + +#ifdef PT_PINCTRL_EN + rc = pt_pinctrl_select_normal(pdata, dev); + if (rc) + pr_err("%s: GPIO pins activation error: rc=%d\n", + __func__, rc); +#endif + +#ifdef TT7XXX_EXAMPLE + pt_debug(dev, DL_INFO, + "%s: Enable defined pwr: VDDI, VCC\n", __func__); + /* + * Force part into RESET by holding XRES#(TP_XRES) + * while powering it up + */ + if (pdata->rst_gpio) + gpio_set_value(pdata->rst_gpio, 0); + + /* Turn on VDDI [Digital Interface] (+1.8v) */ + if (pdata->vddi_gpio) { + rc = gpio_request(pdata->vddi_gpio, NULL); + if (rc < 0) { + gpio_free(pdata->vddi_gpio); + rc = gpio_request(pdata->vddi_gpio, NULL); + } + if (rc < 0) { + pr_err("%s: Failed requesting VDDI GPIO %d\n", + __func__, pdata->vddi_gpio); + } + rc = gpio_direction_output(pdata->vddi_gpio, 1); + if (rc) + pr_err("%s: setcfg for VDDI GPIO %d failed\n", + __func__, pdata->vddi_gpio); + gpio_free(pdata->vddi_gpio); + usleep_range(3000, 4000); + } + + /* Turn on VCC */ + if (pdata->vcc_gpio) { + rc = gpio_request(pdata->vcc_gpio, NULL); + if (rc < 0) { + gpio_free(pdata->vcc_gpio); + rc = gpio_request(pdata->vcc_gpio, NULL); + } + if (rc < 0) { + pr_err("%s: Failed requesting VCC GPIO %d\n", + __func__, pdata->vcc_gpio); + } + rc = gpio_direction_output(pdata->vcc_gpio, 1); + if (rc) + pr_err("%s: setcfg for VCC GPIO %d failed\n", + __func__, pdata->vcc_gpio); + gpio_free(pdata->vcc_gpio); + usleep_range(3000, 4000); + } + + usleep_range(12000, 15000); + /* Force part out of RESET by releasing XRES#(TP_XRES) */ + if (pdata->rst_gpio) + gpio_set_value(pdata->rst_gpio, 1); +#else + pt_debug(dev, DL_INFO, "%s: Enable defined pwr\n", __func__); +#endif + return rc; +} + +/******************************************************************************* + * FUNCTION: pt_sleep + * + * SUMMARY: Suspend power for "power on/off" sleep strategy which against to + * "deepsleep" strategy. + * + * RETURN: + * 0 = success + * !0 = fail + * + * PARAMETERS: + * *pdata - pointer to the platform data structure + * *dev - pointer to Device structure + * *ignore_irq - pointer to atomic structure to allow the host ignoring false + * IRQ during power down + ******************************************************************************/ +static int pt_sleep(struct pt_core_platform_data *pdata, + struct device *dev, atomic_t *ignore_irq) +{ + /* Example for TT7XXX */ + int rc = 0; + +#ifdef TT7XXX_EXAMPLE + pt_debug(dev, DL_INFO, + "%s: Turn off defined pwr: VCC, VDDI\n", __func__); + /* + * Force part into RESET by holding XRES#(TP_XRES) + * while powering it up + */ + if (pdata->rst_gpio) + gpio_set_value(pdata->rst_gpio, 0); + + /* Turn off VCC */ + if (pdata->vcc_gpio) { + rc = gpio_request(pdata->vcc_gpio, NULL); + if (rc < 0) { + gpio_free(pdata->vcc_gpio); + rc = gpio_request(pdata->vcc_gpio, NULL); + } + if (rc < 0) { + pr_err("%s: Failed requesting VCC GPIO %d\n", + __func__, pdata->vcc_gpio); + } + rc = gpio_direction_output(pdata->vcc_gpio, 0); + if (rc) + pr_err("%s: setcfg for VCC GPIO %d failed\n", + __func__, pdata->vcc_gpio); + gpio_free(pdata->vcc_gpio); + } + + /* Turn off VDDI [Digital Interface] (+1.8v) */ + if (pdata->vddi_gpio) { + rc = gpio_request(pdata->vddi_gpio, NULL); + if (rc < 0) { + gpio_free(pdata->vddi_gpio); + rc = gpio_request(pdata->vddi_gpio, NULL); + } + if (rc < 0) { + pr_err("%s: Failed requesting VDDI GPIO %d\n", + __func__, pdata->vddi_gpio); + } + rc = gpio_direction_output(pdata->vddi_gpio, 0); + if (rc) + pr_err("%s: setcfg for VDDI GPIO %d failed\n", + __func__, pdata->vddi_gpio); + gpio_free(pdata->vddi_gpio); + usleep_range(10000, 12000); + } +#else + pt_debug(dev, DL_INFO, "%s: Turn off defined pwr\n", __func__); +#endif +#ifdef PT_PINCTRL_EN + rc = pt_pinctrl_select_suspend(pdata, dev); + if (rc) + pr_err("%s: GPIO pins suspend error: rc=%d\n", + __func__, rc); +#endif + return rc; +} + +/******************************************************************************* + * FUNCTION: pt_power + * + * SUMMARY: Wrapper function to resume/suspend power with function + * pt_wakeup()/pt_sleep(). + * + * RETURN: + * 0 = success + * !0 = fail + * + * PARAMETERS: + * *pdata - pointer to the platform data structure + * on - flag to remsume/suspend power(0:resume; 1:suspend) + * *dev - pointer to Device structure + * *ignore_irq - pointer to atomic structure to allow the host ignoring false + * IRQ during power up/down + ******************************************************************************/ +int pt_power(struct pt_core_platform_data *pdata, + int on, struct device *dev, atomic_t *ignore_irq) +{ + if (on) + return pt_wakeup(pdata, dev, ignore_irq); + + return pt_sleep(pdata, dev, ignore_irq); +} + /******************************************************************************* * FUNCTION: pt_irq_stat * @@ -780,29 +770,42 @@ int pt_detect(struct pt_core_platform_data *pdata, } #endif -#ifndef PT_REGULATOR_EN /******************************************************************************* - * FUNCTION: pt_setup_power_by_gpio + * FUNCTION: pt_setup_power * - * SUMMARY: With GPIOs to control LDO directly to set power on/off. + * SUMMARY: Turn on/turn off voltage regulator * * RETURN: * 0 = success - * !0 = fail + * !0 = failure * * PARAMETERS: - * *pdata - pointer to the platform data structure - * on - flag to decide power state,PT_MT_POWER_ON/PT_MT_POWER_OFF - * *dev - pointer to Device structure + * *pdata - pointer to core platform data + * on - flag to decide power state,PT_MT_POWER_ON/PT_MT_POWER_OFF + * *dev - pointer to device ******************************************************************************/ -static int pt_setup_power_by_gpio(struct pt_core_platform_data *pdata, - int on, struct device *dev) +int pt_setup_power(struct pt_core_platform_data *pdata, int on, + struct device *dev) { - int rc = 0; int en_vcc = pdata->vcc_gpio; int en_vddi = pdata->vddi_gpio; int en_avdd = pdata->avdd_gpio; int en_avee = pdata->avee_gpio; + int rc = 0; + + /* + * For TDDI parts, force part into RESET by holding DDI XRES + * while powering it up + */ + if (pdata->ddi_rst_gpio) + gpio_set_value(pdata->ddi_rst_gpio, 0); + + /* + * Force part into RESET by holding XRES#(TP_XRES) + * while powering it up + */ + if (pdata->rst_gpio) + gpio_set_value(pdata->rst_gpio, 0); if (on == PT_MT_POWER_ON) { /* @@ -975,58 +978,6 @@ static int pt_setup_power_by_gpio(struct pt_core_platform_data *pdata, } } - return rc; -} -#endif /* PT_REGULATOR_EN */ -/******************************************************************************* - * FUNCTION: pt_setup_power - * - * SUMMARY: Turn on/turn off voltage regulator - * - * RETURN: - * 0 = success - * !0 = failure - * - * PARAMETERS: - * *pdata - pointer to core platform data - * on - flag to decide power state,PT_MT_POWER_ON/PT_MT_POWER_OFF - * *dev - pointer to device - ******************************************************************************/ -int pt_setup_power(struct pt_core_platform_data *pdata, int on, - struct device *dev) -{ - int rc = 0; - - /* - * For TDDI parts, force part into RESET by holding DDI XRES - * while powering it up - */ - if (pdata->ddi_rst_gpio) - gpio_set_value(pdata->ddi_rst_gpio, 0); - - /* - * Force part into RESET by holding XRES#(TP_XRES) - * while powering it up - */ - if (pdata->rst_gpio) - gpio_set_value(pdata->rst_gpio, 0); - -#ifdef PT_REGULATOR_EN - rc = pt_setup_power_by_regulator(pdata, on, dev); - if (rc) { - pt_debug(dev, DL_ERROR, - "%s: Failed setup power by regulator rc=%d", - __func__, rc); - } -#else /* PT_REGULATOR_EN */ - rc = pt_setup_power_by_gpio(pdata, on, dev); - if (rc) { - pt_debug(dev, DL_ERROR, - "%s: Failed setup power by gpio rc=%d", - __func__, rc); - } -#endif /* PT_REGULATOR_EN */ - /* Force part out of RESET by releasing XRES#(TP_XRES) */ if (pdata->rst_gpio) gpio_set_value(pdata->rst_gpio, 1); @@ -1038,137 +989,6 @@ int pt_setup_power(struct pt_core_platform_data *pdata, int on, return rc; } -/******************************************************************************* - * FUNCTION: pt_wakeup - * - * SUMMARY: Resume power for "power on/off" sleep strategy which against to - * "deepsleep" strategy. - * - * RETURN: - * 0 = success - * !0 = fail - * - * PARAMETERS: - * *pdata - pointer to the platform data structure - * *dev - pointer to Device structure - * *ignore_irq - pointer to atomic structure to allow the host ignoring false - * IRQ during power up - ******************************************************************************/ -static int pt_wakeup(struct pt_core_platform_data *pdata, - struct device *dev, atomic_t *ignore_irq) -{ - int rc = 0; - -#ifdef PT_PINCTRL_EN - pt_pinctrl_select_normal(pdata, dev); -#endif - rc = pt_setup_power(pdata, PT_MT_POWER_ON, dev); - if (rc) - pt_debug(dev, DL_ERROR, "%s: Failed setup power\n", __func__); - - return rc; -} - -/******************************************************************************* - * FUNCTION: pt_sleep - * - * SUMMARY: Suspend power for "power on/off" sleep strategy which against to - * "deepsleep" strategy. - * - * RETURN: - * 0 = success - * !0 = fail - * - * PARAMETERS: - * *pdata - pointer to the platform data structure - * *dev - pointer to Device structure - * *ignore_irq - pointer to atomic structure to allow the host ignoring false - * IRQ during power down - ******************************************************************************/ -static int pt_sleep(struct pt_core_platform_data *pdata, - struct device *dev, atomic_t *ignore_irq) -{ - int rc = 0; - - rc = pt_setup_power(pdata, PT_MT_POWER_OFF, dev); - if (rc) - pt_debug(dev, DL_ERROR, "%s: Failed setup power\n", __func__); - -#ifdef PT_PINCTRL_EN - pt_pinctrl_select_suspend(pdata, dev); -#endif - return rc; -} - -/******************************************************************************* - * FUNCTION: pt_power - * - * SUMMARY: Wrapper function to resume/suspend power with function - * pt_wakeup()/pt_sleep(). - * - * RETURN: - * 0 = success - * !0 = fail - * - * PARAMETERS: - * *pdata - pointer to the platform data structure - * on - flag to remsume/suspend power(0:resume; 1:suspend) - * *dev - pointer to Device structure - * *ignore_irq - pointer to atomic structure to allow the host ignoring false - * IRQ during power up/down - ******************************************************************************/ -int pt_power(struct pt_core_platform_data *pdata, - int on, struct device *dev, atomic_t *ignore_irq) -{ - if (on) - return pt_wakeup(pdata, dev, ignore_irq); - - return pt_sleep(pdata, dev, ignore_irq); -} - -#ifdef PT_PTSBC_SUPPORT - -static struct workqueue_struct *parade_wq; -static u32 int_handle; - -/******************************************************************************* - * FUNCTION: pt_irq_work_function - * - * SUMMARY: Work function for queued IRQ activity - * - * RETURN: Void - * - * PARAMETERS: - * *work - pointer to work structure - ******************************************************************************/ -static void pt_irq_work_function(struct work_struct *work) -{ - struct pt_core_data *cd = container_of(work, - struct pt_core_data, irq_work); - - pt_irq(cd->irq, (void *)cd); -} - -/******************************************************************************* - * FUNCTION: pt_irq_wrapper - * - * SUMMARY: Wrapper function for IRQ to queue the irq_work function - * - * RETURN: - * 0 = success - * !0 = failure - * - * PARAMETERS: - * *handle - void pointer to contain the core_data pointer - ******************************************************************************/ -peint_handle *pt_irq_wrapper(void *handle) -{ - struct pt_core_data *cd = (struct pt_core_data *)handle; - - queue_work(parade_wq, &cd->irq_work); - return 0; -} -#endif /* PT_PTSBC_SUPPORT */ /******************************************************************************* * FUNCTION: pt_setup_irq @@ -1209,73 +1029,23 @@ int pt_setup_irq(struct pt_core_platform_data *pdata, int on, } if (cd->irq < 0) return -EINVAL; - cd->irq_enabled = true; - pt_debug(dev, DL_INFO, "%s: initialize threaded irq=%d\n", __func__, cd->irq); - if (pdata->level_irq_udelay > 0) -#ifdef PT_PTSBC_SUPPORT /* use level triggered interrupts */ - irq_flags = TRIG_LEVL_LOW; + irq_flags = IRQF_TRIGGER_LOW; else /* use edge triggered interrupts */ - irq_flags = TRIG_EDGE_NEGATIVE; -#else - /* use level triggered interrupts */ - irq_flags = IRQF_TRIGGER_LOW | IRQF_ONESHOT; - else - /* use edge triggered interrupts */ - irq_flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; -#endif /* PT_PTSBC_SUPPORT */ - -#ifdef PT_PTSBC_SUPPORT - /* Adding new work queue to cd struct */ - INIT_WORK(&cd->irq_work, pt_irq_work_function); - - parade_wq = create_singlethread_workqueue("parade_wq"); - if (!parade_wq) - pt_debug(dev, DL_ERROR, "%s Create workqueue failed.\n", - __func__); - - int_handle = sw_gpio_irq_request(pdata->irq_gpio, irq_flags, - (peint_handle)pt_irq_wrapper, cd); - if (!int_handle) { - pt_debug(dev, DL_ERROR, - "%s: PARADE could not request irq\n", __func__); - rc = -1; - } else { - rc = 0; - /* clk=0: 32Khz; clk=1: 24Mhz*/ - ctp_set_int_port_rate(pdata->irq_gpio, 1); - /* - * Debounce INT Line by clock divider: 2^n. E.g. The - * para:0x03 means the period of interrupt controller is - * 0.33 us = (2^3)/24. It has ability to measure the - * high/low width of the pulse bigger than 1 us. - */ - ctp_set_int_port_deb(pdata->irq_gpio, 0x03); - pt_debug(cd->dev, DL_INFO, - "%s: Parade sw_gpio_irq_request SUCCESS\n", - __func__); - } -#else + irq_flags = IRQF_TRIGGER_FALLING; rc = request_threaded_irq(cd->irq, NULL, pt_irq, - irq_flags, dev_name(dev), cd); + irq_flags | IRQF_ONESHOT, dev_name(dev), cd); if (rc < 0) pt_debug(dev, DL_ERROR, "%s: Error, could not request irq\n", __func__); -#endif /* PT_PTSBC_SUPPORT */ } else { disable_irq_nosync(cd->irq); -#ifndef PT_PTSBC_SUPPORT free_irq(cd->irq, cd); -#else - sw_gpio_irq_free(int_handle); - cancel_work_sync(&cd->irq_work); - destroy_workqueue(parade_wq); -#endif /* PT_PTSBC_SUPPORT */ } return rc; } diff --git a/pt/pt_proximity.c b/pt/pt_proximity.c index ae2998b580..1ad0006c08 100644 --- a/pt/pt_proximity.c +++ b/pt/pt_proximity.c @@ -1,4 +1,3 @@ -#ifndef TTDL_KERNEL_SUBMISSION /* * pt_proximity.c * Parade TrueTouch(TM) Standard Product Proximity Module. @@ -75,6 +74,42 @@ static void pt_report_proximity(struct pt_proximity_data *pd, input_sync(pd->input); } +/******************************************************************************* + * FUNCTION: pt_get_touch_axis + * + * SUMMARY: Calculates touch axis + * + * PARAMETERS: + * *pd - pointer to proximity data structure + * *axis - pointer to axis calculation result + * size - size in bytes + * max - max value of result + * *xy_data - pointer to input data to be parsed + * bofs - bit offset + ******************************************************************************/ +static void pt_get_touch_axis(struct pt_proximity_data *pd, + int *axis, int size, int max, u8 *xy_data, int bofs) +{ + int nbyte; + int next; + + for (nbyte = 0, *axis = 0, next = 0; nbyte < size; nbyte++) { + pt_debug(pd->dev, DL_INFO, + "%s: *axis=%02X(%d) size=%d max=%08X xy_data=%p xy_data[%d]=%02X(%d) bofs=%d\n", + __func__, *axis, *axis, size, max, xy_data, next, + xy_data[next], xy_data[next], bofs); + *axis = *axis + ((xy_data[next] >> bofs) << (nbyte * 8)); + next++; + } + + *axis &= max - 1; + + pt_debug(pd->dev, DL_INFO, + "%s: *axis=%02X(%d) size=%d max=%08X xy_data=%p xy_data[%d]=%02X(%d)\n", + __func__, *axis, *axis, size, max, xy_data, next, + xy_data[next], xy_data[next]); +} + /******************************************************************************* * FUNCTION: pt_get_touch_hdr * @@ -95,7 +130,7 @@ static void pt_get_touch_hdr(struct pt_proximity_data *pd, for (hdr = PT_TCH_TIME; hdr < PT_TCH_NUM_HDR; hdr++) { if (!si->tch_hdr[hdr].report) continue; - pt_get_touch_field(dev, &touch->hdr[hdr], + pt_get_touch_axis(pd, &touch->hdr[hdr], si->tch_hdr[hdr].size, si->tch_hdr[hdr].max, xy_mode + si->tch_hdr[hdr].ofs, @@ -126,7 +161,7 @@ static void pt_get_touch(struct pt_proximity_data *pd, for (abs = PT_TCH_X; abs < PT_TCH_NUM_ABS; abs++) { if (!si->tch_abs[abs].report) continue; - pt_get_touch_field(dev, &touch->abs[abs], + pt_get_touch_axis(pd, &touch->abs[abs], si->tch_abs[abs].size, si->tch_abs[abs].max, xy_data + si->tch_abs[abs].ofs, @@ -778,4 +813,3 @@ int pt_proximity_release(struct device *dev) return 0; } -#endif /* !TTDL_KERNEL_SUBMISSION */ diff --git a/pt/pt_regs.h b/pt/pt_regs.h index 2062a1bbcf..acfca02126 100644 --- a/pt/pt_regs.h +++ b/pt/pt_regs.h @@ -41,12 +41,17 @@ #define PT_PIP2_MAX_FILE_SIZE 0x18000 #define PT_PIP2_FILE_SECTOR_SIZE 0x1000 +#ifndef CONFIG_DRM +#define CONFIG_DRM +#endif + #include +#include +#include #ifdef CONFIG_HAS_EARLYSUSPEND #include -#elif defined(CONFIG_FB) -#include -#include +#elif defined(CONFIG_DRM) +#include #endif #include @@ -74,9 +79,12 @@ #include #include +#include +#include #include #include #include +#include #define STATUS_SUCCESS 0 #define STATUS_FAIL -1 @@ -85,7 +93,6 @@ #define PT_FW_FILE_SUFFIX ".bin" #define PT_FW_FILE_NAME "tt_fw.bin" #define PT_FW_RAM_FILE_NAME "tt_fw_ram.bin" -#ifndef TTDL_KERNEL_SUBMISSION /* Enable special TTDL features */ #ifndef TTHE_TUNER_SUPPORT #define TTHE_TUNER_SUPPORT @@ -98,7 +105,6 @@ #ifndef EASYWAKE_TSG6 #define EASYWAKE_TSG6 #endif -#endif /* !TTDL_KERNEL_SUBMISSION */ #ifdef TTHE_TUNER_SUPPORT #define PT_TTHE_TUNER_FILE_NAME "tthe_tuner" @@ -114,17 +120,38 @@ #define PT_MAX_ELEN 100 #endif +/* Power Management Macros Enablement */ + +#ifndef CONFIG_PM +#define CONFIG_PM +#endif + +#ifndef CONFIG_PM_RUNTIME +#define CONFIG_PM_RUNTIME +#endif + +#ifndef CONFIG_PM_SLEEP +#define CONFIG_PM_SLEEP +#endif + +/* Pin Control Macro Enablement */ +#ifndef PT_PINCTRL_EN +#define PT_PINCTRL_EN +#endif + +#ifndef TT7XXX_EXAMPLE +#define TT7XXX_EXAMPLE +#endif + /* * The largest PIP message is the PIP2 FILE_WRITE which has: * 2 byte register * 4 byte header - * 1 byte file handle * 256 byte payload * 2 byte CRC */ -#define PT_MAX_PIP2_MSG_SIZE 265 +#define PT_MAX_PIP2_MSG_SIZE 264 #define PT_MAX_PIP1_MSG_SIZE 255 -#define PT_HID_DESC_SIZE 30 /* * The minimun size of PIP2 packet includes: @@ -165,26 +192,6 @@ enum PT_STARTUP_STATUS { STARTUP_STATUS_FULL = 0x1FF }; -#define SLAVE_DETECT_MASK 0x01 -/* TTDL Built In Self Test selection bit masks */ -enum PT_TTDL_BIST_TESTS { - PT_BIST_BUS_TEST = 0x01, - PT_BIST_IRQ_TEST = 0x02, - PT_BIST_TP_XRES_TEST = 0x04, - PT_BIST_SLAVE_BUS_TEST = 0x08, - PT_BIST_SLAVE_IRQ_TEST = 0x10, - PT_BIST_SLAVE_XRES_TEST = 0x20 -}; - -/* tthe_tuner node format options */ -enum PT_TTHE_TUNER_FORMAT { - PT_TTHE_TUNER_FORMAT_HID_USB = 0x01, - PT_TTHE_TUNER_FORMAT_HID_I2C = 0x02, - PT_TTHE_TUNER_FORMAT_HID_FINGER_TO_PIP = 0x03, - PT_TTHE_TUNER_FORMAT_HID_FINGER_AND_PEN_TO_PIP = 0x04, - PT_TTHE_TUNER_FORMAT_RESERVED = 0xFE, -}; - #define PT_INITIAL_SHOW_TIME_STAMP 0 /* @@ -220,9 +227,7 @@ enum PT_PIP_REPORT_ID { enum PT_HID_REPORT_ID { PT_HID_FINGER_REPORT_ID = 0x01, - PT_HID_PEN_REPORT_ID = 0x02, - PT_HID_VS_FINGER_REPORT_ID = 0x41, /* Vendor Specific ID */ - PT_HID_VS_PEN_REPORT_ID = 0x42 /* Vendor Specific ID */ + PT_HID_PEN_REPORT_ID = 0x02 }; @@ -230,7 +235,6 @@ enum PT_HID_REPORT_ID { #define HID_VENDOR_ID 0x04B4 #define HID_APP_PRODUCT_ID 0xC101 #define HID_VERSION 0x0100 -#define HID_REPORT_DESC_ID 0xF6 #define HID_APP_REPORT_ID 0xF7 #define HID_BL_REPORT_ID 0xFF #define HID_RESPONSE_REPORT_ID 0xF0 @@ -259,7 +263,6 @@ enum PT_HID_REPORT_ID { #define PT_BL_WAIT_FOR_SENTINEL 500 #define PT_REQUEST_ENUM_TIMEOUT 4000 #define PT_GET_HID_DESCRIPTOR_TIMEOUT 500 -#define PT_HID_GET_REPORT_DESCRIPTOR_TIMEOUT 500 #define PT_HID_CMD_DEFAULT_TIMEOUT 500 #define PT_PIP_CMD_DEFAULT_TIMEOUT 2000 #define PT_PIP1_CMD_DEFAULT_TIMEOUT 1000 @@ -272,11 +275,6 @@ enum PT_HID_REPORT_ID { #define PT_PIP1_CMD_INITIATE_BL_TIMEOUT 20000 #define PT_PIP1_CMD_PROGRAM_AND_VERIFY_TIMEOUT 400 #define PT_PIP2_CMD_FILE_ERASE_TIMEOUT 3000 -/* - * BL internal timeout is 500 ms and here it is slightly larger to consider - * the BUS communication cost. (Bugz#92376) - */ -#define PT_PIP2_CMD_FILE_SECTOR_ERASE_TIMEOUT 600 /* Max counts */ #define PT_WATCHDOG_RETRY_COUNT 30 @@ -293,7 +291,6 @@ enum PT_HID_REPORT_ID { #define BTN_INPUT_HEADER_SIZE 5 #define SENSOR_REPORT_SIZE 150 #define SENSOR_HEADER_SIZE 4 -#define MAX_TOUCH_NUM 6 /* helpers */ #define GET_NUM_TOUCHES(x) ((x) & 0x1F) @@ -318,22 +315,6 @@ enum PT_HID_REPORT_ID { '\255') #define HEXOF(x) (x - _base(x)) -#define HID_ITEM_SIZE_MASK 0x03 -#define HID_ITEM_TYPE_MASK 0x0C -#define HID_ITEM_TAG_MASK 0xF0 - -#define HID_ITEM_SIZE_SHIFT 0 -#define HID_ITEM_TYPE_SHIFT 2 -#define HID_ITEM_TAG_SHIFT 4 - -#define HID_GET_ITEM_SIZE(x) \ - ((x & HID_ITEM_SIZE_MASK) >> HID_ITEM_SIZE_SHIFT) -#define HID_GET_ITEM_TYPE(x) \ - ((x & HID_ITEM_TYPE_MASK) >> HID_ITEM_TYPE_SHIFT) -#define HID_GET_ITEM_TAG(x) \ - ((x & HID_ITEM_TAG_MASK) >> HID_ITEM_TAG_SHIFT) - - #define IS_EASY_WAKE_CONFIGURED(x) \ ((x) != 0 && (x) != 0xFF) @@ -381,7 +362,6 @@ enum PT_HID_REPORT_ID { #define PT_DRV_DBG_CLEAR_PARM_LIST 110 #define PT_DRV_DBG_FORCE_BUS_READ 111 #define PT_DRV_DBG_CLEAR_CAL_DATA 112 -#define PT_DUT_DBG_REPORT_DESC 113 /* * Commands that require additional parameters @@ -406,15 +386,25 @@ enum PT_HID_REPORT_ID { #define PT_DRV_DBG_SET_FORCE_SEQ 214 #define PT_DRV_DBG_BL_WITH_NO_INT 215 #define PT_DRV_DBG_CAL_CACHE_IN_HOST 216 -#define PT_DRV_DBG_NUM_DEVICES 217 +#define PT_DRV_DBG_MULTI_CHIP 217 #define PT_DRV_DBG_SET_PANEL_ID_TYPE 218 #define PT_DRV_DBG_PIP_TIMEOUT 219 -#define PT_DRV_DBG_CORE_PLATFORM_FLAG 220 +#define PT_DRV_DBG_TTHE_HID_USB_FORMAT 220 #ifdef TTDL_PTVIRTDUT_SUPPORT #define PT_DRV_DBG_SET_HW_DETECT 298 #define PT_DRV_DBG_VIRTUAL_I2C_DUT 299 #endif /* TTDL_PTVIRTDUT_SUPPORT */ +/* TTDL Built In Self Test selection bit masks */ +#define PT_TTDL_BIST_BUS_TEST 0x01 +#define PT_TTDL_BIST_IRQ_TEST 0x02 +#define PT_TTDL_BIST_TP_XRES_TEST 0x04 +#define PT_TTDL_BIST_SLAVE_BUS_TEST 0x08 +#define PT_TTDL_BIST_SLAVE_IRQ_TEST 0x10 +#define PT_TTDL_BIST_SLAVE_XRES_TEST 0x20 + +#define SLAVE_DETECT_MASK 0x01 + #define VIRT_MAX_IRQ_RELEASE_TIME_US 500000 #endif /* TTDL DIAGNOSTICS */ @@ -448,9 +438,8 @@ enum PT_HID_REPORT_ID { #define HID_PT_BUTTONSIGNAL 0xff010065 #define HID_PT_MAJOR_CONTACT_AXIS_LENGTH 0xff010066 #define HID_PT_MINOR_CONTACT_AXIS_LENGTH 0xff010067 -#define HID_PT_TCH_COL_USAGE_PG 0x000D0004 +#define HID_PT_TCH_COL_USAGE_PG 0x000D0022 #define HID_PT_BTN_COL_USAGE_PG 0xFF010020 -#define HID_PT_PEN_COL_USAGE_PG 0x000D0020 #define PANEL_ID_NOT_ENABLED 0xFF @@ -621,30 +610,26 @@ enum PIP2_FW_SYSTEM_MODE { /* PIP2 Command/Response data and structures */ enum PIP2_FILE_ID { - PIP2_RAM_FILE = 0x00, - PIP2_FW_FILE = 0x01, - PIP2_CONFIG_FILE = 0x02, - PIP2_FILE_3 = 0x03, - PIP2_FILE_4 = 0x04, - PIP2_FILE_5 = 0x05, - PIP2_FILE_6 = 0x06, - PIP2_FILE_7 = 0x07, - PIP2_FILE_8 = 0x08, - PIP2_FILE_RESERVED = 0x0F, - PIP2_FILE_MAX = PIP2_FILE_RESERVED, + PIP2_RAM_FILE = 0x00, + PIP2_FW_FILE = 0x01, + PIP2_CONFIG_FILE = 0x02, + PIP2_FILE_3 = 0x03, + PIP2_FILE_4 = 0x04, + PIP2_FILE_5 = 0x05, + PIP2_FILE_6 = 0x06, + PIP2_FILE_7 = 0x07, + PIP2_FILE_MAX = PIP2_FILE_7, }; /* Optimize packet sizes per Allwinner H3 bus drivers */ -#define PIP2_FILE_WRITE_LEN_PER_PACKET (245) -#define PIP2_BL_I2C_FILE_WRITE_LEN_PER_PACKET (245) -#define PIP2_BL_SPI_FILE_WRITE_LEN_PER_PACKET (256) -#define PIP2_FILE_WRITE_MAX_LEN_PER_PACKET \ - PIP2_BL_SPI_FILE_WRITE_LEN_PER_PACKET +#define PIP2_FILE_WRITE_LEN_PER_PACKET 245 +#define PIP2_BL_I2C_FILE_WRITE_LEN_PER_PACKET 245 +#define PIP2_BL_SPI_FILE_WRITE_LEN_PER_PACKET 256 enum DUT_GENERATION { DUT_UNKNOWN = 0x00, - DUT_PIP1_ONLY = 0x01, - DUT_PIP2_CAPABLE = 0x02, + DUT_PIP1_ONLY = 0x01, + DUT_PIP2_CAPABLE = 0x02, }; enum PIP2_RSP_ERR { @@ -673,10 +658,6 @@ enum PIP2_RSP_ERR { PIP2_RSP_ERR_UNKNOWN_REGISTER = 0x16, PIP2_RSP_ERR_BAD_LENGTH = 0x17, PIP2_RSP_ERR_TRIM_FAILURE = 0x18, - PIP2_RSP_ERR_BAD_SEQ = 0x19, - PIP2_RSP_ERR_BUF_TOO_SMALL = 0x1A, - PIP2_RSP_ERR_ASYNC_SEQ = 0x1B, - PIP2_RSP_ERR_EXEC_IMAGE = 0x1C, }; /* @@ -731,7 +712,7 @@ enum pip1_bl_status { ERROR_FLASH_ARRAY, ERROR_FLASH_ROW, ERROR_FLASH_PROTECTION, - ERROR_UKNOWN = 15, + ERROR_UNKNOWN = 15, ERROR_INVALID, }; @@ -742,18 +723,6 @@ enum pt_mode { PT_MODE_IGNORE = 255, }; -enum pt_protocol_mode { - PT_PROTOCOL_MODE_PIP = 0, - PT_PROTOCOL_MODE_HID = 1, - PT_PROTOCOL_MODE_IGNORE = 255, -}; - -struct pt_dut_status { - enum PIP2_FW_SYSTEM_MODE fw_system_mode; - enum pt_mode mode; - enum pt_protocol_mode protocol_mode; -} __packed; - enum PT_ENTER_BL_RESULT { PT_ENTER_BL_PASS = 0, PT_ENTER_BL_ERROR = 1, @@ -823,12 +792,8 @@ enum pt_self_test_result { }; #define PT_ST_PRINT_RESULTS true #define PT_ST_NOPRINT false - -enum pt_st_get_result { - PT_ST_DONT_GET_RESULTS = 0, - PT_ST_GET_RESULTS = 1, - PT_ST_GET_RESULTS_BASED_ON_DATA = 2, -}; +#define PT_ST_GET_RESULTS true +#define PT_ST_DONT_GET_RESULTS false /* * Maximum number of parameters for the fw_self_test sysfs (255 - 12 + 2) @@ -1058,8 +1023,7 @@ struct pt_tch_abs_params { size_t min; /* min value */ size_t max; /* max value */ size_t bofs; /* bit offset */ - u8 report; /* non-zero: valid; 0: invalid */ - size_t logical_max; /* logical max value */ + u8 report; }; struct pt_touch { @@ -1067,55 +1031,6 @@ struct pt_touch { int abs[PT_TCH_NUM_ABS]; }; -enum pt_pen_abs { /* for ordering within the extracted pen data array */ - PT_PEN_X, /* X */ - PT_PEN_Y, /* Y */ - PT_PEN_P, /* P (Z) */ - PT_PEN_X_TILT, /* X TILT */ - PT_PEN_Y_TILT, /* Y TILT */ - PT_PEN_TS, /* Tip Switch */ - PT_PEN_BS, /* Barrel Switch */ - PT_PEN_IV, /* Invert */ - PT_PEN_ER, /* Eraser */ - PT_PEN_2ND_BS, /* 2nd Barrel Switch */ - PT_PEN_IR, /* In Range */ - PT_PEN_NUM_ABS, -}; - -static const int pt_pen_abs_field_map[] = { - [PT_PEN_X] = 0x00010030 /* HID_GD_X */, - [PT_PEN_Y] = 0x00010031 /* HID_GD_Y */, - [PT_PEN_P] = 0x000D0030, - [PT_PEN_X_TILT] = 0x000D003D, - [PT_PEN_Y_TILT] = 0x000D003E, - [PT_PEN_TS] = 0x000D0042, - [PT_PEN_BS] = 0x000D0044, - [PT_PEN_IV] = 0x000D003C, - [PT_PEN_ER] = 0x000D0045, - [PT_PEN_2ND_BS] = 0x000D005A, - [PT_PEN_IR] = 0x000D0032, - [PT_PEN_NUM_ABS] = 0, -}; - -static const char * const pt_pen_abs_string[] = { - [PT_PEN_X] = "X", - [PT_PEN_Y] = "Y", - [PT_PEN_P] = "P", - [PT_PEN_X_TILT] = "X_TILT", - [PT_PEN_Y_TILT] = "Y_TILT", - [PT_PEN_TS] = "Tip_Switch", - [PT_PEN_BS] = "Barrel_Switch", - [PT_PEN_IV] = "Invert", - [PT_PEN_ER] = "Eraser", - [PT_PEN_2ND_BS] = "2nd Barrel_Switch", - [PT_PEN_IR] = "In_Range", - [PT_PEN_NUM_ABS] = "INVALID", -}; - -struct pt_pen { - int abs[PT_PEN_NUM_ABS]; -}; - /* button to keycode support */ #define PT_BITS_PER_BTN 1 #define PT_NUM_BTN_EVENT_ID ((1 << PT_BITS_PER_BTN) - 1) @@ -1154,9 +1069,6 @@ struct pt_report_desc_data { u16 tch_record_size; u16 tch_header_size; u16 btn_report_id; - u16 pen_report_id; - u8 max_touch_num; - u8 max_tch_per_packet; }; struct pt_sysinfo { @@ -1169,7 +1081,6 @@ struct pt_sysinfo { struct pt_ttconfig ttconfig; struct pt_tch_abs_params tch_hdr[PT_TCH_NUM_HDR]; struct pt_tch_abs_params tch_abs[PT_TCH_NUM_ABS]; - struct pt_tch_abs_params pen_abs[PT_PEN_NUM_ABS]; u8 *xy_mode; u8 *xy_data; }; @@ -1238,14 +1149,13 @@ struct pt_hid_core { u16 hid_max_output_len; }; -#define PT_HID_MAX_REPORTS 20 -#define PT_HID_MAX_FIELDS 128 -#define PT_HID_MAX_COLLECTIONS 3 -#define PT_HID_MAX_NESTED_COLLECTIONS PT_HID_MAX_COLLECTIONS -#define PT_HID_MAX_CONTINUOUS_USAGES 8 +#define PT_HID_MAX_REPORTS 8 +#define PT_HID_MAX_FIELDS 128 +#define PT_HID_MAX_COLLECTIONS 3 +#define PT_HID_MAX_NESTED_COLLECTIONS PT_HID_MAX_COLLECTIONS /* Max input is for ASCII representation of hex characters */ -#define PT_MAX_INPUT 2048 +#define PT_MAX_INPUT (PT_MAX_PIP2_MSG_SIZE * 2) #define PT_PIP_1P7_EMPTY_BUF 0xFF00 enum pt_module_id { @@ -1285,18 +1195,6 @@ struct pt_mt_data { int t_max; }; -struct pt_pen_data { - struct device *dev; - struct pt_pen_platform_data *pdata; - struct pt_sysinfo *si; - struct input_dev *input; - struct mutex pen_lock; - bool is_suspended; - bool input_device_registered; - bool input_device_allocated; - char phys[NAME_MAX]; -}; - struct pt_btn_data { struct device *dev; struct pt_btn_platform_data *pdata; @@ -1423,8 +1321,7 @@ struct pt_core_nonhid_cmd { int (*get_bl_pip2_version)(struct device *dev); int (*pip2_file_open)(struct device *dev, u8 file_no); int (*pip2_file_close)(struct device *dev, u8 file_no); - int (*pip2_file_erase)(struct device *dev, u8 file_no, u16 file_sector, - int *status); + int (*pip2_file_erase)(struct device *dev, u8 file_no, int *status); int (*read_us_file)(struct device *dev, u8 *file_path, u8 *buf, int *size); int (*pip2_file_read)(struct device *dev, u8 file_no, @@ -1472,11 +1369,9 @@ struct pt_core_commands { struct pt_bin_file_hdr *hdr); int (*request_dut_generation)(struct device *dev); int (*request_hw_version)(struct device *dev, char *hw_version); -#ifndef TTDL_KERNEL_SUBMISSION int (*parse_sysfs_input)(struct device *dev, const char *buf, size_t buf_size, u32 *out_buf, size_t out_buf_size); -#endif #ifdef TTHE_TUNER_SUPPORT int (*request_tthe_print)(struct device *dev, u8 *buf, int buf_len, const u8 *data_name); @@ -1529,26 +1424,18 @@ struct pt_bus_ops { int (*read_default)(struct device *dev, void *buf, int size); int (*read_default_nosize)(struct device *dev, u8 *buf, u32 max); int (*write_read_specific)(struct device *dev, u16 write_len, - u8 *write_buf, u8 *read_buf, u16 read_len); -}; - -#define PT_MAX_DEVICES 3 -struct pt_bist_data { - u8 detected; - u8 mask; - u8 boot_err; - u8 bus_toggled; - u8 irq_toggled; - u8 xres_toggled; - char *bus_err_str; - char *irq_err_str; - char *xres_err_str; - char *print_buf; - u16 pr_index; - int status; + u8 *write_buf, u8 *read_buf); }; struct pt_core_data { + struct pinctrl *ts_pinctrl; + struct pinctrl_state *pinctrl_state_active; + struct pinctrl_state *pinctrl_state_suspend; + struct pinctrl_state *pinctrl_state_release; + + struct regulator *vdd; + struct regulator *vcc_i2c; + struct list_head node; struct list_head module_list; /* List of probed modules */ char core_id[20]; @@ -1560,11 +1447,9 @@ struct pt_core_data { struct mutex sysfs_lock; struct mutex ttdl_restart_lock; struct mutex firmware_class_lock; - struct mutex hid_report_lock; enum pt_mode mode; spinlock_t spinlock; struct pt_mt_data md; - struct pt_pen_data pend; struct pt_btn_data bd; struct pt_proximity_data pd; int phys_num; @@ -1582,6 +1467,7 @@ struct pt_core_data { bool irq_wake; bool irq_disabled; bool hw_detected; + bool runtime; u8 easy_wakeup_gesture; #ifdef EASYWAKE_TSG6 u8 gesture_id; @@ -1602,37 +1488,28 @@ struct pt_core_data { #endif struct pt_sysinfo sysinfo; struct pt_bl_info bl_info; - struct pt_dut_status dut_status; void *exclusive_dev; int exclusive_waits; struct timer_list watchdog_timer; struct work_struct watchdog_work; struct work_struct enum_work; struct work_struct ttdl_restart_work; -#ifdef PT_PTSBC_SUPPORT - struct work_struct irq_work; - struct work_struct probe_work; - struct timer_list probe_timer; -#endif u16 startup_retry_count; struct pt_hid_core hid_core; int hid_cmd_state; int hid_reset_cmd_state; /* reset can happen any time */ struct pt_hid_desc hid_desc; - struct pt_hid_report *hid_reports[PT_HID_MAX_REPORTS]; - int num_hid_reports; struct pt_features features; #define PT_PREALLOCATED_CMD_BUFFER 32 u8 cmd_buf[PT_PREALLOCATED_CMD_BUFFER]; u8 input_buf[PT_MAX_INPUT]; u8 response_buf[PT_MAX_INPUT]; u8 cmd_rsp_buf[PT_MAX_INPUT]; - u8 touch_buf[PT_MAX_INPUT]; u16 cmd_rsp_buf_len; int raw_cmd_status; #ifdef CONFIG_HAS_EARLYSUSPEND struct early_suspend es; -#elif defined(CONFIG_FB) +#elif defined(CONFIG_FB) || defined(CONFIG_DRM) struct notifier_block fb_notifier; enum pt_fb_state fb_state; #endif @@ -1663,7 +1540,7 @@ struct pt_core_data { u8 flashless_dut; u8 bl_with_no_int; u8 cal_cache_in_host; - u8 num_devices; + u8 multi_chip; u8 tthe_hid_usb_format; u8 flashless_auto_bl; u8 pip2_us_file_path[PT_MAX_PATH_SIZE]; @@ -1741,10 +1618,10 @@ static inline int pt_adap_read_default_nosize(struct pt_core_data *cd, } static inline int pt_adap_write_read_specific(struct pt_core_data *cd, - u16 write_len, u8 *write_buf, u8 *read_buf, u16 read_len) + u16 write_len, u8 *write_buf, u8 *read_buf) { return cd->bus_ops->write_read_specific(cd->dev, write_len, write_buf, - read_buf, read_len); + read_buf); } static inline void *pt_get_dynamic_data(struct device *dev, int id) @@ -1815,9 +1692,6 @@ int pt_release(struct pt_core_data *cd); struct pt_core_commands *pt_get_commands(void); struct pt_core_data *pt_get_core_data(char *id); -#ifdef PT_AUX_BRIDGE_ENABLED -int pt_trigger_ttdl_irq(void); -#endif int pt_mt_release(struct device *dev); int pt_mt_probe(struct device *dev); @@ -1841,9 +1715,9 @@ static inline int pt_proximity_release(struct device *dev) { return 0; } static inline unsigned int pt_get_time_stamp(void) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)) - struct timespec64 ts; + struct timespec ts; - ktime_get_real_ts64(&ts); + getnstimeofday(&ts); return (ts.tv_sec*1000 + ts.tv_nsec/1000000); #else struct timeval tv; @@ -1854,8 +1728,6 @@ static inline unsigned int pt_get_time_stamp(void) } void pt_init_function_ptrs(struct pt_mt_data *md); -void pt_get_touch_field(struct device *dev, - int *field, int size, int max, u8 *data, int bofs); int _pt_subscribe_attention(struct device *dev, enum pt_atten_type type, char *id, int (*func)(struct device *), int mode); diff --git a/pt/pt_spi.c b/pt/pt_spi.c index c921ee8c86..d8db405282 100644 --- a/pt/pt_spi.c +++ b/pt/pt_spi.c @@ -51,179 +51,6 @@ static u8 *tmp_rbuf; static u8 *tmp_wbuf; DEFINE_MUTEX(pt_spi_bus_lock); -#ifdef TTDL_PTVIRTDUT_SUPPORT -#define VIRT_DUT_BUF_SIZE 300 -static unsigned char pt_dut_cmd_buf[VIRT_DUT_BUF_SIZE]; -static unsigned char pt_dut_out_buf[VIRT_DUT_BUF_SIZE]; -static int pt_dut_cmd_len; -static int pt_dut_out_len; -DEFINE_MUTEX(virt_spi_lock); - -/******************************************************************************* - * FUNCTION: virt_spi_transfer - * - * SUMMARY: Copies the current spi output message to the temporary buffer - * used by the dut_cmd sysfs node - * - * RETURN VALUE: - * Number of messages transferred which in this function will be 1 - * - * PARAMETERS: - * *buf - pointer to spi command - * len - length of command in the buffer - ******************************************************************************/ -static int virt_spi_transfer(u8 *buf, int len) -{ - int rc = 0; - - mutex_lock(&virt_spi_lock); - if (len <= sizeof(pt_dut_cmd_buf)) { - memcpy(pt_dut_cmd_buf, buf, len); - pt_dut_cmd_len = len; - rc = 1; - } else - rc = 0; - mutex_unlock(&virt_spi_lock); - - return rc; -} - -/******************************************************************************* - * FUNCTION: virt_spi_master_recv - * - * SUMMARY: Copies the spi input message from the dut_out sysfs node into a - * temporary buffer. - * - * RETURN VALUE: - * Length of data transferred - * - * PARAMETERS: - * *dev - pointer to device struct - * *buf - pointer to spi incoming report - * size - size to be read - ******************************************************************************/ -static int virt_spi_master_recv(struct device *dev, u8 *buf, int size) -{ -#ifndef PT_POLL_RESP_BY_BUS - struct pt_core_data *cd = dev_get_drvdata(dev); - int i = 0; -#endif - - mutex_lock(&virt_spi_lock); - memcpy(buf, pt_dut_out_buf, size); - - /* Set "empty buffer" */ - pt_dut_out_buf[1] = 0xFF; - pt_dut_out_len = 0; - mutex_unlock(&virt_spi_lock); - -#ifndef PT_POLL_RESP_BY_BUS - if (cd->bl_with_no_int) { - /* - * Wait for IRQ gpio to be released, make read operation - * synchronize with PtVirtDut tool. - * Safety net: Exit after 500ms (50us * 10000 loops = 500ms) - */ - while (i < VIRT_MAX_IRQ_RELEASE_TIME_US && - !gpio_get_value(cd->cpdata->irq_gpio)) { - pt_debug(dev, DL_INFO, "%s: %d IRQ still Enabled\n", - __func__, i); - usleep_range(50, 60); - i += 50; - } - } -#endif - - pt_debug(dev, DL_INFO, - "%s: Copy msg from dut_out to spi buffer, size=%d\n", - __func__, size); - - return size; -} - -/******************************************************************************* - * FUNCTION: pt_dut_cmd_show - * - * SUMMARY: The show function for the dut_cmd sysfs node. Provides read access - * to the pt_dut_cmd_buf and clears it after it has been read. - * - * RETURN VALUE: - * Number of bytes transferred - * - * PARAMETERS: - * *dev - pointer to device structure - * *attr - pointer to device attributes - * *buf - pointer to output buffer - ******************************************************************************/ -static ssize_t pt_dut_cmd_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int i; - int index = 0; - - /* Only print to sysfs if the buffer has data */ - mutex_lock(&virt_spi_lock); - if (pt_dut_cmd_len > 0) { - for (i = 0; i < pt_dut_cmd_len; i++) - index += scnprintf(buf + index, strlen(buf), "%02X", - pt_dut_cmd_buf[i]); - index += scnprintf(buf + index, strlen(buf), "\n"); - } - pt_dut_cmd_len = 0; - mutex_unlock(&virt_spi_lock); - return index; -} -static DEVICE_ATTR(dut_cmd, 0444, pt_dut_cmd_show, NULL); - -/******************************************************************************* - * FUNCTION: pt_dut_out_store - * - * SUMMARY: The store function for the dut_out sysfs node. Provides write - * access to the pt_dut_out_buf. The smallest valid PIP response is 2 - * bytes so don't update buffer if only 1 byte passed in. - * - * RETURN VALUE: - * Number of bytes read from virtual DUT - * - * PARAMETERS: - * *dev - pointer to device structure - * *attr - pointer to device attributes - * *buf - pointer to buffer that hold the command parameters - * size - size of buf - ******************************************************************************/ -static ssize_t pt_dut_out_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - int loop_max = ARRAY_SIZE(pt_dut_out_buf); - int hex_str_len = strlen(buf)/2; - int i; - const char *pos = buf; - - /* Clear out the last message */ - mutex_lock(&virt_spi_lock); - memset(pt_dut_out_buf, 0, VIRT_DUT_BUF_SIZE); - pt_dut_out_len = 0; - - /* Only update the dut_out buffer if at least 2 byte payload */ - if (size >= 2 && hex_str_len <= loop_max) { - /* Convert string of hex values to byte array */ - for (i = 0; i < hex_str_len; i++) { - pt_dut_out_buf[i] = ((HEXOF(*pos)) << 4) + - HEXOF(*(pos + 1)); - pos += 2; - } - pt_dut_out_len = get_unaligned_le16(&pt_dut_out_buf[0]); - } else if (size >= PT_PIP_1P7_EMPTY_BUF) { - /* Message too large, set to 'empty buffer' message */ - pt_dut_out_buf[1] = 0xFF; - pt_dut_out_len = 0; - } - mutex_unlock(&virt_spi_lock); - - return size; -} -static DEVICE_ATTR(dut_out, 0200, NULL, pt_dut_out_store); -#endif /* TTDL_PTVIRTDUT_SUPPORT */ /******************************************************************************* * FUNCTION: pt_spi_xfer @@ -312,23 +139,13 @@ exit: ******************************************************************************/ static int pt_spi_read_default(struct device *dev, void *buf, int size) { -#ifdef TTDL_PTVIRTDUT_SUPPORT - struct pt_core_data *cd = dev_get_drvdata(dev); -#endif /* TTDL_PTVIRTDUT_SUPPORT */ int rc = 0; if (!buf || !size || size > PT_MAX_PIP2_MSG_SIZE) return -EINVAL; mutex_lock(&pt_spi_bus_lock); -#ifdef TTDL_PTVIRTDUT_SUPPORT - if (cd->route_bus_virt_dut) - virt_spi_master_recv(dev, buf, size); - else - rc = pt_spi_xfer(dev, PT_SPI_RD_OP, buf, size); -#else rc = pt_spi_xfer(dev, PT_SPI_RD_OP, buf, size); -#endif /* TTDL_PTVIRTDUT_SUPPORT */ mutex_unlock(&pt_spi_bus_lock); return rc; @@ -357,21 +174,6 @@ static int pt_spi_read_default_nosize(struct device *dev, u8 *buf, u32 max) { u32 size; int rc = 0; -#ifdef TTDL_PTVIRTDUT_SUPPORT - struct pt_core_data *cd = dev_get_drvdata(dev); - - if (cd->route_bus_virt_dut) { - mutex_lock(&virt_spi_lock); - size = pt_dut_out_len; - mutex_unlock(&virt_spi_lock); - /* Only copy 2 bytes for "empty buffer" or "FW sentinel" */ - if (!size || size == 2 || size >= PT_PIP_1P7_EMPTY_BUF) - size = 2; - virt_spi_master_recv(dev, buf, size); - return 0; - } - -#endif /* TTDL_PTVIRTDUT_SUPPORT */ if (!buf) return 0; @@ -418,18 +220,14 @@ exit: * !0 = failure * * PARAMETERS: - * *dev - pointer to Device structure - * write_len - length of data buffer write_buf - * *write_buf - pointer to buffer to write - * *read_buf - pointer to buffer to read response into - * read_len - length to read, 0 to use pt_spi_read_default_nosize + * *dev - pointer to Device structure + * write_len - length of data buffer write_buf + * *write_buf - pointer to buffer to write + * *read_buf - pointer to buffer to read response into ******************************************************************************/ static int pt_spi_write_read_specific(struct device *dev, u16 write_len, - u8 *write_buf, u8 *read_buf, u16 read_len) + u8 *write_buf, u8 *read_buf) { -#ifdef TTDL_PTVIRTDUT_SUPPORT - struct pt_core_data *cd = dev_get_drvdata(dev); -#endif /* TTDL_PTVIRTDUT_SUPPORT */ int rc = 0; /* Ensure no packet larger than what the PIP spec allows */ @@ -447,21 +245,9 @@ static int pt_spi_write_read_specific(struct device *dev, u16 write_len, } mutex_lock(&pt_spi_bus_lock); -#ifdef TTDL_PTVIRTDUT_SUPPORT - if (cd->route_bus_virt_dut) { - virt_spi_transfer(write_buf, write_len); - pt_debug(dev, DL_DEBUG, "%s: Virt transfer size = %d", - __func__, write_len); - } else { - rc = pt_spi_xfer(dev, PT_SPI_WR_OP, write_buf, write_len); - if (rc < 0) - goto error; - } -#else rc = pt_spi_xfer(dev, PT_SPI_WR_OP, write_buf, write_len); if (rc < 0) goto error; -#endif /* TTDL_PTVIRTDUT_SUPPORT */ mutex_unlock(&pt_spi_bus_lock); if (read_buf) @@ -534,10 +320,6 @@ static int pt_spi_probe(struct spi_device *spi) if (!tmp_wbuf || !tmp_rbuf) return -ENOMEM; -#ifdef TTDL_PTVIRTDUT_SUPPORT - device_create_file(dev, &dev_attr_dut_cmd); - device_create_file(dev, &dev_attr_dut_out); -#endif /* TTDL_PTVIRTDUT_SUPPORT */ rc = pt_probe(&pt_spi_bus_ops, &spi->dev, spi->irq, PT_SPI_DATA_BUF_SIZE); @@ -547,12 +329,6 @@ static int pt_spi_probe(struct spi_device *spi) pt_devtree_clean_pdata(dev); #endif -#ifdef TTDL_PTVIRTDUT_SUPPORT - if (rc) { - device_remove_file(dev, &dev_attr_dut_cmd); - device_remove_file(dev, &dev_attr_dut_out); - } -#endif /* TTDL_PTVIRTDUT_SUPPORT */ return rc; } @@ -580,10 +356,6 @@ static int pt_spi_remove(struct spi_device *spi) kfree(tmp_rbuf); kfree(tmp_wbuf); -#ifdef TTDL_PTVIRTDUT_SUPPORT - device_remove_file(dev, &dev_attr_dut_cmd); - device_remove_file(dev, &dev_attr_dut_out); -#endif /* TTDL_PTVIRTDUT_SUPPORT */ pt_release(cd);