671 lines
22 KiB
C
671 lines
22 KiB
C
|
/*
|
||
|
*
|
||
|
* FocalTech TouchScreen driver.
|
||
|
*
|
||
|
* Copyright (c) 2010-2017, 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
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* Private enumerations, structures and unions using typedef
|
||
|
*****************************************************************************/
|
||
|
/*
|
||
|
* header - byte0:gesture id
|
||
|
* byte1:pointnum
|
||
|
* byte2~7:reserved
|
||
|
* coordinate_x - All gesture point x coordinate
|
||
|
* coordinate_y - All gesture point y coordinate
|
||
|
* mode - 1:enable gesture function(default)
|
||
|
* - 0:disable
|
||
|
* active - 1:enter into gesture(suspend)
|
||
|
* 0:gesture disable or resume
|
||
|
*/
|
||
|
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;
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* 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:
|
||
|
* Input: device, device attribute, char buf
|
||
|
* Output:
|
||
|
* 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:
|
||
|
* Input: device, device attribute, char buf, char count
|
||
|
* Output:
|
||
|
* 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:
|
||
|
* Input: device, device attribute, char buf
|
||
|
* Output:
|
||
|
* 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:
|
||
|
* Input: device, device attribute, char buf, char count
|
||
|
* Output:
|
||
|
* 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:
|
||
|
* Return: 0-success or others-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_report
|
||
|
* Brief:
|
||
|
* Input:
|
||
|
* Output:
|
||
|
* Return:
|
||
|
*****************************************************************************/
|
||
|
static void fts_gesture_report(struct input_dev *input_dev,int gesture_id)
|
||
|
{
|
||
|
int gesture;
|
||
|
|
||
|
FTS_FUNC_ENTER();
|
||
|
FTS_DEBUG("fts gesture_id==0x%x ",gesture_id);
|
||
|
switch (gesture_id)
|
||
|
{
|
||
|
case GESTURE_LEFT:
|
||
|
gesture = KEY_GESTURE_LEFT;
|
||
|
break;
|
||
|
case GESTURE_RIGHT:
|
||
|
gesture = KEY_GESTURE_RIGHT;
|
||
|
break;
|
||
|
case GESTURE_UP:
|
||
|
gesture = KEY_GESTURE_UP;
|
||
|
break;
|
||
|
case GESTURE_DOWN:
|
||
|
gesture = KEY_GESTURE_DOWN;
|
||
|
break;
|
||
|
case GESTURE_DOUBLECLICK:
|
||
|
gesture = KEY_GESTURE_U;
|
||
|
break;
|
||
|
case GESTURE_O:
|
||
|
gesture = KEY_GESTURE_O;
|
||
|
break;
|
||
|
case GESTURE_W:
|
||
|
gesture = KEY_GESTURE_W;
|
||
|
break;
|
||
|
case GESTURE_M:
|
||
|
gesture = KEY_GESTURE_M;
|
||
|
break;
|
||
|
case GESTURE_E:
|
||
|
gesture = KEY_GESTURE_E;
|
||
|
break;
|
||
|
case GESTURE_L:
|
||
|
gesture = KEY_GESTURE_L;
|
||
|
break;
|
||
|
case GESTURE_S:
|
||
|
gesture = KEY_GESTURE_S;
|
||
|
break;
|
||
|
case GESTURE_V:
|
||
|
gesture = KEY_GESTURE_V;
|
||
|
break;
|
||
|
case GESTURE_Z:
|
||
|
gesture = KEY_GESTURE_Z;
|
||
|
break;
|
||
|
case GESTURE_C:
|
||
|
gesture = KEY_GESTURE_C;
|
||
|
break;
|
||
|
default:
|
||
|
gesture = -1;
|
||
|
break;
|
||
|
}
|
||
|
/* report event key */
|
||
|
if (gesture != -1)
|
||
|
{
|
||
|
FTS_DEBUG("Gesture Code=%d", gesture);
|
||
|
input_report_key(input_dev, gesture, 1);
|
||
|
input_sync(input_dev);
|
||
|
input_report_key(input_dev, gesture, 0);
|
||
|
input_sync(input_dev);
|
||
|
}
|
||
|
|
||
|
FTS_FUNC_EXIT();
|
||
|
}
|
||
|
|
||
|
/************************************************************************
|
||
|
* Name: fts_gesture_readdata
|
||
|
* Brief: read data from TP register
|
||
|
* Input:
|
||
|
* Output:
|
||
|
* 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_fw
|
||
|
* Brief: Check IC's gesture recognise by FW or not
|
||
|
* Input:
|
||
|
* Output:
|
||
|
* Return: 1- FW 0- Driver
|
||
|
***********************************************************************/
|
||
|
static int fts_gesture_fw(void)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
|
||
|
switch (chip_types.chip_idh)
|
||
|
{
|
||
|
case 0x54:
|
||
|
case 0x58:
|
||
|
case 0x64:
|
||
|
case 0x87:
|
||
|
case 0x86:
|
||
|
case 0x80:
|
||
|
case 0xE7:
|
||
|
ret = 1;
|
||
|
break;
|
||
|
default:
|
||
|
ret = 0;
|
||
|
break;
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
/************************************************************************
|
||
|
* Name: fts_gesture_readdata
|
||
|
* Brief: read data from TP register
|
||
|
* Input:
|
||
|
* Output:
|
||
|
* 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 (fts_gesture_fw())
|
||
|
{
|
||
|
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_gesture_report(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;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
FTS_ERROR("[GESTURE]IC 0x%x need gesture lib to support gestures.", chip_types.chip_idh);
|
||
|
return 0;
|
||
|
}
|
||
|
#if 0
|
||
|
/* other IC's gestrue in driver, need gesture library */
|
||
|
if (0x24 == buf[0])
|
||
|
{
|
||
|
gestrue_id = 0x24;
|
||
|
fts_gesture_report(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);
|
||
|
fts_gesture_report(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;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* Name: fts_gesture_recovery
|
||
|
* Brief: recovery gesture state when reset or power on
|
||
|
* Input:
|
||
|
* Output:
|
||
|
* 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_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;
|
||
|
}
|
||
|
|
||
|
if (fts_gesture_data.active == 0)
|
||
|
{
|
||
|
FTS_DEBUG("gesture is unactive");
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* 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 = 1;
|
||
|
fts_gesture_data.active = 0;
|
||
|
FTS_FUNC_EXIT();
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/************************************************************************
|
||
|
* Name: fts_gesture_exit
|
||
|
* Brief: call when driver removed
|
||
|
* Input:
|
||
|
* Output:
|
||
|
* Return:
|
||
|
***********************************************************************/
|
||
|
int fts_gesture_exit(struct i2c_client *client)
|
||
|
{
|
||
|
FTS_FUNC_ENTER();
|
||
|
sysfs_remove_group(&client->dev.kobj, &fts_gesture_group);
|
||
|
FTS_FUNC_EXIT();
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|