| /* | |
| * | |
| * FocalTech TouchScreen driver. | |
| * | |
| * Copyright (c) 2010-2016, Focaltech Ltd. All rights reserved. | |
| * | |
| * This software is licensed under the terms of the GNU General Public | |
| * License version 2, as published by the Free Software Foundation, and | |
| * may be copied, distributed, and modified under those terms. | |
| * | |
| * This program is distributed in the hope that it will be useful, | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| * GNU General Public License for more details. | |
| * | |
| */ | |
| /***************************************************************************** | |
| * | |
| * File Name: focaltech_gestrue.c | |
| * | |
| * Author: Focaltech Driver Team | |
| * | |
| * Created: 2016-08-08 | |
| * | |
| * Abstract: | |
| * | |
| * Reference: | |
| * | |
| *****************************************************************************/ | |
| /***************************************************************************** | |
| * 1.Included header files | |
| *****************************************************************************/ | |
| #include "focaltech_core.h" | |
| #if FTS_GESTURE_EN | |
| /****************************************************************************** | |
| * Private constant and macro definitions using #define | |
| *****************************************************************************/ | |
| #define KEY_GESTURE_U KEY_U | |
| #define KEY_GESTURE_UP KEY_UP | |
| #define KEY_GESTURE_DOWN KEY_DOWN | |
| #define KEY_GESTURE_LEFT KEY_LEFT | |
| #define KEY_GESTURE_RIGHT KEY_RIGHT | |
| #define KEY_GESTURE_O KEY_O | |
| #define KEY_GESTURE_E KEY_E | |
| #define KEY_GESTURE_M KEY_M | |
| #define KEY_GESTURE_L KEY_L | |
| #define KEY_GESTURE_W KEY_W | |
| #define KEY_GESTURE_S KEY_S | |
| #define KEY_GESTURE_V KEY_V | |
| #define KEY_GESTURE_C KEY_C | |
| #define KEY_GESTURE_Z KEY_Z | |
| #define GESTURE_LEFT 0x20 | |
| #define GESTURE_RIGHT 0x21 | |
| #define GESTURE_UP 0x22 | |
| #define GESTURE_DOWN 0x23 | |
| #define GESTURE_DOUBLECLICK 0x24 | |
| #define GESTURE_O 0x30 | |
| #define GESTURE_W 0x31 | |
| #define GESTURE_M 0x32 | |
| #define GESTURE_E 0x33 | |
| #define GESTURE_L 0x44 | |
| #define GESTURE_S 0x46 | |
| #define GESTURE_V 0x54 | |
| #define GESTURE_Z 0x41 | |
| #define GESTURE_C 0x34 | |
| #define FTS_GESTRUE_POINTS 255 | |
| #define FTS_GESTRUE_POINTS_HEADER 8 | |
| #define FTS_GESTURE_OUTPUT_ADRESS 0xD3 | |
| /***************************************************************************** | |
| * Private enumerations, structures and unions using typedef | |
| *****************************************************************************/ | |
| struct fts_gesture_st { | |
| u8 header[FTS_GESTRUE_POINTS_HEADER]; | |
| u16 coordinate_x[FTS_GESTRUE_POINTS]; | |
| u16 coordinate_y[FTS_GESTRUE_POINTS]; | |
| u8 mode; | |
| u8 active; | |
| }; | |
| /***************************************************************************** | |
| * Static variables | |
| *****************************************************************************/ | |
| static struct fts_gesture_st fts_gesture_data; | |
| extern struct fts_ts_data *fts_wq_data; | |
| /***************************************************************************** | |
| * Global variable or extern global variabls/functions | |
| *****************************************************************************/ | |
| /***************************************************************************** | |
| * Static function prototypes | |
| *****************************************************************************/ | |
| static ssize_t fts_gesture_show(struct device *dev, | |
| struct device_attribute *attr, char *buf); | |
| static ssize_t fts_gesture_store(struct device *dev, | |
| struct device_attribute *attr, const char *buf, | |
| size_t count); | |
| static ssize_t fts_gesture_buf_show(struct device *dev, | |
| struct device_attribute *attr, char *buf); | |
| static ssize_t fts_gesture_buf_store(struct device *dev, | |
| struct device_attribute *attr, | |
| const char *buf, size_t count); | |
| /* sysfs gesture node | |
| * read example: cat fts_gesture_mode ---read gesture mode | |
| * write example:echo 01 > fts_gesture_mode ---write gesture mode to 01 | |
| * | |
| */ | |
| static DEVICE_ATTR(fts_gesture_mode, S_IRUGO | S_IWUSR, fts_gesture_show, | |
| fts_gesture_store); | |
| /* | |
| * read example: cat fts_gesture_buf ---read gesture buf | |
| */ | |
| static DEVICE_ATTR(fts_gesture_buf, S_IRUGO | S_IWUSR, fts_gesture_buf_show, | |
| fts_gesture_buf_store); | |
| static struct attribute *fts_gesture_mode_attrs[] = { | |
| &dev_attr_fts_gesture_mode.attr, | |
| &dev_attr_fts_gesture_buf.attr, | |
| NULL, | |
| }; | |
| static struct attribute_group fts_gesture_group = { | |
| .attrs = fts_gesture_mode_attrs, | |
| }; | |
| /************************************************************************ | |
| * Name: fts_gesture_show | |
| * Brief: no | |
| * Input: device, device attribute, char buf | |
| * Output: no | |
| * Return: | |
| ***********************************************************************/ | |
| static ssize_t fts_gesture_show(struct device *dev, | |
| struct device_attribute *attr, char *buf) | |
| { | |
| int count; | |
| u8 val; | |
| struct i2c_client *client = container_of(dev, struct i2c_client, dev); | |
| mutex_lock(&fts_input_dev->mutex); | |
| fts_i2c_read_reg(client, FTS_REG_GESTURE_EN, &val); | |
| count = | |
| sprintf(buf, "Gesture Mode: %s\n", | |
| fts_gesture_data.mode ? "On" : "Off"); | |
| count += sprintf(buf + count, "Reg(0xD0) = %d\n", val); | |
| mutex_unlock(&fts_input_dev->mutex); | |
| return count; | |
| } | |
| /************************************************************************ | |
| * Name: fts_gesture_store | |
| * Brief: no | |
| * Input: device, device attribute, char buf, char count | |
| * Output: no | |
| * Return: | |
| ***********************************************************************/ | |
| static ssize_t fts_gesture_store(struct device *dev, | |
| struct device_attribute *attr, const char *buf, | |
| size_t count) | |
| { | |
| mutex_lock(&fts_input_dev->mutex); | |
| if (FTS_SYSFS_ECHO_ON(buf)) { | |
| FTS_INFO("[GESTURE]enable gesture"); | |
| fts_gesture_data.mode = ENABLE; | |
| } else if (FTS_SYSFS_ECHO_OFF(buf)) { | |
| FTS_INFO("[GESTURE]disable gesture"); | |
| fts_gesture_data.mode = DISABLE; | |
| } | |
| mutex_unlock(&fts_input_dev->mutex); | |
| return count; | |
| } | |
| /************************************************************************ | |
| * Name: fts_gesture_buf_show | |
| * Brief: no | |
| * Input: device, device attribute, char buf | |
| * Output: no | |
| * Return: | |
| ***********************************************************************/ | |
| static ssize_t fts_gesture_buf_show(struct device *dev, | |
| struct device_attribute *attr, char *buf) | |
| { | |
| int count; | |
| int i = 0; | |
| mutex_lock(&fts_input_dev->mutex); | |
| count = | |
| snprintf(buf, PAGE_SIZE, "Gesture ID: 0x%x\n", | |
| fts_gesture_data.header[0]); | |
| count += | |
| snprintf(buf + count, PAGE_SIZE, "Gesture PointNum: %d\n", | |
| fts_gesture_data.header[1]); | |
| count += snprintf(buf + count, PAGE_SIZE, "Gesture Point Buf:\n"); | |
| for (i = 0; i < fts_gesture_data.header[1]; i++) { | |
| count += | |
| snprintf(buf + count, PAGE_SIZE, "%3d(%4d,%4d) ", i, | |
| fts_gesture_data.coordinate_x[i], | |
| fts_gesture_data.coordinate_y[i]); | |
| if ((i + 1) % 4 == 0) | |
| count += snprintf(buf + count, PAGE_SIZE, "\n"); | |
| } | |
| count += snprintf(buf + count, PAGE_SIZE, "\n"); | |
| mutex_unlock(&fts_input_dev->mutex); | |
| return count; | |
| } | |
| /************************************************************************ | |
| * Name: fts_gesture_buf_store | |
| * Brief: no | |
| * Input: device, device attribute, char buf, char count | |
| * Output: no | |
| * Return: | |
| ***********************************************************************/ | |
| static ssize_t fts_gesture_buf_store(struct device *dev, | |
| struct device_attribute *attr, | |
| const char *buf, size_t count) | |
| { | |
| /* place holder for future use */ | |
| return -EPERM; | |
| } | |
| /***************************************************************************** | |
| * Name: fts_create_gesture_sysfs | |
| * Brief: | |
| * Input: | |
| * Output: None | |
| * Return: 0-success or error | |
| *****************************************************************************/ | |
| int fts_create_gesture_sysfs(struct i2c_client *client) | |
| { | |
| int ret = 0; | |
| ret = sysfs_create_group(&client->dev.kobj, &fts_gesture_group); | |
| if (ret != 0) { | |
| FTS_ERROR | |
| ("[GESTURE]fts_gesture_mode_group(sysfs) create failed!"); | |
| sysfs_remove_group(&client->dev.kobj, &fts_gesture_group); | |
| return ret; | |
| } | |
| return 0; | |
| } | |
| /***************************************************************************** | |
| * Name: fts_gesture_recovery | |
| * Brief: recovery gesture state when reset | |
| * Input: | |
| * Output: None | |
| * Return: | |
| *****************************************************************************/ | |
| void fts_gesture_recovery(struct i2c_client *client) | |
| { | |
| if (fts_gesture_data.mode && fts_gesture_data.active) { | |
| fts_i2c_write_reg(client, 0xD1, 0xff); | |
| fts_i2c_write_reg(client, 0xD2, 0xff); | |
| fts_i2c_write_reg(client, 0xD5, 0xff); | |
| fts_i2c_write_reg(client, 0xD6, 0xff); | |
| fts_i2c_write_reg(client, 0xD7, 0xff); | |
| fts_i2c_write_reg(client, 0xD8, 0xff); | |
| fts_i2c_write_reg(client, FTS_REG_GESTURE_EN, ENABLE); | |
| } | |
| } | |
| /***************************************************************************** | |
| * Name: fts_gesture_init | |
| * Brief: | |
| * Input: | |
| * Output: None | |
| * Return: None | |
| *****************************************************************************/ | |
| int fts_gesture_init(struct input_dev *input_dev, struct i2c_client *client) | |
| { | |
| FTS_FUNC_ENTER(); | |
| input_set_capability(input_dev, EV_KEY, KEY_POWER); | |
| input_set_capability(input_dev, EV_KEY, KEY_GESTURE_U); | |
| input_set_capability(input_dev, EV_KEY, KEY_GESTURE_UP); | |
| input_set_capability(input_dev, EV_KEY, KEY_GESTURE_DOWN); | |
| input_set_capability(input_dev, EV_KEY, KEY_GESTURE_LEFT); | |
| input_set_capability(input_dev, EV_KEY, KEY_GESTURE_RIGHT); | |
| input_set_capability(input_dev, EV_KEY, KEY_GESTURE_O); | |
| input_set_capability(input_dev, EV_KEY, KEY_GESTURE_E); | |
| input_set_capability(input_dev, EV_KEY, KEY_GESTURE_M); | |
| input_set_capability(input_dev, EV_KEY, KEY_GESTURE_L); | |
| input_set_capability(input_dev, EV_KEY, KEY_GESTURE_W); | |
| input_set_capability(input_dev, EV_KEY, KEY_GESTURE_S); | |
| input_set_capability(input_dev, EV_KEY, KEY_GESTURE_V); | |
| input_set_capability(input_dev, EV_KEY, KEY_GESTURE_Z); | |
| input_set_capability(input_dev, EV_KEY, KEY_GESTURE_C); | |
| __set_bit(KEY_GESTURE_RIGHT, input_dev->keybit); | |
| __set_bit(KEY_GESTURE_LEFT, input_dev->keybit); | |
| __set_bit(KEY_GESTURE_UP, input_dev->keybit); | |
| __set_bit(KEY_GESTURE_DOWN, input_dev->keybit); | |
| __set_bit(KEY_GESTURE_U, input_dev->keybit); | |
| __set_bit(KEY_GESTURE_O, input_dev->keybit); | |
| __set_bit(KEY_GESTURE_E, input_dev->keybit); | |
| __set_bit(KEY_GESTURE_M, input_dev->keybit); | |
| __set_bit(KEY_GESTURE_W, input_dev->keybit); | |
| __set_bit(KEY_GESTURE_L, input_dev->keybit); | |
| __set_bit(KEY_GESTURE_S, input_dev->keybit); | |
| __set_bit(KEY_GESTURE_V, input_dev->keybit); | |
| __set_bit(KEY_GESTURE_C, input_dev->keybit); | |
| __set_bit(KEY_GESTURE_Z, input_dev->keybit); | |
| fts_create_gesture_sysfs(client); | |
| fts_gesture_data.mode = 0; | |
| fts_gesture_data.active = 0; | |
| FTS_FUNC_EXIT(); | |
| return 0; | |
| } | |
| /************************************************************************ | |
| * Name: fts_gesture_exit | |
| * Brief: remove sys | |
| * Input: i2c info | |
| * Output: no | |
| * Return: no | |
| ***********************************************************************/ | |
| int fts_gesture_exit(struct i2c_client *client) | |
| { | |
| sysfs_remove_group(&client->dev.kobj, &fts_gesture_group); | |
| return 0; | |
| } | |
| /***************************************************************************** | |
| * Name: fts_check_gesture | |
| * Brief: | |
| * Input: | |
| * Output: None | |
| * Return: None | |
| *****************************************************************************/ | |
| static void fts_check_gesture(struct input_dev *input_dev, int gesture_id) | |
| { | |
| char *envp[2]; | |
| int gesture; | |
| FTS_FUNC_ENTER(); | |
| switch (gesture_id) { | |
| case GESTURE_LEFT: | |
| envp[0] = "GESTURE=LEFT"; | |
| gesture = KEY_GESTURE_LEFT; | |
| break; | |
| case GESTURE_RIGHT: | |
| envp[0] = "GESTURE=RIGHT"; | |
| gesture = KEY_GESTURE_RIGHT; | |
| break; | |
| case GESTURE_UP: | |
| envp[0] = "GESTURE=UP"; | |
| gesture = KEY_GESTURE_UP; | |
| break; | |
| case GESTURE_DOWN: | |
| envp[0] = "GESTURE=DOWN"; | |
| gesture = KEY_GESTURE_DOWN; | |
| break; | |
| case GESTURE_DOUBLECLICK: | |
| envp[0] = "GESTURE=DOUBLE_CLICK"; | |
| gesture = KEY_POWER; | |
| break; | |
| case GESTURE_O: | |
| envp[0] = "GESTURE=O"; | |
| gesture = KEY_GESTURE_O; | |
| break; | |
| case GESTURE_W: | |
| envp[0] = "GESTURE=W"; | |
| gesture = KEY_GESTURE_W; | |
| break; | |
| case GESTURE_M: | |
| envp[0] = "GESTURE=M"; | |
| gesture = KEY_GESTURE_M; | |
| break; | |
| case GESTURE_E: | |
| envp[0] = "GESTURE=E"; | |
| gesture = KEY_GESTURE_E; | |
| break; | |
| case GESTURE_L: | |
| envp[0] = "GESTURE=L"; | |
| gesture = KEY_GESTURE_L; | |
| break; | |
| case GESTURE_S: | |
| envp[0] = "GESTURE=S"; | |
| gesture = KEY_GESTURE_S; | |
| break; | |
| case GESTURE_V: | |
| envp[0] = "GESTURE=V"; | |
| gesture = KEY_GESTURE_V; | |
| break; | |
| case GESTURE_Z: | |
| envp[0] = "GESTURE=Z"; | |
| gesture = KEY_GESTURE_Z; | |
| break; | |
| case GESTURE_C: | |
| envp[0] = "GESTURE=C"; | |
| gesture = KEY_GESTURE_C; | |
| break; | |
| default: | |
| envp[0] = "GESTURE=NONE"; | |
| gesture = -1; | |
| break; | |
| } | |
| FTS_DEBUG("envp[0]: %s", envp[0]); | |
| /* report event key */ | |
| /*if (gesture != -1) | |
| { | |
| input_report_key(input_dev, gesture, 1); | |
| input_sync(input_dev); | |
| input_report_key(input_dev, gesture, 0); | |
| input_sync(input_dev); | |
| } */ | |
| envp[1] = NULL; | |
| kobject_uevent_env(&fts_wq_data->client->dev.kobj, KOBJ_CHANGE, envp); | |
| sysfs_notify(&fts_wq_data->client->dev.kobj, NULL, "GESTURE_ID"); | |
| FTS_FUNC_EXIT(); | |
| } | |
| /************************************************************************ | |
| * Name: fts_gesture_readdata | |
| * Brief: read data from TP register | |
| * Input: no | |
| * Output: no | |
| * Return: fail <0 | |
| ***********************************************************************/ | |
| static int fts_gesture_read_buffer(struct i2c_client *client, u8 *buf, | |
| int read_bytes) | |
| { | |
| int remain_bytes; | |
| int ret; | |
| int i; | |
| if (read_bytes <= I2C_BUFFER_LENGTH_MAXINUM) { | |
| ret = fts_i2c_read(client, buf, 1, buf, read_bytes); | |
| } else { | |
| ret = | |
| fts_i2c_read(client, buf, 1, buf, | |
| I2C_BUFFER_LENGTH_MAXINUM); | |
| remain_bytes = read_bytes - I2C_BUFFER_LENGTH_MAXINUM; | |
| for (i = 1; remain_bytes > 0; i++) { | |
| if (remain_bytes <= I2C_BUFFER_LENGTH_MAXINUM) | |
| ret = | |
| fts_i2c_read(client, buf, 0, | |
| buf + | |
| I2C_BUFFER_LENGTH_MAXINUM * i, | |
| remain_bytes); | |
| else | |
| ret = | |
| fts_i2c_read(client, buf, 0, | |
| buf + | |
| I2C_BUFFER_LENGTH_MAXINUM * i, | |
| I2C_BUFFER_LENGTH_MAXINUM); | |
| remain_bytes -= I2C_BUFFER_LENGTH_MAXINUM; | |
| } | |
| } | |
| return ret; | |
| } | |
| /************************************************************************ | |
| * Name: fts_gesture_readdata | |
| * Brief: read data from TP register | |
| * Input: no | |
| * Output: no | |
| * Return: fail <0 | |
| ***********************************************************************/ | |
| int fts_gesture_readdata(struct i2c_client *client) | |
| { | |
| u8 buf[FTS_GESTRUE_POINTS * 4] = { 0 }; | |
| int ret = -1; | |
| int i = 0; | |
| int gestrue_id = 0; | |
| int read_bytes = 0; | |
| u8 pointnum; | |
| FTS_FUNC_ENTER(); | |
| /* init variable before read gesture point */ | |
| memset(fts_gesture_data.header, 0, FTS_GESTRUE_POINTS_HEADER); | |
| memset(fts_gesture_data.coordinate_x, 0, | |
| FTS_GESTRUE_POINTS * sizeof(u16)); | |
| memset(fts_gesture_data.coordinate_y, 0, | |
| FTS_GESTRUE_POINTS * sizeof(u16)); | |
| buf[0] = FTS_REG_GESTURE_OUTPUT_ADDRESS; | |
| ret = fts_i2c_read(client, buf, 1, buf, FTS_GESTRUE_POINTS_HEADER); | |
| if (ret < 0) { | |
| FTS_ERROR("[GESTURE]Read gesture header data failed!!"); | |
| FTS_FUNC_EXIT(); | |
| return ret; | |
| } | |
| /* FW recognize gesture */ | |
| if (chip_types.chip_idh == 0x54 || chip_types.chip_idh == 0x58 | |
| || chip_types.chip_idh == 0x86 || chip_types.chip_idh == 0x87 | |
| || chip_types.chip_idh == 0x64) { | |
| memcpy(fts_gesture_data.header, buf, FTS_GESTRUE_POINTS_HEADER); | |
| gestrue_id = buf[0]; | |
| pointnum = buf[1]; | |
| read_bytes = ((int)pointnum) * 4 + 2; | |
| buf[0] = FTS_REG_GESTURE_OUTPUT_ADDRESS; | |
| FTS_DEBUG("[GESTURE]PointNum=%d", pointnum); | |
| ret = fts_gesture_read_buffer(client, buf, read_bytes); | |
| if (ret < 0) { | |
| FTS_ERROR("[GESTURE]Read gesture touch data failed!!"); | |
| FTS_FUNC_EXIT(); | |
| return ret; | |
| } | |
| fts_check_gesture(fts_input_dev, gestrue_id); | |
| for (i = 0; i < pointnum; i++) { | |
| fts_gesture_data.coordinate_x[i] = | |
| (((s16) buf[0 + (4 * i + 2)]) & 0x0F) << 8 | | |
| (((s16) buf[1 + (4 * i + 2)]) & 0xFF); | |
| fts_gesture_data.coordinate_y[i] = | |
| (((s16) buf[2 + (4 * i + 2)]) & 0x0F) << 8 | | |
| (((s16) buf[3 + (4 * i + 2)]) & 0xFF); | |
| } | |
| FTS_FUNC_EXIT(); | |
| return 0; | |
| } | |
| /* other IC's gestrue in driver */ | |
| if (0x24 == buf[0]) { | |
| gestrue_id = 0x24; | |
| fts_check_gesture(fts_input_dev, gestrue_id); | |
| FTS_DEBUG("[GESTURE]%d check_gesture gestrue_id", gestrue_id); | |
| FTS_FUNC_EXIT(); | |
| return -1; | |
| } | |
| /* Host Driver recognize gesture */ | |
| pointnum = buf[1]; | |
| read_bytes = ((int)pointnum) * 4 + 2; | |
| buf[0] = FTS_REG_GESTURE_OUTPUT_ADDRESS; | |
| ret = fts_gesture_read_buffer(client, buf, read_bytes); | |
| if (ret < 0) { | |
| FTS_ERROR ("[GESTURE]Driver recognize gesture -" | |
| "Read gesture touch data failed!!"); | |
| FTS_FUNC_EXIT(); | |
| return ret; | |
| } | |
| /* | |
| * Host Driver recognize gesture, need gesture lib.a | |
| * Not use now for compatibility | |
| gestrue_id = fetch_object_sample(buf, pointnum); | |
| */ | |
| gestrue_id = 0x24; | |
| fts_check_gesture(fts_input_dev, gestrue_id); | |
| FTS_DEBUG("[GESTURE]%d read gestrue_id", gestrue_id); | |
| for (i = 0; i < pointnum; i++) { | |
| fts_gesture_data.coordinate_x[i] = | |
| (((s16) buf[0 + (4 * i + 8)]) & 0x0F) << 8 | | |
| (((s16) buf[1 + (4 * i + 8)]) & 0xFF); | |
| fts_gesture_data.coordinate_y[i] = | |
| (((s16) buf[2 + (4 * i + 8)]) & 0x0F) << 8 | | |
| (((s16) buf[3 + (4 * i + 8)]) & 0xFF); | |
| } | |
| FTS_FUNC_EXIT(); | |
| return -1; | |
| } | |
| /***************************************************************************** | |
| * Name: fts_gesture_suspend | |
| * Brief: | |
| * Input: | |
| * Output: None | |
| * Return: None | |
| *****************************************************************************/ | |
| int fts_gesture_suspend(struct i2c_client *i2c_client) | |
| { | |
| int i; | |
| u8 state; | |
| FTS_FUNC_ENTER(); | |
| /* gesture not enable, return immediately */ | |
| if (fts_gesture_data.mode == 0) { | |
| FTS_DEBUG("gesture is disabled"); | |
| FTS_FUNC_EXIT(); | |
| return -1; | |
| } | |
| for (i = 0; i < 5; i++) { | |
| fts_i2c_write_reg(i2c_client, 0xd1, 0xff); | |
| fts_i2c_write_reg(i2c_client, 0xd2, 0xff); | |
| fts_i2c_write_reg(i2c_client, 0xd5, 0xff); | |
| fts_i2c_write_reg(i2c_client, 0xd6, 0xff); | |
| fts_i2c_write_reg(i2c_client, 0xd7, 0xff); | |
| fts_i2c_write_reg(i2c_client, 0xd8, 0xff); | |
| fts_i2c_write_reg(i2c_client, FTS_REG_GESTURE_EN, 0x01); | |
| msleep(1); | |
| fts_i2c_read_reg(i2c_client, FTS_REG_GESTURE_EN, &state); | |
| if (state == 1) | |
| break; | |
| } | |
| if (i >= 5) { | |
| FTS_ERROR("[GESTURE]Enter into gesture(suspend) failed!\n"); | |
| FTS_FUNC_EXIT(); | |
| return -1; | |
| } | |
| fts_gesture_data.active = 1; | |
| FTS_DEBUG("[GESTURE]Enter into gesture(suspend) successfully!"); | |
| FTS_FUNC_EXIT(); | |
| return 0; | |
| } | |
| /***************************************************************************** | |
| * Name: fts_gesture_resume | |
| * Brief: | |
| * Input: | |
| * Output: None | |
| * Return: None | |
| *****************************************************************************/ | |
| int fts_gesture_resume(struct i2c_client *client) | |
| { | |
| int i; | |
| u8 state; | |
| FTS_FUNC_ENTER(); | |
| /* gesture not enable, return immediately */ | |
| if (fts_gesture_data.mode == 0) { | |
| FTS_DEBUG("gesture is disabled"); | |
| FTS_FUNC_EXIT(); | |
| return -1; | |
| } | |
| fts_gesture_data.active = 0; | |
| for (i = 0; i < 5; i++) { | |
| fts_i2c_write_reg(client, FTS_REG_GESTURE_EN, 0x00); | |
| msleep(1); | |
| fts_i2c_read_reg(client, FTS_REG_GESTURE_EN, &state); | |
| if (state == 0) | |
| break; | |
| } | |
| if (i >= 5) | |
| FTS_ERROR("[GESTURE]Clear gesture(resume) failed!\n"); | |
| FTS_FUNC_EXIT(); | |
| return 0; | |
| } | |
| #endif |