Merge "touch: Setting up of DRM notifier"

This commit is contained in:
qctecmdr
2022-09-27 21:45:21 -07:00
committed by Gerrit - the friendly Code Review server
12 changed files with 2115 additions and 5445 deletions

View File

@@ -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

View File

@@ -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 */

File diff suppressed because it is too large Load Diff

View File

@@ -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
@@ -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 <ttdrivers@paradetech.com>");
#endif /* !TTDL_KERNEL_SUBMISSION */

View File

@@ -31,8 +31,8 @@
#include <linux/err.h>
#include <linux/of_device.h>
#include <linux/slab.h>
#include "pt_regs.h"
#include <linux/pt_platform.h>
#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,8 +829,7 @@ 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)
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);
@@ -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);

View File

@@ -33,188 +33,7 @@
#include <linux/version.h>
#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;
}
@@ -334,15 +117,11 @@ skip_read_len:
* 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
******************************************************************************/
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,16 +152,6 @@ 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,
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);

File diff suppressed because it is too large Load Diff

View File

@@ -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;
}

View File

@@ -29,10 +29,6 @@
#include "pt_regs.h"
#include <linux/pt_platform.h>
#include <linux/regulator/consumer.h>
#ifdef PT_PTSBC_SUPPORT
#include <linux/init-input.h>
#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
}
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
* *pdata - pointer to core platform data
* on - flag to decide power state,PT_MT_POWER_ON/PT_MT_POWER_OFF
* *dev - pointer to Device structure
* *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;
}

View File

@@ -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 */

View File

@@ -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 <linux/device.h>
#include <linux/fb.h>
#include <linux/notifier.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#elif defined(CONFIG_FB)
#include <linux/notifier.h>
#include <linux/fb.h>
#elif defined(CONFIG_DRM)
#include <drm/drm_panel.h>
#endif
#include <asm/unaligned.h>
@@ -74,9 +79,12 @@
#include <linux/version.h>
#include <linux/pt_core.h>
#include <linux/i2c.h>
#include <linux/of_gpio.h>
#include <linux/timer.h>
#include <linux/timex.h>
#include <linux/rtc.h>
#include <linux/regulator/consumer.h>
#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
@@ -629,17 +618,13 @@ enum PIP2_FILE_ID {
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_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,
@@ -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_REPORTS 8
#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
/* 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);

View File

@@ -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;
@@ -422,14 +224,10 @@ exit:
* 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
******************************************************************************/
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);