blob: 45bc8723ac9aaf89b8eb64db88140336fa4d6b24 [file] [edit]
/*
*
* FocalTech TouchScreen driver.
*
* Copyright (c) 2012-2020, 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"
/******************************************************************************
* Private constant and macro definitions using #define
*****************************************************************************/
/*****************************************************************************
* Private enumerations, structures and unions using typedef
*****************************************************************************/
/*****************************************************************************
* Static variables
*****************************************************************************/
/*****************************************************************************
* 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)
{
int count = 0;
u8 val = 0;
struct fts_ts_data *ts_data = fts_data;
mutex_lock(&ts_data->input_dev->mutex);
fts_read_reg(FTS_REG_GESTURE_EN, &val);
count = snprintf(buf, PAGE_SIZE, "Gesture Mode:%s\n",
ts_data->gesture_mode ? "On" : "Off");
count += snprintf(buf + count, PAGE_SIZE, "Reg(0xD0)=%d\n", val);
mutex_unlock(&ts_data->input_dev->mutex);
return count;
}
static ssize_t fts_gesture_store(
struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct fts_ts_data *ts_data = fts_data;
mutex_lock(&ts_data->input_dev->mutex);
if (FTS_SYSFS_ECHO_ON(buf)) {
FTS_DEBUG("enable gesture");
ts_data->gesture_mode = ENABLE;
} else if (FTS_SYSFS_ECHO_OFF(buf)) {
FTS_DEBUG("disable gesture");
ts_data->gesture_mode = DISABLE;
}
mutex_unlock(&ts_data->input_dev->mutex);
return count;
}
static inline u32 get_gesture_coordinate(u8 msb, u8 lsb)
{
return FTS_TOUCH_HIRES(((msb & 0xFF) << 8) + (lsb & 0xFF));
}
static ssize_t fts_gesture_buf_show(
struct device *dev, struct device_attribute *attr, char *buf)
{
int count = 0;
struct input_dev *input_dev = fts_data->input_dev;
struct fts_gesture_st *gesture = &fts_data->fts_gesture_data;
mutex_lock(&input_dev->mutex);
count = snprintf(buf, PAGE_SIZE, "Gesture ID:%d\n", gesture->gesture_id);
count += snprintf(buf + count, PAGE_SIZE, "Gesture PointNum:%d\n",
gesture->point_num);
count += snprintf(buf + count, PAGE_SIZE, "Gesture Points Buffer:\n");
count += snprintf(buf + count, PAGE_SIZE, "(%4d,%4d) ",
get_gesture_coordinate(gesture->coordinate_x_msb,
gesture->coordinate_x_lsb),
get_gesture_coordinate(gesture->coordinate_y_msb,
gesture->coordinate_y_lsb));
count += snprintf(buf + count, PAGE_SIZE, "\n");
mutex_unlock(&input_dev->mutex);
return count;
}
static ssize_t fts_gesture_buf_store(
struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
return -EPERM;
}
/* sysfs gesture node
* read example: cat fts_gesture_mode ---read gesture mode
* write example:echo 1 > fts_gesture_mode --- write gesture mode to 1
*
*/
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,
};
static int fts_create_gesture_sysfs(struct device *dev)
{
int ret = 0;
ret = sysfs_create_group(&dev->kobj, &fts_gesture_group);
if (ret) {
FTS_ERROR("gesture sys node create fail");
sysfs_remove_group(&dev->kobj, &fts_gesture_group);
return ret;
}
return 0;
}
/*****************************************************************************
* Name: fts_gesture_readdata
* Brief: Read information about gesture: enable flag/gesture points..., if ges-
* ture enable, save gesture points' information, and report to OS.
* It will be called this function every intrrupt when FTS_GESTURE_EN = 1
*
* gesture data length: 1(enable) + 1(reserve) + 2(header) + 6 * 4
* Input: ts_data - global struct data
* is_report - whether report gesture event or not.
* Output:
* Return: 0 - read gesture data successfully, the report data is gesture data
* 1 - tp not in suspend/gesture not enable in TP FW
* -Exx - error
*****************************************************************************/
int fts_gesture_readdata(struct fts_ts_data *ts_data)
{
struct fts_gesture_st *gesture = &fts_data->fts_gesture_data;
u8 cmd[2] = { 0 };
cmd[0] = FTS_GESTURE_MAJOR_MINOR;
/*if (!ts_data->suspended) {
return -EINVAL;
}*/
fts_read(cmd, 1, gesture->data, sizeof(struct fts_gesture_st));
if (gesture->gesture_enable != ENABLE) {
FTS_DEBUG("gesture not enable in fw, don't process gesture");
return -EINVAL;
}
if (ts_data->log_level >= 1) {
FTS_ERROR("gesture_id=0x%x, point_num=%d, x=%d, y=%d,"
"major=%d, minor=%d, orientation=%d\n",
gesture->gesture_id, gesture->point_num,
get_gesture_coordinate(gesture->coordinate_x_msb,
gesture->coordinate_x_lsb),
get_gesture_coordinate(gesture->coordinate_y_msb,
gesture->coordinate_y_lsb),
gesture->major, gesture->minor,
gesture->orientation);
}
return 0;
}
int fts_gesture_init(struct fts_ts_data *ts_data)
{
FTS_FUNC_ENTER();
fts_create_gesture_sysfs(ts_data->dev);
memset(&ts_data->fts_gesture_data, 0, sizeof(struct fts_gesture_st));
ts_data->gesture_mode = FTS_GESTURE_EN;
FTS_FUNC_EXIT();
return 0;
}
int fts_gesture_exit(struct fts_ts_data *ts_data)
{
FTS_FUNC_ENTER();
sysfs_remove_group(&ts_data->dev->kobj, &fts_gesture_group);
FTS_FUNC_EXIT();
return 0;
}