diff options
Diffstat (limited to 'drivers/input/touchscreen/mxt1664s_sec.c')
-rw-r--r-- | drivers/input/touchscreen/mxt1664s_sec.c | 656 |
1 files changed, 592 insertions, 64 deletions
diff --git a/drivers/input/touchscreen/mxt1664s_sec.c b/drivers/input/touchscreen/mxt1664s_sec.c index 0b90a10..e83e68e 100644 --- a/drivers/input/touchscreen/mxt1664s_sec.c +++ b/drivers/input/touchscreen/mxt1664s_sec.c @@ -20,18 +20,16 @@ #include <linux/interrupt.h> #include <linux/slab.h> #include <linux/err.h> +#include <linux/delay.h> +#include <linux/uaccess.h> +#include <linux/firmware.h> +#include <linux/fs.h> #include <linux/i2c/mxt1664s.h> #include "mxt1664s_dev.h" #if TSP_SEC_SYSFS - -/* TODO: -* need to add dignostic fucntions for read reference -* and data form IC to usc T37 register -*/ - static void set_default_result(struct mxt_data_sysfs *data) { char delim = ':'; @@ -62,9 +60,445 @@ static void not_support_cmd(void *device_data) buff, strnlen(buff, sizeof(buff))); } +static bool check_xy_range(struct mxt_data *data, u16 node) +{ + u8 x_line = node / data->info.matrix_ysize; + u8 y_line = node % data->info.matrix_ysize; + return (y_line < data->y_num) ? + (x_line < data->x_num) : false; +} + +/* + Vendor specific helper functions */ +static int mxt_xy_to_node(struct mxt_data *data) +{ + struct i2c_client *client = data->client; + struct mxt_data_sysfs *sysfs_data = data->sysfs_data; + + char buff[16] = {0}; + int node; + + /* cmd_param[0][1] : [x][y] */ + if (sysfs_data->cmd_param[0] < 0 || + sysfs_data->cmd_param[0] >= data->x_num || + sysfs_data->cmd_param[1] < 0 || + sysfs_data->cmd_param[1] >= data->y_num) { + snprintf(buff, sizeof(buff) , "%s", "NG"); + set_cmd_result(sysfs_data, buff, strnlen(buff, sizeof(buff))); + sysfs_data->cmd_state = CMD_STATUS_FAIL; + + dev_info(&client->dev, "%s: parameter error: %u,%u\n", + __func__, sysfs_data->cmd_param[0], + sysfs_data->cmd_param[1]); + return -EINVAL; + } + + /* + * maybe need to consider orient. + * --> y number + * |(0,0) (0,1) + * |(1,0) (1,1) + * v + * x number + */ + node = sysfs_data->cmd_param[0] * data->y_num + + sysfs_data->cmd_param[1]; + + dev_info(&client->dev, "%s: node = %d\n", __func__, node); + return node; +} + +static void mxt_node_to_xy(struct mxt_data *data, u16 *x, u16 *y) +{ + struct i2c_client *client = data->client; + struct mxt_data_sysfs *sysfs_data = data->sysfs_data; + + *x = sysfs_data->delta_max_node / data->y_num; + *y = sysfs_data->delta_max_node % data->y_num; + + dev_info(&client->dev, "%s: node[%d] is X,Y=%d,%d\n", __func__, + sysfs_data->delta_max_node, *x, *y); +} + +static bool mxt_check_last_line(struct mxt_data *data, u16 num) +{ +#if TSP_INFORM_CHARGER + if ((data->x_num - 1) == (num / data->y_num)) + return data->charging_mode; + else +#endif + return false; +} + +static int mxt_set_diagnostic_mode(struct mxt_data *data, u8 dbg_mode) +{ + struct i2c_client *client = data->client; + u8 cur_mode; + int ret; + + ret = mxt_write_object(data, GEN_COMMANDPROCESSOR_T6, + CMD_DIAGNOSTIC_OFFSET, dbg_mode); + + if (ret) { + dev_err(&client->dev, + "Failed change diagnositc mode to %d\n", dbg_mode); + goto out; + } + + if (dbg_mode & MXT_DIAG_MODE_MASK) { + do { + ret = mxt_read_object(data, DEBUG_DIAGNOSTIC_T37, + MXT_DIAGNOSTIC_MODE, &cur_mode); + if (ret) { + dev_err(&client->dev, "Failed getting diagnositc mode\n"); + goto out; + } + msleep(20); + + } while (cur_mode != dbg_mode); + dev_dbg(&client->dev, + "current dianostic chip mode is %d\n", cur_mode); + } +out: + return ret; +} + +#if 0 +static int mxt_read_diagnostic_data(struct mxt_data *data, + u8 dbg_mode, u16 node, u16 *dbg_data) +{ + struct i2c_client *client = data->client; + struct mxt_object *dbg_object; + u8 read_page, read_point; + u8 cur_page, cnt_page; + u8 data_buf[DATA_PER_NODE] = { 0 }; + int ret = 0; + + /* calculate the read page and point */ + read_page = node / NODE_PER_PAGE; + node %= NODE_PER_PAGE; + read_point = (node * DATA_PER_NODE) + 2; + + /* to make the Page Num to 0 */ + ret = mxt_set_diagnostic_mode(data, MXT_DIAG_CTE_MODE); + if (ret) + goto out; + + /* change the debug mode */ + ret = mxt_set_diagnostic_mode(data, dbg_mode); + if (ret) + goto out; + + /* get object info for diagnostic */ + dbg_object = mxt_get_object_info(data, DEBUG_DIAGNOSTIC_T37); + if (!dbg_object) { + dev_err(&client->dev, "fail to get object_info\n"); + ret = -EINVAL; + goto out; + } + + /* move to the proper page */ + for (cnt_page = 1; cnt_page <= read_page; cnt_page++) { + ret = mxt_set_diagnostic_mode(data, MXT_DIAG_PAGE_UP); + if (ret) + goto out; + do { + msleep(20); + ret = mxt_read_mem(data, + dbg_object->start_address + MXT_DIAGNOSTIC_PAGE, + 1, &cur_page); + if (ret) { + dev_err(&client->dev, + "%s Read fail page\n", __func__); + goto out; + } + } while (cur_page != cnt_page); + } + + /* read the dbg data */ + ret = mxt_read_mem(data, dbg_object->start_address + read_point, + DATA_PER_NODE, data_buf); + if (ret) + goto out; + + *dbg_data = ((u16)data_buf[1] << 8) + (u16)data_buf[0]; + + dev_info(&client->dev, "dbg_mode[%d]: dbg data[%d] = %d\n", + dbg_mode, (read_page * NODE_PER_PAGE) + node, + dbg_mode == MXT_DIAG_DELTA_MODE ? (s16)(*dbg_data) : *dbg_data); +out: + return ret; +} +#endif + +static void mxt_treat_dbg_data(struct mxt_data *data, + struct mxt_object *dbg_object, u8 dbg_mode, u8 read_point, u16 num) +{ + struct i2c_client *client = data->client; + struct mxt_data_sysfs *sysfs_data = data->sysfs_data; + u8 data_buffer[DATA_PER_NODE] = { 0 }; + + if (dbg_mode == MXT_DIAG_DELTA_MODE) { + /* read delta data */ + mxt_read_mem(data, dbg_object->start_address + read_point, + DATA_PER_NODE, data_buffer); + + sysfs_data->delta[num] = + ((u16)data_buffer[1] << 8) + (u16)data_buffer[0]; + + dev_dbg(&client->dev, "delta[%d] = %d\n", + num, sysfs_data->delta[num]); + + if (abs(sysfs_data->delta[num]) + > abs(sysfs_data->delta_max_data)) { + sysfs_data->delta_max_node = num; + sysfs_data->delta_max_data = sysfs_data->delta[num]; + } + } else if (dbg_mode == MXT_DIAG_REFERENCE_MODE) { + /* read reference data */ + mxt_read_mem(data, dbg_object->start_address + read_point, + DATA_PER_NODE, data_buffer); + + sysfs_data->reference[num] = + ((u16)data_buffer[1] << 8) + (u16)data_buffer[0] + - REF_OFFSET_VALUE; + + if (mxt_check_last_line(data, num)) + sysfs_data->reference[num] *= 2; + + /* check that reference is in spec or not */ + if (sysfs_data->reference[num] < REF_MIN_VALUE + || sysfs_data->reference[num] > REF_MAX_VALUE) { + dev_err(&client->dev, "reference[%d] is out of range =" + " %d(%d,%d)\n", num, sysfs_data->reference[num], + num / data->y_num, num % data->y_num); + } + + if (sysfs_data->reference[num] > sysfs_data->ref_max_data) + sysfs_data->ref_max_data = + sysfs_data->reference[num]; + if (sysfs_data->reference[num] < sysfs_data->ref_min_data) + sysfs_data->ref_min_data = + sysfs_data->reference[num]; + + dev_dbg(&client->dev, "reference[%d] = %d\n", + num, sysfs_data->reference[num]); + } +} + +static int mxt_read_all_diagnostic_data(struct mxt_data *data, u8 dbg_mode) +{ + struct i2c_client *client = data->client; + struct mxt_data_sysfs *sysfs_data = data->sysfs_data; + struct mxt_object *dbg_object; + u8 read_page, cur_page, end_page, read_point; + u16 node = 0, num = 0, cnt = 0; + int ret = 0; + + /* to make the Page Num to 0 */ + ret = mxt_set_diagnostic_mode(data, MXT_DIAG_CTE_MODE); + if (ret) + goto out; + + /* change the debug mode */ + ret = mxt_set_diagnostic_mode(data, dbg_mode); + if (ret) + goto out; + + /* get object info for diagnostic */ + dbg_object = mxt_get_object_info(data, DEBUG_DIAGNOSTIC_T37); + if (!dbg_object) { + dev_err(&client->dev, "fail to get object_info\n"); + ret = -EINVAL; + goto out; + } + + /* calculate end page of IC */ + sysfs_data->ref_min_data = REF_MAX_VALUE; + sysfs_data->ref_max_data = REF_MIN_VALUE; + sysfs_data->delta_max_data = 0; + sysfs_data->delta_max_node = 0; + end_page = (data->info.matrix_xsize * data->info.matrix_ysize) + / NODE_PER_PAGE; + + /* read the dbg data */ + for (read_page = 0 ; read_page < end_page; read_page++) { + for (node = 0; node < NODE_PER_PAGE; node++) { + read_point = (node * DATA_PER_NODE) + 2; + + if (check_xy_range(data, cnt)) { + mxt_treat_dbg_data(data, dbg_object, dbg_mode, + read_point, num); + num++; + } + cnt++; + } + ret = mxt_set_diagnostic_mode(data, MXT_DIAG_PAGE_UP); + if (ret) + goto out; + do { + msleep(20); + ret = mxt_read_mem(data, + dbg_object->start_address + MXT_DIAGNOSTIC_PAGE, + 1, &cur_page); + if (ret) { + dev_err(&client->dev, + "%s Read fail page\n", __func__); + goto out; + } + } while (cur_page != read_page + 1); + } + + if (dbg_mode == MXT_DIAG_REFERENCE_MODE) { + dev_info(&client->dev, "min/max reference is [%d/%d]\n", + sysfs_data->ref_min_data, sysfs_data->ref_max_data); + } else if (dbg_mode == MXT_DIAG_DELTA_MODE) { + dev_info(&client->dev, "max delta node %d=[%d]\n", + sysfs_data->delta_max_node, sysfs_data->delta_max_data); + } +out: + return ret; +} + +/* +* find the x,y position to use maximum delta. +* it is diffult to map the orientation and caculate the node number +* because layout is always different according to device +*/ +static void find_delta_node(void *device_data) +{ + struct mxt_data *data = (struct mxt_data *)device_data; + struct mxt_data_sysfs *sysfs_data = data->sysfs_data; + char buff[16] = {0}; + u16 x, y; + int ret; + + set_default_result(sysfs_data); + + /* read all delta to get the maximum delta value */ + ret = mxt_read_all_diagnostic_data(data, + MXT_DIAG_DELTA_MODE); + if (ret) { + sysfs_data->cmd_state = CMD_STATUS_FAIL; + } else { + mxt_node_to_xy(data, &x, &y); + snprintf(buff, sizeof(buff), "%d,%d", x, y); + set_cmd_result(sysfs_data, buff, strnlen(buff, sizeof(buff))); + + sysfs_data->cmd_state = CMD_STATUS_OK; + } +} + +/* - Vendor specific helper functions */ + +/* + function realted samsung factory test */ static void fw_update(void *device_data) { - /* .... */ + struct mxt_data *data = (struct mxt_data *)device_data; + struct i2c_client *client = data->client; + struct mxt_data_sysfs *sysfs_data = data->sysfs_data; + struct file *filp = NULL; + const struct firmware *fw = NULL; + const u8 *fw_data = NULL; + long fw_size = 0; + mm_segment_t old_fs = {0}; + char *fw_path; + int ret; + + set_default_result(sysfs_data); + + fw_path = kzalloc(MXT_MAX_FW_PATH, GFP_KERNEL); + if (fw_path == NULL) { + dev_err(&client->dev, "failed to allocate firmware path.\n"); + goto out; + } + + switch (sysfs_data->cmd_param[0]) { + case MXT_FW_FROM_UMS: + snprintf(fw_path, MXT_MAX_FW_PATH, "/sdcard/%s", MXT_FW_NAME); + + old_fs = get_fs(); + set_fs(get_ds()); + + filp = filp_open(fw_path, O_RDONLY, 0); + if (IS_ERR(filp)) { + dev_err(&client->dev, "could not open firmware: %s,%d\n", + fw_path, (s32)filp); + goto err_open; + } + + fw_size = filp->f_path.dentry->d_inode->i_size; + + fw_data = kzalloc((size_t)fw_size, GFP_KERNEL); + if (!fw_data) { + dev_err(&client->dev, "fail to alloc buffer for fw\n"); + goto err_alloc; + } + ret = vfs_read(filp, (char __user *)fw_data, + fw_size, &filp->f_pos); + if (ret != fw_size) { + dev_err(&client->dev, "fail to read file %s (ret = %d)\n", + fw_path, ret); + goto err_read; + } + filp_close(filp, current->files); + set_fs(old_fs); + break; + + case MXT_FW_FROM_BUILT_IN: + case MXT_FW_FROM_REQ_FW: + snprintf(fw_path, MXT_MAX_FW_PATH, "tsp_atmel/%s", MXT_FW_NAME); + + ret = request_firmware(&fw, fw_path, &client->dev); + if (ret) { + dev_err(&client->dev, + "could not request firmware %s\n", fw_path); + goto err_open; + } + + fw_size = fw->size; + fw_data = kzalloc(fw_size, GFP_KERNEL); + if (!fw_data) { + dev_err(&client->dev, "fail to alloc buffer for fw\n"); + goto err_alloc; + } + memcpy((void *)fw_data, fw->data, fw_size); + release_firmware(fw); + break; + + default: + dev_err(&client->dev, "invalid fw file type!!\n"); + goto not_support; + } + + kfree(fw_path); + disable_irq(data->client->irq); + + ret = mxt_flash_fw_from_sysfs(data, fw_data, fw_size); + + enable_irq(data->client->irq); + kfree(fw_data); + + if (ret) + sysfs_data->cmd_state = CMD_STATUS_FAIL; + else + sysfs_data->cmd_state = CMD_STATUS_OK; + + return; + +err_read: + kfree(fw_data); +err_alloc: + if (!filp) + filp_close(filp, current->files); + release_firmware(fw); +err_open: + if (!filp) + set_fs(old_fs); +not_support: + kfree(fw_path); +out: + sysfs_data->cmd_state = CMD_STATUS_FAIL; + return; } static void get_fw_ver_bin(void *device_data) @@ -76,8 +510,7 @@ static void get_fw_ver_bin(void *device_data) char buff[40] = {0}; set_default_result(sysfs_data); - snprintf(buff, sizeof(buff), "version: %#02x build: %#02x", - MXT_FIRM_VERSION, MXT_FIRM_BUILD); + snprintf(buff, sizeof(buff), "%02x", MXT_FIRM_VERSION); set_cmd_result(sysfs_data, buff, strnlen(buff, sizeof(buff))); sysfs_data->cmd_state = CMD_STATUS_OK; @@ -92,13 +525,10 @@ static void get_fw_ver_ic(void *device_data) struct mxt_data_sysfs *sysfs_data = data->sysfs_data; char buff[40] = {0}; - int ver, build; + int ver = data->info.version; set_default_result(sysfs_data); - - ver = data->info.version; - build = data->info.build; - snprintf(buff, sizeof(buff), "version: %#02x build: %#02x", ver, build); + snprintf(buff, sizeof(buff), "%02x", ver); set_cmd_result(sysfs_data, buff, strnlen(buff, sizeof(buff))); sysfs_data->cmd_state = CMD_STATUS_OK; @@ -108,7 +538,18 @@ static void get_fw_ver_ic(void *device_data) static void get_config_ver(void *device_data) { - not_support_cmd(device_data); + struct mxt_data *data = (struct mxt_data *)device_data; + struct i2c_client *client = data->client; + struct mxt_data_sysfs *sysfs_data = data->sysfs_data; + char buff[40] = {0}; + + set_default_result(sysfs_data); + snprintf(buff, sizeof(buff), "%s", data->config_version); + + set_cmd_result(sysfs_data, buff, strnlen(buff, sizeof(buff))); + sysfs_data->cmd_state = CMD_STATUS_OK; + dev_info(&client->dev, "%s: %s(%d)\n", __func__, + buff, strnlen(buff, sizeof(buff))); } static void get_threshold(void *device_data) @@ -122,9 +563,8 @@ static void get_threshold(void *device_data) set_default_result(sysfs_data); - threshold = mxt_read_object(data, + mxt_read_object(data, TOUCH_MULTITOUCHSCREEN_T9, 7, &threshold); - if (threshold < 0) { snprintf(buff, sizeof(buff), "%s", "NG"); set_cmd_result(sysfs_data, buff, strnlen(buff, sizeof(buff))); @@ -149,16 +589,17 @@ static void module_off_master(void *device_data) mutex_lock(&data->lock); if (data->mxt_enabled) { + disable_irq(client->irq); + if (data->pdata->power_off()) snprintf(buff, sizeof(buff), "%s", "NG"); else snprintf(buff, sizeof(buff), "%s", "OK"); - disable_irq(client->irq); data->mxt_enabled = false; - } else + } else { snprintf(buff, sizeof(buff), "%s", "OK"); - + } mutex_unlock(&data->lock); set_default_result(sysfs_data); @@ -219,7 +660,7 @@ static void get_chip_vendor(void *device_data) snprintf(buff, sizeof(buff), "%s", "ATMEL"); set_cmd_result(sysfs_data, buff, strnlen(buff, sizeof(buff))); sysfs_data->cmd_state = CMD_STATUS_OK; - dev_info(&client->dev, "%s: %s(%d)\n", __func__, + dev_dbg(&client->dev, "%s: %s(%d)\n", __func__, buff, strnlen(buff, sizeof(buff))); } @@ -236,7 +677,7 @@ static void get_chip_name(void *device_data) snprintf(buff, sizeof(buff), "%s", "MXT1664S"); set_cmd_result(sysfs_data, buff, strnlen(buff, sizeof(buff))); sysfs_data->cmd_state = CMD_STATUS_OK; - dev_info(&client->dev, "%s: %s(%d)\n", __func__, + dev_dbg(&client->dev, "%s: %s(%d)\n", __func__, buff, strnlen(buff, sizeof(buff))); } @@ -247,16 +688,16 @@ static void get_x_num(void *device_data) struct mxt_data_sysfs *sysfs_data = data->sysfs_data; char buff[16] = {0}; - int val; + u8 val = 0; set_default_result(sysfs_data); - val = data->info.matrix_xsize; + val = data->x_num; if (val < 0) { snprintf(buff, sizeof(buff), "%s", "NG"); set_cmd_result(sysfs_data, buff, strnlen(buff, sizeof(buff))); sysfs_data->cmd_state = CMD_STATUS_FAIL; - dev_info(&client->dev, + dev_err(&client->dev, "%s: fail to read num of x (%d).\n", __func__, val); return; @@ -265,7 +706,7 @@ static void get_x_num(void *device_data) set_cmd_result(sysfs_data, buff, strnlen(buff, sizeof(buff))); sysfs_data->cmd_state = CMD_STATUS_OK; - dev_info(&client->dev, "%s: %s(%d)\n", __func__, buff, + dev_dbg(&client->dev, "%s: %s(%d)\n", __func__, buff, strnlen(buff, sizeof(buff))); } @@ -276,16 +717,16 @@ static void get_y_num(void *device_data) struct mxt_data_sysfs *sysfs_data = data->sysfs_data; char buff[16] = {0}; - int val; + u8 val; set_default_result(sysfs_data); - val = data->info.matrix_ysize; + val = data->y_num; if (val < 0) { snprintf(buff, sizeof(buff), "%s", "NG"); set_cmd_result(sysfs_data, buff, strnlen(buff, sizeof(buff))); sysfs_data->cmd_state = CMD_STATUS_FAIL; - dev_info(&client->dev, + dev_err(&client->dev, "%s: fail to read num of y (%d).\n", __func__, val); return; @@ -294,7 +735,7 @@ static void get_y_num(void *device_data) set_cmd_result(sysfs_data, buff, strnlen(buff, sizeof(buff))); sysfs_data->cmd_state = CMD_STATUS_OK; - dev_info(&client->dev, "%s: %s(%d)\n", __func__, buff, + dev_dbg(&client->dev, "%s: %s(%d)\n", __func__, buff, strnlen(buff, sizeof(buff))); } @@ -302,43 +743,94 @@ static void run_reference_read(void *device_data) { struct mxt_data *data = (struct mxt_data *)device_data; struct mxt_data_sysfs *sysfs_data = data->sysfs_data; + int ret; + char buff[16] = {0}; set_default_result(sysfs_data); - sysfs_data->cmd_state = CMD_STATUS_OK; + ret = mxt_read_all_diagnostic_data(data, + MXT_DIAG_REFERENCE_MODE); + if (ret) + sysfs_data->cmd_state = CMD_STATUS_FAIL; + else { + snprintf(buff, sizeof(buff), "%d,%d", + sysfs_data->ref_min_data, sysfs_data->ref_max_data); + set_cmd_result(sysfs_data, buff, strnlen(buff, sizeof(buff))); + + sysfs_data->cmd_state = CMD_STATUS_OK; + } } static void get_reference(void *device_data) { struct mxt_data *data = (struct mxt_data *)device_data; + struct i2c_client *client = data->client; struct mxt_data_sysfs *sysfs_data = data->sysfs_data; + char buff[16] = {0}; + int node; set_default_result(sysfs_data); /* add read function */ - sysfs_data->cmd_state = CMD_STATUS_OK; + node = mxt_xy_to_node(data); + if (node < 0) { + sysfs_data->cmd_state = CMD_STATUS_FAIL; + return; + } else { + snprintf(buff, sizeof(buff), "%u", + sysfs_data->reference[node]); + set_cmd_result(sysfs_data, + buff, strnlen(buff, sizeof(buff))); + + sysfs_data->cmd_state = CMD_STATUS_OK; + } + dev_info(&client->dev, "%s: %s(%d)\n", __func__, buff, + strnlen(buff, sizeof(buff))); } static void run_delta_read(void *device_data) { struct mxt_data *data = (struct mxt_data *)device_data; struct mxt_data_sysfs *sysfs_data = data->sysfs_data; + int ret; set_default_result(sysfs_data); - /* add read function */ - sysfs_data->cmd_state = CMD_STATUS_OK; + ret = mxt_read_all_diagnostic_data(data, + MXT_DIAG_DELTA_MODE); + if (ret) + sysfs_data->cmd_state = CMD_STATUS_FAIL; + else + sysfs_data->cmd_state = CMD_STATUS_OK; } static void get_delta(void *device_data) { struct mxt_data *data = (struct mxt_data *)device_data; + struct i2c_client *client = data->client; struct mxt_data_sysfs *sysfs_data = data->sysfs_data; + char buff[16] = {0}; + int node; set_default_result(sysfs_data); /* add read function */ - sysfs_data->cmd_state = CMD_STATUS_OK; + + node = mxt_xy_to_node(data); + if (node < 0) { + sysfs_data->cmd_state = CMD_STATUS_FAIL; + return; + } else { + snprintf(buff, sizeof(buff), "%d", + sysfs_data->delta[node]); + set_cmd_result(sysfs_data, + buff, strnlen(buff, sizeof(buff))); + + sysfs_data->cmd_state = CMD_STATUS_OK; + } + dev_info(&client->dev, "%s: %s(%d)\n", __func__, buff, + strnlen(buff, sizeof(buff))); } +/* - function realted samsung factory test */ #define TSP_CMD(name, func) .cmd_name = name, .cmd_func = func #define TOSTRING (x) #x @@ -367,6 +859,7 @@ struct tsp_cmd tsp_cmds[] = { {TSP_CMD("get_reference", get_reference),}, {TSP_CMD("run_delta_read", run_delta_read),}, {TSP_CMD("get_delta", get_delta),}, + {TSP_CMD("find_delta", find_delta_node),}, {TSP_CMD("not_support_cmd", not_support_cmd),}, }; @@ -469,7 +962,7 @@ static ssize_t show_cmd_status(struct device *dev, char buff[16] = {0}; - dev_info(&data->client->dev, "tsp cmd: status:%d\n", + dev_dbg(&data->client->dev, "tsp cmd: status:%d\n", sysfs_data->cmd_state); if (sysfs_data->cmd_state == CMD_STATUS_WAITING) @@ -508,14 +1001,31 @@ static ssize_t show_cmd_result(struct device *dev, struct device_attribute return snprintf(buf, TSP_BUF_SIZE, "%s\n", sysfs_data->cmd_result); } +static ssize_t show_cmd_list(struct device *dev, struct device_attribute + *devattr, char *buf) +{ + struct mxt_data *data = dev_get_drvdata(dev); + struct mxt_data_sysfs *sysfs_data = data->sysfs_data; + struct tsp_cmd *tsp_cmd_ptr = NULL; + int cnt = 0; + + list_for_each_entry(tsp_cmd_ptr, &sysfs_data->cmd_list_head, list) + cnt += sprintf(buf + cnt, + "%s\n", tsp_cmd_ptr->cmd_name); + + return cnt; +} + static DEVICE_ATTR(cmd, S_IWUSR | S_IWGRP, NULL, store_cmd); static DEVICE_ATTR(cmd_status, S_IRUGO, show_cmd_status, NULL); static DEVICE_ATTR(cmd_result, S_IRUGO, show_cmd_result, NULL); +static DEVICE_ATTR(cmd_list, S_IRUGO, show_cmd_list, NULL); static struct attribute *touchscreen_attributes[] = { &dev_attr_cmd.attr, &dev_attr_cmd_status.attr, &dev_attr_cmd_result.attr, + &dev_attr_cmd_list.attr, NULL, }; @@ -767,7 +1277,13 @@ static ssize_t mxt_debug_setting(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - return 0; + struct mxt_data *data = dev_get_drvdata(dev); + u32 mode = 0; + + if (sscanf(buf, "%u", &mode) == 1) + data->debug_log = !!mode; + + return count; } static ssize_t mxt_object_setting(struct device *dev, @@ -825,9 +1341,9 @@ static ssize_t mxt_object_show(struct device *dev, dev_info(&client->dev, "object type T%d\n", object_type); object = mxt_get_object_info(data, object_type); - if (object == NULL) { + if (!object) { dev_err(&client->dev, "fail to get object_info\n"); - goto out; + return -EINVAL; } else { for (i = 0; i < object->size; i++) { mxt_read_mem(data, object->start_address + i, @@ -835,7 +1351,7 @@ static ssize_t mxt_object_show(struct device *dev, dev_info(&client->dev, "Byte %u --> %u\n", i, val); } } -out: + return count; } @@ -905,7 +1421,7 @@ int __devinit mxt_sysfs_init(struct i2c_client *client) data->sysfs_data = sysfs_data; fac_dev_ts = device_create(sec_class, - NULL, 0, data, "sec_touchscreen"); + NULL, 0, data, "tsp"); if (IS_ERR(fac_dev_ts)) { dev_err(&client->dev, "Failed to create device for the sysfs\n"); ret = IS_ERR(fac_dev_ts); @@ -948,44 +1464,56 @@ free_mem: return ret; } -/* TODO: it will be applied */ #if TSP_BOOSTER static void mxt_set_dvfs_off(struct work_struct *work) { struct mxt_data *data = - container_of(work, struct mxt_data, booster.dvfs_dwork.work); - - if (data->mxt_enabled) { - disable_irq(client->irq); - - dev_info(&data->client->dev, "%s!!!\n", __func__); + container_of(work, struct mxt_data, + booster.dvfs_dwork.work); + + if (data->booster.touch_cpu_lock_status) + dev_lock(data->booster.bus_dev, + data->booster.dev, SEC_BUS_LOCK_FREQ); + else { + dev_unlock(data->booster.bus_dev, data->booster.dev); + exynos_cpufreq_lock_free(DVFS_LOCK_ID_TSP); + } +} +void mxt_set_dvfs_on(struct mxt_data *data, bool en) +{ + if (0 == data->booster.cpu_lv) + exynos_cpufreq_get_level(SEC_DVFS_LOCK_FREQ, + &data->booster.cpu_lv); + + if (en) { + if (!data->booster.touch_cpu_lock_status) { + cancel_delayed_work(&data->booster.dvfs_dwork); + dev_lock(data->booster.bus_dev, + data->booster.dev, SEC_BUS_LOCK_FREQ2); + exynos_cpufreq_lock(DVFS_LOCK_ID_TSP, + data->booster.cpu_lv); + data->booster.touch_cpu_lock_status = true; + schedule_delayed_work(&data->booster.dvfs_dwork, + msecs_to_jiffies(SEC_DVFS_LOCK_TIMEOUT)); + } + } else { if (data->booster.touch_cpu_lock_status) { - exynos_cpufreq_lock_free(DVFS_LOCK_ID_TSP); + schedule_delayed_work(&data->booster.dvfs_dwork, + msecs_to_jiffies(SEC_DVFS_LOCK_TIMEOUT)); data->booster.touch_cpu_lock_status = false; } - enable_irq(client->irq); } } -static void mxt_set_dvfs_on(struct mxt_data *data) -{ - dev_info(&data->client->dev, "%s!!!\n", __func__); - - cancel_delayed_work(&data->booster.dvfs_dwork); - exynos_cpufreq_lock(DVFS_LOCK_ID_TSP, - data->booster.cpu_lv); - data->booster.touch_cpu_lock_status = true; -} - -static int mxt_init_dvfs(struct mxt_data *data) +int mxt_init_dvfs(struct mxt_data *data) { - int ret; - INIT_DELAYED_WORK(&data->booster.dvfs_dwork, mxt_set_dvfs_off); - return exynos_cpufreq_get_level(TOUCH_BOOSTER_LIMIT_CLK, + data->booster.bus_dev = dev_get("exynos-busfreq"); + exynos_cpufreq_get_level(SEC_DVFS_LOCK_FREQ, &data->booster.cpu_lv); + return 0; } #endif /* - TOUCH_BOOSTER */ |