summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--syna_tcm2.c12
-rw-r--r--tcm/synaptics_touchcom_core_dev.h11
-rw-r--r--tcm/synaptics_touchcom_core_v1.c105
-rw-r--r--tcm/synaptics_touchcom_func_base.c29
-rw-r--r--tcm/synaptics_touchcom_func_base.h15
-rw-r--r--tcm/synaptics_touchcom_func_reflash.c3
6 files changed, 135 insertions, 40 deletions
diff --git a/syna_tcm2.c b/syna_tcm2.c
index cbbc153..7fcb58d 100644
--- a/syna_tcm2.c
+++ b/syna_tcm2.c
@@ -910,13 +910,11 @@ static void syna_dev_reflash_startup_work(struct work_struct *work)
goto exit;
}
- /* allocate the input device if not registered yet */
- if (tcm->input_dev == NULL) {
- retval = syna_dev_set_up_input_device(tcm);
- if (retval < 0) {
- LOGE("Fail to register input device\n");
- goto exit;
- }
+ /* check and re-create the input device if needed */
+ retval = syna_dev_set_up_input_device(tcm);
+ if (retval < 0) {
+ LOGE("Fail to register input device\n");
+ goto exit;
}
exit:
diff --git a/tcm/synaptics_touchcom_core_dev.h b/tcm/synaptics_touchcom_core_dev.h
index 0b8bcf4..4765713 100644
--- a/tcm/synaptics_touchcom_core_dev.h
+++ b/tcm/synaptics_touchcom_core_dev.h
@@ -44,7 +44,7 @@
#include "syna_tcm2_platform.h"
-#define SYNA_TCM_CORE_LIB_VERSION 0x0111
+#define SYNA_TCM_CORE_LIB_VERSION 0x0112
/**
@@ -596,7 +596,7 @@ struct tcm_message_data_blob {
unsigned char seq_toggle;
unsigned int default_resp_reading;
- /* completion event command processing */
+ /* completion event for command processing */
syna_pal_completion_t cmd_completion;
/* internal buffers
@@ -614,6 +614,13 @@ struct tcm_message_data_blob {
/* mutex for the read/write protection */
syna_pal_mutex_t rw_mutex;
+ /* flag for the enabling of predict reading
+ * predict reading aims to retrieve all data in one transfer;
+ * otherwise, standard reading reads 4-byte header and payload
+ * data separately
+ */
+ bool predict_reads;
+ unsigned int predict_length;
};
/**
diff --git a/tcm/synaptics_touchcom_core_v1.c b/tcm/synaptics_touchcom_core_v1.c
index d10380f..e18d8ee 100644
--- a/tcm/synaptics_touchcom_core_v1.c
+++ b/tcm/synaptics_touchcom_core_v1.c
@@ -485,7 +485,7 @@ exit:
*
* @param
* [ in] tcm_dev: the device handle
- * [ in] length: length of payload data
+ * [ in] length: remaining length of payload data
*
* @return
* on success, 0 or positive value; otherwise, negative value on error.
@@ -511,9 +511,18 @@ static int syna_tcm_v1_continued_read(struct tcm_dev *tcm_dev,
tcm_msg = &tcm_dev->msg_data;
+ if ((length == 0) || (tcm_msg->payload_length == 0))
+ return 0;
+
+ if ((length & 0xffff) == 0xffff) {
+ LOGE("Invalid length to read\n");
+ return _EINVAL;
+ }
+
/* continued read packet contains the header, payload, and a padding */
- total_length = MESSAGE_HEADER_SIZE + length + 1;
- remaining_length = total_length - MESSAGE_HEADER_SIZE;
+ total_length = MESSAGE_HEADER_SIZE + tcm_msg->payload_length + 1;
+ /* length to read, remember a padding at the end */
+ remaining_length = length + 1;
syna_tcm_buf_lock(&tcm_msg->in);
@@ -527,7 +536,7 @@ static int syna_tcm_v1_continued_read(struct tcm_dev *tcm_dev,
}
/* available chunk space for payload =
- * total chunk size - (header marker byte + header status byte)
+ * total chunk size - (marker + status code)
*/
if (tcm_dev->max_rd_size == 0)
chunk_space = remaining_length;
@@ -537,7 +546,7 @@ static int syna_tcm_v1_continued_read(struct tcm_dev *tcm_dev,
chunks = syna_pal_ceil_div(remaining_length, chunk_space);
chunks = chunks == 0 ? 1 : chunks;
- offset = MESSAGE_HEADER_SIZE;
+ offset = MESSAGE_HEADER_SIZE + (tcm_msg->payload_length - length);
syna_tcm_buf_lock(&tcm_msg->temp);
@@ -629,6 +638,8 @@ static int syna_tcm_v1_read_message(struct tcm_dev *tcm_dev,
struct tcm_message_data_blob *tcm_msg = NULL;
syna_pal_mutex_t *rw_mutex = NULL;
syna_pal_completion_t *cmd_completion = NULL;
+ unsigned int len = 0;
+ bool do_predict = false;
if (!tcm_dev) {
LOGE("Invalid tcm device handle\n");
@@ -639,6 +650,9 @@ static int syna_tcm_v1_read_message(struct tcm_dev *tcm_dev,
rw_mutex = &tcm_msg->rw_mutex;
cmd_completion = &tcm_msg->cmd_completion;
+ /* predict reading is applied when report streaming only */
+ do_predict = (ATOMIC_GET(tcm_msg->command_status) == CMD_STATE_IDLE);
+
if (status_report_code)
*status_report_code = STATUS_INVALID;
@@ -646,9 +660,27 @@ static int syna_tcm_v1_read_message(struct tcm_dev *tcm_dev,
syna_tcm_buf_lock(&tcm_msg->in);
+ /* determine the length to read */
+ len = MESSAGE_HEADER_SIZE;
+ if (tcm_msg->predict_reads && do_predict)
+ len += tcm_msg->predict_length;
+
+ /* ensure the size of in.buf */
+ if (len > tcm_msg->in.buf_size) {
+ retval = syna_tcm_buf_alloc(&tcm_msg->in, len);
+ if (retval < 0) {
+ LOGE("Fail to allocate memory for buf_in\n");
+ syna_tcm_buf_unlock(&tcm_msg->in);
+
+ tcm_msg->status_report_code = STATUS_INVALID;
+ tcm_msg->payload_length = 0;
+ goto exit;
+ }
+ }
+
/* read in the message header from device */
retval = syna_tcm_v1_read(tcm_dev,
- MESSAGE_HEADER_SIZE,
+ len,
tcm_msg->in.buf,
tcm_msg->in.buf_size
);
@@ -676,31 +708,16 @@ static int syna_tcm_v1_read_message(struct tcm_dev *tcm_dev,
syna_tcm_buf_unlock(&tcm_msg->in);
- if ((tcm_msg->status_report_code <= STATUS_ERROR) ||
- (tcm_msg->status_report_code == STATUS_INVALID)) {
- switch (tcm_msg->status_report_code) {
- case STATUS_OK:
- break;
- case STATUS_CONTINUED_READ:
- LOGE("Out-of-sync continued read\n");
- case STATUS_IDLE:
- tcm_msg->payload_length = 0;
- retval = 0;
- goto exit;
- default:
- LOGE("Incorrect Status code, 0x%02x\n",
- tcm_msg->status_report_code);
- tcm_msg->payload_length = 0;
- goto do_dispatch;
- }
- }
-
if (tcm_msg->payload_length == 0)
goto do_dispatch;
+ if (tcm_msg->payload_length > (len - MESSAGE_HEADER_SIZE))
+ len = tcm_msg->payload_length - (len - MESSAGE_HEADER_SIZE);
+ else
+ len = 0;
+
/* retrieve the remaining data, if any */
- retval = syna_tcm_v1_continued_read(tcm_dev,
- tcm_msg->payload_length);
+ retval = syna_tcm_v1_continued_read(tcm_dev, len);
if (retval < 0) {
LOGE("Fail to do continued read\n");
goto exit;
@@ -737,6 +754,26 @@ do_dispatch:
tcm_dev->external_buf.data_length = tcm_msg->payload_length;
syna_tcm_buf_unlock(&tcm_dev->external_buf);
+ if ((tcm_msg->status_report_code <= STATUS_ERROR) ||
+ (tcm_msg->status_report_code == STATUS_INVALID)) {
+ switch (tcm_msg->status_report_code) {
+ case STATUS_OK:
+ break;
+ case STATUS_CONTINUED_READ:
+ LOGE("Out-of-sync continued read\n");
+ retval = _EIO;
+ goto exit;
+ case STATUS_IDLE:
+ retval = 0;
+ goto exit;
+ default:
+ LOGE("Incorrect Status code, 0x%02x\n",
+ tcm_msg->status_report_code);
+ retval = _EIO;
+ goto exit;
+ }
+ }
+
/* process the retrieved packet */
if (tcm_msg->status_report_code >= REPORT_IDENTIFY)
syna_tcm_v1_dispatch_report(tcm_dev);
@@ -747,6 +784,17 @@ do_dispatch:
if (status_report_code)
*status_report_code = tcm_msg->status_report_code;
+ /* update the length for predict reading */
+ if (tcm_msg->predict_reads && do_predict) {
+ if (tcm_dev->max_rd_size < MESSAGE_HEADER_SIZE)
+ tcm_msg->predict_length = tcm_msg->payload_length;
+ else
+ tcm_msg->predict_length = MIN(tcm_msg->payload_length,
+ tcm_dev->max_rd_size - MESSAGE_HEADER_SIZE - 1);
+
+ tcm_msg->predict_length += 1; /* padding byte */
+ }
+
retval = 0;
exit:
@@ -1002,7 +1050,7 @@ int syna_tcm_v1_detect(struct tcm_dev *tcm_dev, unsigned char *data,
return _EINVAL;
}
- if ((!data) || (size < MESSAGE_HEADER_SIZE)) {
+ if ((!data) || (size != MESSAGE_HEADER_SIZE)) {
LOGE("Invalid parameters\n");
return _EINVAL;
}
@@ -1020,6 +1068,7 @@ int syna_tcm_v1_detect(struct tcm_dev *tcm_dev, unsigned char *data,
if (header->code == REPORT_IDENTIFY) {
payload_length = syna_pal_le2_to_uint(header->length);
+ tcm_msg->payload_length = payload_length;
/* retrieve the identify info packet */
retval = syna_tcm_v1_continued_read(tcm_dev,
diff --git a/tcm/synaptics_touchcom_func_base.c b/tcm/synaptics_touchcom_func_base.c
index 8e83c15..8c9d0b2 100644
--- a/tcm/synaptics_touchcom_func_base.c
+++ b/tcm/synaptics_touchcom_func_base.c
@@ -1676,3 +1676,32 @@ exit:
return retval;
}
+/**
+ * syna_tcm_enable_predict_reading()
+ *
+ * predict reading aims to retrieve all data in one transfer;
+ * while, standard reads will read 4-byte header and payload data separately
+ *
+ * @param
+ * [ in] tcm_dev: the device handle
+ * [ in] en: '1' to low power deep sleep mode; '0' to active mode
+ *
+ * @return
+ * on success, 0 or positive value; otherwise, negative value on error.
+ */
+int syna_tcm_enable_predict_reading(struct tcm_dev *tcm_dev, bool en)
+{
+ if (!tcm_dev) {
+ LOGE("Invalid tcm device handle\n");
+ return _EINVAL;
+ }
+
+ tcm_dev->msg_data.predict_reads = en;
+ tcm_dev->msg_data.predict_length = 0;
+
+ LOGI("Predicted reading is %s\n",
+ (en) ? "enabled":"disabled");
+
+ return 0;
+}
+
diff --git a/tcm/synaptics_touchcom_func_base.h b/tcm/synaptics_touchcom_func_base.h
index d0a155b..391aace 100644
--- a/tcm/synaptics_touchcom_func_base.h
+++ b/tcm/synaptics_touchcom_func_base.h
@@ -414,5 +414,20 @@ int syna_tcm_send_command(struct tcm_dev *tcm_dev,
unsigned int payload_length, unsigned char *resp_code,
struct tcm_buffer *resp, unsigned int delay_ms_resp);
+/**
+ * syna_tcm_enable_predict_reading()
+ *
+ * predict reading aims to retrieve all data in one transfer;
+ * while, standard reads will read 4-byte header and payload data separately
+ *
+ * @param
+ * [ in] tcm_dev: the device handle
+ * [ in] en: '1' to low power deep sleep mode; '0' to active mode
+ *
+ * @return
+ * on success, 0 or positive value; otherwise, negative value on error.
+ */
+int syna_tcm_enable_predict_reading(struct tcm_dev *tcm_dev, bool en);
+
#endif /* end of _SYNAPTICS_TOUCHCOM_BASE_FUNCS_H_ */
diff --git a/tcm/synaptics_touchcom_func_reflash.c b/tcm/synaptics_touchcom_func_reflash.c
index a434bac..ca7f712 100644
--- a/tcm/synaptics_touchcom_func_reflash.c
+++ b/tcm/synaptics_touchcom_func_reflash.c
@@ -222,9 +222,6 @@ int syna_tcm_compare_image_id_info(struct tcm_dev *tcm_dev,
LOGN("Image build ID is different from device fw ID\n");
result = UPDATE_FIRMWARE_CONFIG;
goto exit;
- } else {
- result = UPDATE_NONE;
- goto exit;
}
image_config_id = header->customer_config_id;