blob: 6ab5d47170cce99e36ee6c05636c1f58094f0e46 [file] [log] [blame]
/*
*
* FocalTech ftxxxx 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_ex_mode.c
*
* Author: Liu WeiGuang
*
* Created: 2016-08-31
*
* Abstract:
*
* Reference:
*
*****************************************************************************/
/*****************************************************************************
* 1.Included header files
*****************************************************************************/
#include "focaltech_core.h"
/*****************************************************************************
* 2.Private constant and macro definitions using #define
*****************************************************************************/
/*****************************************************************************
* 3.Private enumerations, structures and unions using typedef
*****************************************************************************/
struct fts_mode_flag {
int fts_glove_mode_flag;
int fts_cover_mode_flag;
int fts_charger_mode_flag;
};
struct fts_mode_flag g_fts_mode_flag;
/*****************************************************************************
* 4.Static variables
*****************************************************************************/
/*****************************************************************************
* 5.Global variable or extern global variabls/functions
*****************************************************************************/
int fts_enter_glove_mode(struct i2c_client *client, int mode);
int fts_glove_init(struct i2c_client *client);
int fts_glove_exit(struct i2c_client *client);
int fts_enter_cover_mode(struct i2c_client *client, int mode);
int fts_cover_init(struct i2c_client *client);
int fts_cover_exit(struct i2c_client *client);
int fts_enter_charger_mode(struct i2c_client *client, int mode);
int fts_charger_init(struct i2c_client *client);
int fts_charger_exit(struct i2c_client *client);
/*****************************************************************************
* 6.Static function prototypes
*******************************************************************************/
#if FTS_GLOVE_EN
static ssize_t fts_touch_glove_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
return snprintf(buf, PAGE_SIZE, "Glove: %s\n",
g_fts_mode_flag.fts_glove_mode_flag ? "On" : "Off");
}
static ssize_t fts_touch_glove_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
int ret;
if (FTS_SYSFS_ECHO_ON(buf)) {
if (!g_fts_mode_flag.fts_glove_mode_flag) {
FTS_INFO("[Mode]enter glove mode");
ret = fts_enter_glove_mode(fts_i2c_client, true);
if (ret >= 0)
g_fts_mode_flag.fts_glove_mode_flag = true;
}
} else if (FTS_SYSFS_ECHO_OFF(buf)) {
if (g_fts_mode_flag.fts_glove_mode_flag) {
FTS_INFO("[Mode]exit glove mode");
ret = fts_enter_glove_mode(fts_i2c_client, false);
if (ret >= 0)
g_fts_mode_flag.fts_glove_mode_flag = false;
}
}
FTS_INFO("[Mode]glove mode status: %d",
g_fts_mode_flag.fts_glove_mode_flag);
return count;
}
/************************************************************************
* Name: fts_enter_glove_mode
* Brief: change glove mode
* Input: glove mode
* Output: no
* Return: success >=0, otherwise failed
***********************************************************************/
int fts_enter_glove_mode(struct i2c_client *client, int mode)
{
int ret = 0;
static u8 buf_addr[2] = { 0 };
static u8 buf_value[2] = { 0 };
buf_addr[0] = FTS_REG_GLOVE_MODE_EN;
if (mode)
buf_value[0] = 0x01;
else
buf_value[0] = 0x00;
ret = fts_i2c_write_reg(client, buf_addr[0], buf_value[0]);
if (ret < 0)
FTS_ERROR("[Mode]fts_enter_glove_mode write value fail");
return ret;
}
/* read and write glove mode
* read example: cat fts_touch_glove_mode---read glove mode
* write example:echo 01 > fts_touch_glove_mode ---write glove mode to 01
*
*/
static DEVICE_ATTR(fts_glove_mode, S_IRUGO | S_IWUSR, fts_touch_glove_show,
fts_touch_glove_store);
#endif
#if FTS_COVER_EN
static ssize_t fts_touch_cover_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
return snprintf(buf, PAGE_SIZE, "Cover: %s\n",
g_fts_mode_flag.fts_cover_mode_flag ? "On" : "Off");
}
static ssize_t fts_touch_cover_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
int ret;
if (FTS_SYSFS_ECHO_ON(buf)) {
if (!g_fts_mode_flag.fts_cover_mode_flag) {
FTS_INFO("[Mode]enter cover mode");
ret = fts_enter_cover_mode(fts_i2c_client, true);
if (ret >= 0)
g_fts_mode_flag.fts_cover_mode_flag = true;
}
} else if (FTS_SYSFS_ECHO_OFF(buf)) {
if (g_fts_mode_flag.fts_cover_mode_flag) {
FTS_INFO("[Mode]exit cover mode");
ret = fts_enter_cover_mode(fts_i2c_client, false);
if (ret >= 0)
g_fts_mode_flag.fts_cover_mode_flag = false;
}
}
FTS_INFO("[Mode]cover mode status: %d",
g_fts_mode_flag.fts_cover_mode_flag);
return count;
}
/************************************************************************
* Name: fts_enter_cover_mode
* Brief: change cover mode
* Input: cover mode
* Output: no
* Return: success >=0, otherwise failed
***********************************************************************/
int fts_enter_cover_mode(struct i2c_client *client, int mode)
{
int ret = 0;
static u8 buf_addr[2] = { 0 };
static u8 buf_value[2] = { 0 };
buf_addr[0] = FTS_REG_COVER_MODE_EN;
if (mode)
buf_value[0] = 0x01;
else
buf_value[0] = 0x00;
ret = fts_i2c_write_reg(client, buf_addr[0], buf_value[0]);
if (ret < 0)
FTS_ERROR("[Mode] fts_enter_cover_mode write value fail\n");
return ret;
}
/* read and write cover mode
* read example: cat fts_touch_cover_mode---read cover mode
* write example:echo 01 > fts_touch_cover_mode ---write cover mode to 01
*
*/
static DEVICE_ATTR(fts_cover_mode, S_IRUGO | S_IWUSR, fts_touch_cover_show,
fts_touch_cover_store);
#endif
#if FTS_CHARGER_EN
static ssize_t fts_touch_charger_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
return snprintf(buf, PAGE_SIZE, "Charger: %s\n",
g_fts_mode_flag.fts_charger_mode_flag ? "On" : "Off");
}
static ssize_t fts_touch_charger_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
int ret;
if (FTS_SYSFS_ECHO_ON(buf)) {
if (!g_fts_mode_flag.fts_charger_mode_flag) {
FTS_INFO("[Mode]enter charger mode");
ret = fts_enter_charger_mode(fts_i2c_client, true);
if (ret >= 0)
g_fts_mode_flag.fts_charger_mode_flag = true;
}
} else if (FTS_SYSFS_ECHO_OFF(buf)) {
if (g_fts_mode_flag.fts_charger_mode_flag) {
FTS_INFO("[Mode]exit charger mode");
ret = fts_enter_charger_mode(fts_i2c_client, false);
if (ret >= 0)
g_fts_mode_flag.fts_charger_mode_flag = false;
}
}
FTS_INFO("[Mode]charger mode status: %d",
g_fts_mode_flag.fts_charger_mode_flag);
return count;
}
/************************************************************************
* Name: fts_enter_charger_mode
* Brief: change charger mode
* Input: charger mode
* Output: no
* Return: success >=0, otherwise failed
***********************************************************************/
int fts_enter_charger_mode(struct i2c_client *client, int mode)
{
int ret = 0;
static u8 buf_addr[2] = { 0 };
static u8 buf_value[2] = { 0 };
buf_addr[0] = FTS_REG_CHARGER_MODE_EN;
if (mode)
buf_value[0] = 0x01;
else
buf_value[0] = 0x00;
ret = fts_i2c_write_reg(client, buf_addr[0], buf_value[0]);
if (ret < 0)
FTS_DEBUG("[Mode]fts_enter_charger_mode write value fail");
return ret;
}
/* read and write charger mode
* read example: cat fts_touch_charger_mode---read charger mode
* write example:echo 01 > fts_touch_charger_mode ---write charger mode to 01
*
*/
static DEVICE_ATTR(fts_charger_mode, S_IRUGO | S_IWUSR, fts_touch_charger_show,
fts_touch_charger_store);
#endif
static struct attribute *fts_touch_mode_attrs[] = {
#if FTS_GLOVE_EN
&dev_attr_fts_glove_mode.attr,
#endif
#if FTS_COVER_EN
&dev_attr_fts_cover_mode.attr,
#endif
#if FTS_CHARGER_EN
&dev_attr_fts_charger_mode.attr,
#endif
NULL,
};
static struct attribute_group fts_touch_mode_group = {
.attrs = fts_touch_mode_attrs,
};
int fts_ex_mode_init(struct i2c_client *client)
{
int err = 0;
g_fts_mode_flag.fts_glove_mode_flag = false;
g_fts_mode_flag.fts_cover_mode_flag = false;
g_fts_mode_flag.fts_charger_mode_flag = false;
err = sysfs_create_group(&client->dev.kobj, &fts_touch_mode_group);
if (0 != err) {
FTS_ERROR("[Mode]create sysfs failed.");
sysfs_remove_group(&client->dev.kobj, &fts_touch_mode_group);
return -EIO;
}
FTS_DEBUG("[Mode]create sysfs succeeded");
return err;
}
int fts_ex_mode_exit(struct i2c_client *client)
{
sysfs_remove_group(&client->dev.kobj, &fts_touch_mode_group);
return 0;
}
int fts_ex_mode_recovery(struct i2c_client *client)
{
int ret = 0;
#if FTS_GLOVE_EN
if (g_fts_mode_flag.fts_glove_mode_flag)
ret = fts_enter_glove_mode(client, true);
#endif
#if FTS_COVER_EN
if (g_fts_mode_flag.fts_cover_mode_flag)
ret = fts_enter_cover_mode(client, true);
#endif
#if FTS_CHARGER_EN
if (g_fts_mode_flag.fts_charger_mode_flag)
ret = fts_enter_charger_mode(client, true);
#endif
return ret;
}